version 0.2.1

This commit is contained in:
Werner Koch 1998-01-28 16:09:43 +00:00
parent 3d637328c9
commit 9bf8ce27bc
35 changed files with 714 additions and 274 deletions

View File

@ -1,6 +1,6 @@
## Process this file with automake to produce Makefile.in
SUBDIRS = util mpi cipher tools po intl g10
SUBDIRS = @INTLSUB@ @POSUB@ util mpi cipher tools g10
EXTRA_DIST = VERSION

View File

@ -38,15 +38,16 @@ INSTALL_DATA = @INSTALL_DATA@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
transform = @program_transform_name@
SUBDIRS = util mpi cipher tools po intl g10
SUBDIRS = @INTLSUB@ @POSUB@ util mpi cipher tools g10
EXTRA_DIST = VERSION
ACLOCAL = aclocal.m4
ACCONFIG = acconfig.h
CONFIG_HEADER_IN = config.h.in
mkinstalldirs = $(top_srcdir)/scripts/mkinstalldirs
CONFIG_HEADER = ./config.h
DIST_COMMON = README ABOUT-NLS AUTHORS COPYING ChangeLog INSTALL \
Makefile.am Makefile.in NEWS README TODO acconfig.h config.h.in \
configure configure.in stamp-h.in
Makefile.am Makefile.in NEWS README TODO acconfig.h aclocal.m4 \
config.h.in configure configure.in stamp-h.in
PACKAGE = @PACKAGE@

14
NEWS
View File

@ -1,4 +1,12 @@
* We have secure memeory on systems which support mlock().
It is not complete yet, because we do not have signal handler
which does a cleanup in very case.
We should also check the ulimit for the user in the case
that the admin does not have set a limit on locked pages.
* started with internationalization support.
* The logic to handle the web of trust is now implemented. It is
has some bugs; but I'm going to change the algorithm anyway.
It works by calculating the trustlevel on the fly. It may ask
@ -14,12 +22,10 @@
* Read support for new version packets (OpenPGP).
* Comment packets are now of coorect OpenPGP type 16. Old comment
packets writen by G10 are detected because they always start with
* Comment packets are now of correct OpenPGP type 16. Old comment
packets written by G10 are detected because they always start with
a hash which is an invalid version byte.
* The string "(INSECURE!)" is appended to a new user-id if this
is generated on a system without a good random number generator.
* works (more or less) on a UltraPenguin (sparc64--gnu-linux)

3
README
View File

@ -10,6 +10,9 @@
* Some features are not yet implemented
PLEASE USE "--no-armor" BECAUSE THERE IS STILL A BUG IN IT!
(put it into the option file)
Please subscribe to g10@net.lut.ac.uk by sending a mail with
the word "subscribe" in the body to "g10-request@net.lut.ac.uk".

2
TODO
View File

@ -5,9 +5,7 @@
* add a way to difference between errors and eof in the underflow/flush
function of iobuf.
* check that all output is filtered when displayed.
* add trust stuff
* add checking of armor trailers
* add real secure memory
* look for a way to reuse RSA signatures
* remove all "Fixmes"
* speed up the RIPE-MD-160

View File

@ -1 +1 @@
0.2.0
0.2.1

View File

