]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Check nsec3param configuration values
authorMatthijs Mekking <matthijs@isc.org>
Tue, 13 Oct 2020 15:48:22 +0000 (17:48 +0200)
committerMatthijs Mekking <matthijs@isc.org>
Thu, 26 Nov 2020 09:43:27 +0000 (10:43 +0100)
Check 'nsec3param' configuration for the number of iterations.  The
maximum number of iterations that are allowed are based on the key
size (see https://tools.ietf.org/html/rfc5155#section-10.3).

Check 'nsec3param' configuration for correct salt. If the string is
not "-" or hex-based, this is a bad salt.

bin/tests/system/checkconf/kasp-bad-keylen.conf [new file with mode: 0644]
bin/tests/system/checkconf/kasp-bad-nsec3-iter.conf [new file with mode: 0644]
bin/tests/system/checkconf/kasp-bad-nsec3-salt.conf [new file with mode: 0644]
bin/tests/system/checkconf/tests.sh
lib/dns/include/dns/result.h
lib/dns/result.c
lib/isccfg/kaspconf.c

diff --git a/bin/tests/system/checkconf/kasp-bad-keylen.conf b/bin/tests/system/checkconf/kasp-bad-keylen.conf
new file mode 100644 (file)
index 0000000..ec52436
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+dnssec-policy "bad-keylen" {
+       keys {
+               csk lifetime P10Y algorithm rsasha1 511;
+       };
+};
+
+zone "example.net" {
+       type master;
+       file "example.db";
+       dnssec-policy "badkeylen";
+};
diff --git a/bin/tests/system/checkconf/kasp-bad-nsec3-iter.conf b/bin/tests/system/checkconf/kasp-bad-nsec3-iter.conf
new file mode 100644 (file)
index 0000000..f537f50
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+dnssec-policy "rsasha1" {
+       keys {
+               csk lifetime P10Y algorithm rsasha1 1024;
+       };
+       nsec3param iterations 150;
+};
+
+dnssec-policy "rsasha1-bad" {
+       keys {
+               csk lifetime P10Y algorithm rsasha1 1024;
+       };
+       nsec3param iterations 151;
+};
+
+dnssec-policy "rsasha256" {
+       keys {
+               csk lifetime P10Y algorithm rsasha256 2048;
+       };
+       nsec3param iterations 500;
+};
+
+dnssec-policy "rsasha256-bad" {
+       keys {
+               csk lifetime P10Y algorithm rsasha256 2048;
+       };
+       nsec3param iterations 501;
+};
+
+dnssec-policy "rsasha512" {
+       keys {
+               csk lifetime P10Y algorithm rsasha512 4096;
+       };
+       nsec3param iterations 2500;
+};
+
+dnssec-policy "rsasha512-bad" {
+       keys {
+               csk lifetime P10Y algorithm rsasha512 4096;
+       };
+       nsec3param iterations 2501;
+};
+
+zone "example.net" {
+       type master;
+       file "example.db";
+       dnssec-policy "default";
+};
diff --git a/bin/tests/system/checkconf/kasp-bad-nsec3-salt.conf b/bin/tests/system/checkconf/kasp-bad-nsec3-salt.conf
new file mode 100644 (file)
index 0000000..7701d3b
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+dnssec-policy "bad-salt" {
+       nsec3param salt "pepper";
+};
+
+zone "example.net" {
+       type master;
+       file "example.db";
+       dnssec-policy "bad-salt";
+};
+
index 244c226469c9d77a93c50681c762c4b450ff54a6..eb39d59b56760e7da855bc664b2c3723fd5f0e4c 100644 (file)
@@ -509,7 +509,35 @@ if [ $ret != 0 ]; then echo_i "failed"; fi
 status=`expr $status + $ret`
 
 n=`expr $n + 1`
-echo_i "checking named-checkconf kasp predefined key lengths ($n)"
+echo_i "checking named-checkconf kasp nsec3 salt errors ($n)"
+ret=0
+$CHECKCONF kasp-bad-nsec3-salt.conf > checkconf.out$n 2>&1 && ret=1
+grep "dnssec-policy: bad nsec3 salt pepper" < checkconf.out$n > /dev/null || ret=1
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo_i "checking named-checkconf kasp nsec3 iterations errors ($n)"
+ret=0
+$CHECKCONF kasp-bad-nsec3-iter.conf > checkconf.out$n 2>&1 && ret=1
+grep "dnssec-policy: nsec3 iterations value 151 out of range" < checkconf.out$n > /dev/null || ret=1
+grep "dnssec-policy: nsec3 iterations value 501 out of range" < checkconf.out$n > /dev/null || ret=1
+grep "dnssec-policy: nsec3 iterations value 2501 out of range" < checkconf.out$n > /dev/null || ret=1
+lines=$(wc -l < "checkconf.out$n")
+if [ $lines != 3 ]; then ret=1; fi
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo_i "checking named-checkconf kasp key errors ($n)"
+ret=0
+$CHECKCONF kasp-bad-keylen.conf > checkconf.out$n 2>&1 && ret=1
+grep "dnssec-policy: key with algorithm rsasha1 has invalid key length 511" < checkconf.out$n > /dev/null || ret=1
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo_i "checking named-checkconf kasp predefined key length ($n)"
 ret=0
 $CHECKCONF kasp-ignore-keylen.conf > checkconf.out$n 2>&1 || ret=1
 grep "dnssec-policy: key algorithm ecdsa256 has predefined length; ignoring length value 2048" < checkconf.out$n > /dev/null || ret=1
index b7f178c7af9178a8e52cd599751f675c6473a923..f6ec856308fae07441afdb7169ffef07b144db6b 100644 (file)
 #define DNS_R_NOKEYMATCH       (ISC_RESULTCLASS_DNS + 120)
 #define DNS_R_TOOMANYKEYS      (ISC_RESULTCLASS_DNS + 121)
 #define DNS_R_KEYNOTACTIVE     (ISC_RESULTCLASS_DNS + 122)
+#define DNS_R_NSEC3ITERRANGE   (ISC_RESULTCLASS_DNS + 123)
+#define DNS_R_NSEC3BADSALT     (ISC_RESULTCLASS_DNS + 124)
 
-#define DNS_R_NRESULTS 123 /*%< Number of results */
+#define DNS_R_NRESULTS 125 /*%< Number of results */
 
 /*
  * DNS wire format rcodes.
index 465f72f7839b87766eca85993f0e1b1f6fe8c98b..7df73f78e5a16ff50392f40d440b3d31f883c871 100644 (file)
@@ -169,6 +169,9 @@ static const char *text[DNS_R_NRESULTS] = {
        "no matching key found",       /*%< 120 DNS_R_NOKEYMATCH */
        "too many keys matching",      /*%< 121 DNS_R_TOOMANYKEYS */
        "key is not actively signing", /*%< 122 DNS_R_KEYNOTACTIVE */
+
+       "NSEC3 iterations out of range", /*%< 123 DNS_R_NSEC3ITERRANGE */
+       "bad NSEC3 salt",                /*%< 124 DNS_R_NSEC3BADSALT */
 };
 
 static const char *ids[DNS_R_NRESULTS] = {
@@ -299,6 +302,8 @@ static const char *ids[DNS_R_NRESULTS] = {
        "DNS_R_NOKEYMATCH",
        "DNS_R_TOOMANYKEYS",
        "DNS_R_KEYNOTACTIVE",
+       "DNS_R_NSEC3ITERRANGE",
+       "DNS_R_NSEC3BADSALT",
 };
 
 static const char *rcode_text[DNS_R_NRCODERESULTS] = {
index 6629bf52b3e010c3b8e4b6e3f1feb247c75a66aa..af52c9c64f9cf97ab5c1e6e8ad3ec033b65d51b0 100644 (file)
@@ -166,17 +166,47 @@ cleanup:
 }
 
 static isc_result_t
-cfg_nsec3param_fromconfig(const cfg_obj_t *config, dns_kasp_t *kasp) {
+cfg_nsec3param_fromconfig(const cfg_obj_t *config, dns_kasp_t *kasp,
+                         isc_log_t *logctx) {
+       dns_kasp_key_t *kkey;
+       unsigned int min_keysize = 4096;
        const cfg_obj_t *obj = NULL;
        const char *salt = NULL;
-       uint8_t iter = DEFAULT_NSEC3PARAM_ITER;
+       uint32_t iter = DEFAULT_NSEC3PARAM_ITER;
        bool optout = false;
+       isc_result_t ret = ISC_R_SUCCESS;
 
        /* How many iterations. */
        obj = cfg_tuple_get(config, "iterations");
        if (cfg_obj_isuint32(obj)) {
                iter = cfg_obj_asuint32(obj);
        }
+       dns_kasp_freeze(kasp);
+       for (kkey = ISC_LIST_HEAD(dns_kasp_keys(kasp)); kkey != NULL;
+            kkey = ISC_LIST_NEXT(kkey, link))
+       {
+               unsigned int keysize = dns_kasp_key_size(kkey);
+               if (keysize < min_keysize) {
+                       min_keysize = keysize;
+               }
+       }
+       dns_kasp_thaw(kasp);
+       /* See RFC 5155 Section 10.3 for iteration limits. */
+       if (min_keysize <= 1024 && iter > 150) {
+               ret = DNS_R_NSEC3ITERRANGE;
+       } else if (min_keysize <= 2048 && iter > 500) {
+               ret = DNS_R_NSEC3ITERRANGE;
+       } else if (min_keysize <= 4096 && iter > 2500) {
+               ret = DNS_R_NSEC3ITERRANGE;
+       }
+
+       if (ret == DNS_R_NSEC3ITERRANGE) {
+               cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
+                           "dnssec-policy: nsec3 iterations value %u "
+                           "out of range",
+                           iter);
+               return (ret);
+       }
 
        /* Opt-out? */
        obj = cfg_tuple_get(config, "optout");
@@ -190,7 +220,12 @@ cfg_nsec3param_fromconfig(const cfg_obj_t *config, dns_kasp_t *kasp) {
                salt = cfg_obj_asstring(obj);
        }
 
-       return dns_kasp_setnsec3param(kasp, iter, optout, salt);
+       ret = dns_kasp_setnsec3param(kasp, iter, optout, salt);
+       if (ret != ISC_R_SUCCESS) {
+               cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
+                           "dnssec-policy: bad nsec3 salt %s", salt);
+       }
+       return (ret);
 }
 
 isc_result_t
@@ -282,7 +317,7 @@ cfg_kasp_fromconfig(const cfg_obj_t *config, isc_mem_t *mctx, isc_log_t *logctx,
                dns_kasp_setnsec3(kasp, false);
        } else {
                dns_kasp_setnsec3(kasp, true);
-               result = cfg_nsec3param_fromconfig(nsec3, kasp);
+               result = cfg_nsec3param_fromconfig(nsec3, kasp, logctx);
                if (result != ISC_R_SUCCESS) {
                        goto cleanup;
                }