]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Code changes for CSK
authorMatthijs Mekking <matthijs@isc.org>
Wed, 30 Oct 2019 13:38:28 +0000 (14:38 +0100)
committerMatthijs Mekking <matthijs@isc.org>
Wed, 6 Nov 2019 21:36:21 +0000 (22:36 +0100)
Update dns_dnssec_keyactive to differentiate between the roles ZSK
and KSK.  A key is active if it is signing but that differs per role.
A ZSK is signing if its ZRRSIG state is in RUMOURED or OMNIPRESENT,
a KSK is signing if its KRRSIG state is in RUMOURED or OMNIPRESENT.

This means that a key can be actively signing for one role but not
the other.  Add checks in inline signing (zone.c and update.c) to
cover the case where a CSK is active in its KSK role but not the ZSK
role.

lib/dns/dnssec.c
lib/dns/dst_api.c
lib/dns/include/dst/dst.h
lib/dns/update.c
lib/dns/zone.c

index ac70dc97033c5df1bee64d6d670e63d73e284d03..388689144b575feca750773d43ab472cb2f16224 100644 (file)
@@ -584,13 +584,25 @@ bool
 dns_dnssec_keyactive(dst_key_t *key, isc_stdtime_t now) {
        isc_result_t result;
        isc_stdtime_t publish, active, revoke, remove;
-       bool hint_publish, hint_sign, hint_revoke, hint_remove;
+       bool hint_publish, hint_zsign, hint_ksign, hint_revoke, hint_remove;
        int major, minor;
+       bool ksk = false, zsk = false;
+       isc_result_t ret;
 
        /* Is this an old-style key? */
        result = dst_key_getprivateformat(key, &major, &minor);
        RUNTIME_CHECK(result == ISC_R_SUCCESS);
 
+       /* Is this a KSK? */
+       ret = dst_key_getbool(key, DST_BOOL_KSK, &ksk);
+       if (ret != ISC_R_SUCCESS) {
+               ksk = ((dst_key_flags(key) & DNS_KEYFLAG_KSK) != 0);
+       }
+       ret = dst_key_getbool(key, DST_BOOL_ZSK, &zsk);
+       if (ret != ISC_R_SUCCESS) {
+               zsk = ((dst_key_flags(key) & DNS_KEYFLAG_KSK) == 0);
+       }
+
        /*
         * Smart signing started with key format 1.3; prior to that, all
         * keys are assumed active.
@@ -599,7 +611,8 @@ dns_dnssec_keyactive(dst_key_t *key, isc_stdtime_t now) {
                return (true);
 
        hint_publish = dst_key_is_published(key, now, &publish);
-       hint_sign = dst_key_is_signing(key, now, &active);
+       hint_zsign = dst_key_is_signing(key, DST_BOOL_ZSK, now, &active);
+       hint_ksign = dst_key_is_signing(key, DST_BOOL_KSK, now, &active);
        hint_revoke = dst_key_is_revoked(key, now, &revoke);
        hint_remove = dst_key_is_removed(key, now, &remove);
 
@@ -609,7 +622,10 @@ dns_dnssec_keyactive(dst_key_t *key, isc_stdtime_t now) {
        if (hint_publish && hint_revoke) {
                return (true);
        }
-       if (hint_sign) {
+       if (hint_zsign && zsk) {
+               return (true);
+       }
+       if (hint_ksign && ksk) {
                return (true);
        }
        return (false);
@@ -1255,7 +1271,8 @@ dns_dnssec_get_hints(dns_dnsseckey_t *key, isc_stdtime_t now) {
        REQUIRE(key != NULL && key->key != NULL);
 
        key->hint_publish = dst_key_is_published(key->key, now, &publish);
-       key->hint_sign = dst_key_is_signing(key->key, now, &active);
+       key->hint_sign = dst_key_is_signing(key->key, DST_BOOL_ZSK, now,
+                                           &active);
        key->hint_revoke = dst_key_is_revoked(key->key, now, &revoke);
        key->hint_remove = dst_key_is_removed(key->key, now, &remove);
 
index d8d8869e4a63b87d93b02ab89375eb0fb129a7f0..cfa4bbcda63e5d0805eee93c9d04150ca48b6f39 100644 (file)
@@ -2476,7 +2476,7 @@ dst_key_is_active(dst_key_t *key, isc_stdtime_t now)
 
 
 bool
-dst_key_is_signing(dst_key_t *key, isc_stdtime_t now, isc_stdtime_t *active)
+dst_key_is_signing(dst_key_t *key, int role, isc_stdtime_t now, isc_stdtime_t *active)
 {
        dst_key_state_t state;
        isc_result_t result;
@@ -2503,7 +2503,7 @@ dst_key_is_signing(dst_key_t *key, isc_stdtime_t now, isc_stdtime_t *active)
         * If the RRSIG state is RUMOURED or OMNIPRESENT, it means the key
         * is active.
         */
-       if (ksk) {
+       if (ksk && role == DST_BOOL_KSK) {
                result = dst_key_getstate(key, DST_KEY_KRRSIG, &state);
                if (result == ISC_R_SUCCESS) {
                        krrsig_ok = ((state == DST_KEY_STATE_RUMOURED) ||
@@ -2515,8 +2515,7 @@ dst_key_is_signing(dst_key_t *key, isc_stdtime_t now, isc_stdtime_t *active)
                        time_ok = true;
                        inactive = false;
                }
-       }
-       if (zsk) {
+       } else if (zsk && role == DST_BOOL_ZSK) {
                result = dst_key_getstate(key, DST_KEY_ZRRSIG, &state);
                if (result == ISC_R_SUCCESS) {
                        zrrsig_ok = ((state == DST_KEY_STATE_RUMOURED) ||
index a37725f404e7603c188a8886fe3642bb977e5d45..febadabae76f1d0c66e1ddec8c21c7aab49e357e 100644 (file)
@@ -1138,9 +1138,10 @@ dst_key_is_active(dst_key_t *key, isc_stdtime_t now);
  */
 
 bool
-dst_key_is_signing(dst_key_t *key, isc_stdtime_t now, isc_stdtime_t *active);
+dst_key_is_signing(dst_key_t *key, int role, isc_stdtime_t now,
+                  isc_stdtime_t *active);
 /*%<
- * Check if it is safe to use this key for signing.
+ * Check if it is safe to use this key for signing, given the role.
  *
  * Requires:
  *     'key' to be valid.
index 4c621c404f258b14bfa28cf6a2eb065bc04c28a1..9bd5896796ea8a62e85458cc8bb818e5cac9b716 100644 (file)
@@ -1167,6 +1167,7 @@ add_sigs(dns_update_log_t *log, dns_zone_t *zone, dns_db_t *db,
                         * A dnssec-policy is found. Check what RRsets this
                         * key should sign.
                         */
+                       isc_stdtime_t when;
                        isc_result_t kresult;
                        bool ksk = false;
                        bool zsk = false;
@@ -1200,6 +1201,14 @@ add_sigs(dns_update_log_t *log, dns_zone_t *zone, dns_db_t *db,
                                 * Other RRsets are signed with ZSK.
                                 */
                                continue;
+                       } else if (zsk && !dst_key_is_signing(keys[i],
+                                                             DST_BOOL_ZSK,
+                                                             inception,
+                                                             &when)) {
+                               /*
+                                * This key is not active for zone-signing.
+                                */
+                               continue;
                        }
 
                        /*
index c88c1714ac4fd384a3893789fba837a28b38e48f..85832daef5f6d77adc2402c4ee432eb35719b837 100644 (file)
@@ -6616,6 +6616,7 @@ add_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
                         * key should sign.
                         */
                        isc_result_t kresult;
+                       isc_stdtime_t when;
                        bool ksk = false;
                        bool zsk = false;
 
@@ -6648,6 +6649,12 @@ add_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
                                 * Other RRsets are signed with ZSK.
                                 */
                                continue;
+                       } else if (!dst_key_is_signing(keys[i], DST_BOOL_ZSK,
+                                                      inception, &when)) {
+                               /*
+                                * This key is not active for zone-signing.
+                                */
+                               continue;
                        }
 
                        /*
@@ -7027,8 +7034,8 @@ signed_with_good_key(dns_zone_t* zone, dns_db_t *db, dns_dbnode_t *node,
 
        if (kasp) {
                dns_kasp_key_t* kkey;
-               int ksk_count = 0, zsk_count = 0;
-               bool approved = false;
+               int zsk_count = 0;
+               bool approved;
 
                for (kkey = ISC_LIST_HEAD(kasp->keys); kkey != NULL;
                     kkey = ISC_LIST_NEXT(kkey, link))
@@ -7036,9 +7043,6 @@ signed_with_good_key(dns_zone_t* zone, dns_db_t *db, dns_dbnode_t *node,
                        if (dns_kasp_key_algorithm(kkey) != dst_key_alg(key)) {
                                continue;
                        }
-                       if (dns_kasp_key_ksk(kkey)) {
-                               ksk_count++;
-                       }
                        if (dns_kasp_key_zsk(kkey)) {
                                zsk_count++;
                        }
@@ -7053,7 +7057,7 @@ signed_with_good_key(dns_zone_t* zone, dns_db_t *db, dns_dbnode_t *node,
                         * be signed with a key in the current DS RRset,
                         * which would only include KSK's.)
                         */
-                       approved = (ksk_count == count);
+                       approved = false;
                } else {
                        approved = (zsk_count == count);
                }
@@ -7149,6 +7153,7 @@ sign_a_node(dns_db_t *db, dns_zone_t *zone, dns_name_t *name,
            dns_diff_t *diff, int32_t *signatures, isc_mem_t *mctx)
 {
        isc_result_t result;
+       dns_kasp_t *kasp = dns_zone_getkasp(zone);
        dns_rdatasetiter_t *iterator = NULL;
        dns_rdataset_t rdataset;
        dns_rdata_t rdata = DNS_RDATA_INIT;
@@ -7216,6 +7221,8 @@ sign_a_node(dns_db_t *db, dns_zone_t *zone, dns_name_t *name,
        }
        result = dns_rdatasetiter_first(iterator);
        while (result == ISC_R_SUCCESS) {
+               isc_stdtime_t when;
+
                dns_rdatasetiter_current(iterator, &rdataset);
                if (rdataset.type == dns_rdatatype_soa ||
                    rdataset.type == dns_rdatatype_rrsig)
@@ -7237,7 +7244,14 @@ sign_a_node(dns_db_t *db, dns_zone_t *zone, dns_name_t *name,
                        }
                } else if (!is_zsk) {
                        goto next_rdataset;
+               } else if (is_zsk && !dst_key_is_signing(key, DST_BOOL_ZSK,
+                                                        inception, &when)) {
+                       /* Only applies to dnssec-policy. */
+                       if (kasp != NULL) {
+                               goto next_rdataset;
+                       }
                }
+
                if (seen_ns && !seen_soa &&
                    rdataset.type != dns_rdatatype_ds &&
                    rdataset.type != dns_rdatatype_nsec)