From 0bb73ee428a257f4acc35c1087ae871cee8437b8 Mon Sep 17 00:00:00 2001 From: David Shaw Date: Sun, 29 Dec 2002 15:58:44 +0000 Subject: [PATCH] * getkey.c (merge_selfsigs_main), main.h, sig-check.c (check_key_signature2): Pass the ultimately trusted pk directly to check_key_signature2 to avoid going through the key selection mechanism. This prevents a deadly embrace when two keys without selfsigs each sign the other. --- g10/ChangeLog | 8 ++++++++ g10/getkey.c | 9 ++++++--- g10/main.h | 2 +- g10/sig-check.c | 23 ++++++++++++++--------- 4 files changed, 29 insertions(+), 13 deletions(-) diff --git a/g10/ChangeLog b/g10/ChangeLog index 798e4ce71..34020c963 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,11 @@ +2002-12-29 David Shaw + + * getkey.c (merge_selfsigs_main), main.h, sig-check.c + (check_key_signature2): Pass the ultimately trusted pk directly to + check_key_signature2 to avoid going through the key selection + mechanism. This prevents a deadly embrace when two keys without + selfsigs each sign the other. + 2002-12-27 David Shaw * keyserver.c (keyserver_refresh): Don't print the "refreshing..." diff --git a/g10/getkey.c b/g10/getkey.c index abc8b2715..0e41f2d7c 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -1571,6 +1571,8 @@ merge_selfsigs_main( KBNODE keyblock, int *r_revoked ) else if ( k->pkt->pkttype == PKT_SIGNATURE && uidnode ) { PKT_signature *sig = k->pkt->pkt.signature; + u32 dummy; + int dum2; if(sig->keyid[0] != kid[0] || sig->keyid[1]!=kid[1]) { @@ -1584,9 +1586,10 @@ merge_selfsigs_main( KBNODE keyblock, int *r_revoked ) trusted key is still valid - if it has been revoked or the user should also renmove the ultimate trust flag. */ - if(get_pubkey_fast(ultimate_pk,sig->keyid)==0 && - check_key_signature(keyblock,k,NULL)==0 && - get_ownertrust(ultimate_pk)==TRUST_ULTIMATE) + if(get_pubkey_fast(ultimate_pk,sig->keyid)==0 + && check_key_signature2(keyblock,k,ultimate_pk, + NULL,&dummy,&dum2)==0 + && get_ownertrust(ultimate_pk)==TRUST_ULTIMATE) { free_public_key(ultimate_pk); pk->is_valid=1; diff --git a/g10/main.h b/g10/main.h index 03d43e112..418653460 100644 --- a/g10/main.h +++ b/g10/main.h @@ -113,7 +113,7 @@ int sign_symencrypt_file (const char *fname, STRLIST locusr); /*-- sig-check.c --*/ int check_revocation_keys (PKT_public_key *pk, PKT_signature *sig); int check_key_signature( KBNODE root, KBNODE node, int *is_selfsig ); -int check_key_signature2( KBNODE root, KBNODE node, +int check_key_signature2( KBNODE root, KBNODE node, PKT_public_key *check_pk, int *is_selfsig, u32 *r_expiredate, int *r_expired ); /*-- delkey.c --*/ diff --git a/g10/sig-check.c b/g10/sig-check.c index c068e4409..6468cf9ea 100644 --- a/g10/sig-check.c +++ b/g10/sig-check.c @@ -475,12 +475,14 @@ check_key_signature( KBNODE root, KBNODE node, int *is_selfsig ) { u32 dummy; int dum2; - return check_key_signature2(root, node, is_selfsig, &dummy, &dum2 ); + return check_key_signature2(root, node, NULL, is_selfsig, &dummy, &dum2 ); } +/* If check_pk is set, then use it to check the signature in node + rather than getting it from root or the keydb. */ int -check_key_signature2( KBNODE root, KBNODE node, int *is_selfsig, - u32 *r_expiredate, int *r_expired ) +check_key_signature2( KBNODE root, KBNODE node, PKT_public_key *check_pk, + int *is_selfsig, u32 *r_expiredate, int *r_expired ) { MD_HANDLE md; PKT_public_key *pk; @@ -595,14 +597,17 @@ check_key_signature2( KBNODE root, KBNODE node, int *is_selfsig, md = md_open( algo, 0 ); hash_public_key( md, pk ); hash_uid_node( unode, md, sig ); - if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] ) { + if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] ) + { if( is_selfsig ) - *is_selfsig = 1; + *is_selfsig = 1; rc = do_check( pk, sig, md, r_expired ); - } - else { - rc = signature_check2( sig, md, r_expiredate, r_expired ); - } + } + else if (check_pk) + rc=do_check(check_pk,sig,md,r_expired); + else + rc = signature_check2( sig, md, r_expiredate, r_expired ); + cache_sig_result ( sig, rc ); md_close(md); }