]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Check if key-store exists
authorMatthijs Mekking <matthijs@isc.org>
Wed, 9 Feb 2022 10:19:21 +0000 (11:19 +0100)
committerMatthijs Mekking <matthijs@isc.org>
Thu, 25 Jan 2024 13:38:12 +0000 (14:38 +0100)
Add checkconf check to ensure that the used key-store in the keys
section exists. Error if that is not the case. We also don't allow
the special keyword 'key-directory' as that is internally used to
signal that the zone's key-directory should be used.

bin/tests/system/checkconf/bad-kasp-keystore.conf [new file with mode: 0644]
bin/tests/system/checkconf/bad-keystore-key-directory.conf [new file with mode: 0644]
lib/dns/include/dns/kasp.h
lib/dns/include/dns/keystore.h
lib/dns/kasp.c
lib/isccfg/check.c

diff --git a/bin/tests/system/checkconf/bad-kasp-keystore.conf b/bin/tests/system/checkconf/bad-kasp-keystore.conf
new file mode 100644 (file)
index 0000000..8bbe9a3
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * SPDX-License-Identifier: MPL-2.0
+ *
+ * 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 https://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+// Bad dnssec-policy configuration because there is no key-store with this name.
+dnssec-policy "bad" {
+       keys {
+               csk key-store "ks404" lifetime unlimited algorithm 13;
+       };
+};
diff --git a/bin/tests/system/checkconf/bad-keystore-key-directory.conf b/bin/tests/system/checkconf/bad-keystore-key-directory.conf
new file mode 100644 (file)
index 0000000..7007cf8
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * SPDX-License-Identifier: MPL-2.0
+ *
+ * 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 https://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+// Bad key-store configuration because the keyword 'key-directory' may not
+// be used.
+key-store "key-directory" {
+       directory ".";
+};
+
+dnssec-policy "bad" {
+       keys {
+               csk key-store "key-directory" lifetime unlimited algorithm 13;
+       };
+};
index 92bf406c98b0379aeef0eb519a1dde0297e22d09..288c754c9fdebb9cae0a47e0ea8f79e9c81ec0e8 100644 (file)
@@ -51,11 +51,11 @@ struct dns_kasp_key {
        ISC_LINK(struct dns_kasp_key) link;
 
        /* Configuration */
-       char     *keystore;
-       uint32_t lifetime;
-       uint8_t  algorithm;
-       int      length;
-       uint8_t  role;
+       const char *keystore;
+       uint32_t    lifetime;
+       uint8_t     algorithm;
+       int         length;
+       uint8_t     role;
 };
 
 struct dns_kasp_nsec3param {
@@ -644,6 +644,21 @@ dns_kasp_key_lifetime(dns_kasp_key_t *key);
  *
  */
 
+const char *
+dns_kasp_key_keystore(dns_kasp_key_t *key);
+/*%<
+ * The keystore reference of this key.
+ *
+ * Requires:
+ *
+ *\li  key != NULL
+ *
+ * Returns:
+ *
+ *\li  Keystore of key, or NULL if zone's key-directory is used.
+ *
+ */
+
 bool
 dns_kasp_key_ksk(dns_kasp_key_t *key);
 /*%<
index f898817f5739a0c6a98492ff0f2ccb2619dcd02c..a5d5840aa10768d577731227a587a91694a7c08a 100644 (file)
@@ -57,6 +57,8 @@ struct dns_keystore {
 #define DNS_KEYSTORE_MAGIC     ISC_MAGIC('K', 'E', 'Y', 'S')
 #define DNS_KEYSTORE_VALID(ks) ISC_MAGIC_VALID(ks, DNS_KEYSTORE_MAGIC)
 
+#define DNS_KEYSTORE_KEYDIRECTORY "key-directory"
+
 isc_result_t
 dns_keystore_create(isc_mem_t *mctx, const char *name, dns_keystore_t **kspp);
 /*%<
index aa6637f59432f05a92b127ee4c2bed1af57fc3c1..de8d757fd449725dcfb5c3375db1ec7cc2a26416 100644 (file)
@@ -408,7 +408,9 @@ dns_kasp_key_destroy(dns_kasp_key_t *key) {
        REQUIRE(key != NULL);
 
        if (key->keystore != NULL) {
-               isc_mem_free(key->mctx, key->keystore);
+               char *ks;
+               DE_CONST(key->keystore, ks);
+               isc_mem_free(key->mctx, ks);
                key->keystore = NULL;
        }
        isc_mem_putanddetach(&key->mctx, key, sizeof(*key));
@@ -472,6 +474,13 @@ dns_kasp_key_lifetime(dns_kasp_key_t *key) {
        return (key->lifetime);
 }
 
+const char *
+dns_kasp_key_keystore(dns_kasp_key_t *key) {
+       REQUIRE(key != NULL);
+
+       return (key->keystore);
+}
+
 bool
 dns_kasp_key_ksk(dns_kasp_key_t *key) {
        REQUIRE(key != NULL);
index c4e09f1c8833de9efb2a719814da23a3b5c80c70..5929b27888dd88a0a9ae96162c9557e72ce1a4f8 100644 (file)
@@ -47,6 +47,7 @@
 #include <dns/dnstap.h>
 #include <dns/fixedname.h>
 #include <dns/kasp.h>
+#include <dns/keystore.h>
 #include <dns/keyvalues.h>
 #include <dns/peer.h>
 #include <dns/rbt.h>
@@ -1187,6 +1188,39 @@ check_port(const cfg_obj_t *options, isc_log_t *logctx, const char *type,
        return (ISC_R_SUCCESS);
 }
 
+static isc_result_t
+check_keystore(const cfg_obj_t *obj, isc_log_t *logctx, dns_kasp_t *kasp,
+              dns_keystorelist_t *kslist) {
+       isc_result_t result = ISC_R_SUCCESS;
+       dns_kasp_key_t *kkey;
+       dns_keystore_t *ks = NULL;
+
+       REQUIRE(kasp != NULL);
+
+       dns_kasp_freeze(kasp);
+
+       for (kkey = ISC_LIST_HEAD(dns_kasp_keys(kasp)); kkey != NULL;
+            kkey = ISC_LIST_NEXT(kkey, link))
+       {
+               const char *keystore = dns_kasp_key_keystore(kkey);
+               if (keystore != NULL && strcmp("key-directory", keystore) != 0)
+               {
+                       if (dns_keystorelist_find(kslist, keystore, &ks) ==
+                           ISC_R_SUCCESS) {
+                               dns_keystore_detach(&ks);
+                       } else {
+                               cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
+                                           "key-store '%s' not found",
+                                           keystore);
+                               result = ISC_R_FAILURE;
+                       }
+               }
+       }
+
+       dns_kasp_thaw(kasp);
+       return (result);
+}
+
 static isc_result_t
 check_options(const cfg_obj_t *options, const cfg_obj_t *config,
              bool check_algorithms, isc_log_t *logctx, isc_mem_t *mctx,
@@ -1200,6 +1234,8 @@ check_options(const cfg_obj_t *options, const cfg_obj_t *config,
        const char *str;
        isc_buffer_t b;
        uint32_t lifetime = 3600;
+       dns_keystorelist_t kslist;
+       dns_keystore_t *ks = NULL, *ks_next = NULL;
        const char *ccalg = "siphash24";
        cfg_aclconfctx_t *actx = NULL;
        static const char *sources[] = {
@@ -1329,6 +1365,55 @@ check_options(const cfg_obj_t *options, const cfg_obj_t *config,
                }
        }
 
+       /*
+        * Check key-store.
+        */
+       ISC_LIST_INIT(kslist);
+
+       obj = NULL;
+       (void)cfg_map_get(options, "key-store", &obj);
+       if (obj != NULL) {
+               if (optlevel != optlevel_config) {
+                       cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
+                                   "may only be configured at the top level");
+                       if (result == ISC_R_SUCCESS) {
+                               result = ISC_R_FAILURE;
+                       }
+               } else if (cfg_obj_islist(obj)) {
+                       for (element = cfg_list_first(obj); element != NULL;
+                            element = cfg_list_next(element))
+                       {
+                               isc_result_t ret;
+                               const char *name;
+                               cfg_obj_t *kconfig = cfg_listelt_value(element);
+                               if (!cfg_obj_istuple(kconfig)) {
+                                       continue;
+                               }
+                               name = cfg_obj_asstring(cfg_tuple_get(
+                                       cfg_listelt_value(element), "name"));
+                               if (strcmp(DNS_KEYSTORE_KEYDIRECTORY, name) == 0) {
+                                       cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
+                                                   "name '%s' not allowed",
+                                                   DNS_KEYSTORE_KEYDIRECTORY);
+                                       if (result == ISC_R_SUCCESS) {
+                                               result = ISC_R_FAILURE;
+                                       }
+                               }
+
+                               ret = cfg_keystore_fromconfig(
+                                       kconfig, mctx, logctx, &kslist, &ks);
+                               if (ret != ISC_R_SUCCESS) {
+                                       if (result == ISC_R_SUCCESS) {
+                                               result = ret;
+                                       }
+                               }
+                               if (ks != NULL) {
+                                       dns_keystore_detach(&ks);
+                               }
+                       }
+               }
+       }
+
        /*
         * Check dnssec-policy.
         */
