From d78df5f96d973ac7704261b928a0e545cf4544d5 Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Fri, 15 Dec 2023 16:07:46 +1100 Subject: [PATCH 1/5] Don't delete the NSEC3PARAM immediately Wait until the new NSEC or NSEC3 chain is generated then it should be deleted. (cherry picked from commit f3ae88d84ec839d93fbc7f1dbc7ac8b80d349872) --- lib/dns/nsec3.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/lib/dns/nsec3.c b/lib/dns/nsec3.c index 2563c3e98c..5785cc1b50 100644 --- a/lib/dns/nsec3.c +++ b/lib/dns/nsec3.c @@ -1138,12 +1138,6 @@ dns_nsec3param_deletechains(dns_db_t *db, dns_dbversion_t *ver, dns_rdata_t private = DNS_RDATA_INIT; dns_rdataset_current(&rdataset, &rdata); - - CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL, origin, - rdataset.ttl, &rdata, &tuple)); - CHECK(do_one_tuple(&tuple, db, ver, diff)); - INSIST(tuple == NULL); - dns_nsec3param_toprivate(&rdata, &private, privatetype, buf, sizeof(buf)); buf[2] = DNS_NSEC3FLAG_REMOVE; From 7e24befc2ab89923b76aa68dcadc2108d4a2d12d Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Mon, 18 Dec 2023 11:23:21 +1100 Subject: [PATCH 2/5] Regression check for NSEC3 to NSEC conversion When transitioning from NSEC3 to NSEC the NSEC3 must be built before the NSEC3PARAM is removed. Check each delta in the conversion to ensure this ordering is met. (cherry picked from commit 7d90c056b039cc943413d82e4c9c748b45c60893) --- bin/tests/system/autosign/tests.sh | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/bin/tests/system/autosign/tests.sh b/bin/tests/system/autosign/tests.sh index fb50de4a98..a6283d5054 100755 --- a/bin/tests/system/autosign/tests.sh +++ b/bin/tests/system/autosign/tests.sh @@ -1806,5 +1806,18 @@ n=$((n + 1)) if [ "$ret" -ne 0 ]; then echo_i "failed"; fi status=$((status + ret)) +echo_i "check that NSEC3 to NSEC builds the NSEC chain first ($n)" +ret=0 +$JOURNALPRINT ns3/nsec3-to-nsec.example.db.jnl \ + | awk 'BEGIN { nsec3param=0; nsec=0 } +$1 == "del" && $5 == "SOA" { if (nsec3param || nsec) { if (nsec3param && !nsec) { exit(1); } else { exit(0); } } } +$1 == "del" && $5 == "NSEC3PARAM" { nsec3param=1 } +$1 == "add" && $2 == "nsec3-to-nsec.example." && $5 == "NSEC" { nsec=1 } +END { if (nsec3param || nsec) { if (nsec3param && !nsec) { exit(1); } else { exit(0); } } else { exit(1); } } +' || ret=1 +n=$((n + 1)) +if [ "$ret" -ne 0 ]; then echo_i "failed"; fi +status=$((status + ret)) + echo_i "exit status: $status" [ $status -eq 0 ] || exit 1 From b9fc29cb95b2bc389515732e6c37d58a73c16c4c Mon Sep 17 00:00:00 2001 From: Matthijs Mekking Date: Tue, 19 Dec 2023 13:23:44 +0100 Subject: [PATCH 3/5] Regression check for NSEC3 to NSEC3 conversion When changing the NSEC3 chain, the new NSEC3 chain must be built before the old NSEC3PARAM is removed. Check each delta in the conversion to ensure this ordering is met. (cherry picked from commit 1d6b892e04e7d8841c778c40bce61c7ff2c1dccb) --- bin/tests/system/autosign/ns3/keygen.sh | 8 ++++++ bin/tests/system/autosign/ns3/named.conf.in | 8 ++++++ .../autosign/ns3/nsec3-to-nsec3.example.db.in | 26 +++++++++++++++++++ bin/tests/system/autosign/tests.sh | 20 +++++++++++++- 4 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 bin/tests/system/autosign/ns3/nsec3-to-nsec3.example.db.in diff --git a/bin/tests/system/autosign/ns3/keygen.sh b/bin/tests/system/autosign/ns3/keygen.sh index b863a08f53..b59cb509c4 100644 --- a/bin/tests/system/autosign/ns3/keygen.sh +++ b/bin/tests/system/autosign/ns3/keygen.sh @@ -192,6 +192,14 @@ $KEYGEN -q -a $DEFAULT_ALGORITHM -fk $zone >kg.out 2>&1 || dumpit kg.out $KEYGEN -q -a $DEFAULT_ALGORITHM $zone >kg.out 2>&1 || dumpit kg.out $SIGNER -S -3 beef -A -o $zone -f $zonefile $infile >s.out || dumpit s.out +# +# NSEC3->NSEC3 transition test zone. +# +setup nsec3-to-nsec3.example +$KEYGEN -q -a $DEFAULT_ALGORITHM -fk $zone >kg.out 2>&1 || dumpit kg.out +$KEYGEN -q -a $DEFAULT_ALGORITHM $zone >kg.out 2>&1 || dumpit kg.out +$SIGNER -S -3 beef -A -o $zone -f $zonefile $infile >s.out || dumpit s.out + # # secure-to-insecure transition test zone; used to test removal of # keys via nsupdate diff --git a/bin/tests/system/autosign/ns3/named.conf.in b/bin/tests/system/autosign/ns3/named.conf.in index 1f878e6737..cbdf8f7133 100644 --- a/bin/tests/system/autosign/ns3/named.conf.in +++ b/bin/tests/system/autosign/ns3/named.conf.in @@ -186,6 +186,14 @@ zone "secure-to-insecure2.example" { dnssec-secure-to-insecure yes; }; +zone "nsec3-to-nsec3.example" { + type primary; + file "nsec3-to-nsec3.example.db"; + allow-update { any; }; + inline-signing no; + max-journal-size 10M; +}; + zone "oldsigs.example" { type primary; file "oldsigs.example.db"; diff --git a/bin/tests/system/autosign/ns3/nsec3-to-nsec3.example.db.in b/bin/tests/system/autosign/ns3/nsec3-to-nsec3.example.db.in new file mode 100644 index 0000000000..0b11a00b00 --- /dev/null +++ b/bin/tests/system/autosign/ns3/nsec3-to-nsec3.example.db.in @@ -0,0 +1,26 @@ +; Copyright (C) Internet Systems Consortium, Inc. ("ISC") +; +; SPDX-License-Identifier: MPL-2.0 +; +; This Source Code Form is subject to the terms of the Mozilla Public +; License, v. 2.0. If a copy of the MPL was not distributed with this +; file, you can obtain one at https://mozilla.org/MPL/2.0/. +; +; See the COPYRIGHT file distributed with this work for additional +; information regarding copyright ownership. + +$TTL 300 ; 5 minutes +@ IN SOA mname1. . ( + 2009102722 ; serial + 20 ; refresh (20 seconds) + 20 ; retry (20 seconds) + 1814400 ; expire (3 weeks) + 3600 ; minimum (1 hour) + ) + NS ns +ns A 10.53.0.3 + +a A 10.0.0.1 +b A 10.0.0.2 +d A 10.0.0.4 +x CNAME a diff --git a/bin/tests/system/autosign/tests.sh b/bin/tests/system/autosign/tests.sh index a6283d5054..5789fe7352 100755 --- a/bin/tests/system/autosign/tests.sh +++ b/bin/tests/system/autosign/tests.sh @@ -177,6 +177,9 @@ status=$((status + ret)) echo_i "Convert optout-with-ent from nsec to nsec3" ($RNDCCMD 10.53.0.2 signing -nsec3param 1 1 1 - optout-with-ent 2>&1 | sed 's/^/ns2 /' | cat_i) || ret=1 +echo_i "Convert nsec3-to-nsec3.example from having salt 'beef' to no salt" +($RNDCCMD 10.53.0.3 signing -nsec3param 1 1 1 - nsec3-to-nsec3.example 2>&1 | sed 's/^/ns3 /' | cat_i) || ret=1 + echo_i "Initial counts of RRSIG expiry fields values for auto signed zones" for z in .; do echo_i zone $z @@ -1180,7 +1183,8 @@ checkprivate private.secure.example 10.53.0.3 2 || ret=1 # pre-signed checkprivate nsec3.example 10.53.0.3 || ret=1 checkprivate nsec3.nsec3.example 10.53.0.3 || ret=1 checkprivate nsec3.optout.example 10.53.0.3 || ret=1 -checkprivate nsec3-to-nsec.example 10.53.0.3 2 || ret=1 # automatically removed +checkprivate nsec3-to-nsec.example 10.53.0.3 2 || ret=1 # automatically removed +checkprivate nsec3-to-nsec3.example 10.53.0.3 2 || ret=1 # automatically removed if $SHELL ../testcrypto.sh -q RSASHA1; then checkprivate nsec-only.example 10.53.0.3 || ret=1 fi @@ -1819,5 +1823,19 @@ n=$((n + 1)) if [ "$ret" -ne 0 ]; then echo_i "failed"; fi status=$((status + ret)) +echo_i "check that NSEC3 to NSEC3 builds the new NSEC3 chain first ($n)" +ret=0 +$JOURNALPRINT ns3/nsec3-to-nsec3.example.db.jnl \ + | awk 'BEGIN { addnsec3param=0; delnsec3param=0; nsec3=0 } +$1 == "del" && $5 == "SOA" { if (delnsec3param || nsec3 || addnsec3param) { if (delnsec3param && (!nsec3 || !addnsec3param)) { exit(1); } else { exit(0); } } } +$1 == "del" && $5 == "NSEC3PARAM" { delnsec3param=1 } +$1 == "add" && $5 == "NSEC3PARAM" { addnsec3param=1 } +$1 == "add" && $5 == "NSEC3" { nsec3=1 } +END { if (delnsec3param || nsec3 || addnsec3param) { if (delnsec3param && (!nsec3 || !addnsec3param)) { exit(1); } else { exit(0); } } else { exit(1); } } +' || ret=1 +n=$((n + 1)) +if [ "$ret" -ne 0 ]; then echo_i "failed"; fi +status=$((status + ret)) + echo_i "exit status: $status" [ $status -eq 0 ] || exit 1 From d5aa22ec7418014b91a2f7e97c00b964d4660108 Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Fri, 15 Dec 2023 19:37:20 +1100 Subject: [PATCH 4/5] Add CHANGES for [GL #1794] and [GL #4459] (cherry picked from commit 9b5ed853d07717b59f749f1a9445a02e0f4f5419) --- CHANGES | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGES b/CHANGES index f64ea009b5..86ff535f29 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,11 @@ +6312. [bug] Conversion from NSEC3 signed to NSEC signed could + temporarily put the zone into a state where it was + treated as unsigned until the NSEC chain was built. + Additionally conversion from one set of NSEC3 parameters + to another could also temporarily put the zone into a + state where it was treated as unsigned until the new + NSEC3 chain was built. [GL #1794] [GL #4495] + 6310. [bug] Memory leak in zone.c:sign_zone. When named signed a zone it could leak dst_keys due to a misplaced 'continue'. [GL #4488] From 1a52dccd323ece352da073ae01c8ede62c852b17 Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Fri, 22 Dec 2023 11:55:39 +1100 Subject: [PATCH 5/5] Handle multiple NSEC3PARAM records in tests When transitioning from one NSEC3 chain to another it is legal for there to be multiple complete chains in the zone with multiple NSEC3PARAM records. Handle this intermediate state by checking for the expected length in the loop. --- bin/tests/system/dnssec/tests.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/tests/system/dnssec/tests.sh b/bin/tests/system/dnssec/tests.sh index 6a295b5a23..bdaac667e0 100644 --- a/bin/tests/system/dnssec/tests.sh +++ b/bin/tests/system/dnssec/tests.sh @@ -2720,7 +2720,7 @@ rndccmd 10.53.0.3 signing -nsec3param 1 0 0 auto inline.example >/dev/null 2>&1 rndccmd 10.53.0.3 status >/dev/null || ret=1 for i in 1 2 3 4 5 6 7 8 9 10; do salt=$(dig_with_opts +nodnssec +short nsec3param inline.example. @10.53.0.3 | awk '{print $4}') - [ -n "$salt" ] && [ "$salt" != "-" ] && break + [ "$salt" != "-" ] && [ "${#salt}" -eq 16 ] && break echo_i "sleeping ...." sleep 1 done @@ -2737,7 +2737,7 @@ rndccmd 10.53.0.3 signing -nsec3param 1 0 0 auto inline.example >/dev/null 2>&1 rndccmd 10.53.0.3 status >/dev/null || ret=1 for i in 1 2 3 4 5 6 7 8 9 10; do salt=$(dig_with_opts +nodnssec +short nsec3param inline.example. @10.53.0.3 | awk '{print $4}') - [ -n "$salt" ] && [ "$salt" != "$oldsalt" ] && break + [ "$salt" != "$oldsalt" ] && [ "${#salt}" -eq 16 ] && break echo_i "sleeping ...." sleep 1 done