db.@O@ dbiterator.@O@ dbtable.@O@ diff.@O@ dispatch.@O@ \
dlz.@O@ dns64.@O@ dnsrps.@O@ dnssec.@O@ ds.@O@ dyndb.@O@ \
ecs.@O@ fixedname.@O@ forward.@O@ \
- ipkeylist.@O@ iptable.@O@ journal.@O@ keydata.@O@ \
+ ipkeylist.@O@ iptable.@O@ journal.@O@ kasp.@O@ keydata.@O@ \
keytable.@O@ lib.@O@ log.@O@ lookup.@O@ \
master.@O@ masterdump.@O@ message.@O@ \
name.@O@ ncache.@O@ nsec.@O@ nsec3.@O@ nta.@O@ \
db.c dbiterator.c dbtable.c diff.c dispatch.c \
dlz.c dns64.c dnsrps.c dnssec.c ds.c dyndb.c \
ecs.c fixedname.c forward.c \
- ipkeylist.c iptable.c journal.c keydata.c keytable.c lib.c \
- log.c lookup.c master.c masterdump.c message.c \
+ ipkeylist.c iptable.c journal.c kasp.c keydata.c keytable.c \
+ lib.c log.c lookup.c master.c masterdump.c message.c \
name.c ncache.c nsec.c nsec3.c nta.c \
order.c peer.c portlist.c \
rbt.c rbtdb.c rcode.c rdata.c rdatalist.c \
--- /dev/null
+/*
+ * 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 DNS_KASP_H
+#define DNS_KASP_H 1
+
+/*****
+ ***** Module Info
+ *****/
+
+/*! \file dns/kasp.h
+ * \brief
+ * DNSSEC Key and Signing Policy (KASP)
+ *
+ * A "kasp" is a DNSSEC policy, that determines how a zone should be
+ * signed and maintained.
+ */
+
+#include <time.h>
+
+#include <isc/lang.h>
+#include <isc/magic.h>
+#include <isc/mutex.h>
+#include <isc/refcount.h>
+
+#include <dns/types.h>
+
+ISC_LANG_BEGINDECLS
+
+/* Stores a KASP key */
+struct dns_kasp_key {
+ isc_mem_t* mctx;
+
+ /* Locked by themselves. */
+ isc_refcount_t references;
+
+ /* Under owner's locking control. */
+ ISC_LINK(struct dns_kasp_key) link;
+
+ /* Configuration */
+ time_t lifetime;
+ uint32_t algorithm;
+ int length;
+ uint8_t role;
+};
+
+/* Stores a DNSSEC policy */
+struct dns_kasp {
+ unsigned int magic;
+ isc_mem_t* mctx;
+ char* name;
+
+ /* Internals. */
+ isc_mutex_t lock;
+ bool frozen;
+
+ /* Locked by themselves. */
+ isc_refcount_t references;
+
+ /* Under owner's locking control. */
+ ISC_LINK(struct dns_kasp) link;
+
+ /* Configuration: signatures */
+ uint32_t signatures_refresh;
+ uint32_t signatures_validity;
+ uint32_t signatures_validity_dnskey;
+
+ /* Configuration: Keys */
+ dns_kasp_keylist_t keys;
+ uint32_t dnskey_ttl;
+
+ /* Configuration: Timings */
+ uint32_t publish_safety;
+ uint32_t retire_safety;
+
+ // TODO: The rest of the KASP configuration
+};
+
+#define DNS_KASP_MAGIC ISC_MAGIC('K','A','S','P')
+#define DNS_KASP_VALID(kasp) ISC_MAGIC_VALID(kasp, DNS_KASP_MAGIC)
+
+/* Defaults */
+#define DNS_KASP_SIG_REFRESH (86400*5)
+#define DNS_KASP_SIG_VALIDITY (86400*14)
+#define DNS_KASP_SIG_VALIDITY_DNSKEY (86400*14)
+#define DNS_KASP_KEY_TTL (3600)
+#define DNS_KASP_PUBLISH_SAFETY (300)
+#define DNS_KASP_RETIRE_SAFETY (300)
+
+/* Key roles */
+#define DNS_KASP_KEY_ROLE_KSK 0x01
+#define DNS_KASP_KEY_ROLE_ZSK 0x02
+
+isc_result_t
+dns_kasp_create(isc_mem_t *mctx, const char* name, dns_kasp_t **kaspp);
+/*%<
+ * Create a KASP.
+ *
+ * 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
+ *\li #ISC_R_NOMEMORY
+ *
+ *\li Other errors are possible.
+ */
+
+void
+dns_kasp_attach(dns_kasp_t *source, dns_kasp_t **targetp);
+/*%<
+ * Attach '*targetp' to 'source'.
+ *
+ * Requires:
+ *
+ *\li 'source' is a valid, frozen kasp.
+ *
+ *\li 'targetp' points to a NULL dns_kasp_t *.
+ *
+ * Ensures:
+ *
+ *\li *targetp is attached to source.
+ *
+ *\li While *targetp is attached, the kasp will not shut down.
+ */
+
+void
+dns_kasp_detach(dns_kasp_t **kaspp);
+/*%<
+ * Detach KASP.
+ *
+ * Requires:
+ *
+ *\li 'kaspp' points to a valid dns_kasp_t *
+ *
+ * Ensures:
+ *
+ *\li *kaspp is NULL.
+ */
+
+void
+dns_kasp_freeze(dns_kasp_t *kasp);
+/*%<
+ * Freeze kasp. No changes can be made to kasp configuration while frozen.
+ *
+ * Requires:
+ *
+ *\li 'kasp' is a valid, unfrozen kasp.
+ *
+ * Ensures:
+ *
+ *\li 'kasp' is frozen.
+ */
+
+void
+dns_kasp_thaw(dns_kasp_t *kasp);
+/*%<
+ * Thaw kasp.
+ *
+ * Requires:
+ *
+ *\li 'kasp' is a valid, frozen kasp.
+ *
+ * Ensures:
+ *
+ *\li 'kasp' is no longer frozen.
+ */
+
+const char*
+dns_kasp_getname(dns_kasp_t *kasp);
+/*%<
+ * Get kasp name.
+ *
+ * Requires:
+ *
+ *\li 'kasp' is a valid, frozen kasp.
+ *
+ * Returns:
+ *
+ *\li name of 'kasp'.
+ */
+
+isc_result_t
+dns_kasplist_find(dns_kasplist_t *list, const char *name, dns_kasp_t **kaspp);
+/*%<
+ * Search for a kasp with name 'name' in 'list'.
+ * If found, '*kaspp' is (strongly) attached to it.
+ *
+ * Requires:
+ *
+ *\li 'kaspp' points to a NULL dns_kasp_t *.
+ *
+ * Returns:
+ *
+ *\li #ISC_R_SUCCESS A matching kasp was found.
+ *\li #ISC_R_NOTFOUND No matching kasp was found.
+ */
+
+isc_result_t
+dns_kasp_key_create(isc_mem_t* mctx, dns_kasp_key_t **keyp);
+/*%<
+ * Create a key inside a KASP.
+ *
+ * Requires:
+ *
+ *\li 'mctx' is a valid memory context.
+ *
+ *\li keyp != NULL && *keyp == NULL
+ *
+ * Returns:
+ *
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_NOMEMORY
+ *
+ *\li Other errors are possible.
+ */
+
+void
+dns_kasp_key_destroy(dns_kasp_key_t* key);
+/*%<
+ * Destroy a KASP key.
+ *
+ * Requires:
+ *
+ *\li 'key' is a valid KASP key.
+ *
+ *\li kasp != NULL && key != NULL
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* DNS_KASP_H */
typedef struct dns_geoip_databases dns_geoip_databases_t;
typedef struct dns_iptable dns_iptable_t;
typedef uint32_t dns_iterations_t;
+typedef struct dns_kasp dns_kasp_t;
+typedef ISC_LIST(dns_kasp_t) dns_kasplist_t;
+typedef struct dns_kasp_key dns_kasp_key_t;
+typedef ISC_LIST(dns_kasp_key_t) dns_kasp_keylist_t;
typedef uint16_t dns_keyflags_t;
typedef struct dns_keynode dns_keynode_t;
typedef ISC_LIST(dns_keynode_t) dns_keynodelist_t;
*\li 'zone' to be a valid zone.
*/
+dns_kasp_t*
+dns_zone_getkasp(dns_zone_t *zone);
+/*%<
+ * Returns the current kasp.
+ *
+ * Require:
+ *\li 'zone' to be a valid zone.
+ */
+
+void
+dns_zone_setkasp(dns_zone_t *zone, dns_kasp_t* kasp);
+/*%<
+ * Set kasp for zone. If a kasp is already set, it will be detached.
+ *
+ * Requires:
+ *\li 'zone' to be a valid zone.
+ */
+
void
dns_zone_setoption(dns_zone_t *zone, dns_zoneopt_t option,
bool value);
--- /dev/null
+/*
+ * 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.
+ */
+
+/*! \file */
+
+#include <string.h>
+
+#include <isc/assertions.h>
+#include <isc/file.h>
+#include <isc/log.h>
+#include <isc/mem.h>
+#include <isc/util.h>
+
+#include <dns/log.h>
+#include <dns/kasp.h>
+
+isc_result_t
+dns_kasp_create(isc_mem_t *mctx, const char *name, dns_kasp_t **kaspp)
+{
+ dns_kasp_t *kasp;
+
+ REQUIRE(name != NULL);
+ REQUIRE(kaspp != NULL && *kaspp == NULL);
+
+ kasp = isc_mem_get(mctx, sizeof(*kasp));
+ kasp->mctx = NULL;
+ isc_mem_attach(mctx, &kasp->mctx);
+
+ kasp->name = isc_mem_strdup(mctx, name);
+ isc_mutex_init(&kasp->lock);
+ kasp->frozen = false;
+
+ isc_refcount_init(&kasp->references, 1);
+
+ ISC_LINK_INIT(kasp, link);
+
+ kasp->signatures_refresh = DNS_KASP_SIG_REFRESH;
+ kasp->signatures_validity = DNS_KASP_SIG_VALIDITY;
+ kasp->signatures_validity_dnskey = DNS_KASP_SIG_VALIDITY_DNSKEY;
+
+ ISC_LIST_INIT(kasp->keys);
+
+ kasp->dnskey_ttl = DNS_KASP_KEY_TTL;
+ kasp->publish_safety = DNS_KASP_PUBLISH_SAFETY;
+ kasp->retire_safety = DNS_KASP_RETIRE_SAFETY;
+
+ // TODO: The rest of the KASP configuration
+
+ kasp->magic = DNS_KASP_MAGIC;
+ *kaspp = kasp;
+
+ return (ISC_R_SUCCESS);
+}
+
+void
+dns_kasp_attach(dns_kasp_t *source, dns_kasp_t **targetp) {
+ REQUIRE(DNS_KASP_VALID(source));
+ REQUIRE(targetp != NULL && *targetp == NULL);
+ isc_refcount_increment(&source->references);
+ *targetp = source;
+}
+
+static inline void
+destroy(dns_kasp_t *kasp) {
+ dns_kasp_key_t *key;
+ dns_kasp_key_t *key_next;
+
+ for (key = ISC_LIST_HEAD(kasp->keys); key != NULL; key = key_next) {
+ key_next = ISC_LIST_NEXT(key, link);
+ ISC_LIST_UNLINK(kasp->keys, key, link);
+ dns_kasp_key_destroy(key);
+ }
+ ISC_INSIST(ISC_LIST_EMPTY(kasp->keys));
+
+ isc_mem_free(kasp->mctx, kasp->name);
+ isc_mem_putanddetach(&kasp->mctx, kasp, sizeof(*kasp));
+}
+
+void
+dns_kasp_detach(dns_kasp_t **kaspp) {
+ REQUIRE(kaspp != NULL && DNS_KASP_VALID(*kaspp));
+ dns_kasp_t *kasp = *kaspp;
+ *kaspp = NULL;
+
+ if (isc_refcount_decrement(&kasp->references) == 1) {
+ destroy(kasp);
+ }
+}
+
+void
+dns_kasp_freeze(dns_kasp_t *kasp) {
+ REQUIRE(DNS_KASP_VALID(kasp));
+ REQUIRE(!kasp->frozen);
+ kasp->frozen = true;
+}
+
+void
+dns_kasp_thaw(dns_kasp_t *kasp) {
+ REQUIRE(DNS_KASP_VALID(kasp));
+ REQUIRE(kasp->frozen);
+ kasp->frozen = false;
+}
+
+const char*
+dns_kasp_getname(dns_kasp_t *kasp) {
+ REQUIRE(DNS_KASP_VALID(kasp));
+ return kasp->name;
+}
+
+isc_result_t
+dns_kasplist_find(dns_kasplist_t *list, const char *name, dns_kasp_t **kaspp)
+{
+ dns_kasp_t *kasp;
+
+ if (list == NULL) {
+ return (ISC_R_NOTFOUND);
+ }
+ INSIST(list != NULL);
+
+ for (kasp = ISC_LIST_HEAD(*list); kasp != NULL;
+ kasp = ISC_LIST_NEXT(kasp, link))
+ {
+ if (strcmp(kasp->name, name) == 0) {
+ break;
+ }
+ }
+ if (kasp == NULL) {
+ return (ISC_R_NOTFOUND);
+ }
+ dns_kasp_attach(kasp, kaspp);
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+dns_kasp_key_create(isc_mem_t* mctx, dns_kasp_key_t **keyp)
+{
+ dns_kasp_key_t *key;
+
+ REQUIRE(keyp != NULL && *keyp == NULL);
+
+ key = isc_mem_get(mctx, sizeof(*key));
+ key->mctx = NULL;
+ isc_mem_attach(mctx, &key->mctx);
+
+ ISC_LINK_INIT(key, link);
+
+ key->lifetime = 0;
+ key->algorithm = 0;
+ key->length = -1;
+ key->role = 0;
+ *keyp = key;
+ return (ISC_R_SUCCESS);
+}
+
+void
+dns_kasp_key_destroy(dns_kasp_key_t* key)
+{
+ REQUIRE(key != NULL);
+ isc_mem_putanddetach(&key->mctx, key, sizeof(*key));
+}
dns_journal_set_sourceserial
dns_journal_write_transaction
dns_journal_writediff
+dns_kasp_create
+dns_kasp_attach
+dns_kasp_detach
+dns_kasp_freeze
+dns_kasp_getname
+dns_kasp_key_create
+dns_kasp_key_destroy
+dns_kasp_thaw
+dns_kasplist_find
dns_keydata_fromdnskey
dns_keydata_todnskey
dns_keyflags_fromtext
dns_zone_getincludes
dns_zone_getjournal
dns_zone_getjournalsize
+dns_zone_getkasp
dns_zone_getkeydirectory
dns_zone_getkeyopts
dns_zone_getkeyvalidityinterval
dns_zone_setisself
dns_zone_setjournal
dns_zone_setjournalsize
+dns_zone_setkasp
dns_zone_setkeydirectory
dns_zone_setkeyopt
dns_zone_setkeyvalidityinterval
<ClCompile Include="..\journal.c">
<Filter>Library Source Files</Filter>
</ClCompile>
+ <ClCompile Include="..\kasp.c">
+ <Filter>Library Source Files</Filter>
+ </ClCompile>
<ClCompile Include="..\keydata.c">
<Filter>Library Source Files</Filter>
</ClCompile>
<ClInclude Include="..\include\dns\journal.h">
<Filter>Library Header Files</Filter>
</ClInclude>
+ <ClInclude Include="..\include\dns\kasp.h">
+ <Filter>Library Header Files</Filter>
+ </ClInclude>
<ClInclude Include="..\include\dns\keydata.h">
<Filter>Library Header Files</Filter>
</ClInclude>
<ClCompile Include="..\ipkeylist.c" />
<ClCompile Include="..\iptable.c" />
<ClCompile Include="..\journal.c" />
+ <ClCompile Include="..\kasp.c" />
<ClCompile Include="..\key.c" />
<ClCompile Include="..\keydata.c" />
<ClCompile Include="..\keytable.c" />
<ClInclude Include="..\include\dns\ipkeylist.h" />
<ClInclude Include="..\include\dns\iptable.h" />
<ClInclude Include="..\include\dns\journal.h" />
+ <ClInclude Include="..\include\dns\kasp.h" />
<ClInclude Include="..\include\dns\keydata.h" />
<ClInclude Include="..\include\dns\keyflags.h" />
<ClInclude Include="..\include\dns\keytable.h" />
#include <dns/dnssec.h>
#include <dns/events.h>
#include <dns/journal.h>
+#include <dns/kasp.h>
#include <dns/keydata.h>
#include <dns/keytable.h>
#include <dns/keyvalues.h>
uint32_t sigresigninginterval;
dns_view_t *view;
dns_view_t *prev_view;
+ dns_kasp_t *kasp;
dns_checkmxfunc_t checkmx;
dns_checksrvfunc_t checksrv;
dns_checknsfunc_t checkns;
zone->sigvalidityinterval = 30 * 24 * 3600;
zone->keyvalidityinterval = 0;
zone->sigresigninginterval = 7 * 24 * 3600;
+ zone->kasp = NULL;
zone->view = NULL;
zone->prev_view = NULL;
zone->checkmx = NULL;
isc_mem_free(zone->mctx, zone->keydirectory);
}
zone->keydirectory = NULL;
+ if (zone->kasp != NULL) {
+ dns_kasp_detach(&zone->kasp);
+ }
zone->journalsize = -1;
if (zone->journal != NULL) {
isc_mem_free(zone->mctx, zone->journal);
}
}
+void
+dns_zone_setkasp(dns_zone_t *zone, dns_kasp_t* kasp)
+{
+ REQUIRE(DNS_ZONE_VALID(zone));
+
+ LOCK_ZONE(zone);
+ if (zone->kasp != NULL) {
+ dns_kasp_t* oldkasp = zone->kasp;
+ zone->kasp = NULL;
+ dns_kasp_detach(&oldkasp);
+ }
+ zone->kasp = kasp;
+ UNLOCK_ZONE(zone);
+}
+
+dns_kasp_t*
+dns_zone_getkasp(dns_zone_t *zone)
+{
+ REQUIRE(DNS_ZONE_VALID(zone));
+
+ return (zone->kasp);
+}
+
void
dns_zone_setoption(dns_zone_t *zone, dns_zoneopt_t option,
bool value)
./lib/dns/include/dns/ipkeylist.h C 2016,2018,2019
./lib/dns/include/dns/iptable.h C 2007,2012,2014,2016,2018,2019
./lib/dns/include/dns/journal.h C 1999,2000,2001,2004,2005,2006,2007,2008,2009,2011,2013,2016,2017,2018,2019
+./lib/dns/include/dns/kasp.h C 2019
./lib/dns/include/dns/keydata.h C 2009,2016,2018,2019
./lib/dns/include/dns/keyflags.h C 1999,2000,2001,2004,2005,2006,2007,2016,2018,2019
./lib/dns/include/dns/keytable.h C 2000,2001,2004,2005,2007,2009,2010,2014,2015,2016,2017,2018,2019
./lib/dns/ipkeylist.c C 2016,2018,2019
./lib/dns/iptable.c C 2007,2008,2009,2013,2014,2016,2017,2018,2019
./lib/dns/journal.c C 1999,2000,2001,2002,2004,2005,2007,2008,2009,2010,2011,2013,2014,2015,2016,2017,2018,2019
+./lib/dns/kasp.c C 2019
./lib/dns/key.c C 2001,2004,2005,2006,2007,2011,2016,2018,2019
./lib/dns/keydata.c C 2009,2014,2016,2018,2019
./lib/dns/keytable.c C 2000,2001,2004,2005,2007,2009,2010,2013,2014,2015,2016,2017,2018,2019