gpg: Add new --auto-key-locate mechanism "dane".
authorWerner Koch <wk@gnupg.org>
Tue, 6 Oct 2015 18:31:43 +0000 (20:31 +0200)
committerWerner Koch <wk@gnupg.org>
Tue, 6 Oct 2015 18:31:43 +0000 (20:31 +0200)
* g10/call-dirmngr.c (gpg_dirmngr_dns_cert): Allow fetching via DANE.
* g10/keyserver.c (keyserver_import_cert): Add arg "dane_mode".
* g10/options.h (AKL_DANE): New.
* g10/getkey.c (get_pubkey_byname): Implement AKL_DANE.
(parse_auto_key_locate): Ditto.
--

To test this use

  gpg --auto-key-locate clear,dane,local --locate-key -v wk@gnupg.org

Signed-off-by: Werner Koch <wk@gnupg.org>
doc/gpg.texi
g10/call-dirmngr.c
g10/getkey.c
g10/keyserver-internal.h
g10/keyserver.c
g10/options.h

index 7d78e9e..980d326 100644 (file)
@@ -1463,6 +1463,10 @@ mechanisms, in the order they are to be tried:
   @item pka
   Locate a key using DNS PKA.
 
+  @item dane
+  Locate a key using DANE, as specified
+  in draft-ietf-dane-openpgpkey-05.txt.
+
   @item ldap
   Using DNS Service Discovery, check the domain in question for any LDAP
   keyservers to use.  If this fails, attempt to locate the key using the
index 75cd51d..10dcb20 100644 (file)
@@ -1103,7 +1103,10 @@ dns_cert_status_cb (void *opaque, const char *line)
    CERT record found with a supported type; it is expected that only
    one CERT record is used.  If CERTTYPE is one of the supported
    certtypes, only records with this certtype are considered and the
-   first one found is returned.  All R_* args are optional. */
+   first one found is returned.  All R_* args are optional.
+
+   If CERTTYPE is NULL the DANE method is used to fetch the key.
+ */
 gpg_error_t
 gpg_dirmngr_dns_cert (ctrl_t ctrl, const char *name, const char *certtype,
                       estream_t *r_key,
@@ -1129,7 +1132,7 @@ gpg_dirmngr_dns_cert (ctrl_t ctrl, const char *name, const char *certtype,
   if (err)
     return err;
 
-  line = es_bsprintf ("DNS_CERT %s %s", certtype, name);
+  line = es_bsprintf ("DNS_CERT %s %s", certtype? certtype : "--dane", name);
   if (!line)
     {
       err = gpg_error_from_syserror ();
index ba29c3d..a5f5689 100644 (file)
@@ -898,7 +898,7 @@ get_pubkey_byname (ctrl_t ctrl, GETKEY_CTX * retctx, PKT_public_key * pk,
            case AKL_CERT:
              mechanism = "DNS CERT";
              glo_ctrl.in_auto_key_retrieve++;
-             rc = keyserver_import_cert (ctrl, name, &fpr, &fpr_len);
+             rc = keyserver_import_cert (ctrl, name, 0, &fpr, &fpr_len);
              glo_ctrl.in_auto_key_retrieve--;
              break;
 
@@ -909,6 +909,13 @@ get_pubkey_byname (ctrl_t ctrl, GETKEY_CTX * retctx, PKT_public_key * pk,
              glo_ctrl.in_auto_key_retrieve--;
              break;
 
+           case AKL_DANE:
+             mechanism = "DANE";
+             glo_ctrl.in_auto_key_retrieve++;
+             rc = keyserver_import_cert (ctrl, name, 1, &fpr, &fpr_len);
+             glo_ctrl.in_auto_key_retrieve--;
+             break;
+
            case AKL_LDAP:
              mechanism = "LDAP";
              glo_ctrl.in_auto_key_retrieve++;
@@ -3060,6 +3067,8 @@ parse_auto_key_locate (char *options)
 #endif
       else if (ascii_strcasecmp (tok, "pka") == 0)
        akl->type = AKL_PKA;
+      else if (ascii_strcasecmp (tok, "dane") == 0)
+       akl->type = AKL_DANE;
       else if ((akl->spec = parse_keyserver_uri (tok, 1)))
        akl->type = AKL_SPEC;
       else
index beaa13c..676b4db 100644 (file)
@@ -40,7 +40,7 @@ int keyserver_import_keyid (ctrl_t ctrl, u32 *keyid,
 gpg_error_t keyserver_refresh (ctrl_t ctrl, strlist_t users);
 gpg_error_t keyserver_search (ctrl_t ctrl, strlist_t tokens);
 int keyserver_fetch (ctrl_t ctrl, strlist_t urilist);
-int keyserver_import_cert (ctrl_t ctrl, const char *name,
+int keyserver_import_cert (ctrl_t ctrl, const char *name, int dane_mode,
                            unsigned char **fpr,size_t *fpr_len);
 gpg_error_t keyserver_import_pka (ctrl_t ctrl, const char *name,
                                   unsigned char **fpr,size_t *fpr_len);
index e20c16b..a6257e5 100644 (file)
@@ -1881,30 +1881,34 @@ keyserver_fetch (ctrl_t ctrl, strlist_t urilist)
 }
 
 
-/* Import key in a CERT or pointed to by a CERT */
+/* Import key in a CERT or pointed to by a CERT.  In DANE_MODE fetch
+   the certificate using the DANE method.  */
 int
-keyserver_import_cert (ctrl_t ctrl,
-                       const char *name,unsigned char **fpr,size_t *fpr_len)
+keyserver_import_cert (ctrl_t ctrl, const char *name, int dane_mode,
+                       unsigned char **fpr,size_t *fpr_len)
 {
   gpg_error_t err;
-  char *domain,*look,*url;
+  char *look,*url;
   estream_t key;
 
+  look = xstrdup(name);
 
-  look=xstrdup(name);
-
-  domain=strrchr(look,'@');
-  if(domain)
-    *domain='.';
+  if (!dane_mode)
+    {
+      char *domain = strrchr (look,'@');
+      if (domain)
+        *domain='.';
+    }
 
-  err = gpg_dirmngr_dns_cert (ctrl, look, "*", &key, fpr, fpr_len, &url);
+  err = gpg_dirmngr_dns_cert (ctrl, look, dane_mode? NULL : "*",
+                              &key, fpr, fpr_len, &url);
   if (err)
     ;
   else if (key)
     {
       int armor_status=opt.no_armor;
 
-      /* CERTs are always in binary format */
+      /* CERTs and DANE records are always in binary format */
       opt.no_armor=1;
 
       err = import_keys_es_stream (ctrl, key, NULL, fpr, fpr_len,
index fd2f4a2..f5b23dd 100644 (file)
@@ -240,6 +240,7 @@ struct
       AKL_LOCAL,
       AKL_CERT,
       AKL_PKA,
+      AKL_DANE,
       AKL_LDAP,
       AKL_KEYSERVER,
       AKL_SPEC