]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
nsec3: rfc5155 errata 3114 8.5 was implemented
authorGrigorii Demidov <grigorii.demidov@nic.cz>
Thu, 11 Feb 2016 12:30:19 +0000 (13:30 +0100)
committerGrigorii Demidov <grigorii.demidov@nic.cz>
Thu, 11 Feb 2016 12:30:19 +0000 (13:30 +0100)
lib/dnssec/nsec3.c
lib/dnssec/nsec3.h
lib/layer/validate.c
tests/deckard

index b8d4b5a112cbce3aa4c20f41bbf5c2f39e446df6..87b72f5baad065f45ee8b65e873e3a02c9d2d308 100644 (file)
@@ -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;
 }
+
index 4b154312d9c57ed256b5775cbda6335cbbcb95dd..73cc35561a84204bf31bfe8711872a7442809a1e 100644 (file)
@@ -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);
index 453a00cafb2b53638e94be08d1c56a73da20f7e3..2e8387c3183a477d5c2f72af6a1af0f99a1e96ac 100644 (file)
@@ -23,6 +23,7 @@
 #include <libknot/packet/wire.h>
 #include <libknot/rrtype/rdname.h>
 #include <libknot/rrtype/rrsig.h>
+#include <dnssec/error.h>
 
 #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;
+                               }
                        }
                }
        }
index 866b7b95ce7355d112b9e47504825c31c6fcb27a..e73a0854552d94e8bc5306e75c3a2229bc739531 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 866b7b95ce7355d112b9e47504825c31c6fcb27a
+Subproject commit e73a0854552d94e8bc5306e75c3a2229bc739531