aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2015-10-06 18:31:43 +0000
committerWerner Koch <[email protected]>2015-10-06 18:31:43 +0000
commit9ac31f91b10059474da1c9580fb99e94278d4c11 (patch)
tree04f6667ad289aa69cb2b0b1e0ef01f3eed398863
parentdirmngr: Addlow fetching keys using OpenPGP DANE (diff)
downloadgnupg-9ac31f91b10059474da1c9580fb99e94278d4c11.tar.gz
gnupg-9ac31f91b10059474da1c9580fb99e94278d4c11.zip
gpg: Add new --auto-key-locate mechanism "dane".
* 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 [email protected] Signed-off-by: Werner Koch <[email protected]>
-rw-r--r--doc/gpg.texi4
-rw-r--r--g10/call-dirmngr.c7
-rw-r--r--g10/getkey.c11
-rw-r--r--g10/keyserver-internal.h2
-rw-r--r--g10/keyserver.c26
-rw-r--r--g10/options.h1
6 files changed, 36 insertions, 15 deletions
diff --git a/doc/gpg.texi b/doc/gpg.texi
index 7d78e9e3e..980d32643 100644
--- a/doc/gpg.texi
+++ b/doc/gpg.texi
@@ -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
diff --git a/g10/call-dirmngr.c b/g10/call-dirmngr.c
index 75cd51d4e..10dcb2009 100644
--- a/g10/call-dirmngr.c
+++ b/g10/call-dirmngr.c
@@ -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 ();
diff --git a/g10/getkey.c b/g10/getkey.c
index ba29c3dca..a5f568956 100644
--- a/g10/getkey.c
+++ b/g10/getkey.c
@@ -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
diff --git a/g10/keyserver-internal.h b/g10/keyserver-internal.h
index beaa13c51..676b4dbbf 100644
--- a/g10/keyserver-internal.h
+++ b/g10/keyserver-internal.h
@@ -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);
diff --git a/g10/keyserver.c b/g10/keyserver.c
index e20c16b08..a6257e539 100644
--- a/g10/keyserver.c
+++ b/g10/keyserver.c
@@ -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,
diff --git a/g10/options.h b/g10/options.h
index fd2f4a2f6..f5b23dd18 100644
--- a/g10/options.h
+++ b/g10/options.h
@@ -240,6 +240,7 @@ struct
AKL_LOCAL,
AKL_CERT,
AKL_PKA,
+ AKL_DANE,
AKL_LDAP,
AKL_KEYSERVER,
AKL_SPEC