From: Matthijs Mekking Date: Wed, 11 Sep 2019 08:58:44 +0000 (+0200) Subject: Add code for creating kasp from config X-Git-Tag: v9.15.6~26^2~34 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7bfac50336f17035325441d56b2193b2e03ddcb5;p=thirdparty%2Fbind9.git Add code for creating kasp from config Add code for creating, configuring, and destroying KASP keys. When using the default policy, create one CSK, no rollover. --- diff --git a/lib/isccfg/Makefile.in b/lib/isccfg/Makefile.in index a04e88bcaa5..269f4c6963a 100644 --- a/lib/isccfg/Makefile.in +++ b/lib/isccfg/Makefile.in @@ -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 index 00000000000..9d18f445dad --- /dev/null +++ b/lib/isccfg/include/isccfg/kaspconf.h @@ -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 + +#include + +#include + +/*** + *** 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 index 00000000000..eafb4c3b354 --- /dev/null +++ b/lib/isccfg/kaspconf.c @@ -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 +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + + +/* + * 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); +} diff --git a/lib/isccfg/win32/libisccfg.def b/lib/isccfg/win32/libisccfg.def index 61e6e86ce4c..1c40b3c34b1 100644 --- a/lib/isccfg/win32/libisccfg.def +++ b/lib/isccfg/win32/libisccfg.def @@ -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 diff --git a/lib/isccfg/win32/libisccfg.vcxproj.filters.in b/lib/isccfg/win32/libisccfg.vcxproj.filters.in index 46b4e54bc57..91d4202d7ed 100644 --- a/lib/isccfg/win32/libisccfg.vcxproj.filters.in +++ b/lib/isccfg/win32/libisccfg.vcxproj.filters.in @@ -30,6 +30,9 @@ Source Files + + Source Files + Source Files @@ -53,6 +56,9 @@ Header Files + + Header Files + Header Files @@ -63,4 +69,4 @@ Header Files - \ No newline at end of file + diff --git a/lib/isccfg/win32/libisccfg.vcxproj.in b/lib/isccfg/win32/libisccfg.vcxproj.in index a900a11e960..584341f82fa 100644 --- a/lib/isccfg/win32/libisccfg.vcxproj.in +++ b/lib/isccfg/win32/libisccfg.vcxproj.in @@ -116,6 +116,7 @@ + @@ -127,6 +128,7 @@ + diff --git a/util/copyrights b/util/copyrights index cff1a45fc04..f81e084f1f6 100644 --- a/util/copyrights +++ b/util/copyrights @@ -2437,9 +2437,11 @@ ./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