]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
layer/validate: Implemented empty non-terminal NSEC check.
authorKarel Slany <karel.slany@nic.cz>
Fri, 18 Sep 2015 09:25:12 +0000 (11:25 +0200)
committerKarel Slany <karel.slany@nic.cz>
Fri, 18 Sep 2015 09:25:12 +0000 (11:25 +0200)
lib/dnssec/nsec.c
lib/dnssec/nsec.h

index 572755cd6f27b04bb73d89c22be60d805f017cf9..c5a974477227277be47624c81453c271b6f42474 100644 (file)
@@ -355,6 +355,51 @@ int kr_nsec_wildcard_answer_response_check(const knot_pkt_t *pkt, knot_section_t
        return kr_error(ENOENT);
 }
 
+/**
+ * Check whether the NSEC RR proves that there is a empty non-terminal.
+ * @param nsec  NSEC RRSet.
+ * @param sname Searched name.
+ * @return      0 or error code.
+ */
+static int nsec_empty_nonterminal(const knot_rrset_t *nsec, const knot_dname_t *sname)
+{
+       assert(nsec && sname);
+
+       int ret = nsec_nonamematch(nsec, sname);
+       if (ret != 0) {
+               return ret;
+       }
+
+       const knot_dname_t *next = knot_nsec_next(&nsec->rrs);
+
+       if (knot_dname_in(sname, next)) {
+               return kr_ok();
+       } else {
+               return kr_error(EINVAL);
+       }
+}
+
+int kr_nsec_empty_nonterminal_response_check(const knot_pkt_t *pkt, knot_section_t section_id,
+                                             const knot_dname_t *sname)
+{
+       const knot_pktsection_t *sec = knot_pkt_section(pkt, section_id);
+       if (!sec || !sname) {
+               return kr_error(EINVAL);
+       }
+
+       for (unsigned i = 0; i < sec->count; ++i) {
+               const knot_rrset_t *rrset = knot_pkt_rr(sec, i);
+               if (rrset->type != KNOT_RRTYPE_NSEC) {
+                       continue;
+               }
+               if (nsec_empty_nonterminal(rrset, sname) == 0) {
+                       return kr_ok();
+               }
+       }
+
+       return kr_error(ENOENT);
+}
+
 int kr_nsec_existence_denial(const knot_pkt_t *pkt, knot_section_t section_id,
                              const knot_dname_t *sname, uint16_t stype, mm_ctx_t *pool)
 {
index 73ab99454056ff481be461d831c61a717c2b04c2..1f9d258c185567317d7f4b09904298398979244b 100644 (file)
@@ -73,6 +73,18 @@ int kr_nsec_wildcard_no_data_response_check(const knot_pkt_t *pkt, knot_section_
 int kr_nsec_wildcard_answer_response_check(const knot_pkt_t *pkt, knot_section_t section_id,
                                            const knot_dname_t *sname);
 
+/**
+ * Empty non-terminal response.
+ * @note There are no NSEC records for empty non-terminals. The existence of
+ *     the domain is inferred from the covering NSEC record.
+ * @param pkt        Packet structure to be processed.
+ * @param section_id Packet section to be processed.
+ * @param sname      Name to be checked.
+ * @return           0 or error code.
+ */
+int kr_nsec_empty_nonterminal_response_check(const knot_pkt_t *pkt, knot_section_t section_id,
+                                             const knot_dname_t *sname);
+
 /**
  * Authenticated denial of existence according to RFC4035 5.4.
  * @note No RRSIGs are validated.