diff --git a/lib/dns/dnssec.c b/lib/dns/dnssec.c index 81c541fee7..54bbd1fd6a 100644 --- a/lib/dns/dnssec.c +++ b/lib/dns/dnssec.c @@ -2010,24 +2010,50 @@ dns_dnssec_syncupdate(dns_dnsseckeylist_t *keys, dns_dnsseckeylist_t *rmkeys, } } - if (dns_rdataset_isassociated(cds) && syncdelete(key->key, now)) - { - /* Delete both SHA-1 and SHA-256 */ - if (exists(cds, &cds_sha1)) { - RETERR(delrdata(&cds_sha1, diff, origin, - cds->ttl, mctx)); - } - if (exists(cds, &cds_sha256)) { - RETERR(delrdata(&cds_sha256, diff, origin, - cds->ttl, mctx)); - } - } + if (syncdelete(key->key, now)) { + char keystr[DST_KEY_FORMATSIZE]; + dst_key_format(key->key, keystr, sizeof(keystr)); - if (dns_rdataset_isassociated(cdnskey) && - syncdelete(key->key, now)) { - if (exists(cdnskey, &cdnskeyrdata)) { - RETERR(delrdata(&cdnskeyrdata, diff, origin, - cdnskey->ttl, mctx)); + if (dns_rdataset_isassociated(cds)) { + /* Delete both SHA-1 and SHA-256 */ + if (exists(cds, &cds_sha1)) { + isc_log_write(dns_lctx, + DNS_LOGCATEGORY_GENERAL, + DNS_LOGMODULE_DNSSEC, + ISC_LOG_INFO, + "CDS (SHA-1) for key %s " + "is now deleted", + keystr); + RETERR(delrdata(&cds_sha1, diff, origin, + cds->ttl, mctx)); + } + if (exists(cds, &cds_sha256)) { + isc_log_write(dns_lctx, + DNS_LOGCATEGORY_GENERAL, + DNS_LOGMODULE_DNSSEC, + ISC_LOG_INFO, + "CDS (SHA-256) for key " + "%s is now deleted", + keystr); + RETERR(delrdata(&cds_sha256, diff, + origin, cds->ttl, + mctx)); + } + } + + if (dns_rdataset_isassociated(cdnskey)) { + if (exists(cdnskey, &cdnskeyrdata)) { + isc_log_write(dns_lctx, + DNS_LOGCATEGORY_GENERAL, + DNS_LOGMODULE_DNSSEC, + ISC_LOG_INFO, + "CDNSKEY for key %s is " + "now deleted", + keystr); + RETERR(delrdata(&cdnskeyrdata, diff, + origin, cdnskey->ttl, + mctx)); + } } } } @@ -2047,6 +2073,9 @@ dns_dnssec_syncupdate(dns_dnsseckeylist_t *keys, dns_dnsseckeylist_t *rmkeys, dns_rdata_t cdnskeyrdata = DNS_RDATA_INIT; dns_name_t *origin = dst_key_name(key->key); + char keystr[DST_KEY_FORMATSIZE]; + dst_key_format(key->key, keystr, sizeof(keystr)); + RETERR(make_dnskey(key->key, keybuf, sizeof(keybuf), &cdnskeyrdata)); @@ -2058,10 +2087,21 @@ dns_dnssec_syncupdate(dns_dnsseckeylist_t *keys, dns_dnsseckeylist_t *rmkeys, DNS_DSDIGEST_SHA256, dsbuf2, &cds_sha256)); if (exists(cds, &cds_sha1)) { + isc_log_write( + dns_lctx, DNS_LOGCATEGORY_GENERAL, + DNS_LOGMODULE_DNSSEC, ISC_LOG_INFO, + "CDS (SHA-1) for key %s is now deleted", + keystr); RETERR(delrdata(&cds_sha1, diff, origin, cds->ttl, mctx)); } if (exists(cds, &cds_sha256)) { + isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, + DNS_LOGMODULE_DNSSEC, + ISC_LOG_INFO, + "CDS (SHA-256) for key %s is now " + "deleted", + keystr); RETERR(delrdata(&cds_sha256, diff, origin, cds->ttl, mctx)); } @@ -2069,6 +2109,11 @@ dns_dnssec_syncupdate(dns_dnsseckeylist_t *keys, dns_dnsseckeylist_t *rmkeys, if (dns_rdataset_isassociated(cdnskey)) { if (exists(cdnskey, &cdnskeyrdata)) { + isc_log_write( + dns_lctx, DNS_LOGCATEGORY_GENERAL, + DNS_LOGMODULE_DNSSEC, ISC_LOG_INFO, + "CDNSKEY for key %s is now deleted", + keystr); RETERR(delrdata(&cdnskeyrdata, diff, origin, cdnskey->ttl, mctx)); } @@ -2081,6 +2126,81 @@ failure: return (result); } +isc_result_t +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) { + 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_rdata_t cds_delete = DNS_RDATA_INIT; + dns_rdata_t cdnskey_delete = DNS_RDATA_INIT; + isc_region_t r; + isc_result_t result; + + r.base = keybuf; + r.length = sizeof(keybuf); + dns_rdata_fromregion(&cdnskey_delete, zclass, dns_rdatatype_cdnskey, + &r); + + r.base = dsbuf; + r.length = sizeof(dsbuf); + dns_rdata_fromregion(&cds_delete, zclass, dns_rdatatype_cds, &r); + + dns_name_format(origin, namebuf, sizeof(namebuf)); + + if (dnssec_insecure) { + if (!dns_rdataset_isassociated(cdnskey) || + !exists(cdnskey, &cdnskey_delete)) { + isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, + DNS_LOGMODULE_DNSSEC, ISC_LOG_INFO, + "CDNSKEY (DELETE) for zone %s is now " + "published", + namebuf); + RETERR(addrdata(&cdnskey_delete, diff, origin, 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 " + "published", + namebuf); + RETERR(addrdata(&cds_delete, diff, origin, ttl, mctx)); + } + } else { + if (dns_rdataset_isassociated(cdnskey) && + exists(cdnskey, &cdnskey_delete)) { + isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, + DNS_LOGMODULE_DNSSEC, ISC_LOG_INFO, + "CDNSKEY (DELETE) for zone %s is now " + "deleted", + namebuf); + 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; + +failure: + return (result); +} + /* * Update 'keys' with information from 'newkeys'. * diff --git a/lib/dns/include/dns/dnssec.h b/lib/dns/include/dns/dnssec.h index 6e951c7267..c51b2c9aad 100644 --- a/lib/dns/include/dns/dnssec.h +++ b/lib/dns/include/dns/dnssec.h @@ -357,6 +357,25 @@ dns_dnssec_syncupdate(dns_dnsseckeylist_t *keys, dns_dnsseckeylist_t *rmkeys, isc_mem_t *mctx); /*%< * Update the CDS and CDNSKEY RRsets, adding and removing keys as needed. + * + * Returns: + *\li ISC_R_SUCCESS + *\li Other values indicate error + */ + +isc_result_t +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); +/*%< + * 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). + * + * Returns: + *\li ISC_R_SUCCESS + *\li Other values indicate error */ isc_result_t diff --git a/lib/dns/win32/libdns.def.in b/lib/dns/win32/libdns.def.in index cb9919f483..443b2f97df 100644 --- a/lib/dns/win32/libdns.def.in +++ b/lib/dns/win32/libdns.def.in @@ -344,7 +344,7 @@ dns_dnssec_selfsigns dns_dnssec_sign dns_dnssec_signmessage dns_dnssec_signs -dns_dnssec_syncupdate +dns_dnssec_syncdelete dns_dnssec_syncupdate dns_dnssec_updatekeys dns_dnssec_verify diff --git a/lib/dns/zone.c b/lib/dns/zone.c index 0df09eb67a..002ca46b70 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -19912,6 +19912,17 @@ zone_rekey(dns_zone_t *zone) { goto failure; } + result = dns_dnssec_syncdelete(&cdsset, &cdnskeyset, + &zone->origin, zone->rdclass, + ttl, &diff, mctx, insecure); + if (result != ISC_R_SUCCESS) { + dnssec_log(zone, ISC_LOG_ERROR, + "zone_rekey:couldn't update CDS/CDNSKEY " + "DELETE records: %s", + isc_result_totext(result)); + goto failure; + } + /* * See if any pre-existing keys have newly become active; * also, see if any new key is for a new algorithm, as in that