From 1aec20776c0568c71aac299feb5519facc80348f Mon Sep 17 00:00:00 2001 From: David Shaw Date: Wed, 4 Dec 2002 18:50:10 +0000 Subject: [PATCH] * main.h, keyedit.c, keygen.c: Back out previous (2002-12-01) change. Minimal isn't always best. * sign.c (update_keysig_packet): Use the current time rather then a modification of the original signature time. Make sure that this doesn't cause a time warp. * keygen.c (keygen_add_key_expire): Properly handle a key expiration date in the past (use a duration of 0). * keyedit.c (menu_expire): Use update_keysig_packet so any sig subpackets are maintained during the update. * build-packet.c (build_sig_subpkt): Mark sig expired or unexpired when the sig expiration subpacket is added. (build_sig_subpkt_from_sig): Handle making an expiration subpacket from a sig that has already expired (use a duration of 0). * packet.h, sign.c (update_keysig_packet), keyedit.c (menu_set_primary_uid, menu_set_preferences): Add ability to issue 0x18 subkey binding sigs to update_keysig_packet and change all callers. --- g10/ChangeLog | 25 +++++++++++++++++- g10/build-packet.c | 15 ++++++++++- g10/keyedit.c | 20 +++++---------- g10/keygen.c | 63 ++++++++++++++++------------------------------ g10/main.h | 7 +----- g10/packet.h | 3 ++- g10/sign.c | 49 +++++++++++++++++++++++++----------- 7 files changed, 104 insertions(+), 78 deletions(-) diff --git a/g10/ChangeLog b/g10/ChangeLog index a4bd26830..f80dc6b7e 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,7 +1,30 @@ 2002-12-04 David Shaw + * main.h, keyedit.c, keygen.c: Back out previous (2002-12-01) + change. Minimal isn't always best. + + * sign.c (update_keysig_packet): Use the current time rather then + a modification of the original signature time. Make sure that + this doesn't cause a time warp. + + * keygen.c (keygen_add_key_expire): Properly handle a key + expiration date in the past (use a duration of 0). + + * keyedit.c (menu_expire): Use update_keysig_packet so any sig + subpackets are maintained during the update. + + * build-packet.c (build_sig_subpkt): Mark sig expired or unexpired + when the sig expiration subpacket is added. + (build_sig_subpkt_from_sig): Handle making an expiration subpacket + from a sig that has already expired (use a duration of 0). + + * packet.h, sign.c (update_keysig_packet), keyedit.c + (menu_set_primary_uid, menu_set_preferences): Add ability to issue + 0x18 subkey binding sigs to update_keysig_packet and change all + callers. + * trustdb.c (validate_keys): Show trust parameters when building - trustdb, and make sure that the version record update was + the trustdb, and make sure that the version record update was successful. (init_trustdb): If the current parameters aren't what was used for building the trustdb, the trustdb is invalid. diff --git a/g10/build-packet.c b/g10/build-packet.c index d0122b1b0..269cca304 100644 --- a/g10/build-packet.c +++ b/g10/build-packet.c @@ -763,6 +763,15 @@ build_sig_subpkt (PKT_signature *sig, sigsubpkttype_t type, sig->trust_regexp=buffer; break; + /* This should never happen since we don't currently allow + creating such a subpacket, but just in case... */ + case SIGSUBPKT_SIG_EXPIRE: + if(buffer_to_u32(buffer)+sig->timestamp<=make_timestamp()) + sig->flags.expired=1; + else + sig->flags.expired=0; + break; + default: break; } @@ -869,7 +878,11 @@ build_sig_subpkt_from_sig( PKT_signature *sig ) if(sig->expiredate) { - u = sig->expiredate-sig->timestamp; + if(sig->expiredate>sig->timestamp) + u=sig->expiredate-sig->timestamp; + else + u=0; + buf[0] = (u >> 24) & 0xff; buf[1] = (u >> 16) & 0xff; buf[2] = (u >> 8) & 0xff; diff --git a/g10/keyedit.c b/g10/keyedit.c index 8373a7f2c..e25debf90 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -2694,20 +2694,12 @@ menu_expire( KBNODE pub_keyblock, KBNODE sec_keyblock ) if( !sn ) log_info(_("No corresponding signature in secret ring\n")); - /* create new self signature */ if( mainkey ) - rc = make_keysig_packet( &newsig, main_pk, uid, NULL, - sk, 0x13, 0, 0, 0, 0, - keygen_add_std_prefs, main_pk ); + rc = update_keysig_packet(&newsig, sig, main_pk, uid, NULL, + sk, keygen_add_key_expire, main_pk); else - { - struct flags_expire fe; - fe.pk=sub_pk; - fe.sig=sig; - rc = make_keysig_packet( &newsig, main_pk, NULL, sub_pk, - sk, 0x18, 0, 0, 0, 0, - keygen_copy_flags_add_expire,&fe); - } + rc = update_keysig_packet(&newsig, sig, main_pk, NULL, sub_pk, + sk, keygen_add_key_expire, sub_pk ); if( rc ) { log_error("make_keysig_packet failed: %s\n", g10_errstr(rc)); @@ -2852,7 +2844,7 @@ menu_set_primary_uid ( KBNODE pub_keyblock, KBNODE sec_keyblock ) if (action) { int rc = update_keysig_packet (&newsig, sig, - main_pk, uid, + main_pk, uid, NULL, sk, change_primary_uid_cb, action > 0? "x":NULL ); @@ -2937,7 +2929,7 @@ menu_set_preferences (KBNODE pub_keyblock, KBNODE sec_keyblock ) int rc; rc = update_keysig_packet (&newsig, sig, - main_pk, uid, + main_pk, uid, NULL, sk, keygen_upd_std_prefs, NULL ); diff --git a/g10/keygen.c b/g10/keygen.c index aa30b4d6b..24ba95fb9 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -143,56 +143,37 @@ do_add_key_flags (PKT_signature *sig, unsigned int use) build_sig_subpkt (sig, SIGSUBPKT_KEY_FLAGS, buf, 1); } -static void -do_copy_key_flags (PKT_signature *sig, PKT_signature *oldsig) -{ - const byte *f; - size_t n; - - /* Note that this will make any key flags in the unhashed area - disappear. This may be good or bad, depending on your point of - view. */ - f=parse_sig_subpkt(oldsig->hashed,SIGSUBPKT_KEY_FLAGS,&n); - if(f) - build_sig_subpkt(sig,SIGSUBPKT_KEY_FLAGS,f,n); -} - -static void -do_add_key_expire( PKT_signature *sig, PKT_public_key *pk ) -{ - if( pk->expiredate ) - { - byte buf[4]; - u32 u; - - u = pk->expiredate > pk->timestamp? pk->expiredate - pk->timestamp - : pk->timestamp; - buf[0] = (u >> 24) & 0xff; - buf[1] = (u >> 16) & 0xff; - buf[2] = (u >> 8) & 0xff; - buf[3] = u & 0xff; - build_sig_subpkt( sig, SIGSUBPKT_KEY_EXPIRE, buf, 4 ); - } -} int -keygen_copy_flags_add_expire( PKT_signature *sig, void *opaque ) +keygen_add_key_expire( PKT_signature *sig, void *opaque ) { - struct flags_expire *fe=opaque; - do_add_key_expire(sig,fe->pk); - do_copy_key_flags(sig,fe->sig); + PKT_public_key *pk = opaque; + byte buf[8]; + u32 u; - return 0; + if( pk->expiredate ) { + if(pk->expiredate > pk->timestamp) + u= pk->expiredate - pk->timestamp; + else + u= 0; + + buf[0] = (u >> 24) & 0xff; + buf[1] = (u >> 16) & 0xff; + buf[2] = (u >> 8) & 0xff; + buf[3] = u & 0xff; + build_sig_subpkt( sig, SIGSUBPKT_KEY_EXPIRE, buf, 4 ); + } + + return 0; } static int keygen_add_key_flags_and_expire (PKT_signature *sig, void *opaque) { - struct opaque_data_usage_and_pk *oduap = opaque; + struct opaque_data_usage_and_pk *oduap = opaque; - do_add_key_flags (sig, oduap->usage); - do_add_key_expire(sig,oduap->pk); - return 0; + do_add_key_flags (sig, oduap->usage); + return keygen_add_key_expire (sig, oduap->pk); } static int @@ -511,7 +492,7 @@ keygen_add_std_prefs( PKT_signature *sig, void *opaque ) byte buf[8]; do_add_key_flags (sig, pk->pubkey_usage); - do_add_key_expire (sig, pk); + keygen_add_key_expire( sig, opaque ); keygen_upd_std_prefs (sig, opaque); buf[0] = 0x80; /* no modify - It is reasonable that a key holder diff --git a/g10/main.h b/g10/main.h index 94ee0df9f..03d43e112 100644 --- a/g10/main.h +++ b/g10/main.h @@ -130,12 +130,7 @@ u32 ask_expiredate(void); void generate_keypair( const char *fname ); int keygen_set_std_prefs (const char *string,int personal); PKT_user_id *keygen_get_std_prefs (void); -struct flags_expire -{ - PKT_public_key *pk; - PKT_signature *sig; -}; -int keygen_copy_flags_add_expire( PKT_signature *sig, void *opaque ); +int keygen_add_key_expire( PKT_signature *sig, void *opaque ); int keygen_add_std_prefs( PKT_signature *sig, void *opaque ); int keygen_upd_std_prefs( PKT_signature *sig, void *opaque ); int keygen_add_revkey(PKT_signature *sig, void *opaque); diff --git a/g10/packet.h b/g10/packet.h index c3dc0c7ab..00b7d2b14 100644 --- a/g10/packet.h +++ b/g10/packet.h @@ -490,7 +490,8 @@ int make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk, int update_keysig_packet( PKT_signature **ret_sig, PKT_signature *orig_sig, PKT_public_key *pk, - PKT_user_id *uid, + PKT_user_id *uid, + PKT_public_key *subpk, PKT_secret_key *sk, int (*mksubpkt)(PKT_signature *, void *), void *opaque ); diff --git a/g10/sign.c b/g10/sign.c index 524205228..c08b98a63 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -1264,6 +1264,7 @@ update_keysig_packet( PKT_signature **ret_sig, PKT_signature *orig_sig, PKT_public_key *pk, PKT_user_id *uid, + PKT_public_key *subpk, PKT_secret_key *sk, int (*mksubpkt)(PKT_signature *, void *), void *opaque @@ -1273,32 +1274,52 @@ update_keysig_packet( PKT_signature **ret_sig, int rc=0; MD_HANDLE md; - if (!orig_sig || !pk || !uid || !sk) - return G10ERR_GENERAL; - if (orig_sig->sig_class < 0x10 || orig_sig->sig_class > 0x13 ) - return G10ERR_GENERAL; + if ((!orig_sig || !pk || !sk) + || (orig_sig->sig_class >= 0x10 && orig_sig->sig_class <= 0x13 && !uid) + || (orig_sig->sig_class == 0x18 && !subpk)) + return G10ERR_GENERAL; md = md_open( orig_sig->digest_algo, 0 ); /* hash the public key certificate and the user id */ hash_public_key( md, pk ); - hash_uid (md, orig_sig->version, uid); + + if( orig_sig->sig_class == 0x18 ) + hash_public_key( md, subpk ); + else + hash_uid (md, orig_sig->version, uid); /* create a new signature packet */ sig = copy_signature (NULL, orig_sig); - if ( sig->version >= 4 && mksubpkt) - rc = (*mksubpkt)(sig, opaque); - /* we increase the timestamp by one second so that a future import - of this key will replace the existing one. We also make sure that - we don't create a timestamp in the future */ - sig->timestamp++; - while (sig->timestamp >= make_timestamp()) - sleep (1); - /* put the updated timestamp back into the data */ + /* We need to create a new timestamp so that new sig expiration + calculations are done correctly... */ + sig->timestamp=make_timestamp(); + + /* ... but we won't make a timestamp earlier than the existing + one. */ + while(sig->timestamp<=orig_sig->timestamp) + { + sleep(1); + sig->timestamp=make_timestamp(); + } + + /* Note that already expired sigs will remain expired (with a + duration of 0) since build-packet.c:build_sig_subpkt_from_sig + detects this case. */ + if( sig->version >= 4 ) + { + /* Put the updated timestamp into the sig. Note that this + will automagically lower any sig expiration dates to + correctly correspond to the differences in the timestamps + (i.e. the duration will shrink). */ build_sig_subpkt_from_sig( sig ); + if (mksubpkt) + rc = (*mksubpkt)(sig, opaque); + } + if (!rc) { hash_sigversion_to_magic (md, sig); md_final(md);