Commit 298372d8 authored by Mark Andrews's avatar Mark Andrews

only sign with other keys when deleting a key if there are not already...

only sign with other keys when deleting a key if there are not already existing signature for the deleted algorithm

(cherry picked from commit 0667bf7a)
(cherry picked from commit c1e342ce)
parent 5ab633d5
...@@ -812,7 +812,8 @@ static void zone_maintenance(dns_zone_t *zone); ...@@ -812,7 +812,8 @@ static void zone_maintenance(dns_zone_t *zone);
static void zone_notify(dns_zone_t *zone, isc_time_t *now); static void zone_notify(dns_zone_t *zone, isc_time_t *now);
static void dump_done(void *arg, isc_result_t result); static void dump_done(void *arg, isc_result_t result);
static isc_result_t zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, static isc_result_t zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm,
isc_uint16_t keyid, isc_boolean_t deleteit); isc_uint16_t keyid,
isc_boolean_t deleteit);
static isc_result_t delete_nsec(dns_db_t *db, dns_dbversion_t *ver, static isc_result_t delete_nsec(dns_db_t *db, dns_dbversion_t *ver,
dns_dbnode_t *node, dns_name_t *name, dns_dbnode_t *node, dns_name_t *name,
dns_diff_t *diff); dns_diff_t *diff);
...@@ -8187,15 +8188,26 @@ zone_nsec3chain(dns_zone_t *zone) { ...@@ -8187,15 +8188,26 @@ zone_nsec3chain(dns_zone_t *zone) {
INSIST(version == NULL); INSIST(version == NULL);
} }
/*%
* Delete all RRSIG records with the given algorithm and keyid.
* Remove the NSEC record and RRSIGs if nkeys is zero.
* If all remaining RRsets are signed with the given algorithm
* set *has_algp to ISC_TRUE.
*/
static isc_result_t static isc_result_t
del_sig(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, del_sig(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
dns_dbnode_t *node, unsigned int nkeys, dns_secalg_t algorithm, dns_dbnode_t *node, unsigned int nkeys, dns_secalg_t algorithm,
isc_uint16_t keyid, dns_diff_t *diff) isc_uint16_t keyid, isc_boolean_t *has_algp, dns_diff_t *diff)
{ {
dns_rdata_rrsig_t rrsig; dns_rdata_rrsig_t rrsig;
dns_rdataset_t rdataset; dns_rdataset_t rdataset;
dns_rdatasetiter_t *iterator = NULL; dns_rdatasetiter_t *iterator = NULL;
isc_result_t result; isc_result_t result;
isc_boolean_t alg_missed = ISC_FALSE;
isc_boolean_t alg_found = ISC_FALSE;
char namebuf[DNS_NAME_FORMATSIZE];
dns_name_format(name, namebuf, sizeof(namebuf));
result = dns_db_allrdatasets(db, node, version, 0, &iterator); result = dns_db_allrdatasets(db, node, version, 0, &iterator);
if (result != ISC_R_SUCCESS) { if (result != ISC_R_SUCCESS) {
...@@ -8208,6 +8220,7 @@ del_sig(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, ...@@ -8208,6 +8220,7 @@ del_sig(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
for (result = dns_rdatasetiter_first(iterator); for (result = dns_rdatasetiter_first(iterator);
result == ISC_R_SUCCESS; result == ISC_R_SUCCESS;
result = dns_rdatasetiter_next(iterator)) { result = dns_rdatasetiter_next(iterator)) {
isc_boolean_t has_alg = ISC_FALSE;
dns_rdatasetiter_current(iterator, &rdataset); dns_rdatasetiter_current(iterator, &rdataset);
if (nkeys == 0 && rdataset.type == dns_rdatatype_nsec) { if (nkeys == 0 && rdataset.type == dns_rdatatype_nsec) {
for (result = dns_rdataset_first(&rdataset); for (result = dns_rdataset_first(&rdataset);
...@@ -8230,13 +8243,20 @@ del_sig(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, ...@@ -8230,13 +8243,20 @@ del_sig(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
} }
for (result = dns_rdataset_first(&rdataset); for (result = dns_rdataset_first(&rdataset);
result == ISC_R_SUCCESS; result == ISC_R_SUCCESS;
result = dns_rdataset_next(&rdataset)) { result = dns_rdataset_next(&rdataset))
{
dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdata_t rdata = DNS_RDATA_INIT;
dns_rdataset_current(&rdataset, &rdata); dns_rdataset_current(&rdataset, &rdata);
CHECK(dns_rdata_tostruct(&rdata, &rrsig, NULL)); CHECK(dns_rdata_tostruct(&rdata, &rrsig, NULL));
if (rrsig.algorithm != algorithm || if (nkeys != 0 &&
rrsig.keyid != keyid) (rrsig.algorithm != algorithm ||
rrsig.keyid != keyid))
{
if (rrsig.algorithm == algorithm) {
has_alg = ISC_TRUE;
}
continue; continue;
}
CHECK(update_one_rr(db, version, diff, CHECK(update_one_rr(db, version, diff,
DNS_DIFFOP_DELRESIGN, name, DNS_DIFFOP_DELRESIGN, name,
rdataset.ttl, &rdata)); rdataset.ttl, &rdata));
...@@ -8244,9 +8264,25 @@ del_sig(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, ...@@ -8244,9 +8264,25 @@ del_sig(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
dns_rdataset_disassociate(&rdataset); dns_rdataset_disassociate(&rdataset);
if (result != ISC_R_NOMORE) if (result != ISC_R_NOMORE)
break; break;
/*
* After deleting, if there's still a signature for
* 'algorithm', set alg_found; if not, set alg_missed.
*/
if (has_alg) {
alg_found = ISC_TRUE;
} else {
alg_missed = ISC_TRUE;
}
} }
if (result == ISC_R_NOMORE) if (result == ISC_R_NOMORE)
result = ISC_R_SUCCESS; result = ISC_R_SUCCESS;
/*
* Set `has_algp` if the algorithm was found in every RRset:
* i.e., found in at least one, and not missing from any.
*/
*has_algp = ISC_TF(alg_found && !alg_missed);
failure: failure:
if (dns_rdataset_isassociated(&rdataset)) if (dns_rdataset_isassociated(&rdataset))
dns_rdataset_disassociate(&rdataset); dns_rdataset_disassociate(&rdataset);
...@@ -8276,6 +8312,7 @@ zone_sign(dns_zone_t *zone) { ...@@ -8276,6 +8312,7 @@ zone_sign(dns_zone_t *zone) {
dst_key_t *zone_keys[DNS_MAXZONEKEYS]; dst_key_t *zone_keys[DNS_MAXZONEKEYS];
isc_int32_t signatures; isc_int32_t signatures;
isc_boolean_t check_ksk, keyset_kskonly, is_ksk; isc_boolean_t check_ksk, keyset_kskonly, is_ksk;
isc_boolean_t with_ksk, with_zsk;
isc_boolean_t commit = ISC_FALSE; isc_boolean_t commit = ISC_FALSE;
isc_boolean_t delegation; isc_boolean_t delegation;
isc_boolean_t build_nsec = ISC_FALSE; isc_boolean_t build_nsec = ISC_FALSE;
...@@ -8367,6 +8404,7 @@ zone_sign(dns_zone_t *zone) { ...@@ -8367,6 +8404,7 @@ zone_sign(dns_zone_t *zone) {
build_nsec = ISC_TRUE; build_nsec = ISC_TRUE;
while (signing != NULL && nodes-- > 0 && signatures > 0) { while (signing != NULL && nodes-- > 0 && signatures > 0) {
isc_boolean_t has_alg = ISC_FALSE;
nextsigning = ISC_LIST_NEXT(signing, link); nextsigning = ISC_LIST_NEXT(signing, link);
ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
...@@ -8406,6 +8444,9 @@ zone_sign(dns_zone_t *zone) { ...@@ -8406,6 +8444,9 @@ zone_sign(dns_zone_t *zone) {
zone_keys[j] = zone_keys[i]; zone_keys[j] = zone_keys[i];
j++; j++;
} }
for (i = j; i < nkeys; i++) {
zone_keys[i] = NULL;
}
nkeys = j; nkeys = j;
} }
...@@ -8415,7 +8456,7 @@ zone_sign(dns_zone_t *zone) { ...@@ -8415,7 +8456,7 @@ zone_sign(dns_zone_t *zone) {
dns_dbiterator_pause(signing->dbiterator); dns_dbiterator_pause(signing->dbiterator);
CHECK(del_sig(db, version, name, node, nkeys, CHECK(del_sig(db, version, name, node, nkeys,
signing->algorithm, signing->keyid, signing->algorithm, signing->keyid,
zonediff.diff)); &has_alg, zonediff.diff));
} }
/* /*
...@@ -8446,8 +8487,10 @@ zone_sign(dns_zone_t *zone) { ...@@ -8446,8 +8487,10 @@ zone_sign(dns_zone_t *zone) {
/* /*
* Process one node. * Process one node.
*/ */
with_ksk = ISC_FALSE;
with_zsk = ISC_FALSE;
dns_dbiterator_pause(signing->dbiterator); dns_dbiterator_pause(signing->dbiterator);
for (i = 0; i < nkeys; i++) { for (i = 0; !has_alg && i < nkeys; i++) {
isc_boolean_t both = ISC_FALSE; isc_boolean_t both = ISC_FALSE;
/* /*
...@@ -8517,6 +8560,19 @@ zone_sign(dns_zone_t *zone) { ...@@ -8517,6 +8560,19 @@ zone_sign(dns_zone_t *zone) {
else else
is_ksk = ISC_FALSE; is_ksk = ISC_FALSE;
/*
* If deleting signatures, we need to ensure that
* the RRset is still signed at least once by a
* KSK and a ZSK.
*/
if (signing->deleteit && !is_ksk && with_zsk) {
continue;
}
if (signing->deleteit && is_ksk && with_ksk) {
continue;
}
CHECK(sign_a_node(db, name, node, version, build_nsec3, CHECK(sign_a_node(db, name, node, version, build_nsec3,
build_nsec, zone_keys[i], inception, build_nsec, zone_keys[i], inception,
expire, zone->minimum, is_ksk, expire, zone->minimum, is_ksk,
...@@ -8527,8 +8583,15 @@ zone_sign(dns_zone_t *zone) { ...@@ -8527,8 +8583,15 @@ zone_sign(dns_zone_t *zone) {
* If we are adding we are done. Look for other keys * If we are adding we are done. Look for other keys
* of the same algorithm if deleting. * of the same algorithm if deleting.
*/ */
if (!signing->deleteit) if (!signing->deleteit) {
break; break;
}
if (!is_ksk) {
with_zsk = ISC_TRUE;
}
if (KSK(zone_keys[i])) {
with_ksk = ISC_TRUE;
}
} }
/* /*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment