2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-28 21:17:54 +00:00

Code changes for CSK

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.
This commit is contained in:
Matthijs Mekking 2019-10-30 14:38:28 +01:00
parent 6468ffc336
commit 67033bfd3d
5 changed files with 56 additions and 16 deletions

View File

@ -584,13 +584,25 @@ bool
dns_dnssec_keyactive(dst_key_t *key, isc_stdtime_t now) { dns_dnssec_keyactive(dst_key_t *key, isc_stdtime_t now) {
isc_result_t result; isc_result_t result;
isc_stdtime_t publish, active, revoke, remove; 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; int major, minor;
bool ksk = false, zsk = false;
isc_result_t ret;
/* Is this an old-style key? */ /* Is this an old-style key? */
result = dst_key_getprivateformat(key, &major, &minor); result = dst_key_getprivateformat(key, &major, &minor);
RUNTIME_CHECK(result == ISC_R_SUCCESS); 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 * Smart signing started with key format 1.3; prior to that, all
* keys are assumed active. * keys are assumed active.
@ -599,7 +611,8 @@ dns_dnssec_keyactive(dst_key_t *key, isc_stdtime_t now) {
return (true); return (true);
hint_publish = dst_key_is_published(key, now, &publish); 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_revoke = dst_key_is_revoked(key, now, &revoke);
hint_remove = dst_key_is_removed(key, now, &remove); 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) { if (hint_publish && hint_revoke) {
return (true); return (true);
} }
if (hint_sign) { if (hint_zsign && zsk) {
return (true);
}
if (hint_ksign && ksk) {
return (true); return (true);
} }
return (false); return (false);
@ -1255,7 +1271,8 @@ dns_dnssec_get_hints(dns_dnsseckey_t *key, isc_stdtime_t now) {
REQUIRE(key != NULL && key->key != NULL); REQUIRE(key != NULL && key->key != NULL);
key->hint_publish = dst_key_is_published(key->key, now, &publish); 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_revoke = dst_key_is_revoked(key->key, now, &revoke);
key->hint_remove = dst_key_is_removed(key->key, now, &remove); key->hint_remove = dst_key_is_removed(key->key, now, &remove);

View File

@ -2476,7 +2476,7 @@ dst_key_is_active(dst_key_t *key, isc_stdtime_t now)
bool 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; dst_key_state_t state;
isc_result_t result; 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 * If the RRSIG state is RUMOURED or OMNIPRESENT, it means the key
* is active. * is active.
*/ */
if (ksk) { if (ksk && role == DST_BOOL_KSK) {
result = dst_key_getstate(key, DST_KEY_KRRSIG, &state); result = dst_key_getstate(key, DST_KEY_KRRSIG, &state);
if (result == ISC_R_SUCCESS) { if (result == ISC_R_SUCCESS) {
krrsig_ok = ((state == DST_KEY_STATE_RUMOURED) || 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; time_ok = true;
inactive = false; inactive = false;
} }
} } else if (zsk && role == DST_BOOL_ZSK) {
if (zsk) {
result = dst_key_getstate(key, DST_KEY_ZRRSIG, &state); result = dst_key_getstate(key, DST_KEY_ZRRSIG, &state);
if (result == ISC_R_SUCCESS) { if (result == ISC_R_SUCCESS) {
zrrsig_ok = ((state == DST_KEY_STATE_RUMOURED) || zrrsig_ok = ((state == DST_KEY_STATE_RUMOURED) ||

View File

@ -1138,9 +1138,10 @@ dst_key_is_active(dst_key_t *key, isc_stdtime_t now);
*/ */
bool 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: * Requires:
* 'key' to be valid. * 'key' to be valid.

View 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 * A dnssec-policy is found. Check what RRsets this
* key should sign. * key should sign.
*/ */
isc_stdtime_t when;
isc_result_t kresult; isc_result_t kresult;
bool ksk = false; bool ksk = false;
bool zsk = 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. * Other RRsets are signed with ZSK.
*/ */
continue; continue;
} else if (zsk && !dst_key_is_signing(keys[i],
DST_BOOL_ZSK,
inception,
&when)) {
/*
* This key is not active for zone-signing.
*/
continue;
} }
/* /*

View File

@ -6616,6 +6616,7 @@ add_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
* key should sign. * key should sign.
*/ */
isc_result_t kresult; isc_result_t kresult;
isc_stdtime_t when;
bool ksk = false; bool ksk = false;
bool zsk = 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. * Other RRsets are signed with ZSK.
*/ */
continue; 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) { if (kasp) {
dns_kasp_key_t* kkey; dns_kasp_key_t* kkey;
int ksk_count = 0, zsk_count = 0; int zsk_count = 0;
bool approved = false; bool approved;
for (kkey = ISC_LIST_HEAD(kasp->keys); kkey != NULL; for (kkey = ISC_LIST_HEAD(kasp->keys); kkey != NULL;
kkey = ISC_LIST_NEXT(kkey, link)) 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)) { if (dns_kasp_key_algorithm(kkey) != dst_key_alg(key)) {
continue; continue;
} }
if (dns_kasp_key_ksk(kkey)) {
ksk_count++;
}
if (dns_kasp_key_zsk(kkey)) { if (dns_kasp_key_zsk(kkey)) {
zsk_count++; 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, * be signed with a key in the current DS RRset,
* which would only include KSK's.) * which would only include KSK's.)
*/ */
approved = (ksk_count == count); approved = false;
} else { } else {
approved = (zsk_count == count); 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) dns_diff_t *diff, int32_t *signatures, isc_mem_t *mctx)
{ {
isc_result_t result; isc_result_t result;
dns_kasp_t *kasp = dns_zone_getkasp(zone);
dns_rdatasetiter_t *iterator = NULL; dns_rdatasetiter_t *iterator = NULL;
dns_rdataset_t rdataset; dns_rdataset_t rdataset;
dns_rdata_t rdata = DNS_RDATA_INIT; 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); result = dns_rdatasetiter_first(iterator);
while (result == ISC_R_SUCCESS) { while (result == ISC_R_SUCCESS) {
isc_stdtime_t when;
dns_rdatasetiter_current(iterator, &rdataset); dns_rdatasetiter_current(iterator, &rdataset);
if (rdataset.type == dns_rdatatype_soa || if (rdataset.type == dns_rdatatype_soa ||
rdataset.type == dns_rdatatype_rrsig) 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) { } else if (!is_zsk) {
goto next_rdataset; 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 && if (seen_ns && !seen_soa &&
rdataset.type != dns_rdatatype_ds && rdataset.type != dns_rdatatype_ds &&
rdataset.type != dns_rdatatype_nsec) rdataset.type != dns_rdatatype_nsec)