From: Matthijs Mekking Date: Tue, 18 Mar 2025 09:34:53 +0000 (+0100) Subject: Convert enable dnssec test case to pytest X-Git-Tag: v9.21.9~15^2~5 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=233fdb8d520bda11fe18efe9c14e36930e6e96b0;p=thirdparty%2Fbind9.git Convert enable dnssec test case to pytest Move the 'enable-dnssec' to the rollover test dir and convert to pytest. This requires new test functionality to check that "CDS is published" messages are logged (or prohibited). The setup part is slightly adapted such that it no longer needs to set the '-P sync' value in most cases (this is then set by 'named'), and to adjust for the inappropriate safety intervals fix. --- diff --git a/bin/tests/system/isctest/kasp.py b/bin/tests/system/isctest/kasp.py index 35d8c6e82a9..5beb8f26323 100644 --- a/bin/tests/system/isctest/kasp.py +++ b/bin/tests/system/isctest/kasp.py @@ -25,6 +25,7 @@ import dns.tsig import isctest.log import isctest.query import isctest.util +from isctest.vars.algorithms import Algorithm, ALL_ALGORITHMS_BY_NUM DEFAULT_TTL = 300 @@ -403,6 +404,11 @@ class Key: def is_zsk(self) -> bool: return self.get_metadata("ZSK") == "yes" + @property + def algorithm(self) -> Algorithm: + num = int(self.get_metadata("Algorithm")) + return ALL_ALGORITHMS_BY_NUM[num] + def dnskey_equals(self, value, cdnskey=False): dnskey = value.split() @@ -955,6 +961,19 @@ def check_cds(rrset, keys): assert numcds == len(cdss) +def check_cdslog(server, zone, key, substr): + with server.watch_log_from_start() as watcher: + watcher.wait_for_line( + f"{substr} for key {zone}/{key.algorithm.name}/{key.tag} is now published" + ) + + +def check_cdslog_prohibit(server, zone, key, substr): + server.log.prohibit( + f"{substr} for key {zone}/{key.algorithm.name}/{key.tag} is now published" + ) + + def _query_rrset(server, fqdn, qtype, tsig=None): response = _query(server, fqdn, qtype, tsig=tsig) assert response.rcode() == dns.rcode.NOERROR diff --git a/bin/tests/system/isctest/vars/algorithms.py b/bin/tests/system/isctest/vars/algorithms.py index 26bcc579f8b..446ab09d695 100644 --- a/bin/tests/system/isctest/vars/algorithms.py +++ b/bin/tests/system/isctest/vars/algorithms.py @@ -90,6 +90,8 @@ ALL_ALGORITHMS = [ ED448, ] +ALL_ALGORITHMS_BY_NUM = {alg.number: alg for alg in ALL_ALGORITHMS} + ALGORITHM_SETS = { "stable": AlgorithmSet( default=ECDSAP256SHA256, alternative=RSASHA256, disabled=ECDSAP384SHA384 diff --git a/bin/tests/system/kasp/ns3/named-fips.conf.in b/bin/tests/system/kasp/ns3/named-fips.conf.in index 8368c4822e7..dbbc6e0f37e 100644 --- a/bin/tests/system/kasp/ns3/named-fips.conf.in +++ b/bin/tests/system/kasp/ns3/named-fips.conf.in @@ -324,30 +324,6 @@ zone "zsk-retired.autosign" { dnssec-policy "autosign"; }; -/* - * Zones for testing enabling DNSSEC. - */ -zone "step1.enable-dnssec.autosign" { - type primary; - file "step1.enable-dnssec.autosign.db"; - dnssec-policy "enable-dnssec"; -}; -zone "step2.enable-dnssec.autosign" { - type primary; - file "step2.enable-dnssec.autosign.db"; - dnssec-policy "enable-dnssec"; -}; -zone "step3.enable-dnssec.autosign" { - type primary; - file "step3.enable-dnssec.autosign.db"; - dnssec-policy "enable-dnssec"; -}; -zone "step4.enable-dnssec.autosign" { - type primary; - file "step4.enable-dnssec.autosign.db"; - dnssec-policy "enable-dnssec"; -}; - /* * Zones for testing ZSK Pre-Publication steps. */ diff --git a/bin/tests/system/kasp/ns3/policies/autosign.conf.in b/bin/tests/system/kasp/ns3/policies/autosign.conf.in index bc3b7e11ddb..062885ad241 100644 --- a/bin/tests/system/kasp/ns3/policies/autosign.conf.in +++ b/bin/tests/system/kasp/ns3/policies/autosign.conf.in @@ -25,26 +25,6 @@ dnssec-policy "autosign" { }; }; -dnssec-policy "enable-dnssec" { - - signatures-refresh P1W; - signatures-validity P2W; - signatures-validity-dnskey P2W; - - dnskey-ttl 300; - max-zone-ttl PT12H; - zone-propagation-delay PT5M; - retire-safety PT20M; - publish-safety PT5M; - - parent-propagation-delay 1h; - parent-ds-ttl 2h; - - keys { - csk lifetime unlimited algorithm @DEFAULT_ALGORITHM_NUMBER@; - }; -}; - dnssec-policy "zsk-prepub" { signatures-refresh P1W; diff --git a/bin/tests/system/kasp/ns3/setup.sh b/bin/tests/system/kasp/ns3/setup.sh index 7eeb2488384..827bca18c0d 100644 --- a/bin/tests/system/kasp/ns3/setup.sh +++ b/bin/tests/system/kasp/ns3/setup.sh @@ -281,75 +281,6 @@ oldtimes="-P $T2 -A $T2 -I $T1 -D $T1" OLD=$($KEYGEN -a $DEFAULT_ALGORITHM -L 300 $oldtimes $zone 2>keygen.out.$zone.3) $SETTIME -s -g $H -k $H $T1 -z $H $T1 "$OLD" >settime.out.$zone.3 2>&1 -# -# The zones at enable-dnssec.autosign represent the various steps of the -# initial signing of a zone. -# - -# Step 1: -# This is an unsigned zone and named should perform the initial steps of -# introducing the DNSSEC records in the right order. -setup step1.enable-dnssec.autosign -cp template.db.in $zonefile - -# Step 2: -# The DNSKEY has been published long enough to become OMNIPRESENT. -setup step2.enable-dnssec.autosign -# DNSKEY TTL: 300 seconds -# zone-propagation-delay: 5 minutes (300 seconds) -# publish-safety: 5 minutes (300 seconds) -# Total: 900 seconds -TpubN="now-900s" -# RRSIG TTL: 12 hour (43200 seconds) -# zone-propagation-delay: 5 minutes (300 seconds) -# Already passed time: -900 seconds -# Total: 42600 seconds -TsbmN="now+42600s" -keytimes="-P ${TpubN} -P sync ${TsbmN} -A ${TpubN}" -CSK=$($KEYGEN -k enable-dnssec -l policies/autosign.conf $keytimes $zone 2>keygen.out.$zone.1) -$SETTIME -s -g $O -k $R $TpubN -r $R $TpubN -d $H $TpubN -z $R $TpubN "$CSK" >settime.out.$zone.1 2>&1 -cat template.db.in "${CSK}.key" >"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK" >>"$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 - -# Step 3: -# The zone signatures have been published long enough to become OMNIPRESENT. -setup step3.enable-dnssec.autosign -# Passed time since publications: 42600 + 900 = 43500 seconds. -TpubN="now-43500s" -# The key is secure for using in chain of trust when the DNSKEY is OMNIPRESENT. -TcotN="now-42600s" -# We can submit the DS now. -TsbmN="now" -keytimes="-P ${TpubN} -P sync ${TsbmN} -A ${TpubN}" -CSK=$($KEYGEN -k enable-dnssec -l policies/autosign.conf $keytimes $zone 2>keygen.out.$zone.1) -$SETTIME -s -g $O -k $O $TcotN -r $O $TcotN -d $H $TpubN -z $R $TpubN "$CSK" >settime.out.$zone.1 2>&1 -cat template.db.in "${CSK}.key" >"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK" >>"$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 - -# Step 4: -# The DS has been submitted long enough ago to become OMNIPRESENT. -setup step4.enable-dnssec.autosign -# DS TTL: 2 hour (7200 seconds) -# parent-propagation-delay: 1 hour (3600 seconds) -# retire-safety: 20 minutes (1200 seconds) -# Total aditional time: 12000 seconds -# 44700 + 12000 = 56700 -TpubN="now-56700s" -# 43800 + 12000 = 55800 -TcotN="now-55800s" -TsbmN="now-12000s" -keytimes="-P ${TpubN} -P sync ${TsbmN} -A ${TpubN}" -CSK=$($KEYGEN -k enable-dnssec -l policies/autosign.conf $keytimes $zone 2>keygen.out.$zone.1) -$SETTIME -s -g $O -P ds $TsbmN -k $O $TcotN -r $O $TcotN -d $R $TsbmN -z $O $TsbmN "$CSK" >settime.out.$zone.1 2>&1 -cat template.db.in "${CSK}.key" >"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK" >>"$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 - # # The zones at zsk-prepub.autosign represent the various steps of a ZSK # Pre-Publication rollover. diff --git a/bin/tests/system/kasp/tests.sh b/bin/tests/system/kasp/tests.sh index b83b6a16d6f..ae5f3b9774f 100644 --- a/bin/tests/system/kasp/tests.sh +++ b/bin/tests/system/kasp/tests.sh @@ -206,55 +206,6 @@ set_keytimes_autosign_policy() { set_addkeytime "KEY2" "REMOVED" "${retired}" 695100 } -# -# Testing DNSSEC introduction. -# - -# -# Zone: step1.enable-dnssec.autosign. -# -set_zone "step1.enable-dnssec.autosign" -set_policy "enable-dnssec" "1" "300" -set_server "ns3" "10.53.0.3" -# Key properties. -key_clear "KEY1" -set_keyrole "KEY1" "csk" -set_keylifetime "KEY1" "0" -set_keyalgorithm "KEY1" "$DEFAULT_ALGORITHM_NUMBER" "$DEFAULT_ALGORITHM" "$DEFAULT_BITS" -set_keysigning "KEY1" "yes" -set_zonesigning "KEY1" "yes" -# The DNSKEY and signatures are introduced first, the DS remains hidden. -set_keystate "KEY1" "GOAL" "omnipresent" -set_keystate "KEY1" "STATE_DNSKEY" "rumoured" -set_keystate "KEY1" "STATE_KRRSIG" "rumoured" -set_keystate "KEY1" "STATE_ZRRSIG" "rumoured" -set_keystate "KEY1" "STATE_DS" "hidden" -# This policy lists only one key (CSK). -key_clear "KEY2" -key_clear "KEY3" -key_clear "KEY4" - -check_keys -check_dnssecstatus "$SERVER" "$POLICY" "$ZONE" - -# Set expected key times: -# - The first key is immediately published and activated. -created=$(key_get KEY1 CREATED) -set_keytime "KEY1" "PUBLISHED" "${created}" -set_keytime "KEY1" "ACTIVE" "${created}" -# - The DS can be published if the DNSKEY and RRSIG records are -# OMNIPRESENT. This happens after max-zone-ttl (12h) plus -# plus zone-propagation-delay (5m) = -# 43200 + 300 = 43500. -set_addkeytime "KEY1" "SYNCPUBLISH" "${created}" 43500 -# - Key lifetime is unlimited, so not setting RETIRED and REMOVED. - -# Various signing policy checks. -check_keytimes -check_apex -check_subdomain -dnssec_verify - _check_next_key_event() { _expect=$1 @@ -290,110 +241,6 @@ check_next_key_event() { } -# Next key event is when the DNSKEY RRset becomes OMNIPRESENT: DNSKEY TTL plus -# publish safety plus the zone propagation delay: 900 seconds. -check_next_key_event 900 - -# -# Zone: step2.enable-dnssec.autosign. -# -set_zone "step2.enable-dnssec.autosign" -set_policy "enable-dnssec" "1" "300" -set_server "ns3" "10.53.0.3" -# The DNSKEY is omnipresent, but the zone signatures not yet. -# Thus, the DS remains hidden. -set_keystate "KEY1" "STATE_DNSKEY" "omnipresent" -set_keystate "KEY1" "STATE_KRRSIG" "omnipresent" - -# Various signing policy checks. -check_keys -check_dnssecstatus "$SERVER" "$POLICY" "$ZONE" - -# Set expected key times: -# - The key was published and activated 900 seconds ago (with settime). -created=$(key_get KEY1 CREATED) -set_addkeytime "KEY1" "PUBLISHED" "${created}" -900 -set_addkeytime "KEY1" "ACTIVE" "${created}" -900 -set_addkeytime "KEY1" "SYNCPUBLISH" "${created}" 42600 - -# Continue signing policy checks. -check_keytimes -check_apex -check_subdomain -dnssec_verify - -# Next key event is when the zone signatures become OMNIPRESENT: max-zone-ttl -# plus zone propagation delay plus retire safety minus the already elapsed -# 900 seconds: 12h + 300s + 20m - 900 = 43500 - 900 = 42600 seconds -check_next_key_event 42600 - -# -# Zone: step3.enable-dnssec.autosign. -# -set_zone "step3.enable-dnssec.autosign" -set_policy "enable-dnssec" "1" "300" -set_server "ns3" "10.53.0.3" -# All signatures should be omnipresent, so the DS can be submitted. -set_keystate "KEY1" "STATE_ZRRSIG" "omnipresent" -set_keystate "KEY1" "STATE_DS" "rumoured" - -# Various signing policy checks. -check_keys -check_dnssecstatus "$SERVER" "$POLICY" "$ZONE" - -# Set expected key times: -# - The key was published and activated 43500 seconds ago (with settime). -created=$(key_get KEY1 CREATED) -set_addkeytime "KEY1" "PUBLISHED" "${created}" -43500 -set_addkeytime "KEY1" "ACTIVE" "${created}" -43500 -set_keytime "KEY1" "SYNCPUBLISH" "${created}" - -# Continue signing policy checks. -check_keytimes -check_apex -check_subdomain -dnssec_verify -# Check that CDS publication is logged. -check_cdslog "$DIR" "$ZONE" KEY1 - -# The DS can be introduced. We ignore any parent registration delay, so set -# the DS publish time to now. -rndc_checkds "$SERVER" "$DIR" KEY1 "now" "published" "$ZONE" -# Next key event is when the DS can move to the OMNIPRESENT state. This occurs -# when the parent propagation delay have passed, plus the DS TTL and retire -# safety delay: 1h + 2h = 3h = 10800 seconds -check_next_key_event 10800 - -# -# Zone: step4.enable-dnssec.autosign. -# -set_zone "step4.enable-dnssec.autosign" -set_policy "enable-dnssec" "1" "300" -set_server "ns3" "10.53.0.3" -# The DS is omnipresent. -set_keystate "KEY1" "STATE_DS" "omnipresent" - -# Various signing policy checks. -check_keys -check_dnssecstatus "$SERVER" "$POLICY" "$ZONE" - -# Set expected key times: -# - The key was published and activated 56700 seconds ago (with settime). -created=$(key_get KEY1 CREATED) -set_addkeytime "KEY1" "PUBLISHED" "${created}" -56700 -set_addkeytime "KEY1" "ACTIVE" "${created}" -56700 -set_addkeytime "KEY1" "SYNCPUBLISH" "${created}" -12000 - -# Continue signing policy checks. -check_keytimes -check_apex -check_subdomain -dnssec_verify - -# Next key event is never, the zone dnssec-policy has been established. So we -# fall back to the default loadkeys interval. -check_next_key_event 3600 - # # Testing ZSK Pre-Publication rollover. # diff --git a/bin/tests/system/rollover/ns3/kasp.conf.j2 b/bin/tests/system/rollover/ns3/kasp.conf.j2 index 2ab26877f0e..f432cfc6c01 100644 --- a/bin/tests/system/rollover/ns3/kasp.conf.j2 +++ b/bin/tests/system/rollover/ns3/kasp.conf.j2 @@ -29,3 +29,22 @@ dnssec-policy "multisigner-model2" { zsk key-directory lifetime unlimited algorithm @DEFAULT_ALGORITHM@ tag-range 32768 65535; }; }; + +dnssec-policy "enable-dnssec" { + signatures-refresh P1W; + signatures-validity P2W; + signatures-validity-dnskey P2W; + + dnskey-ttl 300; + max-zone-ttl PT12H; + zone-propagation-delay PT5M; + retire-safety PT20M; + publish-safety PT5M; + + parent-propagation-delay 1h; + parent-ds-ttl 2h; + + keys { + csk lifetime unlimited algorithm @DEFAULT_ALGORITHM_NUMBER@; + }; +}; diff --git a/bin/tests/system/rollover/ns3/named.conf.j2 b/bin/tests/system/rollover/ns3/named.conf.j2 index 573865d1b96..c65404a8ca5 100644 --- a/bin/tests/system/rollover/ns3/named.conf.j2 +++ b/bin/tests/system/rollover/ns3/named.conf.j2 @@ -67,3 +67,27 @@ zone "single-to-multisigner.kasp" { dnssec-policy "multisigner-model2"; allow-update { any; }; }; + +/* + * Zones for testing enabling DNSSEC. + */ +zone "step1.enable-dnssec.autosign" { + type primary; + file "step1.enable-dnssec.autosign.db"; + dnssec-policy "enable-dnssec"; +}; +zone "step2.enable-dnssec.autosign" { + type primary; + file "step2.enable-dnssec.autosign.db"; + dnssec-policy "enable-dnssec"; +}; +zone "step3.enable-dnssec.autosign" { + type primary; + file "step3.enable-dnssec.autosign.db"; + dnssec-policy "enable-dnssec"; +}; +zone "step4.enable-dnssec.autosign" { + type primary; + file "step4.enable-dnssec.autosign.db"; + dnssec-policy "enable-dnssec"; +}; diff --git a/bin/tests/system/rollover/ns3/setup.sh b/bin/tests/system/rollover/ns3/setup.sh index 969b6a7e6c1..ac6a47924cf 100644 --- a/bin/tests/system/rollover/ns3/setup.sh +++ b/bin/tests/system/rollover/ns3/setup.sh @@ -79,3 +79,64 @@ cat template.db.in "${KSK}.key" "${ZSK}.key" >"$infile" $SIGNER -PS -z -x -s now-2w -e now-1mi -o $zone -f "${zonefile}" $infile >signer.out.$zone.1 2>&1 echo "Lifetime: 0" >>"${KSK}".state echo "Lifetime: 0" >>"${ZSK}".state + +# +# The zones at enable-dnssec.autosign represent the various steps of the +# initial signing of a zone. +# + +# Step 1: +# This is an unsigned zone and named should perform the initial steps of +# introducing the DNSSEC records in the right order. +setup step1.enable-dnssec.autosign +cp template.db.in $zonefile + +# Step 2: +# The DNSKEY has been published long enough to become OMNIPRESENT. +setup step2.enable-dnssec.autosign +# DNSKEY TTL: 300 seconds +# zone-propagation-delay: 5 minutes (300 seconds) +# publish-safety: 5 minutes (300 seconds) +# Total: 900 seconds +TpubN="now-900s" +keytimes="-P ${TpubN} -A ${TpubN}" +CSK=$($KEYGEN -k enable-dnssec -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1) +$SETTIME -s -g $O -k $R $TpubN -r $R $TpubN -d $H $TpubN -z $R $TpubN "$CSK" >settime.out.$zone.1 2>&1 +cat template.db.in "${CSK}.key" >"$infile" +private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK" >>"$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 + +# Step 3: +# The zone signatures have been published long enough to become OMNIPRESENT. +setup step3.enable-dnssec.autosign +# Passed time since publication: +# max-zone-ttl: 12 hours (43200 seconds) +# zone-propagation-delay: 5 minutes (300 seconds) +TpubN="now-43500s" +# We can submit the DS now. +keytimes="-P ${TpubN} -A ${TpubN}" +CSK=$($KEYGEN -k enable-dnssec -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1) +$SETTIME -s -g $O -k $O $TpubN -r $O $TpubN -d $H $TpubN -z $R $TpubN "$CSK" >settime.out.$zone.1 2>&1 +cat template.db.in "${CSK}.key" >"$infile" +private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK" >>"$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 + +# Step 4: +# The DS has been submitted long enough ago to become OMNIPRESENT. +setup step4.enable-dnssec.autosign +# DS TTL: 2 hour (7200 seconds) +# parent-propagation-delay: 1 hour (3600 seconds) +# Total aditional time: 10800 seconds +# 43500 + 10800 = 54300 +TpubN="now-54300s" +TsbmN="now-10800s" +keytimes="-P ${TpubN} -A ${TpubN} -P sync ${TsbmN}" +CSK=$($KEYGEN -k enable-dnssec -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1) +$SETTIME -s -g $O -P ds $TsbmN -k $O $TpubN -r $O $TpubN -d $R $TpubN -z $O $TsbmN "$CSK" >settime.out.$zone.1 2>&1 +cat template.db.in "${CSK}.key" >"$infile" +private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK" >>"$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 + diff --git a/bin/tests/system/rollover/tests_rollover.py b/bin/tests/system/rollover/tests_rollover.py index a055639d36a..05e1e9753ce 100644 --- a/bin/tests/system/rollover/tests_rollover.py +++ b/bin/tests/system/rollover/tests_rollover.py @@ -382,3 +382,134 @@ def test_rollover_multisigner(servers): isctest.kasp.check_apex(server, zone, ksks, zsks) isctest.kasp.check_subdomain(server, zone, ksks, zsks) isctest.kasp.check_dnssec_verify(server, zone) + + +def check_rollover_step(server, zone, config, policy, keyprops, nextev): + ttl = int(config["dnskey-ttl"].total_seconds()) + expected = isctest.kasp.policy_to_properties(ttl, keyprops) + isctest.kasp.check_zone_is_signed(server, zone) + keys = isctest.kasp.keydir_to_keylist(zone, server.identifier) + ksks = [k for k in keys if k.is_ksk()] + zsks = [k for k in keys if not k.is_ksk()] + isctest.kasp.check_keys(zone, keys, expected) + + for kp in expected: + kp.set_expected_keytimes(config) + + # Check that CDS publication/withdrawal is logged. + if "KSK" not in kp.metadata: + continue + if kp.metadata["KSK"] == "no": + continue + key = kp.key + + if kp.metadata["DSState"] == "rumoured": + isctest.kasp.check_cdslog(server, zone, key, "CDS (SHA-256)") + isctest.kasp.check_cdslog(server, zone, key, "CDNSKEY") + isctest.kasp.check_cdslog_prohibit(server, zone, key, "CDS (SHA-384)") + + # The DS can be introduced. We ignore any parent registration delay, + # so set the DS publish time to now. + server.rndc(f"dnssec -checkds -key {key.tag} published {zone}") + + if kp.metadata["DSState"] == "unretentive": + # The DS can be withdrawn. We ignore any parent registration + # delay, so set the DS withdraw time to now. + server.rndc(f"dnssec -checkds -key {key.tag} withdrawn {zone}") + + isctest.kasp.check_keytimes(keys, expected) + isctest.kasp.check_dnssecstatus(server, zone, keys, policy=policy) + isctest.kasp.check_apex(server, zone, ksks, zsks) + isctest.kasp.check_subdomain(server, zone, ksks, zsks) + isctest.kasp.check_dnssec_verify(server, zone) + + def check_next_key_event(): + return isctest.kasp.next_key_event_equals(server, zone, nextev) + + isctest.run.retry_with_timeout(check_next_key_event, timeout=5) + + +def test_rollover_enable_dnssec(servers): + server = servers["ns3"] + policy = "enable-dnssec" + config = { + "dnskey-ttl": timedelta(seconds=300), + "ds-ttl": timedelta(hours=2), + "max-zone-ttl": timedelta(hours=12), + "parent-propagation-delay": timedelta(hours=1), + "publish-safety": timedelta(minutes=5), + "retire-safety": timedelta(minutes=20), + "signatures-refresh": timedelta(days=7), + "signatures-validity": timedelta(days=14), + "zone-propagation-delay": timedelta(minutes=5), + } + alg = os.environ["DEFAULT_ALGORITHM_NUMBER"] + size = os.environ["DEFAULT_BITS"] + + ipub = Ipub(config) + ipubC = IpubC(config, rollover=False) + iretZSK = Iret(config, rollover=False) + iretKSK = Iret(config, zsk=False, ksk=True, rollover=False) + offsets = { + "step1": 0, + "step2": -int(ipub.total_seconds()), + "step3": -int(iretZSK.total_seconds()), + "step4": -int(ipubC.total_seconds() + iretKSK.total_seconds()), + } + + steps = [ + { + # Step 1. + "zone": "step1.enable-dnssec.autosign", + "keyprops": [ + f"csk unlimited {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured zrrsig:rumoured ds:hidden offset:{offsets['step1']}", + ], + # Next key event is when the DNSKEY RRset becomes OMNIPRESENT, + # after the publication interval. + "nextev": ipub, + }, + { + # Step 2. + "zone": "step2.enable-dnssec.autosign", + # The DNSKEY is omnipresent, but the zone signatures not yet. + # Thus, the DS remains hidden. + # dnskey: rumoured -> omnipresent + # krrsig: rumoured -> omnipresent + "keyprops": [ + f"csk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:rumoured ds:hidden offset:{offsets['step2']}", + ], + # Next key event is when the zone signatures become OMNIPRESENT, + # Minus the time already elapsed. + "nextev": iretZSK - ipub, + }, + { + # Step 3. + "zone": "step3.enable-dnssec.autosign", + # All signatures should be omnipresent, so the DS can be submitted. + # zrrsig: rumoured -> omnipresent + # ds: hidden -> rumoured + "keyprops": [ + f"csk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:rumoured offset:{offsets['step3']}", + ], + # Next key event is when the DS can move to the OMNIPRESENT state. + # This is after the retire interval. + "nextev": iretKSK, + }, + { + # Step 4. + "zone": "step4.enable-dnssec.autosign", + # DS has been published long enough. + # ds: rumoured -> omnipresent + "keyprops": [ + f"csk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{offsets['step4']}", + ], + # Next key event is never, the zone dnssec-policy has been + # established. So we fall back to the default loadkeys interval. + "nextev": timedelta(hours=1), + }, + ] + + for step in steps: + check_rollover_step( + server, step["zone"], config, policy, step["keyprops"], step["nextev"] + )