diff --git a/lib/dns/dnssec.c b/lib/dns/dnssec.c index ac70dc9703..388689144b 100644 --- a/lib/dns/dnssec.c +++ b/lib/dns/dnssec.c @@ -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); diff --git a/lib/dns/dst_api.c b/lib/dns/dst_api.c index d8d8869e4a..cfa4bbcda6 100644 --- a/lib/dns/dst_api.c +++ b/lib/dns/dst_api.c @@ -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) || diff --git a/lib/dns/include/dst/dst.h b/lib/dns/include/dst/dst.h index a37725f404..febadabae7 100644 --- a/lib/dns/include/dst/dst.h +++ b/lib/dns/include/dst/dst.h @@ -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. diff --git a/lib/dns/update.c b/lib/dns/update.c index 4c621c404f..9bd5896796 100644 --- a/lib/dns/update.c +++ b/lib/dns/update.c @@ -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; } /* diff --git a/lib/dns/zone.c b/lib/dns/zone.c index c88c1714ac..85832daef5 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -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)