From: Grigorii Demidov Date: Thu, 11 Feb 2016 12:30:19 +0000 (+0100) Subject: nsec3: rfc5155 errata 3114 8.5 was implemented X-Git-Tag: v1.0.0~59^2~5 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=79179e8a56edc7b29fde559246af76edc60cfab9;p=thirdparty%2Fknot-resolver.git nsec3: rfc5155 errata 3114 8.5 was implemented --- diff --git a/lib/dnssec/nsec3.c b/lib/dnssec/nsec3.c index b8d4b5a11..87b72f5ba 100644 --- a/lib/dnssec/nsec3.c +++ b/lib/dnssec/nsec3.c @@ -505,7 +505,7 @@ int kr_nsec3_name_error_response_check(const knot_pkt_t *pkt, knot_section_t sec * @param type Type to be checked. * @return 0 or error code. */ -static int maches_name_and_type(int *flags, const knot_rrset_t *nsec3, +static int matches_name_and_type(int *flags, const knot_rrset_t *nsec3, const knot_dname_t *name, uint16_t type) { assert(flags && nsec3 && name); @@ -565,7 +565,7 @@ static int no_data_response_no_ds(const knot_pkt_t *pkt, knot_section_t section_ } flags = 0; - int ret = maches_name_and_type(&flags, rrset, sname, stype); + int ret = matches_name_and_type(&flags, rrset, sname, stype); if (ret != 0) { return ret; } @@ -611,7 +611,7 @@ static int matches_closest_encloser_wildcard(const knot_pkt_t *pkt, knot_section } flags = 0; - int ret = maches_name_and_type(&flags, rrset, wildcard, stype); + int ret = matches_name_and_type(&flags, rrset, wildcard, stype); if (ret != 0) { return ret; } @@ -659,13 +659,14 @@ int kr_nsec3_wildcard_answer_response_check(const knot_pkt_t *pkt, knot_section_ return kr_error(ENOENT); } -int kr_nsec3_no_data(const knot_pkt_t *pkt, knot_section_t section_id, - const knot_dname_t *sname, uint16_t stype) + +int kr_nsec3_no_data_ds(const knot_pkt_t *pkt, knot_section_t section_id, + const knot_dname_t *sname) { /* DS record may be also matched by an existing NSEC3 RR. */ - int ret = no_data_response_no_ds(pkt, section_id, sname, stype); + int ret = no_data_response_no_ds(pkt, section_id, sname, KNOT_RRTYPE_DS); if (ret == 0) { - /* Satisfies RFC5155 8.5 and 8.6, first paragraph. */ + /* Satisfies RFC5155 8.6, first paragraph. */ return ret; } @@ -679,11 +680,56 @@ int kr_nsec3_no_data(const knot_pkt_t *pkt, knot_section_t section_id, } assert(encloser_name && covering_next_nsec3); - if ((stype == KNOT_RRTYPE_DS) && has_optout(covering_next_nsec3)) { - /* Satisfies RFC5155 8.6, second paragraph. */ - return 0; + if (!has_optout(covering_next_nsec3)) { + ret = DNSSEC_NOT_FOUND; + } + + /* Satisfies RFC5155 8.6, second paragraph. */ + return ret; +} + + +int kr_nsec3_no_data_no_ds(const knot_pkt_t *pkt, knot_section_t section_id, + const knot_dname_t *sname, uint16_t stype) +{ + int ret = no_data_response_no_ds(pkt, section_id, sname, stype); + if (ret == 0) { + /* Satisfies RFC5155 8.5, first paragraph. */ + return ret; + } + + /* Check RFC5155 8.7. */ + /* Find closest provable encloser. */ + const knot_dname_t *encloser_name = NULL; + const knot_rrset_t *covering_next_nsec3 = NULL; + ret = closest_encloser_proof(pkt, section_id, sname, &encloser_name, + NULL, &covering_next_nsec3); + if (ret != 0) { + return ret; } - return matches_closest_encloser_wildcard(pkt, section_id, + assert(encloser_name && covering_next_nsec3); + ret = matches_closest_encloser_wildcard(pkt, section_id, encloser_name, stype); + if (ret == 0) { + /* Satisfies RFC5155 8.7 */ + return ret; + } + + if (has_optout(covering_next_nsec3)) { + /* + * Satisfies RFC5155 ERRATA 3441 8.5 + * (No Data Responses, QTYPE is not DS) + * - empty nonterminal derived from unsecure delegation. + * Moreover, ENT may be wilcard. + * Hence it covers "wilcard nodata response" case. + * It is not an error, but + * denial of existance can not be proven. + * Set error code to proceed unsecure. + */ + ret = DNSSEC_NOT_FOUND; + } + + return ret; } + diff --git a/lib/dnssec/nsec3.h b/lib/dnssec/nsec3.h index 4b154312d..73cc35561 100644 --- a/lib/dnssec/nsec3.h +++ b/lib/dnssec/nsec3.h @@ -41,13 +41,24 @@ int kr_nsec3_wildcard_answer_response_check(const knot_pkt_t *pkt, knot_section_ const knot_dname_t *sname, int trim_to_next); /** - * Authenticated denial of existence according to RFC5155 8.5, 8.6 and 8.7. + * Authenticated denial of existence according to RFC5155 8.5 and 8.7. * @note No RRSIGs are validated. * @param pkt Packet structure to be processed. * @param section_id Packet section to be processed. * @param sname Queried domain name. * @param stype Queried type. * @return 0 or error code. + * @retval DNSSEC_NOT_FOUND denial of existence can't be proven due to opt-out. */ -int kr_nsec3_no_data(const knot_pkt_t *pkt, knot_section_t section_id, +int kr_nsec3_no_data_no_ds(const knot_pkt_t *pkt, knot_section_t section_id, const knot_dname_t *sname, uint16_t stype); +/** + * Authenticated denial of existence according to RFC5155 8.6 + * @note No RRSIGs are validated. + * @param pkt Packet structure to be processed. + * @param section_id Packet section to be processed. + * @param sname Queried domain name. + * @return 0 or error code. + */ +int kr_nsec3_no_data_ds(const knot_pkt_t *pkt, knot_section_t section_id, + const knot_dname_t *sname); diff --git a/lib/layer/validate.c b/lib/layer/validate.c index 453a00caf..2e8387c31 100644 --- a/lib/layer/validate.c +++ b/lib/layer/validate.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "lib/dnssec/nsec.h" #include "lib/dnssec/nsec3.h" @@ -294,7 +295,7 @@ static int update_delegation(struct kr_request *req, struct kr_query *qry, knot_ if (!has_nsec3) { ret = kr_nsec_existence_denial(answer, KNOT_AUTHORITY, proved_name, KNOT_RRTYPE_DS); } else { - ret = kr_nsec3_no_data(answer, KNOT_AUTHORITY, proved_name, KNOT_RRTYPE_DS); + ret = kr_nsec3_no_data_ds(answer, KNOT_AUTHORITY, proved_name); } if (ret != 0) { DEBUG_MSG(qry, "<= bogus proof of DS non-existence\n"); @@ -421,12 +422,18 @@ static int validate(knot_layer_t *ctx, knot_pkt_t *pkt) if (!has_nsec3) { ret = kr_nsec_existence_denial(pkt, KNOT_AUTHORITY, knot_pkt_qname(pkt), knot_pkt_qtype(pkt)); } else { - ret = kr_nsec3_no_data(pkt, KNOT_AUTHORITY, knot_pkt_qname(pkt), knot_pkt_qtype(pkt)); + ret = kr_nsec3_no_data_no_ds(pkt, KNOT_AUTHORITY, knot_pkt_qname(pkt), knot_pkt_qtype(pkt)); } if (ret != 0) { - DEBUG_MSG(qry, "<= bad NODATA proof\n"); - qry->flags |= QUERY_DNSSEC_BOGUS; - return KNOT_STATE_FAIL; + if (has_nsec3 && (ret == DNSSEC_NOT_FOUND)) { + DEBUG_MSG(qry, "<= can't prove NODATA due to optout, going insecure\n"); + qry->flags &= ~QUERY_DNSSEC_WANT; + qry->flags |= QUERY_DNSSEC_INSECURE; + } else { + DEBUG_MSG(qry, "<= bad NODATA proof\n"); + qry->flags |= QUERY_DNSSEC_BOGUS; + return KNOT_STATE_FAIL; + } } } } diff --git a/tests/deckard b/tests/deckard index 866b7b95c..e73a08545 160000 --- a/tests/deckard +++ b/tests/deckard @@ -1 +1 @@ -Subproject commit 866b7b95ce7355d112b9e47504825c31c6fcb27a +Subproject commit e73a0854552d94e8bc5306e75c3a2229bc739531