diff --git a/Makefile.am b/Makefile.am index a2a1d87cd..7e3529c5f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -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 diff --git a/Makefile.in b/Makefile.in index 41e1626ef..4bf9cf0df 100644 --- a/Makefile.in +++ b/Makefile.in @@ -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@ diff --git a/NEWS b/NEWS index c5fbdafb8..ba17e9688 100644 --- a/NEWS +++ b/NEWS @@ -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) - diff --git a/README b/README index 91d3ac983..c2a0fd047 100644 --- a/README +++ b/README @@ -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". diff --git a/TODO b/TODO index 283e72cc9..b1a7313c3 100644 --- a/TODO +++ b/TODO @@ -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 diff --git a/VERSION b/VERSION index 0ea3a944b..0c62199f1 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.2.0 +0.2.1 diff --git a/cipher/random.c b/cipher/random.c index dbf71478b..3355abf1a 100644 --- a/cipher/random.c +++ b/cipher/random.c @@ -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()); diff --git a/config.h.in b/config.h.in index fb816095b..cdb8e2de0 100644 --- a/config.h.in +++ b/config.h.in @@ -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 diff --git a/configure.in b/configure.in index e9a05956e..7017948de 100644 --- a/configure.in +++ b/configure.in @@ -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) diff --git a/g10/Makefile.am b/g10/Makefile.am index ec432e049..154ffe689 100644 --- a/g10/Makefile.am +++ b/g10/Makefile.am @@ -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 diff --git a/g10/Makefile.in b/g10/Makefile.in index ec99a5bc2..a11c89aba 100644 --- a/g10/Makefile.in +++ b/g10/Makefile.in @@ -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) diff --git a/g10/elg.c b/g10/elg.c index 492049a30..f3a8923fa 100644 --- a/g10/elg.c +++ b/g10/elg.c @@ -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) ); diff --git a/g10/filter.h b/g10/filter.h index bedacf9b6..b81a78db6 100644 --- a/g10/filter.h +++ b/g10/filter.h @@ -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; diff --git a/g10/g10.c b/g10/g10.c index 73cb147b0..cab9dc371 100644 --- a/g10/g10.c +++ b/g10/g10.c @@ -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 ); } diff --git a/g10/keygen.c b/g10/keygen.c index 1f932f71b..a817463db 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -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) \"\n\n" ); +" \"Heinrich Heine (Der Dichter) \"\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 */ diff --git a/g10/main.h b/g10/main.h index 5a76173a1..5548f8112 100644 --- a/g10/main.h +++ b/g10/main.h @@ -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 ); diff --git a/g10/mainproc.c b/g10/mainproc.c index 36c3381da..35a44939b 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -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", diff --git a/g10/rsa.c b/g10/rsa.c index c6266516f..b81e1b1bf 100644 --- a/g10/rsa.c +++ b/g10/rsa.c @@ -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 = diff --git a/g10/sign.c b/g10/sign.c index 247b30edd..31fe2bd05 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -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(); diff --git a/include/memory.h b/include/memory.h index 6a9ed84df..bf4e66b2a 100644 --- a/include/memory.h +++ b/include/memory.h @@ -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*/ diff --git a/mpi/mpi-add.c b/mpi/mpi-add.c index 70fc31208..dbea7ac38 100644 --- a/mpi/mpi-add.c +++ b/mpi/mpi-add.c @@ -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) */ diff --git a/po/ChangeLog b/po/ChangeLog new file mode 100644 index 000000000..e69de29bb diff --git a/po/Makefile.in.in b/po/Makefile.in.in index 49a7b1c45..04b1577d7 100644 --- a/po/Makefile.in.in +++ b/po/Makefile.in.in @@ -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 diff --git a/po/POTFILES.in b/po/POTFILES.in index fe5d39422..a5dabe2a1 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -4,11 +4,12 @@ # utility # cipher +cipher/random.c # main program g10/g10.c g10/pkclist.c - +g10/keygen.c diff --git a/po/de.po b/po/de.po index a62cf145b..a3ea55f6a 100644 --- a/po/de.po +++ b/po/de.po @@ -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 .\n" msgstr "Berichte über Wanzen bitte an .\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) \"\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 "" diff --git a/scripts/distfiles b/scripts/distfiles index bdfb3987f..f048185f3 100644 --- a/scripts/distfiles +++ b/scripts/distfiles @@ -2,3 +2,4 @@ config.guess config.sub install-sh mkinstalldirs +mkdiff diff --git a/tools/Makefile.am b/tools/Makefile.am index 31ac04bcb..bddbf5773 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -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 diff --git a/tools/Makefile.in b/tools/Makefile.in index 67e3d6f89..c9e82d7e6 100644 --- a/tools/Makefile.in +++ b/tools/Makefile.in @@ -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 diff --git a/tools/bftest.c b/tools/bftest.c index bbfcd5dd1..c5d31eb1e 100644 --- a/tools/bftest.c +++ b/tools/bftest.c @@ -22,9 +22,13 @@ #include #include #include +#ifdef __MINGW32__ + #include + #include +#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++; diff --git a/util/Makefile.am b/util/Makefile.am index 5fd3e59ca..222b4d876 100644 --- a/util/Makefile.am +++ b/util/Makefile.am @@ -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 diff --git a/util/Makefile.in b/util/Makefile.in index ca24380d6..9ca5f0fd2 100644 --- a/util/Makefile.in +++ b/util/Makefile.in @@ -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." diff --git a/util/argparse.c b/util/argparse.c index 09c820a72..795e87648 100644 --- a/util/argparse.c +++ b/util/argparse.c @@ -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 ) diff --git a/util/logger.c b/util/logger.c index 2355b6267..04dac2ce6 100644 --- a/util/logger.c +++ b/util/logger.c @@ -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(); } diff --git a/util/memory.c b/util/memory.c index 1a60b4931..cd4dc815d 100644 --- a/util/memory.c +++ b/util/memory.c @@ -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 } diff --git a/util/secmem.c b/util/secmem.c new file mode 100644 index 000000000..097a71fe8 --- /dev/null +++ b/util/secmem.c @@ -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 +#include +#include +#include +#include +#include +#if defined(HAVE_MLOCK) || defined(HAVE_MMAP) + #include + #include + #include +#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 ); +} +