summaryrefslogtreecommitdiff
path: root/src/resolve/resolved-dns-dnssec.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2016-01-14 17:25:06 +0100
committerLennart Poettering <lennart@poettering.net>2016-01-17 20:44:25 +0100
commit588c53d0441ee33b617582429434b47492f51744 (patch)
treec5d91bae40f4a45d295a7d350e4cb4677c274bed /src/resolve/resolved-dns-dnssec.c
parent3d39e6e5d475461c20d0300da80ff8cae5780ccf (diff)
downloadsystemd-588c53d0441ee33b617582429434b47492f51744.tar.gz
resolved: some RR types may appear only or not at all in a zone apex
Add extra checks when validating with RRSIGs. This follows recommendations from: http://www.george-barwood.pwp.blueyonder.co.uk/DnsServer/NotesOnDNSSSEC.htm
Diffstat (limited to 'src/resolve/resolved-dns-dnssec.c')
-rw-r--r--src/resolve/resolved-dns-dnssec.c36
1 files changed, 30 insertions, 6 deletions
diff --git a/src/resolve/resolved-dns-dnssec.c b/src/resolve/resolved-dns-dnssec.c
index afff979b5a..4aade4829e 100644
--- a/src/resolve/resolved-dns-dnssec.c
+++ b/src/resolve/resolved-dns-dnssec.c
@@ -508,14 +508,14 @@ int dnssec_verify_rrset(
DnssecResult *result) {
uint8_t wire_format_name[DNS_WIRE_FOMAT_HOSTNAME_MAX];
- size_t hash_size;
- void *hash;
DnsResourceRecord **list, *rr;
+ const char *source, *name;
gcry_md_hd_t md = NULL;
int r, md_algorithm;
size_t k, n = 0;
+ size_t hash_size;
+ void *hash;
bool wildcard;
- const char *source;
assert(key);
assert(rrsig);
@@ -544,8 +544,32 @@ int dnssec_verify_rrset(
return 0;
}
+ name = DNS_RESOURCE_KEY_NAME(key);
+
+ /* Some keys may only appear signed in the zone apex, and are invalid anywhere else. (SOA, NS...) */
+ if (dns_type_apex_only(rrsig->rrsig.type_covered)) {
+ r = dns_name_equal(rrsig->rrsig.signer, name);
+ if (r < 0)
+ return r;
+ if (r == 0) {
+ *result = DNSSEC_INVALID;
+ return 0;
+ }
+ }
+
+ /* OTOH DS RRs may not appear in the zone apex, but are valid everywhere else. */
+ if (rrsig->rrsig.type_covered == DNS_TYPE_DS) {
+ r = dns_name_equal(rrsig->rrsig.signer, name);
+ if (r < 0)
+ return r;
+ if (r > 0) {
+ *result = DNSSEC_INVALID;
+ return 0;
+ }
+ }
+
/* Determine the "Source of Synthesis" and whether this is a wildcard RRSIG */
- r = dns_name_suffix(DNS_RESOURCE_KEY_NAME(key), rrsig->rrsig.labels, &source);
+ r = dns_name_suffix(name, rrsig->rrsig.labels, &source);
if (r < 0)
return r;
if (r > 0 && !dns_type_may_wildcard(rrsig->rrsig.type_covered)) {
@@ -556,11 +580,11 @@ int dnssec_verify_rrset(
if (r == 1) {
/* If we stripped a single label, then let's see if that maybe was "*". If so, we are not really
* synthesized from a wildcard, we are the wildcard itself. Treat that like a normal name. */
- r = dns_name_startswith(DNS_RESOURCE_KEY_NAME(key), "*");
+ r = dns_name_startswith(name, "*");
if (r < 0)
return r;
if (r > 0)
- source = DNS_RESOURCE_KEY_NAME(key);
+ source = name;
wildcard = r == 0;
} else