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;