@@ -1367,6 +1452,12 @@ check_options(const cfg_obj_t *options, const cfg_obj_t *config,
                                        ret = cfg_kasp_fromconfig(
                                                kconfig, NULL, check_algorithms,
                                                mctx, logctx, &list, &kasp);
+                                       if (ret == ISC_R_SUCCESS) {
+                                               /* Check key-stores of keys */
+                                               ret = check_keystore(
+                                                       obj, logctx, kasp,
+                                                       &kslist);
+                                       }
                                        if (ret != ISC_R_SUCCESS) {
                                                if (result == ISC_R_SUCCESS) {
                                                        result = ret;
@@ -1407,6 +1498,18 @@ check_options(const cfg_obj_t *options, const cfg_obj_t *config,
                }
        }
 
+       /*
+        * Cleanup key-store.
+        */
+       for (ks = ISC_LIST_HEAD(kslist); ks != NULL; ks = ks_next) {
+               ks_next = ISC_LIST_NEXT(ks, link);
+               ISC_LIST_UNLINK(kslist, ks, link);
+               dns_keystore_detach(&ks);
+       }
+
+       /*
+        * Other checks.
+        */
        obj = NULL;
        cfg_map_get(options, "max-rsa-exponent-size", &obj);
        if (obj != NULL) {