]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Add code for creating kasp from config
authorMatthijs Mekking <matthijs@isc.org>
Wed, 11 Sep 2019 08:58:44 +0000 (10:58 +0200)
committerMatthijs Mekking <matthijs@isc.org>
Wed, 6 Nov 2019 21:31:44 +0000 (22:31 +0100)
Add code for creating, configuring, and destroying KASP keys.  When
using the default policy, create one CSK, no rollover.

lib/isccfg/Makefile.in
lib/isccfg/include/isccfg/kaspconf.h [new file with mode: 0644]
lib/isccfg/kaspconf.c [new file with mode: 0644]
lib/isccfg/win32/libisccfg.def
lib/isccfg/win32/libisccfg.vcxproj.filters.in
lib/isccfg/win32/libisccfg.vcxproj.in
util/copyrights

index a04e88bcaa57c75732297a92a934ed2b88573ede..269f4c6963a458982d9663b13da5a5bef2398d1e 100644 (file)
@@ -35,11 +35,11 @@ SUBDIRS =   include
 TESTDIRS =     @UNITTESTS@
 
 # Alphabetically
-OBJS =         aclconf.@O@ dnsconf.@O@ log.@O@ namedconf.@O@ \
+OBJS =         aclconf.@O@ dnsconf.@O@ kaspconf.@O@ log.@O@ namedconf.@O@ \
                parser.@O@ version.@O@
 
 # Alphabetically
-SRCS =         aclconf.c dnsconf.c log.c namedconf.c \
+SRCS =         aclconf.c dnsconf.c kaspconf.c log.c namedconf.c \
                parser.c version.c
 
 TARGETS =      timestamp
