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);
/*
* 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':
nomerge = false;
break;
+ case 'k':
+ checkflags |= BIND_CHECK_KEYS;
+ break;
+
case 'l':
list_zones = true;
break;
Synopsis
~~~~~~~~
-:program:`named-checkconf` [**-achjlnvz**] [**-p** [**-x** ]] [**-t** directory] {filename}
+:program:`named-checkconf` [**-achjklnvz**] [**-p** [**-x** ]] [**-t** directory] {filename}
Description
~~~~~~~~~~~
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
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);
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")),
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;
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) {
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) {
#include <dns/dnssec.h>
#include <dns/keystore.h>
+#include <dns/name.h>
#include <dns/types.h>
/* For storing a list of digest types */
#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);
/*%<
*\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);
/*%<
*\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,
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);
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;
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);
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)) {
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,
#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>
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;
}
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;
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.
*/
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;
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;
if (kasp == NULL) {
goto check;
}
+ INSIST(kaspobj != NULL);
/* Check key-stores of keys */
dns_kasp_freeze(kasp);
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;
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;
*/
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);
* 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,
#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);
/*%<
*
* 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:
*
*/
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;
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;
}
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;
}
}
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)
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;
}
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;
}
(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;
}
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;
}
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;
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;
}
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;
}
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;
}
}
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;
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;
}
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;
}
}
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;
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);
}
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;
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);
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;
}
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;
}
(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;
}
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;
}
}
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",
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)));
}
}
} 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;
}