summaryrefslogtreecommitdiff
path: root/src/resolve
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2015-12-21 19:57:34 +0100
committerLennart Poettering <lennart@poettering.net>2015-12-26 19:09:10 +0100
commite7ff0e0b391341bdc4d9c08dff1c477e1df6a682 (patch)
tree03852136cb91d95a6549b74a983f295abdc8c250 /src/resolve
parentd38d5ca65b3f8fd19348a7919cf1f1f07c955393 (diff)
resolved: properly implement RRSIG validation of wildcarded RRsets
Note that this is still not complete, one additional step is still missing: when we verified that a wildcard RRset is properly signed, we still need to do an NSEC/NSEC3 proof that no more specific RRset exists.
Diffstat (limited to 'src/resolve')
-rw-r--r--src/resolve/resolved-dns-dnssec.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/src/resolve/resolved-dns-dnssec.c b/src/resolve/resolved-dns-dnssec.c
index 814cb1c0f9..9ddad38fa6 100644
--- a/src/resolve/resolved-dns-dnssec.c
+++ b/src/resolve/resolved-dns-dnssec.c
@@ -384,10 +384,17 @@ int dnssec_verify_rrset(
gcry_md_write(md, wire_format_name, r);
for (k = 0; k < n; k++) {
+ const char *suffix;
size_t l;
rr = list[k];
- r = dns_name_to_wire_format(DNS_RESOURCE_KEY_NAME(rr->key), wire_format_name, sizeof(wire_format_name), true);
+ r = dns_name_suffix(DNS_RESOURCE_KEY_NAME(rr->key), rrsig->rrsig.labels, &suffix);
+ if (r < 0)
+ goto finish;
+ if (r > 0) /* This is a wildcard! */
+ gcry_md_write(md, (uint8_t[]) { 1, '*'}, 2);
+
+ r = dns_name_to_wire_format(suffix, wire_format_name, sizeof(wire_format_name), true);
if (r < 0)
goto finish;
gcry_md_write(md, wire_format_name, r);
@@ -497,6 +504,8 @@ int dnssec_rrsig_match_dnskey(DnsResourceRecord *rrsig, DnsResourceRecord *dnske
}
int dnssec_key_match_rrsig(const DnsResourceKey *key, DnsResourceRecord *rrsig) {
+ int r;
+
assert(key);
assert(rrsig);
@@ -509,6 +518,18 @@ int dnssec_key_match_rrsig(const DnsResourceKey *key, DnsResourceRecord *rrsig)
if (rrsig->rrsig.type_covered != key->type)
return 0;
+ /* Make sure signer is a parent of the RRset */
+ r = dns_name_endswith(DNS_RESOURCE_KEY_NAME(rrsig->key), rrsig->rrsig.signer);
+ if (r <= 0)
+ return r;
+
+ /* Make sure the owner name has at least as many labels as the "label" fields indicates. */
+ r = dns_name_count_labels(DNS_RESOURCE_KEY_NAME(rrsig->key));
+ if (r < 0)
+ return r;
+ if (r < rrsig->rrsig.labels)
+ return 0;
+
return dns_name_equal(DNS_RESOURCE_KEY_NAME(rrsig->key), DNS_RESOURCE_KEY_NAME(key));
}