Files
bind9/lib/dns/include/dns/kasp.h
Evan Hunt 10accd6260 clean up uses of ISC_R_NOMEMORY
the isc_mem allocation functions can no longer fail; as a result,
ISC_R_NOMEMORY is now rarely used: only when an external library
such as libjson-c or libfstrm could return NULL. (even in
these cases, arguably we should assert rather than returning
ISC_R_NOMEMORY.)

code and comments that mentioned ISC_R_NOMEMORY have been
cleaned up, and the following functions have been changed to
type void, since (in most cases) the only value they could
return was ISC_R_SUCCESS:

- dns_dns64_create()
- dns_dyndb_create()
- dns_ipkeylist_resize()
- dns_kasp_create()
- dns_kasp_key_create()
- dns_keystore_create()
- dns_order_create()
- dns_order_add()
- dns_peerlist_new()
- dns_tkeyctx_create()
- dns_view_create()
- dns_zone_setorigin()
- dns_zone_setfile()
- dns_zone_setstream()
- dns_zone_getdbtype()
- dns_zone_setjournal()
- dns_zone_setkeydirectory()
- isc_lex_openstream()
- isc_portset_create()
- isc_symtab_create()

(the exception is dns_view_create(), which could have returned
other error codes in the event of a crypto library failure when
calling isc_file_sanitize(), but that should be a RUNTIME_CHECK
anyway.)
2025-01-23 15:54:57 -08:00

878 lines
15 KiB
C

