mirror of
https://github.com/isc-projects/bind9.git
synced 2026-05-28 04:34:54 -04:00
Implement named-checkconf -k (check keys)
With named-checkconf -k you can check your configuration including checking the dnssec-policy keys against the configured keystores. If there is a mismatch in the key files versus the policy, named-checkconf will fail. This is useful for running before migrating to dnssec-policy. For logging purposes, introduce a function that writes the identifying information about a policy key into a string. Allow a dnssec key to be initialized outside the keymgr code. Add 'log_errors' to 'cfg_kasp_fromconfig' to avoid duplicate error logs.
This commit is contained in:
parent
72a640d8b1
commit
9fe520ece9
12 changed files with 409 additions and 170 deletions
|
|
@ -57,7 +57,7 @@ usage(void);
|
|||
static void
|
||||
usage(void) {
|
||||
fprintf(stderr,
|
||||
"usage: %s [-achijlvz] [-p [-x]] [-t directory] "
|
||||
"usage: %s [-achijklvz] [-p [-x]] [-t directory] "
|
||||
"[named.conf]\n",
|
||||
isc_commandline_progname);
|
||||
exit(EXIT_SUCCESS);
|
||||
|
|
@ -593,7 +593,7 @@ main(int argc, char **argv) {
|
|||
/*
|
||||
* Process memory debugging argument first.
|
||||
*/
|
||||
#define CMDLINE_FLAGS "acdhijlm:nt:pvxz"
|
||||
#define CMDLINE_FLAGS "acdhijklm:nt:pvxz"
|
||||
while ((c = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) {
|
||||
switch (c) {
|
||||
case 'm':
|
||||
|
|
@ -638,6 +638,10 @@ main(int argc, char **argv) {
|
|||
nomerge = false;
|
||||
break;
|
||||
|
||||
case 'k':
|
||||
checkflags |= BIND_CHECK_KEYS;
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
list_zones = true;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ named-checkconf - named configuration file syntax checking tool
|
|||
Synopsis
|
||||
~~~~~~~~
|
||||
|
||||
:program:`named-checkconf` [**-achjlnvz**] [**-p** [**-x** ]] [**-t** directory] {filename}
|
||||
:program:`named-checkconf` [**-achjklnvz**] [**-p** [**-x** ]] [**-t** directory] {filename}
|
||||
|
||||
Description
|
||||
~~~~~~~~~~~
|
||||
|
|
@ -56,6 +56,12 @@ Options
|
|||
|
||||
When loading a zonefile, this option instructs :iscman:`named` to read the journal if it exists.
|
||||
|
||||
.. option:: -k
|
||||
|
||||
Check the `dnssec-policy`'s DNSSEC keys against the key files in
|
||||
the `key-directory`. This is useful when checking a `named.conf`
|
||||
to ensure a DNSSEC policy matches the existing keys.
|
||||
|
||||
.. option:: -l
|
||||
|
||||
This option lists all the configured zones. Each line of output contains the zone
|
||||
|
|
|
|||
|
|
@ -601,6 +601,9 @@ kasp_from_conf(cfg_obj_t *config, isc_mem_t *mctx, const char *name,
|
|||
const cfg_obj_t *keystores = NULL;
|
||||
dns_keystore_t *keystore = NULL;
|
||||
dns_keystorelist_t kslist;
|
||||
unsigned int options = (ISCCFG_KASPCONF_CHECK_ALGORITHMS |
|
||||
ISCCFG_KASPCONF_CHECK_KEYLIST |
|
||||
ISCCFG_KASPCONF_LOG_ERRORS);
|
||||
|
||||
ISC_LIST_INIT(kasplist);
|
||||
ISC_LIST_INIT(kslist);
|
||||
|
|
@ -635,8 +638,8 @@ kasp_from_conf(cfg_obj_t *config, isc_mem_t *mctx, const char *name,
|
|||
continue;
|
||||
}
|
||||
|
||||
result = cfg_kasp_fromconfig(kconfig, NULL, true, mctx, &kslist,
|
||||
&kasplist, &kasp);
|
||||
result = cfg_kasp_fromconfig(kconfig, NULL, options, mctx,
|
||||
&kslist, &kasplist, &kasp);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
fatal("failed to configure dnssec-policy '%s': %s",
|
||||
cfg_obj_asstring(cfg_tuple_get(kconfig, "name")),
|
||||
|
|
|
|||
|
|
@ -8052,6 +8052,9 @@ configure_kasplist(const cfg_obj_t *config, dns_kasplist_t *kasplist,
|
|||
isc_result_t result = ISC_R_SUCCESS;
|
||||
dns_kasp_t *default_kasp = NULL;
|
||||
const cfg_obj_t *kasps = NULL;
|
||||
unsigned int kaspopts = (ISCCFG_KASPCONF_CHECK_ALGORITHMS |
|
||||
ISCCFG_KASPCONF_CHECK_KEYLIST |
|
||||
ISCCFG_KASPCONF_LOG_ERRORS);
|
||||
|
||||
APPLY_CONFIGURATION_SUBROUTINE_LOG;
|
||||
|
||||
|
|
@ -8063,7 +8066,7 @@ configure_kasplist(const cfg_obj_t *config, dns_kasplist_t *kasplist,
|
|||
cfg_obj_t *kconfig = cfg_listelt_value(element);
|
||||
dns_kasp_t *kasp = NULL;
|
||||
|
||||
result = cfg_kasp_fromconfig(kconfig, default_kasp, true,
|
||||
result = cfg_kasp_fromconfig(kconfig, default_kasp, kaspopts,
|
||||
isc_g_mctx, keystorelist, kasplist,
|
||||
&kasp);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
|
|
@ -8091,7 +8094,7 @@ configure_kasplist(const cfg_obj_t *config, dns_kasplist_t *kasplist,
|
|||
cfg_obj_t *kconfig = cfg_listelt_value(element);
|
||||
dns_kasp_t *kasp = NULL;
|
||||
|
||||
result = cfg_kasp_fromconfig(kconfig, default_kasp, true,
|
||||
result = cfg_kasp_fromconfig(kconfig, default_kasp, kaspopts,
|
||||
isc_g_mctx, keystorelist, kasplist,
|
||||
&kasp);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
|
||||
#include <dns/dnssec.h>
|
||||
#include <dns/keystore.h>
|
||||
#include <dns/name.h>
|
||||
#include <dns/types.h>
|
||||
|
||||
/* For storing a list of digest types */
|
||||
|
|
@ -137,6 +138,8 @@ struct dns_kasp {
|
|||
#define DNS_KASP_KEY_ROLE_KSK 0x01
|
||||
#define DNS_KASP_KEY_ROLE_ZSK 0x02
|
||||
|
||||
#define DNS_KASP_KEY_FORMATSIZE (DNS_NAME_FORMATSIZE + 64)
|
||||
|
||||
void
|
||||
dns_kasp_create(isc_mem_t *mctx, const char *name, dns_kasp_t **kaspp);
|
||||
/*%<
|
||||
|
|
@ -764,6 +767,17 @@ dns_kasp_key_match(dns_kasp_key_t *key, dns_dnsseckey_t *dkey);
|
|||
*\li False, otherwise.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_kasp_key_format(dns_kasp_key_t *key, char *cp, unsigned int size);
|
||||
/*%<
|
||||
* Write the identifying information about the policy key (role,
|
||||
* algorithm, tag range) into a string 'cp' of size 'size'.
|
||||
* Requires:
|
||||
*
|
||||
*\li key != NULL
|
||||
*\li cp != NULL
|
||||
*/
|
||||
|
||||
bool
|
||||
dns_kasp_nsec3(dns_kasp_t *kasp);
|
||||
/*%<
|
||||
|
|
|
|||
|
|
@ -37,6 +37,21 @@ dns_keymgr_settime_syncpublish(dst_key_t *key, dns_kasp_t *kasp, bool first);
|
|||
*\li 'kasp' is a valid DNSSEC policy.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_keymgr_key_init(dns_dnsseckey_t *key, dns_kasp_t *kasp, isc_stdtime_t now,
|
||||
bool csk);
|
||||
/*
|
||||
* Initialize this key's properties if not already present. A key created
|
||||
* and derived from a dnssec-policy will have the required metadata available,
|
||||
* otherwise these may be missing and need to be initialized. The key states
|
||||
* will be initialized according to existing timing metadata. If 'csk' is
|
||||
* set to true, the key is considered a combined signing key (CSK).
|
||||
*
|
||||
* Requires:
|
||||
*\li 'key' is a valid DNSSEC key.
|
||||
*\li 'kasp' is a valid DNSSEC policy.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
dns_keymgr_run(const dns_name_t *origin, dns_rdataclass_t rdclass,
|
||||
isc_mem_t *mctx, dns_dnsseckeylist_t *keyring,
|
||||
|
|
|
|||
|
|
@ -559,6 +559,21 @@ dns_kasp_key_match(dns_kasp_key_t *key, dns_dnsseckey_t *dkey) {
|
|||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
dns_kasp_key_format(dns_kasp_key_t *key, char *cp, unsigned int size) {
|
||||
REQUIRE(key != NULL);
|
||||
REQUIRE(cp != NULL);
|
||||
|
||||
char algstr[DNS_NAME_FORMATSIZE];
|
||||
bool csk = dns_kasp_key_ksk(key) && dns_kasp_key_zsk(key);
|
||||
const char *rolestr = (csk ? "csk"
|
||||
: (dns_kasp_key_ksk(key) ? "ksk" : "zsk"));
|
||||
|
||||
dst_algorithm_format(key->algorithm, algstr, sizeof(algstr));
|
||||
snprintf(cp, size, "%s algorithm:%s length:%u tag-range:%u-%u", rolestr,
|
||||
algstr, dns_kasp_key_size(key), key->tag_min, key->tag_max);
|
||||
}
|
||||
|
||||
uint8_t
|
||||
dns_kasp_nsec3iter(dns_kasp_t *kasp) {
|
||||
REQUIRE(kasp != NULL);
|
||||
|
|
|
|||
|
|
@ -1635,16 +1635,9 @@ transition:
|
|||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* See if this key needs to be initialized with properties. A key created
|
||||
* and derived from a dnssec-policy will have the required metadata available,
|
||||
* otherwise these may be missing and need to be initialized. The key states
|
||||
* will be initialized according to existing timing metadata.
|
||||
*
|
||||
*/
|
||||
static void
|
||||
keymgr_key_init(dns_dnsseckey_t *key, dns_kasp_t *kasp, isc_stdtime_t now,
|
||||
bool csk) {
|
||||
void
|
||||
dns_keymgr_key_init(dns_dnsseckey_t *key, dns_kasp_t *kasp, isc_stdtime_t now,
|
||||
bool csk) {
|
||||
bool ksk, zsk;
|
||||
isc_result_t ret;
|
||||
isc_stdtime_t active = 0, pub = 0, syncpub = 0, retire = 0, remove = 0;
|
||||
|
|
@ -1926,7 +1919,7 @@ keymgr_key_rollover(dns_kasp_key_t *kaspkey, dns_dnsseckey_t *active_key,
|
|||
dst_key_setttl(dst_key, dns_kasp_dnskeyttl(kasp));
|
||||
dst_key_settime(dst_key, DST_TIME_CREATED, now);
|
||||
dns_dnsseckey_create(mctx, &dst_key, &new_key);
|
||||
keymgr_key_init(new_key, kasp, now, csk);
|
||||
dns_keymgr_key_init(new_key, kasp, now, csk);
|
||||
keycreated = true;
|
||||
}
|
||||
dst_key_setnum(new_key->key, DST_NUM_LIFETIME, lifetime);
|
||||
|
|
@ -2174,7 +2167,7 @@ dns_keymgr_run(const dns_name_t *origin, dns_rdataclass_t rdclass,
|
|||
ISC_LIST_FOREACH(*keyring, dkey, link) {
|
||||
bool found_match = false;
|
||||
|
||||
keymgr_key_init(dkey, kasp, now, numkeys == 1);
|
||||
dns_keymgr_key_init(dkey, kasp, now, numkeys == 1);
|
||||
|
||||
ISC_LIST_FOREACH(dns_kasp_keys(kasp), kkey, link) {
|
||||
if (dns_kasp_key_match(kkey, dkey)) {
|
||||
|
|
@ -2785,7 +2778,7 @@ dns_keymgr_offline(const dns_name_t *origin, dns_dnsseckeylist_t *keyring,
|
|||
continue;
|
||||
}
|
||||
|
||||
keymgr_key_init(dkey, kasp, now, false);
|
||||
dns_keymgr_key_init(dkey, kasp, now, false);
|
||||
|
||||
/* Get current metadata */
|
||||
RETERR(dst_key_getstate(dkey->key, DST_KEY_DNSKEY,
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@
|
|||
#include <dns/fixedname.h>
|
||||
#include <dns/journal.h>
|
||||
#include <dns/kasp.h>
|
||||
#include <dns/keymgr.h>
|
||||
#include <dns/keystore.h>
|
||||
#include <dns/keyvalues.h>
|
||||
#include <dns/peer.h>
|
||||
|
|
@ -1397,6 +1398,11 @@ check_options(const cfg_obj_t *options, const cfg_obj_t *config,
|
|||
if (obj != NULL) {
|
||||
bool bad_kasp = false;
|
||||
bool bad_name = false;
|
||||
unsigned int kaspopts = (ISCCFG_KASPCONF_CHECK_KEYLIST |
|
||||
ISCCFG_KASPCONF_LOG_ERRORS);
|
||||
if (check_algorithms) {
|
||||
kaspopts |= ISCCFG_KASPCONF_CHECK_ALGORITHMS;
|
||||
}
|
||||
|
||||
if (optlevel != optlevel_config && !cfg_obj_isstring(obj)) {
|
||||
bad_kasp = true;
|
||||
|
|
@ -1422,8 +1428,8 @@ check_options(const cfg_obj_t *options, const cfg_obj_t *config,
|
|||
}
|
||||
|
||||
ret = cfg_kasp_fromconfig(
|
||||
kconfig, NULL, check_algorithms,
|
||||
mctx, &kslist, &list, &kasp);
|
||||
kconfig, NULL, kaspopts, mctx,
|
||||
&kslist, &list, &kasp);
|
||||
if (ret != ISC_R_SUCCESS) {
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
result = ret;
|
||||
|
|
@ -2815,29 +2821,29 @@ cleanup:
|
|||
|
||||
static isc_result_t
|
||||
check_keydir(const cfg_obj_t *config, const cfg_obj_t *zconfig,
|
||||
dns_name_t *zname, const char *name, const char *keydir,
|
||||
isc_symtab_t *keydirs, isc_mem_t *mctx) {
|
||||
dns_name_t *origin, const char *zname, const char *name,
|
||||
const char *keydir, isc_symtab_t *keydirs, isc_mem_t *mctx,
|
||||
bool check_keys) {
|
||||
const char *dir = keydir;
|
||||
isc_result_t ret, result = ISC_R_SUCCESS;
|
||||
bool do_cleanup = false;
|
||||
bool done = false;
|
||||
bool keystore = false;
|
||||
const cfg_obj_t *kasps = NULL;
|
||||
const cfg_obj_t *kaspobj = NULL;
|
||||
dns_kasp_t *kasp = NULL;
|
||||
dns_kasplist_t kasplist;
|
||||
const cfg_obj_t *keystores = NULL;
|
||||
dns_keystorelist_t kslist;
|
||||
isc_time_t timenow;
|
||||
isc_stdtime_t now;
|
||||
|
||||
timenow = isc_time_now();
|
||||
now = isc_time_seconds(&timenow);
|
||||
|
||||
/* If no dnssec-policy or key-store, use the dir (key-directory) */
|
||||
(void)cfg_map_get(config, "dnssec-policy", &kasps);
|
||||
(void)cfg_map_get(config, "key-store", &keystores);
|
||||
if (kasps == NULL || keystores == NULL) {
|
||||
goto check;
|
||||
}
|
||||
|
||||
ISC_LIST_INIT(kasplist);
|
||||
ISC_LIST_INIT(kslist);
|
||||
do_cleanup = true;
|
||||
|
||||
/*
|
||||
* Build the keystore list.
|
||||
|
|
@ -2854,7 +2860,7 @@ check_keydir(const cfg_obj_t *config, const cfg_obj_t *zconfig,
|
|||
*/
|
||||
CFG_LIST_FOREACH(kasps, element) {
|
||||
cfg_obj_t *kconfig = cfg_listelt_value(element);
|
||||
const cfg_obj_t *kaspobj = NULL;
|
||||
kaspobj = NULL;
|
||||
|
||||
if (!cfg_obj_istuple(kconfig)) {
|
||||
continue;
|
||||
|
|
@ -2865,7 +2871,7 @@ check_keydir(const cfg_obj_t *config, const cfg_obj_t *zconfig,
|
|||
continue;
|
||||
}
|
||||
|
||||
ret = cfg_kasp_fromconfig(kconfig, NULL, false, mctx, &kslist,
|
||||
ret = cfg_kasp_fromconfig(kconfig, NULL, 0, mctx, &kslist,
|
||||
&kasplist, &kasp);
|
||||
if (ret != ISC_R_SUCCESS) {
|
||||
kasp = NULL;
|
||||
|
|
@ -2876,6 +2882,7 @@ check_keydir(const cfg_obj_t *config, const cfg_obj_t *zconfig,
|
|||
if (kasp == NULL) {
|
||||
goto check;
|
||||
}
|
||||
INSIST(kaspobj != NULL);
|
||||
|
||||
/* Check key-stores of keys */
|
||||
dns_kasp_freeze(kasp);
|
||||
|
|
@ -2888,35 +2895,116 @@ check_keydir(const cfg_obj_t *config, const cfg_obj_t *zconfig,
|
|||
ret = keydirexist(zconfig,
|
||||
keystore ? "key-store directory"
|
||||
: "key-directory",
|
||||
zname, dir, name, keydirs, mctx);
|
||||
origin, dir, name, keydirs, mctx);
|
||||
if (ret != ISC_R_SUCCESS) {
|
||||
result = ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (check_keys) {
|
||||
/* Find matching key files. */
|
||||
dns_dnsseckeylist_t keys;
|
||||
int numkaspkeys = 0;
|
||||
int numkeyfiles = 0;
|
||||
|
||||
ISC_LIST_INIT(keys);
|
||||
ret = dns_dnssec_findmatchingkeys(origin, kasp, keydir, &kslist,
|
||||
now, mctx, &keys);
|
||||
if (ret != ISC_R_SUCCESS) {
|
||||
result = ret;
|
||||
}
|
||||
|
||||
ISC_LIST_FOREACH(keys, dkey, link) {
|
||||
numkeyfiles++;
|
||||
}
|
||||
|
||||
ISC_LIST_FOREACH(keys, dkey, link) {
|
||||
bool found_match = false;
|
||||
|
||||
dns_keymgr_key_init(dkey, kasp, now, numkeyfiles == 1);
|
||||
|
||||
ISC_LIST_FOREACH(dns_kasp_keys(kasp), kkey, link) {
|
||||
if (dns_kasp_key_match(kkey, dkey)) {
|
||||
found_match = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found_match) {
|
||||
char keystr[DST_KEY_FORMATSIZE];
|
||||
dst_key_format(dkey->key, keystr,
|
||||
sizeof(keystr));
|
||||
cfg_obj_log(kaspobj, ISC_LOG_ERROR,
|
||||
"zone '%s': key file '%s' does not "
|
||||
"match dnssec-policy %s",
|
||||
zname, keystr,
|
||||
dns_kasp_getname(kasp));
|
||||
result = ISC_R_NOTFOUND;
|
||||
}
|
||||
}
|
||||
|
||||
ISC_LIST_FOREACH(dns_kasp_keys(kasp), kkey, link) {
|
||||
bool found_match = false;
|
||||
|
||||
numkaspkeys++;
|
||||
|
||||
ISC_LIST_FOREACH(keys, dkey, link) {
|
||||
if (dns_kasp_key_match(kkey, dkey)) {
|
||||
found_match = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found_match) {
|
||||
char keystr[DNS_KASP_KEY_FORMATSIZE];
|
||||
dns_kasp_key_format(kkey, keystr,
|
||||
sizeof(keystr));
|
||||
|
||||
cfg_obj_log(
|
||||
kaspobj, ISC_LOG_ERROR,
|
||||
"zone '%s': no key file found matching "
|
||||
"dnssec-policy %s key:'%s'",
|
||||
zname, dns_kasp_getname(kasp), keystr);
|
||||
result = ISC_R_NOTFOUND;
|
||||
}
|
||||
}
|
||||
|
||||
if (numkaspkeys != numkeyfiles) {
|
||||
cfg_obj_log(kaspobj, ISC_LOG_ERROR,
|
||||
"zone '%s': wrong number of key files (%d, "
|
||||
"expected %d)",
|
||||
zname, numkeyfiles, numkaspkeys);
|
||||
result = ISC_R_FAILURE;
|
||||
}
|
||||
|
||||
ISC_LIST_FOREACH(keys, key, link) {
|
||||
ISC_LIST_UNLINK(keys, key, link);
|
||||
dns_dnsseckey_destroy(mctx, &key);
|
||||
}
|
||||
}
|
||||
|
||||
dns_kasp_thaw(kasp);
|
||||
done = true;
|
||||
|
||||
check:
|
||||
if (!done) {
|
||||
ret = keydirexist(zconfig, "key-directory", zname, dir, name,
|
||||
ret = keydirexist(zconfig, "key-directory", origin, dir, name,
|
||||
keydirs, mctx);
|
||||
if (ret != ISC_R_SUCCESS) {
|
||||
result = ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (do_cleanup) {
|
||||
if (kasp != NULL) {
|
||||
dns_kasp_detach(&kasp);
|
||||
}
|
||||
ISC_LIST_FOREACH(kasplist, k, link) {
|
||||
ISC_LIST_UNLINK(kasplist, k, link);
|
||||
dns_kasp_detach(&k);
|
||||
}
|
||||
ISC_LIST_FOREACH(kslist, ks, link) {
|
||||
ISC_LIST_UNLINK(kslist, ks, link);
|
||||
dns_keystore_detach(&ks);
|
||||
}
|
||||
if (kasp != NULL) {
|
||||
dns_kasp_detach(&kasp);
|
||||
}
|
||||
ISC_LIST_FOREACH(kasplist, k, link) {
|
||||
ISC_LIST_UNLINK(kasplist, k, link);
|
||||
dns_kasp_detach(&k);
|
||||
}
|
||||
ISC_LIST_FOREACH(kslist, ks, link) {
|
||||
ISC_LIST_UNLINK(kslist, ks, link);
|
||||
dns_keystore_detach(&ks);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
@ -3046,6 +3134,7 @@ isccfg_check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
|
|||
bool has_dnssecpolicy = false;
|
||||
bool kasp_inlinesigning = false;
|
||||
bool inline_signing = false;
|
||||
bool check_keys = (flags & BIND_CHECK_KEYS) != 0;
|
||||
const void *clauses = NULL;
|
||||
const char *option = NULL;
|
||||
const char *kaspname = NULL;
|
||||
|
|
@ -3821,8 +3910,9 @@ isccfg_check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
|
|||
*/
|
||||
if (zname != NULL && keydirs != NULL) {
|
||||
if (has_dnssecpolicy) {
|
||||
tresult = check_keydir(config, zconfig, zname, kaspname,
|
||||
dir, keydirs, mctx);
|
||||
tresult = check_keydir(config, zconfig, zname, znamestr,
|
||||
kaspname, dir, keydirs, mctx,
|
||||
check_keys);
|
||||
} else {
|
||||
tresult = keydirexist(zconfig, "key-directory", zname,
|
||||
dir, kaspname, keydirs, mctx);
|
||||
|
|
|
|||
|
|
@ -41,6 +41,11 @@
|
|||
* Check the dnssec-policy DNSSEC algorithms against those
|
||||
* supported by the crypto provider.
|
||||
*/
|
||||
#define BIND_CHECK_KEYS 0x00000004
|
||||
/*%<
|
||||
* Check the dnssec-policy DNSSEC keys against the key files
|
||||
* in the key stores.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
isccfg_check_namedconf(const cfg_obj_t *config, unsigned int flags,
|
||||
|
|
|
|||
|
|
@ -15,13 +15,17 @@
|
|||
|
||||
#include <isccfg/cfg.h>
|
||||
|
||||
#define ISCCFG_KASPCONF_CHECK_ALGORITHMS 0x01
|
||||
#define ISCCFG_KASPCONF_CHECK_KEYLIST 0x02
|
||||
#define ISCCFG_KASPCONF_LOG_ERRORS 0x04
|
||||
|
||||
/***
|
||||
*** Functions
|
||||
***/
|
||||
|
||||
isc_result_t
|
||||
cfg_kasp_fromconfig(const cfg_obj_t *config, dns_kasp_t *default_kasp,
|
||||
bool check_algorithms, isc_mem_t *mctx,
|
||||
unsigned int options, isc_mem_t *mctx,
|
||||
dns_keystorelist_t *keystorelist, dns_kasplist_t *kasplist,
|
||||
dns_kasp_t **kaspp);
|
||||
/*%<
|
||||
|
|
@ -34,8 +38,16 @@ cfg_kasp_fromconfig(const cfg_obj_t *config, dns_kasp_t *default_kasp,
|
|||
*
|
||||
* The 'keystorelist' is where to lookup key stores if KASP keys are using them.
|
||||
*
|
||||
* If 'check_algorithms' is true then the dnssec-policy DNSSEC key
|
||||
* algorithms are checked against those supported by the crypto provider.
|
||||
* If 'options' has ISCCFG_KASPCONF_CHECK_ALGORITHMS set, then the dnssec-policy
|
||||
* DNSSEC key algorithms are checked against those supported by the crypto
|
||||
* provider.
|
||||
*
|
||||
* If 'options' has ISCCFG_KASPCONF_CHECK_KEYLIST set, then this function
|
||||
* insists that the key list is not empty, unless the policy is "insecure"
|
||||
* (then the key list must be empty).
|
||||
*
|
||||
* If 'options' has ISCCFG_KASPCONF_LOG_ERRORS set, then configuration errors
|
||||
* and warnings are logged to the global logging context.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ get_string(const cfg_obj_t **maps, const char *option) {
|
|||
*/
|
||||
static isc_result_t
|
||||
cfg_kaspkey_fromconfig(const cfg_obj_t *config, dns_kasp_t *kasp,
|
||||
bool check_algorithms, bool offline_ksk,
|
||||
bool check_algorithms, bool log_errors, bool offline_ksk,
|
||||
dns_keystorelist_t *keystorelist,
|
||||
uint32_t ksk_min_lifetime, uint32_t zsk_min_lifetime) {
|
||||
isc_result_t result;
|
||||
|
|
@ -151,10 +151,13 @@ cfg_kaspkey_fromconfig(const cfg_obj_t *config, dns_kasp_t *kasp,
|
|||
key->role |= DNS_KASP_KEY_ROLE_ZSK;
|
||||
} else if (strcmp(rolestr, "csk") == 0) {
|
||||
if (offline_ksk) {
|
||||
cfg_obj_log(
|
||||
config, ISC_LOG_ERROR,
|
||||
"dnssec-policy: csk keys are not "
|
||||
"allowed when offline-ksk is enabled");
|
||||
if (log_errors) {
|
||||
cfg_obj_log(config, ISC_LOG_ERROR,
|
||||
"dnssec-policy: csk keys "
|
||||
"are not "
|
||||
"allowed when offline-ksk "
|
||||
"is enabled");
|
||||
}
|
||||
result = ISC_R_FAILURE;
|
||||
goto cleanup;
|
||||
}
|
||||
|
|
@ -172,14 +175,20 @@ cfg_kaspkey_fromconfig(const cfg_obj_t *config, dns_kasp_t *kasp,
|
|||
result = dns_keystorelist_find(keystorelist, keydir,
|
||||
&key->keystore);
|
||||
if (result == ISC_R_NOTFOUND) {
|
||||
cfg_obj_log(obj, ISC_LOG_ERROR,
|
||||
"dnssec-policy: keystore %s does not exist",
|
||||
keydir);
|
||||
if (log_errors) {
|
||||
cfg_obj_log(obj, ISC_LOG_ERROR,
|
||||
"dnssec-policy: keystore %s does "
|
||||
"not exist",
|
||||
keydir);
|
||||
}
|
||||
result = ISC_R_FAILURE;
|
||||
goto cleanup;
|
||||
} else if (result != ISC_R_SUCCESS) {
|
||||
cfg_obj_log(obj, ISC_LOG_ERROR,
|
||||
"dnssec-policy: bad keystore %s", keydir);
|
||||
if (log_errors) {
|
||||
cfg_obj_log(obj, ISC_LOG_ERROR,
|
||||
"dnssec-policy: bad keystore %s",
|
||||
keydir);
|
||||
}
|
||||
result = ISC_R_FAILURE;
|
||||
goto cleanup;
|
||||
}
|
||||
|
|
@ -192,9 +201,12 @@ cfg_kaspkey_fromconfig(const cfg_obj_t *config, dns_kasp_t *kasp,
|
|||
}
|
||||
if (key->lifetime > 0) {
|
||||
if (key->lifetime < 30 * (24 * 3600)) {
|
||||
cfg_obj_log(obj, ISC_LOG_WARNING,
|
||||
"dnssec-policy: key lifetime is "
|
||||
"shorter than 30 days");
|
||||
if (log_errors) {
|
||||
cfg_obj_log(obj, ISC_LOG_WARNING,
|
||||
"dnssec-policy: key "
|
||||
"lifetime is "
|
||||
"shorter than 30 days");
|
||||
}
|
||||
}
|
||||
if ((key->role & DNS_KASP_KEY_ROLE_KSK) != 0 &&
|
||||
key->lifetime <= ksk_min_lifetime)
|
||||
|
|
@ -207,10 +219,14 @@ cfg_kaspkey_fromconfig(const cfg_obj_t *config, dns_kasp_t *kasp,
|
|||
error = true;
|
||||
}
|
||||
if (error) {
|
||||
cfg_obj_log(obj, ISC_LOG_ERROR,
|
||||
"dnssec-policy: key lifetime is "
|
||||
"shorter than the time it takes to "
|
||||
"do a rollover");
|
||||
if (log_errors) {
|
||||
cfg_obj_log(obj, ISC_LOG_ERROR,
|
||||
"dnssec-policy: key "
|
||||
"lifetime is "
|
||||
"shorter than the time it "
|
||||
"takes to "
|
||||
"do a rollover");
|
||||
}
|
||||
result = ISC_R_FAILURE;
|
||||
goto cleanup;
|
||||
}
|
||||
|
|
@ -222,9 +238,11 @@ cfg_kaspkey_fromconfig(const cfg_obj_t *config, dns_kasp_t *kasp,
|
|||
result = dst_algorithm_fromtext(&key->algorithm,
|
||||
(isc_textregion_t *)&alg);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
cfg_obj_log(obj, ISC_LOG_ERROR,
|
||||
"dnssec-policy: bad algorithm %s",
|
||||
alg.base);
|
||||
if (log_errors) {
|
||||
cfg_obj_log(obj, ISC_LOG_ERROR,
|
||||
"dnssec-policy: bad algorithm %s",
|
||||
alg.base);
|
||||
}
|
||||
result = DNS_R_BADALG;
|
||||
goto cleanup;
|
||||
}
|
||||
|
|
@ -232,10 +250,13 @@ cfg_kaspkey_fromconfig(const cfg_obj_t *config, dns_kasp_t *kasp,
|
|||
(key->algorithm == DST_ALG_RSASHA1 ||
|
||||
key->algorithm == DST_ALG_NSEC3RSASHA1))
|
||||
{
|
||||
cfg_obj_log(obj, ISC_LOG_ERROR,
|
||||
"dnssec-policy: algorithm %s not supported "
|
||||
"in FIPS mode",
|
||||
alg.base);
|
||||
if (log_errors) {
|
||||
cfg_obj_log(obj, ISC_LOG_ERROR,
|
||||
"dnssec-policy: algorithm %s not "
|
||||
"supported "
|
||||
"in FIPS mode",
|
||||
alg.base);
|
||||
}
|
||||
result = DNS_R_BADALG;
|
||||
goto cleanup;
|
||||
}
|
||||
|
|
@ -243,9 +264,12 @@ cfg_kaspkey_fromconfig(const cfg_obj_t *config, dns_kasp_t *kasp,
|
|||
if (check_algorithms &&
|
||||
!dst_algorithm_supported(key->algorithm))
|
||||
{
|
||||
cfg_obj_log(obj, ISC_LOG_ERROR,
|
||||
"dnssec-policy: algorithm %s not supported",
|
||||
alg.base);
|
||||
if (log_errors) {
|
||||
cfg_obj_log(obj, ISC_LOG_ERROR,
|
||||
"dnssec-policy: algorithm %s not "
|
||||
"supported",
|
||||
alg.base);
|
||||
}
|
||||
result = DNS_R_BADALG;
|
||||
goto cleanup;
|
||||
}
|
||||
|
|
@ -253,10 +277,13 @@ cfg_kaspkey_fromconfig(const cfg_obj_t *config, dns_kasp_t *kasp,
|
|||
switch (key->algorithm) {
|
||||
case DST_ALG_RSASHA1:
|
||||
case DST_ALG_NSEC3RSASHA1:
|
||||
cfg_obj_log(obj, ISC_LOG_WARNING,
|
||||
"dnssec-policy: DNSSEC algorithm %s is "
|
||||
"deprecated",
|
||||
alg.base);
|
||||
if (log_errors) {
|
||||
cfg_obj_log(
|
||||
obj, ISC_LOG_WARNING,
|
||||
"dnssec-policy: DNSSEC algorithm %s is "
|
||||
"deprecated",
|
||||
alg.base);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
@ -280,11 +307,15 @@ cfg_kaspkey_fromconfig(const cfg_obj_t *config, dns_kasp_t *kasp,
|
|||
min = DST_ALG_RSASHA512 ? 1024 : 512;
|
||||
}
|
||||
if (size < min || size > 4096) {
|
||||
cfg_obj_log(obj, ISC_LOG_ERROR,
|
||||
"dnssec-policy: key with "
|
||||
"algorithm %s has invalid "
|
||||
"key length %u",
|
||||
alg.base, size);
|
||||
if (log_errors) {
|
||||
cfg_obj_log(obj, ISC_LOG_ERROR,
|
||||
"dnssec-policy: "
|
||||
"key with "
|
||||
"algorithm %s has "
|
||||
"invalid "
|
||||
"key length %u",
|
||||
alg.base, size);
|
||||
}
|
||||
result = ISC_R_RANGE;
|
||||
goto cleanup;
|
||||
}
|
||||
|
|
@ -293,11 +324,15 @@ cfg_kaspkey_fromconfig(const cfg_obj_t *config, dns_kasp_t *kasp,
|
|||
case DST_ALG_ECDSA384:
|
||||
case DST_ALG_ED25519:
|
||||
case DST_ALG_ED448:
|
||||
cfg_obj_log(obj, ISC_LOG_WARNING,
|
||||
"dnssec-policy: key algorithm %s "
|
||||
"has predefined length; ignoring "
|
||||
"length value %u",
|
||||
alg.base, size);
|
||||
if (log_errors) {
|
||||
cfg_obj_log(obj, ISC_LOG_WARNING,
|
||||
"dnssec-policy: key "
|
||||
"algorithm %s "
|
||||
"has predefined length; "
|
||||
"ignoring "
|
||||
"length value %u",
|
||||
alg.base, size);
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -311,25 +346,31 @@ cfg_kaspkey_fromconfig(const cfg_obj_t *config, dns_kasp_t *kasp,
|
|||
obj = cfg_tuple_get(tagrange, "tag-min");
|
||||
tag_min = cfg_obj_asuint32(obj);
|
||||
if (tag_min > 0xffff) {
|
||||
cfg_obj_log(obj, ISC_LOG_ERROR,
|
||||
"dnssec-policy: tag-min "
|
||||
"too big");
|
||||
if (log_errors) {
|
||||
cfg_obj_log(obj, ISC_LOG_ERROR,
|
||||
"dnssec-policy: tag-min "
|
||||
"too big");
|
||||
}
|
||||
result = ISC_R_RANGE;
|
||||
goto cleanup;
|
||||
}
|
||||
obj = cfg_tuple_get(tagrange, "tag-max");
|
||||
tag_max = cfg_obj_asuint32(obj);
|
||||
if (tag_max > 0xffff) {
|
||||
cfg_obj_log(obj, ISC_LOG_ERROR,
|
||||
"dnssec-policy: tag-max "
|
||||
"too big");
|
||||
if (log_errors) {
|
||||
cfg_obj_log(obj, ISC_LOG_ERROR,
|
||||
"dnssec-policy: tag-max "
|
||||
"too big");
|
||||
}
|
||||
result = ISC_R_RANGE;
|
||||
goto cleanup;
|
||||
}
|
||||
if (tag_min >= tag_max) {
|
||||
cfg_obj_log(
|
||||
obj, ISC_LOG_ERROR,
|
||||
"dnssec-policy: tag-min >= tag_max");
|
||||
if (log_errors) {
|
||||
cfg_obj_log(obj, ISC_LOG_ERROR,
|
||||
"dnssec-policy: tag-min >= "
|
||||
"tag_max");
|
||||
}
|
||||
result = ISC_R_RANGE;
|
||||
goto cleanup;
|
||||
}
|
||||
|
|
@ -348,7 +389,8 @@ cleanup:
|
|||
}
|
||||
|
||||
static isc_result_t
|
||||
cfg_nsec3param_fromconfig(const cfg_obj_t *config, dns_kasp_t *kasp) {
|
||||
cfg_nsec3param_fromconfig(const cfg_obj_t *config, dns_kasp_t *kasp,
|
||||
bool log_errors) {
|
||||
unsigned int min_keysize = 4096;
|
||||
const cfg_obj_t *obj = NULL;
|
||||
uint32_t iter = DEFAULT_NSEC3PARAM_ITER;
|
||||
|
|
@ -382,18 +424,22 @@ cfg_nsec3param_fromconfig(const cfg_obj_t *config, dns_kasp_t *kasp) {
|
|||
if (badalg > 0) {
|
||||
char algstr[DNS_SECALG_FORMATSIZE];
|
||||
dns_secalg_format((dns_secalg_t)badalg, algstr, sizeof(algstr));
|
||||
cfg_obj_log(
|
||||
obj, ISC_LOG_ERROR,
|
||||
"dnssec-policy: cannot use nsec3 with algorithm '%s'",
|
||||
algstr);
|
||||
if (log_errors) {
|
||||
cfg_obj_log(obj, ISC_LOG_ERROR,
|
||||
"dnssec-policy: cannot use nsec3 with "
|
||||
"algorithm '%s'",
|
||||
algstr);
|
||||
}
|
||||
return DNS_R_NSEC3BADALG;
|
||||
}
|
||||
|
||||
if (iter != DEFAULT_NSEC3PARAM_ITER) {
|
||||
cfg_obj_log(obj, ISC_LOG_ERROR,
|
||||
"dnssec-policy: nsec3 iterations value %u "
|
||||
"not allowed, must be zero",
|
||||
iter);
|
||||
if (log_errors) {
|
||||
cfg_obj_log(obj, ISC_LOG_ERROR,
|
||||
"dnssec-policy: nsec3 iterations value %u "
|
||||
"not allowed, must be zero",
|
||||
iter);
|
||||
}
|
||||
return DNS_R_NSEC3ITERRANGE;
|
||||
}
|
||||
|
||||
|
|
@ -409,9 +455,12 @@ cfg_nsec3param_fromconfig(const cfg_obj_t *config, dns_kasp_t *kasp) {
|
|||
saltlen = cfg_obj_asuint32(obj);
|
||||
}
|
||||
if (saltlen > 0xff) {
|
||||
cfg_obj_log(obj, ISC_LOG_ERROR,
|
||||
"dnssec-policy: nsec3 salt length %u too high",
|
||||
saltlen);
|
||||
if (log_errors) {
|
||||
cfg_obj_log(
|
||||
obj, ISC_LOG_ERROR,
|
||||
"dnssec-policy: nsec3 salt length %u too high",
|
||||
saltlen);
|
||||
}
|
||||
return DNS_R_NSEC3SALTRANGE;
|
||||
}
|
||||
|
||||
|
|
@ -420,7 +469,7 @@ cfg_nsec3param_fromconfig(const cfg_obj_t *config, dns_kasp_t *kasp) {
|
|||
}
|
||||
|
||||
static isc_result_t
|
||||
add_digest(dns_kasp_t *kasp, const cfg_obj_t *digest) {
|
||||
add_digest(dns_kasp_t *kasp, const cfg_obj_t *digest, bool log_errors) {
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
isc_textregion_t r;
|
||||
dns_dsdigest_t alg;
|
||||
|
|
@ -430,21 +479,28 @@ add_digest(dns_kasp_t *kasp, const cfg_obj_t *digest) {
|
|||
r.length = strlen(str);
|
||||
result = dns_dsdigest_fromtext(&alg, &r);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
cfg_obj_log(digest, ISC_LOG_ERROR,
|
||||
"dnssec-policy: bad cds digest-type %s", str);
|
||||
if (log_errors) {
|
||||
cfg_obj_log(digest, ISC_LOG_ERROR,
|
||||
"dnssec-policy: bad cds digest-type %s",
|
||||
str);
|
||||
}
|
||||
result = DNS_R_BADALG;
|
||||
} else if (!dst_ds_digest_supported(alg)) {
|
||||
cfg_obj_log(digest, ISC_LOG_ERROR,
|
||||
"dnssec-policy: unsupported cds "
|
||||
"digest-type %s",
|
||||
str);
|
||||
if (log_errors) {
|
||||
cfg_obj_log(digest, ISC_LOG_ERROR,
|
||||
"dnssec-policy: unsupported cds "
|
||||
"digest-type %s",
|
||||
str);
|
||||
}
|
||||
result = DST_R_UNSUPPORTEDALG;
|
||||
} else {
|
||||
if (alg == DNS_DSDIGEST_SHA1) {
|
||||
cfg_obj_log(
|
||||
digest, ISC_LOG_WARNING,
|
||||
"dnssec-policy: deprecated CDS digest-type %s",
|
||||
str);
|
||||
if (log_errors) {
|
||||
cfg_obj_log(digest, ISC_LOG_WARNING,
|
||||
"dnssec-policy: deprecated CDS "
|
||||
"digest-type %s",
|
||||
str);
|
||||
}
|
||||
}
|
||||
dns_kasp_adddigest(kasp, alg);
|
||||
}
|
||||
|
|
@ -453,7 +509,7 @@ add_digest(dns_kasp_t *kasp, const cfg_obj_t *digest) {
|
|||
|
||||
isc_result_t
|
||||
cfg_kasp_fromconfig(const cfg_obj_t *config, dns_kasp_t *default_kasp,
|
||||
bool check_algorithms, isc_mem_t *mctx,
|
||||
unsigned int options, isc_mem_t *mctx,
|
||||
dns_keystorelist_t *keystorelist, dns_kasplist_t *kasplist,
|
||||
dns_kasp_t **kaspp) {
|
||||
isc_result_t result;
|
||||
|
|
@ -474,6 +530,10 @@ cfg_kasp_fromconfig(const cfg_obj_t *config, dns_kasp_t *default_kasp,
|
|||
uint32_t ipub = 0, iret = 0;
|
||||
uint32_t ksk_min_lifetime = 0, zsk_min_lifetime = 0;
|
||||
bool offline_ksk = false, manual_mode = false;
|
||||
bool check_algorithms = (options & ISCCFG_KASPCONF_CHECK_ALGORITHMS) !=
|
||||
0;
|
||||
bool check_keylist = (options & ISCCFG_KASPCONF_CHECK_KEYLIST) != 0;
|
||||
bool log_errors = (options & ISCCFG_KASPCONF_LOG_ERRORS) != 0;
|
||||
|
||||
REQUIRE(config != NULL);
|
||||
REQUIRE(kaspp != NULL && *kaspp == NULL);
|
||||
|
|
@ -487,10 +547,12 @@ cfg_kasp_fromconfig(const cfg_obj_t *config, dns_kasp_t *default_kasp,
|
|||
result = dns_kasplist_find(kasplist, kaspname, &kasp);
|
||||
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
cfg_obj_log(
|
||||
config, ISC_LOG_ERROR,
|
||||
"dnssec-policy: duplicately named policy found '%s'",
|
||||
kaspname);
|
||||
if (log_errors) {
|
||||
cfg_obj_log(config, ISC_LOG_ERROR,
|
||||
"dnssec-policy: duplicately named policy "
|
||||
"found '%s'",
|
||||
kaspname);
|
||||
}
|
||||
dns_kasp_detach(&kasp);
|
||||
return ISC_R_EXISTS;
|
||||
}
|
||||
|
|
@ -526,42 +588,51 @@ cfg_kasp_fromconfig(const cfg_obj_t *config, dns_kasp_t *default_kasp,
|
|||
sigvalidity = get_duration(maps, "signatures-validity-dnskey",
|
||||
DNS_KASP_SIG_VALIDITY_DNSKEY);
|
||||
if (sigrefresh >= (sigvalidity * 0.9)) {
|
||||
cfg_obj_log(
|
||||
config, ISC_LOG_ERROR,
|
||||
"dnssec-policy: policy '%s' signatures-refresh must be "
|
||||
"at most 90%% of the signatures-validity-dnskey",
|
||||
kaspname);
|
||||
if (log_errors) {
|
||||
cfg_obj_log(config, ISC_LOG_ERROR,
|
||||
"dnssec-policy: policy '%s' "
|
||||
"signatures-refresh must be "
|
||||
"at most 90%% of the "
|
||||
"signatures-validity-dnskey",
|
||||
kaspname);
|
||||
}
|
||||
result = ISC_R_FAILURE;
|
||||
}
|
||||
dns_kasp_setsigvalidity_dnskey(kasp, sigvalidity);
|
||||
|
||||
if (sigjitter > sigvalidity) {
|
||||
cfg_obj_log(
|
||||
config, ISC_LOG_ERROR,
|
||||
"dnssec-policy: policy '%s' signatures-jitter cannot "
|
||||
"be larger than signatures-validity-dnskey",
|
||||
kaspname);
|
||||
if (log_errors) {
|
||||
cfg_obj_log(config, ISC_LOG_ERROR,
|
||||
"dnssec-policy: policy '%s' "
|
||||
"signatures-jitter cannot "
|
||||
"be larger than signatures-validity-dnskey",
|
||||
kaspname);
|
||||
}
|
||||
result = ISC_R_FAILURE;
|
||||
}
|
||||
|
||||
sigvalidity = get_duration(maps, "signatures-validity",
|
||||
DNS_KASP_SIG_VALIDITY);
|
||||
if (sigrefresh >= (sigvalidity * 0.9)) {
|
||||
cfg_obj_log(
|
||||
config, ISC_LOG_ERROR,
|
||||
"dnssec-policy: policy '%s' signatures-refresh must be "
|
||||
"at most 90%% of the signatures-validity",
|
||||
kaspname);
|
||||
if (log_errors) {
|
||||
cfg_obj_log(config, ISC_LOG_ERROR,
|
||||
"dnssec-policy: policy '%s' "
|
||||
"signatures-refresh must be "
|
||||
"at most 90%% of the signatures-validity",
|
||||
kaspname);
|
||||
}
|
||||
result = ISC_R_FAILURE;
|
||||
}
|
||||
dns_kasp_setsigvalidity(kasp, sigvalidity);
|
||||
|
||||
if (sigjitter > sigvalidity) {
|
||||
cfg_obj_log(
|
||||
config, ISC_LOG_ERROR,
|
||||
"dnssec-policy: policy '%s' signatures-jitter cannot "
|
||||
"be larger than signatures-validity",
|
||||
kaspname);
|
||||
if (log_errors) {
|
||||
cfg_obj_log(config, ISC_LOG_ERROR,
|
||||
"dnssec-policy: policy '%s' "
|
||||
"signatures-jitter cannot "
|
||||
"be larger than signatures-validity",
|
||||
kaspname);
|
||||
}
|
||||
result = ISC_R_FAILURE;
|
||||
}
|
||||
|
||||
|
|
@ -619,7 +690,8 @@ cfg_kasp_fromconfig(const cfg_obj_t *config, dns_kasp_t *default_kasp,
|
|||
(void)confget(maps, "cds-digest-types", &cds);
|
||||
if (cds != NULL) {
|
||||
CFG_LIST_FOREACH(cds, element) {
|
||||
result = add_digest(kasp, cfg_listelt_value(element));
|
||||
result = add_digest(kasp, cfg_listelt_value(element),
|
||||
log_errors);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
|
@ -658,14 +730,16 @@ cfg_kasp_fromconfig(const cfg_obj_t *config, dns_kasp_t *default_kasp,
|
|||
CFG_LIST_FOREACH(keys, element) {
|
||||
cfg_obj_t *kobj = cfg_listelt_value(element);
|
||||
result = cfg_kaspkey_fromconfig(
|
||||
kobj, kasp, check_algorithms, offline_ksk,
|
||||
keystorelist, ksk_min_lifetime,
|
||||
kobj, kasp, check_algorithms, log_errors,
|
||||
offline_ksk, keystorelist, ksk_min_lifetime,
|
||||
zsk_min_lifetime);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
cfg_obj_log(kobj, ISC_LOG_ERROR,
|
||||
"dnssec-policy: failed to "
|
||||
"configure keys (%s)",
|
||||
isc_result_totext(result));
|
||||
if (log_errors) {
|
||||
cfg_obj_log(kobj, ISC_LOG_ERROR,
|
||||
"dnssec-policy: failed to "
|
||||
"configure keys (%s)",
|
||||
isc_result_totext(result));
|
||||
}
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
|
@ -698,19 +772,22 @@ cfg_kasp_fromconfig(const cfg_obj_t *config, dns_kasp_t *default_kasp,
|
|||
if (role[i] !=
|
||||
(DNS_KASP_KEY_ROLE_ZSK | DNS_KASP_KEY_ROLE_KSK))
|
||||
{
|
||||
cfg_obj_log(keys, ISC_LOG_ERROR,
|
||||
"dnssec-policy: algorithm %zu "
|
||||
"requires both KSK and ZSK roles",
|
||||
i);
|
||||
if (log_errors) {
|
||||
cfg_obj_log(keys, ISC_LOG_ERROR,
|
||||
"dnssec-policy: algorithm "
|
||||
"%zu requires both KSK and "
|
||||
"ZSK roles",
|
||||
i);
|
||||
}
|
||||
result = ISC_R_FAILURE;
|
||||
}
|
||||
if (warn[i][0]) {
|
||||
if (warn[i][0] && log_errors) {
|
||||
cfg_obj_log(keys, ISC_LOG_WARNING,
|
||||
"dnssec-policy: algorithm %zu has "
|
||||
"multiple keys with ZSK role",
|
||||
i);
|
||||
}
|
||||
if (warn[i][1]) {
|
||||
if (warn[i][1] && log_errors) {
|
||||
cfg_obj_log(keys, ISC_LOG_WARNING,
|
||||
"dnssec-policy: algorithm %zu has "
|
||||
"multiple keys with KSK role",
|
||||
|
|
@ -744,20 +821,22 @@ cfg_kasp_fromconfig(const cfg_obj_t *config, dns_kasp_t *default_kasp,
|
|||
keystorelist, DNS_KEYSTORE_KEYDIRECTORY,
|
||||
&new_key->keystore);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
cfg_obj_log(config, ISC_LOG_ERROR,
|
||||
"dnssec-policy: failed to "
|
||||
"find keystore (%s)",
|
||||
isc_result_totext(result));
|
||||
if (log_errors) {
|
||||
cfg_obj_log(config, ISC_LOG_ERROR,
|
||||
"dnssec-policy: failed to "
|
||||
"find keystore (%s)",
|
||||
isc_result_totext(result));
|
||||
}
|
||||
goto cleanup;
|
||||
}
|
||||
dns_kasp_addkey(kasp, new_key);
|
||||
}
|
||||
}
|
||||
|
||||
if (strcmp(kaspname, "insecure") == 0) {
|
||||
if (strcmp(kaspname, "insecure") == 0 && check_keylist) {
|
||||
/* "dnssec-policy insecure": key list must be empty */
|
||||
INSIST(dns_kasp_keylist_empty(kasp));
|
||||
} else if (default_kasp != NULL) {
|
||||
} else if (default_kasp != NULL && check_keylist) {
|
||||
/* There must be keys configured. */
|
||||
INSIST(!(dns_kasp_keylist_empty(kasp)));
|
||||
}
|
||||
|
|
@ -775,7 +854,7 @@ cfg_kasp_fromconfig(const cfg_obj_t *config, dns_kasp_t *default_kasp,
|
|||
}
|
||||
} else {
|
||||
dns_kasp_setnsec3(kasp, true);
|
||||
result = cfg_nsec3param_fromconfig(nsec3, kasp);
|
||||
result = cfg_nsec3param_fromconfig(nsec3, kasp, log_errors);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue