From: Matthijs Mekking Date: Wed, 17 Mar 2021 09:04:00 +0000 (+0100) Subject: Delete CDS/CDNSKEY records when zone is unsigned X-Git-Tag: v9.17.12~27^2~1 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=6f31f62d69e7516722f1b6cf0c1ba32421be3246;p=thirdparty%2Fbind9.git Delete CDS/CDNSKEY records when zone is unsigned CDS/CDNSKEY DELETE records are only useful if they are signed, otherwise the parent cannot verify these RRsets anyway. So once the DS has been removed (and signaled to BIND), we can remove the DNSKEY and RRSIG records, and at this point we can also remove the CDS/CDNSKEY records. --- diff --git a/bin/tests/system/kasp/tests.sh b/bin/tests/system/kasp/tests.sh index 43343e18796..05025e5af25 100644 --- a/bin/tests/system/kasp/tests.sh +++ b/bin/tests/system/kasp/tests.sh @@ -3623,8 +3623,6 @@ check_next_key_event 93600 set_zone "step2.going-insecure.kasp" set_policy "none" "2" "7200" set_server "ns6" "10.53.0.6" -# Expect a CDS/CDNSKEY Delete Record. -set_cdsdelete # The DS is long enough removed from the zone to be considered HIDDEN. # This means the DNSKEY and the KSK signatures can be removed. @@ -3693,8 +3691,6 @@ set_zone "step2.going-insecure-dynamic.kasp" set_dynamic set_policy "none" "2" "7200" set_server "ns6" "10.53.0.6" -# Expect a CDS/CDNSKEY Delete Record. -set_cdsdelete # The DS is long enough removed from the zone to be considered HIDDEN. # This means the DNSKEY and the KSK signatures can be removed. diff --git a/lib/dns/zone.c b/lib/dns/zone.c index 6083b058e6b..4f98f38a6a8 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -20123,7 +20123,12 @@ zone_rekey(dns_zone_t *zone) { } if (result == ISC_R_SUCCESS) { - bool insecure = dns_zone_secure_to_insecure(zone, false); + /* + * Publish CDS/CDNSKEY DELETE records if the zone is + * transitioning from secure to insecure. + */ + bool cds_delete = dns_zone_secure_to_insecure(zone, false); + isc_stdtime_t when; /* * Only update DNSKEY TTL if we have a policy. @@ -20160,9 +20165,36 @@ zone_rekey(dns_zone_t *zone) { goto failure; } + if (cds_delete) { + /* + * Only publish CDS/CDNSKEY DELETE records if there is + * a KSK that can be used to verify the RRset. This + * means there must be a key with the KSK role that is + * published and is used for signing. + */ + cds_delete = false; + for (key = ISC_LIST_HEAD(dnskeys); key != NULL; + key = ISC_LIST_NEXT(key, link)) { + dst_key_t *dstk = key->key; + bool ksk = false; + (void)dst_key_getbool(dstk, DST_BOOL_KSK, &ksk); + if (!ksk) { + continue; + } + + if (dst_key_haskasp(dstk) && + dst_key_is_published(dstk, now, &when) && + dst_key_is_signing(dstk, DST_BOOL_KSK, now, + &when)) + { + cds_delete = true; + break; + } + } + } result = dns_dnssec_syncdelete(&cdsset, &cdnskeyset, &zone->origin, zone->rdclass, - ttl, &diff, mctx, insecure); + ttl, &diff, mctx, cds_delete); if (result != ISC_R_SUCCESS) { dnssec_log(zone, ISC_LOG_ERROR, "zone_rekey:couldn't update CDS/CDNSKEY "