]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Add configuration for key-store
authorMatthijs Mekking <matthijs@isc.org>
Thu, 20 Jan 2022 13:00:27 +0000 (14:00 +0100)
committerMatthijs Mekking <matthijs@isc.org>
Thu, 25 Jan 2024 13:38:11 +0000 (14:38 +0100)
Add new configuration for setting key stores. The new 'key-store'
statement allows users to configure key store backends. These can be
of type 'file' (that works the same as 'key-directory') or of type
'pkcs11'. In the latter case, keys should be stored in a HSM that is
accessible through a PKCS#11 interface.

Keys configured within 'dnssec-policy' can now also use the 'key-store'
option to set a specific key store.

Update the checkconf test to accomodate for the new configuration.

bin/tests/system/checkconf/good-kasp.conf
bin/tests/system/checkconf/good.conf.in
doc/misc/options
lib/isccfg/namedconf.c

index d5da98fc6dbaa3284235404da1dcb87640073fc9..40b5793ad07ceaf3f2d00e29aacc98143c163fb6 100644 (file)
@@ -26,7 +26,7 @@ dnssec-policy "test" {
        keys {
                ksk key-directory lifetime P1Y algorithm ecdsa256;
                zsk lifetime P30D algorithm 13;
-               csk key-directory lifetime unlimited algorithm rsasha256 2048;
+               csk key-store "hsm" lifetime unlimited algorithm rsasha256 2048;
        };
        max-zone-ttl 86400;
        nsec3param iterations 0 optout no salt-length 8;
@@ -39,6 +39,10 @@ dnssec-policy "test" {
        signatures-validity-dnskey P14D;
        zone-propagation-delay PT5M;
 };
+key-store "hsm" {
+       directory ".";
+       uri "pkcs11:token=bind9;pin-value=1234";
+};
 options {
        dnssec-policy "default";
 };
index 7d1f6b85760c4ac1129e30f1faba338064f8fb87..b39b20941a7c2cf9198008de6c1912394eacc25d 100644 (file)
@@ -24,8 +24,8 @@ dnssec-policy "test" {
        dnskey-ttl 3600;
        keys {
                ksk key-directory lifetime P1Y algorithm 13 256;
-               zsk key-directory lifetime P30D algorithm 13;
-               csk key-directory lifetime P30D algorithm 8 2048;
+               zsk lifetime P30D algorithm 13;
+               csk key-store "hsm" lifetime P30D algorithm 8 2048;
        };
        max-zone-ttl 86400;
        nsec3param ;
@@ -39,6 +39,10 @@ dnssec-policy "test" {
        signatures-validity-dnskey P14D;
        zone-propagation-delay PT5M;
 };
+key-store "hsm" {
+       directory ".";
+       uri "pkcs11:token=bind9;pin-value=1234";
+};
 options {
        avoid-v4-udp-ports {
                100;
index edf6fb04afbfaaea41f3ff5f2e6be5651d203497..bde27bd36dfe38a5b12b607d1a7aa4e3ac2d5ecb 100644 (file)
@@ -15,7 +15,7 @@ dnssec-policy <string> {
        cds-digest-types { <string>; ... };
        dnskey-ttl <duration>;
        inline-signing <boolean>;
-       keys { ( csk | ksk | zsk ) [ ( key-directory ) ] lifetime <duration_or_unlimited> algorithm <string> [ <integer> ]; ... };
+       keys { ( csk | ksk | zsk ) [ key-directory | key-store <string> ] lifetime <duration_or_unlimited> algorithm <string> [ <integer> ]; ... };
        max-zone-ttl <duration>;
        nsec3param [ iterations <integer> ] [ optout <boolean> ] [ salt-length <integer> ];
        parent-ds-ttl <duration>;
@@ -42,6 +42,11 @@ key <string> {
        secret <string>;
 }; // may occur multiple times
 
+key-store <string> {
+       directory <string>;
+       uri <quoted_string>;
+}; // may occur multiple times
+
 logging {
        category <string> { <string>; ... }; // may occur multiple times
        channel <string> {
index 625edc7f4f1afe39b67fada966df3b43b29402de..216eebce30998f6514aca01ff54f76182f385a9c 100644 (file)
@@ -105,6 +105,7 @@ static cfg_type_t cfg_type_http_description;
 static cfg_type_t cfg_type_ixfrdifftype;
 static cfg_type_t cfg_type_ixfrratio;
 static cfg_type_t cfg_type_key;
+static cfg_type_t cfg_type_keystore;
 static cfg_type_t cfg_type_logfile;
 static cfg_type_t cfg_type_logging;
 static cfg_type_t cfg_type_logseverity;
@@ -477,7 +478,6 @@ static cfg_tuplefielddef_t dnssecpolicy_fields[] = {
        { "options", &cfg_type_dnssecpolicyopts, 0 },
        { NULL, NULL, 0 }
 };
-
 static cfg_type_t cfg_type_dnssecpolicy = {
        "dnssec-policy", cfg_parse_tuple, cfg_print_tuple,
        cfg_doc_tuple,   &cfg_rep_tuple,  dnssecpolicy_fields
@@ -582,10 +582,58 @@ static cfg_type_t cfg_type_dnsseckeyrole = {
 /*%
  * DNSSEC key storage types.
  */
-static const char *dnsseckeystore_enums[] = { "key-directory", NULL };
-static cfg_type_t cfg_type_dnsseckeystore = {
-       "dnssec-key-storage", parse_optional_enum, cfg_print_ustring,
-       doc_optional_enum,    &cfg_rep_string,     dnsseckeystore_enums
+static keyword_type_t keystore_kw = { "key-store", &cfg_type_astring };
+static cfg_type_t cfg_type_keystorage = { "keystorage",           parse_keyvalue,
+                                         print_keyvalue,  doc_keyvalue,
+                                         &cfg_rep_string, &keystore_kw };
+
+static isc_result_t
+parse_keystore(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
+       isc_result_t result;
+       cfg_obj_t *obj = NULL;
+
+       UNUSED(type);
+
+       CHECK(cfg_peektoken(pctx, 0));
+       if (pctx->token.type == isc_tokentype_string &&
+           strcasecmp(TOKEN_STRING(pctx), "key-directory") == 0)
+       {
+               CHECK(cfg_parse_obj(pctx, &cfg_type_ustring, &obj));
+       } else if (pctx->token.type == isc_tokentype_string &&
+                  strcasecmp(TOKEN_STRING(pctx), "key-store") == 0)
+       {
+               CHECK(cfg_parse_obj(pctx, &cfg_type_keystorage, &obj));
+       } else {
+               CHECK(cfg_parse_void(pctx, NULL, &obj));
+       }
+
+       *ret = obj;
+cleanup:
+       return (result);
+}
+
+static void
+doc_keystore(cfg_printer_t *pctx, const cfg_type_t *type) {
+       UNUSED(type);
+
+       cfg_print_cstr(pctx, "[ key-directory | key-store <string> ]");
+}
+
+static void
+print_keystore(cfg_printer_t *pctx, const cfg_obj_t *obj) {
+       REQUIRE(pctx != NULL);
+       REQUIRE(obj != NULL);
+       REQUIRE(obj->type->rep == &cfg_rep_string);
+
+       if (strcasecmp(cfg_obj_asstring(obj), "key-directory") != 0) {
+               cfg_print_cstr(pctx, "key-store ");
+       }
+       cfg_print_ustring(pctx, obj);
+}
+
+static cfg_type_t cfg_type_optional_keystore = {
+       "optionalkeystorage", parse_keystore,  print_keystore,
+       doc_keystore,         &cfg_rep_string, &keystore_kw
 };
 
 /*%
@@ -604,7 +652,7 @@ static cfg_type_t cfg_type_lifetime = { "lifetime",    parse_keyvalue,
 
 static cfg_tuplefielddef_t kaspkey_fields[] = {
        { "role", &cfg_type_dnsseckeyrole, 0 },
-       { "keystore-type", &cfg_type_dnsseckeystore, 0 },
+       { "keystorage", &cfg_type_optional_keystore, 0 },
        { "lifetime", &cfg_type_lifetime, 0 },
        { "algorithm", &cfg_type_algorithm, 0 },
        { "length", &cfg_type_optional_uint32, 0 },
@@ -1143,6 +1191,7 @@ static cfg_clausedef_t namedconf_clauses[] = {
        { "http", &cfg_type_http_description,
          CFG_CLAUSEFLAG_MULTI | CFG_CLAUSEFLAG_NOTCONFIGURED },
 #endif
+       { "key-store", &cfg_type_keystore, CFG_CLAUSEFLAG_MULTI },
        { "logging", &cfg_type_logging, 0 },
        { "lwres", NULL, CFG_CLAUSEFLAG_MULTI | CFG_CLAUSEFLAG_ANCIENT },
        { "masters", &cfg_type_remoteservers,
@@ -2549,6 +2598,29 @@ static cfg_type_t cfg_type_key = { "key",          cfg_parse_named_map,
                                   cfg_print_map, cfg_doc_map,
                                   &cfg_rep_map,  key_clausesets };
 
+/*%
+ * A key-store statement.
+ */
+static cfg_clausedef_t keystore_clauses[] = { { "directory", &cfg_type_astring,
+                                               0 },
+                                             { "uri", &cfg_type_qstring, 0 },
+                                             { NULL, NULL, 0 } };
+
+static cfg_clausedef_t *keystore_clausesets[] = { keystore_clauses, NULL };
+static cfg_type_t cfg_type_keystoreopts = {
+       "keystoreopts", cfg_parse_map, cfg_print_map,
+       cfg_doc_map,    &cfg_rep_map,  keystore_clausesets
+};
+
+static cfg_tuplefielddef_t keystore_fields[] = {
+       { "name", &cfg_type_astring, 0 },
+       { "options", &cfg_type_keystoreopts, 0 },
+       { NULL, NULL, 0 }
+};
+static cfg_type_t cfg_type_keystore = { "key-store",    cfg_parse_tuple,
+                                       cfg_print_tuple, cfg_doc_tuple,
+                                       &cfg_rep_tuple,  keystore_fields };
+
 /*%
  * Clauses that can be found in a 'server' statement.
  *