From 6f717d0817573a76c3e586eae02793d8b23a0581 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 29 Dec 2015 19:09:14 +0100 Subject: resolved: include GOST in list of DNSSEC algorithms We don't implement it, and we have no intention to, but at least mention that it exists. (This also adds a couple of other algorithms to the algorithm string list, where these strings were missing previously.) --- src/resolve/resolved-dns-rr.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src/resolve/resolved-dns-rr.h') diff --git a/src/resolve/resolved-dns-rr.h b/src/resolve/resolved-dns-rr.h index fccc4dba6a..317be0efbe 100644 --- a/src/resolve/resolved-dns-rr.h +++ b/src/resolve/resolved-dns-rr.h @@ -51,8 +51,9 @@ enum { DNSSEC_ALGORITHM_RSASHA1, DNSSEC_ALGORITHM_DSA_NSEC3_SHA1, DNSSEC_ALGORITHM_RSASHA1_NSEC3_SHA1, - DNSSEC_ALGORITHM_RSASHA256 = 8, /* RFC 5702 */ - DNSSEC_ALGORITHM_RSASHA512 = 10, /* RFC 5702 */ + DNSSEC_ALGORITHM_RSASHA256 = 8, /* RFC 5702 */ + DNSSEC_ALGORITHM_RSASHA512 = 10, /* RFC 5702 */ + DNSSEC_ALGORITHM_ECC_GOST = 12, /* RFC 5933 */ DNSSEC_ALGORITHM_ECDSAP256SHA256 = 13, /* RFC 6605 */ DNSSEC_ALGORITHM_ECDSAP384SHA384 = 14, /* RFC 6605 */ DNSSEC_ALGORITHM_INDIRECT = 252, @@ -65,8 +66,9 @@ enum { * https://www.iana.org/assignments/ds-rr-types/ds-rr-types.xhtml */ enum { DNSSEC_DIGEST_SHA1 = 1, - DNSSEC_DIGEST_SHA256 = 2, - DNSSEC_DIGEST_SHA384 = 4, + DNSSEC_DIGEST_SHA256 = 2, /* RFC 4509 */ + DNSSEC_DIGEST_GOST_R_34_11_94 = 3, /* RFC 5933 */ + DNSSEC_DIGEST_SHA384 = 4, /* RFC 6605 */ _DNSSEC_DIGEST_MAX_DEFINED }; -- cgit v1.2.3-54-g00ecf From 6af47493de0ef2b66d4c3fbcdd4a2e12fec4bfba Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 29 Dec 2015 19:27:09 +0100 Subject: resolved: add comments referencing various RFCs to various places --- src/resolve/resolved-dns-cache.c | 3 ++- src/resolve/resolved-dns-dnssec.c | 10 +++++++++- src/resolve/resolved-dns-rr.c | 4 ++++ src/resolve/resolved-dns-rr.h | 18 ++++++++++-------- 4 files changed, 25 insertions(+), 10 deletions(-) (limited to 'src/resolve/resolved-dns-rr.h') diff --git a/src/resolve/resolved-dns-cache.c b/src/resolve/resolved-dns-cache.c index 3193985542..1c7dd56b3b 100644 --- a/src/resolve/resolved-dns-cache.c +++ b/src/resolve/resolved-dns-cache.c @@ -26,7 +26,8 @@ #include "resolved-dns-packet.h" #include "string-util.h" -/* Never cache more than 4K entries */ +/* Never cache more than 4K entries. RFC 1536, Section 5 suggests to + * leave DNS caches unbounded, but that's crazy. */ #define CACHE_MAX 4096 /* We never keep any item longer than 2h in our cache */ diff --git a/src/resolve/resolved-dns-dnssec.c b/src/resolve/resolved-dns-dnssec.c index a3aa90e98d..3f5226de0d 100644 --- a/src/resolve/resolved-dns-dnssec.c +++ b/src/resolve/resolved-dns-dnssec.c @@ -458,7 +458,15 @@ static int dnssec_rrsig_expired(DnsResourceRecord *rrsig, usec_t realtime) { static int algorithm_to_gcrypt_md(uint8_t algorithm) { - /* Translates a DNSSEC signature algorithm into a gcrypt digest identifier */ + /* Translates a DNSSEC signature algorithm into a gcrypt + * digest identifier. + * + * Note that we implement all algorithms listed as "Must + * implement" and "Recommended to Implement" in RFC6944. We + * don't implement any algorithms that are listed as + * "Optional" or "Must Not Implement". Specifically, we do not + * implement RSAMD5, DSASHA1, DH, DSA-NSEC3-SHA1, and + * GOST-ECC. */ switch (algorithm) { diff --git a/src/resolve/resolved-dns-rr.c b/src/resolve/resolved-dns-rr.c index 89645b064c..274e857586 100644 --- a/src/resolve/resolved-dns-rr.c +++ b/src/resolve/resolved-dns-rr.c @@ -311,6 +311,9 @@ int dns_resource_key_to_string(const DnsResourceKey *key, char **ret) { const char *c, *t; char *s; + /* If we cannot convert the CLASS/TYPE into a known string, + use the format recommended by RFC 3597, Section 5. */ + c = dns_class_to_string(key->class); if (!c) { sprintf(cbuf, "CLASS%u", key->class); @@ -1021,6 +1024,7 @@ const char *dns_resource_record_to_string(DnsResourceRecord *rr) { if (!t) return NULL; + /* Format as documented in RFC 3597, Section 5 */ r = asprintf(&s, "%s \\# %zu %s", k, rr->generic.size, t); if (r < 0) return NULL; diff --git a/src/resolve/resolved-dns-rr.h b/src/resolve/resolved-dns-rr.h index 317be0efbe..cee3978969 100644 --- a/src/resolve/resolved-dns-rr.h +++ b/src/resolve/resolved-dns-rr.h @@ -157,6 +157,7 @@ struct DnsResourceRecord { char *exchange; } mx; + /* https://tools.ietf.org/html/rfc1876 */ struct { uint8_t version; uint8_t size; @@ -167,14 +168,6 @@ struct DnsResourceRecord { uint32_t altitude; } loc; - struct { - uint16_t key_tag; - uint8_t algorithm; - uint8_t digest_type; - void *digest; - size_t digest_size; - } ds; - /* https://tools.ietf.org/html/rfc4255#section-3.1 */ struct { uint8_t algorithm; @@ -212,6 +205,15 @@ struct DnsResourceRecord { Bitmap *types; } nsec; + /* https://tools.ietf.org/html/rfc4034#section-5.1 */ + struct { + uint16_t key_tag; + uint8_t algorithm; + uint8_t digest_type; + void *digest; + size_t digest_size; + } ds; + struct { uint8_t algorithm; uint8_t flags; -- cgit v1.2.3-54-g00ecf From d15ad74251454d55b715958d8e6f50f45195904a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 29 Dec 2015 20:50:03 +0100 Subject: resolved: NSEC3 hash algorithms are distinct from DS digest algorithms Previously, we'd use the same set of identifiers for both, but that's actually incorrect. It didn't matter much since the only NSEC3 hash algorithm defined (SHA-1) is mapped to code 1 which is also what it is encoded as in DS digests, but we really should make sure to use two distinct enumerations. --- src/resolve/resolved-dns-dnssec.c | 20 +++++++++++++++++++- src/resolve/resolved-dns-rr.h | 7 +++++++ 2 files changed, 26 insertions(+), 1 deletion(-) (limited to 'src/resolve/resolved-dns-rr.h') diff --git a/src/resolve/resolved-dns-dnssec.c b/src/resolve/resolved-dns-dnssec.c index aca67b85f8..e4b32c7e4b 100644 --- a/src/resolve/resolved-dns-dnssec.c +++ b/src/resolve/resolved-dns-dnssec.c @@ -1057,6 +1057,20 @@ int dnssec_verify_dnskey_search(DnsResourceRecord *dnskey, DnsAnswer *validated_ return 0; } +static int nsec3_hash_to_gcrypt_md(uint8_t algorithm) { + + /* Translates a DNSSEC NSEC3 hash algorithm into a gcrypt digest identifier */ + + switch (algorithm) { + + case NSEC3_ALGORITHM_SHA1: + return GCRY_MD_SHA1; + + default: + return -EOPNOTSUPP; + } +} + int dnssec_nsec3_hash(DnsResourceRecord *nsec3, const char *name, void *ret) { uint8_t wire_format[DNS_WIRE_FOMAT_HOSTNAME_MAX]; gcry_md_hd_t md = NULL; @@ -1073,7 +1087,7 @@ int dnssec_nsec3_hash(DnsResourceRecord *nsec3, const char *name, void *ret) { if (nsec3->key->type != DNS_TYPE_NSEC3) return -EINVAL; - algorithm = digest_to_gcrypt_md(nsec3->nsec3.algorithm); + algorithm = nsec3_hash_to_gcrypt_md(nsec3->nsec3.algorithm); if (algorithm < 0) return algorithm; @@ -1138,6 +1152,10 @@ static int nsec3_is_good(DnsResourceRecord *rr, DnsAnswerFlags flags, DnsResourc if (!IN_SET(rr->nsec3.flags, 0, 1)) return 0; + /* Ignore NSEC3 RRs whose algorithm we don't know */ + if (nsec3_hash_to_gcrypt_md(rr->nsec3.algorithm) < 0) + return 0; + if (!nsec3) return 1; diff --git a/src/resolve/resolved-dns-rr.h b/src/resolve/resolved-dns-rr.h index cee3978969..27c5f5384e 100644 --- a/src/resolve/resolved-dns-rr.h +++ b/src/resolve/resolved-dns-rr.h @@ -72,6 +72,13 @@ enum { _DNSSEC_DIGEST_MAX_DEFINED }; +/* DNSSEC NSEC3 hash algorithms, see + * https://www.iana.org/assignments/dnssec-nsec3-parameters/dnssec-nsec3-parameters.xhtml */ +enum { + NSEC3_ALGORITHM_SHA1 = 1, + _NSEC3_ALGORITHM_MAX_DEFINED +}; + struct DnsResourceKey { unsigned n_ref; uint16_t class, type; -- cgit v1.2.3-54-g00ecf