gpg: Copy the correct digest for use by TOFU.
[gnupg.git] / g10 / keyserver.c
index e9de496..2e2d6a4 100644 (file)
@@ -24,7 +24,6 @@
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
-#include <assert.h>
 #include <errno.h>
 
 #include "gpg.h"
@@ -109,8 +108,7 @@ static gpg_error_t keyserver_get (ctrl_t ctrl,
                                   KEYDB_SEARCH_DESC *desc, int ndesc,
                                   struct keyserver_spec *override_keyserver,
                                   unsigned char **r_fpr, size_t *r_fprlen);
-static gpg_error_t keyserver_put (ctrl_t ctrl, strlist_t keyspecs,
-                                  struct keyserver_spec *keyserver);
+static gpg_error_t keyserver_put (ctrl_t ctrl, strlist_t keyspecs);
 
 
 /* Reasonable guess.  The commonly used test key simon.josefsson.org
@@ -242,13 +240,13 @@ parse_keyserver_uri (const char *string,int require_scheme)
   struct keyserver_spec *keyserver;
   const char *idx;
   int count;
-  char *uri,*options;
+  char *uri, *duped_uri, *options;
 
-  assert(string!=NULL);
+  log_assert (string);
 
   keyserver=xmalloc_clear(sizeof(struct keyserver_spec));
 
-  uri=xstrdup(string);
+  duped_uri = uri = xstrdup (string);
 
   options=strchr(uri,' ');
   if(options)
@@ -436,11 +434,13 @@ parse_keyserver_uri (const char *string,int require_scheme)
       goto fail;
     }
 
+  xfree (duped_uri);
   return keyserver;
 
  fail:
   free_keyserver_spec(keyserver);
 
+  xfree (duped_uri);
   return NULL;
 }
 
@@ -1005,7 +1005,7 @@ keyserver_export (ctrl_t ctrl, strlist_t users)
 
   if(sl)
     {
-      rc = keyserver_put (ctrl, sl, opt.keyserver);
+      rc = keyserver_put (ctrl, sl);
       free_strlist(sl);
     }
 
@@ -1132,6 +1132,14 @@ keyserver_import (ctrl_t ctrl, strlist_t users)
 }
 
 
+/* Return true if any keyserver has been configured. */
+int
+keyserver_any_configured (ctrl_t ctrl)
+{
+  return !gpg_dirmngr_ks_list (ctrl, NULL);
+}
+
+
 /* Import all keys that exactly match NAME */
 int
 keyserver_import_name (ctrl_t ctrl, const char *name,
@@ -1346,7 +1354,10 @@ keyidlist(strlist_t users,KEYDB_SEARCH_DESC **klist,int *count,int fakev3)
 
  leave:
   if(rc)
-    xfree(*klist);
+    {
+      xfree(*klist);
+      *klist = NULL;
+    }
   xfree(desc);
   keydb_release(kdbhd);
   release_kbnode(keyblock);
@@ -1377,7 +1388,12 @@ keyserver_refresh (ctrl_t ctrl, strlist_t users)
   opt.keyserver_options.import_options|=IMPORT_FAST;
 
   /* If refresh_add_fake_v3_keyids is on and it's a HKP or MAILTO
-     scheme, then enable fake v3 keyid generation. */
+     scheme, then enable fake v3 keyid generation.  Note that this
+     works only with a keyserver configured. gpg.conf
+     (i.e. opt.keyserver); however that method of configuring a
+     keyserver is deprecated and in any case it is questionable
+     whether we should keep on supporting these ancient and broken
+     keyservers.  */
   if((opt.keyserver_options.options&KEYSERVER_ADD_FAKE_V3) && opt.keyserver
      && (ascii_strcasecmp(opt.keyserver->scheme,"hkp")==0 ||
         ascii_strcasecmp(opt.keyserver->scheme,"mailto")==0))
@@ -1400,7 +1416,7 @@ keyserver_refresh (ctrl_t ctrl, strlist_t users)
              struct keyserver_spec *keyserver=desc[i].skipfncvalue;
 
               if (!opt.quiet)
-                log_info (_("refreshing 1 key from %s\n"), keyserver->uri);
+                log_info (_("refreshing %d key from %s\n"), 1, keyserver->uri);
 
              /* We use the keyserver structure we parsed out before.
                 Note that a preferred keyserver without a scheme://
@@ -1433,10 +1449,9 @@ keyserver_refresh (ctrl_t ctrl, strlist_t users)
         {
           if (!opt.quiet)
             {
-              if(count==1)
-                log_info(_("refreshing 1 key from %s\n"), tmpuri);
-              else
-                log_info(_("refreshing %d keys from %s\n"), count, tmpuri);
+              log_info (ngettext("refreshing %d key from %s\n",
+                                 "refreshing %d keys from %s\n",
+                                 count), count, tmpuri);
             }
           xfree (tmpuri);
 
@@ -1451,7 +1466,7 @@ keyserver_refresh (ctrl_t ctrl, strlist_t users)
   /* If the original options didn't have fast import, and the trustdb
      is dirty, rebuild. */
   if(!(opt.keyserver_options.import_options&IMPORT_FAST))
-    check_or_update_trustdb ();
+    check_or_update_trustdb (ctrl);
 
   return err;
 }
@@ -1563,7 +1578,7 @@ keyserver_search (ctrl_t ctrl, strlist_t tokens)
 static gpg_error_t
 keyserver_get_chunk (ctrl_t ctrl, KEYDB_SEARCH_DESC *desc, int ndesc,
                      int *r_ndesc_used,
-                     void *stats_handle,
+                     import_stats_t stats_handle,
                      struct keyserver_spec *override_keyserver,
                      unsigned char **r_fpr, size_t *r_fprlen)
 
