From 83dd0c85a2d95ffb136934cf6f57d65395b74e2a Mon Sep 17 00:00:00 2001 From: Matthijs Mekking Date: Tue, 27 Jun 2023 16:27:35 +0200 Subject: [PATCH 1/2] Check all keys despite early failure In the kasp script, if one expected key is not found, continue checking the other key ids, even if there is no match for the first one. This provides a bit more information which keys mismatch and makes for easier debugging test failures. (cherry picked from commit 674249f66a5c41d6742aebb2461ba0659c01eee7) --- bin/tests/system/kasp.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/bin/tests/system/kasp.sh b/bin/tests/system/kasp.sh index f0c83b19ab..d49baa3047 100644 --- a/bin/tests/system/kasp.sh +++ b/bin/tests/system/kasp.sh @@ -725,6 +725,7 @@ check_numkeys() { _check_keys() { ret=0 + _ret=0 # Clear key ids. key_set KEY1 ID "no" @@ -767,10 +768,10 @@ _check_keys() { # If ret is still non-zero, none of the files matched. echo_i "failed" - return 1 + _ret=1 done - return 0 + return $_ret } # Check keys for a configured zone. This verifies: From 80a20c9643b13d0211fe6f099c4648734f9e9980 Mon Sep 17 00:00:00 2001 From: Matthijs Mekking Date: Tue, 27 Jun 2023 16:29:50 +0200 Subject: [PATCH 2/2] Add test for "three is a crowd" bug (GL #2375) Add this test scenario for a bug fixed a while ago. When a third key is introduced while the previous rollover hasn't finished yet, the keymgr could decide to remove the first two keys, because it was not checking for an indirect dependency on the keys. In other words, the previous bug behavior was that the first two keys were removed from the zone too soon. This test case checks that all three keys stay in the zone, and no keys are removed premature after another new key has been introduced. (cherry picked from commit 9c40cf05667075990e13e78787c8a8f356e21793) --- bin/tests/system/kasp/ns3/named-fips.conf.in | 11 +++ bin/tests/system/kasp/ns3/setup.sh | 41 +++++++++++ bin/tests/system/kasp/tests.sh | 77 +++++++++++++++++++- 3 files changed, 126 insertions(+), 3 deletions(-) diff --git a/bin/tests/system/kasp/ns3/named-fips.conf.in b/bin/tests/system/kasp/ns3/named-fips.conf.in index 6199b0496b..b14b142eff 100644 --- a/bin/tests/system/kasp/ns3/named-fips.conf.in +++ b/bin/tests/system/kasp/ns3/named-fips.conf.in @@ -240,6 +240,17 @@ zone "max-zone-ttl.kasp" { dnssec-policy "ttl"; }; +/* + * Zone for testing GL #2375: Three is a crowd. + */ +zone "three-is-a-crowd.kasp" { + type primary; + file "three-is-a-crowd.kasp.db"; + inline-signing yes; + /* Use same policy as KSK rollover test zones. */ + dnssec-policy "ksk-doubleksk"; +}; + /* * Zones in different signing states. */ diff --git a/bin/tests/system/kasp/ns3/setup.sh b/bin/tests/system/kasp/ns3/setup.sh index 21e6356267..8682f54dcb 100644 --- a/bin/tests/system/kasp/ns3/setup.sh +++ b/bin/tests/system/kasp/ns3/setup.sh @@ -1427,3 +1427,44 @@ private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >> "$infile" private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >> "$infile" cp $infile $zonefile $SIGNER -S -z -x -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile > signer.out.$zone.1 2>&1 + +# Test #2375, the "three is a crowd" bug, where a new key is introduced but the +# previous rollover has not finished yet. In other words, we have a key KEY2 +# that is the successor of key KEY1, and we introduce a new key KEY3 that is +# the successor of key KEY2: +# +# KEY1 < KEY2 < KEY3. +# +# The expected behavior is that all three keys remain in the zone, and not +# the bug behavior where KEY2 is removed and immediately replaced with KEY3. +# +# Set up a zone that has a KSK (KEY1) and have the successor key (KEY2) +# published as well. +setup three-is-a-crowd.kasp +# These times are the same as step3.ksk-doubleksk.autosign. +TactN="now-60d" +TretN="now" +TremN="now+50h" +TpubN1="now-27h" +TsbmN1="now" +TactN1="${TretN}" +TretN1="now+60d" +TremN1="now+1490h" +ksktimes="-P ${TactN} -A ${TactN} -P sync ${TactN} -I ${TretN} -D ${TremN}" +newtimes="-P ${TpubN1} -A ${TactN1} -P sync ${TsbmN1} -I ${TretN1} -D ${TremN1}" +zsktimes="-P ${TactN} -A ${TactN}" +KSK1=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $ksktimes $zone 2> keygen.out.$zone.1) +KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $newtimes $zone 2> keygen.out.$zone.2) +ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 $zsktimes $zone 2> keygen.out.$zone.3) +$SETTIME -s -g $H -k $O $TactN -r $O $TactN -d $O $TactN "$KSK1" > settime.out.$zone.1 2>&1 +$SETTIME -s -g $O -k $R $TpubN1 -r $R $TpubN1 -d $H $TpubN1 "$KSK2" > settime.out.$zone.2 2>&1 +$SETTIME -s -g $O -k $O $TactN -z $O $TactN "$ZSK" > settime.out.$zone.3 2>&1 +# Set key rollover relationship. +key_successor $KSK1 $KSK2 +# Sign zone. +cat template.db.in "${KSK1}.key" "${KSK2}.key" "${ZSK}.key" > "$infile" +private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK1" >> "$infile" +private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >> "$infile" +private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >> "$infile" +cp $infile $zonefile +$SIGNER -S -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile > signer.out.$zone.1 2>&1 diff --git a/bin/tests/system/kasp/tests.sh b/bin/tests/system/kasp/tests.sh index fbb8bdc215..4d3bda7737 100644 --- a/bin/tests/system/kasp/tests.sh +++ b/bin/tests/system/kasp/tests.sh @@ -3545,10 +3545,81 @@ dnssec_verify # # Test #2375: Scheduled rollovers are happening faster than they can finish # -set_zone "step1.three-is-a-crowd.kasp" -set_policy "default" "1" "3600" +set_zone "three-is-a-crowd.kasp" +set_policy "ksk-doubleksk" "3" "7200" set_server "ns3" "10.53.0.3" -# TODO (GL #2471). +CDNSKEY="no" +# These are the same time values as calculated for ksk-doubleksk. +Lksk=5184000 +Lzsk=31536000 +IretKSK=180000 +IretZSK=867600 +# KSK (KEY1) is outgoing. +key_clear "KEY1" +set_keyrole "KEY1" "ksk" +set_keylifetime "KEY1" "${Lksk}" +set_keyalgorithm "KEY1" "$DEFAULT_ALGORITHM_NUMBER" "$DEFAULT_ALGORITHM" "$DEFAULT_BITS" +set_keysigning "KEY1" "yes" +set_zonesigning "KEY1" "yes" +set_keystate "KEY1" "GOAL" "hidden" +set_keystate "KEY1" "STATE_DNSKEY" "omnipresent" +set_keystate "KEY1" "STATE_KRRSIG" "omnipresent" +set_keystate "KEY1" "STATE_DS" "unretentive" +# KSK (KEY2) is incoming. +key_clear "KEY2" +set_keyrole "KEY2" "ksk" +set_keylifetime "KEY2" "${Lksk}" +set_keyalgorithm "KEY2" "$DEFAULT_ALGORITHM_NUMBER" "$DEFAULT_ALGORITHM" "$DEFAULT_BITS" +set_keysigning "KEY2" "yes" +set_zonesigning "KEY2" "no" +set_keystate "KEY2" "GOAL" "omnipresent" +set_keystate "KEY2" "STATE_DNSKEY" "omnipresent" +set_keystate "KEY2" "STATE_KRRSIG" "omnipresent" +set_keystate "KEY2" "STATE_DS" "rumoured" +# We will introduce the third KSK shortly. +key_clear "KEY3" +# ZSK (KEY4). +key_clear "KEY4" +set_keyrole "KEY4" "zsk" +set_keylifetime "KEY4" "${Lzsk}" +set_keyalgorithm "KEY4" "$DEFAULT_ALGORITHM_NUMBER" "$DEFAULT_ALGORITHM" "$DEFAULT_BITS" +set_keysigning "KEY4" "no" +set_zonesigning "KEY4" "yes" +set_keystate "KEY4" "GOAL" "omnipresent" +set_keystate "KEY4" "STATE_DNSKEY" "omnipresent" +set_keystate "KEY4" "STATE_ZRRSIG" "omnipresent" +# Run preliminary tests. +check_keys +check_dnssecstatus "$SERVER" "$POLICY" "$ZONE" +check_apex +check_subdomain +dnssec_verify +# Roll over KEY2. +# Set expected key lifetime, which is DNSKEY TTL plus the zone propagation delay, +# plus the publish-safety: 7200s + 1h + 1d = 97200 seconds. +set_keylifetime "KEY2" "97200" +created=$(key_get KEY2 CREATED) +rndc_rollover "$SERVER" "$DIR" $(key_get KEY2 ID) "${created}" "$ZONE" +# Update expected number of keys and key states. +set_keystate "KEY2" "GOAL" "hidden" +set_policy "ksk-doubleksk" "4" "7200" +CDNSKEY="no" +# New KSK (KEY3) is introduced. +set_keyrole "KEY3" "ksk" +set_keylifetime "KEY3" "${Lksk}" +set_keyalgorithm "KEY3" "$DEFAULT_ALGORITHM_NUMBER" "$DEFAULT_ALGORITHM" "$DEFAULT_BITS" +set_keysigning "KEY3" "yes" +set_zonesigning "KEY3" "no" +set_keystate "KEY3" "GOAL" "omnipresent" +set_keystate "KEY3" "STATE_DNSKEY" "rumoured" +set_keystate "KEY3" "STATE_KRRSIG" "rumoured" +set_keystate "KEY3" "STATE_DS" "hidden" +# Run tests again. We now expect four keys (3x KSK, 1x ZSK). +check_keys +check_dnssecstatus "$SERVER" "$POLICY" "$ZONE" +check_apex +check_subdomain +dnssec_verify # Test dynamic zones that switch to inline-signing. set_zone "dynamic2inline.kasp"