From 365011c8f1cf6d73d44503a65b63ffb5bede8065 Mon Sep 17 00:00:00 2001 From: David Shaw Date: Wed, 13 Nov 2002 13:23:03 +0000 Subject: [PATCH] * keyedit.c (show_key_with_all_names_colon): Make --with-colons --edit display match the validity and trust of --with-colons --list-keys. * passphrase.c (agent_send_all_options): Fix compile warning. * keylist.c (list_keyblock_colon): Validity for subkeys should match that of the primary key, and not that of the last user ID. * getkey.c (merge_selfsigs): Revoked/expired/invalid primary keys carry these facts onto all their subkeys, but only after the subkey has a chance to be marked valid. This is to fix an incorrect "invalid public key" error verifying a signature made by a revoked signing subkey, with a valid unrevoked primary key. --- g10/ChangeLog | 17 ++++++++++++++ g10/getkey.c | 40 +++++++++++++++----------------- g10/keyedit.c | 60 +++++++++++++++++++++++++++++++++++++----------- g10/keylist.c | 12 ++++++---- g10/passphrase.c | 2 +- 5 files changed, 90 insertions(+), 41 deletions(-) diff --git a/g10/ChangeLog b/g10/ChangeLog index 5edc87e9e..3c62bdd04 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,20 @@ +2002-11-13 David Shaw + + * keyedit.c (show_key_with_all_names_colon): Make --with-colons + --edit display match the validity and trust of --with-colons + --list-keys. + + * passphrase.c (agent_send_all_options): Fix compile warning. + + * keylist.c (list_keyblock_colon): Validity for subkeys should + match that of the primary key, and not that of the last user ID. + + * getkey.c (merge_selfsigs): Revoked/expired/invalid primary keys + carry these facts onto all their subkeys, but only after the + subkey has a chance to be marked valid. This is to fix an + incorrect "invalid public key" error verifying a signature made by + a revoked signing subkey, with a valid unrevoked primary key. + 2002-11-09 Werner Koch * passphrase.c (agent_send_all_options): Use tty_get_ttyname to diff --git a/g10/getkey.c b/g10/getkey.c index 6214d8b54..ab296f641 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -1787,21 +1787,6 @@ merge_selfsigs( KBNODE keyblock ) } merge_selfsigs_main ( keyblock, &revoked ); - main_pk = keyblock->pkt->pkt.public_key; - if ( revoked ) { - /* if the primary key has been revoked we better set the revoke - * flag on that key and all subkeys */ - for(k=keyblock; k; k = k->next ) { - if ( k->pkt->pkttype == PKT_PUBLIC_KEY - || k->pkt->pkttype == PKT_PUBLIC_SUBKEY ) { - PKT_public_key *pk = k->pkt->pkt.public_key; - pk->is_revoked = 1; - pk->main_keyid[0] = main_pk->main_keyid[0]; - pk->main_keyid[1] = main_pk->main_keyid[1]; - } - } - return; - } /* now merge in the data from each of the subkeys */ for(k=keyblock; k; k = k->next ) { @@ -1810,12 +1795,25 @@ merge_selfsigs( KBNODE keyblock ) } } - /* If the main key is not valid, then the subkeys aren't either, - even if they have binding sigs. */ - if(!main_pk->is_valid) - for(k=keyblock; k; k=k->next) - if(k->pkt->pkttype==PKT_PUBLIC_SUBKEY) - k->pkt->pkt.public_key->is_valid=0; + main_pk = keyblock->pkt->pkt.public_key; + if ( revoked || main_pk->has_expired || !main_pk->is_valid ) { + /* if the primary key is revoked, expired, or invalid we + * better set the appropriate flags on that key and all + * subkeys */ + for(k=keyblock; k; k = k->next ) { + if ( k->pkt->pkttype == PKT_PUBLIC_KEY + || k->pkt->pkttype == PKT_PUBLIC_SUBKEY ) { + PKT_public_key *pk = k->pkt->pkt.public_key; + if(!main_pk->is_valid) + pk->is_valid = 0; + if(revoked) + pk->is_revoked = 1; + if(main_pk->has_expired) + pk->has_expired = main_pk->has_expired; + } + } + return; + } /* set the preference list of all keys to those of the primary real * user ID. Note: we use these preferences when we don't know by diff --git a/g10/keyedit.c b/g10/keyedit.c index 18e71fae3..b52d8f4d1 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -1698,8 +1698,9 @@ static void show_key_with_all_names_colon (KBNODE keyblock) { KBNODE node; - int i, j; + int i, j, ulti_hack=0; byte pk_version=0; + PKT_public_key *primary=NULL; /* the keys */ for ( node = keyblock; node; node = node->next ) @@ -1708,14 +1709,12 @@ show_key_with_all_names_colon (KBNODE keyblock) || (node->pkt->pkttype == PKT_PUBLIC_SUBKEY) ) { PKT_public_key *pk = node->pkt->pkt.public_key; - int otrust=0, trust=0; u32 keyid[2]; if (node->pkt->pkttype == PKT_PUBLIC_KEY) { - trust = get_validity_info (pk, NULL); - otrust = get_ownertrust_info (pk); pk_version = pk->version; + primary=pk; } keyid_from_pk (pk, keyid); @@ -1727,8 +1726,14 @@ show_key_with_all_names_colon (KBNODE keyblock) putchar ('r'); else if (pk->has_expired) putchar ('e'); - else - putchar (trust); + else if (!(opt.fast_list_mode || opt.no_expensive_trust_checks )) + { + int trust = get_validity_info (pk, NULL); + if(trust=='u') + ulti_hack=1; + putchar (trust); + } + printf (":%u:%d:%08lX%08lX:%lu:%lu:", nbits_from_pk (pk), pk->pubkey_algo, @@ -1738,7 +1743,9 @@ show_key_with_all_names_colon (KBNODE keyblock) if (pk->local_id) printf ("%lu", pk->local_id); putchar (':'); - putchar (otrust); + if (node->pkt->pkttype==PKT_PUBLIC_KEY + && !(opt.fast_list_mode || opt.no_expensive_trust_checks )) + putchar(get_ownertrust_info (pk)); putchar(':'); putchar('\n'); @@ -1771,19 +1778,44 @@ show_key_with_all_names_colon (KBNODE keyblock) if ( node->pkt->pkttype == PKT_USER_ID ) { PKT_user_id *uid = node->pkt->pkt.user_id; - int trustletter = '?'; ++i; + if(uid->attrib_data) - { - printf ("uat:%c::::::::%u %lu", trustletter, - uid->numattribs,uid->attrib_len); - } + printf("uat:"); + else + printf("uid:"); + + if ( uid->is_revoked ) + printf("r::::::::"); + else if ( uid->is_expired ) + printf("e::::::::"); + else if ( opt.fast_list_mode || opt.no_expensive_trust_checks ) + printf("::::::::"); else { - printf ("uid:%c::::::::", trustletter); - print_string (stdout, uid->name, uid->len, ':'); + byte namehash[20]; + int uid_validity; + + if( primary && !ulti_hack ) + { + if( uid->attrib_data ) + rmd160_hash_buffer(namehash, + uid->attrib_data, uid->attrib_len); + else + rmd160_hash_buffer( namehash, uid->name, uid->len ); + uid_validity = get_validity_info( primary, namehash ); + } + else + uid_validity = 'u'; + printf("%c::::::::",uid_validity); } + + if(uid->attrib_data) + printf ("%u %lu",uid->numattribs,uid->attrib_len); + else + print_string (stdout, uid->name, uid->len, ':'); + putchar (':'); /* signature class */ putchar (':'); diff --git a/g10/keylist.c b/g10/keylist.c index afe88265d..c77ec2df5 100644 --- a/g10/keylist.c +++ b/g10/keylist.c @@ -694,7 +694,6 @@ list_keyblock_colon( KBNODE keyblock, int secret, int fpr ) sk = NULL; keyid_from_pk( pk, keyid ); fputs( "pub:", stdout ); - trustletter = 0; if ( !pk->is_valid ) putchar ('i'); else if ( pk->is_revoked ) @@ -755,6 +754,7 @@ list_keyblock_colon( KBNODE keyblock, int secret, int fpr ) } else { byte namehash[20]; + int uid_validity; if( pk && !ulti_hack ) { if( node->pkt->pkt.user_id->attrib_data ) @@ -765,11 +765,11 @@ list_keyblock_colon( KBNODE keyblock, int secret, int fpr ) rmd160_hash_buffer( namehash, node->pkt->pkt.user_id->name, node->pkt->pkt.user_id->len ); - trustletter = get_validity_info( pk, namehash ); + uid_validity = get_validity_info( pk, namehash ); } else - trustletter = 'u'; - printf("%s:%c::::::::",str,trustletter); + uid_validity = 'u'; + printf("%s:%c::::::::",str,uid_validity); } } if(node->pkt->pkt.user_id->attrib_data) @@ -818,7 +818,9 @@ list_keyblock_colon( KBNODE keyblock, int secret, int fpr ) else if ( opt.fast_list_mode || opt.no_expensive_trust_checks ) ; else { - printf("%c", trustletter ); + /* trustletter should always be defined here */ + if(trustletter) + printf("%c", trustletter ); } printf(":%u:%d:%08lX%08lX:%s:%s:", nbits_from_pk( pk2 ), diff --git a/g10/passphrase.c b/g10/passphrase.c index ff733d02a..0b65e2e1c 100644 --- a/g10/passphrase.c +++ b/g10/passphrase.c @@ -346,7 +346,7 @@ static int agent_send_all_options (int fd) { char *dft_display = NULL; - char *dft_ttyname = NULL; + const char *dft_ttyname = NULL; char *dft_ttytype = NULL; char *old_lc = NULL; char *dft_lc = NULL;