]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
add support for key algorithm mnemonics in dnssec-policy
authorEvan Hunt <each@isc.org>
Thu, 6 Feb 2020 20:13:20 +0000 (12:13 -0800)
committerMatthijs Mekking <github@pletterpet.nl>
Fri, 7 Feb 2020 18:17:05 +0000 (19:17 +0100)
12 files changed:
bin/tests/system/checkconf/bad-kasp-key1.conf [new file with mode: 0644]
bin/tests/system/checkconf/bad-kasp-key2.conf [new file with mode: 0644]
bin/tests/system/checkconf/bad-kasp-key3.conf [new file with mode: 0644]
bin/tests/system/checkconf/bad-kasp-key4.conf [new file with mode: 0644]
bin/tests/system/checkconf/good-kasp.conf
bin/tests/system/checkconf/kasp-ignore-keylen.conf
bin/tests/system/checkconf/tests.sh
doc/arm/Bv9ARM-book.xml
lib/bind9/check.c
lib/dns/include/dns/kasp.h
lib/isccfg/kaspconf.c
lib/isccfg/namedconf.c

diff --git a/bin/tests/system/checkconf/bad-kasp-key1.conf b/bin/tests/system/checkconf/bad-kasp-key1.conf
new file mode 100644 (file)
index 0000000..628788c
--- /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 "badalg" {
+       keys {
+               csk lifetime unlimited algorithm ceasarscipher;
+       };
+};
+
+zone "example.net" {
+       type master;
+       file "example.db";
+       dnssec-policy "badalg";
+};
diff --git a/bin/tests/system/checkconf/bad-kasp-key2.conf b/bin/tests/system/checkconf/bad-kasp-key2.conf
new file mode 100644 (file)
index 0000000..b6f513f
--- /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 "badalg" {
+       keys {
+               csk lifetime unlimited algorithm 8 4097;
+       };
+};
+
+zone "example.net" {
+       type master;
+       file "example.db";
+       dnssec-policy "badalg";
+};
diff --git a/bin/tests/system/checkconf/bad-kasp-key3.conf b/bin/tests/system/checkconf/bad-kasp-key3.conf
new file mode 100644 (file)
index 0000000..5a93301
--- /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 "badalg" {
+       keys {
+               csk lifetime unlimited algorithm rsasha512 1023;
+       };
+};
+
+zone "example.net" {
+       type master;
+       file "example.db";
+       dnssec-policy "badalg";
+};
diff --git a/bin/tests/system/checkconf/bad-kasp-key4.conf b/bin/tests/system/checkconf/bad-kasp-key4.conf
new file mode 100644 (file)
index 0000000..785b3ca
--- /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 "badalg" {
+       keys {
+               csk lifetime unlimited algorithm 5 511;
+       };
+};
+
+zone "example.net" {
+       type master;
+       file "example.db";
+       dnssec-policy "badalg";
+};
index 6dcc404559df83c3e4bafa708cdab41171fd0b8f..ae4c319e088161012bb5ec9b63d4d084e7972c6e 100644 (file)
@@ -17,9 +17,9 @@
 dnssec-policy "test" {
        dnskey-ttl 3600;
        keys {
-               ksk key-directory lifetime P1Y algorithm 13;
+               ksk key-directory lifetime P1Y algorithm ecdsa256;
                zsk lifetime P30D algorithm 13;
-               csk key-directory lifetime unlimited algorithm 8 2048;
+               csk key-directory lifetime unlimited algorithm rsasha256 2048;
        };
        max-zone-ttl 86400;
        parent-ds-ttl 7200;
index 5874bdb88738c0e4dbcddf25cb59b3e3a41cd9d2..b2680bd74df5d1de82452efe026ab29847518211 100644 (file)
@@ -12,9 +12,7 @@
 dnssec-policy "warn-length" {
        keys {
                // Algorithm 13 has predefined length, warn about length param.
-               csk lifetime unlimited algorithm 13 2048;
-               // Algorithm 5 length out of range, warn about length param.
-               csk lifetime unlimited algorithm 5 4097;
+               csk lifetime unlimited algorithm ecdsa256 2048;
        };
 };
 
index 814b3b761b3da2112adcad504b99533351781b09..07fc06cd1f03ea869b98fc5ff9ad5bbfe21ae2a3 100644 (file)
@@ -475,9 +475,9 @@ if [ $ret != 0 ]; then echo_i "failed"; ret=1; fi
 status=`expr $status + $ret`
 
 n=`expr $n + 1`
-echo_i "checking named-checkconf kasp warnings ($n)"
+echo_i "checking named-checkconf kasp errors ($n)"
 ret=0
-$CHECKCONF kasp-and-other-dnssec-options.conf > checkconf.out$n 2>&1
+$CHECKCONF kasp-and-other-dnssec-options.conf > checkconf.out$n 2>&1 && ret=1
 grep "'auto-dnssec maintain;' cannot be configured if dnssec-policy is also set" < checkconf.out$n > /dev/null || ret=1
 grep "dnskey-sig-validity: cannot be configured if dnssec-policy is also set" < checkconf.out$n > /dev/null || ret=1
 grep "dnssec-dnskey-kskonly: cannot be configured if dnssec-policy is also set" < checkconf.out$n > /dev/null || ret=1
@@ -490,11 +490,10 @@ if [ $ret != 0 ]; then echo_i "failed"; fi
 status=`expr $status + $ret`
 
 n=`expr $n + 1`
-echo_i "checking named-checkconf kasp key warnings ($n)"
+echo_i "checking named-checkconf kasp predefined key lengths ($n)"
 ret=0
-$CHECKCONF kasp-ignore-keylen.conf > checkconf.out$n 2>&1
-grep "dnssec-policy: key algorithm 13 has predefined length, ignoring length value 2048" < checkconf.out$n > /dev/null || ret=1
-grep "dnssec-policy: key with algorithm 5 has invalid key length, ignoring length value 4097" < checkconf.out$n > /dev/null || ret=1
+$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
 if [ $ret != 0 ]; then echo_i "failed"; fi
 status=`expr $status + $ret`
 
index 28f88f89da09c0b2677f8f7362f98e69d3efffc6..77445bd79ee70be86da71eaa4967497194ca77ea 100644 (file)
@@ -11113,9 +11113,9 @@ example.com                 CNAME   rpz-tcp-only.
                </para>
 
 <programlisting>keys {
-    ksk key-directory lifetime unlimited algorithm 8 2048;
+    ksk key-directory lifetime unlimited algorithm rsasha1 2048;
     zsk key-directory lifetime P30D algorithm 8;
-    csk key-directory lifetime P6MT12H3M15S algorithm 13;
+    csk key-directory lifetime P6MT12H3M15S algorithm ecdsa256;
 };
 </programlisting>
 
@@ -11150,10 +11150,11 @@ example.com                 CNAME   rpz-tcp-only.
                </para>
                <para>
                  The <command>algorithm</command> parameter(s) are the key's
-                 algorithm, expressed numerically, and its size in bits.  The
-                 size may be omitted, as shown in the example for the
-                 second and third keys; in this case an appropriate
-                 default size will be used.
+                 algorithm, expressed either as a string ("rsasha256",
+                 "ecdsa384", etc) or as a decimal number, and the key's
+                 size in bits. The size may be omitted, as shown in
+                 the example for the second and third keys; in this case
+                 an appropriate default size will be used.
                </para>
              </listitem>
            </varlistentry>
index f085dd2a33ba5897ef2f64a5fe48f8d1a43615f8..f34b1132faaa1ad5c62bf1fe24fd6165c4efbd1f 100644 (file)
@@ -976,11 +976,12 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx,
        if (obj != NULL) {
                bool bad_kasp = false;
                bool bad_name = false;
+
                if (optlevel != optlevel_config && !cfg_obj_isstring(obj)) {
                        bad_kasp = true;
                } else if (optlevel == optlevel_config) {
                        dns_kasplist_t list;
-                       dns_kasp_t* kasp, *kasp_next;
+                       dns_kasp_t *kasp = NULL, *kasp_next = NULL;
 
                        ISC_LIST_INIT(list);
 
@@ -989,11 +990,11 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx,
                                     element != NULL;
                                     element = cfg_list_next(element))
                                {
+                                       isc_result_t ret;
                                        cfg_obj_t *kconfig =
                                                     cfg_listelt_value(element);
 
-                                       if (!cfg_obj_istuple(kconfig))
-                                       {
+                                       if (!cfg_obj_istuple(kconfig)) {
                                                bad_kasp = true;
                                                continue;
                                        }
@@ -1001,17 +1002,24 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx,
                                                bad_name = true;
                                                continue;
                                        }
-                                       kasp = NULL;
-                                       (void)cfg_kasp_fromconfig(kconfig, mctx,
+
+                                       ret = cfg_kasp_fromconfig(kconfig, mctx,
                                                                  logctx,
                                                                  &list, &kasp);
+                                       if (ret != ISC_R_SUCCESS) {
+                                               if (result == ISC_R_SUCCESS) {
+                                                       result = ret;
+                                               }
+                                       }
+
                                        if (kasp != NULL) {
                                                dns_kasp_detach(&kasp);
                                        }
                                }
                        }
 
-                       for (kasp = ISC_LIST_HEAD(list); kasp != NULL;
+                       for (kasp = ISC_LIST_HEAD(list);
+                            kasp != NULL;
                             kasp = kasp_next)
                        {
                                kasp_next = ISC_LIST_NEXT(kasp, link);
index e98a486e068e7ece320c3ce4678928937a644150..c9fd8ba8d60eb9ee9e27fe93a30c0427f6f211cd 100644 (file)
@@ -45,7 +45,7 @@ struct dns_kasp_key {
 
        /* Configuration */
        uint32_t                        lifetime;
-       uint32_t                        algorithm;
+       uint8_t                         algorithm;
        int                             length;
        uint8_t                         role;
 };
index 9538be6376a2e2f543bfe5979aac8e101eeebd58..76fc5d050bdd0ef7a1f5472288812843ce546e17 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <isc/mem.h>
 #include <isc/print.h>
+#include <isc/region.h>
 #include <isc/string.h>
 #include <isc/util.h>
 
@@ -25,6 +26,8 @@
 #include <dns/kasp.h>
 #include <dns/keyvalues.h>
 #include <dns/log.h>
+#include <dns/result.h>
+#include <dns/secalg.h>
 
 
 /*
@@ -65,7 +68,7 @@ get_duration(const cfg_obj_t **maps, const char* option, uint32_t dfl)
  * Create a new kasp key derived from configuration.
  */
 static isc_result_t
-cfg_kaspkey_fromconfig(const cfg_obj_t *config, dns_kasp_tkasp,
+cfg_kaspkey_fromconfig(const cfg_obj_t *config, dns_kasp_t *kasp,
                       isc_log_t *logctx)
 {
        isc_result_t result;
@@ -86,6 +89,7 @@ cfg_kaspkey_fromconfig(const cfg_obj_t *config, dns_kasp_t* kasp,
        } else {
                const char *rolestr = NULL;
                const cfg_obj_t *obj = NULL;
+               isc_consttextregion_t alg;
 
                rolestr = cfg_obj_asstring(cfg_tuple_get(config, "role"));
                if (strcmp(rolestr, "ksk") == 0) {
@@ -104,7 +108,17 @@ cfg_kaspkey_fromconfig(const cfg_obj_t *config, dns_kasp_t* kasp,
                }
 
                obj = cfg_tuple_get(config, "algorithm");
-               key->algorithm = cfg_obj_asuint32(obj);
+               alg.base = cfg_obj_asstring(obj);
+               alg.length = strlen(alg.base);
+               result = dns_secalg_fromtext(&key->algorithm,
+                                            (isc_textregion_t *) &alg);
+               if (result != ISC_R_SUCCESS) {
+                       cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
+                                   "dnssec-policy: bad algorithm %s",
+                                   alg.base);
+                       result = DNS_R_BADALG;
+                       goto cleanup;
+               }
 
                obj = cfg_tuple_get(config, "length");
                if (cfg_obj_isuint32(obj)) {
@@ -121,10 +135,11 @@ cfg_kaspkey_fromconfig(const cfg_obj_t *config, dns_kasp_t* kasp,
                                        cfg_obj_log(obj, logctx,
                                                    ISC_LOG_ERROR,
                                                    "dnssec-policy: key with "
-                                                   "algorithm %u has invalid "
-                                                   "key length",
-                                                   key->algorithm);
-                                       return (ISC_R_RANGE);
+                                                   "algorithm %s has invalid "
+                                                   "key length %u",
+                                                   alg.base, size);
+                                       result = ISC_R_RANGE;
+                                       goto cleanup;
                                }
                                break;
                        case DNS_KEYALG_ECDSA256:
@@ -132,10 +147,9 @@ cfg_kaspkey_fromconfig(const cfg_obj_t *config, dns_kasp_t* kasp,
                        case DNS_KEYALG_ED25519:
                        case DNS_KEYALG_ED448:
                                cfg_obj_log(obj, logctx, ISC_LOG_WARNING,
-                                           "dnssec-policy: key algorithm %u "
+                                           "dnssec-policy: key algorithm %s "
                                            "has predefined length; ignoring "
-                                           "length value %u", key->algorithm,
-                                           size);
+                                           "length value %u", alg.base, size);
                        default:
                                break;
                        }
@@ -145,7 +159,13 @@ cfg_kaspkey_fromconfig(const cfg_obj_t *config, dns_kasp_t* kasp,
        }
 
        dns_kasp_addkey(kasp, key);
+       return (ISC_R_SUCCESS);
+
+cleanup:
+
+       dns_kasp_key_destroy(key);
        return (result);
+
 }
 
 isc_result_t
index 0753819090c1664815c500f34442ae970db0f8d6..b0216d453175482a69123620d7d0a9f75b571e1c 100644 (file)
@@ -540,10 +540,10 @@ static cfg_type_t cfg_type_dnsseckeystore = {
 /*%
  * A dnssec key, as used in the "keys" statement in a "dnssec-policy".
  */
-static keyword_type_t algorithm_kw = { "algorithm", &cfg_type_uint32 };
+static keyword_type_t algorithm_kw = { "algorithm", &cfg_type_ustring };
 static cfg_type_t cfg_type_algorithm = {
        "algorithm", parse_keyvalue, print_keyvalue,
-       doc_keyvalue, &cfg_rep_uint32, &algorithm_kw
+       doc_keyvalue, &cfg_rep_string, &algorithm_kw
 };
 
 static keyword_type_t lifetime_kw = { "lifetime",