Symlink ns1 and ns2 to rollover/ns1 and rollover/ns2.
Symlink ns3/template.db.j2.manual to rollover/ns3/template.db.j2.manual.
Since the bootstrapping is done before the templates are rendered
automatically, replace @DEFAULT_ALGORITHM@ in ns3/kasp.conf.j2 to
ecdsa256 and rename to ns3/kasp.conf.
+++ /dev/null
-../../rollover/ns3/template.db.in
\ No newline at end of file
--- /dev/null
+../rollover/ns1
\ No newline at end of file
--- /dev/null
+../rollover/ns2
\ No newline at end of file
cdnskey no;
keys {
- ksk key-directory lifetime P60D algorithm @DEFAULT_ALGORITHM@;
- zsk key-directory lifetime unlimited algorithm @DEFAULT_ALGORITHM@;
+ ksk key-directory lifetime P60D algorithm ecdsa256;
+ zsk key-directory lifetime unlimited algorithm ecdsa256;
};
zone-propagation-delay PT1H;
cdnskey no;
keys {
- ksk key-directory lifetime P60D algorithm @DEFAULT_ALGORITHM@;
- zsk key-directory lifetime unlimited algorithm @DEFAULT_ALGORITHM@;
+ ksk key-directory lifetime P60D algorithm ecdsa256;
+ zsk key-directory lifetime unlimited algorithm ecdsa256;
};
zone-propagation-delay PT1H;
+++ /dev/null
-../../rollover/ns3/template.db.in
\ No newline at end of file
--- /dev/null
+../../rollover/ns3/template.db.j2.manual
\ No newline at end of file
--- /dev/null
+../../_common/trusted.conf.j2
\ No newline at end of file
+++ /dev/null
-#!/bin/sh -e
-
-# 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.
-
-# shellcheck source=conf.sh
-. ../conf.sh
-
-cd "ns3"
-
-setup() {
- zone="$1"
- echo_i "setting up zone: $zone"
- zonefile="${zone}.db"
- infile="${zone}.db.infile"
- echo "$zone" >>zones
-}
-
-# Set in the key state files the Predecessor/Successor fields.
-# Key $1 is the predecessor of key $2.
-key_successor() {
- id1=$(keyfile_to_key_id "$1")
- id2=$(keyfile_to_key_id "$2")
- echo "Predecessor: ${id1}" >>"${2}.state"
- echo "Successor: ${id2}" >>"${1}.state"
-}
-
-# Make lines shorter by storing key states in environment variables.
-H="HIDDEN"
-R="RUMOURED"
-O="OMNIPRESENT"
-U="UNRETENTIVE"
-
-#
-# The zones at ksk-doubleksk.$tld represent the various steps of a KSK
-# Double-KSK rollover.
-#
-
-for tld in autosign manual; do
- # Step 1:
- # Introduce the first key. This will immediately be active.
- setup step1.ksk-doubleksk.$tld
- TactN="now-7d"
- keytimes="-P ${TactN} -A ${TactN}"
- KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $keytimes $zone 2>keygen.out.$zone.1)
- ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 $keytimes $zone 2>keygen.out.$zone.2)
- $SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN "$KSK" >settime.out.$zone.1 2>&1
- $SETTIME -s -g $O -k $O $TactN -z $O $TactN "$ZSK" >settime.out.$zone.2 2>&1
- cat template.db.in "${KSK}.key" "${ZSK}.key" >"$infile"
- cp $infile $zonefile
- $SIGNER -S -x -G "cds:sha-256" -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
-
- # Step 2:
- # It is time to submit the introduce the new KSK.
- setup step2.ksk-doubleksk.$tld
- # Lksk: 60d
- # Dreg: n/a
- # DprpC: 1h
- # TTLds: 1d
- # TTLkey: 2h
- # publish-safety: 1d
- # retire-safety: 2d
- #
- # According to RFC 7583:
- # Tpub(N+1) <= Tact(N) + Lksk - Dreg - IpubC
- # IpubC = DprpC + TTLkey (+publish-safety)
- #
- # IpubC = 27h
- # Tact(N) = now - Lksk + Dreg + IpubC = now - 60d + 27h
- # = now - 1440h + 27h = now - 1413h
- TactN="now-1413h"
- keytimes="-P ${TactN} -A ${TactN}"
- KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $keytimes $zone 2>keygen.out.$zone.1)
- ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 $keytimes $zone 2>keygen.out.$zone.2)
- $SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN "$KSK" >settime.out.$zone.1 2>&1
- $SETTIME -s -g $O -k $O $TactN -z $O $TactN "$ZSK" >settime.out.$zone.2 2>&1
- cat template.db.in "${KSK}.key" "${ZSK}.key" >"$infile"
- private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK" >>"$infile"
- private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile"
- cp $infile $zonefile
- $SIGNER -S -x -G "cds:sha-256" -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
-
- # Step 3:
- # It is time to submit the DS.
- setup step3.ksk-doubleksk.$tld
- # According to RFC 7583:
- # Iret = DprpP + TTLds (+retire-safety)
- #
- # Iret = 50h
- # Tpub(N) = now - Lksk = now - 60d = now - 60d
- # Tact(N) = now - 1413h
- # Tret(N) = now
- # Trem(N) = now + Iret = now + 50h
- # Tpub(N+1) = now - IpubC = now - 27h
- # Tact(N+1) = now
- # Tret(N+1) = now + Lksk = now + 60d
- # Trem(N+1) = now + Lksk + Iret = now + 60d + 50h
- # = now + 1440h + 50h = 1490h
- TpubN="now-60d"
- TactN="now-1413h"
- TretN="now"
- TremN="now+50h"
- TpubN1="now-27h"
- TactN1="now"
- TretN1="now+60d"
- TremN1="now+1490h"
- ksktimes="-P ${TpubN} -A ${TpubN} -P sync ${TactN} -I ${TretN} -D ${TremN} -D sync ${TactN1}"
- newtimes="-P ${TpubN1} -A ${TactN1} -P sync ${TactN1} -I ${TretN1} -D ${TremN1}"
- zsktimes="-P ${TpubN} -A ${TpubN}"
- 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 $TpubN -r $O $TpubN -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 $TpubN -z $O $TpubN "$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 -G "cds:sha-256" -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
-
- # Step 4:
- # The DS should be swapped now.
- setup step4.ksk-doubleksk.$tld
- # Tpub(N) = now - Lksk - Iret = now - 60d - 50h
- # = now - 1440h - 50h = now - 1490h
- # Tact(N) = now - 1490h + 27h = now - 1463h
- # Tret(N) = now - Iret = now - 50h
- # Trem(N) = now
- # Tpub(N+1) = now - Iret - IpubC = now - 50h - 27h
- # = now - 77h
- # Tact(N+1) = Tret(N)
- # Tret(N+1) = now + Lksk - Iret = now + 60d - 50h = now + 1390h
- # Trem(N+1) = now + Lksk = now + 60d
- TpubN="now-1490h"
- TactN="now-1463h"
- TretN="now-50h"
- TremN="now"
- TpubN1="now-77h"
- TactN1="${TretN}"
- TretN1="now+1390h"
- TremN1="now+60d"
- ksktimes="-P ${TpubN} -A ${TpubN} -P sync ${TactN} -I ${TretN} -D ${TremN} -D sync ${TactN1}"
- newtimes="-P ${TpubN1} -A ${TactN1} -P sync ${TactN1} -I ${TretN1} -D ${TremN1}"
- zsktimes="-P ${TpubN} -A ${TpubN}"
- 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 $U $TretN -D ds $TretN "$KSK1" >settime.out.$zone.1 2>&1
- $SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $R $TactN1 -P ds $TactN1 "$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 -G "cds:sha-256" -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
-
- # Step 5:
- # The predecessor DNSKEY is removed long enough that is has become HIDDEN.
- setup step5.ksk-doubleksk.$tld
- # Subtract DNSKEY TTL + zone-propagation-delay from all the times (3h).
- # Tpub(N) = now - 1490h - 3h = now - 1493h
- # Tact(N) = now - 1463h - 3h = now - 1466h
- # Tret(N) = now - 50h - 3h = now - 53h
- # Trem(N) = now - 3h
- # Tpub(N+1) = now - 77h - 3h = now - 80h
- # Tact(N+1) = Tret(N)
- # Tret(N+1) = now + 1390h - 3h = now + 1387h
- # Trem(N+1) = now + 60d - 3h = now + 1441h
- TpubN="now-1493h"
- TactN="now-1466h"
- TretN="now-53h"
- TremN="now-3h"
- TpubN1="now-80h"
- TactN1="${TretN}"
- TretN1="now+1387h"
- TremN1="now+1441h"
- ksktimes="-P ${TpubN} -A ${TpubN} -P sync ${TactN} -I ${TretN} -D ${TremN} -D sync ${TactN1}"
- newtimes="-P ${TpubN1} -A ${TactN1} -P sync ${TactN1} -I ${TretN1} -D ${TremN1}"
- zsktimes="-P ${TpubN} -A ${TpubN}"
- 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 $U $TretN -r $U $TretN -d $H $TretN "$KSK1" >settime.out.$zone.1 2>&1
- $SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $O $TactN1 "$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 -G "cds:sha-256" -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
-
- # Step 6:
- # The predecessor DNSKEY can be purged.
- setup step6.ksk-doubleksk.$tld
- # Subtract purge-keys interval from all the times (1h).
- TpubN="now-1494h"
- TactN="now-1467h"
- TretN="now-54h"
- TremN="now-4h"
- TpubN1="now-81h"
- TactN1="${TretN}"
- TretN1="now+1386h"
- TremN1="now+1440h"
- ksktimes="-P ${TpubN} -A ${TpubN} -P sync ${TactN} -I ${TretN} -D ${TremN} -D sync ${TactN1}"
- newtimes="-P ${TpubN1} -A ${TactN1} -P sync ${TactN1} -I ${TretN1} -D ${TremN1}"
- zsktimes="-P ${TpubN} -A ${TpubN}"
- 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 $H $TretN -r $H $TretN -d $H $TretN "$KSK1" >settime.out.$zone.1 2>&1
- $SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $O $TactN1 "$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 -G "cds:sha-256" -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
-done
KSK_KEYTTLPROP,
TIMEDELTA,
)
-
+from rollover.setup import (
+ configure_root,
+ configure_tld,
+ configure_ksk_doubleksk,
+)
CDSS = ["CDS (SHA-256)"]
POLICY = "ksk-doubleksk"
OFFSETS["step6-s"] = OFFSETS["step5-s"] - int(KSK_CONFIG["purge-keys"].total_seconds())
+def bootstrap():
+ data = {
+ "tlds": [],
+ "trust_anchors": [],
+ }
+
+ tlds = []
+ for tld_name in [
+ "autosign",
+ "manual",
+ ]:
+ delegations = configure_ksk_doubleksk(tld_name)
+
+ tld = configure_tld(tld_name, delegations)
+ tlds.append(tld)
+
+ data["tlds"].append(tld_name)
+
+ ta = configure_root(tlds)
+ data["trust_anchors"].append(ta)
+
+ return data
+
+
@pytest.mark.parametrize(
"tld",
[
render_and_sign_zone(zonename, [ksk_name, zsk_name], extra_options="-P")
return zones
+
+
+def configure_ksk_doubleksk(tld: str) -> List[Zone]:
+ # The zones at ksk-doubleksk.$tld represent the various steps of a KSK
+ # Double-KSK rollover.
+ zones = []
+ zone = f"ksk-doubleksk.{tld}"
+ cds = "cds:sha-256"
+ keygen = CmdHelper("KEYGEN", "-a ECDSAP256SHA256 -L 7200")
+ settime = CmdHelper("SETTIME", "-s")
+
+ # Step 1:
+ # Introduce the first key. This will immediately be active.
+ zonename = f"step1.{zone}"
+ zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
+ isctest.log.info(f"setup {zonename}")
+ # Timing metadata.
+ TactN = "now-7d"
+ keytimes = f"-P {TactN} -A {TactN}"
+ # Key generation.
+ ksk_name = keygen(f"-f KSK {keytimes} {zonename}", cwd="ns3").strip()
+ zsk_name = keygen(f"{keytimes} {zonename}", cwd="ns3").strip()
+ settime(
+ f"-g OMNIPRESENT -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -d OMNIPRESENT {TactN} {ksk_name}",
+ cwd="ns3",
+ )
+ settime(
+ f"-g OMNIPRESENT -k OMNIPRESENT {TactN} -z OMNIPRESENT {TactN} {zsk_name}",
+ cwd="ns3",
+ )
+ # Signing.
+ render_and_sign_zone(zonename, [ksk_name, zsk_name], extra_options=f"-G {cds}")
+
+ # Step 2:
+ # It is time to introduce the new KSK.
+ zonename = f"step2.{zone}"
+ zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
+ isctest.log.info(f"setup {zonename}")
+ # Lksk: 60d
+ # Dreg: n/a
+ # DprpC: 1h
+ # TTLds: 1d
+ # TTLkey: 2h
+ # publish-safety: 1d
+ # retire-safety: 2d
+ #
+ # According to RFC 7583:
+ # Tpub(N+1) <= Tact(N) + Lksk - Dreg - IpubC
+ # IpubC = DprpC + TTLkey (+publish-safety)
+ #
+ # IpubC = 27h
+ # Tact(N) = now - Lksk + Dreg + IpubC = now - 60d + 27h
+ # = now - 1440h + 27h = now - 1413h
+ TactN = "now-1413h"
+ keytimes = f"-P {TactN} -A {TactN}"
+ # Key generation.
+ ksk_name = keygen(f"-f KSK {keytimes} {zonename}", cwd="ns3").strip()
+ zsk_name = keygen(f"{keytimes} {zonename}", cwd="ns3").strip()
+ settime(
+ f"-g OMNIPRESENT -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -d OMNIPRESENT {TactN} {ksk_name}",
+ cwd="ns3",
+ )
+ settime(
+ f"-g OMNIPRESENT -k OMNIPRESENT {TactN} -z OMNIPRESENT {TactN} {zsk_name}",
+ cwd="ns3",
+ )
+ # Signing.
+ render_and_sign_zone(zonename, [ksk_name, zsk_name], extra_options=f"-G {cds}")
+
+ # Step 3:
+ # It is time to submit the DS.
+ zonename = f"step3.{zone}"
+ zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
+ isctest.log.info(f"setup {zonename}")
+ # According to RFC 7583:
+ # Iret = DprpP + TTLds (+retire-safety)
+ #
+ # Iret = 50h
+ # Tpub(N) = now - Lksk = now - 60d = now - 60d
+ # Tact(N) = now - 1413h
+ # Tret(N) = now
+ # Trem(N) = now + Iret = now + 50h
+ # Tpub(N+1) = now - IpubC = now - 27h
+ # Tact(N+1) = now
+ # Tret(N+1) = now + Lksk = now + 60d
+ # Trem(N+1) = now + Lksk + Iret = now + 60d + 50h
+ # = now + 1440h + 50h = 1490h
+ TpubN = "now-60d"
+ TactN = "now-1413h"
+ TretN = "now"
+ TremN = "now+50h"
+ TpubN1 = "now-27h"
+ TactN1 = "now"
+ TretN1 = "now+60d"
+ TremN1 = "now+1490h"
+ ksktimes = (
+ f"-P {TpubN} -A {TpubN} -P sync {TactN} -I {TretN} -D {TremN} -D sync {TactN1}"
+ )
+ newtimes = f"-P {TpubN1} -A {TactN1} -P sync {TactN1} -I {TretN1} -D {TremN1}"
+ zsktimes = f"-P {TpubN} -A {TpubN}"
+ # Key generation.
+ ksk1_name = keygen(f"-f KSK {ksktimes} {zonename}", cwd="ns3").strip()
+ ksk2_name = keygen(f"-f KSK {newtimes} {zonename}", cwd="ns3").strip()
+ zsk_name = keygen(f"{zsktimes} {zonename}", cwd="ns3").strip()
+ settime(
+ f"-g HIDDEN -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -d OMNIPRESENT {TactN} {ksk1_name}",
+ cwd="ns3",
+ )
+ settime(
+ f"-g OMNIPRESENT -k RUMOURED {TpubN1} -r RUMOURED {TpubN1} -d HIDDEN {TpubN1} {ksk2_name}",
+ cwd="ns3",
+ )
+ settime(
+ f"-g OMNIPRESENT -k OMNIPRESENT {TpubN} -z OMNIPRESENT {TpubN} {zsk_name}",
+ cwd="ns3",
+ )
+ # Set key rollover relationship.
+ set_key_relationship(ksk1_name, ksk2_name)
+ # Signing.
+ render_and_sign_zone(
+ zonename, [ksk1_name, ksk2_name, zsk_name], extra_options=f"-G {cds}"
+ )
+
+ # Step 4:
+ # The DS should be swapped now.
+ zonename = f"step4.{zone}"
+ zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
+ isctest.log.info(f"setup {zonename}")
+ # Tpub(N) = now - Lksk - Iret = now - 60d - 50h
+ # = now - 1440h - 50h = now - 1490h
+ # Tact(N) = now - 1490h + 27h = now - 1463h
+ # Tret(N) = now - Iret = now - 50h
+ # Trem(N) = now
+ # Tpub(N+1) = now - Iret - IpubC = now - 50h - 27h
+ # = now - 77h
+ # Tact(N+1) = Tret(N)
+ # Tret(N+1) = now + Lksk - Iret = now + 60d - 50h = now + 1390h
+ # Trem(N+1) = now + Lksk = now + 60d
+ TpubN = "now-1490h"
+ TactN = "now-1463h"
+ TretN = "now-50h"
+ TremN = "now"
+ TpubN1 = "now-77h"
+ TactN1 = TretN
+ TretN1 = "now+1390h"
+ TremN1 = "now+60d"
+ ksktimes = (
+ f"-P {TpubN} -A {TpubN} -P sync {TactN} -I {TretN} -D {TremN} -D sync {TactN1}"
+ )
+ newtimes = f"-P {TpubN1} -A {TactN1} -P sync {TactN1} -I {TretN1} -D {TremN1}"
+ zsktimes = f"-P {TpubN} -A {TpubN}"
+ # Key generation.
+ ksk1_name = keygen(f"-f KSK {ksktimes} {zonename}", cwd="ns3").strip()
+ ksk2_name = keygen(f"-f KSK {newtimes} {zonename}", cwd="ns3").strip()
+ zsk_name = keygen(f"{zsktimes} {zonename}", cwd="ns3").strip()
+ settime(
+ f"-g HIDDEN -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -d UNRETENTIVE {TretN} -D ds {TretN} {ksk1_name}",
+ cwd="ns3",
+ )
+ settime(
+ f"-g OMNIPRESENT -k OMNIPRESENT {TactN1} -r OMNIPRESENT {TactN1} -d RUMOURED {TactN1} -P ds {TactN1} {ksk2_name}",
+ cwd="ns3",
+ )
+ settime(
+ f"-g OMNIPRESENT -k OMNIPRESENT {TactN} -z OMNIPRESENT {TactN} {zsk_name}",
+ cwd="ns3",
+ )
+ # Set key rollover relationship.
+ set_key_relationship(ksk1_name, ksk2_name)
+ # Signing.
+ render_and_sign_zone(
+ zonename, [ksk1_name, ksk2_name, zsk_name], extra_options=f"-G {cds}"
+ )
+
+ # Step 5:
+ # The predecessor DNSKEY is removed long enough that is has become HIDDEN.
+ zonename = f"step5.{zone}"
+ zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
+ isctest.log.info(f"setup {zonename}")
+ # Subtract DNSKEY TTL + zone-propagation-delay from all the times (3h).
+ # Tpub(N) = now - 1490h - 3h = now - 1493h
+ # Tact(N) = now - 1463h - 3h = now - 1466h
+ # Tret(N) = now - 50h - 3h = now - 53h
+ # Trem(N) = now - 3h
+ # Tpub(N+1) = now - 77h - 3h = now - 80h
+ # Tact(N+1) = Tret(N)
+ # Tret(N+1) = now + 1390h - 3h = now + 1387h
+ # Trem(N+1) = now + 60d - 3h = now + 1441h
+ TpubN = "now-1493h"
+ TactN = "now-1466h"
+ TretN = "now-53h"
+ TremN = "now-3h"
+ TpubN1 = "now-80h"
+ TactN1 = TretN
+ TretN1 = "now+1387h"
+ TremN1 = "now+1441h"
+ ksktimes = (
+ f"-P {TpubN} -A {TpubN} -P sync {TactN} -I {TretN} -D {TremN} -D sync {TactN1}"
+ )
+ newtimes = f"-P {TpubN1} -A {TactN1} -P sync {TactN1} -I {TretN1} -D {TremN1}"
+ zsktimes = f"-P {TpubN} -A {TpubN}"
+ # Key generation.
+ ksk1_name = keygen(f"-f KSK {ksktimes} {zonename}", cwd="ns3").strip()
+ ksk2_name = keygen(f"-f KSK {newtimes} {zonename}", cwd="ns3").strip()
+ zsk_name = keygen(f"{zsktimes} {zonename}", cwd="ns3").strip()
+ settime(
+ f"-g HIDDEN -k UNRETENTIVE {TretN} -r UNRETENTIVE {TretN} -d HIDDEN {TretN} {ksk1_name}",
+ cwd="ns3",
+ )
+ settime(
+ f"-g OMNIPRESENT -k OMNIPRESENT {TactN1} -r OMNIPRESENT {TactN1} -d OMNIPRESENT {TactN1} {ksk2_name}",
+ cwd="ns3",
+ )
+ settime(
+ f"-g OMNIPRESENT -k OMNIPRESENT {TactN} -z OMNIPRESENT {TactN} {zsk_name}",
+ cwd="ns3",
+ )
+ # Set key rollover relationship.
+ set_key_relationship(ksk1_name, ksk2_name)
+ # Signing.
+ render_and_sign_zone(
+ zonename, [ksk1_name, ksk2_name, zsk_name], extra_options=f"-G {cds}"
+ )
+
+ # Step 6:
+ # The predecessor DNSKEY can be purged.
+ zonename = f"step6.{zone}"
+ zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
+ isctest.log.info(f"setup {zonename}")
+ # Subtract purge-keys interval from all the times (1h).
+ TpubN = "now-1494h"
+ TactN = "now-1467h"
+ TretN = "now-54h"
+ TremN = "now-4h"
+ TpubN1 = "now-81h"
+ TactN1 = TretN
+ TretN1 = "now+1386h"
+ TremN1 = "now+1440h"
+ ksktimes = (
+ f"-P {TpubN} -A {TpubN} -P sync {TactN} -I {TretN} -D {TremN} -D sync {TactN1}"
+ )
+ newtimes = f"-P {TpubN1} -A {TactN1} -P sync {TactN1} -I {TretN1} -D {TremN1}"
+ zsktimes = f"-P {TpubN} -A {TpubN}"
+ # Key generation.
+ ksk1_name = keygen(f"-f KSK {ksktimes} {zonename}", cwd="ns3").strip()
+ ksk2_name = keygen(f"-f KSK {newtimes} {zonename}", cwd="ns3").strip()
+ zsk_name = keygen(f"{zsktimes} {zonename}", cwd="ns3").strip()
+ settime(
+ f"-g HIDDEN -k HIDDEN {TretN} -r HIDDEN {TretN} -d HIDDEN {TretN} {ksk1_name}",
+ cwd="ns3",
+ )
+ settime(
+ f"-g OMNIPRESENT -k OMNIPRESENT {TactN1} -r OMNIPRESENT {TactN1} -d OMNIPRESENT {TactN1} {ksk2_name}",
+ cwd="ns3",
+ )
+ settime(
+ f"-g OMNIPRESENT -k OMNIPRESENT {TactN} -z OMNIPRESENT {TactN} {zsk_name}",
+ cwd="ns3",
+ )
+ # Set key rollover relationship.
+ set_key_relationship(ksk1_name, ksk2_name)
+ # Signing.
+ render_and_sign_zone(
+ zonename, [ksk1_name, ksk2_name, zsk_name], extra_options=f"-G {cds}"
+ )
+
+ return zones