* getkey.c (get_pubkey_direct): New.
authorWerner Koch <wk@gnupg.org>
Tue, 1 Oct 2002 08:38:24 +0000 (08:38 +0000)
committerWerner Koch <wk@gnupg.org>
Tue, 1 Oct 2002 08:38:24 +0000 (08:38 +0000)
(merge_selfsigs_main): Use it here to look for an ultimately
trusted key.  Using the full get_pubkey might lead to an
infinitive recursion.

g10/ChangeLog
g10/getkey.c

index 6783e60..c5e9e14 100644 (file)
@@ -1,3 +1,10 @@
+2002-10-01  Werner Koch  <wk@gnupg.org>
+
+       * 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  <dshaw@jabberwocky.com>
 
        * keyserver.c (parse_keyserver_uri): Force the keyserver URI
index fab0f6c..a123f5f 100644 (file)
@@ -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)
                      {