]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Mark DNSSEC responses with NSEC3 records that exceed 150 as insecure
authorMark Andrews <marka@isc.org>
Wed, 17 Feb 2021 05:33:49 +0000 (16:33 +1100)
committerMatthijs Mekking <matthijs@isc.org>
Fri, 30 Apr 2021 09:16:45 +0000 (11:16 +0200)
(cherry picked from commit af02bbcdd6c4117a20092ed39533e7171e9a6771)

lib/dns/include/dns/nsec3.h
lib/dns/nsec3.c
lib/dns/validator.c

index 2f178b680b25e0285d221d8a53883177b11ed506..0cbcb51108dcd75baa9c09c90bfcd664ca3e56eb 100644 (file)
@@ -24,7 +24,8 @@
 #include <dns/rdatastruct.h>
 #include <dns/types.h>
 
-#define DNS_NSEC3_SALTSIZE 255
+#define DNS_NSEC3_SALTSIZE     255
+#define DNS_NSEC3_MAXITERATIONS 150U
 
 /*
  * hash = 1, flags =1, iterations = 2, salt length = 1, salt = 255 (max)
index b5df23eefeab2080f53ff778846965158c28cbc9..7ff9e8df404c873d5151b70073fba21c3fd717a5 100644 (file)
@@ -1880,7 +1880,7 @@ try_private:
 
 unsigned int
 dns_nsec3_maxiterations(void) {
-       return (150);
+       return (DNS_NSEC3_MAXITERATIONS);
 }
 
 isc_result_t
@@ -2022,6 +2022,13 @@ dns_nsec3_noexistnodata(dns_rdatatype_t type, const dns_name_t *name,
        first = true;
 
        while (qlabels >= zlabels) {
+               /*
+                * If there are too many iterations reject the NSEC3 record.
+                */
+               if (nsec3.iterations > DNS_NSEC3_MAXITERATIONS) {
+                       return (DNS_R_NSEC3ITERRANGE);
+               }
+
                length = isc_iterated_hash(hash, nsec3.hash, nsec3.iterations,
                                           nsec3.salt, nsec3.salt_length,
                                           qname->ndata, qname->length);
index 27adb5a31f5a4fbdeecb84358da9e21e2906e7db..e54fc70b2eca8ab9d47285604c35278c54ea22cc 100644 (file)
@@ -2245,6 +2245,26 @@ findnsec3proofs(dns_validator_t *val) {
                if (unknown) {
                        val->attributes |= VALATTR_FOUNDUNKNOWN;
                }
+               if (result == DNS_R_NSEC3ITERRANGE) {
+                       /*
+                        * We don't really know which NSEC3 record provides
+                        * which proof.  Just populate them.
+                        */
+                       if (NEEDNOQNAME(val) &&
+                           proofs[DNS_VALIDATOR_NOQNAMEPROOF] == NULL) {
+                               proofs[DNS_VALIDATOR_NOQNAMEPROOF] = name;
+                       } else if (setclosest) {
+                               proofs[DNS_VALIDATOR_CLOSESTENCLOSER] = name;
+                       } else if (NEEDNODATA(val) &&
+                                  proofs[DNS_VALIDATOR_NODATAPROOF] == NULL) {
+                               proofs[DNS_VALIDATOR_NODATAPROOF] = name;
+                       } else if (NEEDNOWILDCARD(val) &&
+                                  proofs[DNS_VALIDATOR_NOWILDCARDPROOF] ==
+                                          NULL) {
+                               proofs[DNS_VALIDATOR_NOWILDCARDPROOF] = name;
+                       }
+                       return (result);
+               }
                if (result != ISC_R_SUCCESS) {
                        continue;
                }
@@ -2501,7 +2521,13 @@ validate_nx(dns_validator_t *val, bool resume) {
         */
        if (!NEEDNODATA(val) && !NEEDNOWILDCARD(val) && NEEDNOQNAME(val)) {
                if (!FOUNDNOQNAME(val)) {
-                       findnsec3proofs(val);
+                       result = findnsec3proofs(val);
+                       if (result == DNS_R_NSEC3ITERRANGE) {
+                               validator_log(val, ISC_LOG_DEBUG(3),
+                                             "too many iterations");
+                               markanswer(val, "validate_nx (3)", NULL);
+                               return (ISC_R_SUCCESS);
+                       }
                }
 
                if (FOUNDNOQNAME(val) && FOUNDCLOSEST(val) && !FOUNDOPTOUT(val))
@@ -2531,7 +2557,13 @@ validate_nx(dns_validator_t *val, bool resume) {
        }
 
        if (!FOUNDNOQNAME(val) && !FOUNDNODATA(val)) {
-               findnsec3proofs(val);
+               result = findnsec3proofs(val);
+               if (result == DNS_R_NSEC3ITERRANGE) {
+                       validator_log(val, ISC_LOG_DEBUG(3),
+                                     "too many iterations");
+                       markanswer(val, "validate_nx (4)", NULL);
+                       return (ISC_R_SUCCESS);
+               }
        }
 
        /*