From 9ac31f91b10059474da1c9580fb99e94278d4c11 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 6 Oct 2015 20:31:43 +0200 Subject: [PATCH] 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 wk@gnupg.org Signed-off-by: Werner Koch --- doc/gpg.texi | 4 ++++ g10/call-dirmngr.c | 7 +++++-- g10/getkey.c | 11 ++++++++++- g10/keyserver-internal.h | 2 +- g10/keyserver.c | 26 +++++++++++++++----------- g10/options.h | 1 + 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); + if (!dane_mode) + { + char *domain = strrchr (look,'@'); + if (domain) + *domain='.'; + } - 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