diff --git a/g10/ChangeLog b/g10/ChangeLog index 7db99bc20..a79b1c97c 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,11 @@ +2002-11-12 David Shaw + + * 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 a13baf856..7ae6465aa 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -1834,21 +1834,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 ) { @@ -1857,12 +1842,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