diff --git a/lib/isccfg/include/isccfg/kaspconf.h b/lib/isccfg/include/isccfg/kaspconf.h
new file mode 100644 (file)
index 0000000..9d18f44
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ */
+
+
+#ifndef ISCCFG_KASPCONF_H
+#define ISCCFG_KASPCONF_H 1
+
+#include <isc/lang.h>
+
+#include <isccfg/cfg.h>
+
+#include <dns/types.h>
+
+/***
+ *** Functions
+ ***/
+
+ISC_LANG_BEGINDECLS
+
+isc_result_t
+cfg_kasp_fromconfig(const cfg_obj_t *config, isc_mem_t* mctx,
+                   dns_kasplist_t *kasplist, dns_kasp_t **kaspp);
+/*%<
+ * Create and configure a KASP. If 'config' is NULL, the default configuration
+ * is used. If a 'kasplist' is provided, a lookup happens and if a KASP
+ * already exists with the same name, no new KASP is created, and no attach to
+ * 'kaspp' happens.
+ *
+ * Requires:
+ *
+ *\li  'mctx' is a valid memory context.
+ *
+ *\li  'name' is a valid C string.
+ *
+ *\li  kaspp != NULL && *kaspp == NULL
+ *
+ * Returns:
+ *
+ *\li  #ISC_R_SUCCESS  If creating and configuring the KASP succeeds.
+ *\li  #ISC_R_EXISTS   If 'kasplist' already has a kasp structure with 'name'.
+ *\li  #ISC_R_NOMEMORY
+ *
+ *\li  Other errors are possible.
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISCCFG_KASPCONF_H */
diff --git a/lib/isccfg/kaspconf.c b/lib/isccfg/kaspconf.c
new file mode 100644 (file)
index 0000000..eafb4c3
--- /dev/null
@@ -0,0 +1,206 @@
+/*
+ * 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.
+ */
+
+#include <inttypes.h>
+#include <stdbool.h>
+#include <stdlib.h>
+
+#include <isc/mem.h>
+#include <isc/print.h>
+#include <isc/string.h>
+#include <isc/util.h>
+
+#include <isccfg/namedconf.h>
+#include <isccfg/cfg.h>
+#include <isccfg/kaspconf.h>
+
+#include <dns/kasp.h>
+#include <dns/keyvalues.h>
+#include <dns/log.h>
+
+
+/*
+ * Utility function for getting a configuration option.
+ */
+static isc_result_t
+confget(cfg_obj_t const * const *maps, const char *name, const cfg_obj_t **obj)
+{
+       for (size_t i = 0;; i++) {
+               if (maps[i] == NULL) {
+                       return (ISC_R_NOTFOUND);
+               }
+               if (cfg_map_get(maps[i], name, obj) == ISC_R_SUCCESS) {
+                       return (ISC_R_SUCCESS);
+               }
+       }
+}
+
+/*
+ * Utility function for configuring durations.
+ */
+static time_t
+get_duration(const cfg_obj_t **maps, const char* option, time_t dfl)
+{
+       const cfg_obj_t *obj;
+       isc_result_t result;
+       obj = NULL;
+
+       result = confget(maps, option, &obj);
+       if (result == ISC_R_NOTFOUND) {
+               return (dfl);
+       }
+       INSIST(result == ISC_R_SUCCESS);
+       return (cfg_obj_asduration(obj));
+}
+
+/*
+ * Create a new kasp key derived from configuration.
+ */
+static isc_result_t
+cfg_kaspkey_fromconfig(const cfg_obj_t *config, dns_kasp_t* kasp)
+{
+       isc_result_t result;
+       dns_kasp_key_t *key = NULL;
+
+       /* Create a new key reference. */
+       result = dns_kasp_key_create(kasp->mctx, &key);
+       if (result != ISC_R_SUCCESS) {
+               return (result);
+       }
+       if (config == NULL) {
+               /* We are creating a key reference for the default kasp. */
+               key->role |= DNS_KASP_KEY_ROLE_KSK | DNS_KASP_KEY_ROLE_ZSK;
+               key->lifetime = 0;
+               key->algorithm = DNS_KEYALG_ECDSA256;
+               key->length = -1;
+       } else {
+               const char* rolestr;
+               const cfg_obj_t* obj;
+
+               rolestr = cfg_obj_asstring(cfg_tuple_get(config, "role"));
+               if (strcmp(rolestr, "ksk") == 0) {
+                       key->role |= DNS_KASP_KEY_ROLE_KSK;
+               } else if (strcmp(rolestr, "zsk") == 0) {
+                       key->role |= DNS_KASP_KEY_ROLE_ZSK;
+               } else if (strcmp(rolestr, "csk") == 0) {
+                       key->role |= DNS_KASP_KEY_ROLE_KSK;
+                       key->role |= DNS_KASP_KEY_ROLE_ZSK;
+               }
+               key->lifetime = cfg_obj_asduration(
+                                            cfg_tuple_get(config, "lifetime"));
+               key->algorithm = cfg_obj_asuint32(
+                                           cfg_tuple_get(config, "algorithm"));
+               obj = cfg_tuple_get(config, "length");
+               if (cfg_obj_isuint32(obj)) {
+                       key->length = cfg_obj_asuint32(obj);
+               }
+       }
+       ISC_LIST_APPEND(kasp->keys, key, link);
+       ISC_INSIST(!(ISC_LIST_EMPTY(kasp->keys)));
+       return (result);
+}
+
+isc_result_t
+cfg_kasp_fromconfig(const cfg_obj_t *config, isc_mem_t* mctx,
+                   dns_kasplist_t *kasplist, dns_kasp_t **kaspp)
+{
+       isc_result_t result;
+       const cfg_obj_t *maps[2];
+       const cfg_obj_t *koptions = NULL;
+       const cfg_obj_t *keys = NULL;
+       const cfg_listelt_t *element = NULL;
+       const char *kaspname = NULL;
+       dns_kasp_t *kasp = NULL;
+       int i = 0;
+
+       REQUIRE(kaspp != NULL && *kaspp == NULL);
+
+       kaspname = (config != NULL) ?
+                   cfg_obj_asstring(cfg_tuple_get(config, "name")) :
+                   "default";
+
+       result = dns_kasplist_find(kasplist, kaspname, &kasp);
+
+       if (result == ISC_R_SUCCESS) {
+               return (ISC_R_EXISTS);
+       }
+       if (result != ISC_R_NOTFOUND) {
+               return (result);
+       }
+
+       /* No kasp with configured name was found in list, create new one. */
+       INSIST(kasp == NULL);
+       result = dns_kasp_create(mctx, kaspname, &kasp);
+       if (result != ISC_R_SUCCESS) {
+               return (result);
+       }
+       INSIST(kasp != NULL);
+
+       /* Append it to the list for future lookups. */
+       ISC_LIST_APPEND(*kasplist, kasp, link);
+       ISC_INSIST(!(ISC_LIST_EMPTY(*kasplist)));
+
+       /* Now configure. */
+       INSIST(DNS_KASP_VALID(kasp));
+
+       if (config != NULL) {
+               koptions = cfg_tuple_get(config, "options");
+               maps[i++] = koptions;
+       }
+       maps[i] = NULL;
+
+       /* Configuration: Signatures */
+       kasp->signatures_refresh = get_duration(
+               maps, "signatures-refresh", DNS_KASP_SIG_REFRESH);
+       kasp->signatures_validity = get_duration(
+               maps, "signatures-validity", DNS_KASP_SIG_VALIDITY);
+       kasp->signatures_validity_dnskey = get_duration(
+               maps, "signatures-validity-dnskey",
+               DNS_KASP_SIG_VALIDITY_DNSKEY);
+
+       /* Configuration: Keys */
+       kasp->dnskey_ttl = get_duration(maps, "dnskey-ttl", DNS_KASP_KEY_TTL);
+       kasp->publish_safety = get_duration(maps, "publish-safety",
+                                           DNS_KASP_PUBLISH_SAFETY);
+       kasp->retire_safety = get_duration(maps, "retire-safety",
+                                          DNS_KASP_RETIRE_SAFETY);
+
+       (void)confget(maps, "keys", &keys);
+       if (keys == NULL) {
+               result = cfg_kaspkey_fromconfig(NULL, kasp);
+               if (result != ISC_R_SUCCESS) {
+                       goto cleanup;
+               }
+       } else {
+               for (element = cfg_list_first(keys); element != NULL;
+                    element = cfg_list_next(element))
+               {
+                       cfg_obj_t *kobj = cfg_listelt_value(element);
+                       result = cfg_kaspkey_fromconfig(kobj, kasp);
+                       if (result != ISC_R_SUCCESS) {
+                               goto cleanup;
+                       }
+               }
+       }
+       ISC_INSIST(!(ISC_LIST_EMPTY(kasp->keys)));
+
+       // TODO: Rest of the configuration
+
+       /* Success: Attach the kasp to the pointer and return. */
+       dns_kasp_attach(kasp, kaspp);
+       return (ISC_R_SUCCESS);
+
+cleanup:
+
+       /* Something bad happened, detach (destroys kasp) and return error. */
+       dns_kasp_detach(&kasp);
+       return (result);
+}
index 61e6e86ce4cfed0e2a7715d2efc32c855b19369f..1c40b3c34b1cbb256023df60be53a518c18f9f69 100644 (file)
@@ -24,6 +24,7 @@ cfg_doc_tuple
 cfg_doc_void
 cfg_gettoken
 cfg_is_enum
