]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
fixed validation of root DS
authorMarek Vavruša <mvavrusa@cloudflare.com>
Thu, 5 Apr 2018 03:41:15 +0000 (20:41 -0700)
committerPetr Špaček <petr.spacek@nic.cz>
Thu, 12 Apr 2018 10:14:50 +0000 (12:14 +0200)
The root DS exists outside of DNS hierarchy, so its NSEC proving non-existence
always contains the SOA, as that's the root of DNS and there's nothing above it.

NEWS
lib/cache/nsec1.c
lib/dnssec/nsec.c
lib/dnssec/nsec.h
lib/dnssec/nsec3.c

diff --git a/NEWS b/NEWS
index 93c5eb802ed9b8d69507e64e50c6af6ac282a642..91e79cecc52def98ea00444811426c807579f141 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,7 @@
 Bugfixes
 --------
 - validation: fix SERVFAIL in case of CNAME to NXDOMAIN in a single zone
+- validation: fix SERVFAIL for DS . query
 
 
 Knot Resolver 2.2.0 (2018-03-28)
index bdc64c3fa6fa2ebbdf905d60196f152454bfff3d..fb64f51e62f3b3ba54379c666909d93499c03051 100644 (file)
@@ -324,7 +324,7 @@ int nsec1_encloser(struct key *k, struct answer *ans,
        knot_nsec_bitmap(&nsec_rr->rrs, &bm, &bm_size);
 
        if (exact_match) {
-               if (kr_nsec_bitmap_nodata_check(bm, bm_size, qry->stype) != 0) {
+               if (kr_nsec_bitmap_nodata_check(bm, bm_size, qry->stype, nsec_rr->owner) != 0) {
                        assert(bm);
                        VERBOSE_MSG(qry,
                                "=> NSEC sname: match but failed type check\n");
@@ -489,7 +489,7 @@ int nsec1_src_synth(struct key *k, struct answer *ans, const knot_dname_t *clenc
        }
 
        /* The wildcard exists.  Find if it's NODATA - check type bitmap. */
-       if (kr_nsec_bitmap_nodata_check(bm, bm_size, qry->stype) == 0) {
+       if (kr_nsec_bitmap_nodata_check(bm, bm_size, qry->stype, nsec_rr->owner) == 0) {
                /* NODATA proven; just need to add SOA+RRSIG later */
                WITH_VERBOSE(qry) {
                        const char *msg_start = "=> NSEC wildcard: match proved NODATA";
index f5a1e163ca5fd42fd5456473a03e4928cef6e1ae..ab22ffbe31b48b5a30e866c808dda3373a333551 100644 (file)
@@ -258,10 +258,10 @@ static int coverign_rrsig_labels(const knot_rrset_t *nsec, const knot_pktsection
 }
 
 
-int kr_nsec_bitmap_nodata_check(const uint8_t *bm, uint16_t bm_size, uint16_t type)
+int kr_nsec_bitmap_nodata_check(const uint8_t *bm, uint16_t bm_size, uint16_t type, const knot_dname_t *owner)
 {
        const int NO_PROOF = abs(ENOENT);
-       if (!bm) {
+       if (!bm || !owner) {
                return kr_error(EINVAL);
        }
        if (kr_nsec_bitmap_contains_type(bm, bm_size, type)) {
@@ -278,8 +278,10 @@ int kr_nsec_bitmap_nodata_check(const uint8_t *bm, uint16_t bm_size, uint16_t ty
                /* Security feature: in case of DS also check for SOA
                 * non-existence to be more certain that we don't hold
                 * a child-side NSEC by some mistake (e.g. when forwarding).
-                * See RFC4035 5.2, next-to-last paragraph. */
-               if (kr_nsec_bitmap_contains_type(bm, bm_size, KNOT_RRTYPE_SOA)) {
+                * See RFC4035 5.2, next-to-last paragraph.
+                * This doesn't apply for root DS as it doesn't exist in DNS hierarchy.
+                */
+               if (owner[0] != '\0' && kr_nsec_bitmap_contains_type(bm, bm_size, KNOT_RRTYPE_SOA)) {
                        return NO_PROOF;
                }
                break;
@@ -318,7 +320,7 @@ static int no_data_response_check_rrtype(int *flags, const knot_rrset_t *nsec,
        uint8_t *bm = NULL;
        uint16_t bm_size = 0;
        knot_nsec_bitmap(&nsec->rrs, &bm, &bm_size);
-       int ret = kr_nsec_bitmap_nodata_check(bm, bm_size, type);
+       int ret = kr_nsec_bitmap_nodata_check(bm, bm_size, type, nsec->owner);
        if (ret == kr_ok()) {
                *flags |= FLG_NOEXIST_RRTYPE;
        }
index 7d78a8cfb918c752e5e7ce9e069b461f4bfcc64c..58542414d1a456cddfcb81ba44a3e506a9c9a429 100644 (file)
@@ -41,10 +41,11 @@ int kr_nsec_children_in_zone_check(const uint8_t *bm, uint16_t bm_size);
  * @param bm      Bitmap.
  * @param bm_size Bitmap size.
  * @param type    RR type to check.
+ * @param owner   NSEC record owner.
  * @note This includes special checks for zone cuts, e.g. from RFC 6840 sec. 4.
  * @return 0, abs(ENOENT) (no proof), kr_error(EINVAL)
  */
-int kr_nsec_bitmap_nodata_check(const uint8_t *bm, uint16_t bm_size, uint16_t type);
+int kr_nsec_bitmap_nodata_check(const uint8_t *bm, uint16_t bm_size, uint16_t type, const knot_dname_t *owner);
 
 /**
  * Name error response check (RFC4035 3.1.3.2; RFC4035 5.4, bullet 2).
index 085cd164bf9ba2160d445f79cf7a0a979f7ebdb8..7dafda7510239df38dc635b1ec9a468908292a86 100644 (file)
@@ -554,7 +554,7 @@ static int nodata_find(const knot_pkt_t *pkt, knot_section_t section_id,
                uint8_t *bm = NULL;
                uint16_t bm_size;
                knot_nsec3_bitmap(&nsec3->rrs, 0, &bm, &bm_size);
-               if (kr_nsec_bitmap_nodata_check(bm, bm_size, type) == kr_ok()) {
+               if (kr_nsec_bitmap_nodata_check(bm, bm_size, type, nsec3->owner) == kr_ok()) {
                        return kr_ok();
                }
        }