dns_dnssec_syncdelete(dns_rdataset_t *cds, dns_rdataset_t *cdnskey,
dns_name_t *origin, dns_rdataclass_t zclass,
dns_ttl_t ttl, dns_diff_t *diff, isc_mem_t *mctx,
- bool dnssec_insecure) {
+ bool expect_cds_delete, bool expect_cdnskey_delete) {
unsigned char dsbuf[5] = { 0, 0, 0, 0, 0 }; /* CDS DELETE rdata */
unsigned char keybuf[5] = { 0, 0, 3, 0, 0 }; /* CDNSKEY DELETE rdata */
char namebuf[DNS_NAME_FORMATSIZE];
dns_name_format(origin, namebuf, sizeof(namebuf));
- if (dnssec_insecure) {
- if (!dns_rdataset_isassociated(cdnskey) ||
- !exists(cdnskey, &cdnskey_delete)) {
+ if (expect_cds_delete) {
+ if (!dns_rdataset_isassociated(cds) ||
+ !exists(cds, &cds_delete)) {
isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
DNS_LOGMODULE_DNSSEC, ISC_LOG_INFO,
- "CDNSKEY (DELETE) for zone %s is now "
+ "CDS (DELETE) for zone %s is now "
"published",
namebuf);
- RETERR(addrdata(&cdnskey_delete, diff, origin, ttl,
+ RETERR(addrdata(&cds_delete, diff, origin, ttl, mctx));
+ }
+ } else {
+ if (dns_rdataset_isassociated(cds) && exists(cds, &cds_delete))
+ {
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
+ DNS_LOGMODULE_DNSSEC, ISC_LOG_INFO,
+ "CDS (DELETE) for zone %s is now "
+ "deleted",
+ namebuf);
+ RETERR(delrdata(&cds_delete, diff, origin, cds->ttl,
mctx));
}
+ }
- if (!dns_rdataset_isassociated(cds) ||
- !exists(cds, &cds_delete)) {
+ if (expect_cdnskey_delete) {
+ if (!dns_rdataset_isassociated(cdnskey) ||
+ !exists(cdnskey, &cdnskey_delete)) {
isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
DNS_LOGMODULE_DNSSEC, ISC_LOG_INFO,
- "CDS (DELETE) for zone %s is now "
+ "CDNSKEY (DELETE) for zone %s is now "
"published",
namebuf);
- RETERR(addrdata(&cds_delete, diff, origin, ttl, mctx));
+ RETERR(addrdata(&cdnskey_delete, diff, origin, ttl,
+ mctx));
}
} else {
if (dns_rdataset_isassociated(cdnskey) &&
RETERR(delrdata(&cdnskey_delete, diff, origin,
cdnskey->ttl, mctx));
}
-
- if (dns_rdataset_isassociated(cds) && exists(cds, &cds_delete))
- {
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
- DNS_LOGMODULE_DNSSEC, ISC_LOG_INFO,
- "CDS (DELETE) for zone %s is now "
- "deleted",
- namebuf);
- RETERR(delrdata(&cds_delete, diff, origin, cds->ttl,
- mctx));
- }
}
result = ISC_R_SUCCESS;
dns_dnssec_syncdelete(dns_rdataset_t *cds, dns_rdataset_t *cdnskey,
dns_name_t *origin, dns_rdataclass_t zclass,
dns_ttl_t ttl, dns_diff_t *diff, isc_mem_t *mctx,
- bool dnssec_insecure);
+ bool expect_cds_delete, bool expect_cdnskey_delete);
/*%<
* Add or remove the CDS DELETE record and the CDNSKEY DELETE record.
- * If 'dnssec_insecure' is true, the DELETE records should be present.
- * Otherwise, the DELETE records must be removed from the RRsets (if present).
+ * If 'expect_cds_delete' is true, the CDS DELETE record should be present.
+ * Otherwise, the CDS DELETE record must be removed from the RRsets (if
+ * present). If 'expect_cdnskey_delete' is true, the CDNSKEY DELETE record
+ * should be present. Otherwise, the CDNSKEY DELETE record must be removed
+ * from the RRsets (if present).
*
* Returns:
*\li ISC_R_SUCCESS
KASP_UNLOCK(kasp);
if (result == ISC_R_SUCCESS) {
- bool cds_delete = false;
+ bool cdsdel = false;
+ bool cdnskeydel = false;
isc_stdtime_t when;
/*
* Publish CDS/CDNSKEY DELETE records if the zone is
* transitioning from secure to insecure.
*/
- if (kasp != NULL &&
- strcmp(dns_kasp_getname(kasp), "insecure") == 0) {
- cds_delete = true;
+ if (kasp != NULL) {
+ if (strcmp(dns_kasp_getname(kasp), "insecure") == 0) {
+ cdsdel = true;
+ cdnskeydel = true;
+ }
+ } else {
+ /* Check if there is a CDS DELETE record. */
+ if (dns_rdataset_isassociated(&cdsset)) {
+ for (result = dns_rdataset_first(&cdsset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(&cdsset))
+ {
+ dns_rdata_t crdata = DNS_RDATA_INIT;
+ dns_rdataset_current(&cdsset, &crdata);
+ /*
+ * CDS deletion record has this form
+ * "0 0 0 00" which is 5 zero octets.
+ */
+ if (crdata.length == 5U &&
+ memcmp(crdata.data,
+ (unsigned char[5]){ 0, 0, 0,
+ 0, 0 },
+ 5) == 0)
+ {
+ cdsdel = true;
+ break;
+ }
+ }
+ }
+
+ /* Check if there is a CDNSKEY DELETE record. */
+ if (dns_rdataset_isassociated(&cdnskeyset)) {
+ for (result = dns_rdataset_first(&cdnskeyset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(&cdnskeyset))
+ {
+ dns_rdata_t crdata = DNS_RDATA_INIT;
+ dns_rdataset_current(&cdnskeyset,
+ &crdata);
+ /*
+ * CDNSKEY deletion record has this form
+ * "0 3 0 AA==" which is 2 zero octets,
+ * a 3, and 2 zero octets.
+ */
+ if (crdata.length == 5U &&
+ memcmp(crdata.data,
+ (unsigned char[5]){ 0, 0, 3,
+ 0, 0 },
+ 5) == 0)
+ {
+ cdnskeydel = true;
+ break;
+ }
+ }
+ }
}
/*
goto failure;
}
- if (cds_delete) {
+ if (cdsdel || cdnskeydel) {
/*
* 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;
+ bool allow = 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) &&
+ if (dst_key_is_published(dstk, now, &when) &&
dst_key_is_signing(dstk, DST_BOOL_KSK, now,
&when))
{
- cds_delete = true;
+ allow = true;
break;
}
}
+ if (cdsdel) {
+ cdsdel = allow;
+ }
+ if (cdnskeydel) {
+ cdnskeydel = allow;
+ }
}
- result = dns_dnssec_syncdelete(&cdsset, &cdnskeyset,
- &zone->origin, zone->rdclass,
- ttl, &diff, mctx, cds_delete);
+ result = dns_dnssec_syncdelete(
+ &cdsset, &cdnskeyset, &zone->origin, zone->rdclass, ttl,
+ &diff, mctx, cdsdel, cdnskeydel);
if (result != ISC_R_SUCCESS) {
dnssec_log(zone, ISC_LOG_ERROR,
"zone_rekey:couldn't update CDS/CDNSKEY "