diff --git a/g10/ChangeLog b/g10/ChangeLog index 6783e603d..c5e9e14f4 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,10 @@ +2002-10-01 Werner Koch + + * getkey.c (get_pubkey_direct): New. + (merge_selfsigs_main): Use it here to look for an ultimately + trusted key. Using the full get_pubkey might lead to an + infinitive recursion. + 2002-09-29 David Shaw * keyserver.c (parse_keyserver_uri): Force the keyserver URI diff --git a/g10/getkey.c b/g10/getkey.c index fab0f6c9a..a123f5fdd 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -371,6 +371,58 @@ get_pubkey( PKT_public_key *pk, u32 *keyid ) } +/* Get a public key and store it into the allocated pk. This function + differs from get_pubkey() in that it does not do a check of the key + to avoid recursion. It should be used only in very certain cases. */ +static int +get_pubkey_direct (PKT_public_key *pk, u32 *keyid) +{ + int rc = 0; + KEYDB_HANDLE hd; + KBNODE keyblock; + + assert (pk); +#if MAX_PK_CACHE_ENTRIES + { /* Try to get it from the cache */ + pk_cache_entry_t ce; + + for (ce = pk_cache; ce; ce = ce->next) + { + if (ce->keyid[0] == keyid[0] && ce->keyid[1] == keyid[1]) + { + if (pk) + copy_public_key (pk, ce->pk); + return 0; + } + } + } +#endif + + hd = keydb_new (0); + rc = keydb_search_kid (hd, keyid); + if (rc == -1) + { + keydb_release (hd); + return G10ERR_NO_PUBKEY; + } + rc = keydb_get_keyblock (hd, &keyblock); + keydb_release (hd); + if (rc) + { + log_error ("keydb_get_keyblock failed: %s\n", g10_errstr(rc)); + return G10ERR_NO_PUBKEY; + } + + assert ( keyblock->pkt->pkttype == PKT_PUBLIC_KEY + || keyblock->pkt->pkttype == PKT_PUBLIC_SUBKEY ); + copy_public_key (pk, keyblock->pkt->pkt.public_key ); + release_kbnode (keyblock); + cache_public_key (pk); + return 0; +} + + + KBNODE get_pubkeyblock( u32 *keyid ) { @@ -1463,7 +1515,13 @@ merge_selfsigs_main( KBNODE keyblock, int *r_revoked ) ultimate_pk=m_alloc_clear(sizeof(*ultimate_pk)); - if(get_pubkey(ultimate_pk,sig->keyid)==0 && + /* We don't want to use the full get_pubkey to + avoid infinite recursion in certain cases. + There is no reason to check that an ultimately + trusted key is still valid - if it has been + revoked or the user should also renmove the + ultimate trust flag. */ + if(get_pubkey_direct(ultimate_pk,sig->keyid)==0 && check_key_signature(keyblock,k,NULL)==0 && get_ownertrust(ultimate_pk)==TRUST_ULTIMATE) {