+cfg_kasp_fromconfig
 cfg_list_first
 cfg_list_length
 cfg_list_next
index 46b4e54bc577e44460c4e934df0b1b5e63deaa25..91d4202d7ed4852981a34bd385bdbe8ab528117d 100644 (file)
@@ -30,6 +30,9 @@
     <ClCompile Include="..\dnsconf.c">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="..\kaspconf.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
     <ClCompile Include="..\log.c">
       <Filter>Source Files</Filter>
     </ClCompile>
@@ -53,6 +56,9 @@
     <ClInclude Include="..\include\isccfg\grammar.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="..\include\isccfg\kaspconf.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
     <ClInclude Include="..\include\isccfg\log.h">
       <Filter>Header Files</Filter>
     </ClInclude>
@@ -63,4 +69,4 @@
       <Filter>Header Files</Filter>
     </ClInclude>
   </ItemGroup>
-</Project>
\ No newline at end of file
+</Project>
index a900a11e960eae44e8d068d3485a7ef15c205dd0..584341f82faad2bbdd89c3b09703830b970fc151 100644 (file)
   <ItemGroup>
     <ClCompile Include="..\aclconf.c" />
     <ClCompile Include="..\dnsconf.c" />
+    <ClCompile Include="..\kaspconf.c" />
     <ClCompile Include="..\log.c" />
     <ClCompile Include="..\namedconf.c" />
     <ClCompile Include="..\parser.c" />
     <ClInclude Include="..\include\isccfg\dnsconf.h" />
     <ClInclude Include="..\include\isccfg\cfg.h" />
     <ClInclude Include="..\include\isccfg\grammar.h" />
+    <ClInclude Include="..\include\isccfg\kaspconf.h" />
     <ClInclude Include="..\include\isccfg\log.h" />
     <ClInclude Include="..\include\isccfg\namedconf.h" />
     <ClInclude Include="..\include\isccfg\version.h" />
index cff1a45fc0435ea09d219b59d8f968b8ef923dc2..f81e084f1f62db1f3ebf43b59d910713b3cea8b6 100644 (file)
 ./lib/isccfg/include/isccfg/cfg.h              C       2000,2001,2002,2004,2005,2006,2007,2010,2013,2014,2015,2016,2018,2019
 ./lib/isccfg/include/isccfg/dnsconf.h          C       2009,2016,2018,2019
 ./lib/isccfg/include/isccfg/grammar.h          C       2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2013,2014,2015,2016,2017,2018,2019
+./lib/isccfg/include/isccfg/kaspconf.h         C       2019
 ./lib/isccfg/include/isccfg/log.h              C       2001,2004,2005,2006,2007,2009,2016,2018,2019
 ./lib/isccfg/include/isccfg/namedconf.h                C       2002,2004,2005,2006,2007,2009,2010,2014,2016,2018,2019
 ./lib/isccfg/include/isccfg/version.h          C       2001,2004,2005,2006,2007,2016,2018,2019
+./lib/isccfg/kaspconf.c                                C       2019
 ./lib/isccfg/log.c                             C       2001,2004,2005,2006,2007,2016,2018,2019
 ./lib/isccfg/namedconf.c                       C       2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018,2019
 ./lib/isccfg/parser.c                          C       2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018,2019