gpg: Store key origin info for new keys from a keyserver
authorWerner Koch <wk@gnupg.org>
Mon, 24 Jul 2017 18:47:41 +0000 (20:47 +0200)
committerWerner Koch <wk@gnupg.org>
Mon, 24 Jul 2017 18:47:41 +0000 (20:47 +0200)
* g10/keyserver.c (keyserver_get_chunk): Use KEYORG_KS if request was
done by fingerprint.
* g10/import.c (apply_meta_data): Implement that.

Signed-off-by: Werner Koch <wk@gnupg.org>
g10/import.c
g10/keyserver.c

index e3c8c37..d22c8f4 100644 (file)
@@ -1394,38 +1394,69 @@ apply_meta_data (kbnode_t keyblock, int origin, const char *url)
     {
       if (is_deleted_kbnode (node))
         ;
-      else if (node->pkt->pkttype == PKT_PUBLIC_KEY
-               && (origin == KEYORG_WKD || origin == KEYORG_DANE))
-        {
-          /* For WKD and DANE we insert origin information also for
-           * the key but we don't record the URL because we have have
-           * no use for that: An update using a keyserver has higher
-           * precedence and will thus update this origin info.  For
-           * refresh using WKD or DANE we need to go via the User ID
-           * anyway.  Recall that we are only inserting a new key. */
+      else if (node->pkt->pkttype == PKT_PUBLIC_KEY)
+        {
           PKT_public_key *pk = node->pkt->pkt.public_key;
 
-          pk->keyorg = origin;
-          pk->keyupdate = curtime;
+          if (origin == KEYORG_WKD || origin == KEYORG_DANE)
+            {
+              /* For WKD and DANE we insert origin information also
+               * for the key but we don't record the URL because we
+               * have have no use for that: An update using a
+               * keyserver has higher precedence and will thus update
+               * this origin info.  For refresh using WKD or DANE we
+               * need to go via the User ID anyway.  Recall that we
+               * are only inserting a new key. */
+              pk->keyorg = origin;
+              pk->keyupdate = curtime;
+            }
+          else if (origin == KEYORG_KS && url)
+            {
+              /* If the key was retrieved from a keyserver using a
+               * fingerprint request we add the meta information.
+               * Note that the use of a fingerprint needs to be
+               * enforced by the caller of the import function.  This
+               * is commonly triggered by verifying a modern signature
+               * which has an Issuer Fingerprint signature
+               * subpacket.  */
+              pk->keyorg = origin;
+              pk->keyupdate = curtime;
+              pk->updateurl = xtrystrdup (url);
+              if (!pk->updateurl)
+                return gpg_error_from_syserror ();
+            }
         }
-      else if (node->pkt->pkttype == PKT_USER_ID
-               && (origin == KEYORG_WKD || origin == KEYORG_DANE))
-        {
-          /* We insert origin information on a UID only when we
-           * received them via the Web Key Directory or a DANE record.
-           * The key we receive here from the WKD has been filtered to
-           * contain only the user ID as looked up in the WKD.  For a
-           * DANE origin we this should also be the case.  Thus we
-           * will see here only one user id.  */
+      else if (node->pkt->pkttype == PKT_USER_ID)
+        {
           PKT_user_id *uid = node->pkt->pkt.user_id;
 
-          uid->keyorg = origin;
-          uid->keyupdate = curtime;
-          if (url)
+          if (origin == KEYORG_WKD || origin == KEYORG_DANE)
             {
-              uid->updateurl = xtrystrdup (url);
-              if (!uid->updateurl)
-                return gpg_error_from_syserror ();
+              /* We insert origin information on a UID only when we
+               * received them via the Web Key Directory or a DANE
+               * record.  The key we receive here from the WKD has
+               * been filtered to contain only the user ID as looked
+               * up in the WKD.  For a DANE origin we this should also
+               * be the case.  Thus we will see here only one user
+               * id.  */
+              uid->keyorg = origin;
+              uid->keyupdate = curtime;
+              if (url)
+                {
+                  uid->updateurl = xtrystrdup (url);
+                  if (!uid->updateurl)
+                    return gpg_error_from_syserror ();
+                }
+            }
+          else if (origin == KEYORG_KS && url)
+            {
+              /* If the key was retrieved from a keyserver using a
+               * fingerprint request we mark that also in the user ID.
+               * However we do not store the keyserver URL in the UID.
+               * A later update (merge) from a more trusted source
+               * will replace this info.  */
+              uid->keyorg = origin;
+              uid->keyupdate = curtime;
             }
         }
     }
index 9586448..4d2a2c8 100644 (file)
@@ -1590,11 +1590,12 @@ keyserver_get_chunk (ctrl_t ctrl, KEYDB_SEARCH_DESC *desc, int ndesc,
 {
   gpg_error_t err = 0;
   char **pattern;
-  int idx, npat;
+  int idx, npat, npat_fpr;
   estream_t datastream;
   char *source = NULL;
   size_t linelen;  /* Estimated linelen for KS_GET.  */
   size_t n;
+  int only_fprs;
 
 #define MAX_KS_GET_LINELEN 950  /* Somewhat lower than the real limit.  */
 
@@ -1613,7 +1614,7 @@ keyserver_get_chunk (ctrl_t ctrl, KEYDB_SEARCH_DESC *desc, int ndesc,
      but we are sure that R_NDESC_USED has been updated.  This avoids
      a possible indefinite loop.  */
   linelen = 17; /* "KS_GET --quick --" */
-  for (npat=idx=0; idx < ndesc; idx++)
+  for (npat=npat_fpr=0, idx=0; idx < ndesc; idx++)
     {
       int quiet = 0;
 
@@ -1635,6 +1636,8 @@ keyserver_get_chunk (ctrl_t ctrl, KEYDB_SEARCH_DESC *desc, int ndesc,
                        desc[idx].mode == KEYDB_SEARCH_MODE_FPR20? 20 : 16,
                        pattern[npat]+2);
               npat++;
+              if (desc[idx].mode == KEYDB_SEARCH_MODE_FPR20)
+                npat_fpr++;
             }
         }
       else if(desc[idx].mode == KEYDB_SEARCH_MODE_LONG_KID)
@@ -1716,6 +1719,8 @@ keyserver_get_chunk (ctrl_t ctrl, KEYDB_SEARCH_DESC *desc, int ndesc,
      this is different from NPAT.  */
   *r_ndesc_used = idx;
 
+  only_fprs = (npat && npat == npat_fpr);
+
   err = gpg_dirmngr_ks_get (ctrl, pattern, override_keyserver, quick,
                             &datastream, &source);
   for (idx=0; idx < npat; idx++)
@@ -1747,7 +1752,8 @@ keyserver_get_chunk (ctrl_t ctrl, KEYDB_SEARCH_DESC *desc, int ndesc,
                              (opt.keyserver_options.import_options
                               | IMPORT_NO_SECKEY),
                              keyserver_retrieval_screener, &screenerarg,
-                             0 /* FIXME? */, NULL);
+                             only_fprs? KEYORG_KS : 0,
+                             source);
     }
   es_fclose (datastream);
   xfree (source);