diff --git a/bin/tests/system/isctest/kasp.py b/bin/tests/system/isctest/kasp.py index 35d8c6e82a..5beb8f2632 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 26bcc579f8..446ab09d69 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 8368c4822e..dbbc6e0f37 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 bc3b7e11dd..062885ad24 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 7eeb248838..827bca18c0 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 b83b6a16d6..ae5f3b9774 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 2ab26877f0..f432cfc6c0 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 573865d1b9..c65404a8ca 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 969b6a7e6c..ac6a47924c 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 a055639d36..05e1e9753c 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"] + )