@ -31,6 +31,7 @@
#include "util.h"
#include "cipher.h"
#include "ttyio.h"
#include "i18n.h"
struct cache {
int len;
@ -51,7 +52,11 @@ quick_random_gen( int onoff )
int last = quick_test;
if( onoff != -1 )
quick_test = onoff;
#ifdef HAVE_DEV_RANDOM
return last;
#else
return 1; /* insecure RNG */
#endif
}
@ -137,9 +142,9 @@ fill_buffer( byte *buffer, size_t length, int level )
tv.tv_usec = 0;
if( !(rc=select(fd+1, &rfds, NULL, NULL, &tv)) ) {
if( !warn )
tty_printf(
tty_printf( _(
"\nNot enough random bytes available. Please do some other work to give
the OS a chance to collect more entropy! (Need %d more bytes)\n", length );
the OS a chance to collect more entropy! (Need %d more bytes)\n"), length );
warn = 1;
continue;
}
@ -177,10 +182,10 @@ fill_buffer( byte *buffer, size_t length, int level )
static int initialized=0;
if( !initialized ) {
log_info("warning: using insecure random number generator!!\n");
tty_printf("The random number generator is only a kludge to let\n"
log_info(_("warning: using insecure random number generator!!\n"));
tty_printf(_("The random number generator is only a kludge to let\n"
"it compile - it is in no way a strong RNG!\n\n"
"DON'T USE ANY DATA GENERATED BY THIS PROGRAM!!\n\n");
"DON'T USE ANY DATA GENERATED BY THIS PROGRAM!!\n\n"));
initialized=1;
#ifdef HAVE_RAND
srand(make_timestamp()*getpid());

View File

@ -124,6 +124,12 @@
/* Define if you have the getpagesize function. */
#undef HAVE_GETPAGESIZE
/* Define if you have the mlock function. */
#undef HAVE_MLOCK
/* Define if you have the mmap function. */
#undef HAVE_MMAP
/* Define if you have the munmap function. */
#undef HAVE_MUNMAP

View File

@ -104,7 +104,7 @@ fi
dnl Checks for library functions.
AC_FUNC_VPRINTF
AC_CHECK_FUNCS(strerror stpcpy strlwr tcgetattr rand strtoul)
AC_CHECK_FUNCS(strerror stpcpy strlwr tcgetattr rand strtoul mlock mmap)

View File

@ -46,8 +46,8 @@ g10_SOURCES = g10.c \
sig-check.c
LDADD = -L ../cipher -L ../mpi -L ../util -L ../intl \
-lcipher -lmpi -lutil -lintl
LDADD = -L ../cipher -L ../mpi -L ../util \
-lcipher -lmpi -lutil
$(PROGRAMS): ../cipher/libcipher.a ../mpi/libmpi.a ../util/libutil.a

View File

@ -83,8 +83,8 @@ g10_SOURCES = g10.c \
comment.c \
sig-check.c
LDADD = -L ../cipher -L ../mpi -L ../util -L ../intl \
-lcipher -lmpi -lutil -lintl
LDADD = -L ../cipher -L ../mpi -L ../util \
-lcipher -lmpi -lutil
mkinstalldirs = $(top_srcdir)/scripts/mkinstalldirs
CONFIG_HEADER = ../config.h
PROGRAMS = $(bin_PROGRAMS)

View File

@ -66,18 +66,20 @@ g10_elg_encrypt( PKT_public_cert *pkc, PKT_pubkey_enc *enc, DEK *dek )
void
g10_elg_sign( PKT_secret_cert *skc, PKT_signature *sig, MD_HANDLE md )
g10_elg_sign( PKT_secret_cert *skc, PKT_signature *sig,
MD_HANDLE md, int digest_algo )
{
ELG_secret_key skey;
MPI frame;
byte *dp;
assert( sig->pubkey_algo == PUBKEY_ALGO_ELGAMAL );
if( !digest_algo )
digest_algo = md_get_algo(md);
md_final( md );
dp = md_read( md, 0 );
dp = md_read( md, digest_algo );
keyid_from_skc( skc, sig->keyid );
sig->d.elg.digest_algo = md_get_algo(md);
sig->d.elg.digest_algo = digest_algo;
sig->d.elg.digest_start[0] = dp[0];
sig->d.elg.digest_start[1] = dp[1];
sig->d.elg.a = mpi_alloc( mpi_get_nlimbs(skc->d.elg.p) );

View File

@ -35,9 +35,8 @@ typedef struct {
u32 crc;
byte helpbuf[100];
int helpidx, helplen;
byte tempbuf[100];
int tempidx, templen;
void *fake;
int faked;
int parse_state;
int inp_checked; /* set if inp has been checked */
int inp_bypass; /* set if the input is not armored */
int inp_eof;

View File

@ -116,7 +116,7 @@ wrong_args( const char *text)
fputs(_("Usage: g10 [options] "),stderr);
fputs(text,stderr);
putc('\n',stderr);
exit(2);
g10_exit(2);
}
static void
@ -150,14 +150,14 @@ set_cmd( enum cmd_values *ret_cmd, enum cmd_values new_cmd )
cmd = aKModeC;
else {
log_error(_("conflicting commands\n"));
exit(2);
g10_exit(2);
}
*ret_cmd = cmd;
}
int
void
main( int argc, char **argv )
{
static ARGPARSE_OPTS opts[] = {
@ -237,6 +237,8 @@ main( int argc, char **argv )
enum cmd_values cmd = 0;
secmem_init( 16384 );
i18n_init();
opt.compress = -1; /* defaults to standard compress level */
opt.def_cipher_algo = CIPHER_ALGO_BLOWFISH;
@ -397,7 +399,7 @@ main( int argc, char **argv )
errors++;
}
if( errors )
exit(2);
g10_exit(2);
set_debug();
@ -673,7 +675,17 @@ main( int argc, char **argv )
/* cleanup */
FREE_STRLIST(remusr);
FREE_STRLIST(locusr);
return log_get_errorcount(0)? 2:0;
g10_exit(0);
}
void
g10_exit( int rc )
{
if( opt.verbose )
secmem_dump_stats();
secmem_term();
exit( rc? rc : log_get_errorcount(0)? 2:0 );
}

View File

@ -32,6 +32,7 @@
#include "ttyio.h"
#include "options.h"
#include "keydb.h"
#include "i18n.h"
#if 0
#define TEST_ALGO 1
@ -105,7 +106,7 @@ write_selfsig( KBNODE root, KBNODE pub_root, PKT_secret_cert *skc )
PKT_public_cert *pkc;
if( opt.verbose )
log_info("writing self signature\n");
log_info(_("writing self signature\n"));
/* get the uid packet from the tree */
for( kbctx=NULL; (node=walk_kbtree( root, &kbctx)) ; ) {
@ -201,19 +202,16 @@ gen_elg(unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
#ifdef ENABLE_RSA_KEYGEN
static int
gen_rsa(unsigned nbits, IOBUF pub_io, IOBUF sec_io, DEK *dek,
PKT_public_cert **ret_pkc, PKT_secret_cert **ret_skc )
gen_rsa(unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
PKT_secret_cert **ret_skc )
{
int rc;
PACKET pkt1, pkt2;
PACKET *pkt;
PKT_secret_cert *skc;
PKT_public_cert *pkc;
RSA_public_key pk;
RSA_secret_key sk;
init_packet(&pkt1);
init_packet(&pkt2);
rsa_generate( &pk, &sk, nbits );
skc = m_alloc_clear( sizeof *skc );
@ -234,11 +232,11 @@ gen_rsa(unsigned nbits, IOBUF pub_io, IOBUF sec_io, DEK *dek,
skc->d.rsa.csum += checksum_mpi( skc->d.rsa.rsa_p );
skc->d.rsa.csum += checksum_mpi( skc->d.rsa.rsa_q );
skc->d.rsa.csum += checksum_mpi( skc->d.rsa.rsa_u );
if( !dek ) {
skc->d.rsa.is_protected = 0;
skc->d.rsa.protect_algo = 0;
}
else {
/* return an unprotected version of the skc */
*ret_skc = copy_secret_cert( NULL, skc );
if( dek ) {
skc->d.rsa.is_protected = 1;
skc->d.rsa.protect_algo = CIPHER_ALGO_BLOWFISH;
randomize_buffer( skc->d.rsa.protect.blowfish.iv, 8, 1);
@ -246,31 +244,22 @@ gen_rsa(unsigned nbits, IOBUF pub_io, IOBUF sec_io, DEK *dek,
rc = protect_secret_key( skc, dek );
if( rc ) {
log_error("protect_secret_key failed: %s\n", g10_errstr(rc) );
goto leave;
free_public_cert(pkc);
free_secret_cert(skc);
return rc;
}
}
pkt1.pkttype = PKT_PUBLIC_CERT;
pkt1.pkt.public_cert = pkc;
pkt2.pkttype = PKT_SECRET_CERT;
pkt2.pkt.secret_cert = skc;
pkt = m_alloc_clear(sizeof *pkt);
pkt->pkttype = PKT_PUBLIC_CERT;
pkt->pkt.public_cert = pkc;
add_kbnode(pub_root, new_kbnode( pkt ));
if( (rc = build_packet( pub_io, &pkt1 )) ) {
log_error("build public_cert packet failed: %s\n", g10_errstr(rc) );
goto leave;
}
if( (rc = build_packet( sec_io, &pkt2 )) ) {
log_error("build secret_cert packet failed: %s\n", g10_errstr(rc) );
goto leave;
}
*ret_pkc = pkt1.pkt.public_cert;
pkt1.pkt.public_cert = NULL;
*ret_skc = pkt1.pkt.secret_cert;
pkt1.pkt.secret_cert = NULL;
pkt = m_alloc_clear(sizeof *pkt);
pkt->pkttype = PKT_SECRET_CERT;
pkt->pkt.secret_cert = skc;
add_kbnode(sec_root, new_kbnode( pkt ));
leave:
free_packet(&pkt1);
free_packet(&pkt2);
return rc;
}
#endif /*ENABLE_RSA_KEYGEN*/
@ -305,28 +294,27 @@ generate_keypair()
const char *algo_name;
char *aname, *acomment, *amail;
#ifndef TEST_ALGO
#ifndef TEST_ALGO
if( opt.batch || opt.answer_yes || opt.answer_no )
log_fatal("Key generation can only be used in interactive mode\n");
log_fatal(_("Key generation can only be used in interactive mode\n"));
tty_printf("Please select the algorithm to use:\n"
" (1) ElGamal is the suggested one.\n"
" (2) DSA can only be used for signatures.\n"
#ifdef ENABLE_RSA_KEYGEN
" (3) RSA cannot be used in the U.S.\n"
#endif
);
tty_printf(_("Please select the algorithm to use:\n"
" (1) ElGamal is the suggested one.\n"
" (2) DSA can only be used for signatures.\n"));
#ifdef ENABLE_RSA_KEYGEN
tty_printf(_(" (3) RSA cannot be used in the U.S.\n"));
#endif
#endif
for(;;) {
#ifdef TEST_ALGO
algo = TEST_ALGO;
#else
answer = tty_get("Your selection? (1,2"
#ifdef ENABLE_RSA_KEYGEN
",3"
#endif
") ");
#ifdef ENABLE_RSA_KEYGEN
answer = tty_get(_("Your selection? (1,2,3) "));
#else
answer = tty_get(_("Your selection? (1,2) "));
#endif
tty_kill_prompt();
algo = *answer? atoi(answer): 1;
m_free(answer);
@ -339,7 +327,7 @@ generate_keypair()
else if( algo == 2 ) {
algo = PUBKEY_ALGO_DSA;
algo_name = "DSA";
tty_printf("Sorry; DSA is not yet supported.\n");
tty_printf(_("Sorry; DSA is not yet supported.\n"));
}
#ifdef ENABLE_RSA_KEYGEN
else if( algo == 3 ) {
@ -352,36 +340,33 @@ generate_keypair()
tty_printf("About to generate a new %s keypair.\n"
#ifndef TEST_NBITS
" minimum keysize is 768 bits\n"
" default keysize is 1024 bits\n"
" highest suggested keysize is 2048 bits\n"
#endif
, algo_name );
tty_printf(_("About to generate a new %s keypair.\n"
" minimum keysize is 768 bits\n"
" default keysize is 1024 bits\n"
" highest suggested keysize is 2048 bits\n"), algo_name );
for(;;) {
#ifdef TEST_NBITS
nbits = TEST_NBITS;
#else
answer = tty_get("What keysize do you want? (1024) ");
answer = tty_get(_("What keysize do you want? (1024) "));
tty_kill_prompt();
nbits = *answer? atoi(answer): 1024;
m_free(answer);
#endif
if( algo == PUBKEY_ALGO_DSA && (nbits < 512 || nbits > 1024) )
tty_printf("DSA does only allow keysizes from 512 to 1024\n");
tty_printf(_("DSA does only allow keysizes from 512 to 1024\n"));
else if( nbits < 768 )
tty_printf("keysize too small; 768 is smallest value allowed.\n");
tty_printf(_("keysize too small; 768 is smallest value allowed.\n"));
else if( nbits > 2048 ) {
tty_printf("Keysizes larger than 2048 are not suggested, because "
"computations take REALLY long!\n");
answer = tty_get("Are you sure, that you want this keysize? ");
tty_printf(_("Keysizes larger than 2048 are not suggested, because "
"computations take REALLY long!\n"));
answer = tty_get(_("Are you sure, that you want this keysize? "));
tty_kill_prompt();
if( answer_is_yes(answer) ) {
m_free(answer);
tty_printf("Okay, but keep in mind that your monitor "
"and keyboard radiation is also very vulnerable "
"to attacks!\n");
tty_printf(_("Okay, but keep in mind that your monitor "
"and keyboard radiation is also very vulnerable "
"to attacks!\n"));
break;
}
m_free(answer);
@ -389,24 +374,24 @@ generate_keypair()
else
break;
}
tty_printf("Requested keysize is %u bits\n", nbits );
tty_printf(_("Requested keysize is %u bits\n"), nbits );
if( algo == PUBKEY_ALGO_DSA && (nbits % 64) ) {
nbits = ((nbits + 63) / 64) * 64;
tty_printf("rounded up to %u bits\n", nbits );
tty_printf(_("rounded up to %u bits\n"), nbits );
}
else if( (nbits % 32) ) {
nbits = ((nbits + 31) / 32) * 32;
tty_printf("rounded up to %u bits\n", nbits );
tty_printf(_("rounded up to %u bits\n"), nbits );
}
#ifdef TEST_UID
uid = m_alloc(strlen(TEST_UID)+1);
strcpy(uid, TEST_UID);
#else
tty_printf( "\n"
tty_printf( _("\n"
"You need a User-ID to identify your key; the software constructs the user id\n"
"from Real Name, Comment and Email Address in this form:\n"
" \"Heinrich Heine (Der Dichter) <heinrichh@uni-duesseldorf.de>\"\n\n" );
" \"Heinrich Heine (Der Dichter) <heinrichh@uni-duesseldorf.de>\"\n\n") );
uid = NULL;
aname=acomment=amail=NULL;
for(;;) {
@ -415,15 +400,15 @@ generate_keypair()
if( !aname ) {
for(;;) {
m_free(aname);
aname = tty_get("Real name: ");
aname = tty_get(_("Real name: "));
trim_spaces(aname);
tty_kill_prompt();
if( strpbrk( aname, "<([])>" ) )
tty_printf("Invalid character in name\n");
tty_printf(_("Invalid character in name\n"));
else if( isdigit(*aname) )
tty_printf("Name may not start with a digit\n");
tty_printf(_("Name may not start with a digit\n"));
else if( strlen(aname) < 5 )
tty_printf("Name must be at least 5 characters long\n");
tty_printf(_("Name must be at least 5 characters long\n"));
else
break;
}
@ -431,7 +416,7 @@ generate_keypair()
if( !amail ) {
for(;;) {
m_free(amail);
amail = tty_get("Email address: ");
amail = tty_get(_("Email address: "));
trim_spaces(amail);
strlwr(amail);
tty_kill_prompt();
@ -443,7 +428,7 @@ generate_keypair()
|| amail[strlen(amail)-1] == '@'
|| amail[strlen(amail)-1] == '.'
|| strstr(amail, "..") )
tty_printf("Not a valid email address\n");
tty_printf(_("Not a valid email address\n"));
else
break;
}
@ -451,13 +436,13 @@ generate_keypair()
if( !acomment ) {
for(;;) {
m_free(acomment);
acomment = tty_get("Comment: ");
acomment = tty_get(_("Comment: "));
trim_spaces(acomment);
tty_kill_prompt();
if( !*acomment )
break; /* no comment is okay */
else if( strpbrk( acomment, "()" ) )
tty_printf("Invalid character in comment\n");
tty_printf(_("Invalid character in comment\n"));
else
break;
}
@ -473,15 +458,13 @@ generate_keypair()
/* append a warning if we do not have dev/random
* or it is switched into quick testmode */
#ifdef HAVE_DEV_RANDOM
if( quick_random_gen(-1) )
#endif
strcpy(p, " (INSECURE!)" );
tty_printf("You selected this USER-ID:\n \"%s\"\n\n", uid);
tty_printf(_("You selected this USER-ID:\n \"%s\"\n\n"), uid);
for(;;) {
answer = tty_get("Edit (N)ame, (C)omment, (E)mail or (O)kay? ");
answer = tty_get(_("Edit (N)ame, (C)omment, (E)mail or (O)kay? "));
tty_kill_prompt();
if( strlen(answer) > 1 )
;
@ -513,7 +496,7 @@ generate_keypair()
#endif
tty_printf( "You need a Passphrase to protect your secret key.\n\n" );
tty_printf(_("You need a Passphrase to protect your secret key.\n\n") );
dek = m_alloc_secure( sizeof *dek );
for(;;) {
@ -521,14 +504,14 @@ generate_keypair()
rc = make_dek_from_passphrase( dek , 2 );
if( rc == -1 ) {
m_free(dek); dek = NULL;
tty_printf(
tty_printf(_(
"You don't what a passphrase - this is probably a *bad* idea!\n"
"I will do it anyway. You can change your passphrase at anytime,\n"
"using this program with the option \"--change-passphrase\"\n\n" );
"using this program with the option \"--change-passphrase\"\n\n"));
break;
}
else if( rc == G10ERR_PASSPHRASE ) {
tty_printf("passphrase not correctly repeated; try again.\n");
tty_printf(_("passphrase not correctly repeated; try again.\n"));
}
else if( rc ) {
m_free(dek); dek = NULL;
@ -545,8 +528,8 @@ generate_keypair()
pub_fname = make_filename("~/.g10", "pubring.g10", NULL );
sec_fname = make_filename("~/.g10", "secring.g10", NULL );
if( opt.verbose ) {
tty_printf("writing public certificate to '%s'\n", pub_fname );
tty_printf("writing secret certificate to '%s'\n", sec_fname );
tty_printf(_("writing public certificate to '%s'\n"), pub_fname );
tty_printf(_("writing secret certificate to '%s'\n"), sec_fname );
}
/* we create the packets as a tree of kbnodes. Because the structure
@ -557,17 +540,17 @@ generate_keypair()
pub_root = make_comment_node("#created by G10 pre-release " VERSION );
sec_root = make_comment_node("#created by G10 pre-release " VERSION );
tty_printf(
tty_printf(_(
"We need to generate a lot of random bytes. It is a good idea to perform\n"
"some other action (work in another window, move the mouse, utilize the\n"
"network and the disks) during the prime generation; this gives the random\n"
"number generator a better chance to gain enough entropy.\n" );
"number generator a better chance to gain enough entropy.\n") );
if( algo == PUBKEY_ALGO_ELGAMAL )
rc = gen_elg(nbits, pub_root, sec_root, dek, &skc );
#ifdef ENABLE_RSA_KEYGEN
else if( algo == PUBKEY_ALGO_RSA )
rc = gen_rsa(nbits, pub_io, sec_io, dek, &skc );
rc = gen_rsa(nbits, pub_root, sec_root, dek, &skc );
#endif
else if( algo == PUBKEY_ALGO_DSA )
rc = gen_dsa(nbits, pub_root, sec_root, dek, &skc );
@ -625,7 +608,7 @@ generate_keypair()
else if( (rc=insert_keyblock( &sec_kbpos, sec_root )) )
log_error("can't write secret key: %s\n", g10_errstr(rc) );
else {
tty_printf("public and secret key created and signed.\n" );
tty_printf(_("public and secret key created and signed.\n") );
}
if( !rc1 )
@ -636,7 +619,7 @@ generate_keypair()
if( rc )
tty_printf("Key generation failed: %s\n", g10_errstr(rc) );
tty_printf(_("Key generation failed: %s\n"), g10_errstr(rc) );
release_kbnode( pub_root );
release_kbnode( sec_root );
if( skc ) /* the unprotected secret certificate */

View File

@ -32,6 +32,13 @@ typedef struct {
} encrypt_filter_context_t;
/*-- g10.c --*/
#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 )
void g10_exit(int rc) __attribute__ ((noreturn));
#else
void g10_exit(int rc);
#endif
/*-- encode.c --*/
int encode_symmetric( const char *filename );
int encode_store( const char *filename );
@ -71,11 +78,13 @@ KBNODE make_comment_node( const char *s );
/*-- elg.c --*/
void g10_elg_encrypt( PKT_public_cert *pkc, PKT_pubkey_enc *enc, DEK *dek );
void g10_elg_sign( PKT_secret_cert *skc, PKT_signature *sig, MD_HANDLE md );
void g10_elg_sign( PKT_secret_cert *skc, PKT_signature *sig,
MD_HANDLE md, int digest_algo );
/*-- rsa.c --*/
void g10_rsa_encrypt( PKT_public_cert *pkc, PKT_pubkey_enc *enc, DEK *dek );
void g10_rsa_sign( PKT_secret_cert *skc, PKT_signature *sig, MD_HANDLE md );
void g10_rsa_sign( PKT_secret_cert *skc, PKT_signature *sig,
MD_HANDLE md, int digest_algo );
/*-- import.c --*/
int import_pubkeys( const char *filename );

View File

@ -613,7 +613,7 @@ proc_tree( CTX c, KBNODE node )
print_keyid( stderr, sig->keyid );
putc('\n', stderr);
if( opt.batch )
exit(1);
g10_exit(1);
}
else
log_error("Can't check signature made by %08lX: %s\n",

View File

@ -64,19 +64,20 @@ g10_rsa_encrypt( PKT_public_cert *pkc, PKT_pubkey_enc *enc, DEK *dek )
void
g10_rsa_sign( PKT_secret_cert *skc, PKT_signature *sig, MD_HANDLE md )
g10_rsa_sign( PKT_secret_cert *skc, PKT_signature *sig,
MD_HANDLE md, int digest_algo )
{
#ifdef HAVE_RSA_CIPHER
RSA_secret_key skey;
byte *dp;
assert( sig->pubkey_algo == PUBKEY_ALGO_RSA );
if( !digest_algo )
digest_algo = md_get_algo(md);
md_final( md );
dp = md_read( md, 0 );
dp = md_read( md, digest_algo );
keyid_from_skc( skc, sig->keyid );
sig->d.rsa.digest_algo = md_get_algo( md );
sig->d.rsa.digest_algo = digest_algo;
sig->d.rsa.digest_start[0] = dp[0];
sig->d.rsa.digest_start[1] = dp[1];
sig->d.rsa.rsa_integer =

View File

@ -48,9 +48,9 @@ complete_sig( PKT_signature *sig, PKT_secret_cert *skc, MD_HANDLE md )
if( (rc=check_secret_key( skc )) )
;
else if( sig->pubkey_algo == PUBKEY_ALGO_ELGAMAL )
g10_elg_sign( skc, sig, md );
g10_elg_sign( skc, sig, md, 0 );
else if( sig->pubkey_algo == PUBKEY_ALGO_RSA )
g10_rsa_sign( skc, sig, md );
g10_rsa_sign( skc, sig, md, 0 );
else
BUG();
@ -246,7 +246,6 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
PKT_secret_cert *skc;
PKT_signature *sig;
MD_HANDLE md;
byte *dp;
skc = skc_rover->skc;
@ -265,58 +264,11 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
md_putc( md, a & 0xff );
}
md_final( md );
dp = md_read( md, DIGEST_ALGO_RMD160 );
if( sig->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
ELG_secret_key skey;
MPI frame;
keyid_from_skc( skc, sig->keyid );
sig->d.elg.digest_algo = DIGEST_ALGO_RMD160;
sig->d.elg.digest_start[0] = dp[0];
sig->d.elg.digest_start[1] = dp[1];
sig->d.elg.a = mpi_alloc( mpi_get_nlimbs(skc->d.elg.p) );
sig->d.elg.b = mpi_alloc( mpi_get_nlimbs(skc->d.elg.p) );
frame = encode_rmd160_value( dp, 20, mpi_get_nbits(skc->d.elg.p) );
skey.p = skc->d.elg.p;
skey.g = skc->d.elg.g;
skey.y = skc->d.elg.y;
skey.x = skc->d.elg.x;
elg_sign( sig->d.elg.a, sig->d.elg.b, frame, &skey);
memset( &skey, 0, sizeof skey );
mpi_free(frame);
if( opt.verbose ) {
char *ustr = get_user_id_string( sig->keyid );
log_info("ELG signature from: %s\n", ustr );
m_free(ustr);
}
}
#ifdef HAVE_RSA_CIPHER
else if( sig->pubkey_algo == PUBKEY_ALGO_RSA ) {
RSA_secret_key skey;
keyid_from_skc( skc, sig->keyid );
sig->d.rsa.digest_algo = DIGEST_ALGO_RMD160;
sig->d.rsa.digest_start[0] = dp[0];
sig->d.rsa.digest_start[1] = dp[1];
sig->d.rsa.rsa_integer = encode_rmd160_value( dp, 20,
mpi_get_nbits(skc->d.rsa.rsa_n) );
skey.e = skc->d.rsa.rsa_e;
skey.n = skc->d.rsa.rsa_n;
skey.p = skc->d.rsa.rsa_p;
skey.q = skc->d.rsa.rsa_q;
skey.d = skc->d.rsa.rsa_d;
skey.u = skc->d.rsa.rsa_u;
rsa_secret( sig->d.rsa.rsa_integer, sig->d.rsa.rsa_integer, &skey);
memset( &skey, 0, sizeof skey );
if( opt.verbose ) {
char *ustr = get_user_id_string( sig->keyid );
log_info("RSA signature from: %s\n", ustr );
m_free(ustr);
}
/* fixme: should we check wether the signature is okay? */
}
#endif/*HAVE_RSA_CIPHER*/
if( sig->pubkey_algo == PUBKEY_ALGO_ELGAMAL )
g10_elg_sign( skc, sig, md, DIGEST_ALGO_RMD160 );
else if( sig->pubkey_algo == PUBKEY_ALGO_RSA )
g10_rsa_sign( skc, sig, md, DIGEST_ALGO_RMD160 );
else
BUG();

View File

@ -61,9 +61,20 @@ char *m_strdup( const char * a);
size_t m_size( const void *a );
int m_is_secure( const void *p );
/*-- secmem.c --*/
void secmem_init( size_t npool );
void secmem_term( void );
void *secmem_malloc( size_t size );
void secmem_free( void *a );
void secmem_dump_stats(void);
#define DBG_MEMORY memory_debug_mode
#define DBG_MEMSTAT memory_stat_debug_mode
int memory_debug_mode;
int memory_stat_debug_mode;
#endif /*G10_MEMORY_H*/

View File

@ -216,11 +216,11 @@ mpi_sub_ui(MPI w, MPI u, unsigned long v )
void
mpi_sub(MPI w, MPI u, MPI v)
{
if( 1 || w == v ) {
if( w == v ) {
MPI vv = mpi_copy(v);
vv->sign = !vv->sign;
mpi_add( w, u, vv );
m_free(vv);
mpi_free(vv);
}
else {
/* fixme: this is not thread-save (we temp. modify v) */

0
po/ChangeLog Normal file
View File

View File

@ -55,7 +55,7 @@ SOURCES = cat-id-tbl.c
POFILES = @POFILES@
GMOFILES = @GMOFILES@
DISTFILES = ChangeLog Makefile.in.in POTFILES.in $(PACKAGE).pot \
stamp-cat-id $(POFILES) $(GMOFILES) $(SOURCES)
$(POFILES) $(SOURCES)
POTFILES = \
@ -168,11 +168,12 @@ maintainer-clean: distclean
@echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild."
distdir = ../$(PACKAGE)-$(VERSION)/$(subdir)
dist dist-gettext: update-po $(DISTFILES)
for file in $(DISTFILES); do \
ln $(srcdir)/$$file $(distdir) 2> /dev/null \
|| cp -p $(srcdir)/$$file $(distdir); \
distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
distdir: $(DEP_DISTFILES)
@for file in `cd $(srcdir) && echo $(DISTFILES)`; do \
test -f $(distdir)/$$file \
|| ln $(srcdir)/$$file $(distdir)/$$file 2> /dev/null \
|| cp -p $(srcdir)/$$file $(distdir)/$$file; \
done
update-po: Makefile

View File

@ -4,11 +4,12 @@
# utility
# cipher
cipher/random.c
# main program
g10/g10.c
g10/pkclist.c
g10/keygen.c

224
po/de.po
View File

@ -6,6 +6,32 @@ msgstr ""
"Xgettext-Options: --default-domain=g10 --directory=.. --add-comments --keyword=_ --keyword=N_ --files-from=./POTFILES.in\n"
"Files: g10/g10.c g10/pkclist.c\n"
#: cipher/random.c:146
msgid ""
"\n"
"Not enough random bytes available. Please do some other work to give"
msgstr ""
#: cipher/random.c:185
msgid "warning: using insecure random number generator!!\n"
msgstr ""
#: cipher/random.c:186
msgid ""
"The random number generator is only a kludge to let\n"
"it compile - it is in no way a strong RNG!\n"
"\n"
"DON'T USE ANY DATA GENERATED BY THIS PROGRAM!!\n"
"\n"
msgstr ""
#: g10/g10.c:72
msgid ""
"Syntax: g10 [options] [files]\n"
"sign, check, encrypt or decrypt\n"
"default operation depends on the input data\n"
msgstr ""
#: g10/g10.c:77
msgid "Please report bugs to <g10-bugs@isil.d.shuttle.de>.\n"
msgstr "Berichte über Wanzen bitte an <g10-bugs@isil.d.shuttle.de>.\n"
@ -36,27 +62,27 @@ msgid ""
msgstr ""
" (RSA Verfahren ist vorhanden.)\n"
#: g10/g10.c:109
#: g10/g10.c:116
msgid "Usage: g10 [options] "
msgstr "Aufruf: g10 [Opeionen] "
#: g10/g10.c:145
#: g10/g10.c:152
msgid "conflicting commands\n"
msgstr ""
#: g10/g10.c:157
#: g10/g10.c:164
msgid "create ascii armored output"
msgstr "Ausgabe mit ASCII Armor versehen"
#: g10/g10.c:158
#: g10/g10.c:165
msgid "verbose"
msgstr "detailierte Informationen"
#: g10/g10.c:159
#: g10/g10.c:166
msgid "set compress level (0 disables)"
msgstr "Kompressionspegel sethen (aussschalten mit 0)"
#: g10/g10.c:160
#: g10/g10.c:167
msgid "don't make any changes"
msgstr "Keine wirklichen Änderungen durchführen"
@ -208,43 +234,43 @@ msgstr ""
msgid "export all or the given keys"
msgstr ""
#: g10/g10.c:280
#: g10/g10.c:282
msgid "note: no default option file '%s'\n"
msgstr ""
#: g10/g10.c:283
#: g10/g10.c:285
msgid "option file '%s': %s\n"
msgstr ""
#: g10/g10.c:288
#: g10/g10.c:290
msgid "reading options from '%s'\n"
msgstr ""
#: g10/g10.c:380
#: g10/g10.c:382
msgid "selected cipher algorithm is invalid\n"
msgstr ""
#: g10/g10.c:384
#: g10/g10.c:386
msgid "selected pubkey algorithm is invalid\n"
msgstr ""
#: g10/g10.c:388
#: g10/g10.c:390
msgid "selected digest algorithm is invalid\n"
msgstr ""
#: g10/g10.c:392
#: g10/g10.c:394
msgid "completes-needed must be greater than 0\n"
msgstr ""
#: g10/g10.c:396
#: g10/g10.c:398
msgid "marginals-needed must be greater than 1\n"
msgstr ""
#: g10/g10.c:460
#: g10/g10.c:462
msgid "failed to initialize the TrustDB: %s\n"
msgstr ""
#: g10/g10.c:552 g10/g10.c:569 g10/g10.c:658
#: g10/g10.c:554 g10/g10.c:571 g10/g10.c:660
msgid "can't open '%s'\n"
msgstr ""
@ -306,3 +332,169 @@ msgstr ""
"Ein gültiger Trust Path konnte für diesen Key nicht gefunden werden.\n"
"Mal sehen ob wir now weitere Ownertrust Werte zuordnen können.\n"
"\n"
#: g10/keygen.c:109
msgid "writing self signature\n"
msgstr ""
#: g10/keygen.c:299
msgid "Key generation can only be used in interactive mode\n"
msgstr ""
#: g10/keygen.c:301
msgid ""
"Please select the algorithm to use:\n"
" (1) ElGamal is the suggested one.\n"
" (2) DSA can only be used for signatures.\n"
msgstr ""
#: g10/keygen.c:305
msgid " (3) RSA cannot be used in the U.S.\n"
msgstr ""
#: g10/keygen.c:314
msgid "Your selection? (1,2,3) "
msgstr ""
#: g10/keygen.c:316
msgid "Your selection? (1,2) "
msgstr ""
#: g10/keygen.c:330
msgid "Sorry; DSA is not yet supported.\n"
msgstr ""
#: g10/keygen.c:343
msgid ""
"About to generate a new %s keypair.\n"
" minimum keysize is 768 bits\n"
" default keysize is 1024 bits\n"
" highest suggested keysize is 2048 bits\n"
msgstr ""
#: g10/keygen.c:351
msgid "What keysize do you want? (1024) "
msgstr ""
#: g10/keygen.c:357
msgid "DSA does only allow keysizes from 512 to 1024\n"
msgstr ""
#: g10/keygen.c:359
msgid "keysize too small; 768 is smallest value allowed.\n"
msgstr ""
#: g10/keygen.c:361
msgid "Keysizes larger than 2048 are not suggested, because computations take REALLY long!\n"
msgstr ""
#: g10/keygen.c:363
msgid "Are you sure, that you want this keysize? "
msgstr ""
#: g10/keygen.c:367
msgid "Okay, but keep in mind that your monitor and keyboard radiation is also very vulnerable to attacks!\n"
msgstr ""
#: g10/keygen.c:377
msgid "Requested keysize is %u bits\n"
msgstr ""
#: g10/keygen.c:380 g10/keygen.c:384
msgid "rounded up to %u bits\n"
msgstr ""
#: g10/keygen.c:391
msgid ""
"\n"
"You need a User-ID to identify your key; the software constructs the user id\n"
"from Real Name, Comment and Email Address in this form:\n"
" \"Heinrich Heine (Der Dichter) <heinrichh@uni-duesseldorf.de>\"\n"
"\n"
msgstr ""
#: g10/keygen.c:403
msgid "Real name: "
msgstr ""
#: g10/keygen.c:407
msgid "Invalid character in name\n"
msgstr ""
#: g10/keygen.c:409
msgid "Name may not start with a digit\n"
msgstr ""
#: g10/keygen.c:411
msgid "Name must be at least 5 characters long\n"
msgstr ""
#: g10/keygen.c:419
msgid "Email address: "
msgstr ""
#: g10/keygen.c:431
msgid "Not a valid email address\n"
msgstr ""
#: g10/keygen.c:439
msgid "Comment: "
msgstr ""
#. no comment is okay
#: g10/keygen.c:445
msgid "Invalid character in comment\n"
msgstr ""
#: g10/keygen.c:465
msgid ""
"You selected this USER-ID:\n"
" \"%s\"\n"
"\n"
msgstr ""
#: g10/keygen.c:467
msgid "Edit (N)ame, (C)omment, (E)mail or (O)kay? "
msgstr ""
#: g10/keygen.c:499
msgid ""
"You need a Passphrase to protect your secret key.\n"
"\n"
msgstr ""
#: g10/keygen.c:508
msgid ""
"You don't what a passphrase - this is probably a *bad* idea!\n"
"I will do it anyway. You can change your passphrase at anytime,\n"
"using this program with the option \"--change-passphrase\"\n"
"\n"
msgstr ""
#: g10/keygen.c:514
msgid "passphrase not correctly repeated; try again.\n"
msgstr ""
#: g10/keygen.c:531
msgid "writing public certificate to '%s'\n"
msgstr ""
#: g10/keygen.c:532
msgid "writing secret certificate to '%s'\n"
msgstr ""
#: g10/keygen.c:544
msgid ""
"We need to generate a lot of random bytes. It is a good idea to perform\n"
"some other action (work in another window, move the mouse, utilize the\n"
"network and the disks) during the prime generation; this gives the random\n"
"number generator a better chance to gain enough entropy.\n"
msgstr ""
#: g10/keygen.c:611
msgid "public and secret key created and signed.\n"
msgstr ""
#: g10/keygen.c:622
msgid "Key generation failed: %s\n"
msgstr ""

View File

@ -2,3 +2,4 @@ config.guess
config.sub
install-sh
mkinstalldirs
mkdiff

View File

@ -2,12 +2,15 @@
INCLUDES = -I$(top_srcdir)/include
bin_PROGRAMS = mpicalc
noinst_PROGRAMS = mpicalc bftest
mpicalc_SOURCES = mpicalc.c
bftest_SOURCES = bftest.c
LDADD = -L ../cipher -L ../mpi -L ../util -lmpi -lutil
$(PROGRAMS): ../mpi/libmpi.a
LDADD = -L ../cipher -L ../mpi -L ../util -L ../cipher \
-lmpi -lutil -lmpi -lutil -lcipher
$(PROGRAMS): ../mpi/libmpi.a ../cipher/libcipher.a

View File

@ -40,14 +40,17 @@ transform = @program_transform_name@
INCLUDES = -I$(top_srcdir)/include
bin_PROGRAMS = mpicalc
noinst_PROGRAMS = mpicalc bftest
mpicalc_SOURCES = mpicalc.c
LDADD = -L ../cipher -L ../mpi -L ../util -lmpi -lutil
bftest_SOURCES = bftest.c
LDADD = -L ../cipher -L ../mpi -L ../util -L ../cipher \
-lmpi -lutil -lmpi -lutil -lcipher
mkinstalldirs = $(top_srcdir)/scripts/mkinstalldirs
CONFIG_HEADER = ../config.h
PROGRAMS = $(bin_PROGRAMS)
PROGRAMS = $(noinst_PROGRAMS)
CC = @CC@
@ -65,6 +68,9 @@ LINK = $(CC) $(LDFLAGS) -o $@
mpicalc_OBJECTS = mpicalc.o
EXTRA_mpicalc_SOURCES =
mpicalc_LDADD = $(LDADD)
bftest_OBJECTS = bftest.o
EXTRA_bftest_SOURCES =
bftest_LDADD = $(LDADD)
DIST_COMMON = Makefile.am Makefile.in
@ -77,9 +83,9 @@ DEP_DISTFILES = $(DIST_COMMON) $(SOURCES) $(BUILT_SOURCES) $(HEADERS) \
$(TEXINFOS) $(INFO_DEPS) $(MANS) $(EXTRA_DIST) $(DATA)
TAR = tar
DEP_FILES = $(srcdir)/.deps/mpicalc.P
SOURCES = $(mpicalc_SOURCES)
OBJECTS = $(mpicalc_OBJECTS)
DEP_FILES = $(srcdir)/.deps/bftest.P $(srcdir)/.deps/mpicalc.P
SOURCES = $(mpicalc_SOURCES) $(bftest_SOURCES)
OBJECTS = $(mpicalc_OBJECTS) $(bftest_OBJECTS)
default: all
@ -90,27 +96,14 @@ $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in
Makefile: $(top_builddir)/config.status Makefile.in
cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= ./config.status
mostlyclean-binPROGRAMS:
mostlyclean-noinstPROGRAMS:
clean-binPROGRAMS:
rm -f $(bin_PROGRAMS)
clean-noinstPROGRAMS:
rm -f $(noinst_PROGRAMS)
distclean-binPROGRAMS:
distclean-noinstPROGRAMS:
maintainer-clean-binPROGRAMS:
install-binPROGRAMS: $(bin_PROGRAMS)
$(mkinstalldirs) $(bindir)
list="$(bin_PROGRAMS)"; for p in $$list; do \
if test -f $$p; then \
$(INSTALL_PROGRAM) $$p $(bindir)/`echo $$p|sed '$(transform)'`; \
else :; fi; \
done
uninstall-binPROGRAMS:
list="$(bin_PROGRAMS)"; for p in $$list; do \
rm -f $(bindir)/`echo $$p|sed '$(transform)'`; \
done
maintainer-clean-noinstPROGRAMS:
.c.o:
$(COMPILE) $<
@ -128,6 +121,10 @@ $(mpicalc_OBJECTS): ../config.h
mpicalc: $(mpicalc_OBJECTS) $(mpicalc_DEPENDENCIES)
$(LINK) $(mpicalc_OBJECTS) $(mpicalc_LDADD) $(LIBS)
$(bftest_OBJECTS): ../config.h
bftest: $(bftest_OBJECTS) $(bftest_DEPENDENCIES)
$(LINK) $(bftest_OBJECTS) $(bftest_LDADD) $(LIBS)
ID: $(HEADERS) $(SOURCES)
here=`pwd` && cd $(srcdir) && mkid -f$$here/ID $(SOURCES) $(HEADERS)
@ -189,21 +186,20 @@ check: all
installcheck:
install-exec: install-binPROGRAMS
install-exec:
install-data:
install: install-exec install-data all
@:
uninstall: uninstall-binPROGRAMS
uninstall:
all: $(PROGRAMS) Makefile
install-strip:
$(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' install
installdirs:
$(mkinstalldirs) $(bindir)
mostlyclean-generic:
@ -219,25 +215,25 @@ distclean-generic:
maintainer-clean-generic:
test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
mostlyclean: mostlyclean-binPROGRAMS mostlyclean-compile \
mostlyclean: mostlyclean-noinstPROGRAMS mostlyclean-compile \
mostlyclean-tags mostlyclean-generic
clean: clean-binPROGRAMS clean-compile clean-tags clean-generic \
clean: clean-noinstPROGRAMS clean-compile clean-tags clean-generic \
mostlyclean
distclean: distclean-binPROGRAMS distclean-compile distclean-tags \
distclean: distclean-noinstPROGRAMS distclean-compile distclean-tags \
distclean-generic clean
rm -f config.status
maintainer-clean: maintainer-clean-binPROGRAMS maintainer-clean-compile \
maintainer-clean-tags maintainer-clean-generic \
distclean
maintainer-clean: maintainer-clean-noinstPROGRAMS \
maintainer-clean-compile maintainer-clean-tags \
maintainer-clean-generic distclean
@echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild."
.PHONY: default mostlyclean-binPROGRAMS distclean-binPROGRAMS \
clean-binPROGRAMS maintainer-clean-binPROGRAMS uninstall-binPROGRAMS \
install-binPROGRAMS mostlyclean-compile distclean-compile clean-compile \
.PHONY: default mostlyclean-noinstPROGRAMS distclean-noinstPROGRAMS \
clean-noinstPROGRAMS maintainer-clean-noinstPROGRAMS \
mostlyclean-compile distclean-compile clean-compile \
maintainer-clean-compile tags mostlyclean-tags distclean-tags \
clean-tags maintainer-clean-tags distdir info dvi check installcheck \
install-exec install-data install uninstall all installdirs \
@ -245,7 +241,7 @@ mostlyclean-generic distclean-generic clean-generic \
maintainer-clean-generic clean mostlyclean distclean maintainer-clean
$(PROGRAMS): ../mpi/libmpi.a
$(PROGRAMS): ../mpi/libmpi.a ../cipher/libcipher.a
.SUFFIXES:
.SUFFIXES: .c .o

View File

@ -22,9 +22,13 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef __MINGW32__
#include <io.h>
#include <fcntl.h>
#endif
#include "util.h"
#include "blowfish.h"
#include "cipher.h"
static void
my_usage(void)
@ -48,6 +52,11 @@ main(int argc, char **argv)
char iv[BLOWFISH_BLOCKSIZE];
int n, size=8;
#ifdef __MINGW32__
setmode( fileno(stdin), O_BINARY );
setmode( fileno(stdout), O_BINARY );
#endif
if( argc > 1 && !strcmp(argv[1], "-e") ) {
encode++;
argc--; argv++;

View File

@ -6,7 +6,7 @@ noinst_LIBRARIES = util
util_SOURCES = logger.c fileutil.c miscutil.c strgutil.c \
ttyio.c argparse.c memory.c errors.c iobuf.c
ttyio.c argparse.c memory.c secmem.c errors.c iobuf.c

View File

@ -43,7 +43,7 @@ INCLUDES = -I$(top_srcdir)/include
noinst_LIBRARIES = util
util_SOURCES = logger.c fileutil.c miscutil.c strgutil.c \
ttyio.c argparse.c memory.c errors.c iobuf.c
ttyio.c argparse.c memory.c secmem.c errors.c iobuf.c
mkinstalldirs = $(top_srcdir)/scripts/mkinstalldirs
CONFIG_HEADER = ../config.h
LIBRARIES = $(noinst_LIBRARIES)
@ -64,7 +64,7 @@ COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)
LINK = $(CC) $(LDFLAGS) -o $@
util_LIBADD =
util_OBJECTS = logger.o fileutil.o miscutil.o strgutil.o ttyio.o \
argparse.o memory.o errors.o iobuf.o
argparse.o memory.o secmem.o errors.o iobuf.o
EXTRA_util_SOURCES =
LIBFILES = libutil.a
AR = ar
@ -84,8 +84,8 @@ TAR = tar
DEP_FILES = $(srcdir)/.deps/argparse.P $(srcdir)/.deps/errors.P \
$(srcdir)/.deps/fileutil.P $(srcdir)/.deps/iobuf.P \
$(srcdir)/.deps/logger.P $(srcdir)/.deps/memory.P \
$(srcdir)/.deps/miscutil.P $(srcdir)/.deps/strgutil.P \
$(srcdir)/.deps/ttyio.P
$(srcdir)/.deps/miscutil.P $(srcdir)/.deps/secmem.P \
$(srcdir)/.deps/strgutil.P $(srcdir)/.deps/ttyio.P
SOURCES = $(util_SOURCES)
OBJECTS = $(util_OBJECTS)
@ -170,11 +170,11 @@ $(srcdir)/.deps/%.P: $(srcdir)/%.c
@echo "mkdeps $< > $@"
@re=`echo 's,^$(srcdir)//*,,g;s, $(srcdir)//*, ,g' | sed 's,\.,\\\\.,g'`; \
$(MKDEP) $< | sed "$$re" > $@-tmp
@if test -n "$o"; then \
sed 's/\.o:/$$o:/' $@-tmp > $@; \
@if test -n "$o"; then \
sed 's/\.o:/$$o:/' $@-tmp > $@; \
rm $@-tmp; \
else \
mv $@-tmp $@; \
mv $@-tmp $@; \
fi
# End of maintainer-only section
@ -186,14 +186,14 @@ check: all
installcheck:
install-exec:
install-exec:
install-data:
install-data:
install: install-exec install-data all
@:
uninstall:
uninstall:
all: $(LIBFILES) Makefile
@ -218,16 +218,16 @@ maintainer-clean-generic:
mostlyclean: mostlyclean-noinstLIBRARIES mostlyclean-compile \
mostlyclean-tags mostlyclean-generic
clean: clean-noinstLIBRARIES clean-compile clean-tags clean-generic \
mostlyclean
clean: clean-noinstLIBRARIES clean-compile clean-tags clean-generic \
mostlyclean
distclean: distclean-noinstLIBRARIES distclean-compile distclean-tags \
distclean-generic clean
distclean-generic clean
rm -f config.status
maintainer-clean: maintainer-clean-noinstLIBRARIES \
maintainer-clean-compile maintainer-clean-tags \
maintainer-clean-generic distclean
maintainer-clean-generic distclean
@echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild."

View File

@ -545,7 +545,7 @@ show_help( ARGPARSE_OPTS *opts, unsigned flags )
indent += 10;
puts("Options:");
for(i=0; opts[i].short_opt; i++ ) {
s = _(opts[i].description);
s = _( opts[i].description );
if( s && *s== '\r' ) /* hide this line */
continue;
if( opts[i].short_opt < 256 )

View File

@ -111,6 +111,7 @@ log_fatal( const char *fmt, ... )
va_start( arg_ptr, fmt ) ;
vfprintf(stderr,fmt,arg_ptr) ;
va_end(arg_ptr);
secmem_dump_stats();
exit(2);
}
@ -124,6 +125,7 @@ log_bug( const char *fmt, ... )
vfprintf(stderr,fmt,arg_ptr) ;
va_end(arg_ptr);
fflush(stderr);
secmem_dump_stats();
abort();
}

View File

@ -314,9 +314,10 @@ membug( const char *fmt, ... )
static void
out_of_core(size_t n)
out_of_core(size_t n, int secure)
{
log_fatal("out of memory while allocating %u bytes\n", (unsigned)n );
log_fatal("out of %s memory while allocating %u bytes\n",
secure? "secure":"" ,(unsigned)n );
}
/****************
@ -329,7 +330,7 @@ FNAME(alloc)( size_t n FNAMEPRT )
char *p;
if( !(p = malloc( n + 5 )) )
out_of_core(n);
out_of_core(n,0);
store_len(p,n,0);
p[4+n] = MAGIC_END_BYTE; /* need to add the length somewhere */
return p+4;
@ -344,8 +345,8 @@ FNAME(alloc_secure)( size_t n FNAMEPRT )
{
char *p;
if( !(p = malloc( n + 5 )) ) /* fixme: should alloc from the secure heap*/
out_of_core(n);
if( !(p = secmem_malloc( n + 5 )) )
out_of_core(n,1);
store_len(p,n,1);
p[4+n] = MAGIC_END_BYTE;
return p+4;
@ -408,7 +409,10 @@ FNAME(free)( void *a FNAMEPRT )
free_entry(p-4, info);
#else
m_check(p);
free(p-4);
if( m_is_secure(a) )
secmem_free(p-4);
else
free(p-4);
#endif
}

243
util/secmem.c Normal file
View File

@ -0,0 +1,243 @@
/* secmem.c - memory allocation from a secure heap
* Copyright (c) 1997 by Werner Koch (dd9jn)
*
* This file is part of G10.
*
* G10 is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* G10 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <stdarg.h>
#if defined(HAVE_MLOCK) || defined(HAVE_MMAP)
#include <unistd.h>
#include <sys/mman.h>
#include <sys/types.h>
#endif
#include "types.h"
#include "memory.h"
#include "util.h"
#define DEFAULT_POOLSIZE 8196
typedef struct memblock_struct MEMBLOCK;
struct memblock_struct {
unsigned size;
union {
MEMBLOCK *next;
long align_dummy;
char d[1];
} u;
};
static void *pool;
static int pool_okay;
static int pool_is_mmapped;
static size_t poolsize; /* allocated length */
static size_t poollen; /* used length */
static MEMBLOCK *unused_blocks;
static unsigned max_alloced;
static unsigned cur_alloced;
static unsigned max_blocks;
static unsigned cur_blocks;
static void
lock_pool( void *p, size_t n )
{
#ifdef HAVE_MLOCK
uid_t uid;
int err;
err = mlock( p, n );
if( err && errno )
err = errno;
uid = getuid();
if( uid && !geteuid() ) {
if( setuid( uid ) )
log_fatal("failed to reset uid: %s\n", strerror(errno));
}
if( err ) {
log_error("can´t lock memory: %s\n", strerror(err));
log_info("Warning: using insecure memory!\n");
}
#else
log_info("Please note that you don´t have secure memory on this system\n");
#endif
}
static void
init_pool( size_t n)
{
poolsize = n;
#if HAVE_MMAP && defined(MAP_ANONYMOUS)
poolsize = (poolsize + 4095) & ~4095;
pool = mmap( 0, poolsize, PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
if( pool == (void*)-1 )
log_error("can´t mmap pool of %u bytes: %s - using malloc\n",
(unsigned)poolsize, strerror(errno));
else {
pool_is_mmapped = 1;
pool_okay = 1;
}
#endif
if( !pool_okay ) {
pool = malloc( poolsize );
if( !pool )
log_fatal("can´t allocate memory pool of %u bytes\n",
(unsigned)poolsize);
else
pool_okay = 1;
}
lock_pool( pool, poolsize );
poollen = 0;
}
/* concatenate unused blocks */
static void
compress_pool(void)
{
}
void
secmem_init( size_t n )
{
if( n < DEFAULT_POOLSIZE )
n = DEFAULT_POOLSIZE;
if( !pool_okay )
init_pool(n);
else
log_error("Oops, secure memory pool already initialized\n");
}
void *
secmem_malloc( size_t size )
{
MEMBLOCK *mb, *mb2;
int compressed=0;
if( !pool_okay )
init_pool(DEFAULT_POOLSIZE);
/* blocks are always a multiple of 32 */
size += sizeof(MEMBLOCK);
size = ((size + 31) / 32) * 32;
retry:
/* try to get it from the used blocks */
for(mb = unused_blocks,mb2=NULL; mb; mb2=mb, mb = mb->u.next )
if( mb->size >= size ) {
if( mb2 )
mb2->u.next = mb->u.next;
else
unused_blocks = mb->u.next;
goto leave;
}
/* allocate a new block */
if( (poollen + size <= poolsize) ) {
mb = pool + poollen;
poollen += size;
mb->size = size;
}
else if( !compressed ) {
compressed=1;
compress_pool();
goto retry;
}
else
return NULL;
leave:
cur_alloced += mb->size;
cur_blocks++;
if( cur_alloced > max_alloced )
max_alloced = cur_alloced;
if( cur_blocks > max_blocks )
max_blocks = cur_blocks;
return &mb->u.d;
}
void
secmem_free( void *a )
{
MEMBLOCK *mb;
size_t size;
if( !a )
return;
mb = (MEMBLOCK*)((char*)a - ((size_t) &((MEMBLOCK*)0)->u.d));
size = mb->size;
memset(mb, 0xff, size );
memset(mb, 0xaa, size );
memset(mb, 0x55, size );
memset(mb, 0x00, size );
mb->size = size;
mb->u.next = unused_blocks;
unused_blocks = mb;
cur_blocks--;
cur_alloced -= size;
}
void
secmem_term()
{
if( !pool_okay )
return;
memset( pool, 0xff, poolsize);
memset( pool, 0xaa, poolsize);
memset( pool, 0x55, poolsize);
memset( pool, 0x00, poolsize);
#if HAVE_MMAP
if( pool_is_mmapped )
munmap( pool, poolsize );
#endif
pool = NULL;
pool_okay = 0;
poolsize=0;
poollen=0;
unused_blocks=NULL;
}
void
secmem_dump_stats()
{
fprintf(stderr,
"secmem usage: %u/%u bytes in %u/%u blocks of pool %lu/%lu\n",
cur_alloced, max_alloced, cur_blocks, max_blocks,
(ulong)poollen, (ulong)poolsize );
}