From b649c41005167460c71a369024a09cf4e2d6be2a Mon Sep 17 00:00:00 2001 From: Matthijs Mekking Date: Thu, 27 Nov 2025 12:11:35 +0100 Subject: [PATCH] rollover-algo-ksk-zsk: From setup.sh to pytest bootstrap Symlink ns1 and ns2 to rollover/ns1 and rollover/ns2. Symlink ns3/template.db.j2.manual to rollover/ns3/template.db.j2.manual. The RSASHA256 keys are generated with dnssec-keygen, without a policy provided. Thus we have to fake the lifetime for these keys. Signing has to be done without the -z option, because the KSK should not sign all records in case of a KSK/ZSK split. Update the signing code to allow for extra options when signing with CSK only. (cherry picked from commit 72d35513558c10e0d506a661802088760a8824ce) --- bin/tests/system/rollover-algo-ksk-zsk/ns1 | 1 + bin/tests/system/rollover-algo-ksk-zsk/ns2 | 1 + .../ns3/{kasp.conf.j2 => kasp.conf} | 0 .../rollover-algo-ksk-zsk/ns3/template.db.in | 1 - .../ns3/template.db.j2.manual | 1 + .../rollover-algo-ksk-zsk/ns3/trusted.conf.j2 | 1 + .../system/rollover-algo-ksk-zsk/setup.sh | 201 ------------- .../tests_rollover_algo_ksk_zsk_initial.py | 31 +- .../tests_rollover_algo_ksk_zsk_reconfig.py | 29 ++ bin/tests/system/rollover/setup.py | 266 +++++++++++++++++- 10 files changed, 320 insertions(+), 212 deletions(-) create mode 120000 bin/tests/system/rollover-algo-ksk-zsk/ns1 create mode 120000 bin/tests/system/rollover-algo-ksk-zsk/ns2 rename bin/tests/system/rollover-algo-ksk-zsk/ns3/{kasp.conf.j2 => kasp.conf} (100%) delete mode 120000 bin/tests/system/rollover-algo-ksk-zsk/ns3/template.db.in create mode 120000 bin/tests/system/rollover-algo-ksk-zsk/ns3/template.db.j2.manual create mode 120000 bin/tests/system/rollover-algo-ksk-zsk/ns3/trusted.conf.j2 delete mode 100644 bin/tests/system/rollover-algo-ksk-zsk/setup.sh diff --git a/bin/tests/system/rollover-algo-ksk-zsk/ns1 b/bin/tests/system/rollover-algo-ksk-zsk/ns1 new file mode 120000 index 0000000000..76608beaed --- /dev/null +++ b/bin/tests/system/rollover-algo-ksk-zsk/ns1 @@ -0,0 +1 @@ +../rollover/ns1 \ No newline at end of file diff --git a/bin/tests/system/rollover-algo-ksk-zsk/ns2 b/bin/tests/system/rollover-algo-ksk-zsk/ns2 new file mode 120000 index 0000000000..41a09bb648 --- /dev/null +++ b/bin/tests/system/rollover-algo-ksk-zsk/ns2 @@ -0,0 +1 @@ +../rollover/ns2 \ No newline at end of file diff --git a/bin/tests/system/rollover-algo-ksk-zsk/ns3/kasp.conf.j2 b/bin/tests/system/rollover-algo-ksk-zsk/ns3/kasp.conf similarity index 100% rename from bin/tests/system/rollover-algo-ksk-zsk/ns3/kasp.conf.j2 rename to bin/tests/system/rollover-algo-ksk-zsk/ns3/kasp.conf diff --git a/bin/tests/system/rollover-algo-ksk-zsk/ns3/template.db.in b/bin/tests/system/rollover-algo-ksk-zsk/ns3/template.db.in deleted file mode 120000 index ce6d526285..0000000000 --- a/bin/tests/system/rollover-algo-ksk-zsk/ns3/template.db.in +++ /dev/null @@ -1 +0,0 @@ -../../rollover/ns3/template.db.in \ No newline at end of file diff --git a/bin/tests/system/rollover-algo-ksk-zsk/ns3/template.db.j2.manual b/bin/tests/system/rollover-algo-ksk-zsk/ns3/template.db.j2.manual new file mode 120000 index 0000000000..38619a01b2 --- /dev/null +++ b/bin/tests/system/rollover-algo-ksk-zsk/ns3/template.db.j2.manual @@ -0,0 +1 @@ +../../rollover/ns3/template.db.j2.manual \ No newline at end of file diff --git a/bin/tests/system/rollover-algo-ksk-zsk/ns3/trusted.conf.j2 b/bin/tests/system/rollover-algo-ksk-zsk/ns3/trusted.conf.j2 new file mode 120000 index 0000000000..cb0be77b22 --- /dev/null +++ b/bin/tests/system/rollover-algo-ksk-zsk/ns3/trusted.conf.j2 @@ -0,0 +1 @@ +../../_common/trusted.conf.j2 \ No newline at end of file diff --git a/bin/tests/system/rollover-algo-ksk-zsk/setup.sh b/bin/tests/system/rollover-algo-ksk-zsk/setup.sh deleted file mode 100644 index bc651b9420..0000000000 --- a/bin/tests/system/rollover-algo-ksk-zsk/setup.sh +++ /dev/null @@ -1,201 +0,0 @@ -#!/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" -} - -# Make lines shorter by storing key states in environment variables. -H="HIDDEN" -R="RUMOURED" -O="OMNIPRESENT" -U="UNRETENTIVE" - -# -# The zones at algorithm-roll.$tld represent the various steps of a ZSK/KSK -# algorithm rollover. -# - -for tld in kasp manual; do - # Step 1: - # Introduce the first key. This will immediately be active. - setup step1.algorithm-roll.$tld - echo "$zone" >>zones - TactN="now-7d" - TsbmN="now-161h" - ksktimes="-P ${TactN} -A ${TactN}" - zsktimes="-P ${TactN} -A ${TactN}" - KSK=$($KEYGEN -a RSASHA256 -L 3600 -f KSK $ksktimes $zone 2>keygen.out.$zone.1) - ZSK=$($KEYGEN -a RSASHA256 -L 3600 $zsktimes $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 8 "$KSK" >>"$infile" - private_type_record $zone 8 "$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 - - # Step 2: - # After the publication interval has passed the DNSKEY is OMNIPRESENT. - setup step2.algorithm-roll.$tld - # The time passed since the new algorithm keys have been introduced is 3 hours. - TpubN1="now-3h" - # Tsbm(N+1) = TpubN1 + Ipub = now + TTLsig + Dprp = now - 3h + 6h + 1h = now + 4h - TsbmN1="now+4h" - ksk1times="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I ${TsbmN1}" - zsk1times="-P ${TactN} -A ${TactN} -I ${TsbmN1}" - ksk2times="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}" - zsk2times="-P ${TpubN1} -A ${TpubN1}" - KSK1=$($KEYGEN -a RSASHA256 -L 3600 -f KSK $ksk1times $zone 2>keygen.out.$zone.1) - ZSK1=$($KEYGEN -a RSASHA256 -L 3600 $zsk1times $zone 2>keygen.out.$zone.2) - KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $ksk2times $zone 2>keygen.out.$zone.3) - ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $zsk2times $zone 2>keygen.out.$zone.4) - $SETTIME -s -g $H -k $O $TactN -r $O $TactN -d $O $TactN "$KSK1" >settime.out.$zone.1 2>&1 - $SETTIME -s -g $H -k $O $TactN -z $O $TactN "$ZSK1" >settime.out.$zone.2 2>&1 - $SETTIME -s -g $O -k $R $TpubN1 -r $R $TpubN1 -d $H $TpubN1 "$KSK2" >settime.out.$zone.3 2>&1 - $SETTIME -s -g $O -k $R $TpubN1 -z $R $TpubN1 "$ZSK2" >settime.out.$zone.4 2>&1 - # Fake lifetime of old algorithm keys. - echo "Lifetime: 0" >>"${KSK1}.state" - echo "Lifetime: 0" >>"${ZSK1}.state" - cat template.db.in "${KSK1}.key" "${ZSK1}.key" "${KSK2}.key" "${ZSK2}.key" >"$infile" - private_type_record $zone 8 "$KSK1" >>"$infile" - private_type_record $zone 8 "$ZSK1" >>"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK2" >>"$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 - - # Step 3: - # The zone signatures are also OMNIPRESENT. - setup step3.algorithm-roll.$tld - # The time passed since the new algorithm keys have been introduced is 7 hours. - TpubN1="now-7h" - TsbmN1="now" - ksk1times="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I ${TsbmN1}" - zsk1times="-P ${TactN} -A ${TactN} -I ${TsbmN1}" - ksk2times="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}" - zsk2times="-P ${TpubN1} -A ${TpubN1}" - KSK1=$($KEYGEN -a RSASHA256 -L 3600 -f KSK $ksk1times $zone 2>keygen.out.$zone.1) - ZSK1=$($KEYGEN -a RSASHA256 -L 3600 $zsk1times $zone 2>keygen.out.$zone.2) - KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $ksk2times $zone 2>keygen.out.$zone.3) - ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $zsk2times $zone 2>keygen.out.$zone.4) - $SETTIME -s -g $H -k $O $TactN -r $O $TactN -d $O $TactN "$KSK1" >settime.out.$zone.1 2>&1 - $SETTIME -s -g $H -k $O $TactN -z $O $TactN "$ZSK1" >settime.out.$zone.2 2>&1 - $SETTIME -s -g $O -k $O $TpubN1 -r $O $TpubN1 -d $H $TpubN1 "$KSK2" >settime.out.$zone.3 2>&1 - $SETTIME -s -g $O -k $O $TpubN1 -z $R $TpubN1 "$ZSK2" >settime.out.$zone.4 2>&1 - # Fake lifetime of old algorithm keys. - echo "Lifetime: 0" >>"${KSK1}.state" - echo "Lifetime: 0" >>"${ZSK1}.state" - cat template.db.in "${KSK1}.key" "${ZSK1}.key" "${KSK2}.key" "${ZSK2}.key" >"$infile" - private_type_record $zone 8 "$KSK1" >>"$infile" - private_type_record $zone 8 "$ZSK1" >>"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK2" >>"$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 - - # Step 4: - # The DS is swapped and can become OMNIPRESENT. - setup step4.algorithm-roll.$tld - # The time passed since the DS has been swapped is 3 hours. - TpubN1="now-10h" - TsbmN1="now-3h" - ksk1times="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I ${TsbmN1}" - zsk1times="-P ${TactN} -A ${TactN} -I ${TsbmN1}" - ksk2times="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}" - zsk2times="-P ${TpubN1} -A ${TpubN1}" - KSK1=$($KEYGEN -a RSASHA256 -L 3600 -f KSK $ksk1times $zone 2>keygen.out.$zone.1) - ZSK1=$($KEYGEN -a RSASHA256 -L 3600 $zsk1times $zone 2>keygen.out.$zone.2) - KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $ksk2times $zone 2>keygen.out.$zone.3) - ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $zsk2times $zone 2>keygen.out.$zone.4) - $SETTIME -s -g $H -k $O $TactN -r $O $TactN -d $U $TsbmN1 -D ds $TsbmN1 "$KSK1" >settime.out.$zone.1 2>&1 - $SETTIME -s -g $H -k $O $TactN -z $O $TactN "$ZSK1" >settime.out.$zone.2 2>&1 - $SETTIME -s -g $O -k $O $TpubN1 -r $O $TpubN1 -d $R $TsbmN1 -P ds $TsbmN1 "$KSK2" >settime.out.$zone.3 2>&1 - $SETTIME -s -g $O -k $O $TpubN1 -z $R $TpubN1 "$ZSK2" >settime.out.$zone.4 2>&1 - # Fake lifetime of old algorithm keys. - echo "Lifetime: 0" >>"${KSK1}.state" - echo "Lifetime: 0" >>"${ZSK1}.state" - cat template.db.in "${KSK1}.key" "${ZSK1}.key" "${KSK2}.key" "${ZSK2}.key" >"$infile" - private_type_record $zone 8 "$KSK1" >>"$infile" - private_type_record $zone 8 "$ZSK1" >>"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK2" >>"$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 - - # Step 5: - # The DNSKEY is removed long enough to be HIDDEN. - setup step5.algorithm-roll.$tld - # The time passed since the DNSKEY has been removed is 2 hours. - TpubN1="now-12h" - TsbmN1="now-5h" - ksk1times="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I ${TsbmN1}" - zsk1times="-P ${TactN} -A ${TactN} -I ${TsbmN1}" - ksk2times="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}" - zsk2times="-P ${TpubN1} -A ${TpubN1}" - KSK1=$($KEYGEN -a RSASHA256 -L 3600 -f KSK $ksk1times $zone 2>keygen.out.$zone.1) - ZSK1=$($KEYGEN -a RSASHA256 -L 3600 $zsk1times $zone 2>keygen.out.$zone.2) - KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $ksk2times $zone 2>keygen.out.$zone.3) - ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $zsk2times $zone 2>keygen.out.$zone.4) - $SETTIME -s -g $H -k $U $TsbmN1 -r $U $TsbmN1 -d $H $TsbmN1 "$KSK1" >settime.out.$zone.1 2>&1 - $SETTIME -s -g $H -k $U $TsbmN1 -z $U $TsbmN1 "$ZSK1" >settime.out.$zone.2 2>&1 - $SETTIME -s -g $O -k $O $TpubN1 -r $O $TpubN1 -d $O $TsbmN1 "$KSK2" >settime.out.$zone.3 2>&1 - $SETTIME -s -g $O -k $O $TpubN1 -z $R $TpubN1 "$ZSK2" >settime.out.$zone.4 2>&1 - # Fake lifetime of old algorithm keys. - echo "Lifetime: 0" >>"${KSK1}.state" - echo "Lifetime: 0" >>"${ZSK1}.state" - cat template.db.in "${KSK1}.key" "${ZSK1}.key" "${KSK2}.key" "${ZSK2}.key" >"$infile" - private_type_record $zone 8 "$KSK1" >>"$infile" - private_type_record $zone 8 "$ZSK1" >>"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK2" >>"$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 - - # Step 6: - # The RRSIGs have been removed long enough to be HIDDEN. - setup step6.algorithm-roll.$tld - # Additional time passed: 7h. - TpubN1="now-19h" - TsbmN1="now-12h" - ksk1times="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I ${TsbmN1}" - zsk1times="-P ${TactN} -A ${TactN} -I ${TsbmN1}" - ksk2times="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}" - zsk2times="-P ${TpubN1} -A ${TpubN1}" - KSK1=$($KEYGEN -a RSASHA256 -L 3600 -f KSK $ksk1times $zone 2>keygen.out.$zone.1) - ZSK1=$($KEYGEN -a RSASHA256 -L 3600 $zsk1times $zone 2>keygen.out.$zone.2) - KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $ksk2times $zone 2>keygen.out.$zone.3) - ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $zsk2times $zone 2>keygen.out.$zone.4) - $SETTIME -s -g $H -k $H $TsbmN1 -r $U $TsbmN1 -d $H $TsbmN1 "$KSK1" >settime.out.$zone.1 2>&1 - $SETTIME -s -g $H -k $H $TsbmN1 -z $U $TsbmN1 "$ZSK1" >settime.out.$zone.2 2>&1 - $SETTIME -s -g $O -k $O $TpubN1 -r $O $TpubN1 -d $O $TsbmN1 "$KSK2" >settime.out.$zone.3 2>&1 - $SETTIME -s -g $O -k $O $TpubN1 -z $R $TpubN1 "$ZSK2" >settime.out.$zone.4 2>&1 - # Fake lifetime of old algorithm keys. - echo "Lifetime: 0" >>"${KSK1}.state" - echo "Lifetime: 0" >>"${ZSK1}.state" - cat template.db.in "${KSK1}.key" "${ZSK1}.key" "${KSK2}.key" "${ZSK2}.key" >"$infile" - private_type_record $zone 8 "$KSK1" >>"$infile" - private_type_record $zone 8 "$ZSK1" >>"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK2" >>"$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 -done diff --git a/bin/tests/system/rollover-algo-ksk-zsk/tests_rollover_algo_ksk_zsk_initial.py b/bin/tests/system/rollover-algo-ksk-zsk/tests_rollover_algo_ksk_zsk_initial.py index 32eea7d014..2f74cd0fa4 100644 --- a/bin/tests/system/rollover-algo-ksk-zsk/tests_rollover_algo_ksk_zsk_initial.py +++ b/bin/tests/system/rollover-algo-ksk-zsk/tests_rollover_algo_ksk_zsk_initial.py @@ -22,6 +22,35 @@ from rollover.common import ( TIMEDELTA, ALGOROLL_CONFIG, ) +from rollover.setup import ( + configure_root, + configure_tld, + configure_algo_ksk_zsk, +) + + +def bootstrap(): + data = { + "tlds": [], + "trust_anchors": [], + } + + tlds = [] + for tld_name in [ + "kasp", + "manual", + ]: + delegations = configure_algo_ksk_zsk(tld_name, reconfig=False) + + 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( @@ -31,7 +60,7 @@ from rollover.common import ( param("manual"), ], ) -def test_algoroll_ksk_zsk_initial(ns3, tld): +def test_algoroll_ksk_zsk_initial(tld, ns3): config = ALGOROLL_CONFIG policy = f"rsasha256-{tld}" zone = f"step1.algorithm-roll.{tld}" diff --git a/bin/tests/system/rollover-algo-ksk-zsk/tests_rollover_algo_ksk_zsk_reconfig.py b/bin/tests/system/rollover-algo-ksk-zsk/tests_rollover_algo_ksk_zsk_reconfig.py index 419690191d..cfac1739f8 100644 --- a/bin/tests/system/rollover-algo-ksk-zsk/tests_rollover_algo_ksk_zsk_reconfig.py +++ b/bin/tests/system/rollover-algo-ksk-zsk/tests_rollover_algo_ksk_zsk_reconfig.py @@ -32,12 +32,41 @@ from rollover.common import ( DURATION, TIMEDELTA, ) +from rollover.setup import ( + configure_root, + configure_tld, + configure_algo_ksk_zsk, +) CONFIG = ALGOROLL_CONFIG POLICY = "ecdsa256" TIME_PASSED = 0 # set in reconfigure() fixture +def bootstrap(): + data = { + "tlds": [], + "trust_anchors": [], + } + + tlds = [] + for tld_name in [ + "kasp", + "manual", + ]: + delegations = configure_algo_ksk_zsk(tld_name, reconfig=True) + + 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.fixture(scope="module", autouse=True) def after_servers_start(ns3, templates): global TIME_PASSED # pylint: disable=global-statement diff --git a/bin/tests/system/rollover/setup.py b/bin/tests/system/rollover/setup.py index 5124bd46ab..f52135a83d 100644 --- a/bin/tests/system/rollover/setup.py +++ b/bin/tests/system/rollover/setup.py @@ -90,7 +90,16 @@ def configure_root(delegations: List[Zone]) -> TrustAnchor: return ksk.into_ta("static-ds") -def render_and_sign_zone(zonename: str, keys: List[str]): +def fake_lifetime(keys: List[str]): + """ + Fake lifetime of old algorithm keys. + """ + for key in keys: + with open(f"ns3/{key}.state", "a") as statefile: + statefile.write("Lifetime: 0\n") + + +def render_and_sign_zone(zonename: str, keys: List[str], extra_options: str = ""): dnskeys = [] privaterrs = [] for key_name in keys: @@ -109,8 +118,8 @@ def render_and_sign_zone(zonename: str, keys: List[str]): } templates.render(f"ns3/{outfile}", tdata, template=f"ns3/{template}") - signer = CmdHelper("SIGNER", "-S -g -x -z -s now-1h -e now+2w -O raw") - signer(f"-o {zonename} -f {outfile}.signed {outfile}", cwd="ns3") + signer = CmdHelper("SIGNER", "-S -g -x -s now-1h -e now+2w -O raw") + signer(f"{extra_options} -o {zonename} -f {outfile}.signed {outfile}", cwd="ns3") def configure_algo_csk(tld: str, policy: str, reconfig: bool = False) -> List[Zone]: @@ -136,7 +145,7 @@ def configure_algo_csk(tld: str, policy: str, reconfig: bool = False) -> List[Zo cwd="ns3", ) # Signing. - render_and_sign_zone(zonename, [csk_name]) + render_and_sign_zone(zonename, [csk_name], extra_options="-z") if reconfig: # Step 2: @@ -160,7 +169,7 @@ def configure_algo_csk(tld: str, policy: str, reconfig: bool = False) -> List[Zo cwd="ns3", ) # Signing. - render_and_sign_zone(zonename, [csk1_name, csk2_name]) + render_and_sign_zone(zonename, [csk1_name, csk2_name], extra_options="-z") # Step 3: # The zone signatures are also OMNIPRESENT. @@ -184,7 +193,7 @@ def configure_algo_csk(tld: str, policy: str, reconfig: bool = False) -> List[Zo cwd="ns3", ) # Signing. - render_and_sign_zone(zonename, [csk1_name, csk2_name]) + render_and_sign_zone(zonename, [csk1_name, csk2_name], extra_options="-z") # Step 4: # The DS is swapped and can become OMNIPRESENT. @@ -208,7 +217,7 @@ def configure_algo_csk(tld: str, policy: str, reconfig: bool = False) -> List[Zo cwd="ns3", ) # Signing. - render_and_sign_zone(zonename, [csk1_name, csk2_name]) + render_and_sign_zone(zonename, [csk1_name, csk2_name], extra_options="-z") # Step 5: # The DNSKEY is removed long enough to be HIDDEN. @@ -232,7 +241,7 @@ def configure_algo_csk(tld: str, policy: str, reconfig: bool = False) -> List[Zo cwd="ns3", ) # Signing. - render_and_sign_zone(zonename, [csk1_name, csk2_name]) + render_and_sign_zone(zonename, [csk1_name, csk2_name], extra_options="-z") # Step 6: # The RRSIGs have been removed long enough to be HIDDEN. @@ -256,6 +265,245 @@ def configure_algo_csk(tld: str, policy: str, reconfig: bool = False) -> List[Zo cwd="ns3", ) # Signing. - render_and_sign_zone(zonename, [csk1_name, csk2_name]) + render_and_sign_zone(zonename, [csk1_name, csk2_name], extra_options="-z") + + return zones + + +def configure_algo_ksk_zsk(tld: str, reconfig: bool = False) -> List[Zone]: + # The zones at algorithm-roll.$tld represent the various steps of a ZSK/KSK + # algorithm rollover. + zones = [] + zone = f"algorithm-roll.{tld}" + keygen = CmdHelper("KEYGEN", "-L 3600") + 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}") + TactN = "now-7d" + TsbmN = "now-161h" + keytimes = f"-P {TactN} -A {TactN}" + # Key generation. + ksk_name = keygen(f"-a RSASHA256 -f KSK {keytimes} {zonename}", cwd="ns3").strip() + zsk_name = keygen(f"-a RSASHA256 {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]) + + if reconfig: + # Step 2: + # After the publication interval has passed the DNSKEY is OMNIPRESENT. + zonename = f"step2.{zone}" + zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3"))) + isctest.log.info(f"setup {zonename}") + # The time passed since the new algorithm keys have been introduced is 3 hours. + # Tsbm(N+1) = TpubN1 + Ipub = now + TTLsig + Dprp = now - 3h + 6h + 1h = now + 4h + TpubN1 = "now-3h" + TsbmN1 = "now+4h" + ksk1times = f"-P {TactN} -A {TactN} -P sync {TsbmN} -I {TsbmN1}" + zsk1times = f"-P {TactN} -A {TactN} -I {TsbmN1}" + ksk2times = f"-P {TpubN1} -A {TpubN1} -P sync {TsbmN1}" + zsk2times = f"-P {TpubN1} -A {TpubN1}" + # Key generation. + ksk1_name = keygen( + f"-a RSASHA256 -f KSK {ksk1times} {zonename}", cwd="ns3" + ).strip() + zsk1_name = keygen(f"-a RSASHA256 {zsk1times} {zonename}", cwd="ns3").strip() + ksk2_name = keygen( + f"-a ECDSA256 -f KSK {ksk2times} {zonename}", cwd="ns3" + ).strip() + zsk2_name = keygen(f"-a ECDSA256 {zsk2times} {zonename}", cwd="ns3").strip() + settime( + f"-g HIDDEN -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -d OMNIPRESENT {TactN} {ksk1_name}", + cwd="ns3", + ) + settime( + f"-g HIDDEN -k OMNIPRESENT {TactN} -z OMNIPRESENT {TactN} {zsk1_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 RUMOURED {TpubN1} -z RUMOURED {TpubN1} {zsk2_name}", + cwd="ns3", + ) + # Signing. + fake_lifetime([ksk1_name, zsk1_name]) + render_and_sign_zone(zonename, [ksk1_name, zsk1_name, ksk2_name, zsk2_name]) + + # Step 3: + # The zone signatures are also OMNIPRESENT. + zonename = f"step3.{zone}" + zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3"))) + isctest.log.info(f"setup {zonename}") + # The time passed since the new algorithm keys have been introduced is 7 hours. + TpubN1 = "now-7h" + TsbmN1 = "now" + ksk1times = f"-P {TactN} -A {TactN} -P sync {TsbmN} -I {TsbmN1}" + zsk1times = f"-P {TactN} -A {TactN} -I {TsbmN1}" + ksk2times = f"-P {TpubN1} -A {TpubN1} -P sync {TsbmN1}" + zsk2times = f"-P {TpubN1} -A {TpubN1}" + # Key generation. + ksk1_name = keygen( + f"-a RSASHA256 -f KSK {ksk1times} {zonename}", cwd="ns3" + ).strip() + zsk1_name = keygen(f"-a RSASHA256 {zsk1times} {zonename}", cwd="ns3").strip() + ksk2_name = keygen( + f"-a ECDSA256 -f KSK {ksk2times} {zonename}", cwd="ns3" + ).strip() + zsk2_name = keygen(f"-a ECDSA256 {zsk2times} {zonename}", cwd="ns3").strip() + settime( + f"-g HIDDEN -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -d OMNIPRESENT {TactN} {ksk1_name}", + cwd="ns3", + ) + settime( + f"-g HIDDEN -k OMNIPRESENT {TactN} -z OMNIPRESENT {TactN} {zsk1_name}", + cwd="ns3", + ) + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TpubN1} -r OMNIPRESENT {TpubN1} -d HIDDEN {TpubN1} {ksk2_name}", + cwd="ns3", + ) + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TpubN1} -z RUMOURED {TpubN1} {zsk2_name}", + cwd="ns3", + ) + # Signing. + fake_lifetime([ksk1_name, zsk1_name]) + render_and_sign_zone(zonename, [ksk1_name, zsk1_name, ksk2_name, zsk2_name]) + + # Step 4: + # The DS is swapped and can become OMNIPRESENT. + zonename = f"step4.{zone}" + zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3"))) + isctest.log.info(f"setup {zonename}") + # The time passed since the DS has been swapped is 3 hours. + TpubN1 = "now-10h" + TsbmN1 = "now-3h" + ksk1times = f"-P {TactN} -A {TactN} -P sync {TsbmN} -I {TsbmN1}" + zsk1times = f"-P {TactN} -A {TactN} -I {TsbmN1}" + ksk2times = f"-P {TpubN1} -A {TpubN1} -P sync {TsbmN1}" + zsk2times = f"-P {TpubN1} -A {TpubN1}" + # Key generation. + ksk1_name = keygen( + f"-a RSASHA256 -f KSK {ksk1times} {zonename}", cwd="ns3" + ).strip() + zsk1_name = keygen(f"-a RSASHA256 {zsk1times} {zonename}", cwd="ns3").strip() + ksk2_name = keygen( + f"-a ECDSA256 -f KSK {ksk2times} {zonename}", cwd="ns3" + ).strip() + zsk2_name = keygen(f"-a ECDSA256 {zsk2times} {zonename}", cwd="ns3").strip() + settime( + f"-g HIDDEN -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -d UNRETENTIVE {TsbmN1} -D ds {TsbmN1} {ksk1_name}", + cwd="ns3", + ) + settime( + f"-g HIDDEN -k OMNIPRESENT {TactN} -z OMNIPRESENT {TactN} {zsk1_name}", + cwd="ns3", + ) + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TpubN1} -r OMNIPRESENT {TpubN1} -d RUMOURED {TsbmN1} -P ds {TsbmN1} {ksk2_name}", + cwd="ns3", + ) + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TpubN1} -z RUMOURED {TpubN1} {zsk2_name}", + cwd="ns3", + ) + # Signing. + fake_lifetime([ksk1_name, zsk1_name]) + render_and_sign_zone(zonename, [ksk1_name, zsk1_name, ksk2_name, zsk2_name]) + + # Step 5: + # The DNSKEY is removed long enough to be HIDDEN. + zonename = f"step5.{zone}" + zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3"))) + isctest.log.info(f"setup {zonename}") + # The time passed since the DNSKEY has been removed is 2 hours. + TpubN1 = "now-12h" + TsbmN1 = "now-5h" + ksk1times = f"-P {TactN} -A {TactN} -P sync {TsbmN} -I {TsbmN1}" + zsk1times = f"-P {TactN} -A {TactN} -I {TsbmN1}" + ksk2times = f"-P {TpubN1} -A {TpubN1} -P sync {TsbmN1}" + zsk2times = f"-P {TpubN1} -A {TpubN1}" + # Key generation. + ksk1_name = keygen( + f"-a RSASHA256 -f KSK {ksk1times} {zonename}", cwd="ns3" + ).strip() + zsk1_name = keygen(f"-a RSASHA256 {zsk1times} {zonename}", cwd="ns3").strip() + ksk2_name = keygen( + f"-a ECDSA256 -f KSK {ksk2times} {zonename}", cwd="ns3" + ).strip() + zsk2_name = keygen(f"-a ECDSA256 {zsk2times} {zonename}", cwd="ns3").strip() + settime( + f"-g HIDDEN -k UNRETENTIVE {TsbmN1} -r UNRETENTIVE {TsbmN1} -d HIDDEN {TsbmN1} {ksk1_name}", + cwd="ns3", + ) + settime( + f"-g HIDDEN -k UNRETENTIVE {TsbmN1} -z UNRETENTIVE {TsbmN1} {zsk1_name}", + cwd="ns3", + ) + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TpubN1} -r OMNIPRESENT {TpubN1} -d OMNIPRESENT {TsbmN1} {ksk2_name}", + cwd="ns3", + ) + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TpubN1} -z RUMOURED {TpubN1} {zsk2_name}", + cwd="ns3", + ) + # Signing. + fake_lifetime([ksk1_name, zsk1_name]) + render_and_sign_zone(zonename, [ksk1_name, zsk1_name, ksk2_name, zsk2_name]) + + # Step 6: + # The RRSIGs have been removed long enough to be HIDDEN. + zonename = f"step6.{zone}" + zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3"))) + isctest.log.info(f"setup {zonename}") + # Additional time passed: 7h. + TpubN1 = "now-19h" + TsbmN1 = "now-12h" + ksk1times = f"-P {TactN} -A {TactN} -P sync {TsbmN} -I {TsbmN1}" + zsk1times = f"-P {TactN} -A {TactN} -I {TsbmN1}" + ksk2times = f"-P {TpubN1} -A {TpubN1} -P sync {TsbmN1}" + zsk2times = f"-P {TpubN1} -A {TpubN1}" + ksk1_name = keygen( + f"-a RSASHA256 -f KSK {ksk1times} {zonename}", cwd="ns3" + ).strip() + zsk1_name = keygen(f"-a RSASHA256 {zsk1times} {zonename}", cwd="ns3").strip() + ksk2_name = keygen( + f"-a ECDSA256 -f KSK {ksk2times} {zonename}", cwd="ns3" + ).strip() + zsk2_name = keygen(f"-a ECDSA256 {zsk2times} {zonename}", cwd="ns3").strip() + settime( + f"-g HIDDEN -k HIDDEN {TsbmN1} -r UNRETENTIVE {TsbmN1} -d HIDDEN {TsbmN1} {ksk1_name}", + cwd="ns3", + ) + settime( + f"-g HIDDEN -k HIDDEN {TsbmN1} -z UNRETENTIVE {TsbmN1} {zsk1_name}", + cwd="ns3", + ) + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TpubN1} -r OMNIPRESENT {TpubN1} -d OMNIPRESENT {TsbmN1} {ksk2_name}", + cwd="ns3", + ) + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TpubN1} -z RUMOURED {TpubN1} {zsk2_name}", + cwd="ns3", + ) + # Signing. + fake_lifetime([ksk1_name, zsk1_name]) + render_and_sign_zone(zonename, [ksk1_name, zsk1_name, ksk2_name, zsk2_name]) return zones