resolved: dnssec - factor out hashed domain generation
This commit is contained in:
parent
146035b3bb
commit
6f76ec5a7b
|
@ -1071,7 +1071,7 @@ static int nsec3_hash_to_gcrypt_md(uint8_t algorithm) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int dnssec_nsec3_hash(DnsResourceRecord *nsec3, const char *name, void *ret) {
|
int dnssec_nsec3_hash(const DnsResourceRecord *nsec3, const char *name, void *ret) {
|
||||||
uint8_t wire_format[DNS_WIRE_FOMAT_HOSTNAME_MAX];
|
uint8_t wire_format[DNS_WIRE_FOMAT_HOSTNAME_MAX];
|
||||||
gcry_md_hd_t md = NULL;
|
gcry_md_hd_t md = NULL;
|
||||||
size_t hash_size;
|
size_t hash_size;
|
||||||
|
@ -1192,10 +1192,37 @@ static int nsec3_is_good(DnsResourceRecord *rr, DnsAnswerFlags flags, DnsResourc
|
||||||
return dns_name_equal(a, b);
|
return dns_name_equal(a, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int nsec3_hashed_domain(const DnsResourceRecord *nsec3, const char *domain, const char *zone, char **ret) {
|
||||||
|
_cleanup_free_ char *l = NULL, *hashed_domain = NULL;
|
||||||
|
uint8_t hashed[DNSSEC_HASH_SIZE_MAX];
|
||||||
|
int hashed_size;
|
||||||
|
|
||||||
|
assert(nsec3);
|
||||||
|
assert(domain);
|
||||||
|
assert(zone);
|
||||||
|
assert(ret);
|
||||||
|
|
||||||
|
hashed_size = dnssec_nsec3_hash(nsec3, domain, hashed);
|
||||||
|
if (hashed_size < 0)
|
||||||
|
return hashed_size;
|
||||||
|
|
||||||
|
l = base32hexmem(hashed, hashed_size, false);
|
||||||
|
if (!l)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
hashed_domain = strjoin(l, ".", zone, NULL);
|
||||||
|
if (!hashed_domain)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
*ret = hashed_domain;
|
||||||
|
hashed_domain = NULL;
|
||||||
|
|
||||||
|
return hashed_size;
|
||||||
|
}
|
||||||
|
|
||||||
/* See RFC 5155, Section 8 */
|
/* See RFC 5155, Section 8 */
|
||||||
static int dnssec_test_nsec3(DnsAnswer *answer, DnsResourceKey *key, DnssecNsecResult *result, bool *authenticated) {
|
static int dnssec_test_nsec3(DnsAnswer *answer, DnsResourceKey *key, DnssecNsecResult *result, bool *authenticated) {
|
||||||
_cleanup_free_ char *next_closer_domain = NULL, *l = NULL;
|
_cleanup_free_ char *next_closer_domain = NULL;
|
||||||
uint8_t hashed[DNSSEC_HASH_SIZE_MAX];
|
|
||||||
const char *zone, *p, *pp = NULL;
|
const char *zone, *p, *pp = NULL;
|
||||||
DnsResourceRecord *rr, *enclosure_rr, *suffix_rr;
|
DnsResourceRecord *rr, *enclosure_rr, *suffix_rr;
|
||||||
DnsAnswerFlags flags;
|
DnsAnswerFlags flags;
|
||||||
|
@ -1242,9 +1269,9 @@ found_zone:
|
||||||
/* Second step, find the closest encloser NSEC3 RR in 'answer' that matches 'key' */
|
/* Second step, find the closest encloser NSEC3 RR in 'answer' that matches 'key' */
|
||||||
p = DNS_RESOURCE_KEY_NAME(key);
|
p = DNS_RESOURCE_KEY_NAME(key);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
_cleanup_free_ char *hashed_domain = NULL, *label = NULL;
|
_cleanup_free_ char *hashed_domain = NULL;
|
||||||
|
|
||||||
hashed_size = dnssec_nsec3_hash(suffix_rr, p, hashed);
|
hashed_size = nsec3_hashed_domain(suffix_rr, p, zone, &hashed_domain);
|
||||||
if (hashed_size == -EOPNOTSUPP) {
|
if (hashed_size == -EOPNOTSUPP) {
|
||||||
*result = DNSSEC_NSEC_UNSUPPORTED_ALGORITHM;
|
*result = DNSSEC_NSEC_UNSUPPORTED_ALGORITHM;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1252,14 +1279,6 @@ found_zone:
|
||||||
if (hashed_size < 0)
|
if (hashed_size < 0)
|
||||||
return hashed_size;
|
return hashed_size;
|
||||||
|
|
||||||
label = base32hexmem(hashed, hashed_size, false);
|
|
||||||
if (!label)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
hashed_domain = strjoin(label, ".", zone, NULL);
|
|
||||||
if (!hashed_domain)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
DNS_ANSWER_FOREACH_FLAGS(enclosure_rr, flags, answer) {
|
DNS_ANSWER_FOREACH_FLAGS(enclosure_rr, flags, answer) {
|
||||||
|
|
||||||
r = nsec3_is_good(enclosure_rr, flags, suffix_rr);
|
r = nsec3_is_good(enclosure_rr, flags, suffix_rr);
|
||||||
|
@ -1326,20 +1345,12 @@ found_closest_encloser:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = dnssec_nsec3_hash(enclosure_rr, pp, hashed);
|
r = nsec3_hashed_domain(enclosure_rr, pp, zone, &next_closer_domain);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
if (r != hashed_size)
|
if (r != hashed_size)
|
||||||
return -EBADMSG;
|
return -EBADMSG;
|
||||||
|
|
||||||
l = base32hexmem(hashed, hashed_size, false);
|
|
||||||
if (!l)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
next_closer_domain = strjoin(l, ".", zone, NULL);
|
|
||||||
if (!next_closer_domain)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
DNS_ANSWER_FOREACH_FLAGS(rr, flags, answer) {
|
DNS_ANSWER_FOREACH_FLAGS(rr, flags, answer) {
|
||||||
_cleanup_free_ char *label = NULL, *next_hashed_domain = NULL;
|
_cleanup_free_ char *label = NULL, *next_hashed_domain = NULL;
|
||||||
|
|
||||||
|
|
|
@ -87,7 +87,7 @@ uint16_t dnssec_keytag(DnsResourceRecord *dnskey);
|
||||||
|
|
||||||
int dnssec_canonicalize(const char *n, char *buffer, size_t buffer_max);
|
int dnssec_canonicalize(const char *n, char *buffer, size_t buffer_max);
|
||||||
|
|
||||||
int dnssec_nsec3_hash(DnsResourceRecord *nsec3, const char *name, void *ret);
|
int dnssec_nsec3_hash(const DnsResourceRecord *nsec3, const char *name, void *ret);
|
||||||
|
|
||||||
typedef enum DnssecNsecResult {
|
typedef enum DnssecNsecResult {
|
||||||
DNSSEC_NSEC_NO_RR, /* No suitable NSEC/NSEC3 RR found */
|
DNSSEC_NSEC_NO_RR, /* No suitable NSEC/NSEC3 RR found */
|
||||||
|
|
Loading…
Reference in New Issue