From dce4566802053e2480dffea2380201373d2e6ec2 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 1 Aug 2001 10:30:24 +0000 Subject: [PATCH] Changed lsign behaviour, allow future subkeys, don't list revoked keys --- NEWS | 7 +++++++ TODO | 8 -------- doc/ChangeLog | 4 ++++ doc/gpg.sgml | 9 +++++++++ g10/ChangeLog | 14 ++++++++++++++ g10/g10.c | 3 +++ g10/getkey.c | 8 +++++++- g10/keyedit.c | 32 +++++++++++++------------------- g10/keygen.c | 4 ++-- g10/keylist.c | 6 ++++++ g10/options.h | 1 + g10/packet.h | 2 +- g10/revoke.c | 2 +- g10/sign.c | 20 ++++++++++++++------ 14 files changed, 82 insertions(+), 38 deletions(-) diff --git a/NEWS b/NEWS index 7c35dc746..202271654 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,13 @@ * New option --preserve-permissions. + * Subkeys created in the future are not used for encryption or + signing unless the new option --ignore-valid-from is used. + + * Revoked user-IDs are not listed unless signatures are listed too + or we are in verbose mode. + + Noteworthy changes in version 1.0.6 (2001-05-29) ------------------------------------------------ diff --git a/TODO b/TODO index b15adce59..d8131654e 100644 --- a/TODO +++ b/TODO @@ -1,12 +1,7 @@ - * Change the 'no lsign with v3 key policy" to simply use a v4 - signature in that case. Hmm, that's what Thomas' patch was about. - * Put a note into readme.w32 that there is a man page and a options file; write the registry stuff in regedit format. - * Ignore subkeys created in the future. - * Allow "gpg -cs" * Show more info does not work from edit->trust @@ -66,9 +61,6 @@ * Check for consistent spelling of user ID, key ID etc. Replace "user id not found" in getkey.c by "no valid user ID found". - * Do not return "[revoked] User Name" unless in verbose mode, so that - revoked user IDs are better hidden. - * Replace the printing of the user name by [self-signature] when appropriate so that a key listing does not get clobbered. diff --git a/doc/ChangeLog b/doc/ChangeLog index ab5ef7949..84bfcd55c 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,3 +1,7 @@ +2001-08-01 Werner Koch + + * gpg.sgml: Added --ignore-valid-from + 2001-04-20 Werner Koch * faq.raw (Maintained-by): Removed note that load-extension is not diff --git a/doc/gpg.sgml b/doc/gpg.sgml index 1fa217f6f..efbc9fbaa 100644 --- a/doc/gpg.sgml +++ b/doc/gpg.sgml @@ -1267,6 +1267,15 @@ be older than the key due to clock problems. This option makes these checks just a warning. + +--ignore-valid-from + +GnuPG normally does not select and use subkeys created in the future. This +option allows the use of such keys and thus exhibits the pre-1.0.7 +behaviour. You should not use this option unless you there is some +clock problem. + + --ignore-crc-error diff --git a/g10/ChangeLog b/g10/ChangeLog index 9966c4199..ed3bceb1c 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,17 @@ +2001-08-01 Werner Koch + + * keylist.c (list_keyblock_print): Do not list revoked UIDs unless + in verbose mode and we do no signature listing. + + * getkey.c (finish_lookup): Skip subkeys which are not yet valid. + * g10.c, options.h: New option --ignore-valid-from. + + * sign.c (make_keysig_packet): Added new sigversion argument to + allow the caller to force generation of required signature + version. Changed all callers. Suggested by Thomas Roessler. + * keyedit.c (sign_uids): Force v4 signature generation for local + sigs. Removed the check for local signature and pre-v4 keys. + 2001-07-27 Werner Koch * keyedit.c (sign_uids): Check that we are not trying to to a diff --git a/g10/g10.c b/g10/g10.c index 87f372021..3b5a78ab9 100644 --- a/g10/g10.c +++ b/g10/g10.c @@ -193,6 +193,7 @@ enum cmd_and_opt_values { aNull = 0, oFastListMode, oListOnly, oIgnoreTimeConflict, + oIgnoreValidFrom, oIgnoreCrcError, oShowSessionKey, oOverrideSessionKey, @@ -392,6 +393,7 @@ static ARGPARSE_OPTS opts[] = { { oFixedListMode,"fixed-list-mode", 0, "@" }, { oListOnly, "list-only", 0, "@"}, { oIgnoreTimeConflict, "ignore-time-conflict", 0, "@" }, + { oIgnoreValidFrom, "ignore-valid-from", 0, "@" }, { oIgnoreCrcError, "ignore-crc-error", 0,"@" }, { oShowSessionKey, "show-session-key", 0, "@" }, { oOverrideSessionKey, "override-session-key", 2, "@" }, @@ -973,6 +975,7 @@ main( int argc, char **argv ) case oFixedListMode: opt.fixed_list_mode = 1; break; case oListOnly: opt.list_only=1; break; case oIgnoreTimeConflict: opt.ignore_time_conflict = 1; break; + case oIgnoreValidFrom: opt.ignore_valid_from = 1; break; case oIgnoreCrcError: opt.ignore_crc_error = 1; break; case oNoRandomSeedFile: use_random_seed = 0; break; case oNoAutoKeyRetrieve: opt.auto_key_retrieve = 0; break; diff --git a/g10/getkey.c b/g10/getkey.c index 16306a71a..bb16f91bc 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -1649,7 +1649,7 @@ merge_selfsigs_main( KBNODE keyblock, int *r_revoked ) if ( pk->version >= 4 ) pk->expiredate = key_expire; /* Fixme: we should see how to get rid of the expiretime fields but - * this needs changes at other palces too. */ + * this needs changes at other places too. */ /* and now find the real primary user ID and delete all others */ uiddate = uiddate2 = 0; @@ -2077,6 +2077,7 @@ finish_lookup( GETKEY_CTX ctx, KBNODE foundk ) unsigned int req_usage = ( ctx->req_usage & USAGE_MASK ); u32 latest_date; KBNODE latest_key; + u32 curtime = make_timestamp (); assert( !foundk || foundk->pkt->pkttype == PKT_PUBLIC_KEY || foundk->pkt->pkttype == PKT_PUBLIC_SUBKEY ); @@ -2134,6 +2135,11 @@ finish_lookup( GETKEY_CTX ctx, KBNODE foundk ) log_debug( "\tsubkey has expired\n"); continue; } + if ( pk->timestamp > curtime && !opt.ignore_valid_from ) { + if (DBG_CACHE) + log_debug( "\tsubkey not yet valid\n"); + continue; + } if ( !((pk->pubkey_usage&USAGE_MASK) & req_usage) ) { if (DBG_CACHE) diff --git a/g10/keyedit.c b/g10/keyedit.c index 565e9994e..4f8aa0871 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -282,17 +282,6 @@ sign_uids( KBNODE keyblock, STRLIST locusr, int *ret_modified, int local ) if( rc ) goto leave; - if (local) { - for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) { - if (sk_rover->sk->version < 4) { - tty_printf ("Local only signing not possible " - "due to an old style key\n"); - rc = G10ERR_UNU_SECKEY; - goto leave; - } - } - } - /* loop over all signaturs */ for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) { u32 sk_keyid[2]; @@ -375,11 +364,16 @@ sign_uids( KBNODE keyblock, STRLIST locusr, int *ret_modified, int local ) memset( &attrib, 0, sizeof attrib ); attrib.non_exportable = local; node->flag &= ~NODFLG_MARK_A; + + /* we force createion of a v4 signature for local + * signatures, otherwise we would not generate the + * subpacket with v3 keys and the signature becomes + * exportable */ rc = make_keysig_packet( &sig, primary_pk, node->pkt->pkt.user_id, NULL, sk, - 0x10, 0, + 0x10, 0, local?4:0, sign_mk_attrib, &attrib ); if( rc ) { @@ -1319,7 +1313,7 @@ menu_adduid( KBNODE pub_keyblock, KBNODE sec_keyblock ) sec_where = NULL; assert(pk && sk ); - rc = make_keysig_packet( &sig, pk, uid, NULL, sk, 0x13, 0, + rc = make_keysig_packet( &sig, pk, uid, NULL, sk, 0x13, 0, 0, keygen_add_std_prefs, pk ); free_secret_key( sk ); if( rc ) { @@ -1614,11 +1608,11 @@ menu_expire( KBNODE pub_keyblock, KBNODE sec_keyblock ) /* create new self signature */ if( mainkey ) rc = make_keysig_packet( &newsig, main_pk, uid, NULL, - sk, 0x13, 0, + sk, 0x13, 0, 0, keygen_add_std_prefs, main_pk ); else rc = make_keysig_packet( &newsig, main_pk, NULL, sub_pk, - sk, 0x18, 0, + sk, 0x18, 0, 0, keygen_add_key_expire, sub_pk ); if( rc ) { log_error("make_keysig_packet failed: %s\n", @@ -2058,7 +2052,7 @@ menu_revsig( KBNODE keyblock ) unode->pkt->pkt.user_id, NULL, sk, - 0x30, 0, + 0x30, 0, 0, sign_mk_attrib, &attrib ); free_secret_key(sk); @@ -2120,9 +2114,9 @@ menu_revkey( KBNODE pub_keyblock, KBNODE sec_keyblock ) node->flag &= ~NODFLG_SELKEY; sk = copy_secret_key( NULL, sec_keyblock->pkt->pkt.secret_key ); - rc = make_keysig_packet( &sig, mainpk, NULL, subpk, sk, 0x28, 0, - sign_mk_attrib, - &attrib ); + rc = make_keysig_packet( &sig, mainpk, NULL, subpk, sk, + 0x28, 0, 0, + sign_mk_attrib, &attrib ); free_secret_key(sk); if( rc ) { log_error(_("signing failed: %s\n"), g10_errstr(rc)); diff --git a/g10/keygen.c b/g10/keygen.c index c3e44b553..dad42a690 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -190,7 +190,7 @@ write_selfsig( KBNODE root, KBNODE pub_root, PKT_secret_key *sk ) cache_public_key (pk); /* and make the signature */ - rc = make_keysig_packet( &sig, pk, uid, NULL, sk, 0x13, 0, + rc = make_keysig_packet( &sig, pk, uid, NULL, sk, 0x13, 0, 0, keygen_add_std_prefs, pk ); if( rc ) { log_error("make_keysig_packet failed: %s\n", g10_errstr(rc) ); @@ -235,7 +235,7 @@ write_keybinding( KBNODE root, KBNODE pub_root, PKT_secret_key *sk ) BUG(); /* and make the signature */ - rc = make_keysig_packet( &sig, pk, NULL, subpk, sk, 0x18, 0, + rc = make_keysig_packet( &sig, pk, NULL, subpk, sk, 0x18, 0, 0, keygen_add_key_expire, subpk ); if( rc ) { log_error("make_keysig_packet failed: %s\n", g10_errstr(rc) ); diff --git a/g10/keylist.c b/g10/keylist.c index 62194d823..f445d67b6 100644 --- a/g10/keylist.c +++ b/g10/keylist.c @@ -243,6 +243,12 @@ list_keyblock_print ( KBNODE keyblock, int secret ) for( kbctx=NULL; (node=walk_kbnode( keyblock, &kbctx, 0)) ; ) { if( node->pkt->pkttype == PKT_USER_ID && !opt.fast_list_mode ) { + /* don't list revoked UIDS unless we are in verbose mode and + * signature listing has not been requested */ + if ( !opt.verbose && !opt.list_sigs + && node->pkt->pkt.user_id->is_revoked ) + continue; + if( any ) printf("uid%*s", 28, ""); diff --git a/g10/options.h b/g10/options.h index 567d9201e..e76104fab 100644 --- a/g10/options.h +++ b/g10/options.h @@ -91,6 +91,7 @@ struct { int fast_list_mode; int fixed_list_mode; int ignore_time_conflict; + int ignore_valid_from; int ignore_crc_error; int command_fd; int auto_key_retrieve; diff --git a/g10/packet.h b/g10/packet.h index 05fb24017..3258593d8 100644 --- a/g10/packet.h +++ b/g10/packet.h @@ -402,7 +402,7 @@ int write_comment( IOBUF out, const char *s ); int make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk, PKT_user_id *uid, PKT_public_key *subpk, PKT_secret_key *sk, - int sigclass, int digest_algo, + int sigclass, int digest_algo, int sigversion, int (*mksubpkt)(PKT_signature *, void *), void *opaque ); int update_keysig_packet( PKT_signature **ret_sig, diff --git a/g10/revoke.c b/g10/revoke.c index ef98dc235..7e25aeaa2 100644 --- a/g10/revoke.c +++ b/g10/revoke.c @@ -191,7 +191,7 @@ gen_revoke( const char *uname ) iobuf_push_filter( out, armor_filter, &afx ); /* create it */ - rc = make_keysig_packet( &sig, pk, NULL, NULL, sk, 0x20, 0, + rc = make_keysig_packet( &sig, pk, NULL, NULL, sk, 0x20, 0, 0, revocation_reason_build_cb, reason ); if( rc ) { diff --git a/g10/sign.c b/g10/sign.c index 645d676af..d622abb27 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -793,16 +793,20 @@ clearsign_file( const char *fname, STRLIST locusr, const char *outfile ) /**************** - * Create a signature packet for the given public key certificate - * and the user id and return it in ret_sig. User signature class SIGCLASS - * user-id is not used (and may be NULL if sigclass is 0x20) - * If digest_algo is 0 the function selects an appropriate one. + * Create a signature packet for the given public key certificate and + * the user id and return it in ret_sig. User signature class SIGCLASS + * user-id is not used (and may be NULL if sigclass is 0x20) If + * DIGEST_ALGO is 0 the function selects an appropriate one. + * SIGVERSION gives the minimal required signature packet version; + * this is needed so that special properties like local sign are not + * applied (actually: dropped) when a v3 key is used. */ int make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk, PKT_user_id *uid, PKT_public_key *subpk, PKT_secret_key *sk, int sigclass, int digest_algo, + int sigversion, int (*mksubpkt)(PKT_signature *, void *), void *opaque ) { @@ -813,6 +817,10 @@ make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk, assert( (sigclass >= 0x10 && sigclass <= 0x13) || sigclass == 0x20 || sigclass == 0x18 || sigclass == 0x30 || sigclass == 0x28 ); + + if (sigversion < sk->version) + sigversion = sk->version; + if( !digest_algo ) { switch( sk->pubkey_algo ) { case PUBKEY_ALGO_DSA: digest_algo = DIGEST_ALGO_SHA1; break; @@ -829,7 +837,7 @@ make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk, hash_public_key( md, subpk ); } else if( sigclass != 0x20 ) { - if( sk->version >=4 ) { + if( sigversion >=4 ) { byte buf[5]; buf[0] = 0xb4; /* indicates a userid packet */ buf[1] = uid->len >> 24; /* always use 4 length bytes */ @@ -842,7 +850,7 @@ make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk, } /* and make the signature packet */ sig = m_alloc_clear( sizeof *sig ); - sig->version = sk->version; + sig->version = sigversion; keyid_from_sk( sk, sig->keyid ); sig->pubkey_algo = sk->pubkey_algo; sig->digest_algo = digest_algo;