*/
static bool
delsig_ok(dns_rdata_rrsig_t *rrsig_ptr, dst_key_t **keys, unsigned int nkeys,
- bool *warn) {
+ bool kasp, bool *warn) {
unsigned int i = 0;
isc_result_t ret;
bool have_ksk = false, have_zsk = false;
*warn = true;
}
+ if (have_pksk && have_pzsk) {
+ return (true);
+ }
+
/*
- * It's okay to delete a signature if there is an active key
- * with the same algorithm to replace it.
+ * Deleting the SOA RRSIG is always okay.
*/
- if (have_pksk || have_pzsk) {
+ if (rrsig_ptr->covered == dns_rdatatype_soa) {
return (true);
}
+ /*
+ * It's okay to delete a signature if there is an active key with the
+ * same algorithm to replace it, unless that violates the DNSSEC
+ * policy.
+ */
+ if (have_pksk || have_pzsk) {
+ if (kasp && have_pzsk) {
+ return (true);
+ }
+ return (!kasp);
+ }
+
/*
* Failing that, it is *not* okay to delete a signature
* if the associated public key is still in the DNSKEY RRset
dns_rdataset_t rdataset;
unsigned int i;
dns_rdata_rrsig_t rrsig;
+ bool kasp = (dns_zone_getkasp(zone) != NULL);
bool found;
int64_t timewarn = 0, timemaybe = 0;
type != dns_rdatatype_cdnskey)
{
bool warn = false, deleted = false;
- if (delsig_ok(&rrsig, keys, nkeys, &warn)) {
+ if (delsig_ok(&rrsig, keys, nkeys, kasp, &warn)) {
result = update_one_rr(db, ver, zonediff->diff,
DNS_DIFFOP_DELRESIGN,
name, rdataset.ttl,
isc_stdtime_t when;
bool ksk = false;
bool zsk = false;
+ bool have_ksk = false;
+ bool have_zsk = false;
kresult = dst_key_getbool(keys[i], DST_BOOL_KSK, &ksk);
if (kresult != ISC_R_SUCCESS) {
}
}
+ have_ksk = ksk;
+ have_zsk = zsk;
+ both = have_ksk && have_zsk;
+
+ for (j = 0; j < nkeys; j++) {
+ if (both) {
+ break;
+ }
+
+ if (j == i || ALG(keys[i]) != ALG(keys[j])) {
+ continue;
+ }
+
+ /*
+ * Don't consider inactive keys or offline keys.
+ */
+ if (!dst_key_isprivate(keys[j])) {
+ continue;
+ }
+ if (dst_key_inactive(keys[j])) {
+ continue;
+ }
+
+ if (REVOKE(keys[j])) {
+ continue;
+ }
+
+ if (!have_ksk) {
+ kresult = dst_key_getbool(keys[j],
+ DST_BOOL_KSK,
+ &have_ksk);
+ if (kresult != ISC_R_SUCCESS) {
+ if (KSK(keys[j])) {
+ have_ksk = true;
+ }
+ }
+ }
+ if (!have_zsk) {
+ kresult = dst_key_getbool(keys[j],
+ DST_BOOL_ZSK,
+ &have_zsk);
+ if (kresult != ISC_R_SUCCESS) {
+ if (!KSK(keys[j])) {
+ have_zsk = true;
+ }
+ }
+ }
+ both = have_ksk && have_zsk;
+ }
+
if (type == dns_rdatatype_dnskey ||
type == dns_rdatatype_cdnskey ||
type == dns_rdatatype_cds)
/*
* Other RRsets are signed with ZSK.
*/
- continue;
+ if (type != dns_rdatatype_soa &&
+ type != zone->privatetype) {
+ continue;
+ }
+ if (have_zsk) {
+ continue;
+ }
} else if (!dst_key_is_signing(keys[i], DST_BOOL_ZSK,
inception, &when)) {
/*