diff --git a/lib/isccfg/kaspconf.c b/lib/isccfg/kaspconf.c index f2eb77aab2..a8a078f0c7 100644 --- a/lib/isccfg/kaspconf.c +++ b/lib/isccfg/kaspconf.c @@ -262,7 +262,7 @@ cfg_kasp_fromconfig(const cfg_obj_t *config, const char *name, isc_mem_t *mctx, const cfg_listelt_t *element = NULL; const char *kaspname = NULL; dns_kasp_t *kasp = NULL; - int i = 0; + size_t i = 0; REQUIRE(kaspp != NULL && *kaspp == NULL); @@ -323,6 +323,9 @@ cfg_kasp_fromconfig(const cfg_obj_t *config, const char *name, isc_mem_t *mctx, (void)confget(maps, "keys", &keys); if (keys != NULL) { + char role[256] = { 0 }; + dns_kasp_key_t *kkey = NULL; + for (element = cfg_list_first(keys); element != NULL; element = cfg_list_next(element)) { @@ -333,6 +336,36 @@ cfg_kasp_fromconfig(const cfg_obj_t *config, const char *name, isc_mem_t *mctx, } } INSIST(!(dns_kasp_keylist_empty(kasp))); + dns_kasp_freeze(kasp); + for (kkey = ISC_LIST_HEAD(dns_kasp_keys(kasp)); kkey != NULL; + kkey = ISC_LIST_NEXT(kkey, link)) + { + uint32_t keyalg = dns_kasp_key_algorithm(kkey); + INSIST(keyalg < ARRAY_SIZE(role)); + + if (dns_kasp_key_zsk(kkey)) { + role[keyalg] |= DNS_KASP_KEY_ROLE_ZSK; + } + + if (dns_kasp_key_ksk(kkey)) { + role[keyalg] |= DNS_KASP_KEY_ROLE_KSK; + } + } + dns_kasp_thaw(kasp); + for (i = 0; i < ARRAY_SIZE(role); i++) { + if (role[i] != 0 && role[i] != (DNS_KASP_KEY_ROLE_ZSK | + DNS_KASP_KEY_ROLE_KSK)) + { + cfg_obj_log(keys, logctx, ISC_LOG_ERROR, + "dnssec-policy: algorithm %zu " + "requires both KSK and ZSK roles", + i); + result = ISC_R_FAILURE; + } + } + if (result != ISC_R_SUCCESS) { + goto cleanup; + } } else if (strcmp(kaspname, "insecure") == 0) { /* "dnssec-policy insecure": key list must be empty */ INSIST(strcmp(kaspname, "insecure") == 0);