@@ -1746,7 +1761,7 @@ keyserver_get (ctrl_t ctrl, KEYDB_SEARCH_DESC *desc, int ndesc,
                unsigned char **r_fpr, size_t *r_fprlen)
 {
   gpg_error_t err;
-  void *stats_handle;
+  import_stats_t stats_handle;
   int ndesc_used;
   int any_good = 0;
 
@@ -1773,21 +1788,21 @@ keyserver_get (ctrl_t ctrl, KEYDB_SEARCH_DESC *desc, int ndesc,
 }
 
 
-/* Send all keys specified by KEYSPECS to the KEYSERVERS.  */
+/* Send all keys specified by KEYSPECS to the configured keyserver.  */
 static gpg_error_t
-keyserver_put (ctrl_t ctrl, strlist_t keyspecs,
-               struct keyserver_spec *keyserver)
+keyserver_put (ctrl_t ctrl, strlist_t keyspecs)
 
 {
   gpg_error_t err;
   strlist_t kspec;
+  char *ksurl;
 
   if (!keyspecs)
     return 0;  /* Return success if the list is empty.  */
 
-  if (!opt.keyserver)
+  if (gpg_dirmngr_ks_list (ctrl, &ksurl))
     {
-      log_error (_("no keyserver known (use option --keyserver)\n"));
+      log_error (_("no keyserver known\n"));
       return gpg_error (GPG_ERR_NO_KEYSERVER);
     }
 
@@ -1805,14 +1820,9 @@ keyserver_put (ctrl_t ctrl, strlist_t keyspecs,
         log_error (_("skipped \"%s\": %s\n"), kspec->d, gpg_strerror (err));
       else
         {
-          if (keyserver->host)
-            log_info (_("sending key %s to %s server %s\n"),
-                      keystr (keyblock->pkt->pkt.public_key->keyid),
-                      keyserver->scheme, keyserver->host);
-          else
-            log_info (_("sending key %s to %s\n"),
-                      keystr (keyblock->pkt->pkt.public_key->keyid),
-                      keyserver->uri);
+          log_info (_("sending key %s to %s\n"),
+                    keystr (keyblock->pkt->pkt.public_key->keyid),
+                    ksurl?ksurl:"[?]");
 
           err = gpg_dirmngr_ks_put (ctrl, data, datalen, keyblock);
           release_kbnode (keyblock);
@@ -1825,6 +1835,7 @@ keyserver_put (ctrl_t ctrl, strlist_t keyspecs,
         }
     }
 
+  xfree (ksurl);
 
   return err;
 
@@ -1832,7 +1843,7 @@ keyserver_put (ctrl_t ctrl, strlist_t keyspecs,
 
 
 /* Loop over all URLs in STRLIST and fetch the key at that URL.  Note
-   that the fetch operation ignores the configured key servers and
+   that the fetch operation ignores the configured keyservers and
    instead directly retrieves the keys.  */
 int
 keyserver_fetch (ctrl_t ctrl, strlist_t urilist)
@@ -1855,7 +1866,7 @@ keyserver_fetch (ctrl_t ctrl, strlist_t urilist)
       err = gpg_dirmngr_ks_fetch (ctrl, sl->d, &datastream);
       if (!err)
         {
-          void *stats_handle;
+          import_stats_t stats_handle;
 
           stats_handle = import_new_stats_handle();
           import_keys_es_stream (ctrl, datastream, stats_handle, NULL, NULL,
@@ -1876,7 +1887,7 @@ keyserver_fetch (ctrl_t ctrl, strlist_t urilist)
   /* If the original options didn't have fast import, and the trustdb
      is dirty, rebuild. */
   if (!(opt.keyserver_options.import_options&IMPORT_FAST))
-    check_or_update_trustdb ();
+    check_or_update_trustdb (ctrl);
 
   return 0;
 }
@@ -1938,15 +1949,15 @@ keyserver_import_cert (ctrl_t ctrl, const char *name, int dane_mode,
              free_keyserver_spec(spec);
            }
        }
-      else if(opt.keyserver)
+      else if (keyserver_any_configured (ctrl))
        {
          /* If only a fingerprint is provided, try and fetch it from
-            our --keyserver */
+            the configured keyserver. */
 
          err = keyserver_import_fprint (ctrl, *fpr,*fpr_len,opt.keyserver);
        }
       else
-       log_info(_("no keyserver known (use option --keyserver)\n"));
+       log_info(_("no keyserver known\n"));
 
       /* Give a better string here? "CERT fingerprint for \"%s\"
         found, but no keyserver" " known (use option
@@ -1994,6 +2005,39 @@ keyserver_import_pka (ctrl_t ctrl, const char *name,
 }
 
 
+/* Import a key using the Web Key Directory protocol.  */
+gpg_error_t
+keyserver_import_wkd (ctrl_t ctrl, const char *name,
+                      unsigned char **fpr, size_t *fpr_len)
+{
+  gpg_error_t err;
+  estream_t key;
+
+  err = gpg_dirmngr_wkd_get (ctrl, name, &key);
+  if (err)
+    ;
+  else if (key)
+    {
+      int armor_status = opt.no_armor;
+
+      /* Keys returned via WKD are in binary format. */
+      opt.no_armor = 1;
+
+      err = import_keys_es_stream (ctrl, key, NULL, fpr, fpr_len,
+                                   (opt.keyserver_options.import_options
+                                    | IMPORT_NO_SECKEY),
+                                   NULL, NULL);
+
+      opt.no_armor = armor_status;
+
+      es_fclose (key);
+      key = NULL;
+    }
+
+  return err;
+}
+
+
 /* Import a key by name using LDAP */
 int
 keyserver_import_ldap (ctrl_t ctrl,