/*
* 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.
*/
#pragma once
/*****
***** 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 <isc/magic.h>
#include <isc/mutex.h>
#include <isc/refcount.h>
#include <dns/dnssec.h>
#include <dns/keystore.h>
#include <dns/types.h>
/* For storing a list of digest types */
struct dns_kasp_digest {
dns_dsdigest_t digest;
ISC_LINK(dns_kasp_digest_t) link;
};
/* 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 */
dns_keystore_t *keystore;
uint32_t lifetime;
uint8_t algorithm;
int length;
uint8_t role;
uint16_t tag_min;
uint16_t tag_max;
};
struct dns_kasp_nsec3param {
uint8_t saltlen;
uint8_t algorithm;
uint8_t iterations;
bool optout;
};
/* 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_jitter;
uint32_t signatures_refresh;
uint32_t signatures_validity;
uint32_t signatures_validity_dnskey;
/* Configuration: Keys */
bool offlineksk;
bool cdnskey;
dns_kasp_digestlist_t digests;
dns_kasp_keylist_t keys;
dns_ttl_t dnskey_ttl;
/* Configuration: Denial of existence */
bool nsec3;
dns_kasp_nsec3param_t nsec3param;
/* Configuration: Timings */
uint32_t publish_safety;
uint32_t retire_safety;
uint32_t purge_keys;
/* Zone settings */
dns_ttl_t zone_max_ttl;
uint32_t zone_propagation_delay;
bool inline_signing;
/* Parent settings */
dns_ttl_t parent_ds_ttl;
uint32_t parent_propagation_delay;
};
#define DNS_KASP_MAGIC ISC_MAGIC('K', 'A', 'S', 'P')
#define DNS_KASP_VALID(kasp) ISC_MAGIC_VALID(kasp, DNS_KASP_MAGIC)
/* Defaults */
#define DEFAULT_JITTER (12 * 3600)
#define DNS_KASP_SIG_JITTER "PT12H"
#define DNS_KASP_SIG_REFRESH "P5D"
#define DNS_KASP_SIG_VALIDITY "P14D"
#define DNS_KASP_SIG_VALIDITY_DNSKEY "P14D"
#define DNS_KASP_KEY_TTL "3600"
#define DNS_KASP_DS_TTL "86400"
#define DNS_KASP_PUBLISH_SAFETY "3600"
#define DNS_KASP_PURGE_KEYS "P90D"
#define DNS_KASP_RETIRE_SAFETY "3600"
#define DNS_KASP_ZONE_MAXTTL "86400"
#define DNS_KASP_ZONE_PROPDELAY "300"
#define DNS_KASP_PARENT_PROPDELAY "3600"
/* Key roles */
#define DNS_KASP_KEY_ROLE_KSK 0x01
#define DNS_KASP_KEY_ROLE_ZSK 0x02
void
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:
*/
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 kasp.
*
* Returns:
*
*\li name of 'kasp'.
*/
uint32_t
dns_kasp_signdelay(dns_kasp_t *kasp);
/*%<
* Get the delay that is needed to ensure that all existing RRsets have been
* re-signed with a successor key. This is the signature validity minus the
* signature refresh time (that indicates how far before signature expiry an
* RRSIG should be refreshed).
*
* Requires:
*
*\li 'kasp' is a valid, frozen kasp.
*
* Returns:
*
*\li signature refresh interval.
*/
uint32_t
dns_kasp_sigjitter(dns_kasp_t *kasp);
/*%<
* Get signature jitter value.
*
* Requires:
*
*\li 'kasp' is a valid, frozen kasp.
*
* Returns:
*
*\li signature jitter value.
*/
void
dns_kasp_setsigjitter(dns_kasp_t *kasp, uint32_t value);
/*%<
* Set signature jitter value.
*
* Requires:
*
*\li 'kasp' is a valid, thawed kasp.
*/
uint32_t
dns_kasp_sigrefresh(dns_kasp_t *kasp);
/*%<
* Get signature refresh interval.
*
* Requires:
*
*\li 'kasp' is a valid, frozen kasp.
*
* Returns:
*
*\li signature refresh interval.
*/
void
dns_kasp_setsigrefresh(dns_kasp_t *kasp, uint32_t value);
/*%<
* Set signature refresh interval.
*
* Requires:
*
*\li 'kasp' is a valid, thawed kasp.
*/
uint32_t
dns_kasp_sigvalidity(dns_kasp_t *kasp);
uint32_t
dns_kasp_sigvalidity_dnskey(dns_kasp_t *kasp);
/*%<
* Get signature validity.
*
* Requires:
*
*\li 'kasp' is a valid, frozen kasp.
*
* Returns:
*
*\li signature validity.
*/
void
dns_kasp_setsigvalidity(dns_kasp_t *kasp, uint32_t value);
void
dns_kasp_setsigvalidity_dnskey(dns_kasp_t *kasp, uint32_t value);
/*%<
* Set signature validity.
*
* Requires:
*
*\li 'kasp' is a valid, thawed kasp.
*/
dns_ttl_t
dns_kasp_dnskeyttl(dns_kasp_t *kasp);
/*%<
* Get DNSKEY TTL.
*
* Requires:
*
*\li 'kasp' is a valid, frozen kasp.
*
* Returns:
*
*\li DNSKEY TTL.
*/
void
dns_kasp_setdnskeyttl(dns_kasp_t *kasp, dns_ttl_t ttl);
/*%<
* Set DNSKEY TTL.
*
* Requires:
*
*\li 'kasp' is a valid, thawed kasp.
*/
uint32_t
dns_kasp_purgekeys(dns_kasp_t *kasp);
/*%<
* Get purge keys interval.
*
* Requires:
*
*\li 'kasp' is a valid, frozen kasp.
*
* Returns:
*
*\li Purge keys interval.
*/
void
dns_kasp_setpurgekeys(dns_kasp_t *kasp, uint32_t value);
/*%<
* Set purge keys interval.
*
* Requires:
*
*\li 'kasp' is a valid, thawed kasp.
*/
uint32_t
dns_kasp_publishsafety(dns_kasp_t *kasp);
/*%<
* Get publish safety interval.
*
* Requires:
*
*\li 'kasp' is a valid, frozen kasp.
*
* Returns:
*
*\li Publish safety interval.
*/
void
dns_kasp_setpublishsafety(dns_kasp_t *kasp, uint32_t value);
/*%<
* Set publish safety interval.
*
* Requires:
*
*\li 'kasp' is a valid, thawed kasp.
*/
uint32_t
dns_kasp_retiresafety(dns_kasp_t *kasp);
/*%<
* Get retire safety interval.
*
* Requires:
*
*\li 'kasp' is a valid, frozen kasp.
*
* Returns:
*
*\li Retire safety interval.
*/
void
dns_kasp_setretiresafety(dns_kasp_t *kasp, uint32_t value);
/*%<
* Set retire safety interval.
*
* Requires:
*
*\li 'kasp' is a valid, thawed kasp.
*/
bool
dns_kasp_inlinesigning(dns_kasp_t *kasp);
/*%<
* Should we use inline-signing for this DNSSEC policy?
*
* Requires:
*
*\li 'kasp' is a valid, frozen kasp.
*
* Returns:
*
*\li true or false.
*/
void
dns_kasp_setinlinesigning(dns_kasp_t *kasp, bool value);
/*%<
* Set inline-signing.
*
* Requires:
*
*\li 'kasp' is a valid, thawed kasp.
*/
dns_ttl_t
dns_kasp_zonemaxttl(dns_kasp_t *kasp, bool fallback);
/*%<
* Get maximum zone TTL. If 'fallback' is true, return a default maximum TTL
* if the maximum zone TTL is set to unlimited (value 0). Fallback should be
* used if determining key rollover timings in keymgr.c
*
* Requires:
*
*\li 'kasp' is a valid, frozen kasp.
*
* Returns:
*
*\li Maximum zone TTL.
*/
void
dns_kasp_setzonemaxttl(dns_kasp_t *kasp, dns_ttl_t ttl);
/*%<
* Set maximum zone TTL.
*
* Requires:
*
*\li 'kasp' is a valid, thawed kasp.
*/
uint32_t
dns_kasp_zonepropagationdelay(dns_kasp_t *kasp);
/*%<
* Get zone propagation delay.
*
* Requires:
*
*\li 'kasp' is a valid, frozen kasp.
*
* Returns:
*
*\li Zone propagation delay.
*/
void
dns_kasp_setzonepropagationdelay(dns_kasp_t *kasp, uint32_t value);
/*%<
* Set zone propagation delay.
*
* Requires:
*
*\li 'kasp' is a valid, thawed kasp.
*/
dns_ttl_t
dns_kasp_dsttl(dns_kasp_t *kasp);
/*%<
* Get DS TTL (should match that of the parent DS record).
*
* Requires:
*
*\li 'kasp' is a valid, frozen kasp.
*
* Returns:
*
*\li Expected parent DS TTL.
*/
void
dns_kasp_setdsttl(dns_kasp_t *kasp, dns_ttl_t ttl);
/*%<
* Set DS TTL.
*
* Requires:
*
*\li 'kasp' is a valid, thawed kasp.
*/
uint32_t
dns_kasp_parentpropagationdelay(dns_kasp_t *kasp);
/*%<
* Get parent zone propagation delay.
*
* Requires:
*
*\li 'kasp' is a valid, frozen kasp.
*
* Returns:
*
*\li Parent zone propagation delay.
*/
void
dns_kasp_setparentpropagationdelay(dns_kasp_t *kasp, uint32_t value);
/*%<
* Set parent propagation delay.
*
* Requires:
*
*\li 'kasp' is a valid, thawed 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.
*/
dns_kasp_keylist_t
dns_kasp_keys(dns_kasp_t *kasp);
/*%<
* Get the list of kasp keys.
*
* Requires:
*
*\li 'kasp' is a valid, frozen kasp.
*/
bool
dns_kasp_keylist_empty(dns_kasp_t *kasp);
/*%<
* Check if the keylist is empty.
*
* Requires:
*
*\li 'kasp' is a valid kasp.
*
* Returns:
*
*\li true if the keylist is empty, false otherwise.
*/
void
dns_kasp_addkey(dns_kasp_t *kasp, dns_kasp_key_t *key);
/*%<
* Add a key.
*
* Requires:
*
*\li 'kasp' is a valid, thawed kasp.
*\li 'key' is not NULL.
*/
void
dns_kasp_key_create(dns_kasp_t *kasp, dns_kasp_key_t **keyp);
/*%<
* Create a key inside a KASP.
*
* Requires:
*
*\li 'kasp' is a valid kasp.
*
*\li keyp != NULL && *keyp == NULL
*/
void
dns_kasp_key_destroy(dns_kasp_key_t *key);
/*%<
* Destroy a KASP key.
*
* Requires:
*
*\li key != NULL
*/
uint32_t
dns_kasp_key_algorithm(dns_kasp_key_t *key);
/*%<
* Get the key algorithm.
*
* Requires:
*
*\li key != NULL
*
* Returns:
*
*\li Key algorithm.
*/
unsigned int
dns_kasp_key_size(dns_kasp_key_t *key);
/*%<
* Get the key size.
*
* Requires:
*
*\li key != NULL
*
* Returns:
*
*\li Configured key size, or default key size for key algorithm if no size
* configured.
*/
uint32_t
dns_kasp_key_lifetime(dns_kasp_key_t *key);
/*%<
* The lifetime of this key (how long may this key be active?)
*
* Requires:
*
*\li key != NULL
*
* Returns:
*
*\li Lifetime of key.
*
*/
dns_keystore_t *
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);
/*%<
* Does this key act as a KSK?
*
* Requires:
*
*\li key != NULL
*
* Returns:
*
*\li True, if the key role has DNS_KASP_KEY_ROLE_KSK set.
*\li False, otherwise.
*
*/
bool
dns_kasp_key_zsk(dns_kasp_key_t *key);
/*%<
* Does this key act as a ZSK?
*
* Requires:
*
*\li key != NULL
*
* Returns:
*
*\li True, if the key role has DNS_KASP_KEY_ROLE_ZSK set.
*\li False, otherwise.
*
*/
uint16_t
dns_kasp_key_tagmin(dns_kasp_key_t *key);
/*%<
* Returns the minimum permitted key tag value.
*
* Requires:
*
*\li key != NULL
*/
uint16_t
dns_kasp_key_tagmax(dns_kasp_key_t *key);
/*%<
* Returns the maximum permitted key tag value.
*
* Requires:
*
*\li key != NULL
*/
bool
dns_kasp_key_match(dns_kasp_key_t *key, dns_dnsseckey_t *dkey);
/*%<
* Does the DNSSEC key 'dkey' match the policy parameters from the kasp key
* 'key'? A DNSSEC key matches if it has the same algorithm and size, and if
* it has the same role as the kasp key configuration.
*
* Requires:
*
*\li key != NULL
*\li dkey != NULL
*
* Returns:
*
*\li True, if the DNSSEC key matches.
*\li False, otherwise.
*/
bool
dns_kasp_nsec3(dns_kasp_t *kasp);
/*%<
* Return true if NSEC3 chain should be used.
*
* Requires:
*
*\li 'kasp' is a valid, frozen kasp.
*
*/
uint8_t
dns_kasp_nsec3iter(dns_kasp_t *kasp);
/*%<
* The number of NSEC3 iterations to use.
*
* Requires:
*
*\li 'kasp' is a valid, frozen kasp.
*\li 'kasp->nsec3' is true.
*
*/
uint8_t
dns_kasp_nsec3flags(dns_kasp_t *kasp);
/*%<
* The NSEC3 flags field value.
*
* Requires:
*
*\li 'kasp' is a valid, frozen kasp.
*\li 'kasp->nsec3' is true.
*
*/
uint8_t
dns_kasp_nsec3saltlen(dns_kasp_t *kasp);
/*%<
* The NSEC3 salt length.
*
* Requires:
*
*\li 'kasp' is a valid, frozen kasp.
*\li 'kasp->nsec3' is true.
*
*/
void
dns_kasp_setnsec3(dns_kasp_t *kasp, bool nsec3);
/*%<
* Set to use NSEC3 if 'nsec3' is 'true', otherwise policy will use NSEC.
*
* Requires:
*
*\li 'kasp' is a valid, unfrozen kasp.
*
*/
void
dns_kasp_setnsec3param(dns_kasp_t *kasp, uint8_t iter, bool optout,
uint8_t saltlen);
/*%<
* Set the desired NSEC3 parameters.
*
* Requires:
*
*\li 'kasp' is a valid, unfrozen kasp.
*\li 'kasp->nsec3' is true.
*
*/
bool
dns_kasp_offlineksk(dns_kasp_t *kasp);
/*%<
* Should we be using Offline KSK key management?
*
* Requires:
*
*\li 'kasp' is a valid, frozen kasp.
*
*/
void
dns_kasp_setofflineksk(dns_kasp_t *kasp, bool offlineksk);
/*%<
* Enable/disable Offline KSK.
*
* Requires:
*
*\li 'kasp' is a valid, unfrozen kasp.
*
*/
bool
dns_kasp_cdnskey(dns_kasp_t *kasp);
/*%<
* Do we need to publish a CDNSKEY?
*
* Requires:
*
*\li 'kasp' is a valid, frozen kasp.
*
*/
void
dns_kasp_setcdnskey(dns_kasp_t *kasp, bool cdnskey);
/*%<
* Enable/disable publication of CDNSKEY records.
*
* Requires:
*
*\li 'kasp' is a valid, unfrozen kasp.
*
*/
dns_kasp_digestlist_t
dns_kasp_digests(dns_kasp_t *kasp);
/*%<
* Get the list of kasp CDS digest types. This determines which CDS records
* should be published.
*
* Requires:
*
*\li 'kasp' is a valid, frozen kasp.
*/
void
dns_kasp_adddigest(dns_kasp_t *kasp, dns_dsdigest_t alg);
/*%<
* Add a CDS digest type, this will enable publication of a CDS record with
* digest type 'alg'.
*
* Requires:
*
*\li 'kasp' is a valid, thawed kasp.
*/