From: Marek VavruĊĦa Date: Thu, 5 Apr 2018 03:41:15 +0000 (-0700) Subject: fixed validation of root DS X-Git-Tag: v2.3.0~13^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b3785d71430f4682c82043b0ce37296371e055bd;p=thirdparty%2Fknot-resolver.git fixed validation of root DS 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. --- diff --git a/NEWS b/NEWS index 93c5eb802..91e79cecc 100644 --- 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) diff --git a/lib/cache/nsec1.c b/lib/cache/nsec1.c index bdc64c3fa..fb64f51e6 100644 --- a/lib/cache/nsec1.c +++ b/lib/cache/nsec1.c @@ -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"; diff --git a/lib/dnssec/nsec.c b/lib/dnssec/nsec.c index f5a1e163c..ab22ffbe3 100644 --- a/lib/dnssec/nsec.c +++ b/lib/dnssec/nsec.c @@ -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; } diff --git a/lib/dnssec/nsec.h b/lib/dnssec/nsec.h index 7d78a8cfb..58542414d 100644 --- a/lib/dnssec/nsec.h +++ b/lib/dnssec/nsec.h @@ -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). diff --git a/lib/dnssec/nsec3.c b/lib/dnssec/nsec3.c index 085cd164b..7dafda751 100644 --- a/lib/dnssec/nsec3.c +++ b/lib/dnssec/nsec3.c @@ -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(); } }