diff options
-rw-r--r-- | g10/ChangeLog | 60 | ||||
-rw-r--r-- | g10/build-packet.c | 3 | ||||
-rw-r--r-- | g10/exec.c | 7 | ||||
-rw-r--r-- | g10/getkey.c | 16 | ||||
-rw-r--r-- | g10/gpg.c | 89 | ||||
-rw-r--r-- | g10/import.c | 34 | ||||
-rw-r--r-- | g10/keygen.c | 123 | ||||
-rw-r--r-- | g10/options.h | 3 | ||||
-rw-r--r-- | g10/parse-packet.c | 38 | ||||
-rw-r--r-- | g10/sign.c | 9 |
10 files changed, 323 insertions, 59 deletions
diff --git a/g10/ChangeLog b/g10/ChangeLog index 47e9a7328..4a838257e 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,63 @@ +2006-06-27 Werner Koch <[email protected]> + + Applied patches from 1.4.x (2006-05-22 to 2006-06-23) from David: + + * keygen.c (keygen_upd_std_prefs, keygen_add_std_prefs) + (proc_parameter_file): Add --default-keyserver-url to specify a + keyserver URL at key generation time, and "Keyserver:" keyword for + doing the same through a batch file. + * options.h, gpg.c (main): Ditto. + + * sign.c (do_sign): For now don't accept a truncated hash even + for DSA1 keys (be liberal in what you accept, etc). + + * import.c (import_one): Add a flag (from_sk) so we don't check + prefs on an autoconverted public key. The check should only + happen on the sk side. Noted by Dirk Traulsen. + + * keygen.c (gen_card_key): Add optional argument to return a + pointer (not a copy) of the stub secret key for the secret key we + just generated on the card. + (generate_card_subkeypair): Use it here so that the signing key on + the card can use the card to generate the 0x19 backsig on the + primary key. Noted by Janko Heilgeist and Jonas Oberg. + + * parse-packet.c (parse_user_id): Cap the user ID size at 2048 + bytes. This prevents a memory allocation attack with a very large + user ID. A very large packet length could even cause the + allocation (a u32) to wrap around to a small number. Noted by + Evgeny Legerov on full-disclosure. + + * keygen.c (gen_dsa): Allow generating DSA2 keys. Allow + specifying sizes > 1024 when --enable-dsa2 is set. The size of q + is set automatically based on the key size. + (ask_keysize, generate_keypair): Ask for DSA size when + --enable-dsa2 is set. + + * exec.c (make_tempdir) [W32]: Fix bug with a temporary directory + on W32 that is over 256 bytes long. Noted by Israel G. Lugo. + + * gpg.c (reopen_std): New function to reopen fd 0, 1, or 2 if we + are called with them closed. This is to protect our + keyring/trustdb files from corruption if they get attached to one + of the standard fds. Print a warning if possible that this has + happened, and fail completely if we cannot reopen (should never + happen). + (main): Call it here. + + * parse-packet.c (dump_sig_subpkt, parse_signature): Fix meaning + of key expiration and sig expiration subpackets - zero means + "never expire" according to 2440, not "expire instantly". + * build-packet.c (build_sig_subpkt_from_sig): Ditto. + * getkey.c (fixup_uidnode, merge_selfsigs_main) + (merge_selfsigs_subkey): Ditto. + * keygen.c (keygen_add_key_expire): Ditto. + + * getkey.c (get_pubkey_byname) + * import.c (import_one): Fix key selection problem when + auto-key-locate returns a list of keys, not all of which are + usable (revoked, expired, etc). Noted by Simon Josefsson. + 2006-05-24 Werner Koch <[email protected]> * keyid.c (hash_public_key): Do not double hash the length bytes, diff --git a/g10/build-packet.c b/g10/build-packet.c index cbf037483..878481961 100644 --- a/g10/build-packet.c +++ b/g10/build-packet.c @@ -841,7 +841,8 @@ build_sig_subpkt_from_sig( PKT_signature *sig ) if(sig->expiredate>sig->timestamp) u=sig->expiredate-sig->timestamp; else - u=0; + u=1; /* A 1-second expiration time is the shortest one + OpenPGP has */ buf[0] = (u >> 24) & 0xff; buf[1] = (u >> 16) & 0xff; diff --git a/g10/exec.c b/g10/exec.c index 6938a409a..203c4c78f 100644 --- a/g10/exec.c +++ b/g10/exec.c @@ -127,8 +127,11 @@ static int make_tempdir(struct exec_info *info) if(tmp==NULL) { #if defined (_WIN32) - tmp=xmalloc(256); - if(GetTempPath(256,tmp)==0) + int err; + + tmp=xmalloc(MAX_PATH+2); + err=GetTempPath(MAX_PATH+1,tmp); + if(err==0 || err>MAX_PATH+1) strcpy(tmp,"c:\\windows\\temp"); else { diff --git a/g10/getkey.c b/g10/getkey.c index bff2a0ddc..c0088c38c 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -935,7 +935,7 @@ get_pubkey_byname (PKT_public_key *pk, for(akl=opt.auto_key_locate;akl;akl=akl->next) { - unsigned char *fpr; + unsigned char *fpr=NULL; size_t fpr_len; switch(akl->type) @@ -1507,12 +1507,12 @@ fixup_uidnode ( KBNODE uidnode, KBNODE signode, u32 keycreated ) /* store the key flags in the helper variable for later processing */ uid->help_key_usage=parse_key_usage(sig); - /* ditto or the key expiration */ - uid->help_key_expire = 0; + /* ditto for the key expiration */ p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_EXPIRE, NULL); - if ( p ) { - uid->help_key_expire = keycreated + buffer_to_u32(p); - } + if( p && buffer_to_u32(p) ) + uid->help_key_expire = keycreated + buffer_to_u32(p); + else + uid->help_key_expire = 0; /* Set the primary user ID flag - we will later wipe out some * of them to only have one in our keyblock */ @@ -1724,7 +1724,7 @@ merge_selfsigs_main(KBNODE keyblock, int *r_revoked, struct revoke_info *rinfo) key_usage=parse_key_usage(sig); p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_EXPIRE, NULL); - if ( p ) + if( p && buffer_to_u32(p) ) { key_expire = keytimestamp + buffer_to_u32(p); key_expire_seen = 1; @@ -2128,7 +2128,7 @@ merge_selfsigs_subkey( KBNODE keyblock, KBNODE subnode ) subpk->pubkey_usage = key_usage; p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_EXPIRE, NULL); - if ( p ) + if ( p && buffer_to_u32(p) ) key_expire = keytimestamp + buffer_to_u32(p); else key_expire = 0; @@ -328,6 +328,7 @@ enum cmd_and_opt_values oNoAutoCheckTrustDB, oPreservePermissions, oDefaultPreferenceList, + oDefaultKeyserverURL, oPersonalCipherPreferences, oPersonalDigestPreferences, oPersonalCompressPreferences, @@ -659,6 +660,7 @@ static ARGPARSE_OPTS opts[] = { { aRebuildKeydbCaches, "rebuild-keydb-caches", 256, "@"}, { oPreservePermissions, "preserve-permissions", 0, "@"}, { oDefaultPreferenceList, "default-preference-list", 2, "@"}, + { oDefaultKeyserverURL, "default-keyserver-url", 2, "@"}, { oPersonalCipherPreferences, "personal-cipher-preferences", 2, "@"}, { oPersonalDigestPreferences, "personal-digest-preferences", 2, "@"}, { oPersonalCompressPreferences, "personal-compress-preferences", 2, "@"}, @@ -1643,6 +1645,78 @@ parse_trust_model(const char *model) log_error("unknown trust model `%s'\n",model); } + + +/* Make sure that the standard file descriptors are opened. Obviously + some folks close them before an exec and the next file we open will + get one of them assigned and thus any output (i.e. diagnostics) end + up in that file (e.g. the trustdb). Not actually a gpg problem as + this will hapenn with almost all utilities when called in a wrong + way. However we try to minimize the damage here and raise + awareness of the problem. + + Must be called before we open any files! */ +static void +reopen_std(void) +{ +#if defined(HAVE_STAT) && !defined(HAVE_W32_SYSTEM) + struct stat statbuf; + int did_stdin=0,did_stdout=0,did_stderr=0; + FILE *complain; + + if(fstat(STDIN_FILENO,&statbuf)==-1 && errno==EBADF) + { + if(open("/dev/null",O_RDONLY)==STDIN_FILENO) + did_stdin=1; + else + did_stdin=2; + } + + if(fstat(STDOUT_FILENO,&statbuf)==-1 && errno==EBADF) + { + if(open("/dev/null",O_WRONLY)==STDOUT_FILENO) + did_stdout=1; + else + did_stdout=2; + } + + if(fstat(STDERR_FILENO,&statbuf)==-1 && errno==EBADF) + { + if(open("/dev/null",O_WRONLY)==STDERR_FILENO) + did_stderr=1; + else + did_stderr=2; + } + + /* It's hard to log this sort of thing since the filehandle we would + complain to may be closed... */ + if(did_stderr==0) + complain=stderr; + else if(did_stdout==0) + complain=stdout; + else + complain=NULL; + + if(complain) + { + if(did_stdin==1) + fprintf(complain,"gpg: WARNING: standard input reopened\n"); + if(did_stdout==1) + fprintf(complain,"gpg: WARNING: standard output reopened\n"); + if(did_stderr==1) + fprintf(complain,"gpg: WARNING: standard error reopened\n"); + + if(did_stdin==2 || did_stdout==2 || did_stderr==2) + fprintf(complain,"gpg: fatal: unable to reopen standard input," + " output, or error\n"); + } + + if(did_stdin==2 || did_stdout==2 || did_stderr==2) + exit(3); +#endif /* HAVE_STAT && !HAVE_W32_SYSTEM */ +} + + int main (int argc, char **argv ) { @@ -1697,7 +1771,7 @@ main (int argc, char **argv ) /* Please note that we may running SUID(ROOT), so be very CAREFUL when adding any stuff between here and the call to secmem_init() somewhere after the option parsing. */ - + reopen_std (); trap_unaligned(); set_strusage (my_strusage); gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN); @@ -2586,6 +2660,19 @@ main (int argc, char **argv ) case oDefaultPreferenceList: opt.def_preference_list = pargs.r.ret_str; break; + case oDefaultKeyserverURL: + { + struct keyserver_spec *keyserver; + keyserver=parse_keyserver_uri(pargs.r.ret_str,1, + configname,configlineno); + if(!keyserver) + log_error(_("could not parse keyserver URL\n")); + else + free_keyserver_spec(keyserver); + + opt.def_keyserver_url = pargs.r.ret_str; + } + break; case oPersonalCipherPreferences: pers_cipher_list=pargs.r.ret_str; break; diff --git a/g10/import.c b/g10/import.c index 4526d84d7..3b41e08cf 100644 --- a/g10/import.c +++ b/g10/import.c @@ -66,7 +66,7 @@ static int read_block( IOBUF a, PACKET **pending_pkt, KBNODE *ret_root ); static void revocation_present(KBNODE keyblock); static int import_one(const char *fname, KBNODE keyblock,struct stats_s *stats, unsigned char **fpr,size_t *fpr_len, - unsigned int options); + unsigned int options,int from_sk); static int import_secret_one( const char *fname, KBNODE keyblock, struct stats_s *stats, unsigned int options); static int import_revoke_cert( const char *fname, KBNODE node, @@ -258,7 +258,7 @@ import( IOBUF inp, const char* fname,struct stats_s *stats, while( !(rc = read_block( inp, &pending_pkt, &keyblock) )) { if( keyblock->pkt->pkttype == PKT_PUBLIC_KEY ) - rc = import_one( fname, keyblock, stats, fpr, fpr_len, options ); + rc = import_one( fname, keyblock, stats, fpr, fpr_len, options, 0); else if( keyblock->pkt->pkttype == PKT_SECRET_KEY ) rc = import_secret_one( fname, keyblock, stats, options ); else if( keyblock->pkt->pkttype == PKT_SIGNATURE @@ -679,7 +679,8 @@ check_prefs(KBNODE keyblock) */ static int import_one( const char *fname, KBNODE keyblock, struct stats_s *stats, - unsigned char **fpr,size_t *fpr_len,unsigned int options ) + unsigned char **fpr,size_t *fpr_len,unsigned int options, + int from_sk ) { PKT_public_key *pk; PKT_public_key *pk_orig; @@ -698,9 +699,6 @@ import_one( const char *fname, KBNODE keyblock, struct stats_s *stats, pk = node->pkt->pkt.public_key; - if(fpr) - *fpr=fingerprint_from_pk(pk,NULL,fpr_len); - keyid_from_pk( pk, keyid ); uidnode = find_next_kbnode( keyblock, PKT_USER_ID ); @@ -978,13 +976,31 @@ import_one( const char *fname, KBNODE keyblock, struct stats_s *stats, if(mod_key) { revocation_present(keyblock_orig); - if(seckey_available(keyid)==0) + if(!from_sk && seckey_available(keyid)==0) check_prefs(keyblock_orig); } else if(new_key) { + /* A little explanation for this: we fill in the fingerprint + when importing keys as it can be useful to know the + fingerprint in certain keyserver-related cases (a keyserver + asked for a particular name, but the key doesn't have that + name). However, in cases where we're importing more than + one key at a time, we cannot know which key to fingerprint. + In these cases, rather than guessing, we do not fingerpring + at all, and we must hope the user ID on the keys are + useful. */ + if(fpr) + { + xfree(*fpr); + if(stats->imported==1) + *fpr=fingerprint_from_pk(pk,NULL,fpr_len); + else + *fpr=NULL; + } + revocation_present(keyblock); - if(seckey_available(keyid)==0) + if(!from_sk && seckey_available(keyid)==0) check_prefs(keyblock); } @@ -1156,7 +1172,7 @@ import_secret_one( const char *fname, KBNODE keyblock, if(pub_keyblock) { import_one(fname,pub_keyblock,stats, - NULL,NULL,opt.import_options); + NULL,NULL,opt.import_options,1); release_kbnode(pub_keyblock); } } diff --git a/g10/keygen.c b/g10/keygen.c index f791c6cd0..7a6296974 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -42,6 +42,7 @@ #include "trustdb.h" #include "status.h" #include "i18n.h" +#include "keyserver-internal.h" #include "call-agent.h" @@ -69,7 +70,8 @@ enum para_name { pPASSPHRASE_S2K, pSERIALNO, pBACKUPENCDIR, - pHANDLE + pHANDLE, + pKEYSERVER }; struct para_data_s { @@ -125,6 +127,7 @@ static void do_generate_keypair( struct para_data_s *para, static int write_keyblock( IOBUF out, KBNODE node ); static int gen_card_key (int algo, int keyno, int is_primary, KBNODE pub_root, KBNODE sec_root, + PKT_secret_key **ret_sk, u32 expireval, struct para_data_s *para); static int gen_card_key_with_backup (int algo, int keyno, int is_primary, KBNODE pub_root, KBNODE sec_root, @@ -224,7 +227,7 @@ keygen_add_key_expire( PKT_signature *sig, void *opaque ) if(pk->expiredate > pk->timestamp) u= pk->expiredate - pk->timestamp; else - u= 0; + u= 1; buf[0] = (u >> 24) & 0xff; buf[1] = (u >> 16) & 0xff; @@ -657,6 +660,7 @@ keygen_upd_std_prefs( PKT_signature *sig, void *opaque ) /* Make sure that the MDC feature flag is set if needed */ add_feature_mdc (sig,mdc_available); add_keyserver_modify (sig,ks_modify); + keygen_add_keyserver_url(sig,NULL); return 0; } @@ -675,6 +679,7 @@ keygen_add_std_prefs( PKT_signature *sig, void *opaque ) do_add_key_flags (sig, pk->pubkey_usage); keygen_add_key_expire( sig, opaque ); keygen_upd_std_prefs (sig, opaque); + keygen_add_keyserver_url(sig,NULL); return 0; } @@ -684,6 +689,9 @@ keygen_add_keyserver_url(PKT_signature *sig, void *opaque) { const char *url=opaque; + if(!url) + url=opt.def_keyserver_url; + if(url) build_sig_subpkt(sig,SIGSUBPKT_PREF_KS,url,strlen(url)); else @@ -940,7 +948,6 @@ write_selfsigs( KBNODE sec_root, KBNODE pub_root, PKT_secret_key *sk, return rc; } -/* sub_sk is currently unused (reserved for backsigs) */ static int write_keybinding( KBNODE root, KBNODE pub_root, PKT_secret_key *pri_sk, PKT_secret_key *sub_sk, @@ -1224,20 +1231,54 @@ gen_dsa (unsigned int nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek, PKT_public_key *pk; gcry_sexp_t s_parms, s_key; gcry_sexp_t misc_key_info; + unsigned int qbits; - if( nbits > 1024 || nbits < 512 ) { + if ( nbits < 512 || (!opt.flags.dsa2 && nbits > 1024)) + { nbits = 1024; log_info(_("keysize invalid; using %u bits\n"), nbits ); - } + } + else if ( nbits > 3072 ) + { + nbits = 3072; + log_info(_("keysize invalid; using %u bits\n"), nbits ); + } - if( (nbits % 64) ) { + if( (nbits % 64) ) + { nbits = ((nbits + 63) / 64) * 64; log_info(_("keysize rounded up to %u bits\n"), nbits ); - } + } + + /* + Figure out a q size based on the key size. FIPS 180-3 says: + + L = 1024, N = 160 + L = 2048, N = 224 + L = 2048, N = 256 + L = 3072, N = 256 + + 2048/256 is an odd pair since there is also a 2048/224 and + 3072/256. Matching sizes is not a very exact science. + + We'll do 256 qbits for nbits over 2048, 224 for nbits over 1024 + but less than 2048, and 160 for 1024 (DSA1). + */ + + if (nbits > 2048) + qbits = 256; + else if ( nbits > 1024) + qbits = 224; + else + qbits = 160; + + if (qbits != 160 ) + log_info (_("WARNING: some OpenPGP programs can't" + " handle a DSA key with this digest size\n")); rc = gcry_sexp_build (&s_parms, NULL, - "(genkey(dsa(nbits %d)))", - (int)nbits); + "(genkey(dsa(nbits %d)(qbits %d)))", + (int)nbits, (int)qbits); if (rc) log_bug ("gcry_sexp_build failed: %s\n", gpg_strerror (rc)); @@ -1253,9 +1294,8 @@ gen_dsa (unsigned int nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek, pk = xmalloc_clear( sizeof *pk ); sk->timestamp = pk->timestamp = make_timestamp(); sk->version = pk->version = 4; - if( expireval ) { - sk->expiredate = pk->expiredate = sk->timestamp + expireval; - } + if (expireval) + sk->expiredate = pk->expiredate = sk->timestamp + expireval; sk->pubkey_algo = pk->pubkey_algo = PUBKEY_ALGO_DSA; rc = key_from_sexp (pk->pkey, s_key, "public-key", "pqgy"); @@ -1633,10 +1673,10 @@ ask_keysize( int algo ) switch(algo) { case PUBKEY_ALGO_DSA: - if(opt.expert) + if(opt.flags.dsa2) { def=1024; - max=1024; + max=3072; } else { @@ -2375,6 +2415,25 @@ proc_parameter_file( struct para_data_s *para, const char *fname, /* Set preferences, if any. */ keygen_set_std_prefs(get_parameter_value( para, pPREFERENCES ), 0); + /* Set keyserver, if any. */ + s1=get_parameter_value( para, pKEYSERVER ); + if(s1) + { + struct keyserver_spec *spec; + + spec=parse_keyserver_uri(s1,1,NULL,0); + if(spec) + { + free_keyserver_spec(spec); + opt.def_keyserver_url=s1; + } + else + { + log_error("%s:%d: invalid keyserver url\n", fname, r->lnr ); + return -1; + } + } + /* Set revoker, if any. */ if (parse_revocation_key (fname, para, pREVOKER)) return -1; @@ -2467,6 +2526,7 @@ read_parameter_file( const char *fname ) { "Preferences", pPREFERENCES }, { "Revoker", pREVOKER }, { "Handle", pHANDLE }, + { "Keyserver", pKEYSERVER }, { NULL, 0 } }; IOBUF fp; @@ -2746,12 +2806,12 @@ generate_keypair (const char *fname, const char *card_serialno, sprintf( r->u.value, "%d", PUBKEY_ALGO_DSA ); r->next = para; para = r; - tty_printf(_("DSA keypair will have %u bits.\n"),1024); - r = xmalloc_clear( sizeof *r + 20 ); - r->key = pKEYLENGTH; - strcpy( r->u.value, "1024" ); - r->next = para; - para = r; + nbits = ask_keysize( PUBKEY_ALGO_DSA ); + r = xmalloc_clear( sizeof *r + 20 ); + r->key = pKEYLENGTH; + sprintf( r->u.value, "%u", nbits); + r->next = para; + para = r; r = xmalloc_clear( sizeof *r + 20 ); r->key = pKEYUSAGE; strcpy( r->u.value, "sign" ); @@ -2791,7 +2851,7 @@ generate_keypair (const char *fname, const char *card_serialno, } } - + nbits = ask_keysize( algo ); r = xmalloc_clear( sizeof *r + 20 ); r->key = both? pSUBKEYLENGTH : pKEYLENGTH; @@ -3057,7 +3117,7 @@ do_generate_keypair( struct para_data_s *para, } else { - rc = gen_card_key (PUBKEY_ALGO_RSA, 1, 1, pub_root, sec_root, + rc = gen_card_key (PUBKEY_ALGO_RSA, 1, 1, pub_root, sec_root, NULL, get_parameter_u32 (para, pKEYEXPIRE), para); if (!rc) { @@ -3093,7 +3153,7 @@ do_generate_keypair( struct para_data_s *para, if (!rc && card && get_parameter (para, pAUTHKEYTYPE)) { - rc = gen_card_key (PUBKEY_ALGO_RSA, 3, 0, pub_root, sec_root, + rc = gen_card_key (PUBKEY_ALGO_RSA, 3, 0, pub_root, sec_root, NULL, get_parameter_u32 (para, pKEYEXPIRE), para); if (!rc) @@ -3129,6 +3189,7 @@ do_generate_keypair( struct para_data_s *para, } else rc = gen_card_key (PUBKEY_ALGO_RSA, 2, 0, pub_root, sec_root, + NULL, get_parameter_u32 (para, pKEYEXPIRE), para); } @@ -3353,7 +3414,7 @@ generate_subkeypair( KBNODE pub_keyblock, KBNODE sec_keyblock ) } rc = do_create( algo, nbits, pub_keyblock, sec_keyblock, - dek, s2k, &sub_sk, expire, 1 ); + dek, s2k, &sub_sk, expire, 1 ); if( !rc ) rc = write_keybinding(pub_keyblock, pub_keyblock, pri_sk, sub_sk, use); if( !rc ) @@ -3387,7 +3448,7 @@ generate_card_subkeypair (KBNODE pub_keyblock, KBNODE sec_keyblock, { int okay=0, rc=0; KBNODE node; - PKT_secret_key *pri_sk = NULL; + PKT_secret_key *pri_sk = NULL, *sub_sk; int algo; unsigned int use; u32 expire; @@ -3467,11 +3528,12 @@ generate_card_subkeypair (KBNODE pub_keyblock, KBNODE sec_keyblock, if (passphrase) set_next_passphrase (passphrase); - rc = gen_card_key (algo, keyno, 0, pub_keyblock, sec_keyblock, expire, para); + rc = gen_card_key (algo, keyno, 0, pub_keyblock, sec_keyblock, + &sub_sk, expire, para); if (!rc) - rc = write_keybinding (pub_keyblock, pub_keyblock, pri_sk, NULL, use); + rc = write_keybinding (pub_keyblock, pub_keyblock, pri_sk, sub_sk, use); if (!rc) - rc = write_keybinding (sec_keyblock, pub_keyblock, pri_sk, NULL, use); + rc = write_keybinding (sec_keyblock, pub_keyblock, pri_sk, sub_sk, use); if (!rc) { okay = 1; @@ -3518,7 +3580,7 @@ write_keyblock( IOBUF out, KBNODE node ) static int gen_card_key (int algo, int keyno, int is_primary, - KBNODE pub_root, KBNODE sec_root, + KBNODE pub_root, KBNODE sec_root, PKT_secret_key **ret_sk, u32 expireval, struct para_data_s *para) { #ifdef ENABLE_CARD_SUPPORT @@ -3579,6 +3641,9 @@ gen_card_key (int algo, int keyno, int is_primary, sk->protect.iv[sk->protect.ivlen] = xtoi_2 (s); } + if( ret_sk ) + *ret_sk = sk; + pkt = xcalloc (1,sizeof *pkt); pkt->pkttype = is_primary ? PKT_PUBLIC_KEY : PKT_PUBLIC_SUBKEY; pkt->pkt.public_key = pk; diff --git a/g10/options.h b/g10/options.h index b97b2f3f9..75c2745fc 100644 --- a/g10/options.h +++ b/g10/options.h @@ -154,7 +154,8 @@ struct unsigned int export_options; unsigned int list_options; unsigned int verify_options; - char *def_preference_list; + const char *def_preference_list; + const char *def_keyserver_url; prefitem_t *personal_cipher_prefs; prefitem_t *personal_digest_prefs; prefitem_t *personal_compress_prefs; diff --git a/g10/parse-packet.c b/g10/parse-packet.c index cd6e1dbe6..d792bfff9 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -1,6 +1,6 @@ /* parse-packet.c - read packets - * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, - * 2005 Free Software Foundation, Inc. + * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, + * 2006 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -876,8 +876,13 @@ dump_sig_subpkt( int hashed, int type, int critical, break; case SIGSUBPKT_SIG_EXPIRE: if( length >= 4 ) - fprintf (listfp, "sig expires after %s", - strtimevalue( buffer_to_u32(buffer) ) ); + { + if(buffer_to_u32(buffer)) + fprintf (listfp, "sig expires after %s", + strtimevalue( buffer_to_u32(buffer) ) ); + else + fprintf (listfp, "sig does not expire"); + } break; case SIGSUBPKT_EXPORTABLE: if( length ) @@ -901,8 +906,13 @@ dump_sig_subpkt( int hashed, int type, int critical, break; case SIGSUBPKT_KEY_EXPIRE: if( length >= 4 ) - fprintf (listfp, "key expires after %s", - strtimevalue( buffer_to_u32(buffer) ) ); + { + if(buffer_to_u32(buffer)) + fprintf (listfp, "key expires after %s", + strtimevalue( buffer_to_u32(buffer) ) ); + else + fprintf (listfp, "key does not expire"); + } break; case SIGSUBPKT_PREF_SYM: fputs("pref-sym-algos:", listfp ); @@ -1408,7 +1418,7 @@ parse_signature( IOBUF inp, int pkttype, unsigned long pktlen, log_info ("signature packet without keyid\n"); p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_SIG_EXPIRE,NULL); - if(p) + if(p && buffer_to_u32(p)) sig->expiredate=sig->timestamp+buffer_to_u32(p); if(sig->expiredate && sig->expiredate<=make_timestamp()) sig->flags.expired=1; @@ -2027,6 +2037,20 @@ parse_user_id( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet ) { byte *p; + /* Cap the size of a user ID at 2k: a value absurdly large enough + that there is no sane user ID string (which is printable text + as of RFC2440bis) that won't fit in it, but yet small enough to + avoid allocation problems. A large pktlen may not be + allocatable, and a very large pktlen could actually cause our + allocation to wrap around in xmalloc to a small number. */ + + if (pktlen > 2048) + { + log_error ("packet(%d) too large\n", pkttype); + iobuf_skip_rest(inp, pktlen, 0); + return G10ERR_INVALID_PACKET; + } + packet->pkt.user_id = xmalloc_clear(sizeof *packet->pkt.user_id + pktlen); packet->pkt.user_id->len = pktlen; packet->pkt.user_id->ref=1; diff --git a/g10/sign.c b/g10/sign.c index 3e1d7bc53..0538f0020 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -320,6 +320,12 @@ do_sign( PKT_secret_key *sk, PKT_signature *sig, } else { +#if 0 /* disabled *. + /* Disabled for now. It seems reasonable to accept a + truncated hash for a DSA1 key, even though we don't + generate it without --enable-dsa2. Be liberal in what you + accept, etc. */ + /* If it's a DSA key, and q is 160 bits, it might be an old-style DSA key. If the hash doesn't match the q, fail unless --enable-dsa2 is set. If the q isn't 160 bits, then @@ -333,6 +339,7 @@ do_sign( PKT_secret_key *sk, PKT_signature *sig, log_error(_("DSA requires the use of a 160 bit hash algorithm\n")); return G10ERR_GENERAL; } +#endif /* disabled */ frame = encode_md_value( NULL, sk, md, digest_algo ); if (!frame) @@ -1539,7 +1546,7 @@ update_keysig_packet( PKT_signature **ret_sig, } /* Note that already expired sigs will remain expired (with a - duration of 0) since build-packet.c:build_sig_subpkt_from_sig + duration of 1) since build-packet.c:build_sig_subpkt_from_sig detects this case. */ if( sig->version >= 4 ) |