diff --git a/bin/tests/system/isctest/kasp.py b/bin/tests/system/isctest/kasp.py index a3b71577d9..2c7ebcdc24 100644 --- a/bin/tests/system/isctest/kasp.py +++ b/bin/tests/system/isctest/kasp.py @@ -1650,3 +1650,19 @@ def wait_keymgr_done(server: NamedInstance, zone: str, reconfig: bool = False) - messages.append(f"keymgr: {zone} done") with server.watch_log_from_start(timeout=60) as watcher: watcher.wait_for_sequence(messages) + + +def private_type_record(zone: str, key: Key, rrtype: int = 65534) -> str: + """ + Write a private type record recording the state of the signing process for + a given zone and key, print the private type record with given RRtype, + indicating that the signing process for this key is completed. + """ + keyid = key.tag + algorithm = key.get_dnsalg() + secalg = int(key.get_metadata("Algorithm")) + + if algorithm < 256: + return f"{zone}. 0 IN TYPE{rrtype} \\# 5 {secalg:02x}{keyid:04x}0000" + + return f"{zone}. 0 IN TYPE{rrtype} \\# 7 {secalg:02x}{keyid:04x}0000{algorithm:04x}" diff --git a/bin/tests/system/isctest/template.py b/bin/tests/system/isctest/template.py index 4e27a219d1..f454dca7d0 100644 --- a/bin/tests/system/isctest/template.py +++ b/bin/tests/system/isctest/template.py @@ -82,6 +82,20 @@ class TemplateEngine: self.render(template[:-3], data) +@dataclass +class Nameserver: + name: str + ip: str + + +@dataclass +class Zone: + name: str + filename: str + ns: Nameserver + type: str = "primary" + + @dataclass class TrustAnchor: domain: str diff --git a/bin/tests/system/rollover-algo-csk/ns1 b/bin/tests/system/rollover-algo-csk/ns1 new file mode 120000 index 0000000000..76608beaed --- /dev/null +++ b/bin/tests/system/rollover-algo-csk/ns1 @@ -0,0 +1 @@ +../rollover/ns1 \ No newline at end of file diff --git a/bin/tests/system/rollover-algo-csk/ns2 b/bin/tests/system/rollover-algo-csk/ns2 new file mode 120000 index 0000000000..41a09bb648 --- /dev/null +++ b/bin/tests/system/rollover-algo-csk/ns2 @@ -0,0 +1 @@ +../rollover/ns2 \ No newline at end of file diff --git a/bin/tests/system/rollover-algo-csk/ns6/csk1.conf.j2 b/bin/tests/system/rollover-algo-csk/ns3/csk1.conf similarity index 100% rename from bin/tests/system/rollover-algo-csk/ns6/csk1.conf.j2 rename to bin/tests/system/rollover-algo-csk/ns3/csk1.conf diff --git a/bin/tests/system/rollover-algo-csk/ns6/csk2.conf.j2 b/bin/tests/system/rollover-algo-csk/ns3/csk2.conf similarity index 90% rename from bin/tests/system/rollover-algo-csk/ns6/csk2.conf.j2 rename to bin/tests/system/rollover-algo-csk/ns3/csk2.conf index 5afdd1e774..958dfe15d8 100644 --- a/bin/tests/system/rollover-algo-csk/ns6/csk2.conf.j2 +++ b/bin/tests/system/rollover-algo-csk/ns3/csk2.conf @@ -17,7 +17,7 @@ dnssec-policy "csk-algoroll-kasp" { signatures-validity-dnskey 30d; keys { - csk lifetime unlimited algorithm @DEFAULT_ALGORITHM@; + csk lifetime unlimited algorithm ecdsa256; }; dnskey-ttl 1h; @@ -37,7 +37,7 @@ dnssec-policy "csk-algoroll-manual" { signatures-validity-dnskey 30d; keys { - csk lifetime unlimited algorithm @DEFAULT_ALGORITHM@; + csk lifetime unlimited algorithm ecdsa256; }; dnskey-ttl 1h; diff --git a/bin/tests/system/rollover-algo-csk/ns3/named.common.conf.j2 b/bin/tests/system/rollover-algo-csk/ns3/named.common.conf.j2 new file mode 120000 index 0000000000..5dc26178cb --- /dev/null +++ b/bin/tests/system/rollover-algo-csk/ns3/named.common.conf.j2 @@ -0,0 +1 @@ +../../rollover/ns3/named.common.conf.j2 \ No newline at end of file diff --git a/bin/tests/system/rollover-algo-csk/ns6/named.conf.j2 b/bin/tests/system/rollover-algo-csk/ns3/named.conf.j2 similarity index 100% rename from bin/tests/system/rollover-algo-csk/ns6/named.conf.j2 rename to bin/tests/system/rollover-algo-csk/ns3/named.conf.j2 diff --git a/bin/tests/system/rollover-algo-csk/ns3/template.db.j2.manual b/bin/tests/system/rollover-algo-csk/ns3/template.db.j2.manual new file mode 120000 index 0000000000..38619a01b2 --- /dev/null +++ b/bin/tests/system/rollover-algo-csk/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-csk/ns3/trusted.conf.j2 b/bin/tests/system/rollover-algo-csk/ns3/trusted.conf.j2 new file mode 120000 index 0000000000..3e7d850edf --- /dev/null +++ b/bin/tests/system/rollover-algo-csk/ns3/trusted.conf.j2 @@ -0,0 +1 @@ +../../rollover/ns3/trusted.conf.j2 \ No newline at end of file diff --git a/bin/tests/system/rollover-algo-csk/ns6/named.common.conf.j2 b/bin/tests/system/rollover-algo-csk/ns6/named.common.conf.j2 deleted file mode 120000 index 6b841ab2ad..0000000000 --- a/bin/tests/system/rollover-algo-csk/ns6/named.common.conf.j2 +++ /dev/null @@ -1 +0,0 @@ -../../rollover-dynamic2inline/ns6/named.common.conf.j2 \ No newline at end of file diff --git a/bin/tests/system/rollover-algo-csk/ns6/template.db.in b/bin/tests/system/rollover-algo-csk/ns6/template.db.in deleted file mode 120000 index 21598660d1..0000000000 --- a/bin/tests/system/rollover-algo-csk/ns6/template.db.in +++ /dev/null @@ -1 +0,0 @@ -../../rollover-dynamic2inline/ns6/template.db.in \ No newline at end of file diff --git a/bin/tests/system/rollover-algo-csk/setup.sh b/bin/tests/system/rollover-algo-csk/setup.sh deleted file mode 100644 index 200da1388e..0000000000 --- a/bin/tests/system/rollover-algo-csk/setup.sh +++ /dev/null @@ -1,152 +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 "ns6" - -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 csk-algorithm-roll.$tld represent the various steps of a CSK -# algorithm rollover. -# - -for tld in kasp manual; do - # Step 1: - # Introduce the first key. This will immediately be active. - setup step1.csk-algorithm-roll.$tld - echo "$zone" >>zones - TactN="now-7d" - TsbmN="now-161h" - csktimes="-P ${TactN} -A ${TactN}" - CSK=$($KEYGEN -k csk-algoroll-$tld -l csk1.conf $csktimes $zone 2>keygen.out.$zone.1) - $SETTIME -s -g $O -k $O $TactN -r $O $TactN -z $O $TactN -d $O $TactN "$CSK" >settime.out.$zone.1 2>&1 - cat template.db.in "${CSK}.key" >"$infile" - private_type_record $zone 5 "$CSK" >>"$infile" - cp $infile $zonefile - $SIGNER -S -x -z -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.csk-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" - csktimes="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I now" - newtimes="-P ${TpubN1} -A ${TpubN1}" - CSK1=$($KEYGEN -k csk-algoroll-$tld -l csk1.conf $csktimes $zone 2>keygen.out.$zone.1) - CSK2=$($KEYGEN -k csk-algoroll-$tld -l csk2.conf $newtimes $zone 2>keygen.out.$zone.2) - $SETTIME -s -g $H -k $O $TactN -r $O $TactN -z $O $TactN -d $O $TactN "$CSK1" >settime.out.$zone.1 2>&1 - $SETTIME -s -g $O -k $R $TpubN1 -r $R $TpubN1 -z $R $TpubN1 -d $H $TpubN1 "$CSK2" >settime.out.$zone.2 2>&1 - # Fake lifetime of old algorithm keys. - echo "Lifetime: 0" >>"${CSK1}.state" - cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" - private_type_record $zone 5 "$CSK1" >>"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" - cp $infile $zonefile - $SIGNER -S -x -z -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.csk-algorithm-roll.$tld - # The time passed since the new algorithm keys have been introduced is 7 hours. - TpubN1="now-7h" - TsbmN1="now" - ckstimes="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I ${TsbmN1}" - newtimes="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}" - CSK1=$($KEYGEN -k csk-algoroll-$tld -l csk1.conf $csktimes $zone 2>keygen.out.$zone.1) - CSK2=$($KEYGEN -k csk-algoroll-$tld -l csk2.conf $newtimes $zone 2>keygen.out.$zone.2) - $SETTIME -s -g $H -k $O $TactN -r $O $TactN -z $O $TactN -d $O $TactN "$CSK1" >settime.out.$zone.1 2>&1 - $SETTIME -s -g $O -k $O $TpubN1 -r $O $TpubN1 -z $R $TpubN1 -d $H $TpubN1 "$CSK2" >settime.out.$zone.2 2>&1 - # Fake lifetime of old algorithm keys. - echo "Lifetime: 0" >>"${CSK1}.state" - cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" - private_type_record $zone 5 "$CSK1" >>"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" - cp $infile $zonefile - $SIGNER -S -x -z -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.csk-algorithm-roll.$tld - # The time passed since the DS has been swapped is 3 hours. - TpubN1="now-10h" - TsbmN1="now-3h" - csktimes="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I ${TsbmN1}" - newtimes="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}" - CSK1=$($KEYGEN -k csk-algoroll-$tld -l csk1.conf $csktimes $zone 2>keygen.out.$zone.1) - CSK2=$($KEYGEN -k csk-algoroll-$tld -l csk2.conf $newtimes $zone 2>keygen.out.$zone.2) - $SETTIME -s -g $H -k $O $TactN -r $O $TactN -z $O $TsbmN1 -d $U $TsbmN1 -D ds $TsbmN1 "$CSK1" >settime.out.$zone.1 2>&1 - $SETTIME -s -g $O -k $O $TpubN1 -r $O $TpubN1 -z $O $TsbmN1 -d $R $TsbmN1 -P ds $TsbmN1 "$CSK2" >settime.out.$zone.2 2>&1 - # Fake lifetime of old algorithm keys. - echo "Lifetime: 0" >>"${CSK1}.state" - cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" - private_type_record $zone 5 "$CSK1" >>"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" - cp $infile $zonefile - $SIGNER -S -x -z -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.csk-algorithm-roll.$tld - # The time passed since the DNSKEY has been removed is 2 hours. - TpubN1="now-12h" - TsbmN1="now-5h" - csktimes="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I ${TsbmN1}" - newtimes="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}" - CSK1=$($KEYGEN -k csk-algoroll-$tld -l csk1.conf $csktimes $zone 2>keygen.out.$zone.1) - CSK2=$($KEYGEN -k csk-algoroll-$tld -l csk2.conf $newtimes $zone 2>keygen.out.$zone.2) - $SETTIME -s -g $H -k $U $TactN -r $U $TactN -z $U $TsbmN1 -d $H $TsbmN1 "$CSK1" >settime.out.$zone.1 2>&1 - $SETTIME -s -g $O -k $O $TpubN1 -r $O $TpubN1 -z $O $TsbmN1 -d $O $TsbmN1 "$CSK2" >settime.out.$zone.2 2>&1 - # Fake lifetime of old algorithm keys. - echo "Lifetime: 0" >>"${CSK1}.state" - cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" - private_type_record $zone 5 "$CSK1" >>"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" - cp $infile $zonefile - $SIGNER -S -x -z -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.csk-algorithm-roll.$tld - # Additional time passed: 7h. - TpubN1="now-19h" - TsbmN1="now-12h" - csktimes="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I ${TsbmN1}" - newtimes="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}" - CSK1=$($KEYGEN -k csk-algoroll-$tld -l csk1.conf $csktimes $zone 2>keygen.out.$zone.1) - CSK2=$($KEYGEN -k csk-algoroll-$tld -l csk2.conf $newtimes $zone 2>keygen.out.$zone.2) - $SETTIME -s -g $H -k $H $TactN -r $U $TactN -z $U $TactN -d $H $TsbmN1 "$CSK1" >settime.out.$zone.1 2>&1 - $SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -z $O $TsubN1 -d $O $TsbmN1 "$CSK2" >settime.out.$zone.2 2>&1 - # Fake lifetime of old algorithm keys. - echo "Lifetime: 0" >>"${CSK1}.state" - cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" - private_type_record $zone 5 "$CSK1" >>"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" - cp $infile $zonefile - $SIGNER -S -x -z -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-csk/tests_rollover_algo_csk_initial.py b/bin/tests/system/rollover-algo-csk/tests_rollover_algo_csk_initial.py index 0b96fb7328..131933f40f 100644 --- a/bin/tests/system/rollover-algo-csk/tests_rollover_algo_csk_initial.py +++ b/bin/tests/system/rollover-algo-csk/tests_rollover_algo_csk_initial.py @@ -22,20 +22,54 @@ from rollover.common import ( TIMEDELTA, ALGOROLL_CONFIG, ) +from rollover.setup import ( + configure_root, + configure_tld, + configure_algo_csk, +) + +POLICY = "csk-algoroll" + + +def bootstrap(): + data = { + "tlds": [], + "trust_anchors": [], + } + + tlds = [] + for tld_name in [ + "kasp", + "manual", + ]: + delegations = configure_algo_csk( + tld_name, f"{POLICY}-{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( - "tld, policy", + "tld", [ - param("kasp", "csk-algoroll-kasp"), - param("manual", "csk-algoroll-manual"), + param("kasp"), + param("manual"), ], ) -def test_algoroll_csk_initial(ns6, tld, policy): +def test_algoroll_csk_initial(tld, ns3): config = ALGOROLL_CONFIG zone = f"step1.csk-algorithm-roll.{tld}" + policy = f"{POLICY}-{tld}" - isctest.kasp.wait_keymgr_done(ns6, zone) + isctest.kasp.wait_keymgr_done(ns3, zone) step = { "zone": zone, @@ -45,4 +79,4 @@ def test_algoroll_csk_initial(ns6, tld, policy): ], "nextev": TIMEDELTA["PT1H"], } - isctest.kasp.check_rollover_step(ns6, config, policy, step) + isctest.kasp.check_rollover_step(ns3, config, policy, step) diff --git a/bin/tests/system/rollover-algo-csk/tests_rollover_algo_csk_reconfig.py b/bin/tests/system/rollover-algo-csk/tests_rollover_algo_csk_reconfig.py index f9d5edb455..254f438dd8 100644 --- a/bin/tests/system/rollover-algo-csk/tests_rollover_algo_csk_reconfig.py +++ b/bin/tests/system/rollover-algo-csk/tests_rollover_algo_csk_reconfig.py @@ -32,21 +32,52 @@ from rollover.common import ( DURATION, TIMEDELTA, ) +from rollover.setup import ( + configure_root, + configure_tld, + configure_algo_csk, +) CONFIG = ALGOROLL_CONFIG POLICY = "csk-algoroll" TIME_PASSED = 0 # set in reconfigure() fixture +def bootstrap(): + data = { + "tlds": [], + "trust_anchors": [], + } + + tlds = [] + for tld_name in [ + "kasp", + "manual", + ]: + delegations = configure_algo_csk( + tld_name, f"{POLICY}-{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(ns6, templates): +def after_servers_start(ns3, templates): global TIME_PASSED # pylint: disable=global-statement - isctest.kasp.wait_keymgr_done(ns6, "step1.csk-algorithm-roll.kasp") + isctest.kasp.wait_keymgr_done(ns3, "step1.csk-algorithm-roll.kasp") - templates.render("ns6/named.conf", {"csk_roll": True}) + templates.render("ns3/named.conf", {"csk_roll": True}) start_time = KeyTimingMetadata.now() - ns6.reconfigure() + ns3.reconfigure() # Calculate time passed to correctly check for next key events. TIME_PASSED = KeyTimingMetadata.now().value - start_time.value @@ -59,11 +90,11 @@ def after_servers_start(ns6, templates): param("manual"), ], ) -def test_algoroll_csk_reconfig_step1(tld, ns6, alg, size): +def test_algoroll_csk_reconfig_step1(tld, ns3, alg, size): zone = f"step1.csk-algorithm-roll.{tld}" policy = f"{POLICY}-{tld}" - isctest.kasp.wait_keymgr_done(ns6, zone, reconfig=True) + isctest.kasp.wait_keymgr_done(ns3, zone, reconfig=True) if tld == "manual": # Same as initial. @@ -76,18 +107,18 @@ def test_algoroll_csk_reconfig_step1(tld, ns6, alg, size): "manual-mode": True, "nextev": None, } - keys = isctest.kasp.check_rollover_step(ns6, CONFIG, policy, step) + keys = isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step) # Check logs. tag = keys[0].key.tag msg1 = f"keymgr-manual-mode: block retire DNSKEY {zone}/RSASHA256/{tag} (CSK)" msg2 = f"keymgr-manual-mode: block new key generation for zone {zone} (policy {policy})" - assert msg1 in ns6.log - assert msg2 in ns6.log + assert msg1 in ns3.log + assert msg2 in ns3.log # Force step. - with ns6.watch_log_from_here() as watcher: - ns6.rndc(f"dnssec -step {zone}") + with ns3.watch_log_from_here() as watcher: + ns3.rndc(f"dnssec -step {zone}") watcher.wait_for_line( f"zone {zone}/IN (signed): zone_rekey done: key {tag}/RSASHA256" ) @@ -105,7 +136,7 @@ def test_algoroll_csk_reconfig_step1(tld, ns6, alg, size): # Next key event is when the ecdsa256 keys have been propagated. "nextev": ALGOROLL_IPUB, } - isctest.kasp.check_rollover_step(ns6, CONFIG, policy, step) + isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step) @pytest.mark.parametrize( @@ -115,11 +146,11 @@ def test_algoroll_csk_reconfig_step1(tld, ns6, alg, size): param("manual"), ], ) -def test_algoroll_csk_reconfig_step2(tld, ns6, alg, size): +def test_algoroll_csk_reconfig_step2(tld, ns3, alg, size): zone = f"step2.csk-algorithm-roll.{tld}" policy = f"{POLICY}-{tld}" - isctest.kasp.wait_keymgr_done(ns6, zone, reconfig=True) + isctest.kasp.wait_keymgr_done(ns3, zone, reconfig=True) # manual-mode: Nothing changing in the zone, no 'dnssec -step' required. @@ -142,7 +173,7 @@ def test_algoroll_csk_reconfig_step2(tld, ns6, alg, size): # the time passed between key creation and invoking 'rndc reconfig'. "nextev": ALGOROLL_IPUBC - ALGOROLL_IPUB - TIME_PASSED, } - isctest.kasp.check_rollover_step(ns6, CONFIG, policy, step) + isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step) @pytest.mark.parametrize( @@ -152,11 +183,11 @@ def test_algoroll_csk_reconfig_step2(tld, ns6, alg, size): param("manual"), ], ) -def test_algoroll_csk_reconfig_step3(tld, ns6, alg, size): +def test_algoroll_csk_reconfig_step3(tld, ns3, alg, size): zone = f"step3.csk-algorithm-roll.{tld}" policy = f"{POLICY}-{tld}" - isctest.kasp.wait_keymgr_done(ns6, zone, reconfig=True) + isctest.kasp.wait_keymgr_done(ns3, zone, reconfig=True) if tld == "manual": # Same as step 2, but the zone signatures have become OMNIPRESENT. @@ -170,16 +201,16 @@ def test_algoroll_csk_reconfig_step3(tld, ns6, alg, size): "manual-mode": True, "nextev": None, } - keys = isctest.kasp.check_rollover_step(ns6, CONFIG, policy, step) + keys = isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step) # Check logs. tag = keys[1].key.tag msg = f"keymgr-manual-mode: block transition CSK {zone}/ECDSAP256SHA256/{tag} type DS state HIDDEN to state RUMOURED" - assert msg in ns6.log + assert msg in ns3.log # Force step. - with ns6.watch_log_from_here() as watcher: - ns6.rndc(f"dnssec -step {zone}") + with ns3.watch_log_from_here() as watcher: + ns3.rndc(f"dnssec -step {zone}") watcher.wait_for_line( f"zone {zone}/IN (signed): zone_rekey done: key {tag}/ECDSAP256SHA256" ) @@ -187,14 +218,14 @@ def test_algoroll_csk_reconfig_step3(tld, ns6, alg, size): # Check logs. tag = keys[0].key.tag msg = f"keymgr-manual-mode: block transition CSK {zone}/RSASHA256/{tag} type DS state OMNIPRESENT to state UNRETENTIVE" - if msg in ns6.log: + if msg in ns3.log: # Force step. isctest.log.debug( f"keymgr-manual-mode blocking transition CSK {zone}/RSASHA256/{tag} type DS state OMNIPRESENT to state UNRETENTIVE, step again" ) tag = keys[1].key.tag - with ns6.watch_log_from_here() as watcher: - ns6.rndc(f"dnssec -step {zone}") + with ns3.watch_log_from_here() as watcher: + ns3.rndc(f"dnssec -step {zone}") watcher.wait_for_line( f"zone {zone}/IN (signed): zone_rekey done: key {tag}/ECDSAP256SHA256" ) @@ -211,7 +242,7 @@ def test_algoroll_csk_reconfig_step3(tld, ns6, alg, size): # after the publication interval of the parent side. "nextev": ALGOROLL_IRETKSK - TIME_PASSED, } - isctest.kasp.check_rollover_step(ns6, CONFIG, policy, step) + isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step) @pytest.mark.parametrize( @@ -221,11 +252,11 @@ def test_algoroll_csk_reconfig_step3(tld, ns6, alg, size): param("manual"), ], ) -def test_algoroll_csk_reconfig_step4(tld, ns6, alg, size): +def test_algoroll_csk_reconfig_step4(tld, ns3, alg, size): zone = f"step4.csk-algorithm-roll.{tld}" policy = f"{POLICY}-{tld}" - isctest.kasp.wait_keymgr_done(ns6, zone, reconfig=True) + isctest.kasp.wait_keymgr_done(ns3, zone, reconfig=True) if tld == "manual": # Same as step 3, but the DS has become HIDDEN/OMNIPRESENT. @@ -239,17 +270,17 @@ def test_algoroll_csk_reconfig_step4(tld, ns6, alg, size): "manual-mode": True, "nextev": None, } - keys = isctest.kasp.check_rollover_step(ns6, CONFIG, policy, step) + keys = isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step) # Check logs. tag = keys[0].key.tag msg = f"keymgr-manual-mode: block transition CSK {zone}/RSASHA256/{tag} type DNSKEY state OMNIPRESENT to state UNRETENTIVE" - assert msg in ns6.log + assert msg in ns3.log # Force step. tag = keys[1].key.tag - with ns6.watch_log_from_here() as watcher: - ns6.rndc(f"dnssec -step {zone}") + with ns3.watch_log_from_here() as watcher: + ns3.rndc(f"dnssec -step {zone}") watcher.wait_for_line( f"zone {zone}/IN (signed): zone_rekey done: key {tag}/ECDSAP256SHA256" ) @@ -266,7 +297,7 @@ def test_algoroll_csk_reconfig_step4(tld, ns6, alg, size): # This happens after the DNSKEY TTL plus zone propagation delay. "nextev": ALGOROLL_KEYTTLPROP, } - isctest.kasp.check_rollover_step(ns6, CONFIG, policy, step) + isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step) @pytest.mark.parametrize( @@ -276,11 +307,11 @@ def test_algoroll_csk_reconfig_step4(tld, ns6, alg, size): param("manual"), ], ) -def test_algoroll_csk_reconfig_step5(tld, ns6, alg, size): +def test_algoroll_csk_reconfig_step5(tld, ns3, alg, size): zone = f"step5.csk-algorithm-roll.{tld}" policy = f"{POLICY}-{tld}" - isctest.kasp.wait_keymgr_done(ns6, zone, reconfig=True) + isctest.kasp.wait_keymgr_done(ns3, zone, reconfig=True) # manual-mode: Nothing changing in the zone, no 'dnssec -step' required. @@ -300,7 +331,7 @@ def test_algoroll_csk_reconfig_step5(tld, ns6, alg, size): # between key creation and invoking 'rndc reconfig'. "nextev": ALGOROLL_IRET - ALGOROLL_IRETKSK - ALGOROLL_KEYTTLPROP - TIME_PASSED, } - isctest.kasp.check_rollover_step(ns6, CONFIG, policy, step) + isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step) @pytest.mark.parametrize( @@ -310,11 +341,11 @@ def test_algoroll_csk_reconfig_step5(tld, ns6, alg, size): param("manual"), ], ) -def test_algoroll_csk_reconfig_step6(tld, ns6, alg, size): +def test_algoroll_csk_reconfig_step6(tld, ns3, alg, size): zone = f"step6.csk-algorithm-roll.{tld}" policy = f"{POLICY}-{tld}" - isctest.kasp.wait_keymgr_done(ns6, zone, reconfig=True) + isctest.kasp.wait_keymgr_done(ns3, zone, reconfig=True) # manual-mode: Nothing changing in the zone, no 'dnssec -step' required. @@ -333,4 +364,4 @@ def test_algoroll_csk_reconfig_step6(tld, ns6, alg, size): # Include hidden keys in output. "verbose": True, } - isctest.kasp.check_rollover_step(ns6, CONFIG, policy, step) + isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step) 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/ns6/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/ns6/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/named.common.conf.j2 b/bin/tests/system/rollover-algo-ksk-zsk/ns3/named.common.conf.j2 new file mode 120000 index 0000000000..5dc26178cb --- /dev/null +++ b/bin/tests/system/rollover-algo-ksk-zsk/ns3/named.common.conf.j2 @@ -0,0 +1 @@ +../../rollover/ns3/named.common.conf.j2 \ No newline at end of file diff --git a/bin/tests/system/rollover-algo-ksk-zsk/ns6/named.conf.j2 b/bin/tests/system/rollover-algo-ksk-zsk/ns3/named.conf.j2 similarity index 100% rename from bin/tests/system/rollover-algo-ksk-zsk/ns6/named.conf.j2 rename to bin/tests/system/rollover-algo-ksk-zsk/ns3/named.conf.j2 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/ns6/named.common.conf.j2 b/bin/tests/system/rollover-algo-ksk-zsk/ns6/named.common.conf.j2 deleted file mode 120000 index 6b841ab2ad..0000000000 --- a/bin/tests/system/rollover-algo-ksk-zsk/ns6/named.common.conf.j2 +++ /dev/null @@ -1 +0,0 @@ -../../rollover-dynamic2inline/ns6/named.common.conf.j2 \ No newline at end of file diff --git a/bin/tests/system/rollover-algo-ksk-zsk/ns6/template.db.in b/bin/tests/system/rollover-algo-ksk-zsk/ns6/template.db.in deleted file mode 120000 index 21598660d1..0000000000 --- a/bin/tests/system/rollover-algo-ksk-zsk/ns6/template.db.in +++ /dev/null @@ -1 +0,0 @@ -../../rollover-dynamic2inline/ns6/template.db.in \ 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 db27d74e71..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 "ns6" - -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 1617a40b5b..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,12 +60,12 @@ from rollover.common import ( param("manual"), ], ) -def test_algoroll_ksk_zsk_initial(ns6, tld): +def test_algoroll_ksk_zsk_initial(tld, ns3): config = ALGOROLL_CONFIG policy = f"rsasha256-{tld}" zone = f"step1.algorithm-roll.{tld}" - isctest.kasp.wait_keymgr_done(ns6, zone) + isctest.kasp.wait_keymgr_done(ns3, zone) step = { "zone": zone, @@ -47,4 +76,4 @@ def test_algoroll_ksk_zsk_initial(ns6, tld): ], "nextev": TIMEDELTA["PT1H"], } - isctest.kasp.check_rollover_step(ns6, config, policy, step) + isctest.kasp.check_rollover_step(ns3, config, policy, step) 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 228e65045e..67de084d46 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,21 +32,50 @@ 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(ns6, templates): +def after_servers_start(ns3, templates): global TIME_PASSED # pylint: disable=global-statement - isctest.kasp.wait_keymgr_done(ns6, "step1.algorithm-roll.kasp") + isctest.kasp.wait_keymgr_done(ns3, "step1.algorithm-roll.kasp") - templates.render("ns6/named.conf", {"alg_roll": True}) + templates.render("ns3/named.conf", {"alg_roll": True}) start_time = KeyTimingMetadata.now() - ns6.reconfigure() + ns3.reconfigure() # Calculate time passed to correctly check for next key events. TIME_PASSED = KeyTimingMetadata.now().value - start_time.value @@ -59,11 +88,11 @@ def after_servers_start(ns6, templates): param("manual"), ], ) -def test_algoroll_ksk_zsk_reconfig_step1(tld, ns6, alg, size): +def test_algoroll_ksk_zsk_reconfig_step1(tld, ns3, alg, size): zone = f"step1.algorithm-roll.{tld}" policy = f"{POLICY}-{tld}" - isctest.kasp.wait_keymgr_done(ns6, zone, reconfig=True) + isctest.kasp.wait_keymgr_done(ns3, zone, reconfig=True) if tld == "manual": # Same as initial. @@ -77,7 +106,7 @@ def test_algoroll_ksk_zsk_reconfig_step1(tld, ns6, alg, size): "manual-mode": True, "nextev": None, } - keys = isctest.kasp.check_rollover_step(ns6, CONFIG, policy, step) + keys = isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step) # Check logs. ktag = keys[0].key.tag @@ -85,13 +114,13 @@ def test_algoroll_ksk_zsk_reconfig_step1(tld, ns6, alg, size): msg1 = f"keymgr-manual-mode: block retire DNSKEY {zone}/RSASHA256/{ktag} (KSK)" msg2 = f"keymgr-manual-mode: block retire DNSKEY {zone}/RSASHA256/{ztag} (ZSK)" msg3 = f"keymgr-manual-mode: block new key generation for zone {zone} (policy {policy})" # twice - assert msg1 in ns6.log - assert msg2 in ns6.log - assert len(ns6.log.grep(msg3)) >= 2 + assert msg1 in ns3.log + assert msg2 in ns3.log + assert len(ns3.log.grep(msg3)) == 2 # Force step. - with ns6.watch_log_from_here() as watcher: - ns6.rndc(f"dnssec -step {zone}") + with ns3.watch_log_from_here() as watcher: + ns3.rndc(f"dnssec -step {zone}") watcher.wait_for_line( f"zone {zone}/IN (signed): zone_rekey done: key {ktag}/RSASHA256" ) @@ -110,7 +139,7 @@ def test_algoroll_ksk_zsk_reconfig_step1(tld, ns6, alg, size): # Next key event is when the ecdsa256 keys have been propagated. "nextev": ALGOROLL_IPUB, } - isctest.kasp.check_rollover_step(ns6, CONFIG, policy, step) + isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step) @pytest.mark.parametrize( @@ -120,11 +149,11 @@ def test_algoroll_ksk_zsk_reconfig_step1(tld, ns6, alg, size): param("manual"), ], ) -def test_algoroll_ksk_zsk_reconfig_step2(tld, ns6, alg, size): +def test_algoroll_ksk_zsk_reconfig_step2(tld, ns3, alg, size): zone = f"step2.algorithm-roll.{tld}" policy = f"{POLICY}-{tld}" - isctest.kasp.wait_keymgr_done(ns6, zone, reconfig=True) + isctest.kasp.wait_keymgr_done(ns3, zone, reconfig=True) # manual-mode: Nothing changing in the zone, no 'dnssec -step' required. @@ -149,7 +178,7 @@ def test_algoroll_ksk_zsk_reconfig_step2(tld, ns6, alg, size): # key creation and invoking 'rndc reconfig'. "nextev": ALGOROLL_IPUBC - ALGOROLL_IPUB - TIME_PASSED, } - isctest.kasp.check_rollover_step(ns6, CONFIG, policy, step) + isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step) @pytest.mark.parametrize( @@ -159,11 +188,11 @@ def test_algoroll_ksk_zsk_reconfig_step2(tld, ns6, alg, size): param("manual"), ], ) -def test_algoroll_ksk_zsk_reconfig_step3(tld, ns6, alg, size): +def test_algoroll_ksk_zsk_reconfig_step3(tld, ns3, alg, size): zone = f"step3.algorithm-roll.{tld}" policy = f"{POLICY}-{tld}" - isctest.kasp.wait_keymgr_done(ns6, zone, reconfig=True) + isctest.kasp.wait_keymgr_done(ns3, zone, reconfig=True) if tld == "manual": # Same as step 2, but the zone signatures have become OMNIPRESENT. @@ -179,16 +208,16 @@ def test_algoroll_ksk_zsk_reconfig_step3(tld, ns6, alg, size): "manual-mode": True, "nextev": None, } - keys = isctest.kasp.check_rollover_step(ns6, CONFIG, policy, step) + keys = isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step) # Check logs. tag = keys[2].key.tag msg = f"keymgr-manual-mode: block transition KSK {zone}/ECDSAP256SHA256/{tag} type DS state HIDDEN to state RUMOURED" - assert msg in ns6.log + assert msg in ns3.log # Force step. - with ns6.watch_log_from_here() as watcher: - ns6.rndc(f"dnssec -step {zone}") + with ns3.watch_log_from_here() as watcher: + ns3.rndc(f"dnssec -step {zone}") watcher.wait_for_line( f"zone {zone}/IN (signed): zone_rekey done: key {tag}/ECDSAP256SHA256" ) @@ -196,14 +225,14 @@ def test_algoroll_ksk_zsk_reconfig_step3(tld, ns6, alg, size): # Check logs. tag = keys[0].key.tag msg = f"keymgr-manual-mode: block transition KSK {zone}/RSASHA256/{tag} type DS state OMNIPRESENT to state UNRETENTIVE" - if msg in ns6.log: + if msg in ns3.log: # Force step. isctest.log.debug( f"keymgr-manual-mode blocking transition CSK {zone}/RSASHA256/{tag} type DS state OMNIPRESENT to state UNRETENTIVE, step again" ) tag = keys[2].key.tag - with ns6.watch_log_from_here() as watcher: - ns6.rndc(f"dnssec -step {zone}") + with ns3.watch_log_from_here() as watcher: + ns3.rndc(f"dnssec -step {zone}") watcher.wait_for_line( f"zone {zone}/IN (signed): zone_rekey done: key {tag}/ECDSAP256SHA256" ) @@ -222,7 +251,7 @@ def test_algoroll_ksk_zsk_reconfig_step3(tld, ns6, alg, size): # after the retire interval. "nextev": ALGOROLL_IRETKSK - TIME_PASSED, } - isctest.kasp.check_rollover_step(ns6, CONFIG, policy, step) + isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step) @pytest.mark.parametrize( @@ -232,11 +261,11 @@ def test_algoroll_ksk_zsk_reconfig_step3(tld, ns6, alg, size): param("manual"), ], ) -def test_algoroll_ksk_zsk_reconfig_step4(tld, ns6, alg, size): +def test_algoroll_ksk_zsk_reconfig_step4(tld, ns3, alg, size): zone = f"step4.algorithm-roll.{tld}" policy = f"{POLICY}-{tld}" - isctest.kasp.wait_keymgr_done(ns6, zone, reconfig=True) + isctest.kasp.wait_keymgr_done(ns3, zone, reconfig=True) if tld == "manual": # Same as step 3, but the DS has become HIDDEN/OMNIPRESENT. @@ -252,20 +281,20 @@ def test_algoroll_ksk_zsk_reconfig_step4(tld, ns6, alg, size): "manual-mode": True, "nextev": None, } - keys = isctest.kasp.check_rollover_step(ns6, CONFIG, policy, step) + keys = isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step) # Check logs. ktag = keys[0].key.tag ztag = keys[1].key.tag msg1 = f"keymgr-manual-mode: block transition KSK {zone}/RSASHA256/{ktag} type DNSKEY state OMNIPRESENT to state UNRETENTIVE" msg2 = f"keymgr-manual-mode: block transition ZSK {zone}/RSASHA256/{ztag} type DNSKEY state OMNIPRESENT to state UNRETENTIVE" - assert msg1 in ns6.log - assert msg2 in ns6.log + assert msg1 in ns3.log + assert msg2 in ns3.log # Force step. ktag = keys[3].key.tag - with ns6.watch_log_from_here() as watcher: - ns6.rndc(f"dnssec -step {zone}") + with ns3.watch_log_from_here() as watcher: + ns3.rndc(f"dnssec -step {zone}") watcher.wait_for_line( f"zone {zone}/IN (signed): zone_rekey done: key {ktag}/ECDSAP256SHA256" ) @@ -284,7 +313,7 @@ def test_algoroll_ksk_zsk_reconfig_step4(tld, ns6, alg, size): # This happens after the DNSKEY TTL plus zone propagation delay. "nextev": ALGOROLL_KEYTTLPROP, } - isctest.kasp.check_rollover_step(ns6, CONFIG, policy, step) + isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step) @pytest.mark.parametrize( @@ -294,11 +323,11 @@ def test_algoroll_ksk_zsk_reconfig_step4(tld, ns6, alg, size): param("manual"), ], ) -def test_algoroll_ksk_zsk_reconfig_step5(tld, ns6, alg, size): +def test_algoroll_ksk_zsk_reconfig_step5(tld, ns3, alg, size): zone = f"step5.algorithm-roll.{tld}" policy = f"{POLICY}-{tld}" - isctest.kasp.wait_keymgr_done(ns6, zone, reconfig=True) + isctest.kasp.wait_keymgr_done(ns3, zone, reconfig=True) # manual-mode: Nothing changing in the zone, no 'dnssec -step' required. @@ -322,7 +351,7 @@ def test_algoroll_ksk_zsk_reconfig_step5(tld, ns6, alg, size): # Include hidden keys in output. "verbose": True, } - isctest.kasp.check_rollover_step(ns6, CONFIG, policy, step) + isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step) @pytest.mark.parametrize( @@ -332,11 +361,11 @@ def test_algoroll_ksk_zsk_reconfig_step5(tld, ns6, alg, size): param("manual"), ], ) -def test_algoroll_ksk_zsk_reconfig_step6(tld, ns6, alg, size): +def test_algoroll_ksk_zsk_reconfig_step6(tld, ns3, alg, size): zone = f"step6.algorithm-roll.{tld}" policy = f"{POLICY}-{tld}" - isctest.kasp.wait_keymgr_done(ns6, zone, reconfig=True) + isctest.kasp.wait_keymgr_done(ns3, zone, reconfig=True) # manual-mode: Nothing changing in the zone, no 'dnssec -step' required. @@ -357,4 +386,4 @@ def test_algoroll_ksk_zsk_reconfig_step6(tld, ns6, alg, size): # Include hidden keys in output. "verbose": True, } - isctest.kasp.check_rollover_step(ns6, CONFIG, policy, step) + isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step) diff --git a/bin/tests/system/rollover-csk-roll1/ns1 b/bin/tests/system/rollover-csk-roll1/ns1 new file mode 120000 index 0000000000..76608beaed --- /dev/null +++ b/bin/tests/system/rollover-csk-roll1/ns1 @@ -0,0 +1 @@ +../rollover/ns1 \ No newline at end of file diff --git a/bin/tests/system/rollover-csk-roll1/ns2 b/bin/tests/system/rollover-csk-roll1/ns2 new file mode 120000 index 0000000000..41a09bb648 --- /dev/null +++ b/bin/tests/system/rollover-csk-roll1/ns2 @@ -0,0 +1 @@ +../rollover/ns2 \ No newline at end of file diff --git a/bin/tests/system/rollover-csk-roll1/ns3/kasp.conf.j2 b/bin/tests/system/rollover-csk-roll1/ns3/kasp.conf similarity index 90% rename from bin/tests/system/rollover-csk-roll1/ns3/kasp.conf.j2 rename to bin/tests/system/rollover-csk-roll1/ns3/kasp.conf index e6defeded2..09b0e862b6 100644 --- a/bin/tests/system/rollover-csk-roll1/ns3/kasp.conf.j2 +++ b/bin/tests/system/rollover-csk-roll1/ns3/kasp.conf @@ -23,7 +23,7 @@ dnssec-policy "csk-roll1-autosign" { cds-digest-types { "sha-384"; }; // use a different digest type for testing purposes keys { - csk key-directory lifetime P6M algorithm @DEFAULT_ALGORITHM@; + csk key-directory lifetime P6M algorithm ecdsa256; }; zone-propagation-delay 1h; @@ -47,7 +47,7 @@ dnssec-policy "csk-roll1-manual" { cds-digest-types { "sha-384"; }; // use a different digest type for testing purposes keys { - csk key-directory lifetime P6M algorithm @DEFAULT_ALGORITHM@; + csk key-directory lifetime P6M algorithm ecdsa256; }; zone-propagation-delay 1h; diff --git a/bin/tests/system/rollover-csk-roll1/ns3/template.db.in b/bin/tests/system/rollover-csk-roll1/ns3/template.db.in deleted file mode 120000 index ce6d526285..0000000000 --- a/bin/tests/system/rollover-csk-roll1/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-csk-roll1/ns3/template.db.j2.manual b/bin/tests/system/rollover-csk-roll1/ns3/template.db.j2.manual new file mode 120000 index 0000000000..38619a01b2 --- /dev/null +++ b/bin/tests/system/rollover-csk-roll1/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-csk-roll1/ns3/trusted.conf.j2 b/bin/tests/system/rollover-csk-roll1/ns3/trusted.conf.j2 new file mode 120000 index 0000000000..cb0be77b22 --- /dev/null +++ b/bin/tests/system/rollover-csk-roll1/ns3/trusted.conf.j2 @@ -0,0 +1 @@ +../../_common/trusted.conf.j2 \ No newline at end of file diff --git a/bin/tests/system/rollover-csk-roll1/setup.sh b/bin/tests/system/rollover-csk-roll1/setup.sh deleted file mode 100644 index 088add4121..0000000000 --- a/bin/tests/system/rollover-csk-roll1/setup.sh +++ /dev/null @@ -1,314 +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" - 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 csk-roll1.$tld represent the various steps of a CSK rollover -# (which is essentially a ZSK Pre-Publication / KSK Double-KSK rollover). -# - -for tld in autosign manual; do - # Step 1: - # Introduce the first key. This will immediately be active. - setup step1.csk-roll1.$tld - TactN="now-7d" - keytimes="-P ${TactN} -A ${TactN}" - CSK=$($KEYGEN -k csk-roll1-$tld -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1) - $SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN -z $O $TactN "$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 -G "cdnskey,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - - # Step 2: - # It is time to introduce the new CSK. - setup step2.csk-roll1.$tld - # According to RFC 7583: - # KSK: Tpub(N+1) <= Tact(N) + Lksk - IpubC - # ZSK: Tpub(N+1) <= Tact(N) + Lzsk - Ipub - # IpubC = DprpC + TTLkey (+publish-safety) - # Ipub = IpubC - # Lcsk = Lksk = Lzsk - # - # Lcsk: 6mo (186d, 4464h) - # Dreg: N/A - # DprpC: 1h - # TTLkey: 1h - # publish-safety: 1h - # Ipub: 3h - # - # Tact(N) = now - Lcsk + Ipub = now - 186d + 3h - # = now - 4464h + 3h = now - 4461h - TactN="now-4461h" - keytimes="-P ${TactN} -A ${TactN}" - CSK=$($KEYGEN -k csk-roll1-$tld -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1) - $SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN -z $O $TactN "$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 -G "cdnskey,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - - # Step 3: - # It is time to submit the DS and to roll signatures. - setup step3.csk-roll1.$tld - # According to RFC 7583: - # - # Tsbm(N+1) >= Trdy(N+1) - # KSK: Tact(N+1) = Tsbm(N+1) - # ZSK: Tact(N+1) = Tpub(N+1) + Ipub = Tsbm(N+1) - # KSK: Iret = DprpP + TTLds (+retire-safety) - # ZSK: IretZ = Dsgn + Dprp + TTLsig (+retire-safety) - # - # Lcsk: 186d - # Dprp: 1h - # DprpP: 1h - # Dreg: N/A - # Dsgn: 25d - # TTLds: 1h - # TTLsig: 1d - # retire-safety: 2h - # Iret: 4h - # IretZ: 26d3h - # Ipub: 3h - # - # Tpub(N) = now - Lcsk = now - 186d - # Tact(N) = now - Lcsk + Dprp + TTLsig = now - 4439h - # Tret(N) = now - # Trem(N) = now + IretZ = now + 26d3h = now + 627h - # Tpub(N+1) = now - Ipub = now - 3h - # Tact(N+1) = Tret(N) - # Tret(N+1) = now + Lcsk = now + 186d = now + 186d - # Trem(N+1) = now + Lcsk + IretZ = now + 186d + 26d3h = - # = now + 5091h - TpubN="now-186d" - TactN="now-4439h" - TretN="now" - TremN="now+627h" - TpubN1="now-3h" - TactN1="${TretN}" - TretN1="now+186d" - TremN1="now+5091h" - keytimes="-P ${TpubN} -P sync ${TactN} -A ${TpubN} -I ${TretN} -D ${TremN} -D sync ${TactN1}" - newtimes="-P ${TpubN1} -P sync ${TactN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}" - CSK1=$($KEYGEN -k csk-roll1-$tld -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1) - CSK2=$($KEYGEN -k csk-roll1-$tld -l kasp.conf $newtimes $zone 2>keygen.out.$zone.2) - $SETTIME -s -g $H -k $O $TactN -r $O $TactN -d $O $TactN -z $O $TactN "$CSK1" >settime.out.$zone.1 2>&1 - $SETTIME -s -g $O -k $R $TpubN1 -r $R $TpubN1 -d $H $TpubN1 -z $H $TpubN1 "$CSK2" >settime.out.$zone.2 2>&1 - # Set key rollover relationship. - key_successor $CSK1 $CSK2 - # Sign zone. - cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >>"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" - cp $infile $zonefile - $SIGNER -S -z -x -G "cdnskey,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - - # Step 4: - # Some time later all the ZRRSIG records should be from the new CSK, and the - # DS should be swapped. The ZRRSIG records are all replaced after IretZ - # (which is 26d3h). The DS is swapped after Iret (which is 4h). - # In other words, the DS is swapped before all zone signatures are replaced. - setup step4.csk-roll1.$tld - # According to RFC 7583: - # Trem(N) = Tret(N) - Iret + IretZ - # now = Tsbm(N+1) + Iret - # - # Lcsk: 186d - # Iret: 4h - # IretZ: 26d3h - # - # Tpub(N) = now - Iret - Lcsk = now - 4h - 186d = now - 4468h - # Tret(N) = now - Iret = now - 4h = now - 4h - # Trem(N) = now - Iret + IretZ = now - 4h + 26d3h - # = now + 623h - # Tpub(N+1) = now - Iret - IpubC = now - 4h - 3h = now - 7h - # Tact(N+1) = Tret(N) - # Tret(N+1) = now - Iret + Lcsk = now - 4h + 186d = now + 4460h - # Trem(N+1) = now - Iret + Lcsk + IretZ = now - 4h + 186d + 26d3h - # = now + 5087h - TpubN="now-4468h" - TactN="now-4443h" - TretN="now-4h" - TremN="now+623h" - TpubN1="now-7h" - TactN1="${TretN}" - TretN1="now+4460h" - TremN1="now+5087h" - keytimes="-P ${TpubN} -P sync ${TactN} -A ${TpubN} -I ${TretN} -D ${TremN} -D sync ${TactN1}" - newtimes="-P ${TpubN1} -P sync ${TactN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}" - CSK1=$($KEYGEN -k csk-roll1-$tld -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1) - CSK2=$($KEYGEN -k csk-roll1-$tld -l kasp.conf $newtimes $zone 2>keygen.out.$zone.2) - $SETTIME -s -g $H -k $O $TactN -r $O $TactN -d $U $TactN1 -z $U $TactN1 -D ds $TactN1 "$CSK1" >settime.out.$zone.1 2>&1 - $SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $R $TactN1 -z $R $TactN1 -P ds $TactN1 "$CSK2" >settime.out.$zone.2 2>&1 - # Set key rollover relationship. - key_successor $CSK1 $CSK2 - # Sign zone. - cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >>"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" - cp $infile $zonefile - $SIGNER -S -z -x -G "cdnskey,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - - # Step 5: - # After the DS is swapped in step 4, also the KRRSIG records can be removed. - # At this time these have all become hidden. - setup step5.csk-roll1.$tld - # Subtract DNSKEY TTL plus zone propagation delay from all the times (2h). - TpubN="now-4470h" - TactN="now-4445h" - TretN="now-6h" - TremN="now+621h" - TpubN1="now-9h" - TactN1="${TretN}" - TretN1="now+4458h" - TremN1="now+5085h" - keytimes="-P ${TpubN} -P sync ${TactN} -A ${TpubN} -I ${TretN} -D ${TremN} -D sync ${TactN1}" - newtimes="-P ${TpubN1} -P sync ${TactN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}" - CSK1=$($KEYGEN -k csk-roll1-$tld -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1) - CSK2=$($KEYGEN -k csk-roll1-$tld -l kasp.conf $newtimes $zone 2>keygen.out.$zone.2) - $SETTIME -s -g $H -k $O $TactN -r $U now-2h -d $H now-2h -z $U $TactN1 "$CSK1" >settime.out.$zone.1 2>&1 - $SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $O now-2h -z $R $TactN1 "$CSK2" >settime.out.$zone.2 2>&1 - # Set key rollover relationship. - key_successor $CSK1 $CSK2 - # Sign zone. - cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >>"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" - cp $infile $zonefile - $SIGNER -S -z -x -G "cdnskey,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - - # Step 6: - # After the retire interval has passed the predecessor DNSKEY can be - # removed from the zone. - setup step6.csk-roll1.$tld - # According to RFC 7583: - # Trem(N) = Tret(N) + IretZ - # Tret(N) = Tact(N) + Lcsk - # - # Lcsk: 186d - # Iret: 4h - # IretZ: 26d3h - # - # Tpub(N) = now - IretZ - Lcsk = now - 627h - 186d - # = now - 627h - 4464h = now - 5091h - # Tact(N) = now - 627h - 186d - # Tret(N) = now - IretZ = now - 627h - # Trem(N) = now - # Tpub(N+1) = now - IretZ - Ipub = now - 627h - 3h = now - 630h - # Tact(N+1) = Tret(N) - # Tret(N+1) = now - IretZ + Lcsk = now - 627h + 186d = now + 3837h - # Trem(N+1) = now + Lcsk = now + 186d - TpubN="now-5091h" - TactN="now-5066h" - TretN="now-627h" - TremN="now" - TpubN1="now-630h" - TactN1="${TretN}" - TretN1="now+3837h" - TremN1="now+186d" - keytimes="-P ${TpubN} -P sync ${TactN} -A ${TpubN} -I ${TretN} -D ${TremN} -D sync ${TactN1}" - newtimes="-P ${TpubN1} -P sync ${TactN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}" - CSK1=$($KEYGEN -k csk-roll1-$tld -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1) - CSK2=$($KEYGEN -k csk-roll1-$tld -l kasp.conf $newtimes $zone 2>keygen.out.$zone.2) - $SETTIME -s -g $H -k $O $TactN -r $H $TremN -d $H $TremN -z $U $TactN1 "$CSK1" >settime.out.$zone.1 2>&1 - $SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $O $TremN -z $R $TactN1 "$CSK2" >settime.out.$zone.2 2>&1 - # Set key rollover relationship. - key_successor $CSK1 $CSK2 - # Sign zone. - cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >>"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" - cp $infile $zonefile - $SIGNER -S -z -x -G "cdnskey,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - - # Step 7: - # Some time later the predecessor DNSKEY enters the HIDDEN state. - setup step7.csk-roll1.$tld - # Subtract DNSKEY TTL plus zone propagation delay from all the times (2h). - TpubN="now-5093h" - TactN="now-5068h" - TretN="now-629h" - TremN="now-2h" - TpubN1="now-632h" - TactN1="${TretN}" - TretN1="now+3835h" - TremN1="now+4462h" - keytimes="-P ${TpubN} -P sync ${TactN} -A ${TpubN} -I ${TretN} -D ${TremN} -D sync ${TactN1}" - newtimes="-P ${TpubN1} -P sync ${TactN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}" - CSK1=$($KEYGEN -k csk-roll1-$tld -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1) - CSK2=$($KEYGEN -k csk-roll1-$tld -l kasp.conf $newtimes $zone 2>keygen.out.$zone.2) - $SETTIME -s -g $H -k $U $TremN -r $H $TremN -d $H $TremN -z $H $TactN1 "$CSK1" >settime.out.$zone.1 2>&1 - $SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $O $TactN1 -z $O $TactN1 "$CSK2" >settime.out.$zone.2 2>&1 - # Set key rollover relationship. - key_successor $CSK1 $CSK2 - # Sign zone. - cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >>"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" - cp $infile $zonefile - $SIGNER -S -z -x -G "cdnskey,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - - # Step 8: - # The predecessor DNSKEY can be purged. - setup step8.csk-roll1.$tld - TpubN="now-5094h" - TactN="now-5069h" - TretN="now-630h" - TremN="now-3h" - TpubN1="now-633h" - TactN1="${TretN}" - TretN1="now+3834h" - TremN1="now+4461h" - # Subtract purge-keys interval from all the times (1h). - keytimes="-P ${TpubN} -P sync ${TactN} -A ${TpubN} -I ${TretN} -D ${TremN} -D sync ${TactN1}" - newtimes="-P ${TpubN1} -P sync ${TactN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}" - CSK1=$($KEYGEN -k csk-roll1-$tld -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1) - CSK2=$($KEYGEN -k csk-roll1-$tld -l kasp.conf $newtimes $zone 2>keygen.out.$zone.2) - $SETTIME -s -g $H -k $H $TremN -r $H $TremN -d $H $TremN -z $H $TactN1 "$CSK1" >settime.out.$zone.1 2>&1 - $SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $O $TactN1 -z $O $TactN1 "$CSK2" >settime.out.$zone.2 2>&1 - # Set key rollover relationship. - key_successor $CSK1 $CSK2 - # Sign zone. - cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >>"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" - cp $infile $zonefile - $SIGNER -S -z -x -G "cdnskey,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 -done diff --git a/bin/tests/system/rollover-csk-roll1/tests_rollover_csk_roll1.py b/bin/tests/system/rollover-csk-roll1/tests_rollover_csk_roll1.py index fcf4876b90..5e496dbff6 100644 --- a/bin/tests/system/rollover-csk-roll1/tests_rollover_csk_roll1.py +++ b/bin/tests/system/rollover-csk-roll1/tests_rollover_csk_roll1.py @@ -24,7 +24,11 @@ from rollover.common import ( size, TIMEDELTA, ) - +from rollover.setup import ( + configure_root, + configure_tld, + configure_cskroll1, +) CDSS = ["CDNSKEY", "CDS (SHA-384)"] CONFIG = { @@ -65,6 +69,30 @@ OFFSETS["step8-p"] = OFFSETS["step7-p"] - int(CONFIG["purge-keys"].total_seconds OFFSETS["step8-s"] = OFFSETS["step7-s"] - int(CONFIG["purge-keys"].total_seconds()) +def bootstrap(): + data = { + "tlds": [], + "trust_anchors": [], + } + + tlds = [] + for tld_name in [ + "autosign", + "manual", + ]: + delegations = configure_cskroll1(tld_name, f"{POLICY}-{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", [ @@ -72,7 +100,7 @@ OFFSETS["step8-s"] = OFFSETS["step7-s"] - int(CONFIG["purge-keys"].total_seconds param("manual"), ], ) -def test_csk_roll1_step1(tld, alg, size, ns3): +def test_csk_roll1_step1(tld, ns3, alg, size): zone = f"step1.csk-roll1.{tld}" policy = f"{POLICY}-{tld}" diff --git a/bin/tests/system/rollover-csk-roll2/ns1 b/bin/tests/system/rollover-csk-roll2/ns1 new file mode 120000 index 0000000000..76608beaed --- /dev/null +++ b/bin/tests/system/rollover-csk-roll2/ns1 @@ -0,0 +1 @@ +../rollover/ns1 \ No newline at end of file diff --git a/bin/tests/system/rollover-csk-roll2/ns2 b/bin/tests/system/rollover-csk-roll2/ns2 new file mode 120000 index 0000000000..41a09bb648 --- /dev/null +++ b/bin/tests/system/rollover-csk-roll2/ns2 @@ -0,0 +1 @@ +../rollover/ns2 \ No newline at end of file diff --git a/bin/tests/system/rollover-csk-roll2/ns3/kasp.conf.j2 b/bin/tests/system/rollover-csk-roll2/ns3/kasp.conf similarity index 90% rename from bin/tests/system/rollover-csk-roll2/ns3/kasp.conf.j2 rename to bin/tests/system/rollover-csk-roll2/ns3/kasp.conf index cf1708f3eb..30b96679c3 100644 --- a/bin/tests/system/rollover-csk-roll2/ns3/kasp.conf.j2 +++ b/bin/tests/system/rollover-csk-roll2/ns3/kasp.conf @@ -23,7 +23,7 @@ dnssec-policy "csk-roll2-autosign" { cds-digest-types { "sha-256"; "sha-384"; }; // use two digest type for testing purposes keys { - csk key-directory lifetime P6M algorithm @DEFAULT_ALGORITHM@; + csk key-directory lifetime P6M algorithm ecdsa256; }; zone-propagation-delay PT1H; @@ -47,7 +47,7 @@ dnssec-policy "csk-roll2-manual" { cds-digest-types { "sha-256"; "sha-384"; }; // use two digest type for testing purposes keys { - csk key-directory lifetime P6M algorithm @DEFAULT_ALGORITHM@; + csk key-directory lifetime P6M algorithm ecdsa256; }; zone-propagation-delay PT1H; diff --git a/bin/tests/system/rollover-csk-roll2/ns3/template.db.in b/bin/tests/system/rollover-csk-roll2/ns3/template.db.in deleted file mode 120000 index ce6d526285..0000000000 --- a/bin/tests/system/rollover-csk-roll2/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-csk-roll2/ns3/template.db.j2.manual b/bin/tests/system/rollover-csk-roll2/ns3/template.db.j2.manual new file mode 120000 index 0000000000..38619a01b2 --- /dev/null +++ b/bin/tests/system/rollover-csk-roll2/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-csk-roll2/ns3/trusted.conf.j2 b/bin/tests/system/rollover-csk-roll2/ns3/trusted.conf.j2 new file mode 120000 index 0000000000..cb0be77b22 --- /dev/null +++ b/bin/tests/system/rollover-csk-roll2/ns3/trusted.conf.j2 @@ -0,0 +1 @@ +../../_common/trusted.conf.j2 \ No newline at end of file diff --git a/bin/tests/system/rollover-csk-roll2/setup.sh b/bin/tests/system/rollover-csk-roll2/setup.sh deleted file mode 100644 index da1e2d8bfe..0000000000 --- a/bin/tests/system/rollover-csk-roll2/setup.sh +++ /dev/null @@ -1,301 +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" - 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 csk-roll2.$tld represent the various steps of a CSK rollover -# (which is essentially a ZSK Pre-Publication / KSK Double-KSK rollover). -# This scenario differs from the csk-roll1 one because the zone signatures (ZRRSIG) -# are replaced with the new key sooner than the DS is swapped. -# - -for tld in autosign manual; do - # Step 1: - # Introduce the first key. This will immediately be active. - setup step1.csk-roll2.$tld - TactN="now-7d" - keytimes="-P ${TactN} -A ${TactN}" - CSK=$($KEYGEN -k csk-roll2-$tld -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1) - $SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN -z $O $TactN "$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 -G "cdnskey,cds:sha-256,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - - # Step 2: - # It is time to introduce the new CSK. - setup step2.csk-roll2.$tld - # According to RFC 7583: - # KSK: Tpub(N+1) <= Tact(N) + Lksk - IpubC - # ZSK: Tpub(N+1) <= Tact(N) + Lzsk - Ipub - # IpubC = DprpC + TTLkey (+publish-safety) - # Ipub = IpubC - # Lcsk = Lksk = Lzsk - # - # Lcsk: 6mo (186d, 4464h) - # Dreg: N/A - # DprpC: 1h - # TTLkey: 1h - # publish-safety: 1h - # Ipub: 3h - # - # Tact(N) = now - Lcsk + Ipub = now - 186d + 3h - # = now - 4464h + 3h = now - 4461h - TactN="now-4461h" - keytimes="-P ${TactN} -A ${TactN}" - CSK=$($KEYGEN -k csk-roll2-$tld -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1) - $SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN -z $O $TactN "$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 -G "cdnskey,cds:sha-256,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - - # Step 3: - # It is time to submit the DS and to roll signatures. - setup step3.csk-roll2.$tld - # According to RFC 7583: - # - # Tsbm(N+1) >= Trdy(N+1) - # KSK: Tact(N+1) = Tsbm(N+1) - # ZSK: Tact(N+1) = Tpub(N+1) + Ipub = Tsbm(N+1) - # KSK: Iret = DprpP + TTLds (+retire-safety) - # ZSK: IretZ = Dsgn + Dprp + TTLsig (+retire-safety) - # - # Lcsk: 186d - # Dprp: 1h - # DprpP: 1w - # Dreg: N/A - # Dsgn: 12h - # TTLds: 1h - # TTLsig: 1d - # retire-safety: 1h - # Iret: 170h - # IretZ: 38h - # Ipub: 3h - # - # Tpub(N) = now - Lcsk = now - 186d - # Tact(N) = now - Lcsk + Dprp + TTLsig = now - 4439h - # Tret(N) = now - # Trem(N) = now + Iret = now + 170h - # Tpub(N+1) = now - Ipub = now - 3h - # Tact(N+1) = Tret(N) - # Tret(N+1) = now + Lcsk = now + 186d - # Trem(N+1) = now + Lcsk + Iret = now + 186d + 170h = - # = now + 4464h + 170h = now + 4634h - TpubN="now-186d" - TactN="now-4439h" - TretN="now" - TremN="now+170h" - TpubN1="now-3h" - TactN1="${TretN}" - TretN1="now+186d" - TremN1="now+4634h" - keytimes="-P ${TpubN} -P sync ${TactN} -A ${TpubN} -I ${TretN} -D ${TremN} -D sync ${TactN1}" - newtimes="-P ${TpubN1} -P sync ${TactN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}" - CSK1=$($KEYGEN -k csk-roll2-$tld -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1) - CSK2=$($KEYGEN -k csk-roll2-$tld -l kasp.conf $newtimes $zone 2>keygen.out.$zone.2) - $SETTIME -s -g $H -k $O $TactN -r $O $TactN -d $O $TactN -z $O $TactN "$CSK1" >settime.out.$zone.1 2>&1 - $SETTIME -s -g $O -k $R $TpubN1 -r $R $TpubN1 -d $H $TpubN1 -z $H $TpubN1 "$CSK2" >settime.out.$zone.2 2>&1 - # Set key rollover relationship. - key_successor $CSK1 $CSK2 - # Sign zone. - cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >>"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" - cp $infile $zonefile - $SIGNER -S -z -x -G "cdnskey,cds:sha-256,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - - # Step 4: - # Some time later all the ZRRSIG records should be from the new CSK, and the - # DS should be swapped. The ZRRSIG records are all replaced after IretZ (38h). - # The DS is swapped after Dreg + Iret (1w3h). In other words, the zone - # signatures are replaced before the DS is swapped. - setup step4.csk-roll2.$tld - # According to RFC 7583: - # Trem(N) = Tret(N) + IretZ - # - # Lcsk: 186d - # Dreg: N/A - # Iret: 170h - # IretZ: 38h - # - # Tpub(N) = now - IretZ - Lcsk = now - 38h - 186d - # = now - 38h - 4464h = now - 4502h - # Tact(N) = now - Iret - Lcsk + TTLsig = now - 4502h + 25h = now - 4477h - # Tret(N) = now - IretZ = now - 38h - # Trem(N) = now - IretZ + Iret = now - 38h + 170h = now + 132h - # Tpub(N+1) = now - IretZ - IpubC = now - 38h - 3h = now - 41h - # Tact(N+1) = Tret(N) - # Tret(N+1) = now - IretZ + Lcsk = now - 38h + 186d - # = now + 4426h - # Trem(N+1) = now - IretZ + Lcsk + Iret - # = now + 4426h + 3h = now + 4429h - TpubN="now-4502h" - TactN="now-4477h" - TretN="now-38h" - TremN="now+132h" - TpubN1="now-41h" - TactN1="${TretN}" - TretN1="now+4426h" - TremN1="now+4429h" - keytimes="-P ${TpubN} -P sync ${TactN} -A ${TpubN} -I ${TretN} -D ${TremN} -D sync ${TactN1}" - newtimes="-P ${TpubN1} -P sync ${TactN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}" - CSK1=$($KEYGEN -k csk-roll2-$tld -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1) - CSK2=$($KEYGEN -k csk-roll2-$tld -l kasp.conf $newtimes $zone 2>keygen.out.$zone.2) - $SETTIME -s -g $H -k $O $TactN -r $O $TactN -z $U $TretN -d $U $TactN1 -D ds $TactN1 "$CSK1" >settime.out.$zone.1 2>&1 - $SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -z $R $TactN1 -d $R $TactN1 -P ds $TactN1 "$CSK2" >settime.out.$zone.2 2>&1 - # Set key rollover relationship. - key_successor $CSK1 $CSK2 - # Sign zone. - cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >>"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" - cp $infile $zonefile - $SIGNER -S -z -x -G "cdnskey,cds:sha-256,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - - # Step 5: - # Some time later the DS can be swapped and the old DNSKEY can be removed from - # the zone. - setup step5.csk-roll2.$tld - # Subtract Iret (170h) - IretZ (38h) = 132h. - # - # Tpub(N) = now - 4502h - 132h = now - 4634h - # Tact(N) = now - 4477h - 132h = now - 4609h - # Tret(N) = now - 38h - 132h = now - 170h - # Trem(N) = now + 132h - 132h = now - # Tpub(N+1) = now - 41h - 132h = now - 173h - # Tact(N+1) = Tret(N) - # Tret(N+1) = now + 4426h - 132h = now + 4294h - # Trem(N+1) = now + 4492h - 132h = now + 4360h - TpubN="now-4634h" - TactN="now-4609h" - TretN="now-170h" - TremN="now" - TpubN1="now-173h" - TactN1="${TretN}" - TretN1="now+4294h" - TremN1="now+4360h" - keytimes="-P ${TpubN} -P sync ${TactN} -A ${TpubN} -I ${TretN} -D ${TremN} -D sync ${TactN1}" - newtimes="-P ${TpubN1} -P sync ${TactN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}" - CSK1=$($KEYGEN -k csk-roll2-$tld -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1) - CSK2=$($KEYGEN -k csk-roll2-$tld -l kasp.conf $newtimes $zone 2>keygen.out.$zone.2) - $SETTIME -s -g $H -k $O $TactN -r $O $TactN -z $H now-133h -d $U $TactN1 -D ds $TactN1 "$CSK1" >settime.out.$zone.1 2>&1 - $SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -z $O now-133h -d $R $TactN1 -P ds $TactN1 "$CSK2" >settime.out.$zone.2 2>&1 - # Set key rollover relationship. - key_successor $CSK1 $CSK2 - # Sign zone. - cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >>"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" - cp $infile $zonefile - $SIGNER -S -z -x -G "cdnskey,cds:sha-256,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - - # Step 6: - # Some time later the predecessor DNSKEY enters the HIDDEN state. - setup step6.csk-roll2.$tld - # Subtract DNSKEY TTL plus zone propagation delay (2h). - # - # Tpub(N) = now - 4634h - 2h = now - 4636h - # Tact(N) = now - 4609h - 2h = now - 4611h - # Tret(N) = now - 170h - 2h = now - 172h - # Trem(N) = now - 2h - # Tpub(N+1) = now - 173h - 2h = now - 175h - # Tact(N+1) = Tret(N) - # Tret(N+1) = now + 4294h - 2h = now + 4292h - # Trem(N+1) = now + 4360h - 2h = now + 4358h - TpubN="now-4636h" - TactN="now-4611h" - TretN="now-172h" - TremN="now-2h" - TpubN1="now-175h" - TactN1="${TretN}" - TretN1="now+4292h" - TremN1="now+4358h" - keytimes="-P ${TpubN} -P sync ${TactN} -A ${TpubN} -I ${TretN} -D ${TremN} -D sync ${TactN1}" - newtimes="-P ${TpubN1} -P sync ${TactN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}" - CSK1=$($KEYGEN -k csk-roll2-$tld -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1) - CSK2=$($KEYGEN -k csk-roll2-$tld -l kasp.conf $newtimes $zone 2>keygen.out.$zone.2) - $SETTIME -s -g $H -k $U $TremN -r $U $TremN -d $H $TremN -z $H now-135h "$CSK1" >settime.out.$zone.1 2>&1 - $SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $O $TremN -z $O now-135h "$CSK2" >settime.out.$zone.2 2>&1 - # Set key rollover relationship. - key_successor $CSK1 $CSK2 - # Sign zone. - cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >>"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" - cp $infile $zonefile - $SIGNER -S -z -x -G "cdnskey,cds:sha-256,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - - # Step 7: - # The predecessor DNSKEY can be purged, but purge-keys is disabled. - setup step7.csk-roll2.$tld - # Subtract 90 days (default, 2160h) from all the times. - # - # Tpub(N) = now - 4636h - 2160h = now - 6796h - # Tact(N) = now - 4611h - 2160h = now - 6771h - # Tret(N) = now - 172h - 2160h = now - 2332h - # Trem(N) = now - 2h - 2160h = now - 2162h - # Tpub(N+1) = now - 175h - 2160h = now - 2335h - # Tact(N+1) = Tret(N) - # Tret(N+1) = now + 4292h - 2160h = now + 2132h - # Trem(N+1) = now + 4358h - 2160h = now + 2198h - TpubN="now-6796h" - TactN="now-6771h" - TretN="now-2332h" - TremN="now-2162h" - TpubN1="now-2335h" - TactN1="${TretN}" - TretN1="now+2132h" - TremN1="now+2198h" - keytimes="-P ${TpubN} -P sync ${TactN} -A ${TpubN} -I ${TretN} -D ${TremN} -D sync ${TactN1}" - newtimes="-P ${TpubN1} -P sync ${TactN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}" - CSK1=$($KEYGEN -k csk-roll2-$tld -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1) - CSK2=$($KEYGEN -k csk-roll2-$tld -l kasp.conf $newtimes $zone 2>keygen.out.$zone.2) - $SETTIME -s -g $H -k $U $TremN -r $U $TremN -d $H $TremN -z $H now-135h "$CSK1" >settime.out.$zone.1 2>&1 - $SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $O $TremN -z $O now-135h "$CSK2" >settime.out.$zone.2 2>&1 - # Set key rollover relationship. - key_successor $CSK1 $CSK2 - # Sign zone. - cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >>"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" - cp $infile $zonefile - $SIGNER -S -z -x -G "cdnskey,cds:sha-256,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 -done diff --git a/bin/tests/system/rollover-csk-roll2/tests_rollover_csk_roll2.py b/bin/tests/system/rollover-csk-roll2/tests_rollover_csk_roll2.py index 5a3ae2205f..529fd836ee 100644 --- a/bin/tests/system/rollover-csk-roll2/tests_rollover_csk_roll2.py +++ b/bin/tests/system/rollover-csk-roll2/tests_rollover_csk_roll2.py @@ -24,7 +24,11 @@ from rollover.common import ( size, TIMEDELTA, ) - +from rollover.setup import ( + configure_root, + configure_tld, + configure_cskroll2, +) CDSS = ["CDNSKEY", "CDS (SHA-256)", "CDS (SHA-384)"] CONFIG = { @@ -68,6 +72,30 @@ OFFSETS["step7-p"] = OFFSETS["step6-p"] - int(timedelta(days=90).total_seconds() OFFSETS["step7-s"] = OFFSETS["step6-s"] - int(timedelta(days=90).total_seconds()) +def bootstrap(): + data = { + "tlds": [], + "trust_anchors": [], + } + + tlds = [] + for tld_name in [ + "autosign", + "manual", + ]: + delegations = configure_cskroll2(tld_name, f"{POLICY}-{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", [ diff --git a/bin/tests/system/rollover/ns3/template.db.in b/bin/tests/system/rollover-dynamic2inline/ns3/dynamic2inline.kasp.db similarity index 100% rename from bin/tests/system/rollover/ns3/template.db.in rename to bin/tests/system/rollover-dynamic2inline/ns3/dynamic2inline.kasp.db diff --git a/bin/tests/system/rollover-dynamic2inline/ns3/named.common.conf.j2 b/bin/tests/system/rollover-dynamic2inline/ns3/named.common.conf.j2 new file mode 120000 index 0000000000..5dc26178cb --- /dev/null +++ b/bin/tests/system/rollover-dynamic2inline/ns3/named.common.conf.j2 @@ -0,0 +1 @@ +../../rollover/ns3/named.common.conf.j2 \ No newline at end of file diff --git a/bin/tests/system/rollover-dynamic2inline/ns6/named.conf.j2 b/bin/tests/system/rollover-dynamic2inline/ns3/named.conf.j2 similarity index 100% rename from bin/tests/system/rollover-dynamic2inline/ns6/named.conf.j2 rename to bin/tests/system/rollover-dynamic2inline/ns3/named.conf.j2 diff --git a/bin/tests/system/rollover-dynamic2inline/ns6/dynamic2inline.kasp.db b/bin/tests/system/rollover-dynamic2inline/ns6/dynamic2inline.kasp.db deleted file mode 120000 index f334748d7d..0000000000 --- a/bin/tests/system/rollover-dynamic2inline/ns6/dynamic2inline.kasp.db +++ /dev/null @@ -1 +0,0 @@ -./template.db.in \ No newline at end of file diff --git a/bin/tests/system/rollover-dynamic2inline/tests_rollover_dynamic2inline.py b/bin/tests/system/rollover-dynamic2inline/tests_rollover_dynamic2inline.py index 5570ce070f..7ec8591195 100644 --- a/bin/tests/system/rollover-dynamic2inline/tests_rollover_dynamic2inline.py +++ b/bin/tests/system/rollover-dynamic2inline/tests_rollover_dynamic2inline.py @@ -21,12 +21,12 @@ from rollover.common import ( ) -def test_dynamic2inline(alg, size, ns6, templates): +def test_dynamic2inline(alg, size, ns3, templates): config = DEFAULT_CONFIG policy = "default" zone = "dynamic2inline.kasp" - isctest.kasp.wait_keymgr_done(ns6, zone) + isctest.kasp.wait_keymgr_done(ns3, zone) step = { "zone": zone, @@ -37,10 +37,10 @@ def test_dynamic2inline(alg, size, ns6, templates): "nextev": None, } - isctest.kasp.check_rollover_step(ns6, config, policy, step) + isctest.kasp.check_rollover_step(ns3, config, policy, step) - templates.render("ns6/named.conf", {"change_lifetime": True}) - ns6.reconfigure() - isctest.kasp.wait_keymgr_done(ns6, zone, reconfig=True) + templates.render("ns3/named.conf", {"change_lifetime": True}) + ns3.reconfigure() + isctest.kasp.wait_keymgr_done(ns3, zone, reconfig=True) - isctest.kasp.check_rollover_step(ns6, config, policy, step) + isctest.kasp.check_rollover_step(ns3, config, policy, step) diff --git a/bin/tests/system/rollover-enable-dnssec/ns1 b/bin/tests/system/rollover-enable-dnssec/ns1 new file mode 120000 index 0000000000..76608beaed --- /dev/null +++ b/bin/tests/system/rollover-enable-dnssec/ns1 @@ -0,0 +1 @@ +../rollover/ns1 \ No newline at end of file diff --git a/bin/tests/system/rollover-enable-dnssec/ns2 b/bin/tests/system/rollover-enable-dnssec/ns2 new file mode 120000 index 0000000000..41a09bb648 --- /dev/null +++ b/bin/tests/system/rollover-enable-dnssec/ns2 @@ -0,0 +1 @@ +../rollover/ns2 \ No newline at end of file diff --git a/bin/tests/system/rollover-enable-dnssec/ns3/kasp.conf.j2 b/bin/tests/system/rollover-enable-dnssec/ns3/kasp.conf similarity index 89% rename from bin/tests/system/rollover-enable-dnssec/ns3/kasp.conf.j2 rename to bin/tests/system/rollover-enable-dnssec/ns3/kasp.conf index 1f0c0773d2..a3dacfeab3 100644 --- a/bin/tests/system/rollover-enable-dnssec/ns3/kasp.conf.j2 +++ b/bin/tests/system/rollover-enable-dnssec/ns3/kasp.conf @@ -26,7 +26,7 @@ dnssec-policy "enable-dnssec-autosign" { parent-ds-ttl 2h; keys { - csk lifetime unlimited algorithm @DEFAULT_ALGORITHM_NUMBER@; + csk lifetime unlimited algorithm 13; }; }; @@ -47,6 +47,6 @@ dnssec-policy "enable-dnssec-manual" { parent-ds-ttl 2h; keys { - csk lifetime unlimited algorithm @DEFAULT_ALGORITHM_NUMBER@; + csk lifetime unlimited algorithm 13; }; }; diff --git a/bin/tests/system/rollover-enable-dnssec/ns3/template.db.in b/bin/tests/system/rollover-enable-dnssec/ns3/template.db.in deleted file mode 120000 index ce6d526285..0000000000 --- a/bin/tests/system/rollover-enable-dnssec/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-enable-dnssec/ns3/template.db.j2.manual b/bin/tests/system/rollover-enable-dnssec/ns3/template.db.j2.manual new file mode 120000 index 0000000000..38619a01b2 --- /dev/null +++ b/bin/tests/system/rollover-enable-dnssec/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-enable-dnssec/ns3/trusted.conf.j2 b/bin/tests/system/rollover-enable-dnssec/ns3/trusted.conf.j2 new file mode 120000 index 0000000000..cb0be77b22 --- /dev/null +++ b/bin/tests/system/rollover-enable-dnssec/ns3/trusted.conf.j2 @@ -0,0 +1 @@ +../../_common/trusted.conf.j2 \ No newline at end of file diff --git a/bin/tests/system/rollover-enable-dnssec/setup.sh b/bin/tests/system/rollover-enable-dnssec/setup.sh deleted file mode 100644 index 17ee3a79f9..0000000000 --- a/bin/tests/system/rollover-enable-dnssec/setup.sh +++ /dev/null @@ -1,102 +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" - 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 enable-dnssec.$tld represent the various steps of the -# initial signing of a zone. -# - -for tld in autosign manual; do - # 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.$tld - cp template.db.in $zonefile - - # Step 2: - # The DNSKEY has been published long enough to become OMNIPRESENT. - setup step2.enable-dnssec.$tld - # 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-$tld -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.$tld - # 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-$tld -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.$tld - # 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-$tld -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 -done diff --git a/bin/tests/system/rollover-enable-dnssec/tests_rollover_enable_dnssec.py b/bin/tests/system/rollover-enable-dnssec/tests_rollover_enable_dnssec.py index ddcb6a5c79..23d47bdbb6 100644 --- a/bin/tests/system/rollover-enable-dnssec/tests_rollover_enable_dnssec.py +++ b/bin/tests/system/rollover-enable-dnssec/tests_rollover_enable_dnssec.py @@ -23,6 +23,11 @@ from rollover.common import ( CDSS, TIMEDELTA, ) +from rollover.setup import ( + configure_root, + configure_tld, + configure_enable_dnssec, +) CONFIG = { "dnskey-ttl": TIMEDELTA["PT5M"], @@ -47,6 +52,30 @@ OFFSETS["step3"] = -int(IRETZSK.total_seconds()) OFFSETS["step4"] = -int(IPUBC.total_seconds() + IRETKSK.total_seconds()) +def bootstrap(): + data = { + "tlds": [], + "trust_anchors": [], + } + + tlds = [] + for tld_name in [ + "autosign", + "manual", + ]: + delegations = configure_enable_dnssec(tld_name, f"{POLICY}-{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", [ diff --git a/bin/tests/system/rollover-going-insecure/ns1 b/bin/tests/system/rollover-going-insecure/ns1 new file mode 120000 index 0000000000..76608beaed --- /dev/null +++ b/bin/tests/system/rollover-going-insecure/ns1 @@ -0,0 +1 @@ +../rollover/ns1 \ No newline at end of file diff --git a/bin/tests/system/rollover-going-insecure/ns2 b/bin/tests/system/rollover-going-insecure/ns2 new file mode 120000 index 0000000000..41a09bb648 --- /dev/null +++ b/bin/tests/system/rollover-going-insecure/ns2 @@ -0,0 +1 @@ +../rollover/ns2 \ No newline at end of file diff --git a/bin/tests/system/rollover-going-insecure/ns6/kasp.conf.j2 b/bin/tests/system/rollover-going-insecure/ns3/kasp.conf similarity index 78% rename from bin/tests/system/rollover-going-insecure/ns6/kasp.conf.j2 rename to bin/tests/system/rollover-going-insecure/ns3/kasp.conf index 70a4323c7e..f04b692194 100644 --- a/bin/tests/system/rollover-going-insecure/ns6/kasp.conf.j2 +++ b/bin/tests/system/rollover-going-insecure/ns3/kasp.conf @@ -15,7 +15,7 @@ dnssec-policy "unsigning" { dnskey-ttl 7200; keys { - ksk key-directory lifetime unlimited algorithm @DEFAULT_ALGORITHM@; - zsk key-directory lifetime P60D algorithm @DEFAULT_ALGORITHM@; + ksk key-directory lifetime unlimited algorithm ecdsa256; + zsk key-directory lifetime P60D algorithm ecdsa256; }; }; diff --git a/bin/tests/system/rollover-going-insecure/ns3/named.common.conf.j2 b/bin/tests/system/rollover-going-insecure/ns3/named.common.conf.j2 new file mode 120000 index 0000000000..5dc26178cb --- /dev/null +++ b/bin/tests/system/rollover-going-insecure/ns3/named.common.conf.j2 @@ -0,0 +1 @@ +../../rollover/ns3/named.common.conf.j2 \ No newline at end of file diff --git a/bin/tests/system/rollover-going-insecure/ns6/named.conf.j2 b/bin/tests/system/rollover-going-insecure/ns3/named.conf.j2 similarity index 100% rename from bin/tests/system/rollover-going-insecure/ns6/named.conf.j2 rename to bin/tests/system/rollover-going-insecure/ns3/named.conf.j2 diff --git a/bin/tests/system/rollover-going-insecure/ns3/template.db.j2.manual b/bin/tests/system/rollover-going-insecure/ns3/template.db.j2.manual new file mode 120000 index 0000000000..38619a01b2 --- /dev/null +++ b/bin/tests/system/rollover-going-insecure/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-going-insecure/ns3/trusted.conf.j2 b/bin/tests/system/rollover-going-insecure/ns3/trusted.conf.j2 new file mode 120000 index 0000000000..cb0be77b22 --- /dev/null +++ b/bin/tests/system/rollover-going-insecure/ns3/trusted.conf.j2 @@ -0,0 +1 @@ +../../_common/trusted.conf.j2 \ No newline at end of file diff --git a/bin/tests/system/rollover-going-insecure/ns6/named.common.conf.j2 b/bin/tests/system/rollover-going-insecure/ns6/named.common.conf.j2 deleted file mode 120000 index 6b841ab2ad..0000000000 --- a/bin/tests/system/rollover-going-insecure/ns6/named.common.conf.j2 +++ /dev/null @@ -1 +0,0 @@ -../../rollover-dynamic2inline/ns6/named.common.conf.j2 \ No newline at end of file diff --git a/bin/tests/system/rollover-going-insecure/ns6/template.db.in b/bin/tests/system/rollover-going-insecure/ns6/template.db.in deleted file mode 120000 index 21598660d1..0000000000 --- a/bin/tests/system/rollover-going-insecure/ns6/template.db.in +++ /dev/null @@ -1 +0,0 @@ -../../rollover-dynamic2inline/ns6/template.db.in \ No newline at end of file diff --git a/bin/tests/system/rollover-going-insecure/setup.sh b/bin/tests/system/rollover-going-insecure/setup.sh deleted file mode 100644 index f5d9da48a7..0000000000 --- a/bin/tests/system/rollover-going-insecure/setup.sh +++ /dev/null @@ -1,71 +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 "ns6" - -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 child zones (step1, step2) beneath these zones represent the various -# steps of unsigning a zone. -for zn in going-insecure.kasp going-insecure-dynamic.kasp; do - # Step 1: - # Set up a zone with dnssec-policy that is going insecure. - setup step1.$zn - echo "$zone" >>zones - T="now-10d" - S="now-12955mi" - keytimes="-P $T -A $T" - cdstimes="-P sync $S" - KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $keytimes $cdstimes $zone 2>keygen.out.$zone.1) - ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 $keytimes $zone 2>keygen.out.$zone.2) - 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 -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - - # Step 2: - # Set up a zone with dnssec-policy that is going insecure. Don't add - # this zone to the zones file, because this zone is no longer expected - # to be fully signed. - setup step2.$zn - # The DS was withdrawn from the parent zone 26 hours ago. - D="now-26h" - keytimes="-P $T -A $T -I $D -D now" - cdstimes="-P sync $S -D sync $D" - KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $keytimes $cdstimes $zone 2>keygen.out.$zone.1) - ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 $keytimes $zone 2>keygen.out.$zone.2) - $SETTIME -s -g $H -k $O $T -r $O $T -d $U $D -D ds $D "$KSK" >settime.out.$zone.1 2>&1 - $SETTIME -s -g $H -k $O $T -z $O $T "$ZSK" >settime.out.$zone.2 2>&1 - # Fake lifetime of old algorithm keys. - echo "Lifetime: 0" >>"${KSK}.state" - echo "Lifetime: 5184000" >>"${ZSK}.state" - 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 -done diff --git a/bin/tests/system/rollover-going-insecure/tests_rollover_going_insecure_initial.py b/bin/tests/system/rollover-going-insecure/tests_rollover_going_insecure_initial.py index dbfb485c5a..92950124ed 100644 --- a/bin/tests/system/rollover-going-insecure/tests_rollover_going_insecure_initial.py +++ b/bin/tests/system/rollover-going-insecure/tests_rollover_going_insecure_initial.py @@ -22,6 +22,28 @@ from rollover.common import ( DURATION, UNSIGNING_CONFIG, ) +from rollover.setup import ( + configure_root, + configure_tld, + configure_going_insecure, +) + + +def bootstrap(): + data = { + "tlds": [], + "trust_anchors": [], + } + + tlds = [] + tld_name = "kasp" + delegations = configure_going_insecure(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,12 +53,12 @@ from rollover.common import ( "going-insecure-dynamic.kasp", ], ) -def test_going_insecure_initial(zone, ns6, alg, size): +def test_going_insecure_initial(zone, ns3, alg, size): config = UNSIGNING_CONFIG policy = "unsigning" zone = f"step1.{zone}" - isctest.kasp.wait_keymgr_done(ns6, zone) + isctest.kasp.wait_keymgr_done(ns3, zone) step = { "zone": zone, @@ -47,4 +69,4 @@ def test_going_insecure_initial(zone, ns6, alg, size): ], "nextev": None, } - isctest.kasp.check_rollover_step(ns6, config, policy, step) + isctest.kasp.check_rollover_step(ns3, config, policy, step) diff --git a/bin/tests/system/rollover-going-insecure/tests_rollover_going_insecure_reconfig.py b/bin/tests/system/rollover-going-insecure/tests_rollover_going_insecure_reconfig.py index f59940085d..5cd8d65816 100644 --- a/bin/tests/system/rollover-going-insecure/tests_rollover_going_insecure_reconfig.py +++ b/bin/tests/system/rollover-going-insecure/tests_rollover_going_insecure_reconfig.py @@ -23,12 +23,34 @@ from rollover.common import ( DURATION, UNSIGNING_CONFIG, ) +from rollover.setup import ( + configure_root, + configure_tld, + configure_going_insecure, +) + + +def bootstrap(): + data = { + "tlds": [], + "trust_anchors": [], + } + + tlds = [] + tld_name = "kasp" + delegations = configure_going_insecure(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(ns6, templates): - templates.render("ns6/named.conf", {"policy": "insecure"}) - ns6.reconfigure() # move from "unsigning" to "insecure" +def after_servers_start(ns3, templates): + templates.render("ns3/named.conf", {"policy": "insecure"}) + ns3.reconfigure() # move from "unsigning" to "insecure" @pytest.mark.parametrize( @@ -38,12 +60,12 @@ def after_servers_start(ns6, templates): "going-insecure-dynamic.kasp", ], ) -def test_going_insecure_reconfig_step1(zone, alg, size, ns6): +def test_going_insecure_reconfig_step1(zone, alg, size, ns3): config = DEFAULT_CONFIG policy = "insecure" zone = f"step1.{zone}" - isctest.kasp.wait_keymgr_done(ns6, zone, reconfig=True) + isctest.kasp.wait_keymgr_done(ns3, zone, reconfig=True) # Key goal states should be HIDDEN. # The DS may be removed if we are going insecure. @@ -61,7 +83,7 @@ def test_going_insecure_reconfig_step1(zone, alg, size, ns6): "cds-delete": True, "check-keytimes": False, } - isctest.kasp.check_rollover_step(ns6, config, policy, step) + isctest.kasp.check_rollover_step(ns3, config, policy, step) @pytest.mark.parametrize( @@ -71,12 +93,12 @@ def test_going_insecure_reconfig_step1(zone, alg, size, ns6): "going-insecure-dynamic.kasp", ], ) -def test_going_insecure_reconfig_step2(zone, alg, size, ns6): +def test_going_insecure_reconfig_step2(zone, alg, size, ns3): config = DEFAULT_CONFIG policy = "insecure" zone = f"step2.{zone}" - isctest.kasp.wait_keymgr_done(ns6, zone, reconfig=True) + isctest.kasp.wait_keymgr_done(ns3, zone, reconfig=True) # The DS is long enough removed from the zone to be considered # HIDDEN. This means the DNSKEY and the KSK signatures can be @@ -96,4 +118,4 @@ def test_going_insecure_reconfig_step2(zone, alg, size, ns6): "zone-signed": False, "check-keytimes": False, } - isctest.kasp.check_rollover_step(ns6, config, policy, step) + isctest.kasp.check_rollover_step(ns3, config, policy, step) diff --git a/bin/tests/system/rollover-ksk-3crowd/ns1 b/bin/tests/system/rollover-ksk-3crowd/ns1 new file mode 120000 index 0000000000..76608beaed --- /dev/null +++ b/bin/tests/system/rollover-ksk-3crowd/ns1 @@ -0,0 +1 @@ +../rollover/ns1 \ No newline at end of file diff --git a/bin/tests/system/rollover-ksk-3crowd/ns2 b/bin/tests/system/rollover-ksk-3crowd/ns2 new file mode 120000 index 0000000000..41a09bb648 --- /dev/null +++ b/bin/tests/system/rollover-ksk-3crowd/ns2 @@ -0,0 +1 @@ +../rollover/ns2 \ No newline at end of file diff --git a/bin/tests/system/rollover-ksk-3crowd/ns3/kasp.conf b/bin/tests/system/rollover-ksk-3crowd/ns3/kasp.conf new file mode 120000 index 0000000000..ca6c7139f3 --- /dev/null +++ b/bin/tests/system/rollover-ksk-3crowd/ns3/kasp.conf @@ -0,0 +1 @@ +../../rollover-ksk-doubleksk/ns3/kasp.conf \ No newline at end of file diff --git a/bin/tests/system/rollover-ksk-3crowd/ns3/kasp.conf.j2 b/bin/tests/system/rollover-ksk-3crowd/ns3/kasp.conf.j2 deleted file mode 120000 index 138fa68939..0000000000 --- a/bin/tests/system/rollover-ksk-3crowd/ns3/kasp.conf.j2 +++ /dev/null @@ -1 +0,0 @@ -../../rollover-ksk-doubleksk/ns3/kasp.conf.j2 \ No newline at end of file diff --git a/bin/tests/system/rollover-ksk-3crowd/ns3/template.db.in b/bin/tests/system/rollover-ksk-3crowd/ns3/template.db.in deleted file mode 120000 index ce6d526285..0000000000 --- a/bin/tests/system/rollover-ksk-3crowd/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-ksk-3crowd/ns3/template.db.j2.manual b/bin/tests/system/rollover-ksk-3crowd/ns3/template.db.j2.manual new file mode 120000 index 0000000000..38619a01b2 --- /dev/null +++ b/bin/tests/system/rollover-ksk-3crowd/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-ksk-3crowd/ns3/trusted.conf.j2 b/bin/tests/system/rollover-ksk-3crowd/ns3/trusted.conf.j2 new file mode 120000 index 0000000000..cb0be77b22 --- /dev/null +++ b/bin/tests/system/rollover-ksk-3crowd/ns3/trusted.conf.j2 @@ -0,0 +1 @@ +../../_common/trusted.conf.j2 \ No newline at end of file diff --git a/bin/tests/system/rollover-ksk-3crowd/setup.sh b/bin/tests/system/rollover-ksk-3crowd/setup.sh deleted file mode 100644 index 558c77b430..0000000000 --- a/bin/tests/system/rollover-ksk-3crowd/setup.sh +++ /dev/null @@ -1,82 +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" - 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" - -# Test #2375, the "three is a crowd" bug, where a new key is introduced but the -# previous rollover has not finished yet. In other words, we have a key KEY2 -# that is the successor of key KEY1, and we introduce a new key KEY3 that is -# the successor of key KEY2: -# -# KEY1 < KEY2 < KEY3. -# -# The expected behavior is that all three keys remain in the zone, and not -# the bug behavior where KEY2 is removed and immediately replaced with KEY3. -# -# Set up a zone that has a KSK (KEY1) and have the successor key (KEY2) -# published as well. -setup three-is-a-crowd.kasp -# These times are the same as step3.ksk-doubleksk.autosign. -TpubN="now-60d" -TactN="now-1413h" -TretN="now" -TremN="now+50h" -TpubN1="now-27h" -TsbmN1="now" -TactN1="${TretN}" -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 ${TsbmN1} -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 $O $TactN "$KSK1" >settime.out.$zone.1 2>&1 -$SETTIME -s -g $O -k $R $TpubN1 -r $R $TpubN1 -d $H $TpubN1 "$KSK2" >settime.out.$zone.2 2>&1 -$SETTIME -s -g $O -k $O $TactN -z $O $TactN "$ZSK" >settime.out.$zone.3 2>&1 -# Set key rollover relationship. -key_successor $KSK1 $KSK2 -# Sign zone. -cat template.db.in "${KSK1}.key" "${KSK2}.key" "${ZSK}.key" >"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK1" >>"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile" -cp $infile $zonefile -$SIGNER -S -x -G "cds:sha-256" -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 diff --git a/bin/tests/system/rollover-ksk-3crowd/tests_rollover_three_is_a_crowd.py b/bin/tests/system/rollover-ksk-3crowd/tests_rollover_three_is_a_crowd.py index 7fb3fce835..8ced405fbc 100644 --- a/bin/tests/system/rollover-ksk-3crowd/tests_rollover_three_is_a_crowd.py +++ b/bin/tests/system/rollover-ksk-3crowd/tests_rollover_three_is_a_crowd.py @@ -24,6 +24,11 @@ from rollover.common import ( KSK_IPUB, KSK_IRET, ) +from rollover.setup import ( + configure_root, + configure_tld, + configure_ksk_3crowd, +) CDSS = ["CDS (SHA-256)"] @@ -33,6 +38,23 @@ OFFSET2 = -int(timedelta(hours=27).total_seconds()) TTL = int(KSK_CONFIG["dnskey-ttl"].total_seconds()) +def bootstrap(): + data = { + "tlds": [], + "trust_anchors": [], + } + + tlds = [] + tld_name = "kasp" + delegations = configure_ksk_3crowd(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 + + def test_rollover_ksk_three_is_a_crowd(alg, size, ns3): """Test #2375: Scheduled rollovers are happening faster than they can finish.""" zone = "three-is-a-crowd.kasp" diff --git a/bin/tests/system/rollover-ksk-doubleksk/ns1 b/bin/tests/system/rollover-ksk-doubleksk/ns1 new file mode 120000 index 0000000000..76608beaed --- /dev/null +++ b/bin/tests/system/rollover-ksk-doubleksk/ns1 @@ -0,0 +1 @@ +../rollover/ns1 \ No newline at end of file diff --git a/bin/tests/system/rollover-ksk-doubleksk/ns2 b/bin/tests/system/rollover-ksk-doubleksk/ns2 new file mode 120000 index 0000000000..41a09bb648 --- /dev/null +++ b/bin/tests/system/rollover-ksk-doubleksk/ns2 @@ -0,0 +1 @@ +../rollover/ns2 \ No newline at end of file diff --git a/bin/tests/system/rollover-ksk-doubleksk/ns3/kasp.conf.j2 b/bin/tests/system/rollover-ksk-doubleksk/ns3/kasp.conf similarity index 80% rename from bin/tests/system/rollover-ksk-doubleksk/ns3/kasp.conf.j2 rename to bin/tests/system/rollover-ksk-doubleksk/ns3/kasp.conf index c33a9f7c40..5d0643b421 100644 --- a/bin/tests/system/rollover-ksk-doubleksk/ns3/kasp.conf.j2 +++ b/bin/tests/system/rollover-ksk-doubleksk/ns3/kasp.conf @@ -23,8 +23,8 @@ dnssec-policy "ksk-doubleksk-autosign" { 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; @@ -48,8 +48,8 @@ dnssec-policy "ksk-doubleksk-manual" { 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; diff --git a/bin/tests/system/rollover-ksk-doubleksk/ns3/template.db.in b/bin/tests/system/rollover-ksk-doubleksk/ns3/template.db.in deleted file mode 120000 index ce6d526285..0000000000 --- a/bin/tests/system/rollover-ksk-doubleksk/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-ksk-doubleksk/ns3/template.db.j2.manual b/bin/tests/system/rollover-ksk-doubleksk/ns3/template.db.j2.manual new file mode 120000 index 0000000000..38619a01b2 --- /dev/null +++ b/bin/tests/system/rollover-ksk-doubleksk/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-ksk-doubleksk/ns3/trusted.conf.j2 b/bin/tests/system/rollover-ksk-doubleksk/ns3/trusted.conf.j2 new file mode 120000 index 0000000000..cb0be77b22 --- /dev/null +++ b/bin/tests/system/rollover-ksk-doubleksk/ns3/trusted.conf.j2 @@ -0,0 +1 @@ +../../_common/trusted.conf.j2 \ No newline at end of file diff --git a/bin/tests/system/rollover-ksk-doubleksk/setup.sh b/bin/tests/system/rollover-ksk-doubleksk/setup.sh deleted file mode 100644 index cfd654bffd..0000000000 --- a/bin/tests/system/rollover-ksk-doubleksk/setup.sh +++ /dev/null @@ -1,243 +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" - 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 diff --git a/bin/tests/system/rollover-ksk-doubleksk/tests_rollover_ksk_doubleksk.py b/bin/tests/system/rollover-ksk-doubleksk/tests_rollover_ksk_doubleksk.py index 26653a6b53..0eaa236b6d 100644 --- a/bin/tests/system/rollover-ksk-doubleksk/tests_rollover_ksk_doubleksk.py +++ b/bin/tests/system/rollover-ksk-doubleksk/tests_rollover_ksk_doubleksk.py @@ -30,7 +30,11 @@ from rollover.common import ( KSK_KEYTTLPROP, TIMEDELTA, ) - +from rollover.setup import ( + configure_root, + configure_tld, + configure_ksk_doubleksk, +) CDSS = ["CDS (SHA-256)"] POLICY = "ksk-doubleksk" @@ -48,6 +52,30 @@ OFFSETS["step6-p"] = OFFSETS["step5-p"] - int(KSK_CONFIG["purge-keys"].total_sec 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", [ diff --git a/bin/tests/system/rollover-lifetime/ns6/kasp.conf.j2 b/bin/tests/system/rollover-lifetime/ns3/kasp.conf.j2 similarity index 100% rename from bin/tests/system/rollover-lifetime/ns6/kasp.conf.j2 rename to bin/tests/system/rollover-lifetime/ns3/kasp.conf.j2 diff --git a/bin/tests/system/rollover-lifetime/ns3/limit-lifetime.db b/bin/tests/system/rollover-lifetime/ns3/limit-lifetime.db new file mode 120000 index 0000000000..e9d5917b1f --- /dev/null +++ b/bin/tests/system/rollover-lifetime/ns3/limit-lifetime.db @@ -0,0 +1 @@ +template.db.in \ No newline at end of file diff --git a/bin/tests/system/rollover-lifetime/ns3/longer-lifetime.db b/bin/tests/system/rollover-lifetime/ns3/longer-lifetime.db new file mode 120000 index 0000000000..e9d5917b1f --- /dev/null +++ b/bin/tests/system/rollover-lifetime/ns3/longer-lifetime.db @@ -0,0 +1 @@ +template.db.in \ No newline at end of file diff --git a/bin/tests/system/rollover-lifetime/ns3/named.common.conf.j2 b/bin/tests/system/rollover-lifetime/ns3/named.common.conf.j2 new file mode 120000 index 0000000000..5dc26178cb --- /dev/null +++ b/bin/tests/system/rollover-lifetime/ns3/named.common.conf.j2 @@ -0,0 +1 @@ +../../rollover/ns3/named.common.conf.j2 \ No newline at end of file diff --git a/bin/tests/system/rollover-lifetime/ns6/named.conf.j2 b/bin/tests/system/rollover-lifetime/ns3/named.conf.j2 similarity index 91% rename from bin/tests/system/rollover-lifetime/ns6/named.conf.j2 rename to bin/tests/system/rollover-lifetime/ns3/named.conf.j2 index 75b38db728..7adfbda12d 100644 --- a/bin/tests/system/rollover-lifetime/ns6/named.conf.j2 +++ b/bin/tests/system/rollover-lifetime/ns3/named.conf.j2 @@ -20,25 +20,25 @@ include "kasp.conf"; include "named.common.conf"; -zone longer-lifetime { +zone longer-lifetime.kasp { type primary; file "longer-lifetime.db"; dnssec-policy @longer@; }; -zone shorter-lifetime { +zone shorter-lifetime.kasp { type primary; file "shorter-lifetime.db"; dnssec-policy @shorter@; }; -zone limit-lifetime { +zone limit-lifetime.kasp { type primary; file "limit-lifetime.db"; dnssec-policy @limit@; }; -zone unlimit-lifetime { +zone unlimit-lifetime.kasp { type primary; file "unlimit-lifetime.db"; dnssec-policy @unlimit@; diff --git a/bin/tests/system/rollover-lifetime/ns3/shorter-lifetime.db b/bin/tests/system/rollover-lifetime/ns3/shorter-lifetime.db new file mode 120000 index 0000000000..e9d5917b1f --- /dev/null +++ b/bin/tests/system/rollover-lifetime/ns3/shorter-lifetime.db @@ -0,0 +1 @@ +template.db.in \ No newline at end of file diff --git a/bin/tests/system/rollover-dynamic2inline/ns6/template.db.in b/bin/tests/system/rollover-lifetime/ns3/template.db.in similarity index 95% rename from bin/tests/system/rollover-dynamic2inline/ns6/template.db.in rename to bin/tests/system/rollover-lifetime/ns3/template.db.in index f1d8b94e5a..010b05b3cb 100644 --- a/bin/tests/system/rollover-dynamic2inline/ns6/template.db.in +++ b/bin/tests/system/rollover-lifetime/ns3/template.db.in @@ -18,8 +18,8 @@ $TTL 300 3600 ; minimum (1 hour) ) - NS ns6 -ns6 A 10.53.0.6 + NS ns3 +ns3 A 10.53.0.3 a A 10.0.0.1 b A 10.0.0.2 diff --git a/bin/tests/system/rollover-lifetime/ns3/unlimit-lifetime.db b/bin/tests/system/rollover-lifetime/ns3/unlimit-lifetime.db new file mode 120000 index 0000000000..e9d5917b1f --- /dev/null +++ b/bin/tests/system/rollover-lifetime/ns3/unlimit-lifetime.db @@ -0,0 +1 @@ +template.db.in \ No newline at end of file diff --git a/bin/tests/system/rollover-lifetime/ns6/limit-lifetime.db b/bin/tests/system/rollover-lifetime/ns6/limit-lifetime.db deleted file mode 120000 index 21598660d1..0000000000 --- a/bin/tests/system/rollover-lifetime/ns6/limit-lifetime.db +++ /dev/null @@ -1 +0,0 @@ -../../rollover-dynamic2inline/ns6/template.db.in \ No newline at end of file diff --git a/bin/tests/system/rollover-lifetime/ns6/longer-lifetime.db b/bin/tests/system/rollover-lifetime/ns6/longer-lifetime.db deleted file mode 120000 index 21598660d1..0000000000 --- a/bin/tests/system/rollover-lifetime/ns6/longer-lifetime.db +++ /dev/null @@ -1 +0,0 @@ -../../rollover-dynamic2inline/ns6/template.db.in \ No newline at end of file diff --git a/bin/tests/system/rollover-lifetime/ns6/named.common.conf.j2 b/bin/tests/system/rollover-lifetime/ns6/named.common.conf.j2 deleted file mode 120000 index 6b841ab2ad..0000000000 --- a/bin/tests/system/rollover-lifetime/ns6/named.common.conf.j2 +++ /dev/null @@ -1 +0,0 @@ -../../rollover-dynamic2inline/ns6/named.common.conf.j2 \ No newline at end of file diff --git a/bin/tests/system/rollover-lifetime/ns6/shorter-lifetime.db b/bin/tests/system/rollover-lifetime/ns6/shorter-lifetime.db deleted file mode 120000 index 21598660d1..0000000000 --- a/bin/tests/system/rollover-lifetime/ns6/shorter-lifetime.db +++ /dev/null @@ -1 +0,0 @@ -../../rollover-dynamic2inline/ns6/template.db.in \ No newline at end of file diff --git a/bin/tests/system/rollover-lifetime/ns6/unlimit-lifetime.db b/bin/tests/system/rollover-lifetime/ns6/unlimit-lifetime.db deleted file mode 120000 index 21598660d1..0000000000 --- a/bin/tests/system/rollover-lifetime/ns6/unlimit-lifetime.db +++ /dev/null @@ -1 +0,0 @@ -../../rollover-dynamic2inline/ns6/template.db.in \ No newline at end of file diff --git a/bin/tests/system/rollover-lifetime/tests_rollover_lifetime_initial.py b/bin/tests/system/rollover-lifetime/tests_rollover_lifetime_initial.py index 55478d86bc..a7f5ead0fa 100644 --- a/bin/tests/system/rollover-lifetime/tests_rollover_lifetime_initial.py +++ b/bin/tests/system/rollover-lifetime/tests_rollover_lifetime_initial.py @@ -34,17 +34,17 @@ from rollover.common import ( param("unlimit-lifetime", "short-lifetime", "P6M"), ], ) -def test_lifetime_initial(zone, policy, lifetime, alg, size, ns6): +def test_lifetime_initial(zone, policy, lifetime, alg, size, ns3): config = DEFAULT_CONFIG - isctest.kasp.wait_keymgr_done(ns6, zone) + isctest.kasp.wait_keymgr_done(ns3, f"{zone}.kasp") step = { - "zone": zone, + "zone": f"{zone}.kasp", "cdss": CDSS, "keyprops": [ f"csk {DURATION[lifetime]} {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured zrrsig:rumoured ds:hidden", ], "nextev": None, } - isctest.kasp.check_rollover_step(ns6, config, policy, step) + isctest.kasp.check_rollover_step(ns3, config, policy, step) diff --git a/bin/tests/system/rollover-lifetime/tests_rollover_lifetime_reconfig.py b/bin/tests/system/rollover-lifetime/tests_rollover_lifetime_reconfig.py index 9462f1ad97..d28a7e4cd5 100644 --- a/bin/tests/system/rollover-lifetime/tests_rollover_lifetime_reconfig.py +++ b/bin/tests/system/rollover-lifetime/tests_rollover_lifetime_reconfig.py @@ -26,14 +26,14 @@ from rollover.common import ( @pytest.fixture(scope="module", autouse=True) -def after_servers_start(ns6, templates): - isctest.kasp.wait_keymgr_done(ns6, "shorter-lifetime") - isctest.kasp.wait_keymgr_done(ns6, "longer-lifetime") - isctest.kasp.wait_keymgr_done(ns6, "limit-lifetime") - isctest.kasp.wait_keymgr_done(ns6, "unlimit-lifetime") +def after_servers_start(ns3, templates): + isctest.kasp.wait_keymgr_done(ns3, "shorter-lifetime.kasp") + isctest.kasp.wait_keymgr_done(ns3, "longer-lifetime.kasp") + isctest.kasp.wait_keymgr_done(ns3, "limit-lifetime.kasp") + isctest.kasp.wait_keymgr_done(ns3, "unlimit-lifetime.kasp") - templates.render("ns6/named.conf", {"change_lifetime": True}) - ns6.reconfigure() + templates.render("ns3/named.conf", {"change_lifetime": True}) + ns3.reconfigure() @pytest.mark.parametrize( @@ -49,17 +49,17 @@ def after_servers_start(ns6, templates): param("unlimit-lifetime", "unlimited-lifetime", 0), ], ) -def test_lifetime_reconfig(zone, policy, lifetime, alg, size, ns6): +def test_lifetime_reconfig(zone, policy, lifetime, alg, size, ns3): config = DEFAULT_CONFIG - isctest.kasp.wait_keymgr_done(ns6, zone, reconfig=True) + isctest.kasp.wait_keymgr_done(ns3, f"{zone}.kasp", reconfig=True) step = { - "zone": zone, + "zone": f"{zone}.kasp", "cdss": CDSS, "keyprops": [ f"csk {DURATION[lifetime]} {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured zrrsig:rumoured ds:hidden", ], "nextev": None, } - isctest.kasp.check_rollover_step(ns6, config, policy, step) + isctest.kasp.check_rollover_step(ns3, config, policy, step) diff --git a/bin/tests/system/rollover-multisigner/ns3/template.db.in b/bin/tests/system/rollover-multisigner/ns3/template.db.in deleted file mode 120000 index ce6d526285..0000000000 --- a/bin/tests/system/rollover-multisigner/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-multisigner/ns3/template.db.in b/bin/tests/system/rollover-multisigner/ns3/template.db.in new file mode 100644 index 0000000000..010b05b3cb --- /dev/null +++ b/bin/tests/system/rollover-multisigner/ns3/template.db.in @@ -0,0 +1,27 @@ +; 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. + +$TTL 300 +@ IN SOA mname1. . ( + 1 ; serial + 20 ; refresh (20 seconds) + 20 ; retry (20 seconds) + 1814400 ; expire (3 weeks) + 3600 ; minimum (1 hour) + ) + + NS ns3 +ns3 A 10.53.0.3 + +a A 10.0.0.1 +b A 10.0.0.2 +c A 10.0.0.3 + diff --git a/bin/tests/system/rollover-multisigner/ns3/template.db.j2.manual b/bin/tests/system/rollover-multisigner/ns3/template.db.j2.manual new file mode 120000 index 0000000000..38619a01b2 --- /dev/null +++ b/bin/tests/system/rollover-multisigner/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-multisigner/setup.sh b/bin/tests/system/rollover-multisigner/setup.sh deleted file mode 100644 index d9937adb08..0000000000 --- a/bin/tests/system/rollover-multisigner/setup.sh +++ /dev/null @@ -1,67 +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" - 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" - -# Multi-signer zones. -setup "multisigner-model2.kasp" -cp template.db.in "$zonefile" -KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -f KSK -L 3600 -M 32768:65535 $zone 2>keygen.out.$zone.1) -ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -M 32768:65535 $zone 2>keygen.out.$zone.2) -cat "${KSK}.key" | grep -v ";.*" >>"${zone}.db" -cat "${ZSK}.key" | grep -v ";.*" >>"${zone}.db" -# Import a ZSK of another provider into the DNSKEY RRset. -ZSK1=$($KEYGEN -K ../ -a $DEFAULT_ALGORITHM -L 3600 -M 0:32767 $zone 2>keygen.out.$zone.3) -cat "../${ZSK1}.key" | grep -v ";.*" >>"${zone}.db" - -# We are changing an existing single-signed zone to multi-signed -# zone where the key tags do not match the dnssec-policy key tag range -setup single-to-multisigner.kasp -T="now-7d" -S="now-8635mi" # T - 1d5m -keytimes="-P $T -A $T" -cdstimes="-P sync $S" -KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -M 0:32767 -L 3600 -f KSK $keytimes $cdstimes $zone 2>keygen.out.$zone.1) -ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -M 0:32767 -L 3600 $keytimes $zone 2>keygen.out.$zone.2) -$SETTIME -s -g $O -d $O $T -k $O $T -r $O $T "$KSK" >settime.out.$zone.1 2>&1 -$SETTIME -s -g $O -k $O $T -z $O $T "$ZSK" >settime.out.$zone.2 2>&1 -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 diff --git a/bin/tests/system/rollover-multisigner/tests_rollover_multisigner.py b/bin/tests/system/rollover-multisigner/tests_rollover_multisigner.py index 9c4cc47b8b..517992cbde 100644 --- a/bin/tests/system/rollover-multisigner/tests_rollover_multisigner.py +++ b/bin/tests/system/rollover-multisigner/tests_rollover_multisigner.py @@ -21,11 +21,76 @@ import dns.update import isctest from isctest.kasp import Iret +from isctest.run import EnvCmd from rollover.common import ( pytestmark, alg, size, ) +from rollover.setup import fake_lifetime, render_and_sign_zone + + +def bootstrap(): + templates = isctest.template.TemplateEngine(".") + + # Multi-signer zones. + keygen = EnvCmd("KEYGEN", "-a ECDSA256 -L 3600") + settime = EnvCmd("SETTIME", "-s") + + # Model 2. + zonename = "multisigner-model2.kasp" + isctest.log.info(f"setup {zonename}") + # Key generation. + ksk_name = keygen(f"-M 32768:65535 -f KSK {zonename}", cwd="ns3").out.strip() + zsk_name = keygen(f"-M 32768:65535 {zonename}", cwd="ns3").out.strip() + # Signing. + dnskeys = [] + for key_name in [ksk_name, zsk_name]: + key = isctest.kasp.Key(key_name, keydir="ns3") + dnskeys.append(key.dnskey) + # Import a ZSK of another provider into the DNSKEY RRset. + zsk_extra = keygen(f"-M 0:32767 {zonename}").out.strip() + key = isctest.kasp.Key(zsk_extra) + dnskeys.append(key.dnskey) + # Render zone file. + outfile = f"{zonename}.db" + templates = isctest.template.TemplateEngine(".") + template = "template.db.j2.manual" + tdata = { + "fqdn": f"{zonename}.", + "dnskeys": dnskeys, + "privaterrs": [], + } + templates.render(f"ns3/{outfile}", tdata, template=f"ns3/{template}") + + # We are changing an existing single-signed zone to multi-signed + # zone where the key tags do not match the dnssec-policy key tag range + zonename = "single-to-multisigner.kasp" + isctest.log.info(f"setup {zonename}") + # Timing metadata. + TpubN = "now-7d" + TsbmN = "now-8635mi" # T - 1d5m + keytimes = f"-P {TpubN} -A {TpubN}" + cdstimes = f"-P sync {TsbmN}" + # Key generation. + ksk_name = keygen( + f"-M 0:32767 -f KSK {keytimes} {cdstimes} {zonename}", cwd="ns3" + ).out.strip() + zsk_name = keygen(f"-M 0:32767 {keytimes} {zonename}", cwd="ns3").out.strip() + settime( + f"-g OMNIPRESENT -d OMNIPRESENT {TpubN} -k OMNIPRESENT {TpubN} -r OMNIPRESENT {TpubN} {ksk_name}", + cwd="ns3", + ) + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TpubN} -z OMNIPRESENT {TpubN} {zsk_name}", + cwd="ns3", + ) + # Signing. + fake_lifetime(ksk_name, 0) + fake_lifetime(zsk_name, 0) + render_and_sign_zone(zonename, [ksk_name, zsk_name]) + + return {} def test_rollover_multisigner(ns3, alg, size): diff --git a/bin/tests/system/rollover-straight2none/ns1 b/bin/tests/system/rollover-straight2none/ns1 new file mode 120000 index 0000000000..76608beaed --- /dev/null +++ b/bin/tests/system/rollover-straight2none/ns1 @@ -0,0 +1 @@ +../rollover/ns1 \ No newline at end of file diff --git a/bin/tests/system/rollover-straight2none/ns2 b/bin/tests/system/rollover-straight2none/ns2 new file mode 120000 index 0000000000..41a09bb648 --- /dev/null +++ b/bin/tests/system/rollover-straight2none/ns2 @@ -0,0 +1 @@ +../rollover/ns2 \ No newline at end of file diff --git a/bin/tests/system/rollover-straight2none/ns3/kasp.conf b/bin/tests/system/rollover-straight2none/ns3/kasp.conf new file mode 120000 index 0000000000..647bd04b4d --- /dev/null +++ b/bin/tests/system/rollover-straight2none/ns3/kasp.conf @@ -0,0 +1 @@ +../../rollover-going-insecure/ns3/kasp.conf \ No newline at end of file diff --git a/bin/tests/system/rollover-straight2none/ns3/named.common.conf.j2 b/bin/tests/system/rollover-straight2none/ns3/named.common.conf.j2 new file mode 120000 index 0000000000..5dc26178cb --- /dev/null +++ b/bin/tests/system/rollover-straight2none/ns3/named.common.conf.j2 @@ -0,0 +1 @@ +../../rollover/ns3/named.common.conf.j2 \ No newline at end of file diff --git a/bin/tests/system/rollover-straight2none/ns6/named.conf.j2 b/bin/tests/system/rollover-straight2none/ns3/named.conf.j2 similarity index 100% rename from bin/tests/system/rollover-straight2none/ns6/named.conf.j2 rename to bin/tests/system/rollover-straight2none/ns3/named.conf.j2 diff --git a/bin/tests/system/rollover-straight2none/ns3/template.db.j2.manual b/bin/tests/system/rollover-straight2none/ns3/template.db.j2.manual new file mode 120000 index 0000000000..38619a01b2 --- /dev/null +++ b/bin/tests/system/rollover-straight2none/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-straight2none/ns3/trusted.conf.j2 b/bin/tests/system/rollover-straight2none/ns3/trusted.conf.j2 new file mode 120000 index 0000000000..cb0be77b22 --- /dev/null +++ b/bin/tests/system/rollover-straight2none/ns3/trusted.conf.j2 @@ -0,0 +1 @@ +../../_common/trusted.conf.j2 \ No newline at end of file diff --git a/bin/tests/system/rollover-straight2none/ns6/kasp.conf.j2 b/bin/tests/system/rollover-straight2none/ns6/kasp.conf.j2 deleted file mode 120000 index 4a8da1d446..0000000000 --- a/bin/tests/system/rollover-straight2none/ns6/kasp.conf.j2 +++ /dev/null @@ -1 +0,0 @@ -../../rollover-going-insecure/ns6/kasp.conf.j2 \ No newline at end of file diff --git a/bin/tests/system/rollover-straight2none/ns6/named.common.conf.j2 b/bin/tests/system/rollover-straight2none/ns6/named.common.conf.j2 deleted file mode 120000 index 6b841ab2ad..0000000000 --- a/bin/tests/system/rollover-straight2none/ns6/named.common.conf.j2 +++ /dev/null @@ -1 +0,0 @@ -../../rollover-dynamic2inline/ns6/named.common.conf.j2 \ No newline at end of file diff --git a/bin/tests/system/rollover-straight2none/ns6/template.db.in b/bin/tests/system/rollover-straight2none/ns6/template.db.in deleted file mode 120000 index 21598660d1..0000000000 --- a/bin/tests/system/rollover-straight2none/ns6/template.db.in +++ /dev/null @@ -1 +0,0 @@ -../../rollover-dynamic2inline/ns6/template.db.in \ No newline at end of file diff --git a/bin/tests/system/rollover-straight2none/setup.sh b/bin/tests/system/rollover-straight2none/setup.sh deleted file mode 100644 index 2a42dba557..0000000000 --- a/bin/tests/system/rollover-straight2none/setup.sh +++ /dev/null @@ -1,53 +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 "ns6" - -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" - -# These zones are going straight to "none" policy. This is undefined behavior. -T="now-10d" -S="now-12955mi" -csktimes="-P $T -A $T -P sync $S" - -setup going-straight-to-none.kasp -echo "$zone" >>zones -CSK=$($KEYGEN -k default $csktimes $zone 2>keygen.out.$zone.1) -$SETTIME -s -g $O -k $O $TactN -z $O $TactN -r $O $TactN -d $O $TactN "$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+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - -setup going-straight-to-none-dynamic.kasp -echo "$zone" >>zones -CSK=$($KEYGEN -k default $csktimes $zone 2>keygen.out.$zone.1) -$SETTIME -s -g $O -k $O $TactN -z $O $TactN -r $O $TactN -d $O $TactN "$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+2w -o $zone -O full -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 diff --git a/bin/tests/system/rollover-straight2none/tests_rollver_straight2none_initial.py b/bin/tests/system/rollover-straight2none/tests_rollover_straight2none_initial.py similarity index 63% rename from bin/tests/system/rollover-straight2none/tests_rollver_straight2none_initial.py rename to bin/tests/system/rollover-straight2none/tests_rollover_straight2none_initial.py index 1d5a108d2a..c38e5ddd49 100644 --- a/bin/tests/system/rollover-straight2none/tests_rollver_straight2none_initial.py +++ b/bin/tests/system/rollover-straight2none/tests_rollover_straight2none_initial.py @@ -22,6 +22,28 @@ from rollover.common import ( DURATION, DEFAULT_CONFIG, ) +from rollover.setup import ( + configure_root, + configure_tld, + configure_straight2none, +) + + +def bootstrap(): + data = { + "tlds": [], + "trust_anchors": [], + } + + tlds = [] + tld_name = "kasp" + delegations = configure_straight2none(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( @@ -31,11 +53,11 @@ from rollover.common import ( "going-straight-to-none-dynamic.kasp", ], ) -def test_straight2none_initial(zone, ns6, alg, size): +def test_straight2none_initial(zone, ns3, alg, size): config = DEFAULT_CONFIG policy = "default" - isctest.kasp.wait_keymgr_done(ns6, zone) + isctest.kasp.wait_keymgr_done(ns3, zone) step = { "zone": zone, @@ -45,4 +67,4 @@ def test_straight2none_initial(zone, ns6, alg, size): ], "nextev": None, } - isctest.kasp.check_rollover_step(ns6, config, policy, step) + isctest.kasp.check_rollover_step(ns3, config, policy, step) diff --git a/bin/tests/system/rollover-straight2none/tests_rollver_straight2none_reconfig.py b/bin/tests/system/rollover-straight2none/tests_rollover_straight2none_reconfig.py similarity index 59% rename from bin/tests/system/rollover-straight2none/tests_rollver_straight2none_reconfig.py rename to bin/tests/system/rollover-straight2none/tests_rollover_straight2none_reconfig.py index dc1fbf2219..5cfb49653b 100644 --- a/bin/tests/system/rollover-straight2none/tests_rollver_straight2none_reconfig.py +++ b/bin/tests/system/rollover-straight2none/tests_rollover_straight2none_reconfig.py @@ -22,15 +22,37 @@ from rollover.common import ( DURATION, DEFAULT_CONFIG, ) +from rollover.setup import ( + configure_root, + configure_tld, + configure_straight2none, +) + + +def bootstrap(): + data = { + "tlds": [], + "trust_anchors": [], + } + + tlds = [] + tld_name = "kasp" + delegations = configure_straight2none(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.fixture(scope="module", autouse=True) -def after_servers_start(ns6, templates): - isctest.kasp.wait_keymgr_done(ns6, "going-straight-to-none.kasp") - isctest.kasp.wait_keymgr_done(ns6, "going-straight-to-none-dynamic.kasp") +def after_servers_start(ns3, templates): + isctest.kasp.wait_keymgr_done(ns3, "going-straight-to-none.kasp") + isctest.kasp.wait_keymgr_done(ns3, "going-straight-to-none-dynamic.kasp") - templates.render("ns6/named.conf", {"policy": "none"}) - ns6.reconfigure() + templates.render("ns3/named.conf", {"policy": "none"}) + ns3.reconfigure() @pytest.mark.parametrize( @@ -40,7 +62,7 @@ def after_servers_start(ns6, templates): "going-straight-to-none-dynamic.kasp", ], ) -def test_straight2none_reconfig(zone, ns6, alg, size): +def test_straight2none_reconfig(zone, ns3, alg, size): config = DEFAULT_CONFIG policy = None @@ -54,4 +76,4 @@ def test_straight2none_reconfig(zone, ns6, alg, size): ], "nextev": None, } - isctest.kasp.check_rollover_step(ns6, config, policy, step) + isctest.kasp.check_rollover_step(ns3, config, policy, step) diff --git a/bin/tests/system/rollover-zsk-prepub/ns1 b/bin/tests/system/rollover-zsk-prepub/ns1 new file mode 120000 index 0000000000..76608beaed --- /dev/null +++ b/bin/tests/system/rollover-zsk-prepub/ns1 @@ -0,0 +1 @@ +../rollover/ns1 \ No newline at end of file diff --git a/bin/tests/system/rollover-zsk-prepub/ns2 b/bin/tests/system/rollover-zsk-prepub/ns2 new file mode 120000 index 0000000000..41a09bb648 --- /dev/null +++ b/bin/tests/system/rollover-zsk-prepub/ns2 @@ -0,0 +1 @@ +../rollover/ns2 \ No newline at end of file diff --git a/bin/tests/system/rollover-zsk-prepub/ns3/kasp.conf.j2 b/bin/tests/system/rollover-zsk-prepub/ns3/kasp.conf similarity index 78% rename from bin/tests/system/rollover-zsk-prepub/ns3/kasp.conf.j2 rename to bin/tests/system/rollover-zsk-prepub/ns3/kasp.conf index eac3293a6e..c7a1bb5b22 100644 --- a/bin/tests/system/rollover-zsk-prepub/ns3/kasp.conf.j2 +++ b/bin/tests/system/rollover-zsk-prepub/ns3/kasp.conf @@ -22,8 +22,8 @@ dnssec-policy "zsk-prepub-autosign" { purge-keys PT1H; keys { - ksk key-directory lifetime unlimited algorithm @DEFAULT_ALGORITHM@; - zsk key-directory lifetime P30D algorithm @DEFAULT_ALGORITHM@; + ksk key-directory lifetime unlimited algorithm ecdsa256; + zsk key-directory lifetime P30D algorithm ecdsa256; }; zone-propagation-delay PT1H; @@ -43,8 +43,8 @@ dnssec-policy "zsk-prepub-manual" { purge-keys PT1H; keys { - ksk key-directory lifetime unlimited algorithm @DEFAULT_ALGORITHM@; - zsk key-directory lifetime P30D algorithm @DEFAULT_ALGORITHM@; + ksk key-directory lifetime unlimited algorithm ecdsa256; + zsk key-directory lifetime P30D algorithm ecdsa256; }; zone-propagation-delay PT1H; diff --git a/bin/tests/system/rollover-zsk-prepub/ns3/template.db.in b/bin/tests/system/rollover-zsk-prepub/ns3/template.db.in deleted file mode 120000 index ce6d526285..0000000000 --- a/bin/tests/system/rollover-zsk-prepub/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-zsk-prepub/ns3/template.db.j2.manual b/bin/tests/system/rollover-zsk-prepub/ns3/template.db.j2.manual new file mode 120000 index 0000000000..38619a01b2 --- /dev/null +++ b/bin/tests/system/rollover-zsk-prepub/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-zsk-prepub/ns3/trusted.conf.j2 b/bin/tests/system/rollover-zsk-prepub/ns3/trusted.conf.j2 new file mode 120000 index 0000000000..cb0be77b22 --- /dev/null +++ b/bin/tests/system/rollover-zsk-prepub/ns3/trusted.conf.j2 @@ -0,0 +1 @@ +../../_common/trusted.conf.j2 \ No newline at end of file diff --git a/bin/tests/system/rollover-zsk-prepub/setup.sh b/bin/tests/system/rollover-zsk-prepub/setup.sh deleted file mode 100644 index 86bea47159..0000000000 --- a/bin/tests/system/rollover-zsk-prepub/setup.sh +++ /dev/null @@ -1,218 +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" - 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 zsk-prepub.$tld represent the various steps of a ZSK -# Pre-Publication rollover. -# - -for tld in autosign manual; do - # Step 1: - # Introduce the first key. This will immediately be active. - setup step1.zsk-prepub.$tld - TactN="now-7d" - keytimes="-P ${TactN} -A ${TactN}" - KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $keytimes $zone 2>keygen.out.$zone.1) - ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $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 -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 pre-publish the successor ZSK. - setup step2.zsk-prepub.$tld - # According to RFC 7583: - # Tact(N) = now + Ipub - Lzsk = now + 26h - 30d - # = now + 26h - 30d = now − 694h - TactN="now-694h" - keytimes="-P ${TactN} -A ${TactN}" - KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $keytimes $zone 2>keygen.out.$zone.1) - ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $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 -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - - # Step 3: - # After the publication interval has passed the DNSKEY of the successor ZSK - # is OMNIPRESENT and the zone can thus be signed with the successor ZSK. - setup step3.zsk-prepub.$tld - # According to RFC 7583: - # Tpub(N+1) <= Tact(N) + Lzsk - Ipub - # Tact(N+1) = Tact(N) + Lzsk - # - # Tact(N) = now - Lzsk = now - 30d - # Tpub(N+1) = now - Ipub = now - 26h - # Tact(N+1) = now - # Tret(N) = now - # Trem(N) = now + Iret = now + Dsign + Dprp + TTLsig + retire-safety = 8d1h = now + 241h - TactN="now-30d" - TpubN1="now-26h" - TactN1="now" - TremN="now+241h" - keytimes="-P ${TactN} -A ${TactN}" - oldtimes="-P ${TactN} -A ${TactN} -I ${TactN1} -D ${TremN}" - newtimes="-P ${TpubN1} -A ${TactN1}" - KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $keytimes $zone 2>keygen.out.$zone.1) - ZSK1=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $oldtimes $zone 2>keygen.out.$zone.2) - ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $newtimes $zone 2>keygen.out.$zone.3) - $SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN "$KSK" >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 -z $H $TpubN1 "$ZSK2" >settime.out.$zone.3 2>&1 - # Set key rollover relationship. - key_successor $ZSK1 $ZSK2 - # Sign zone. - cat template.db.in "${KSK}.key" "${ZSK1}.key" "${ZSK2}.key" >"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK" >>"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK1" >>"$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: - # After the retire interval has passed the predecessor DNSKEY can be - # removed from the zone. - setup step4.zsk-prepub.$tld - # Lzsk: 30d - # Ipub: 26h - # Dsgn: 1w - # Dprp: 1h - # TTLsig: 1d - # retire-safety: 2d - # - # According to RFC 7583: - # Iret = Dsgn + Dprp + TTLsig (+retire-safety) - # Iret = 1w + 1h + 1d + 2d = 10d1h = 241h - # - # Tact(N) = now - Iret - Lzsk - # = now - 241h - 30d = now - 241h - 720h - # = now - 961h - # Tpub(N+1) = now - Iret - Ipub - # = now - 241h - 26h - # = now - 267h - # Tact(N+1) = now - Iret = now - 241h - TactN="now-961h" - TpubN1="now-267h" - TactN1="now-241h" - TremN="now" - keytimes="-P ${TactN} -A ${TactN}" - oldtimes="-P ${TactN} -A ${TactN} -I ${TactN1} -D ${TremN}" - newtimes="-P ${TpubN1} -A ${TactN1}" - KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $keytimes $zone 2>keygen.out.$zone.1) - ZSK1=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $oldtimes $zone 2>keygen.out.$zone.2) - ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $newtimes $zone 2>keygen.out.$zone.3) - $SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN "$KSK" >settime.out.$zone.1 2>&1 - $SETTIME -s -g $H -k $O $TactN -z $U $TactN1 "$ZSK1" >settime.out.$zone.2 2>&1 - $SETTIME -s -g $O -k $O $TactN1 -z $R $TactN1 "$ZSK2" >settime.out.$zone.3 2>&1 - # Set key rollover relationship. - key_successor $ZSK1 $ZSK2 - # Sign zone. - cat template.db.in "${KSK}.key" "${ZSK1}.key" "${ZSK2}.key" >"$infile" - cp $infile $zonefile - $SIGNER -PS -x -s now-2w -e now-1mi -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.zsk-prepub.$tld - # Subtract DNSKEY TTL + zone-propagation-delay from all the times (2h). - # Tact(N) = now - 961h - 2h = now - 963h - # Tpub(N+1) = now - 267h - 2h = now - 269h - # Tact(N+1) = now - 241h - 2h = now - 243h - # Trem(N) = Tact(N+1) + Iret = now -2h - TactN="now-963h" - TremN="now-2h" - TpubN1="now-269h" - TactN1="now-243h" - TremN="now-2h" - keytimes="-P ${TactN} -A ${TactN}" - oldtimes="-P ${TactN} -A ${TactN} -I ${TactN1} -D ${TremN}" - newtimes="-P ${TpubN1} -A ${TactN1}" - KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $keytimes $zone 2>keygen.out.$zone.1) - ZSK1=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $oldtimes $zone 2>keygen.out.$zone.2) - ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $newtimes $zone 2>keygen.out.$zone.3) - $SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN "$KSK" >settime.out.$zone.1 2>&1 - $SETTIME -s -g $H -k $U $TremN -z $H $TremN "$ZSK1" >settime.out.$zone.2 2>&1 - $SETTIME -s -g $O -k $O $TactN1 -z $O $TremN "$ZSK2" >settime.out.$zone.3 2>&1 - # Set key rollover relationship. - key_successor $ZSK1 $ZSK2 - # Sign zone. - cat template.db.in "${KSK}.key" "${ZSK1}.key" "${ZSK2}.key" >"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK" >>"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK1" >>"$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 predecessor DNSKEY can be purged. - setup step6.zsk-prepub.$tld - # Subtract purge-keys interval from all the times (1h). - TactN="now-964h" - TremN="now-3h" - TpubN1="now-270h" - TactN1="now-244h" - TremN="now-3h" - keytimes="-P ${TactN} -A ${TactN}" - oldtimes="-P ${TactN} -A ${TactN} -I ${TactN1} -D ${TremN}" - newtimes="-P ${TpubN1} -A ${TactN1}" - KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $keytimes $zone 2>keygen.out.$zone.1) - ZSK1=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $oldtimes $zone 2>keygen.out.$zone.2) - ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $newtimes $zone 2>keygen.out.$zone.3) - $SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN "$KSK" >settime.out.$zone.1 2>&1 - $SETTIME -s -g $H -k $H $TremN -z $H $TremN "$ZSK1" >settime.out.$zone.2 2>&1 - $SETTIME -s -g $O -k $O $TactN1 -z $O $TremN "$ZSK2" >settime.out.$zone.3 2>&1 - # Set key rollover relationship. - key_successor $ZSK1 $ZSK2 - # Sign zone. - cat template.db.in "${KSK}.key" "${ZSK1}.key" "${ZSK2}.key" >"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK" >>"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK1" >>"$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-zsk-prepub/tests_rollover_zsk_prepublication.py b/bin/tests/system/rollover-zsk-prepub/tests_rollover_zsk_prepublication.py index f0201296fc..2720275c66 100644 --- a/bin/tests/system/rollover-zsk-prepub/tests_rollover_zsk_prepublication.py +++ b/bin/tests/system/rollover-zsk-prepub/tests_rollover_zsk_prepublication.py @@ -24,6 +24,11 @@ from rollover.common import ( size, TIMEDELTA, ) +from rollover.setup import ( + configure_root, + configure_tld, + configure_zsk_prepub, +) CONFIG = { "dnskey-ttl": TIMEDELTA["PT1H"], @@ -57,6 +62,30 @@ OFFSETS["step6-p"] = OFFSETS["step5-p"] - int(CONFIG["purge-keys"].total_seconds OFFSETS["step6-s"] = OFFSETS["step5-s"] - int(CONFIG["purge-keys"].total_seconds()) +def bootstrap(): + data = { + "tlds": [], + "trust_anchors": [], + } + + tlds = [] + for tld_name in [ + "autosign", + "manual", + ]: + delegations = configure_zsk_prepub(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", [ diff --git a/bin/tests/system/rollover/common.py b/bin/tests/system/rollover/common.py index ff2cf2b781..23612234e4 100644 --- a/bin/tests/system/rollover/common.py +++ b/bin/tests/system/rollover/common.py @@ -15,6 +15,7 @@ import os import pytest from isctest.kasp import Ipub, IpubC, Iret +from isctest.vars.algorithms import Algorithm pytestmark = pytest.mark.extra_artifacts( [ @@ -34,9 +35,11 @@ pytestmark = pytest.mark.extra_artifacts( "ns*/K*.private", "ns*/K*.state", "ns*/keygen.out.*", + "ns*/managed-keys.**", "ns*/settime.out.*", "ns*/signer.out.*", "ns*/zones", + "ns1/root.db.in", ] ) @@ -137,3 +140,12 @@ def alg(): @pytest.fixture def size(): return os.environ["DEFAULT_BITS"] + + +def default_algorithm(): + return Algorithm( + os.environ["DEFAULT_ALGORITHM"], + int(os.environ["DEFAULT_ALGORITHM_NUMBER"]), + int(os.environ["DEFAULT_ALGORITHM_DST_NUMBER"]), + int(os.environ["DEFAULT_BITS"]), + ) diff --git a/bin/tests/system/rollover/ns1/named.conf.j2 b/bin/tests/system/rollover/ns1/named.conf.j2 new file mode 100644 index 0000000000..78aa3781b5 --- /dev/null +++ b/bin/tests/system/rollover/ns1/named.conf.j2 @@ -0,0 +1,31 @@ +/* + * 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. + */ + +// NS1 + +options { + query-source address 10.53.0.1; + notify-source 10.53.0.1; + transfer-source 10.53.0.1; + port @PORT@; + pid-file "named.pid"; + listen-on { 10.53.0.1; }; + listen-on-v6 { none; }; + recursion no; + notify yes; +}; + +zone "." { + type primary; + file "root.db.signed"; +}; diff --git a/bin/tests/system/rollover/ns1/root.db.j2.manual b/bin/tests/system/rollover/ns1/root.db.j2.manual new file mode 100644 index 0000000000..29a23bc02c --- /dev/null +++ b/bin/tests/system/rollover/ns1/root.db.j2.manual @@ -0,0 +1,31 @@ +; 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. + +$TTL 300 +. IN SOA . a.root.servers.nil. ( + 2000042100 ; serial + 600 ; refresh + 600 ; retry + 1200 ; expire + 600 ; minimum + ) +. NS a.root-servers.nil. +a.root-servers.nil. A 10.53.0.1 + +{% for dnskey in dnskeys %} +@dnskey@ +{% endfor %} + +{% for zone in delegations %} +{% set ns_name = zone.ns.name + "." + zone.name %} +@zone.name@ NS @ns_name@ +@ns_name@ A @zone.ns.ip@ +{% endfor %} diff --git a/bin/tests/system/rollover-dynamic2inline/ns6/named.common.conf.j2 b/bin/tests/system/rollover/ns2/named.conf.j2 similarity index 63% rename from bin/tests/system/rollover-dynamic2inline/ns6/named.common.conf.j2 rename to bin/tests/system/rollover/ns2/named.conf.j2 index 9299c97846..e1f7bffdd0 100644 --- a/bin/tests/system/rollover-dynamic2inline/ns6/named.common.conf.j2 +++ b/bin/tests/system/rollover/ns2/named.conf.j2 @@ -11,17 +11,19 @@ * information regarding copyright ownership. */ +// NS2 + options { - query-source address 10.53.0.6; - notify-source 10.53.0.6; - transfer-source 10.53.0.6; + query-source address 10.53.0.2; + notify-source 10.53.0.2; + transfer-source 10.53.0.2; port @PORT@; pid-file "named.pid"; - listen-on { 10.53.0.6; }; + listen-on { 10.53.0.2; }; listen-on-v6 { none; }; allow-transfer { any; }; + allow-notify { 10.53.0.3; }; recursion no; - key-directory "."; dnssec-validation no; }; @@ -31,5 +33,17 @@ key rndc_key { }; controls { - inet 10.53.0.6 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; + inet 10.53.0.2 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; }; + +zone "." { + type hint; + file "../../_common/root.hint"; +}; + +{% for zone in tlds %} +zone "@zone@" { + type primary; + file "@zone@.db.signed"; +}; +{% endfor %} diff --git a/bin/tests/system/rollover/ns2/template.db.j2.manual b/bin/tests/system/rollover/ns2/template.db.j2.manual new file mode 100644 index 0000000000..446a918a44 --- /dev/null +++ b/bin/tests/system/rollover/ns2/template.db.j2.manual @@ -0,0 +1,40 @@ +; 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. + +$TTL 300 +$ORIGIN @fqdn@ + +@fqdn@ IN SOA mname1. . ( + 1 ; serial + 20 ; refresh (20 seconds) + 20 ; retry (20 seconds) + 1814400 ; expire (3 weeks) + 3600 ; minimum (1 hour) + ) + + NS ns2 + +ns2 A 10.53.0.2 +ns3 A 10.53.0.3 + +scanner A 10.53.0.2 + +*._dsync DSYNC CDS NOTIFY @PORT@ scanner + +{% for dnskey in dnskeys %} +@dnskey@ +{% endfor %} + +{% for zone in delegations %} +{% set ns_name = zone.ns.name + "." + zone.name %} +@zone.name@. NS @ns_name@. +@ns_name@. A @zone.ns.ip@ +{% endfor %} diff --git a/bin/tests/system/rollover/ns3/named.common.conf.j2 b/bin/tests/system/rollover/ns3/named.common.conf.j2 index d1c3a054f1..813aa919e1 100644 --- a/bin/tests/system/rollover/ns3/named.common.conf.j2 +++ b/bin/tests/system/rollover/ns3/named.common.conf.j2 @@ -11,6 +11,14 @@ * information regarding copyright ownership. */ +{% if trust_anchors is defined %} +include "trusted.conf"; +{% set dnssec_validation = "yes" %} +{% else %} +{% set dnssec_validation = "auto" %} +{% endif %} + + options { query-source address 10.53.0.3; notify-source 10.53.0.3; @@ -20,8 +28,8 @@ options { listen-on { 10.53.0.3; }; listen-on-v6 { none; }; allow-transfer { any; }; - recursion no; - dnssec-validation no; + recursion yes; + dnssec-validation @dnssec_validation@; }; key rndc_key { @@ -35,5 +43,5 @@ controls { zone "." { type hint; - file "../../_common/root.hint.blackhole"; + file "../../_common/root.hint"; }; diff --git a/bin/tests/system/rollover/ns3/template.db.j2.manual b/bin/tests/system/rollover/ns3/template.db.j2.manual new file mode 100644 index 0000000000..3903587ba9 --- /dev/null +++ b/bin/tests/system/rollover/ns3/template.db.j2.manual @@ -0,0 +1,34 @@ +; 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. + +$TTL 300 +@fqdn@ IN SOA mname1. . ( + 1 ; serial + 20 ; refresh (20 seconds) + 20 ; retry (20 seconds) + 1814400 ; expire (3 weeks) + 3600 ; minimum (1 hour) + ) + + NS ns3 +ns3 A 10.53.0.3 + +a A 10.0.0.1 +b A 10.0.0.2 +c A 10.0.0.3 + +{% for dnskey in dnskeys %} +@dnskey@ +{% endfor %} + +{% for privaterr in privaterrs %} +@privaterr@ +{% endfor %} diff --git a/bin/tests/system/rollover/ns3/trusted.conf.j2 b/bin/tests/system/rollover/ns3/trusted.conf.j2 new file mode 120000 index 0000000000..cb0be77b22 --- /dev/null +++ b/bin/tests/system/rollover/ns3/trusted.conf.j2 @@ -0,0 +1 @@ +../../_common/trusted.conf.j2 \ No newline at end of file diff --git a/bin/tests/system/rollover/setup.py b/bin/tests/system/rollover/setup.py new file mode 100644 index 0000000000..ed4b0d1289 --- /dev/null +++ b/bin/tests/system/rollover/setup.py @@ -0,0 +1,1948 @@ +# 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. + +import shutil +from typing import List + +import isctest +from isctest.kasp import private_type_record +from isctest.template import Nameserver, TrustAnchor, Zone +from isctest.run import EnvCmd +from rollover.common import default_algorithm + + +def configure_tld(zonename: str, delegations: List[Zone]) -> Zone: + templates = isctest.template.TemplateEngine(".") + alg = default_algorithm() + keygen = EnvCmd("KEYGEN", f"-q -a {alg.number} -b {alg.bits} -L 3600") + signer = EnvCmd("SIGNER", "-S -g") + + isctest.log.info(f"create {zonename} zone with delegations and sign") + + for zone in delegations: + try: + shutil.copy(f"{zone.ns.name}/dsset-{zone.name}.", "ns2/") + except FileNotFoundError: + # Some delegations are unsigned. + pass + + ksk_name = keygen(f"-f KSK {zonename}", cwd="ns2").out.strip() + zsk_name = keygen(f"{zonename}", cwd="ns2").out.strip() + ksk = isctest.kasp.Key(ksk_name, keydir="ns2") + zsk = isctest.kasp.Key(zsk_name, keydir="ns2") + dnskeys = [ksk.dnskey, zsk.dnskey] + + template = "template.db.j2.manual" + outfile = f"{zonename}.db" + tdata = { + "fqdn": f"{zonename}.", + "delegations": delegations, + "dnskeys": dnskeys, + } + templates.render(f"ns2/{outfile}", tdata, template=f"ns2/{template}") + signer(f"-P -x -O full -o {zonename} -f {outfile}.signed {outfile}", cwd="ns2") + + return Zone(zonename, f"{outfile}.signed", Nameserver("ns2", "10.53.0.2")) + + +def configure_root(delegations: List[Zone]) -> TrustAnchor: + templates = isctest.template.TemplateEngine(".") + alg = default_algorithm() + keygen = EnvCmd("KEYGEN", f"-q -a {alg.number} -b {alg.bits} -L 3600") + signer = EnvCmd("SIGNER", "-S -g") + + zonename = "." + isctest.log.info("create root zone with delegations and sign") + + for zone in delegations: + shutil.copy(f"{zone.ns.name}/dsset-{zone.name}.", "ns1/") + + ksk_name = keygen(f"-f KSK {zonename}", cwd="ns1").out.strip() + zsk_name = keygen(f"{zonename}", cwd="ns1").out.strip() + ksk = isctest.kasp.Key(ksk_name, keydir="ns1") + zsk = isctest.kasp.Key(zsk_name, keydir="ns1") + dnskeys = [ksk.dnskey, zsk.dnskey] + + template = "root.db.j2.manual" + infile = "root.db.in" + outfile = "root.db.signed" + tdata = { + "fdqn": f"{zonename}.", + "delegations": delegations, + "dnskeys": dnskeys, + } + templates.render(f"ns1/{infile}", tdata, template=f"ns1/{template}") + signer(f"-P -x -O full -o {zonename} -f {outfile} {infile}", cwd="ns1") + + return ksk.into_ta("static-ds") + + +def fake_lifetime(key: str, lifetime: int): + """ + Fake lifetime of key. + """ + with open(f"ns3/{key}.state", "a", encoding="utf-8") as statefile: + statefile.write(f"Lifetime: {lifetime}\n") + + +def set_key_relationship(key1: str, key2: str): + """ + Set in the key state files the Predecessor/Successor fields. + """ + predecessor = isctest.kasp.Key(key1, keydir="ns3") + successor = isctest.kasp.Key(key2, keydir="ns3") + + with open(f"ns3/{key1}.state", "a", encoding="utf-8") as statefile: + statefile.write(f"Successor: {successor.tag}\n") + + with open(f"ns3/{key2}.state", "a", encoding="utf-8") as statefile: + statefile.write(f"Predecessor: {predecessor.tag}\n") + + +def render_and_sign_zone( + zonename: str, keys: List[str], signing: bool = True, extra_options: str = "" +): + dnskeys = [] + privaterrs = [] + for key_name in keys: + key = isctest.kasp.Key(key_name, keydir="ns3") + privaterr = private_type_record(zonename, key) + dnskeys.append(key.dnskey) + privaterrs.append(privaterr) + + outfile = f"{zonename}.db" + templates = isctest.template.TemplateEngine(".") + template = "template.db.j2.manual" + tdata = { + "fqdn": f"{zonename}.", + "dnskeys": dnskeys, + "privaterrs": privaterrs, + } + templates.render(f"ns3/{outfile}", tdata, template=f"ns3/{template}") + + if signing: + signer = EnvCmd("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]: + # The zones at csk-algorithm-roll.$tld represent the various steps + # of a CSK algorithm rollover. + zones = [] + zone = f"csk-algorithm-roll.{tld}" + keygen = EnvCmd("KEYGEN", f"-k {policy}") + settime = EnvCmd("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" + csktimes = f"-P {TactN} -A {TactN}" + # Key generation. + csk_name = keygen(f"-l csk1.conf {csktimes} {zonename}", cwd="ns3").out.strip() + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -z OMNIPRESENT {TactN} -d OMNIPRESENT {TactN} {csk_name}", + cwd="ns3", + ) + # Signing. + render_and_sign_zone(zonename, [csk_name], extra_options="-z") + + 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. + TpubN1 = "now-3h" + csktimes = f"-P {TactN} -A {TactN} -P sync {TsbmN} -I now" + newtimes = f"-P {TpubN1} -A {TpubN1}" + # Key generation. + csk1_name = keygen(f"-l csk1.conf {csktimes} {zonename}", cwd="ns3").out.strip() + csk2_name = keygen(f"-l csk2.conf {newtimes} {zonename}", cwd="ns3").out.strip() + settime( + f"-g HIDDEN -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -z OMNIPRESENT {TactN} -d OMNIPRESENT {TactN} {csk1_name}", + cwd="ns3", + ) + settime( + f"-g OMNIPRESENT -k RUMOURED {TpubN1} -r RUMOURED {TpubN1} -z RUMOURED {TpubN1} -d HIDDEN {TpubN1} {csk2_name}", + cwd="ns3", + ) + # Signing. + render_and_sign_zone(zonename, [csk1_name, csk2_name], extra_options="-z") + + # 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" + csktimes = f"-P {TactN} -A {TactN} -P sync {TsbmN} -I {TsbmN1}" + newtimes = f"-P {TpubN1} -A {TpubN1} -P sync {TsbmN1}" + # Key generation. + csk1_name = keygen(f"-l csk1.conf {csktimes} {zonename}", cwd="ns3").out.strip() + csk2_name = keygen(f"-l csk2.conf {newtimes} {zonename}", cwd="ns3").out.strip() + settime( + f"-g HIDDEN -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -z OMNIPRESENT {TactN} -d OMNIPRESENT {TactN} {csk1_name}", + cwd="ns3", + ) + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TpubN1} -r OMNIPRESENT {TpubN1} -z RUMOURED {TpubN1} -d HIDDEN {TpubN1} {csk2_name}", + cwd="ns3", + ) + # Signing. + render_and_sign_zone(zonename, [csk1_name, csk2_name], extra_options="-z") + + # 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" + csktimes = f"-P {TactN} -A {TactN} -P sync {TsbmN} -I {TsbmN1}" + newtimes = f"-P {TpubN1} -A {TpubN1} -P sync {TsbmN1}" + # Key generation. + csk1_name = keygen(f"-l csk1.conf {csktimes} {zonename}", cwd="ns3").out.strip() + csk2_name = keygen(f"-l csk2.conf {newtimes} {zonename}", cwd="ns3").out.strip() + settime( + f"-g HIDDEN -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -z OMNIPRESENT {TsbmN1} -d UNRETENTIVE {TsbmN1} -D ds {TsbmN1} {csk1_name}", + cwd="ns3", + ) + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TpubN1} -r OMNIPRESENT {TpubN1} -z OMNIPRESENT {TsbmN1} -d RUMOURED {TsbmN1} -P ds {TsbmN1} {csk2_name}", + cwd="ns3", + ) + # Signing. + render_and_sign_zone(zonename, [csk1_name, csk2_name], extra_options="-z") + + # 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" + csktimes = f"-P {TactN} -A {TactN} -P sync {TsbmN} -I {TsbmN1}" + newtimes = f"-P {TpubN1} -A {TpubN1} -P sync {TsbmN1}" + # Key generation. + csk1_name = keygen(f"-l csk1.conf {csktimes} {zonename}", cwd="ns3").out.strip() + csk2_name = keygen(f"-l csk2.conf {newtimes} {zonename}", cwd="ns3").out.strip() + settime( + f"-g HIDDEN -k UNRETENTIVE {TactN} -r UNRETENTIVE {TactN} -z UNRETENTIVE {TsbmN1} -d HIDDEN {TsbmN1} {csk1_name}", + cwd="ns3", + ) + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TpubN1} -r OMNIPRESENT {TpubN1} -z OMNIPRESENT {TsbmN1} -d OMNIPRESENT {TsbmN1} {csk2_name}", + cwd="ns3", + ) + # Signing. + render_and_sign_zone(zonename, [csk1_name, csk2_name], extra_options="-z") + + # 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" + csktimes = f"-P {TactN} -A {TactN} -P sync {TsbmN} -I {TsbmN1}" + newtimes = f"-P {TpubN1} -A {TpubN1} -P sync {TsbmN1}" + # Key generation. + csk1_name = keygen(f"-l csk1.conf {csktimes} {zonename}", cwd="ns3").out.strip() + csk2_name = keygen(f"-l csk2.conf {newtimes} {zonename}", cwd="ns3").out.strip() + settime( + f"-g HIDDEN -k HIDDEN {TactN} -r UNRETENTIVE {TactN} -z UNRETENTIVE {TactN} -d HIDDEN {TsbmN1} {csk1_name}", + cwd="ns3", + ) + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TpubN1} -r OMNIPRESENT {TpubN1} -z OMNIPRESENT {TsbmN1} -d OMNIPRESENT {TsbmN1} {csk2_name}", + cwd="ns3", + ) + # Signing. + 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 = EnvCmd("KEYGEN", "-L 3600") + settime = EnvCmd("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" + ).out.strip() + zsk_name = keygen(f"-a RSASHA256 {keytimes} {zonename}", cwd="ns3").out.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" + ).out.strip() + zsk1_name = keygen( + f"-a RSASHA256 {zsk1times} {zonename}", cwd="ns3" + ).out.strip() + ksk2_name = keygen( + f"-a ECDSA256 -f KSK {ksk2times} {zonename}", cwd="ns3" + ).out.strip() + zsk2_name = keygen(f"-a ECDSA256 {zsk2times} {zonename}", cwd="ns3").out.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, 0) + fake_lifetime(zsk1_name, 0) + 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" + ).out.strip() + zsk1_name = keygen( + f"-a RSASHA256 {zsk1times} {zonename}", cwd="ns3" + ).out.strip() + ksk2_name = keygen( + f"-a ECDSA256 -f KSK {ksk2times} {zonename}", cwd="ns3" + ).out.strip() + zsk2_name = keygen(f"-a ECDSA256 {zsk2times} {zonename}", cwd="ns3").out.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, 0) + fake_lifetime(zsk1_name, 0) + 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" + ).out.strip() + zsk1_name = keygen( + f"-a RSASHA256 {zsk1times} {zonename}", cwd="ns3" + ).out.strip() + ksk2_name = keygen( + f"-a ECDSA256 -f KSK {ksk2times} {zonename}", cwd="ns3" + ).out.strip() + zsk2_name = keygen(f"-a ECDSA256 {zsk2times} {zonename}", cwd="ns3").out.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, 0) + fake_lifetime(zsk1_name, 0) + 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" + ).out.strip() + zsk1_name = keygen( + f"-a RSASHA256 {zsk1times} {zonename}", cwd="ns3" + ).out.strip() + ksk2_name = keygen( + f"-a ECDSA256 -f KSK {ksk2times} {zonename}", cwd="ns3" + ).out.strip() + zsk2_name = keygen(f"-a ECDSA256 {zsk2times} {zonename}", cwd="ns3").out.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, 0) + fake_lifetime(zsk1_name, 0) + 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" + ).out.strip() + zsk1_name = keygen( + f"-a RSASHA256 {zsk1times} {zonename}", cwd="ns3" + ).out.strip() + ksk2_name = keygen( + f"-a ECDSA256 -f KSK {ksk2times} {zonename}", cwd="ns3" + ).out.strip() + zsk2_name = keygen(f"-a ECDSA256 {zsk2times} {zonename}", cwd="ns3").out.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, 0) + fake_lifetime(zsk1_name, 0) + render_and_sign_zone(zonename, [ksk1_name, zsk1_name, ksk2_name, zsk2_name]) + + return zones + + +def configure_cskroll1(tld: str, policy: str) -> List[Zone]: + # The zones at csk-roll1.$tld represent the various steps of a CSK rollover + # (which is essentially a ZSK Pre-Publication / KSK Double-KSK rollover). + zones = [] + zone = f"csk-roll1.{tld}" + cds = "cdnskey,cds:sha384" + keygen = EnvCmd("KEYGEN", f"-k {policy} -l kasp.conf") + settime = EnvCmd("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" + keytimes = f"-P {TactN} -A {TactN}" + # Key generation. + csk_name = keygen(f"{keytimes} {zonename}", cwd="ns3").out.strip() + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -z OMNIPRESENT {TactN} -d OMNIPRESENT {TactN} {csk_name}", + cwd="ns3", + ) + # Signing. + render_and_sign_zone(zonename, [csk_name], extra_options=f"-z -G {cds}") + + # Step 2: + # It is time to introduce the new CSK. + zonename = f"step2.{zone}" + zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3"))) + isctest.log.info(f"setup {zonename}") + # According to RFC 7583: + # KSK: Tpub(N+1) <= Tact(N) + Lksk - IpubC + # ZSK: Tpub(N+1) <= Tact(N) + Lzsk - Ipub + # IpubC = DprpC + TTLkey (+publish-safety) + # Ipub = IpubC + # Lcsk = Lksk = Lzsk + # + # Lcsk: 6mo (186d, 4464h) + # Dreg: N/A + # DprpC: 1h + # TTLkey: 1h + # publish-safety: 1h + # Ipub: 3h + # + # Tact(N) = now - Lcsk + Ipub = now - 186d + 3h + # = now - 4464h + 3h = now - 4461h + TactN = "now-4461h" + keytimes = f"-P {TactN} -A {TactN}" + # Key generation. + csk_name = keygen(f"{keytimes} {zonename}", cwd="ns3").out.strip() + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -z OMNIPRESENT {TactN} -d OMNIPRESENT {TactN} {csk_name}", + cwd="ns3", + ) + # Signing. + render_and_sign_zone(zonename, [csk_name], extra_options=f"-z -G {cds}") + + # Step 3: + # It is time to submit the DS and to roll signatures. + 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: + # + # Tsbm(N+1) >= Trdy(N+1) + # KSK: Tact(N+1) = Tsbm(N+1) + # ZSK: Tact(N+1) = Tpub(N+1) + Ipub = Tsbm(N+1) + # KSK: Iret = DprpP + TTLds (+retire-safety) + # ZSK: IretZ = Dsgn + Dprp + TTLsig (+retire-safety) + # + # Lcsk: 186d + # Dprp: 1h + # DprpP: 1h + # Dreg: N/A + # Dsgn: 25d + # TTLds: 1h + # TTLsig: 1d + # retire-safety: 2h + # Iret: 4h + # IretZ: 26d3h + # Ipub: 3h + # + # Tpub(N) = now - Lcsk = now - 186d + # Tact(N) = now - Lcsk + Dprp + TTLsig = now - 4439h + # Tret(N) = now + # Trem(N) = now + IretZ = now + 26d3h = now + 627h + # Tpub(N+1) = now - Ipub = now - 3h + # Tact(N+1) = Tret(N) + # Tret(N+1) = now + Lcsk = now + 186d = now + 186d + # Trem(N+1) = now + Lcsk + IretZ = now + 186d + 26d3h = + # = now + 5091h + TpubN = "now-186d" + TactN = "now-4439h" + TretN = "now" + TremN = "now+627h" + TpubN1 = "now-3h" + TactN1 = TretN + TretN1 = "now+186d" + TremN1 = "now+5091h" + keytimes = ( + f"-P {TpubN} -P sync {TactN} -A {TpubN} -I {TretN} -D {TremN} -D sync {TactN1}" + ) + newtimes = f"-P {TpubN1} -P sync {TactN1} -A {TactN1} -I {TretN1} -D {TremN1}" + # Key generation. + csk1_name = keygen(f"{keytimes} {zonename}", cwd="ns3").out.strip() + csk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").out.strip() + settime( + f"-g HIDDEN -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -z OMNIPRESENT {TactN} -d OMNIPRESENT {TactN} {csk1_name}", + cwd="ns3", + ) + settime( + f"-g OMNIPRESENT -k RUMOURED {TpubN1} -r RUMOURED {TpubN1} -z HIDDEN {TpubN1} -d HIDDEN {TpubN1} {csk2_name}", + cwd="ns3", + ) + # Set key rollover relationship. + set_key_relationship(csk1_name, csk2_name) + # Signing. + render_and_sign_zone(zonename, [csk1_name, csk2_name], extra_options=f"-z -G {cds}") + + # Step 4: + # Some time later all the ZRRSIG records should be from the new CSK, and the + # DS should be swapped. The ZRRSIG records are all replaced after IretZ + # (which is 26d3h). The DS is swapped after Iret (which is 4h). + # In other words, the DS is swapped before all zone signatures are replaced. + zonename = f"step4.{zone}" + zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3"))) + isctest.log.info(f"setup {zonename}") + # According to RFC 7583: + # Trem(N) = Tret(N) - Iret + IretZ + # now = Tsbm(N+1) + Iret + # + # Lcsk: 186d + # Iret: 4h + # IretZ: 26d3h + # + # Tpub(N) = now - Iret - Lcsk = now - 4h - 186d = now - 4468h + # Tret(N) = now - Iret = now - 4h = now - 4h + # Trem(N) = now - Iret + IretZ = now - 4h + 26d3h + # = now + 623h + # Tpub(N+1) = now - Iret - IpubC = now - 4h - 3h = now - 7h + # Tact(N+1) = Tret(N) + # Tret(N+1) = now - Iret + Lcsk = now - 4h + 186d = now + 4460h + # Trem(N+1) = now - Iret + Lcsk + IretZ = now - 4h + 186d + 26d3h + # = now + 5087h + TpubN = "now-4468h" + TactN = "now-4443h" + TretN = "now-4h" + TremN = "now+623h" + TpubN1 = "now-7h" + TactN1 = TretN + TretN1 = "now+4460h" + TremN1 = "now+5087h" + keytimes = ( + f"-P {TpubN} -P sync {TactN} -A {TpubN} -I {TretN} -D {TremN} -D sync {TactN1}" + ) + newtimes = f"-P {TpubN1} -P sync {TactN1} -A {TactN1} -I {TretN1} -D {TremN1}" + # Key generation. + csk1_name = keygen(f"{keytimes} {zonename}", cwd="ns3").out.strip() + csk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").out.strip() + settime( + f"-g HIDDEN -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -z UNRETENTIVE {TactN1} -d UNRETENTIVE {TactN1} -D ds {TactN1} {csk1_name}", + cwd="ns3", + ) + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TactN1} -r OMNIPRESENT {TactN1} -z RUMOURED {TactN1} -d RUMOURED {TactN1} -P ds {TactN1} {csk2_name}", + cwd="ns3", + ) + # Set key rollover relationship. + set_key_relationship(csk1_name, csk2_name) + # Signing. + render_and_sign_zone(zonename, [csk1_name, csk2_name], extra_options=f"-z -G {cds}") + + # Step 5: + # After the DS is swapped in step 4, also the KRRSIG records can be removed. + # At this time these have all 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 plus zone propagation delay from all the times (2h). + TpubN = "now-4470h" + TactN = "now-4445h" + TretN = "now-6h" + TremN = "now+621h" + TpubN1 = "now-9h" + TactN1 = TretN + TretN1 = "now+4458h" + TremN1 = "now+5085h" + keytimes = ( + f"-P {TpubN} -P sync {TactN} -A {TpubN} -I {TretN} -D {TremN} -D sync {TactN1}" + ) + newtimes = f"-P {TpubN1} -P sync {TactN1} -A {TactN1} -I {TretN1} -D {TremN1}" + # Key generation. + csk1_name = keygen(f"{keytimes} {zonename}", cwd="ns3").out.strip() + csk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").out.strip() + settime( + f"-g HIDDEN -k OMNIPRESENT {TactN} -r UNRETENTIVE now-2h -z UNRETENTIVE {TactN1} -d HIDDEN now-2h {csk1_name}", + cwd="ns3", + ) + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TactN1} -r OMNIPRESENT {TactN1} -z RUMOURED {TactN1} -d OMNIPRESENT now-2h {csk2_name}", + cwd="ns3", + ) + # Set key rollover relationship. + set_key_relationship(csk1_name, csk2_name) + # Signing. + render_and_sign_zone(zonename, [csk1_name, csk2_name], extra_options=f"-z -G {cds}") + + # Step 6: + # After the retire interval has passed the predecessor DNSKEY can be + # removed from the zone. + zonename = f"step6.{zone}" + zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3"))) + isctest.log.info(f"setup {zonename}") + # According to RFC 7583: + # Trem(N) = Tret(N) + IretZ + # Tret(N) = Tact(N) + Lcsk + # + # Lcsk: 186d + # Iret: 4h + # IretZ: 26d3h + # + # Tpub(N) = now - IretZ - Lcsk = now - 627h - 186d + # = now - 627h - 4464h = now - 5091h + # Tact(N) = now - 627h - 186d + # Tret(N) = now - IretZ = now - 627h + # Trem(N) = now + # Tpub(N+1) = now - IretZ - Ipub = now - 627h - 3h = now - 630h + # Tact(N+1) = Tret(N) + # Tret(N+1) = now - IretZ + Lcsk = now - 627h + 186d = now + 3837h + # Trem(N+1) = now + Lcsk = now + 186d + TpubN = "now-5091h" + TactN = "now-5066h" + TretN = "now-627h" + TremN = "now" + TpubN1 = "now-630h" + TactN1 = TretN + TretN1 = "now+3837h" + TremN1 = "now+186d" + keytimes = ( + f"-P {TpubN} -P sync {TactN} -A {TpubN} -I {TretN} -D {TremN} -D sync {TactN1}" + ) + newtimes = f"-P {TpubN1} -P sync {TactN1} -A {TactN1} -I {TretN1} -D {TremN1}" + # Key generation. + csk1_name = keygen(f"{keytimes} {zonename}", cwd="ns3").out.strip() + csk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").out.strip() + settime( + f"-g HIDDEN -k OMNIPRESENT {TactN} -r HIDDEN {TremN} -z UNRETENTIVE {TactN1} -d HIDDEN {TremN} {csk1_name}", + cwd="ns3", + ) + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TactN1} -r OMNIPRESENT {TactN1} -z RUMOURED {TactN1} -d OMNIPRESENT {TremN} {csk2_name}", + cwd="ns3", + ) + # Set key rollover relationship. + set_key_relationship(csk1_name, csk2_name) + # Signing. + render_and_sign_zone(zonename, [csk1_name, csk2_name], extra_options=f"-z -G {cds}") + + # Step 7: + # Some time later the predecessor DNSKEY enters the HIDDEN state. + zonename = f"step7.{zone}" + zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3"))) + isctest.log.info(f"setup {zonename}") + # Subtract DNSKEY TTL plus zone propagation delay from all the times (2h). + TpubN = "now-5093h" + TactN = "now-5068h" + TretN = "now-629h" + TremN = "now-2h" + TpubN1 = "now-632h" + TactN1 = TretN + TretN1 = "now+3835h" + TremN1 = "now+4462h" + keytimes = ( + f"-P {TpubN} -P sync {TactN} -A {TpubN} -I {TretN} -D {TremN} -D sync {TactN1}" + ) + newtimes = f"-P {TpubN1} -P sync {TactN1} -A {TactN1} -I {TretN1} -D {TremN1}" + # Key generation. + csk1_name = keygen(f"{keytimes} {zonename}", cwd="ns3").out.strip() + csk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").out.strip() + settime( + f"-g HIDDEN -k UNRETENTIVE {TremN} -r HIDDEN {TremN} -z HIDDEN {TactN1} -d HIDDEN {TremN} {csk1_name}", + cwd="ns3", + ) + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TactN1} -r OMNIPRESENT {TactN1} -z OMNIPRESENT {TactN1} -d OMNIPRESENT {TactN1} {csk2_name}", + cwd="ns3", + ) + # Set key rollover relationship. + set_key_relationship(csk1_name, csk2_name) + # Signing. + render_and_sign_zone(zonename, [csk1_name, csk2_name], extra_options=f"-z -G {cds}") + + # Step 8: + # The predecessor DNSKEY can be purged. + zonename = f"step8.{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-5094h" + TactN = "now-5069h" + TretN = "now-630h" + TremN = "now-3h" + TpubN1 = "now-633h" + TactN1 = TretN + TretN1 = "now+3834h" + TremN1 = "now+4461h" + keytimes = ( + f"-P {TpubN} -P sync {TactN} -A {TpubN} -I {TretN} -D {TremN} -D sync {TactN1}" + ) + newtimes = f"-P {TpubN1} -P sync {TactN1} -A {TactN1} -I {TretN1} -D {TremN1}" + # Key generation. + csk1_name = keygen(f"{keytimes} {zonename}", cwd="ns3").out.strip() + csk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").out.strip() + settime( + f"-g HIDDEN -k HIDDEN {TremN} -r HIDDEN {TremN} -z HIDDEN {TactN1} -d HIDDEN {TremN} {csk1_name}", + cwd="ns3", + ) + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TactN1} -r OMNIPRESENT {TactN1} -z OMNIPRESENT {TactN1} -d OMNIPRESENT {TactN1} {csk2_name}", + cwd="ns3", + ) + # Set key rollover relationship. + set_key_relationship(csk1_name, csk2_name) + # Signing. + render_and_sign_zone(zonename, [csk1_name, csk2_name], extra_options=f"-z -G {cds}") + + return zones + + +def configure_cskroll2(tld: str, policy: str) -> List[Zone]: + # The zones at csk-roll2.$tld represent the various steps of a CSK rollover + # (which is essentially a ZSK Pre-Publication / KSK Double-KSK rollover). + # This scenario differs from the csk-roll1 one because the zone signatures (ZRRSIG) + # are replaced with the new key sooner than the DS is swapped. + zones = [] + zone = f"csk-roll2.{tld}" + cds = "cdnskey,cds:sha-256,cds:sha-384" + keygen = EnvCmd("KEYGEN", f"-k {policy} -l kasp.conf") + settime = EnvCmd("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" + keytimes = f"-P {TactN} -A {TactN}" + # Key generation. + csk_name = keygen(f"{keytimes} {zonename}", cwd="ns3").out.strip() + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -z OMNIPRESENT {TactN} -d OMNIPRESENT {TactN} {csk_name}", + cwd="ns3", + ) + # Signing. + render_and_sign_zone(zonename, [csk_name], extra_options=f"-z -G {cds}") + + # Step 2: + # It is time to introduce the new CSK. + zonename = f"step2.{zone}" + zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3"))) + isctest.log.info(f"setup {zonename}") + # According to RFC 7583: + # KSK: Tpub(N+1) <= Tact(N) + Lksk - IpubC + # ZSK: Tpub(N+1) <= Tact(N) + Lzsk - Ipub + # IpubC = DprpC + TTLkey (+publish-safety) + # Ipub = IpubC + # Lcsk = Lksk = Lzsk + # + # Lcsk: 6mo (186d, 4464h) + # Dreg: N/A + # DprpC: 1h + # TTLkey: 1h + # publish-safety: 1h + # Ipub: 3h + # + # Tact(N) = now - Lcsk + Ipub = now - 186d + 3h + # = now - 4464h + 3h = now - 4461h + TactN = "now-4461h" + keytimes = f"-P {TactN} -A {TactN}" + # Key generation. + csk_name = keygen(f"{keytimes} {zonename}", cwd="ns3").out.strip() + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -z OMNIPRESENT {TactN} -d OMNIPRESENT {TactN} {csk_name}", + cwd="ns3", + ) + # Signing. + render_and_sign_zone(zonename, [csk_name], extra_options=f"-z -G {cds}") + + # Step 3: + # It is time to submit the DS and to roll signatures. + 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: + # + # Tsbm(N+1) >= Trdy(N+1) + # KSK: Tact(N+1) = Tsbm(N+1) + # ZSK: Tact(N+1) = Tpub(N+1) + Ipub = Tsbm(N+1) + # KSK: Iret = DprpP + TTLds (+retire-safety) + # ZSK: IretZ = Dsgn + Dprp + TTLsig (+retire-safety) + # + # Lcsk: 186d + # Dprp: 1h + # DprpP: 1w + # Dreg: N/A + # Dsgn: 12h + # TTLds: 1h + # TTLsig: 1d + # retire-safety: 1h + # Iret: 170h + # IretZ: 38h + # Ipub: 3h + # + # Tpub(N) = now - Lcsk = now - 186d + # Tact(N) = now - Lcsk + Dprp + TTLsig = now - 4439h + # Tret(N) = now + # Trem(N) = now + IretZ = now + 26d3h = now + 627h + # Tpub(N+1) = now - Ipub = now - 3h + # Tact(N+1) = Tret(N) + # Tret(N+1) = now + Lcsk = now + 186d = now + 186d + # Trem(N+1) = now + Lcsk + IretZ = now + 186d + 26d3h = + # = now + 5091h + TpubN = "now-186d" + TactN = "now-4439h" + TretN = "now" + TremN = "now+170h" + TpubN1 = "now-3h" + TactN1 = TretN + TretN1 = "now+186d" + TremN1 = "now+4634h" + keytimes = ( + f"-P {TpubN} -P sync {TactN} -A {TpubN} -I {TretN} -D {TremN} -D sync {TactN1}" + ) + newtimes = f"-P {TpubN1} -P sync {TactN1} -A {TactN1} -I {TretN1} -D {TremN1}" + # Key generation. + csk1_name = keygen(f"{keytimes} {zonename}", cwd="ns3").out.strip() + csk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").out.strip() + settime( + f"-g HIDDEN -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -z OMNIPRESENT {TactN} -d OMNIPRESENT {TactN} {csk1_name}", + cwd="ns3", + ) + settime( + f"-g OMNIPRESENT -k RUMOURED {TpubN1} -r RUMOURED {TpubN1} -z HIDDEN {TpubN1} -d HIDDEN {TpubN1} {csk2_name}", + cwd="ns3", + ) + # Set key rollover relationship. + set_key_relationship(csk1_name, csk2_name) + # Signing. + render_and_sign_zone(zonename, [csk1_name, csk2_name], extra_options=f"-z -G {cds}") + + # Step 4: + # Some time later all the ZRRSIG records should be from the new CSK, and the + # DS should be swapped. The ZRRSIG records are all replaced after IretZ (38h). + # The DS is swapped after Dreg + Iret (1w3h). In other words, the zone + # signatures are replaced before the DS is swapped. + zonename = f"step4.{zone}" + zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3"))) + isctest.log.info(f"setup {zonename}") + # According to RFC 7583: + # Trem(N) = Tret(N) + IretZ + # + # Lcsk: 186d + # Dreg: N/A + # Iret: 170h + # IretZ: 38h + # + # Tpub(N) = now - IretZ - Lcsk = now - 38h - 186d + # = now - 38h - 4464h = now - 4502h + # Tact(N) = now - Iret - Lcsk + TTLsig = now - 4502h + 25h = now - 4477h + # Tret(N) = now - IretZ = now - 38h + # Trem(N) = now - IretZ + Iret = now - 38h + 170h = now + 132h + # Tpub(N+1) = now - IretZ - IpubC = now - 38h - 3h = now - 41h + # Tact(N+1) = Tret(N) + # Tret(N+1) = now - IretZ + Lcsk = now - 38h + 186d + # = now + 4426h + # Trem(N+1) = now - IretZ + Lcsk + Iret + # = now + 4426h + 3h = now + 4429h + TpubN = "now-4502h" + TactN = "now-4477h" + TretN = "now-38h" + TremN = "now+132h" + TpubN1 = "now-41h" + TactN1 = TretN + TretN1 = "now+4426h" + TremN1 = "now+4429h" + keytimes = ( + f"-P {TpubN} -P sync {TactN} -A {TpubN} -I {TretN} -D {TremN} -D sync {TactN1}" + ) + newtimes = f"-P {TpubN1} -P sync {TactN1} -A {TactN1} -I {TretN1} -D {TremN1}" + # Key generation. + csk1_name = keygen(f"{keytimes} {zonename}", cwd="ns3").out.strip() + csk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").out.strip() + settime( + f"-g HIDDEN -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -z UNRETENTIVE {TretN} -d UNRETENTIVE {TretN} -D ds {TretN} {csk1_name}", + cwd="ns3", + ) + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TactN1} -r OMNIPRESENT {TactN1} -z RUMOURED {TactN1} -d RUMOURED {TactN1} -P ds {TactN1} {csk2_name}", + cwd="ns3", + ) + # Set key rollover relationship. + set_key_relationship(csk1_name, csk2_name) + # Signing. + render_and_sign_zone(zonename, [csk1_name, csk2_name], extra_options=f"-z -G {cds}") + + # Step 5: + # Some time later the DS can be swapped and the old DNSKEY can be removed from + # the zone. + zonename = f"step5.{zone}" + zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3"))) + isctest.log.info(f"setup {zonename}") + # Subtract Iret (170h) - IretZ (38h) = 132h. + # + # Tpub(N) = now - 4502h - 132h = now - 4634h + # Tact(N) = now - 4477h - 132h = now - 4609h + # Tret(N) = now - 38h - 132h = now - 170h + # Trem(N) = now + 132h - 132h = now + # Tpub(N+1) = now - 41h - 132h = now - 173h + # Tact(N+1) = Tret(N) + # Tret(N+1) = now + 4426h - 132h = now + 4294h + # Trem(N+1) = now + 4492h - 132h = now + 4360h + TpubN = "now-4634h" + TactN = "now-4609h" + TretN = "now-170h" + TremN = "now" + TpubN1 = "now-173h" + TactN1 = TretN + TretN1 = "now+4294h" + TremN1 = "now+4360h" + keytimes = ( + f"-P {TpubN} -P sync {TactN} -A {TpubN} -I {TretN} -D {TremN} -D sync {TactN1}" + ) + newtimes = f"-P {TpubN1} -P sync {TactN1} -A {TactN1} -I {TretN1} -D {TremN1}" + # Key generation. + csk1_name = keygen(f"{keytimes} {zonename}", cwd="ns3").out.strip() + csk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").out.strip() + settime( + f"-g HIDDEN -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -z HIDDEN now-133h -d UNRETENTIVE {TactN1} -D ds {TactN1} {csk1_name}", + cwd="ns3", + ) + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TactN1} -r OMNIPRESENT {TactN1} -z OMNIPRESENT now-133h -d RUMOURED {TactN1} -P ds {TactN1} {csk2_name}", + cwd="ns3", + ) + # Set key rollover relationship. + set_key_relationship(csk1_name, csk2_name) + # Signing. + render_and_sign_zone(zonename, [csk1_name, csk2_name], extra_options=f"-z -G {cds}") + + # Step 6: + # Some time later the predecessor DNSKEY enters the HIDDEN state. + zonename = f"step6.{zone}" + zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3"))) + isctest.log.info(f"setup {zonename}") + # Subtract DNSKEY TTL plus zone propagation delay (2h). + # + # Tpub(N) = now - 4634h - 2h = now - 4636h + # Tact(N) = now - 4609h - 2h = now - 4611h + # Tret(N) = now - 170h - 2h = now - 172h + # Trem(N) = now - 2h + # Tpub(N+1) = now - 173h - 2h = now - 175h + # Tact(N+1) = Tret(N) + # Tret(N+1) = now + 4294h - 2h = now + 4292h + # Trem(N+1) = now + 4360h - 2h = now + 4358h + TpubN = "now-4636h" + TactN = "now-4611h" + TretN = "now-172h" + TremN = "now-2h" + TpubN1 = "now-175h" + TactN1 = TretN + TretN1 = "now+4292h" + TremN1 = "now+4358h" + keytimes = ( + f"-P {TpubN} -P sync {TactN} -A {TpubN} -I {TretN} -D {TremN} -D sync {TactN1}" + ) + newtimes = f"-P {TpubN1} -P sync {TactN1} -A {TactN1} -I {TretN1} -D {TremN1}" + # Key generation. + csk1_name = keygen(f"{keytimes} {zonename}", cwd="ns3").out.strip() + csk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").out.strip() + settime( + f"-g HIDDEN -k UNRETENTIVE {TremN} -r UNRETENTIVE {TremN} -z HIDDEN now-135h -d HIDDEN {TremN} {csk1_name}", + cwd="ns3", + ) + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TactN1} -r OMNIPRESENT {TactN1} -z OMNIPRESENT now-135h -d OMNIPRESENT {TremN} {csk2_name}", + cwd="ns3", + ) + # Set key rollover relationship. + set_key_relationship(csk1_name, csk2_name) + # Signing. + render_and_sign_zone(zonename, [csk1_name, csk2_name], extra_options=f"-z -G {cds}") + + # Step 7: + # The predecessor DNSKEY can be purged, but purge-keys is disabled. + zonename = f"step7.{zone}" + zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3"))) + isctest.log.info(f"setup {zonename}") + # Subtract 90 days (default, 2160h) from all the times. + # + # Tpub(N) = now - 4636h - 2160h = now - 6796h + # Tact(N) = now - 4611h - 2160h = now - 6771h + # Tret(N) = now - 172h - 2160h = now - 2332h + # Trem(N) = now - 2h - 2160h = now - 2162h + # Tpub(N+1) = now - 175h - 2160h = now - 2335h + # Tact(N+1) = Tret(N) + # Tret(N+1) = now + 4292h - 2160h = now + 2132h + # Trem(N+1) = now + 4358h - 2160h = now + 2198h + TpubN = "now-6796h" + TactN = "now-6771h" + TretN = "now-2332h" + TremN = "now-2162h" + TpubN1 = "now-2335h" + TactN1 = TretN + TretN1 = "now+2132h" + TremN1 = "now+2198h" + + keytimes = ( + f"-P {TpubN} -P sync {TactN} -A {TpubN} -I {TretN} -D {TremN} -D sync {TactN1}" + ) + newtimes = f"-P {TpubN1} -P sync {TactN1} -A {TactN1} -I {TretN1} -D {TremN1}" + # Key generation. + csk1_name = keygen(f"{keytimes} {zonename}", cwd="ns3").out.strip() + csk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").out.strip() + settime( + f"-g HIDDEN -k UNRETENTIVE {TremN} -r HIDDEN {TremN} -z HIDDEN {TactN1} -d HIDDEN {TremN} {csk1_name}", + cwd="ns3", + ) + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TactN1} -r OMNIPRESENT {TactN1} -z OMNIPRESENT {TactN1} -d OMNIPRESENT {TremN} {csk2_name}", + cwd="ns3", + ) + # Set key rollover relationship. + set_key_relationship(csk1_name, csk2_name) + # Signing. + render_and_sign_zone(zonename, [csk1_name, csk2_name], extra_options=f"-z -G {cds}") + + # Step 8: + # The predecessor DNSKEY can be purged. + zonename = f"step8.{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-5094h" + TactN = "now-5069h" + TretN = "now-630h" + TremN = "now-3h" + TpubN1 = "now-633h" + TactN1 = TretN + TretN1 = "now+3834h" + TremN1 = "now+4461h" + keytimes = ( + f"-P {TpubN} -P sync {TactN} -A {TpubN} -I {TretN} -D {TremN} -D sync {TactN1}" + ) + newtimes = f"-P {TpubN1} -P sync {TactN1} -A {TactN1} -I {TretN1} -D {TremN1}" + # Key generation. + csk1_name = keygen(f"{keytimes} {zonename}", cwd="ns3").out.strip() + csk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").out.strip() + settime( + f"-g HIDDEN -k UNRETENTIVE {TremN} -r UNRETENTIVE {TremN} -z HIDDEN now-2295h -d HIDDEN {TremN} {csk1_name}", + cwd="ns3", + ) + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TactN1} -r OMNIPRESENT {TactN1} -z OMNIPRESENT now-2295h -d OMNIPRESENT {TremN} {csk2_name}", + cwd="ns3", + ) + # Set key rollover relationship. + set_key_relationship(csk1_name, csk2_name) + # Signing. + render_and_sign_zone(zonename, [csk1_name, csk2_name], extra_options=f"-z -G {cds}") + + return zones + + +def configure_enable_dnssec(tld: str, policy: str) -> List[Zone]: + # The zones at enable-dnssec.$tld represent the various steps of the + # initial signing of a zone. + zones = [] + zone = f"enable-dnssec.{tld}" + keygen = EnvCmd("KEYGEN", f"-k {policy} -l kasp.conf") + settime = EnvCmd("SETTIME", "-s") + + # Step 1: + # This is an unsigned zone and named should perform the initial steps of + # introducing the DNSSEC records in the right order. + zonename = f"step1.{zone}" + zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3"))) + isctest.log.info(f"setup {zonename}") + render_and_sign_zone(zonename, [], signing=False) + + # Step 2: + # The DNSKEY has been published long enough to become OMNIPRESENT. + zonename = f"step2.{zone}" + zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3"))) + isctest.log.info(f"setup {zonename}") + # DNSKEY TTL: 300 seconds + # zone-propagation-delay: 5 minutes (300 seconds) + # publish-safety: 5 minutes (300 seconds) + # Total: 900 seconds + TpubN = "now-900s" + keytimes = f"-P {TpubN} -A {TpubN}" + # Key generation. + csk_name = keygen(f"{keytimes} {zonename}", cwd="ns3").out.strip() + settime( + f"-g OMNIPRESENT -k RUMOURED {TpubN} -r RUMOURED {TpubN} -z RUMOURED {TpubN} -d HIDDEN {TpubN} {csk_name}", + cwd="ns3", + ) + # Signing. + render_and_sign_zone(zonename, [csk_name], extra_options="-z") + + # Step 3: + # The zone signatures have been published long enough to become OMNIPRESENT. + zonename = f"step3.{zone}" + zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3"))) + isctest.log.info(f"setup {zonename}") + # Passed time since publication: + # max-zone-ttl: 12 hours (43200 seconds) + # zone-propagation-delay: 5 minutes (300 seconds) + # We can submit the DS now. + TpubN = "now-43500s" + keytimes = f"-P {TpubN} -A {TpubN}" + # Key generation. + csk_name = keygen(f"{keytimes} {zonename}", cwd="ns3").out.strip() + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TpubN} -r OMNIPRESENT {TpubN} -z RUMOURED {TpubN} -d HIDDEN {TpubN} {csk_name}", + cwd="ns3", + ) + # Signing. + render_and_sign_zone(zonename, [csk_name], extra_options="-z") + + # Step 4: + # The DS has been submitted long enough ago to 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}") + # 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 = f"-P {TpubN} -A {TpubN} -P sync {TsbmN}" + # Key generation. + csk_name = keygen(f"{keytimes} {zonename}", cwd="ns3").out.strip() + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TpubN} -r OMNIPRESENT {TpubN} -z OMNIPRESENT {TsbmN} -d RUMOURED {TpubN} -P ds {TsbmN} {csk_name}", + cwd="ns3", + ) + # Signing. + render_and_sign_zone(zonename, [csk_name], extra_options="-z") + + return zones + + +def configure_going_insecure(tld: str, reconfig: bool = False) -> List[Zone]: + zones = [] + keygen = EnvCmd("KEYGEN", "-a ECDSA256 -L 7200") + settime = EnvCmd("SETTIME", "-s") + + # The child zones (step1, step2) beneath these zones represent the various + # steps of unsigning a zone. + for zone in [f"going-insecure.{tld}", f"going-insecure-dynamic.{tld}"]: + # Set up a zone with dnssec-policy that is going insecure. + + # Step 1: + 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. + TpubN = "now-10d" + TsbmN = "now-12955mi" + keytimes = f"-P {TpubN} -A {TpubN}" + cdstimes = f"-P sync {TsbmN}" + # Key generation. + ksk_name = keygen( + f"-f KSK {keytimes} {cdstimes} {zonename}", cwd="ns3" + ).out.strip() + zsk_name = keygen(f"{keytimes} {zonename}", cwd="ns3").out.strip() + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TpubN} -r OMNIPRESENT {TpubN} -d OMNIPRESENT {TpubN} {ksk_name}", + cwd="ns3", + ) + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TpubN} -z OMNIPRESENT {TpubN} {zsk_name}", + cwd="ns3", + ) + # Signing. + render_and_sign_zone(zonename, [ksk_name, zsk_name]) + + if reconfig: + # Step 2: + zonename = f"step2.{zone}" + zones.append( + Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")) + ) + isctest.log.info(f"setup {zonename}") + # The DS was withdrawn from the parent zone 26 hours ago. + TremN = "now-26h" + keytimes = f"-P {TpubN} -A {TpubN} -I {TremN} -D now" + cdstimes = f"-P sync {TsbmN} -D sync {TremN}" + # Key generation. + ksk_name = keygen( + f"-f KSK {keytimes} {cdstimes} {zonename}", cwd="ns3" + ).out.strip() + zsk_name = keygen(f"{keytimes} {zonename}", cwd="ns3").out.strip() + settime( + f"-g HIDDEN -k OMNIPRESENT {TpubN} -r OMNIPRESENT {TpubN} -d UNRETENTIVE {TremN} -D ds {TremN} {ksk_name}", + cwd="ns3", + ) + settime( + f"-g HIDDEN -k OMNIPRESENT {TpubN} -z OMNIPRESENT {TpubN} {zsk_name}", + cwd="ns3", + ) + # Fake lifetime of old algorithm keys. + fake_lifetime(ksk_name, 0) + fake_lifetime(zsk_name, 5184000) + # Signing. + render_and_sign_zone(zonename, [ksk_name, zsk_name], extra_options="-P") + + return zones + + +def configure_straight2none(tld: str) -> List[Zone]: + # These zones are going straight to "none" policy. This is undefined behavior. + zones = [] + keygen = EnvCmd("KEYGEN", "-k default") + settime = EnvCmd("SETTIME", "-s") + + TpubN = "now-10d" + TsbmN = "now-12955mi" + keytimes = f"-P {TpubN} -A {TpubN} -P sync {TsbmN}" + + zonename = f"going-straight-to-none.{tld}" + zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3"))) + isctest.log.info(f"setup {zonename}") + # Key generation. + csk_name = keygen(f"-f KSK {keytimes} {zonename}", cwd="ns3").out.strip() + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TpubN} -r OMNIPRESENT {TpubN} -z OMNIPRESENT {TpubN} -d OMNIPRESENT {TpubN} {csk_name}", + cwd="ns3", + ) + # Signing. + render_and_sign_zone(zonename, [csk_name], extra_options="-z") + + zonename = f"going-straight-to-none-dynamic.{tld}" + zones.append( + Zone(zonename, f"{zonename}.db.signed", Nameserver("ns3", "10.53.0.3")) + ) + isctest.log.info(f"setup {zonename}") + # Key generation. + csk_name = keygen(f"-f KSK {keytimes} {zonename}", cwd="ns3").out.strip() + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TpubN} -r OMNIPRESENT {TpubN} -z OMNIPRESENT {TpubN} -d OMNIPRESENT {TpubN} {csk_name}", + cwd="ns3", + ) + # Signing. + render_and_sign_zone(zonename, [csk_name], extra_options="-z -O full") + + 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 = EnvCmd("KEYGEN", "-a ECDSAP256SHA256 -L 7200") + settime = EnvCmd("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").out.strip() + zsk_name = keygen(f"{keytimes} {zonename}", cwd="ns3").out.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").out.strip() + zsk_name = keygen(f"{keytimes} {zonename}", cwd="ns3").out.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").out.strip() + ksk2_name = keygen(f"-f KSK {newtimes} {zonename}", cwd="ns3").out.strip() + zsk_name = keygen(f"{zsktimes} {zonename}", cwd="ns3").out.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").out.strip() + ksk2_name = keygen(f"-f KSK {newtimes} {zonename}", cwd="ns3").out.strip() + zsk_name = keygen(f"{zsktimes} {zonename}", cwd="ns3").out.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").out.strip() + ksk2_name = keygen(f"-f KSK {newtimes} {zonename}", cwd="ns3").out.strip() + zsk_name = keygen(f"{zsktimes} {zonename}", cwd="ns3").out.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").out.strip() + ksk2_name = keygen(f"-f KSK {newtimes} {zonename}", cwd="ns3").out.strip() + zsk_name = keygen(f"{zsktimes} {zonename}", cwd="ns3").out.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 + + +def configure_ksk_3crowd(tld: str) -> List[Zone]: + # Test #2375, the "three is a crowd" bug, where a new key is introduced but the + # previous rollover has not finished yet. In other words, we have a key KEY2 + # that is the successor of key KEY1, and we introduce a new key KEY3 that is + # the successor of key KEY2: + # + # KEY1 < KEY2 < KEY3. + # + # The expected behavior is that all three keys remain in the zone, and not + # the bug behavior where KEY2 is removed and immediately replaced with KEY3. + # + zones = [] + cds = "cds:sha-256" + keygen = EnvCmd("KEYGEN", "-a ECDSAP256SHA256 -L 7200") + settime = EnvCmd("SETTIME", "-s") + + # Set up a zone that has a KSK (KEY1) and have the successor key (KEY2) + # published as well. + zonename = f"three-is-a-crowd.{tld}" + zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3"))) + isctest.log.info(f"setup {zonename}") + # These times are the same as step3.ksk-doubleksk.autosign. + TpubN = "now-60d" + TactN = "now-1413h" + TretN = "now" + TremN = "now+50h" + TpubN1 = "now-27h" + TactN1 = TretN + 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").out.strip() + ksk2_name = keygen(f"-f KSK {newtimes} {zonename}", cwd="ns3").out.strip() + zsk_name = keygen(f"{zsktimes} {zonename}", cwd="ns3").out.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}" + ) + + return zones + + +def configure_zsk_prepub(tld: str) -> List[Zone]: + # The zones at zsk-prepub.$tld represent the various steps of a ZSK + # Pre-Publication rollover. + zones = [] + zone = f"zsk-prepub.{tld}" + keygen = EnvCmd("KEYGEN", "-a ECDSAP256SHA256 -L 3600") + settime = EnvCmd("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").out.strip() + zsk_name = keygen(f"{keytimes} {zonename}", cwd="ns3").out.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]) + + # Step 2: + # It is time to pre-publish the successor ZSK. + zonename = f"step2.{zone}" + zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3"))) + isctest.log.info(f"setup {zonename}") + # According to RFC 7583: + # Tact(N) = now + Ipub - Lzsk = now + 26h - 30d + # = now + 26h - 30d = now − 694h + TactN = "now-694h" + keytimes = f"-P {TactN} -A {TactN}" + # Key generation. + ksk_name = keygen(f"-f KSK {keytimes} {zonename}", cwd="ns3").out.strip() + zsk_name = keygen(f"{keytimes} {zonename}", cwd="ns3").out.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]) + + # Step 3: + # After the publication interval has passed the DNSKEY of the successor ZSK + # is OMNIPRESENT and the zone can thus be signed with the successor ZSK. + 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: + # Tpub(N+1) <= Tact(N) + Lzsk - Ipub + # Tact(N+1) = Tact(N) + Lzsk + # + # Tact(N) = now - Lzsk = now - 30d + # Tpub(N+1) = now - Ipub = now - 26h + # Tact(N+1) = now + # Tret(N) = now + # Trem(N) = now + Iret = now + Dsign + Dprp + TTLsig + retire-safety = 8d1h = now + 241h + TactN = "now-30d" + TpubN1 = "now-26h" + TactN1 = "now" + TremN = "now+241h" + keytimes = f"-P {TactN} -A {TactN}" + oldtimes = f"-P {TactN} -A {TactN} -I {TactN1} -D {TremN}" + newtimes = f"-P {TpubN1} -A {TactN1}" + # Key generation. + ksk_name = keygen(f"-f KSK {keytimes} {zonename}", cwd="ns3").out.strip() + zsk1_name = keygen(f"{oldtimes} {zonename}", cwd="ns3").out.strip() + zsk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").out.strip() + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -d OMNIPRESENT {TactN} {ksk_name}", + cwd="ns3", + ) + settime( + f"-g HIDDEN -k OMNIPRESENT {TactN} -z OMNIPRESENT {TactN} {zsk1_name}", + cwd="ns3", + ) + settime( + f"-g OMNIPRESENT -k RUMOURED {TpubN1} -z HIDDEN {TpubN1} {zsk2_name}", cwd="ns3" + ) + # Set key rollover relationship. + set_key_relationship(zsk1_name, zsk2_name) + # Signing. + render_and_sign_zone(zonename, [ksk_name, zsk1_name, zsk2_name]) + + # Step 4: + # After the retire interval has passed the predecessor DNSKEY can be + # removed from the zone. + zonename = f"step4.{zone}" + zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3"))) + isctest.log.info(f"setup {zonename}") + # Lzsk: 30d + # Ipub: 26h + # Dsgn: 1w + # Dprp: 1h + # TTLsig: 1d + # retire-safety: 2d + # + # According to RFC 7583: + # Iret = Dsgn + Dprp + TTLsig (+retire-safety) + # Iret = 1w + 1h + 1d + 2d = 10d1h = 241h + # + # Tact(N) = now - Iret - Lzsk + # = now - 241h - 30d = now - 241h - 720h + # = now - 961h + # Tpub(N+1) = now - Iret - Ipub + # = now - 241h - 26h + # = now - 267h + # Tact(N+1) = now - Iret = now - 241h + TactN = "now-961h" + TpubN1 = "now-267h" + TactN1 = "now-241h" + TremN = "now" + keytimes = f"-P {TactN} -A {TactN}" + oldtimes = f"-P {TactN} -A {TactN} -I {TactN1} -D {TremN}" + newtimes = f"-P {TpubN1} -A {TactN1}" + # Key generation. + ksk_name = keygen(f"-f KSK {keytimes} {zonename}", cwd="ns3").out.strip() + zsk1_name = keygen(f"{oldtimes} {zonename}", cwd="ns3").out.strip() + zsk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").out.strip() + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -d OMNIPRESENT {TactN} {ksk_name}", + cwd="ns3", + ) + settime( + f"-g HIDDEN -k OMNIPRESENT {TactN} -z UNRETENTIVE {TactN1} {zsk1_name}", + cwd="ns3", + ) + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TactN1} -z RUMOURED {TactN1} {zsk2_name}", + cwd="ns3", + ) + # Set key rollover relationship. + set_key_relationship(zsk1_name, zsk2_name) + # Signing. + render_and_sign_zone(zonename, [ksk_name, zsk1_name, zsk2_name]) + + # 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 (2h). + # Tact(N) = now - 961h - 2h = now - 963h + # Tpub(N+1) = now - 267h - 2h = now - 269h + # Tact(N+1) = now - 241h - 2h = now - 243h + # Trem(N) = Tact(N+1) + Iret = now -2h + TactN = "now-963h" + TremN = "now-2h" + TpubN1 = "now-269h" + TactN1 = "now-243h" + TremN = "now-2h" + keytimes = f"-P {TactN} -A {TactN}" + oldtimes = f"-P {TactN} -A {TactN} -I {TactN1} -D {TremN}" + newtimes = f"-P {TpubN1} -A {TactN1}" + # Key generation. + ksk_name = keygen(f"-f KSK {keytimes} {zonename}", cwd="ns3").out.strip() + zsk1_name = keygen(f"{oldtimes} {zonename}", cwd="ns3").out.strip() + zsk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").out.strip() + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -d OMNIPRESENT {TactN} {ksk_name}", + cwd="ns3", + ) + settime( + f"-g HIDDEN -k UNRETENTIVE {TremN} -z HIDDEN {TremN} {zsk1_name}", cwd="ns3" + ) + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TactN1} -z OMNIPRESENT {TremN} {zsk2_name}", + cwd="ns3", + ) + # Set key rollover relationship. + set_key_relationship(zsk1_name, zsk2_name) + # Signing. + render_and_sign_zone(zonename, [ksk_name, zsk1_name, zsk2_name]) + + # 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). + TactN = "now-964h" + TremN = "now-3h" + TpubN1 = "now-270h" + TactN1 = "now-244h" + TremN = "now-3h" + keytimes = f"-P {TactN} -A {TactN}" + oldtimes = f"-P {TactN} -A {TactN} -I {TactN1} -D {TremN}" + newtimes = f"-P {TpubN1} -A {TactN1}" + # Key generation. + ksk_name = keygen(f"-f KSK {keytimes} {zonename}", cwd="ns3").out.strip() + zsk1_name = keygen(f"{oldtimes} {zonename}", cwd="ns3").out.strip() + zsk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").out.strip() + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -d OMNIPRESENT {TactN} {ksk_name}", + cwd="ns3", + ) + settime(f"-g HIDDEN -k HIDDEN {TremN} -z HIDDEN {TremN} {zsk1_name}", cwd="ns3") + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TactN1} -z OMNIPRESENT {TremN} {zsk2_name}", + cwd="ns3", + ) + # Set key rollover relationship. + set_key_relationship(zsk1_name, zsk2_name) + # Signing. + render_and_sign_zone(zonename, [ksk_name, zsk1_name, zsk2_name]) + + return zones diff --git a/bin/tests/system/rollover/setup.sh b/bin/tests/system/rollover/setup.sh deleted file mode 100644 index f465ddf46a..0000000000 --- a/bin/tests/system/rollover/setup.sh +++ /dev/null @@ -1,59 +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" - echo "$zone" >>zones -} - -# Make lines shorter by storing key states in environment variables. -H="HIDDEN" -R="RUMOURED" -O="OMNIPRESENT" -U="UNRETENTIVE" - -# Zone to test manual rollover. -setup manual-rollover.kasp -T="now-7d" -keytimes="-P $T -A $T" -KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $keytimes $zone 2>keygen.out.$zone.1) -ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $keytimes $zone 2>keygen.out.$zone.2) -$SETTIME -s -g $O -d $O $T -k $O $T -r $O $T "$KSK" >settime.out.$zone.1 2>&1 -$SETTIME -s -g $O -k $O $T -z $O $T "$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 -PS -x -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - -# Zone to test manual rollover. -setup manual-rollover-zrrsig-rumoured.kasp -T2="now-2h" -zsktimes="-P $T2 -A $T2" -KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $keytimes $zone 2>keygen.out.$zone.1) -ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $zsktimes $zone 2>keygen.out.$zone.2) -$SETTIME -s -g $O -d $O $T -k $O $T -r $O $T "$KSK" >settime.out.$zone.1 2>&1 -$SETTIME -s -g $O -k $O $T2 -z $R $T2 "$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 -PS -x -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 diff --git a/bin/tests/system/rollover/tests_rollover_manual.py b/bin/tests/system/rollover/tests_rollover_manual.py index 75ae7d86c7..f2c9871f4d 100644 --- a/bin/tests/system/rollover/tests_rollover_manual.py +++ b/bin/tests/system/rollover/tests_rollover_manual.py @@ -13,9 +13,86 @@ from datetime import timedelta import os import isctest -from isctest.kasp import KeyTimingMetadata, Ipub, Iret +from isctest.kasp import KeyTimingMetadata, Ipub, Iret, private_type_record +from isctest.template import Nameserver, Zone +from isctest.run import EnvCmd + +from rollover.common import default_algorithm +from rollover.setup import ( + configure_root, + configure_tld, +) + + +def setup_zone(zone, ksk_time, ksk_settime, zsk_time, zsk_settime) -> Zone: + templates = isctest.template.TemplateEngine(".") + alg = default_algorithm() + keygen = EnvCmd("KEYGEN", f"-q -a {alg.number} -b {alg.bits} -L 3600") + signer = EnvCmd("SIGNER", "-S -g") + settime = EnvCmd("SETTIME", "-s") + + isctest.log.info(f"setup {zone}") + template = "template.db.j2.manual" + outfile = f"{zone}.db" + + # Configuration. + isctest.log.info(f"setup {zone}") + template = "template.db.j2.manual" + outfile = f"{zone}.db" + # Key generation. + ksk_name = keygen( + f"-f KSK -P {ksk_time} -A {ksk_time} {zone}", cwd="ns3" + ).out.strip() + zsk_name = keygen(f"-P {zsk_time} -A {zsk_time} {zone}", cwd="ns3").out.strip() + settime(f"{ksk_settime} {ksk_name}", cwd="ns3") + settime(f"{zsk_settime} {zsk_name}", cwd="ns3") + # Signing. + ksk = isctest.kasp.Key(ksk_name, keydir="ns3") + zsk = isctest.kasp.Key(zsk_name, keydir="ns3") + dnskeys = [ksk.dnskey, zsk.dnskey] + privaterrs = [ + private_type_record(zone, ksk), + private_type_record(zone, zsk), + ] + tdata = { + "fqdn": f"{zone}.", + "dnskeys": dnskeys, + "privaterrs": privaterrs, + } + templates.render(f"ns3/{outfile}", tdata, template=f"ns3/{template}") + signer(f"-P -x -O raw -o {zone} -f {outfile}.signed {outfile}", cwd="ns3") + + return Zone(zone, outfile, Nameserver("ns3", "10.53.0.3")) + + +def bootstrap(): + zones = [] + + zone = "manual-rollover.kasp" + when = "now-7d" + ksk_settime = f"-g OMNIPRESENT -k OMNIPRESENT {when} -r OMNIPRESENT {when} -d OMNIPRESENT {when}" + zsk_settime = f"-g OMNIPRESENT -k OMNIPRESENT {when} -z OMNIPRESENT {when}" + zones.append(setup_zone(zone, when, ksk_settime, when, zsk_settime)) + + zone = "manual-rollover-zrrsig-rumoured.kasp" + then = "now-2h" + ksk_settime = f"-g OMNIPRESENT -k OMNIPRESENT {when} -r OMNIPRESENT {when} -d OMNIPRESENT {when}" + zsk_settime = f"-g OMNIPRESENT -k OMNIPRESENT {then} -z RUMOURED {then}" + zones.append(setup_zone(zone, when, ksk_settime, then, zsk_settime)) + + # Chain of trust. + data = { + "tlds": [], + "trust_anchors": [], + } + tld = configure_tld("kasp", zones) + data["tlds"].append("kasp") + + ta = configure_root([tld]) + data["trust_anchors"].append(ta) + + return data -from rollover.common import pytestmark # pylint: disable=unused-import CONFIG = { "dnskey-ttl": timedelta(hours=1),