dirmngr: Improve DNS code to retrieve arbitrary records.

* dirmngr/dns-cert.c (get_dns_cert): Add hack to retrieve arbitrary
resource records.
* dirmngr/dns-cert.h (DNS_CERTTYPE_RRBASE): New.
(DNS_CERTTYPE_RR61): New.
--

This has been tested with ADNS on Unix and with the standard
resolver.  Because ADNS works it should also work on Windows.

Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
Werner Koch 2015-10-06 19:57:00 +02:00
parent 6cf80dc77e
commit 211b8084ee
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
2 changed files with 55 additions and 4 deletions

View File

@ -99,7 +99,11 @@ get_dns_cert (const char *name, int want_certtype,
return err;
}
if (adns_synchronous (state, name, (adns_r_unknown | my_adns_r_cert),
if (adns_synchronous (state, name,
(adns_r_unknown
| (want_certtype < DNS_CERTTYPE_RRBASE
? my_adns_r_cert
: (want_certtype - DNS_CERTTYPE_RRBASE))),
adns_qf_quoteok_query, &answer))
{
err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
@ -122,6 +126,26 @@ get_dns_cert (const char *name, int want_certtype,
int datalen = answer->rrs.byteblock[count].len;
const unsigned char *data = answer->rrs.byteblock[count].data;
/* First check for our generic RR hack. */
if (datalen
&& want_certtype >= DNS_CERTTYPE_RRBASE
&& ((want_certtype - DNS_CERTTYPE_RRBASE)
== (answer->type & ~adns_r_unknown)))
{
/* Found the requested record - return it. */
*r_key = xtrymalloc (datalen);
if (!*r_key)
err = gpg_err_make (default_errsource,
gpg_err_code_from_syserror ());
else
{
memcpy (*r_key, data, datalen);
*r_keylen = datalen;
err = 0;
}
goto leave;
}
if (datalen < 5)
continue; /* Truncated CERT record - skip. */
@ -219,7 +243,11 @@ get_dns_cert (const char *name, int want_certtype,
err = gpg_err_make (default_errsource, GPG_ERR_NOT_FOUND);
r = res_query (name, C_IN, T_CERT, answer, 65536);
r = res_query (name, C_IN,
(want_certtype < DNS_CERTTYPE_RRBASE
? T_CERT
: (want_certtype - DNS_CERTTYPE_RRBASE)),
answer, 65536);
/* Not too big, not too small, no errors and at least 1 answer. */
if (r >= sizeof (HEADER) && r <= 65536
&& (((HEADER *) answer)->rcode) == NOERROR
@ -283,7 +311,28 @@ get_dns_cert (const char *name, int want_certtype,
pt += 2;
/* Check the type and parse. */
if (type == T_CERT)
if (want_certtype >= DNS_CERTTYPE_RRBASE
&& type == (want_certtype - DNS_CERTTYPE_RRBASE)
&& r_key)
{
*r_key = xtrymalloc (dlen);
if (!*r_key)
err = gpg_err_make (default_errsource,
gpg_err_code_from_syserror ());
else
{
memcpy (*r_key, pt, dlen);
*r_keylen = dlen;
err = 0;
}
goto leave;
}
else if (want_certtype >= DNS_CERTTYPE_RRBASE)
{
/* We did not found the requested RR. */
pt += dlen;
}
else if (type == T_CERT)
{
/* We got a CERT type. */
ctype = buf16_to_u16 (pt);

View File

@ -43,7 +43,9 @@
#define DNS_CERTTYPE_IACPKIX 8 /* The URL of an Attribute Certificate. */
#define DNS_CERTTYPE_URI 253 /* URI private. */
#define DNS_CERTTYPE_OID 254 /* OID private. */
/* Hacks for our implementation. */
#define DNS_CERTTYPE_RRBASE 1024 /* Base of special constants. */
#define DNS_CERTTYPE_RR61 (DNS_CERTTYPE_RRBASE + 61)
gpg_error_t get_dns_cert (const char *name, int want_certtype,
void **r_key, size_t *r_keylen,