]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Check dnssec-policy key roles for validity
authorMark Andrews <marka@isc.org>
Tue, 15 Feb 2022 06:12:27 +0000 (17:12 +1100)
committerMark Andrews <marka@isc.org>
Tue, 8 Mar 2022 02:23:14 +0000 (13:23 +1100)
For each algorithm there must be a key performing the KSK and
ZSK rolls.  After reading the keys from named.conf check that
each algorithm present has both rolls.  CSK implicitly has both
rolls.

lib/isccfg/kaspconf.c

index f2eb77aab26765979d75d9d269902e0fb39f1ff6..a8a078f0c78cb4ecd788a5c8fec78f6cc294c785 100644 (file)
@@ -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);