diff --git a/g10/ChangeLog b/g10/ChangeLog index 8889fa743..e11f0aad9 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,14 @@ +2002-05-10 David Shaw + + * packet.h, getkey.c (fixup_uidnode), keyedit.c (show_prefs): Show + assumed prefs for hash and compression as well as the cipher pref. + Show assumed prefs if there are no prefs at all on a v4 + self-signed key. + + * options.h, g10.c (main), sign.c (make_keysig_packet): New + --cert-digest-algo function to override the default key signing + hash algorithm. + 2002-05-09 David Shaw * getkey.c (merge_selfsigs_main): Make sure the revocation key diff --git a/g10/g10.c b/g10/g10.c index f00970fd7..ddeb828b6 100644 --- a/g10/g10.c +++ b/g10/g10.c @@ -168,6 +168,7 @@ enum cmd_and_opt_values { aNull = 0, oNoPGP7, oCipherAlgo, oDigestAlgo, + oCertDigestAlgo, oCompressAlgo, oPasswdFD, #ifdef __riscos__ @@ -432,6 +433,7 @@ static ARGPARSE_OPTS opts[] = { { oSimpleSKChecksum, "simple-sk-checksum", 0, "@"}, { oCipherAlgo, "cipher-algo", 2 , N_("|NAME|use cipher algorithm NAME")}, { oDigestAlgo, "digest-algo", 2 , N_("|NAME|use message digest algorithm NAME")}, + { oCertDigestAlgo, "cert-digest-algo", 2 , "@" }, { oCompressAlgo, "compress-algo", 1 , N_("|N|use compress algorithm N")}, { oThrowKeyid, "throw-keyid", 0, N_("throw keyid field of encrypted packets")}, { oShowPhotos, "show-photos", 0, N_("Show Photo IDs")}, @@ -775,6 +777,7 @@ main( int argc, char **argv ) const char *trustdb_name = NULL; char *def_cipher_string = NULL; char *def_digest_string = NULL; + char *cert_digest_string = NULL; char *s2k_cipher_string = NULL; char *s2k_digest_string = NULL; char *preference_list = NULL; @@ -808,6 +811,7 @@ main( int argc, char **argv ) /* note: if you change these lines, look at oOpenPGP */ opt.def_cipher_algo = 0; opt.def_digest_algo = 0; + opt.cert_digest_algo = 0; opt.def_compress_algo = -1; opt.s2k_mode = 3; /* iterated+salted */ opt.s2k_digest_algo = DIGEST_ALGO_SHA1; @@ -1112,6 +1116,7 @@ main( int argc, char **argv ) opt.not_dash_escaped = 0; opt.def_cipher_algo = 0; opt.def_digest_algo = 0; + opt.cert_digest_algo = 0; opt.def_compress_algo = 1; opt.s2k_mode = 3; /* iterated+salted */ opt.s2k_digest_algo = DIGEST_ALGO_SHA1; @@ -1207,6 +1212,7 @@ main( int argc, char **argv ) #endif /* __riscos__ */ case oCipherAlgo: def_cipher_string = m_strdup(pargs.r.ret_str); break; case oDigestAlgo: def_digest_string = m_strdup(pargs.r.ret_str); break; + case oCertDigestAlgo: cert_digest_string = m_strdup(pargs.r.ret_str); break; case oNoSecmemWarn: secmem_set_flags( secmem_get_flags() | 1 ); break; case oNoPermissionWarn: opt.no_perm_warn=1; break; case oCharset: @@ -1498,6 +1504,12 @@ main( int argc, char **argv ) if( check_digest_algo(opt.def_digest_algo) ) log_error(_("selected digest algorithm is invalid\n")); } + if( cert_digest_string ) { + opt.cert_digest_algo = string_to_digest_algo(cert_digest_string); + m_free(cert_digest_string); cert_digest_string = NULL; + if( check_digest_algo(opt.cert_digest_algo) ) + log_error(_("selected certification digest algorithm is invalid\n")); + } if( s2k_cipher_string ) { opt.s2k_cipher_algo = string_to_cipher_algo(s2k_cipher_string); m_free(s2k_cipher_string); s2k_cipher_string = NULL; diff --git a/g10/getkey.c b/g10/getkey.c index c902fbf36..1a401a111 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -1081,7 +1081,8 @@ fixup_uidnode ( KBNODE uidnode, KBNODE signode, u32 keycreated ) return; /* has been revoked */ } - uid->created = sig->timestamp; /* this one is okay */ + uid->created = sig->timestamp; /* this one is okay */ + uid->selfsigversion = sig->version; /* store the key flags in the helper variable for later processing */ uid->help_key_usage = 0; diff --git a/g10/keyedit.c b/g10/keyedit.c index 251c3d73f..61cd4e78f 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -1415,15 +1415,22 @@ keyedit_menu( const char *username, STRLIST locusr, STRLIST commands, static void show_prefs (PKT_user_id *uid, int verbose) { + const prefitem_t fake={0,0}; const prefitem_t *prefs; int i; - if( !uid || !uid->prefs ) - return; - prefs = uid->prefs; - if (verbose) { - int any, des_seen=0; + if( !uid ) + return; + if( uid->prefs ) + prefs=uid->prefs; + else if(uid->selfsigversion>=4 && verbose) + prefs=&fake; + else + return; + + if (verbose) { + int any, des_seen=0, sha1_seen=0, uncomp_seen=0; tty_printf (" Cipher: "); for(i=any=0; prefs[i].type; i++ ) { if( prefs[i].type == PREFTYPE_SYM ) { @@ -1444,7 +1451,7 @@ show_prefs (PKT_user_id *uid, int verbose) if (!des_seen) { if (any) tty_printf (", "); - tty_printf ("3DES"); + tty_printf ("%s",cipher_algo_to_string(CIPHER_ALGO_3DES)); } tty_printf ("\n Hash: "); for(i=any=0; prefs[i].type; i++ ) { @@ -1459,7 +1466,14 @@ show_prefs (PKT_user_id *uid, int verbose) tty_printf ("%s", s ); else tty_printf ("[%d]", prefs[i].value); - } + if (prefs[i].value == DIGEST_ALGO_SHA1 ) + sha1_seen = 1; + } + } + if (!sha1_seen) { + if (any) + tty_printf (", "); + tty_printf ("%s",digest_algo_to_string(DIGEST_ALGO_SHA1)); } tty_printf ("\n Compression: "); for(i=any=0; prefs[i].type; i++ ) { @@ -1488,9 +1502,21 @@ show_prefs (PKT_user_id *uid, int verbose) tty_printf ("%s", s ); else tty_printf ("[%d]", prefs[i].value); - } + if (prefs[i].value == 0 ) + uncomp_seen = 1; + } } - tty_printf("\n"); + if (!uncomp_seen) { + if (any) + tty_printf (", "); + else + tty_printf ("ZIP, "); + tty_printf ("Uncompressed"); + } + tty_printf ("\n Features: "); + if(uid->mdc_feature) + tty_printf ("MDC"); + tty_printf("\n"); } else { tty_printf(" "); diff --git a/g10/options.h b/g10/options.h index a5faffa1e..e6e1327bd 100644 --- a/g10/options.h +++ b/g10/options.h @@ -64,6 +64,7 @@ struct { int force_mdc; int disable_mdc; int def_digest_algo; + int cert_digest_algo; int def_compress_algo; const char *def_secret_key; char *def_recipient; diff --git a/g10/packet.h b/g10/packet.h index 7a2deddf7..d4f022a7a 100644 --- a/g10/packet.h +++ b/g10/packet.h @@ -171,6 +171,7 @@ typedef struct { prefitem_t *prefs; /* list of preferences (may be NULL)*/ int mdc_feature; u32 created; /* according to the self-signature */ + byte selfsigversion; char name[1]; } PKT_user_id; diff --git a/g10/sign.c b/g10/sign.c index 25cee51a9..59e517898 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -1114,23 +1114,25 @@ make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk, if (sigversion < pk->version) sigversion = pk->version; - if( !digest_algo ) { - switch( sk->pubkey_algo ) { - case PUBKEY_ALGO_DSA: - digest_algo = DIGEST_ALGO_SHA1; - break; - case PUBKEY_ALGO_RSA_S: - case PUBKEY_ALGO_RSA: - if (opt.force_v4_certs || sk->version > 3) - digest_algo = DIGEST_ALGO_SHA1; - else - digest_algo = DIGEST_ALGO_MD5; - break; - default: - digest_algo = DIGEST_ALGO_RMD160; - break; - } - } + if( !digest_algo ) + { + /* Basically, this means use SHA1 always unless it's a v3 RSA + key making a v3 cert (use MD5), or the user specified + something (use whatever they said). They still must use a + 160-bit hash with DSA, or the signature will fail. Note + that this still allows the caller of make_keysig_packet to + override the user setting if it must. */ + + if(opt.cert_digest_algo) + digest_algo=opt.cert_digest_algo; + else if((sk->pubkey_algo==PUBKEY_ALGO_RSA || + sk->pubkey_algo==PUBKEY_ALGO_RSA_S) && + pk->version<4 && sigversion < 4) + digest_algo = DIGEST_ALGO_MD5; + else + digest_algo = DIGEST_ALGO_SHA1; + } + md = md_open( digest_algo, 0 ); /* hash the public key certificate and the user id */