From e620b29e35c7480cb595ce41493111752936fe29 Mon Sep 17 00:00:00 2001 From: Matthijs Mekking Date: Tue, 25 Nov 2025 10:54:57 +0100 Subject: [PATCH 01/16] Move ns6 to ns3 in rollover tests There is no difference, so we are going to make it consistent. This will make it easier to add a chain of trust for these zones (to be done in a future commit). --- .../{ns6 => ns3}/csk1.conf.j2 | 0 .../{ns6 => ns3}/csk2.conf.j2 | 0 .../ns3/named.common.conf.j2 | 1 + .../{ns6 => ns3}/named.conf.j2 | 0 .../rollover-algo-csk/ns3/template.db.in | 1 + .../ns6/named.common.conf.j2 | 1 - .../rollover-algo-csk/ns6/template.db.in | 1 - bin/tests/system/rollover-algo-csk/setup.sh | 2 +- .../tests_rollover_algo_csk_initial.py | 6 +- .../tests_rollover_algo_csk_reconfig.py | 76 +++++++++--------- .../{ns6 => ns3}/kasp.conf.j2 | 0 .../ns3/named.common.conf.j2 | 1 + .../{ns6 => ns3}/named.conf.j2 | 0 .../rollover-algo-ksk-zsk/ns3/template.db.in | 1 + .../ns6/named.common.conf.j2 | 1 - .../rollover-algo-ksk-zsk/ns6/template.db.in | 1 - .../system/rollover-algo-ksk-zsk/setup.sh | 2 +- .../tests_rollover_algo_ksk_zsk_initial.py | 6 +- .../tests_rollover_algo_ksk_zsk_reconfig.py | 80 +++++++++---------- .../{ns6 => ns3}/dynamic2inline.kasp.db | 0 .../ns3/named.common.conf.j2 | 1 + .../{ns6 => ns3}/named.conf.j2 | 0 .../ns3/template.db.in | 1 + .../ns6/named.common.conf.j2 | 35 -------- .../ns6/template.db.in | 27 ------- .../tests_rollover_dynamic2inline.py | 14 ++-- .../{ns6 => ns3}/kasp.conf.j2 | 0 .../ns3/named.common.conf.j2 | 1 + .../{ns6 => ns3}/named.conf.j2 | 0 .../ns3/template.db.in | 1 + .../ns6/named.common.conf.j2 | 1 - .../ns6/template.db.in | 1 - .../system/rollover-going-insecure/setup.sh | 2 +- .../tests_rollover_going_insecure_initial.py | 6 +- .../tests_rollover_going_insecure_reconfig.py | 18 ++--- .../{ns6 => ns3}/kasp.conf.j2 | 0 .../rollover-lifetime/ns3/limit-lifetime.db | 1 + .../rollover-lifetime/ns3/longer-lifetime.db | 1 + .../ns3/named.common.conf.j2 | 1 + .../{ns6 => ns3}/named.conf.j2 | 8 +- .../rollover-lifetime/ns3/shorter-lifetime.db | 1 + .../rollover-lifetime/ns3/unlimit-lifetime.db | 1 + .../rollover-lifetime/ns6/limit-lifetime.db | 1 - .../rollover-lifetime/ns6/longer-lifetime.db | 1 - .../ns6/named.common.conf.j2 | 1 - .../rollover-lifetime/ns6/shorter-lifetime.db | 1 - .../rollover-lifetime/ns6/unlimit-lifetime.db | 1 - .../tests_rollover_lifetime_initial.py | 8 +- .../tests_rollover_lifetime_reconfig.py | 22 ++--- .../rollover-straight2none/ns3/kasp.conf.j2 | 1 + .../ns3/named.common.conf.j2 | 1 + .../{ns6 => ns3}/named.conf.j2 | 0 .../rollover-straight2none/ns3/template.db.in | 1 + .../rollover-straight2none/ns6/kasp.conf.j2 | 1 - .../ns6/named.common.conf.j2 | 1 - .../rollover-straight2none/ns6/template.db.in | 1 - .../system/rollover-straight2none/setup.sh | 2 +- ...> tests_rollover_straight2none_initial.py} | 6 +- ... tests_rollover_straight2none_reconfig.py} | 14 ++-- 59 files changed, 152 insertions(+), 212 deletions(-) rename bin/tests/system/rollover-algo-csk/{ns6 => ns3}/csk1.conf.j2 (100%) rename bin/tests/system/rollover-algo-csk/{ns6 => ns3}/csk2.conf.j2 (100%) create mode 120000 bin/tests/system/rollover-algo-csk/ns3/named.common.conf.j2 rename bin/tests/system/rollover-algo-csk/{ns6 => ns3}/named.conf.j2 (100%) create mode 120000 bin/tests/system/rollover-algo-csk/ns3/template.db.in delete mode 120000 bin/tests/system/rollover-algo-csk/ns6/named.common.conf.j2 delete mode 120000 bin/tests/system/rollover-algo-csk/ns6/template.db.in rename bin/tests/system/rollover-algo-ksk-zsk/{ns6 => ns3}/kasp.conf.j2 (100%) create mode 120000 bin/tests/system/rollover-algo-ksk-zsk/ns3/named.common.conf.j2 rename bin/tests/system/rollover-algo-ksk-zsk/{ns6 => ns3}/named.conf.j2 (100%) create mode 120000 bin/tests/system/rollover-algo-ksk-zsk/ns3/template.db.in delete mode 120000 bin/tests/system/rollover-algo-ksk-zsk/ns6/named.common.conf.j2 delete mode 120000 bin/tests/system/rollover-algo-ksk-zsk/ns6/template.db.in rename bin/tests/system/rollover-dynamic2inline/{ns6 => ns3}/dynamic2inline.kasp.db (100%) create mode 120000 bin/tests/system/rollover-dynamic2inline/ns3/named.common.conf.j2 rename bin/tests/system/rollover-dynamic2inline/{ns6 => ns3}/named.conf.j2 (100%) create mode 120000 bin/tests/system/rollover-dynamic2inline/ns3/template.db.in delete mode 100644 bin/tests/system/rollover-dynamic2inline/ns6/named.common.conf.j2 delete mode 100644 bin/tests/system/rollover-dynamic2inline/ns6/template.db.in rename bin/tests/system/rollover-going-insecure/{ns6 => ns3}/kasp.conf.j2 (100%) create mode 120000 bin/tests/system/rollover-going-insecure/ns3/named.common.conf.j2 rename bin/tests/system/rollover-going-insecure/{ns6 => ns3}/named.conf.j2 (100%) create mode 120000 bin/tests/system/rollover-going-insecure/ns3/template.db.in delete mode 120000 bin/tests/system/rollover-going-insecure/ns6/named.common.conf.j2 delete mode 120000 bin/tests/system/rollover-going-insecure/ns6/template.db.in rename bin/tests/system/rollover-lifetime/{ns6 => ns3}/kasp.conf.j2 (100%) create mode 120000 bin/tests/system/rollover-lifetime/ns3/limit-lifetime.db create mode 120000 bin/tests/system/rollover-lifetime/ns3/longer-lifetime.db create mode 120000 bin/tests/system/rollover-lifetime/ns3/named.common.conf.j2 rename bin/tests/system/rollover-lifetime/{ns6 => ns3}/named.conf.j2 (91%) create mode 120000 bin/tests/system/rollover-lifetime/ns3/shorter-lifetime.db create mode 120000 bin/tests/system/rollover-lifetime/ns3/unlimit-lifetime.db delete mode 120000 bin/tests/system/rollover-lifetime/ns6/limit-lifetime.db delete mode 120000 bin/tests/system/rollover-lifetime/ns6/longer-lifetime.db delete mode 120000 bin/tests/system/rollover-lifetime/ns6/named.common.conf.j2 delete mode 120000 bin/tests/system/rollover-lifetime/ns6/shorter-lifetime.db delete mode 120000 bin/tests/system/rollover-lifetime/ns6/unlimit-lifetime.db create mode 120000 bin/tests/system/rollover-straight2none/ns3/kasp.conf.j2 create mode 120000 bin/tests/system/rollover-straight2none/ns3/named.common.conf.j2 rename bin/tests/system/rollover-straight2none/{ns6 => ns3}/named.conf.j2 (100%) create mode 120000 bin/tests/system/rollover-straight2none/ns3/template.db.in delete mode 120000 bin/tests/system/rollover-straight2none/ns6/kasp.conf.j2 delete mode 120000 bin/tests/system/rollover-straight2none/ns6/named.common.conf.j2 delete mode 120000 bin/tests/system/rollover-straight2none/ns6/template.db.in rename bin/tests/system/rollover-straight2none/{tests_rollver_straight2none_initial.py => tests_rollover_straight2none_initial.py} (86%) rename bin/tests/system/rollover-straight2none/{tests_rollver_straight2none_reconfig.py => tests_rollover_straight2none_reconfig.py} (77%) diff --git a/bin/tests/system/rollover-algo-csk/ns6/csk1.conf.j2 b/bin/tests/system/rollover-algo-csk/ns3/csk1.conf.j2 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.j2 diff --git a/bin/tests/system/rollover-algo-csk/ns6/csk2.conf.j2 b/bin/tests/system/rollover-algo-csk/ns3/csk2.conf.j2 similarity index 100% rename from bin/tests/system/rollover-algo-csk/ns6/csk2.conf.j2 rename to bin/tests/system/rollover-algo-csk/ns3/csk2.conf.j2 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.in b/bin/tests/system/rollover-algo-csk/ns3/template.db.in new file mode 120000 index 0000000000..ce6d526285 --- /dev/null +++ b/bin/tests/system/rollover-algo-csk/ns3/template.db.in @@ -0,0 +1 @@ +../../rollover/ns3/template.db.in \ 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 index 200da1388e..c9e7ab04e5 100644 --- a/bin/tests/system/rollover-algo-csk/setup.sh +++ b/bin/tests/system/rollover-algo-csk/setup.sh @@ -14,7 +14,7 @@ # shellcheck source=conf.sh . ../conf.sh -cd "ns6" +cd "ns3" setup() { zone="$1" 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..a6c1ff81e7 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 @@ -31,11 +31,11 @@ from rollover.common import ( param("manual", "csk-algoroll-manual"), ], ) -def test_algoroll_csk_initial(ns6, tld, policy): +def test_algoroll_csk_initial(ns3, tld, policy): config = ALGOROLL_CONFIG zone = f"step1.csk-algorithm-roll.{tld}" - isctest.kasp.wait_keymgr_done(ns6, zone) + isctest.kasp.wait_keymgr_done(ns3, zone) step = { "zone": zone, @@ -45,4 +45,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..e1a7ab7a6c 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 @@ -39,14 +39,14 @@ TIME_PASSED = 0 # set in reconfigure() fixture @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 +59,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 +76,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 +105,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 +115,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 +142,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 +152,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 +170,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 +187,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 +211,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 +221,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 +239,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 +266,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 +276,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 +300,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 +310,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 +333,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/ns6/kasp.conf.j2 b/bin/tests/system/rollover-algo-ksk-zsk/ns3/kasp.conf.j2 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.j2 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.in b/bin/tests/system/rollover-algo-ksk-zsk/ns3/template.db.in new file mode 120000 index 0000000000..ce6d526285 --- /dev/null +++ b/bin/tests/system/rollover-algo-ksk-zsk/ns3/template.db.in @@ -0,0 +1 @@ +../../rollover/ns3/template.db.in \ 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 index db27d74e71..bc651b9420 100644 --- a/bin/tests/system/rollover-algo-ksk-zsk/setup.sh +++ b/bin/tests/system/rollover-algo-ksk-zsk/setup.sh @@ -14,7 +14,7 @@ # shellcheck source=conf.sh . ../conf.sh -cd "ns6" +cd "ns3" setup() { zone="$1" 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..32eea7d014 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 @@ -31,12 +31,12 @@ from rollover.common import ( param("manual"), ], ) -def test_algoroll_ksk_zsk_initial(ns6, tld): +def test_algoroll_ksk_zsk_initial(ns3, tld): 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 +47,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..15cf0f9ddd 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 @@ -39,14 +39,14 @@ TIME_PASSED = 0 # set in reconfigure() fixture @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 +59,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 +77,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 +85,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 +110,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 +120,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 +149,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 +159,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 +179,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 +196,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 +222,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 +232,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 +252,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 +284,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 +294,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 +322,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 +332,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 +357,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-dynamic2inline/ns6/dynamic2inline.kasp.db b/bin/tests/system/rollover-dynamic2inline/ns3/dynamic2inline.kasp.db similarity index 100% rename from bin/tests/system/rollover-dynamic2inline/ns6/dynamic2inline.kasp.db 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/ns3/template.db.in b/bin/tests/system/rollover-dynamic2inline/ns3/template.db.in new file mode 120000 index 0000000000..ce6d526285 --- /dev/null +++ b/bin/tests/system/rollover-dynamic2inline/ns3/template.db.in @@ -0,0 +1 @@ +../../rollover/ns3/template.db.in \ No newline at end of file diff --git a/bin/tests/system/rollover-dynamic2inline/ns6/named.common.conf.j2 b/bin/tests/system/rollover-dynamic2inline/ns6/named.common.conf.j2 deleted file mode 100644 index 9299c97846..0000000000 --- a/bin/tests/system/rollover-dynamic2inline/ns6/named.common.conf.j2 +++ /dev/null @@ -1,35 +0,0 @@ -/* - * 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. - */ - -options { - query-source address 10.53.0.6; - notify-source 10.53.0.6; - transfer-source 10.53.0.6; - port @PORT@; - pid-file "named.pid"; - listen-on { 10.53.0.6; }; - listen-on-v6 { none; }; - allow-transfer { any; }; - recursion no; - key-directory "."; - dnssec-validation no; -}; - -key rndc_key { - secret "1234abcd8765"; - algorithm @DEFAULT_HMAC@; -}; - -controls { - inet 10.53.0.6 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; -}; diff --git a/bin/tests/system/rollover-dynamic2inline/ns6/template.db.in b/bin/tests/system/rollover-dynamic2inline/ns6/template.db.in deleted file mode 100644 index f1d8b94e5a..0000000000 --- a/bin/tests/system/rollover-dynamic2inline/ns6/template.db.in +++ /dev/null @@ -1,27 +0,0 @@ -; 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 ns6 -ns6 A 10.53.0.6 - -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-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-going-insecure/ns6/kasp.conf.j2 b/bin/tests/system/rollover-going-insecure/ns3/kasp.conf.j2 similarity index 100% rename from bin/tests/system/rollover-going-insecure/ns6/kasp.conf.j2 rename to bin/tests/system/rollover-going-insecure/ns3/kasp.conf.j2 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.in b/bin/tests/system/rollover-going-insecure/ns3/template.db.in new file mode 120000 index 0000000000..ce6d526285 --- /dev/null +++ b/bin/tests/system/rollover-going-insecure/ns3/template.db.in @@ -0,0 +1 @@ +../../rollover/ns3/template.db.in \ 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 index f5d9da48a7..11213c1c83 100644 --- a/bin/tests/system/rollover-going-insecure/setup.sh +++ b/bin/tests/system/rollover-going-insecure/setup.sh @@ -14,7 +14,7 @@ # shellcheck source=conf.sh . ../conf.sh -cd "ns6" +cd "ns3" setup() { zone="$1" 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..61aa583f55 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 @@ -31,12 +31,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 +47,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..9a2d240934 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 @@ -26,9 +26,9 @@ from rollover.common import ( @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 +38,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 +61,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 +71,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 +96,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-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..ce6d526285 --- /dev/null +++ b/bin/tests/system/rollover-lifetime/ns3/limit-lifetime.db @@ -0,0 +1 @@ +../../rollover/ns3/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..ce6d526285 --- /dev/null +++ b/bin/tests/system/rollover-lifetime/ns3/longer-lifetime.db @@ -0,0 +1 @@ +../../rollover/ns3/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..ce6d526285 --- /dev/null +++ b/bin/tests/system/rollover-lifetime/ns3/shorter-lifetime.db @@ -0,0 +1 @@ +../../rollover/ns3/template.db.in \ No newline at end of file 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..ce6d526285 --- /dev/null +++ b/bin/tests/system/rollover-lifetime/ns3/unlimit-lifetime.db @@ -0,0 +1 @@ +../../rollover/ns3/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-straight2none/ns3/kasp.conf.j2 b/bin/tests/system/rollover-straight2none/ns3/kasp.conf.j2 new file mode 120000 index 0000000000..909d9909ee --- /dev/null +++ b/bin/tests/system/rollover-straight2none/ns3/kasp.conf.j2 @@ -0,0 +1 @@ +../../rollover-going-insecure/ns3/kasp.conf.j2 \ 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.in b/bin/tests/system/rollover-straight2none/ns3/template.db.in new file mode 120000 index 0000000000..ce6d526285 --- /dev/null +++ b/bin/tests/system/rollover-straight2none/ns3/template.db.in @@ -0,0 +1 @@ +../../rollover/ns3/template.db.in \ 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 index 2a42dba557..790b0e22ce 100644 --- a/bin/tests/system/rollover-straight2none/setup.sh +++ b/bin/tests/system/rollover-straight2none/setup.sh @@ -14,7 +14,7 @@ # shellcheck source=conf.sh . ../conf.sh -cd "ns6" +cd "ns3" setup() { zone="$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 86% 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..098108a6f5 100644 --- a/bin/tests/system/rollover-straight2none/tests_rollver_straight2none_initial.py +++ b/bin/tests/system/rollover-straight2none/tests_rollover_straight2none_initial.py @@ -31,11 +31,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 +45,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 77% 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..e5fe16aa3d 100644 --- a/bin/tests/system/rollover-straight2none/tests_rollver_straight2none_reconfig.py +++ b/bin/tests/system/rollover-straight2none/tests_rollover_straight2none_reconfig.py @@ -25,12 +25,12 @@ from rollover.common import ( @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 +40,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 +54,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) From f31514e65855239ad114c21d82c5e17e018dc37a Mon Sep 17 00:00:00 2001 From: Matthijs Mekking Date: Tue, 25 Nov 2025 11:17:40 +0100 Subject: [PATCH 02/16] rollover: From setup.sh to pytest bootstrap Introduce rollover/setup.py for all setup related test code. Introduce rollover/ns1 and rollover/ns2 to create a chain of trust to all rollover related test zones. The tld zones in rollover/ns2 contain a DSYNC record that at a later time will be used for testing Generalized DNS Notifications. Write a python version of private_type_record so we can put such records in the zone via jinja2 templating. --- bin/tests/system/isctest/kasp.py | 16 ++++ bin/tests/system/isctest/template.py | 14 +++ bin/tests/system/rollover/common.py | 12 +++ bin/tests/system/rollover/ns1/named.conf.j2 | 31 +++++++ .../system/rollover/ns1/root.db.j2.manual | 31 +++++++ bin/tests/system/rollover/ns2/named.conf.j2 | 49 ++++++++++ .../system/rollover/ns2/template.db.j2.manual | 40 +++++++++ .../system/rollover/ns3/named.common.conf.j2 | 14 ++- .../{template.db.in => template.db.j2.manual} | 9 +- bin/tests/system/rollover/ns3/trusted.conf.j2 | 1 + bin/tests/system/rollover/setup.py | 90 +++++++++++++++++++ bin/tests/system/rollover/setup.sh | 59 ------------ .../system/rollover/tests_rollover_manual.py | 79 +++++++++++++++- 13 files changed, 380 insertions(+), 65 deletions(-) create mode 100644 bin/tests/system/rollover/ns1/named.conf.j2 create mode 100644 bin/tests/system/rollover/ns1/root.db.j2.manual create mode 100644 bin/tests/system/rollover/ns2/named.conf.j2 create mode 100644 bin/tests/system/rollover/ns2/template.db.j2.manual rename bin/tests/system/rollover/ns3/{template.db.in => template.db.j2.manual} (82%) create mode 120000 bin/tests/system/rollover/ns3/trusted.conf.j2 create mode 100644 bin/tests/system/rollover/setup.py delete mode 100644 bin/tests/system/rollover/setup.sh 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/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/ns2/named.conf.j2 b/bin/tests/system/rollover/ns2/named.conf.j2 new file mode 100644 index 0000000000..e1f7bffdd0 --- /dev/null +++ b/bin/tests/system/rollover/ns2/named.conf.j2 @@ -0,0 +1,49 @@ +/* + * 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. + */ + +// NS2 + +options { + 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.2; }; + listen-on-v6 { none; }; + allow-transfer { any; }; + allow-notify { 10.53.0.3; }; + recursion no; + dnssec-validation no; +}; + +key rndc_key { + secret "1234abcd8765"; + algorithm @DEFAULT_HMAC@; +}; + +controls { + 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.in b/bin/tests/system/rollover/ns3/template.db.j2.manual similarity index 82% rename from bin/tests/system/rollover/ns3/template.db.in rename to bin/tests/system/rollover/ns3/template.db.j2.manual index 010b05b3cb..3903587ba9 100644 --- a/bin/tests/system/rollover/ns3/template.db.in +++ b/bin/tests/system/rollover/ns3/template.db.j2.manual @@ -10,7 +10,7 @@ ; information regarding copyright ownership. $TTL 300 -@ IN SOA mname1. . ( +@fqdn@ IN SOA mname1. . ( 1 ; serial 20 ; refresh (20 seconds) 20 ; retry (20 seconds) @@ -25,3 +25,10 @@ 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..c924eb497c --- /dev/null +++ b/bin/tests/system/rollover/setup.py @@ -0,0 +1,90 @@ +# 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 rollover.common import default_algorithm + + +class CmdHelper: + def __init__(self, env_name: str, base_params: str = ""): + self.bin_path = os.environ[env_name] + self.base_params = base_params + + def __call__(self, params: str, **kwargs): + args = f"{self.base_params} {params}".split() + return isctest.run.cmd([self.bin_path] + args, **kwargs).stdout.decode("utf-8") + + +def configure_tld(zonename: str, delegations: List[Zone]) -> Zone: + templates = isctest.template.TemplateEngine(".") + alg = default_algorithm() + keygen = CmdHelper("KEYGEN", f"-q -a {alg.number} -b {alg.bits} -L 3600") + signer = CmdHelper("SIGNER", "-S -g") + + isctest.log.info(f"create {zonename} zone with delegations and sign") + + for zone in delegations: + shutil.copy(f"{zone.ns.name}/dsset-{zone.name}.", "ns2/") + + ksk_name = keygen(f"-f KSK {zonename}", cwd="ns2").strip() + zsk_name = keygen(f"{zonename}", cwd="ns2").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 = CmdHelper("KEYGEN", f"-q -a {alg.number} -b {alg.bits} -L 3600") + signer = CmdHelper("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").strip() + zsk_name = keygen(f"{zonename}", cwd="ns1").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") 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..75a705fca1 100644 --- a/bin/tests/system/rollover/tests_rollover_manual.py +++ b/bin/tests/system/rollover/tests_rollover_manual.py @@ -13,9 +13,84 @@ 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 rollover.common import default_algorithm +from rollover.setup import ( + CmdHelper, + 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 = CmdHelper("KEYGEN", f"-q -a {alg.number} -b {alg.bits} -L 3600") + signer = CmdHelper("SIGNER", "-S -g") + settime = CmdHelper("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").strip() + zsk_name = keygen(f"-P {zsk_time} -A {zsk_time} {zone}", cwd="ns3").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), From 3a6ed195fa9b027fe89bae85e6e55e607b6e29ce Mon Sep 17 00:00:00 2001 From: Matthijs Mekking Date: Thu, 27 Nov 2025 10:37:22 +0100 Subject: [PATCH 03/16] rollover-algo-csk: From setup.sh to pytest bootstrap Symlink ns1 and ns2 to rollover/ns1 and rollover/ns2. Symlink ns3/template.db.j2.manual to rollover/ns3/template.db.j2.manual. Since the bootstrapping is done before the templates are rendered automatically, replace @DEFAULT_ALGORITHM@ in ns3/csk2.conf.j2 to ecdsa256 and rename to ns3/csk2.conf. --- bin/tests/system/rollover-algo-csk/ns1 | 1 + bin/tests/system/rollover-algo-csk/ns2 | 1 + .../ns3/{csk1.conf.j2 => csk1.conf} | 0 .../ns3/{csk2.conf.j2 => csk2.conf} | 4 +- .../rollover-algo-csk/ns3/template.db.in | 1 - .../ns3/template.db.j2.manual | 1 + .../rollover-algo-csk/ns3/trusted.conf.j2 | 1 + bin/tests/system/rollover-algo-csk/setup.sh | 152 ---------------- .../tests_rollover_algo_csk_initial.py | 42 ++++- .../tests_rollover_algo_csk_reconfig.py | 31 ++++ bin/tests/system/rollover/setup.py | 171 ++++++++++++++++++ 11 files changed, 246 insertions(+), 159 deletions(-) create mode 120000 bin/tests/system/rollover-algo-csk/ns1 create mode 120000 bin/tests/system/rollover-algo-csk/ns2 rename bin/tests/system/rollover-algo-csk/ns3/{csk1.conf.j2 => csk1.conf} (100%) rename bin/tests/system/rollover-algo-csk/ns3/{csk2.conf.j2 => csk2.conf} (90%) delete mode 120000 bin/tests/system/rollover-algo-csk/ns3/template.db.in create mode 120000 bin/tests/system/rollover-algo-csk/ns3/template.db.j2.manual create mode 120000 bin/tests/system/rollover-algo-csk/ns3/trusted.conf.j2 delete mode 100644 bin/tests/system/rollover-algo-csk/setup.sh 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/ns3/csk1.conf.j2 b/bin/tests/system/rollover-algo-csk/ns3/csk1.conf similarity index 100% rename from bin/tests/system/rollover-algo-csk/ns3/csk1.conf.j2 rename to bin/tests/system/rollover-algo-csk/ns3/csk1.conf diff --git a/bin/tests/system/rollover-algo-csk/ns3/csk2.conf.j2 b/bin/tests/system/rollover-algo-csk/ns3/csk2.conf similarity index 90% rename from bin/tests/system/rollover-algo-csk/ns3/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/ns3/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/template.db.in b/bin/tests/system/rollover-algo-csk/ns3/template.db.in deleted file mode 120000 index ce6d526285..0000000000 --- a/bin/tests/system/rollover-algo-csk/ns3/template.db.in +++ /dev/null @@ -1 +0,0 @@ -../../rollover/ns3/template.db.in \ No newline at end of file diff --git a/bin/tests/system/rollover-algo-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/setup.sh b/bin/tests/system/rollover-algo-csk/setup.sh deleted file mode 100644 index c9e7ab04e5..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 "ns3" - -setup() { - zone="$1" - echo_i "setting up zone: $zone" - zonefile="${zone}.db" - infile="${zone}.db.infile" -} - -# Make lines shorter by storing key states in environment variables. -H="HIDDEN" -R="RUMOURED" -O="OMNIPRESENT" -U="UNRETENTIVE" - -# -# The zones at 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 a6c1ff81e7..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,18 +22,52 @@ 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(ns3, 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(ns3, zone) 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 e1a7ab7a6c..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,12 +32,43 @@ 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(ns3, templates): global TIME_PASSED # pylint: disable=global-statement diff --git a/bin/tests/system/rollover/setup.py b/bin/tests/system/rollover/setup.py index c924eb497c..5124bd46ab 100644 --- a/bin/tests/system/rollover/setup.py +++ b/bin/tests/system/rollover/setup.py @@ -88,3 +88,174 @@ def configure_root(delegations: List[Zone]) -> TrustAnchor: signer(f"-P -x -O full -o {zonename} -f {outfile} {infile}", cwd="ns1") return ksk.into_ta("static-ds") + + +def render_and_sign_zone(zonename: str, keys: List[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}") + + signer = CmdHelper("SIGNER", "-S -g -x -z -s now-1h -e now+2w -O raw") + signer(f"-o {zonename} -f {outfile}.signed {outfile}", cwd="ns3") + + +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 = CmdHelper("KEYGEN", f"-k {policy}") + settime = CmdHelper("SETTIME", "-s") + + # Step 1: + # Introduce the first key. This will immediately be active. + zonename = f"step1.{zone}" + zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3"))) + isctest.log.info(f"setup {zonename}") + TactN = "now-7d" + TsbmN = "now-161h" + csktimes = f"-P {TactN} -A {TactN}" + # Key generation. + csk_name = keygen(f"-l csk1.conf {csktimes} {zonename}", cwd="ns3").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]) + + 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").strip() + csk2_name = keygen(f"-l csk2.conf {newtimes} {zonename}", cwd="ns3").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]) + + # 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").strip() + csk2_name = keygen(f"-l csk2.conf {newtimes} {zonename}", cwd="ns3").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]) + + # 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").strip() + csk2_name = keygen(f"-l csk2.conf {newtimes} {zonename}", cwd="ns3").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]) + + # 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").strip() + csk2_name = keygen(f"-l csk2.conf {newtimes} {zonename}", cwd="ns3").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]) + + # 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").strip() + csk2_name = keygen(f"-l csk2.conf {newtimes} {zonename}", cwd="ns3").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]) + + return zones From 72d35513558c10e0d506a661802088760a8824ce Mon Sep 17 00:00:00 2001 From: Matthijs Mekking Date: Thu, 27 Nov 2025 12:11:35 +0100 Subject: [PATCH 04/16] rollover-algo-ksk-zsk: From setup.sh to pytest bootstrap Symlink ns1 and ns2 to rollover/ns1 and rollover/ns2. Symlink ns3/template.db.j2.manual to rollover/ns3/template.db.j2.manual. The RSASHA256 keys are generated with dnssec-keygen, without a policy provided. Thus we have to fake the lifetime for these keys. Signing has to be done without the -z option, because the KSK should not sign all records in case of a KSK/ZSK split. Update the signing code to allow for extra options when signing with CSK only. --- bin/tests/system/rollover-algo-ksk-zsk/ns1 | 1 + bin/tests/system/rollover-algo-ksk-zsk/ns2 | 1 + .../ns3/{kasp.conf.j2 => kasp.conf} | 0 .../rollover-algo-ksk-zsk/ns3/template.db.in | 1 - .../ns3/template.db.j2.manual | 1 + .../rollover-algo-ksk-zsk/ns3/trusted.conf.j2 | 1 + .../system/rollover-algo-ksk-zsk/setup.sh | 201 ------------- .../tests_rollover_algo_ksk_zsk_initial.py | 31 +- .../tests_rollover_algo_ksk_zsk_reconfig.py | 29 ++ bin/tests/system/rollover/setup.py | 266 +++++++++++++++++- 10 files changed, 320 insertions(+), 212 deletions(-) create mode 120000 bin/tests/system/rollover-algo-ksk-zsk/ns1 create mode 120000 bin/tests/system/rollover-algo-ksk-zsk/ns2 rename bin/tests/system/rollover-algo-ksk-zsk/ns3/{kasp.conf.j2 => kasp.conf} (100%) delete mode 120000 bin/tests/system/rollover-algo-ksk-zsk/ns3/template.db.in create mode 120000 bin/tests/system/rollover-algo-ksk-zsk/ns3/template.db.j2.manual create mode 120000 bin/tests/system/rollover-algo-ksk-zsk/ns3/trusted.conf.j2 delete mode 100644 bin/tests/system/rollover-algo-ksk-zsk/setup.sh diff --git a/bin/tests/system/rollover-algo-ksk-zsk/ns1 b/bin/tests/system/rollover-algo-ksk-zsk/ns1 new file mode 120000 index 0000000000..76608beaed --- /dev/null +++ b/bin/tests/system/rollover-algo-ksk-zsk/ns1 @@ -0,0 +1 @@ +../rollover/ns1 \ No newline at end of file diff --git a/bin/tests/system/rollover-algo-ksk-zsk/ns2 b/bin/tests/system/rollover-algo-ksk-zsk/ns2 new file mode 120000 index 0000000000..41a09bb648 --- /dev/null +++ b/bin/tests/system/rollover-algo-ksk-zsk/ns2 @@ -0,0 +1 @@ +../rollover/ns2 \ No newline at end of file diff --git a/bin/tests/system/rollover-algo-ksk-zsk/ns3/kasp.conf.j2 b/bin/tests/system/rollover-algo-ksk-zsk/ns3/kasp.conf similarity index 100% rename from bin/tests/system/rollover-algo-ksk-zsk/ns3/kasp.conf.j2 rename to bin/tests/system/rollover-algo-ksk-zsk/ns3/kasp.conf diff --git a/bin/tests/system/rollover-algo-ksk-zsk/ns3/template.db.in b/bin/tests/system/rollover-algo-ksk-zsk/ns3/template.db.in deleted file mode 120000 index ce6d526285..0000000000 --- a/bin/tests/system/rollover-algo-ksk-zsk/ns3/template.db.in +++ /dev/null @@ -1 +0,0 @@ -../../rollover/ns3/template.db.in \ No newline at end of file diff --git a/bin/tests/system/rollover-algo-ksk-zsk/ns3/template.db.j2.manual b/bin/tests/system/rollover-algo-ksk-zsk/ns3/template.db.j2.manual new file mode 120000 index 0000000000..38619a01b2 --- /dev/null +++ b/bin/tests/system/rollover-algo-ksk-zsk/ns3/template.db.j2.manual @@ -0,0 +1 @@ +../../rollover/ns3/template.db.j2.manual \ No newline at end of file diff --git a/bin/tests/system/rollover-algo-ksk-zsk/ns3/trusted.conf.j2 b/bin/tests/system/rollover-algo-ksk-zsk/ns3/trusted.conf.j2 new file mode 120000 index 0000000000..cb0be77b22 --- /dev/null +++ b/bin/tests/system/rollover-algo-ksk-zsk/ns3/trusted.conf.j2 @@ -0,0 +1 @@ +../../_common/trusted.conf.j2 \ No newline at end of file diff --git a/bin/tests/system/rollover-algo-ksk-zsk/setup.sh b/bin/tests/system/rollover-algo-ksk-zsk/setup.sh deleted file mode 100644 index bc651b9420..0000000000 --- a/bin/tests/system/rollover-algo-ksk-zsk/setup.sh +++ /dev/null @@ -1,201 +0,0 @@ -#!/bin/sh -e - -# Copyright (C) Internet Systems Consortium, Inc. ("ISC") -# -# SPDX-License-Identifier: MPL-2.0 -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, you can obtain one at https://mozilla.org/MPL/2.0/. -# -# See the COPYRIGHT file distributed with this work for additional -# information regarding copyright ownership. - -# shellcheck source=conf.sh -. ../conf.sh - -cd "ns3" - -setup() { - zone="$1" - echo_i "setting up zone: $zone" - zonefile="${zone}.db" - infile="${zone}.db.infile" -} - -# Make lines shorter by storing key states in environment variables. -H="HIDDEN" -R="RUMOURED" -O="OMNIPRESENT" -U="UNRETENTIVE" - -# -# The zones at algorithm-roll.$tld represent the various steps of a ZSK/KSK -# algorithm rollover. -# - -for tld in kasp manual; do - # Step 1: - # Introduce the first key. This will immediately be active. - setup step1.algorithm-roll.$tld - echo "$zone" >>zones - TactN="now-7d" - TsbmN="now-161h" - ksktimes="-P ${TactN} -A ${TactN}" - zsktimes="-P ${TactN} -A ${TactN}" - KSK=$($KEYGEN -a RSASHA256 -L 3600 -f KSK $ksktimes $zone 2>keygen.out.$zone.1) - ZSK=$($KEYGEN -a RSASHA256 -L 3600 $zsktimes $zone 2>keygen.out.$zone.2) - $SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN "$KSK" >settime.out.$zone.1 2>&1 - $SETTIME -s -g $O -k $O $TactN -z $O $TactN "$ZSK" >settime.out.$zone.2 2>&1 - cat template.db.in "${KSK}.key" "${ZSK}.key" >"$infile" - private_type_record $zone 8 "$KSK" >>"$infile" - private_type_record $zone 8 "$ZSK" >>"$infile" - cp $infile $zonefile - $SIGNER -S -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - - # Step 2: - # After the publication interval has passed the DNSKEY is OMNIPRESENT. - setup step2.algorithm-roll.$tld - # The time passed since the new algorithm keys have been introduced is 3 hours. - TpubN1="now-3h" - # Tsbm(N+1) = TpubN1 + Ipub = now + TTLsig + Dprp = now - 3h + 6h + 1h = now + 4h - TsbmN1="now+4h" - ksk1times="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I ${TsbmN1}" - zsk1times="-P ${TactN} -A ${TactN} -I ${TsbmN1}" - ksk2times="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}" - zsk2times="-P ${TpubN1} -A ${TpubN1}" - KSK1=$($KEYGEN -a RSASHA256 -L 3600 -f KSK $ksk1times $zone 2>keygen.out.$zone.1) - ZSK1=$($KEYGEN -a RSASHA256 -L 3600 $zsk1times $zone 2>keygen.out.$zone.2) - KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $ksk2times $zone 2>keygen.out.$zone.3) - ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $zsk2times $zone 2>keygen.out.$zone.4) - $SETTIME -s -g $H -k $O $TactN -r $O $TactN -d $O $TactN "$KSK1" >settime.out.$zone.1 2>&1 - $SETTIME -s -g $H -k $O $TactN -z $O $TactN "$ZSK1" >settime.out.$zone.2 2>&1 - $SETTIME -s -g $O -k $R $TpubN1 -r $R $TpubN1 -d $H $TpubN1 "$KSK2" >settime.out.$zone.3 2>&1 - $SETTIME -s -g $O -k $R $TpubN1 -z $R $TpubN1 "$ZSK2" >settime.out.$zone.4 2>&1 - # Fake lifetime of old algorithm keys. - echo "Lifetime: 0" >>"${KSK1}.state" - echo "Lifetime: 0" >>"${ZSK1}.state" - cat template.db.in "${KSK1}.key" "${ZSK1}.key" "${KSK2}.key" "${ZSK2}.key" >"$infile" - private_type_record $zone 8 "$KSK1" >>"$infile" - private_type_record $zone 8 "$ZSK1" >>"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK2" >>"$infile" - cp $infile $zonefile - $SIGNER -S -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - - # Step 3: - # The zone signatures are also OMNIPRESENT. - setup step3.algorithm-roll.$tld - # The time passed since the new algorithm keys have been introduced is 7 hours. - TpubN1="now-7h" - TsbmN1="now" - ksk1times="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I ${TsbmN1}" - zsk1times="-P ${TactN} -A ${TactN} -I ${TsbmN1}" - ksk2times="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}" - zsk2times="-P ${TpubN1} -A ${TpubN1}" - KSK1=$($KEYGEN -a RSASHA256 -L 3600 -f KSK $ksk1times $zone 2>keygen.out.$zone.1) - ZSK1=$($KEYGEN -a RSASHA256 -L 3600 $zsk1times $zone 2>keygen.out.$zone.2) - KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $ksk2times $zone 2>keygen.out.$zone.3) - ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $zsk2times $zone 2>keygen.out.$zone.4) - $SETTIME -s -g $H -k $O $TactN -r $O $TactN -d $O $TactN "$KSK1" >settime.out.$zone.1 2>&1 - $SETTIME -s -g $H -k $O $TactN -z $O $TactN "$ZSK1" >settime.out.$zone.2 2>&1 - $SETTIME -s -g $O -k $O $TpubN1 -r $O $TpubN1 -d $H $TpubN1 "$KSK2" >settime.out.$zone.3 2>&1 - $SETTIME -s -g $O -k $O $TpubN1 -z $R $TpubN1 "$ZSK2" >settime.out.$zone.4 2>&1 - # Fake lifetime of old algorithm keys. - echo "Lifetime: 0" >>"${KSK1}.state" - echo "Lifetime: 0" >>"${ZSK1}.state" - cat template.db.in "${KSK1}.key" "${ZSK1}.key" "${KSK2}.key" "${ZSK2}.key" >"$infile" - private_type_record $zone 8 "$KSK1" >>"$infile" - private_type_record $zone 8 "$ZSK1" >>"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK2" >>"$infile" - cp $infile $zonefile - $SIGNER -S -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - - # Step 4: - # The DS is swapped and can become OMNIPRESENT. - setup step4.algorithm-roll.$tld - # The time passed since the DS has been swapped is 3 hours. - TpubN1="now-10h" - TsbmN1="now-3h" - ksk1times="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I ${TsbmN1}" - zsk1times="-P ${TactN} -A ${TactN} -I ${TsbmN1}" - ksk2times="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}" - zsk2times="-P ${TpubN1} -A ${TpubN1}" - KSK1=$($KEYGEN -a RSASHA256 -L 3600 -f KSK $ksk1times $zone 2>keygen.out.$zone.1) - ZSK1=$($KEYGEN -a RSASHA256 -L 3600 $zsk1times $zone 2>keygen.out.$zone.2) - KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $ksk2times $zone 2>keygen.out.$zone.3) - ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $zsk2times $zone 2>keygen.out.$zone.4) - $SETTIME -s -g $H -k $O $TactN -r $O $TactN -d $U $TsbmN1 -D ds $TsbmN1 "$KSK1" >settime.out.$zone.1 2>&1 - $SETTIME -s -g $H -k $O $TactN -z $O $TactN "$ZSK1" >settime.out.$zone.2 2>&1 - $SETTIME -s -g $O -k $O $TpubN1 -r $O $TpubN1 -d $R $TsbmN1 -P ds $TsbmN1 "$KSK2" >settime.out.$zone.3 2>&1 - $SETTIME -s -g $O -k $O $TpubN1 -z $R $TpubN1 "$ZSK2" >settime.out.$zone.4 2>&1 - # Fake lifetime of old algorithm keys. - echo "Lifetime: 0" >>"${KSK1}.state" - echo "Lifetime: 0" >>"${ZSK1}.state" - cat template.db.in "${KSK1}.key" "${ZSK1}.key" "${KSK2}.key" "${ZSK2}.key" >"$infile" - private_type_record $zone 8 "$KSK1" >>"$infile" - private_type_record $zone 8 "$ZSK1" >>"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK2" >>"$infile" - cp $infile $zonefile - $SIGNER -S -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - - # Step 5: - # The DNSKEY is removed long enough to be HIDDEN. - setup step5.algorithm-roll.$tld - # The time passed since the DNSKEY has been removed is 2 hours. - TpubN1="now-12h" - TsbmN1="now-5h" - ksk1times="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I ${TsbmN1}" - zsk1times="-P ${TactN} -A ${TactN} -I ${TsbmN1}" - ksk2times="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}" - zsk2times="-P ${TpubN1} -A ${TpubN1}" - KSK1=$($KEYGEN -a RSASHA256 -L 3600 -f KSK $ksk1times $zone 2>keygen.out.$zone.1) - ZSK1=$($KEYGEN -a RSASHA256 -L 3600 $zsk1times $zone 2>keygen.out.$zone.2) - KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $ksk2times $zone 2>keygen.out.$zone.3) - ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $zsk2times $zone 2>keygen.out.$zone.4) - $SETTIME -s -g $H -k $U $TsbmN1 -r $U $TsbmN1 -d $H $TsbmN1 "$KSK1" >settime.out.$zone.1 2>&1 - $SETTIME -s -g $H -k $U $TsbmN1 -z $U $TsbmN1 "$ZSK1" >settime.out.$zone.2 2>&1 - $SETTIME -s -g $O -k $O $TpubN1 -r $O $TpubN1 -d $O $TsbmN1 "$KSK2" >settime.out.$zone.3 2>&1 - $SETTIME -s -g $O -k $O $TpubN1 -z $R $TpubN1 "$ZSK2" >settime.out.$zone.4 2>&1 - # Fake lifetime of old algorithm keys. - echo "Lifetime: 0" >>"${KSK1}.state" - echo "Lifetime: 0" >>"${ZSK1}.state" - cat template.db.in "${KSK1}.key" "${ZSK1}.key" "${KSK2}.key" "${ZSK2}.key" >"$infile" - private_type_record $zone 8 "$KSK1" >>"$infile" - private_type_record $zone 8 "$ZSK1" >>"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK2" >>"$infile" - cp $infile $zonefile - $SIGNER -S -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - - # Step 6: - # The RRSIGs have been removed long enough to be HIDDEN. - setup step6.algorithm-roll.$tld - # Additional time passed: 7h. - TpubN1="now-19h" - TsbmN1="now-12h" - ksk1times="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I ${TsbmN1}" - zsk1times="-P ${TactN} -A ${TactN} -I ${TsbmN1}" - ksk2times="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}" - zsk2times="-P ${TpubN1} -A ${TpubN1}" - KSK1=$($KEYGEN -a RSASHA256 -L 3600 -f KSK $ksk1times $zone 2>keygen.out.$zone.1) - ZSK1=$($KEYGEN -a RSASHA256 -L 3600 $zsk1times $zone 2>keygen.out.$zone.2) - KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $ksk2times $zone 2>keygen.out.$zone.3) - ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $zsk2times $zone 2>keygen.out.$zone.4) - $SETTIME -s -g $H -k $H $TsbmN1 -r $U $TsbmN1 -d $H $TsbmN1 "$KSK1" >settime.out.$zone.1 2>&1 - $SETTIME -s -g $H -k $H $TsbmN1 -z $U $TsbmN1 "$ZSK1" >settime.out.$zone.2 2>&1 - $SETTIME -s -g $O -k $O $TpubN1 -r $O $TpubN1 -d $O $TsbmN1 "$KSK2" >settime.out.$zone.3 2>&1 - $SETTIME -s -g $O -k $O $TpubN1 -z $R $TpubN1 "$ZSK2" >settime.out.$zone.4 2>&1 - # Fake lifetime of old algorithm keys. - echo "Lifetime: 0" >>"${KSK1}.state" - echo "Lifetime: 0" >>"${ZSK1}.state" - cat template.db.in "${KSK1}.key" "${ZSK1}.key" "${KSK2}.key" "${ZSK2}.key" >"$infile" - private_type_record $zone 8 "$KSK1" >>"$infile" - private_type_record $zone 8 "$ZSK1" >>"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK2" >>"$infile" - cp $infile $zonefile - $SIGNER -S -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 -done diff --git a/bin/tests/system/rollover-algo-ksk-zsk/tests_rollover_algo_ksk_zsk_initial.py b/bin/tests/system/rollover-algo-ksk-zsk/tests_rollover_algo_ksk_zsk_initial.py index 32eea7d014..2f74cd0fa4 100644 --- a/bin/tests/system/rollover-algo-ksk-zsk/tests_rollover_algo_ksk_zsk_initial.py +++ b/bin/tests/system/rollover-algo-ksk-zsk/tests_rollover_algo_ksk_zsk_initial.py @@ -22,6 +22,35 @@ from rollover.common import ( TIMEDELTA, ALGOROLL_CONFIG, ) +from rollover.setup import ( + configure_root, + configure_tld, + configure_algo_ksk_zsk, +) + + +def bootstrap(): + data = { + "tlds": [], + "trust_anchors": [], + } + + tlds = [] + for tld_name in [ + "kasp", + "manual", + ]: + delegations = configure_algo_ksk_zsk(tld_name, reconfig=False) + + tld = configure_tld(tld_name, delegations) + tlds.append(tld) + + data["tlds"].append(tld_name) + + ta = configure_root(tlds) + data["trust_anchors"].append(ta) + + return data @pytest.mark.parametrize( @@ -31,7 +60,7 @@ from rollover.common import ( param("manual"), ], ) -def test_algoroll_ksk_zsk_initial(ns3, tld): +def test_algoroll_ksk_zsk_initial(tld, ns3): config = ALGOROLL_CONFIG policy = f"rsasha256-{tld}" zone = f"step1.algorithm-roll.{tld}" diff --git a/bin/tests/system/rollover-algo-ksk-zsk/tests_rollover_algo_ksk_zsk_reconfig.py b/bin/tests/system/rollover-algo-ksk-zsk/tests_rollover_algo_ksk_zsk_reconfig.py index 15cf0f9ddd..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,12 +32,41 @@ from rollover.common import ( DURATION, TIMEDELTA, ) +from rollover.setup import ( + configure_root, + configure_tld, + configure_algo_ksk_zsk, +) CONFIG = ALGOROLL_CONFIG POLICY = "ecdsa256" TIME_PASSED = 0 # set in reconfigure() fixture +def bootstrap(): + data = { + "tlds": [], + "trust_anchors": [], + } + + tlds = [] + for tld_name in [ + "kasp", + "manual", + ]: + delegations = configure_algo_ksk_zsk(tld_name, reconfig=True) + + tld = configure_tld(tld_name, delegations) + tlds.append(tld) + + data["tlds"].append(tld_name) + + ta = configure_root(tlds) + data["trust_anchors"].append(ta) + + return data + + @pytest.fixture(scope="module", autouse=True) def after_servers_start(ns3, templates): global TIME_PASSED # pylint: disable=global-statement diff --git a/bin/tests/system/rollover/setup.py b/bin/tests/system/rollover/setup.py index 5124bd46ab..f52135a83d 100644 --- a/bin/tests/system/rollover/setup.py +++ b/bin/tests/system/rollover/setup.py @@ -90,7 +90,16 @@ def configure_root(delegations: List[Zone]) -> TrustAnchor: return ksk.into_ta("static-ds") -def render_and_sign_zone(zonename: str, keys: List[str]): +def fake_lifetime(keys: List[str]): + """ + Fake lifetime of old algorithm keys. + """ + for key in keys: + with open(f"ns3/{key}.state", "a") as statefile: + statefile.write("Lifetime: 0\n") + + +def render_and_sign_zone(zonename: str, keys: List[str], extra_options: str = ""): dnskeys = [] privaterrs = [] for key_name in keys: @@ -109,8 +118,8 @@ def render_and_sign_zone(zonename: str, keys: List[str]): } templates.render(f"ns3/{outfile}", tdata, template=f"ns3/{template}") - signer = CmdHelper("SIGNER", "-S -g -x -z -s now-1h -e now+2w -O raw") - signer(f"-o {zonename} -f {outfile}.signed {outfile}", cwd="ns3") + signer = CmdHelper("SIGNER", "-S -g -x -s now-1h -e now+2w -O raw") + signer(f"{extra_options} -o {zonename} -f {outfile}.signed {outfile}", cwd="ns3") def configure_algo_csk(tld: str, policy: str, reconfig: bool = False) -> List[Zone]: @@ -136,7 +145,7 @@ def configure_algo_csk(tld: str, policy: str, reconfig: bool = False) -> List[Zo cwd="ns3", ) # Signing. - render_and_sign_zone(zonename, [csk_name]) + render_and_sign_zone(zonename, [csk_name], extra_options="-z") if reconfig: # Step 2: @@ -160,7 +169,7 @@ def configure_algo_csk(tld: str, policy: str, reconfig: bool = False) -> List[Zo cwd="ns3", ) # Signing. - render_and_sign_zone(zonename, [csk1_name, csk2_name]) + render_and_sign_zone(zonename, [csk1_name, csk2_name], extra_options="-z") # Step 3: # The zone signatures are also OMNIPRESENT. @@ -184,7 +193,7 @@ def configure_algo_csk(tld: str, policy: str, reconfig: bool = False) -> List[Zo cwd="ns3", ) # Signing. - render_and_sign_zone(zonename, [csk1_name, csk2_name]) + render_and_sign_zone(zonename, [csk1_name, csk2_name], extra_options="-z") # Step 4: # The DS is swapped and can become OMNIPRESENT. @@ -208,7 +217,7 @@ def configure_algo_csk(tld: str, policy: str, reconfig: bool = False) -> List[Zo cwd="ns3", ) # Signing. - render_and_sign_zone(zonename, [csk1_name, csk2_name]) + render_and_sign_zone(zonename, [csk1_name, csk2_name], extra_options="-z") # Step 5: # The DNSKEY is removed long enough to be HIDDEN. @@ -232,7 +241,7 @@ def configure_algo_csk(tld: str, policy: str, reconfig: bool = False) -> List[Zo cwd="ns3", ) # Signing. - render_and_sign_zone(zonename, [csk1_name, csk2_name]) + render_and_sign_zone(zonename, [csk1_name, csk2_name], extra_options="-z") # Step 6: # The RRSIGs have been removed long enough to be HIDDEN. @@ -256,6 +265,245 @@ def configure_algo_csk(tld: str, policy: str, reconfig: bool = False) -> List[Zo cwd="ns3", ) # Signing. - render_and_sign_zone(zonename, [csk1_name, csk2_name]) + render_and_sign_zone(zonename, [csk1_name, csk2_name], extra_options="-z") + + return zones + + +def configure_algo_ksk_zsk(tld: str, reconfig: bool = False) -> List[Zone]: + # The zones at algorithm-roll.$tld represent the various steps of a ZSK/KSK + # algorithm rollover. + zones = [] + zone = f"algorithm-roll.{tld}" + keygen = CmdHelper("KEYGEN", "-L 3600") + settime = CmdHelper("SETTIME", "-s") + + # Step 1: + # Introduce the first key. This will immediately be active. + zonename = f"step1.{zone}" + zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3"))) + isctest.log.info(f"setup {zonename}") + TactN = "now-7d" + TsbmN = "now-161h" + keytimes = f"-P {TactN} -A {TactN}" + # Key generation. + ksk_name = keygen(f"-a RSASHA256 -f KSK {keytimes} {zonename}", cwd="ns3").strip() + zsk_name = keygen(f"-a RSASHA256 {keytimes} {zonename}", cwd="ns3").strip() + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -d OMNIPRESENT {TactN} {ksk_name}", + cwd="ns3", + ) + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TactN} -z OMNIPRESENT {TactN} {zsk_name}", + cwd="ns3", + ) + # Signing. + render_and_sign_zone(zonename, [ksk_name, zsk_name]) + + if reconfig: + # Step 2: + # After the publication interval has passed the DNSKEY is OMNIPRESENT. + zonename = f"step2.{zone}" + zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3"))) + isctest.log.info(f"setup {zonename}") + # The time passed since the new algorithm keys have been introduced is 3 hours. + # Tsbm(N+1) = TpubN1 + Ipub = now + TTLsig + Dprp = now - 3h + 6h + 1h = now + 4h + TpubN1 = "now-3h" + TsbmN1 = "now+4h" + ksk1times = f"-P {TactN} -A {TactN} -P sync {TsbmN} -I {TsbmN1}" + zsk1times = f"-P {TactN} -A {TactN} -I {TsbmN1}" + ksk2times = f"-P {TpubN1} -A {TpubN1} -P sync {TsbmN1}" + zsk2times = f"-P {TpubN1} -A {TpubN1}" + # Key generation. + ksk1_name = keygen( + f"-a RSASHA256 -f KSK {ksk1times} {zonename}", cwd="ns3" + ).strip() + zsk1_name = keygen(f"-a RSASHA256 {zsk1times} {zonename}", cwd="ns3").strip() + ksk2_name = keygen( + f"-a ECDSA256 -f KSK {ksk2times} {zonename}", cwd="ns3" + ).strip() + zsk2_name = keygen(f"-a ECDSA256 {zsk2times} {zonename}", cwd="ns3").strip() + settime( + f"-g HIDDEN -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -d OMNIPRESENT {TactN} {ksk1_name}", + cwd="ns3", + ) + settime( + f"-g HIDDEN -k OMNIPRESENT {TactN} -z OMNIPRESENT {TactN} {zsk1_name}", + cwd="ns3", + ) + settime( + f"-g OMNIPRESENT -k RUMOURED {TpubN1} -r RUMOURED {TpubN1} -d HIDDEN {TpubN1} {ksk2_name}", + cwd="ns3", + ) + settime( + f"-g OMNIPRESENT -k RUMOURED {TpubN1} -z RUMOURED {TpubN1} {zsk2_name}", + cwd="ns3", + ) + # Signing. + fake_lifetime([ksk1_name, zsk1_name]) + render_and_sign_zone(zonename, [ksk1_name, zsk1_name, ksk2_name, zsk2_name]) + + # Step 3: + # The zone signatures are also OMNIPRESENT. + zonename = f"step3.{zone}" + zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3"))) + isctest.log.info(f"setup {zonename}") + # The time passed since the new algorithm keys have been introduced is 7 hours. + TpubN1 = "now-7h" + TsbmN1 = "now" + ksk1times = f"-P {TactN} -A {TactN} -P sync {TsbmN} -I {TsbmN1}" + zsk1times = f"-P {TactN} -A {TactN} -I {TsbmN1}" + ksk2times = f"-P {TpubN1} -A {TpubN1} -P sync {TsbmN1}" + zsk2times = f"-P {TpubN1} -A {TpubN1}" + # Key generation. + ksk1_name = keygen( + f"-a RSASHA256 -f KSK {ksk1times} {zonename}", cwd="ns3" + ).strip() + zsk1_name = keygen(f"-a RSASHA256 {zsk1times} {zonename}", cwd="ns3").strip() + ksk2_name = keygen( + f"-a ECDSA256 -f KSK {ksk2times} {zonename}", cwd="ns3" + ).strip() + zsk2_name = keygen(f"-a ECDSA256 {zsk2times} {zonename}", cwd="ns3").strip() + settime( + f"-g HIDDEN -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -d OMNIPRESENT {TactN} {ksk1_name}", + cwd="ns3", + ) + settime( + f"-g HIDDEN -k OMNIPRESENT {TactN} -z OMNIPRESENT {TactN} {zsk1_name}", + cwd="ns3", + ) + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TpubN1} -r OMNIPRESENT {TpubN1} -d HIDDEN {TpubN1} {ksk2_name}", + cwd="ns3", + ) + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TpubN1} -z RUMOURED {TpubN1} {zsk2_name}", + cwd="ns3", + ) + # Signing. + fake_lifetime([ksk1_name, zsk1_name]) + render_and_sign_zone(zonename, [ksk1_name, zsk1_name, ksk2_name, zsk2_name]) + + # Step 4: + # The DS is swapped and can become OMNIPRESENT. + zonename = f"step4.{zone}" + zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3"))) + isctest.log.info(f"setup {zonename}") + # The time passed since the DS has been swapped is 3 hours. + TpubN1 = "now-10h" + TsbmN1 = "now-3h" + ksk1times = f"-P {TactN} -A {TactN} -P sync {TsbmN} -I {TsbmN1}" + zsk1times = f"-P {TactN} -A {TactN} -I {TsbmN1}" + ksk2times = f"-P {TpubN1} -A {TpubN1} -P sync {TsbmN1}" + zsk2times = f"-P {TpubN1} -A {TpubN1}" + # Key generation. + ksk1_name = keygen( + f"-a RSASHA256 -f KSK {ksk1times} {zonename}", cwd="ns3" + ).strip() + zsk1_name = keygen(f"-a RSASHA256 {zsk1times} {zonename}", cwd="ns3").strip() + ksk2_name = keygen( + f"-a ECDSA256 -f KSK {ksk2times} {zonename}", cwd="ns3" + ).strip() + zsk2_name = keygen(f"-a ECDSA256 {zsk2times} {zonename}", cwd="ns3").strip() + settime( + f"-g HIDDEN -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -d UNRETENTIVE {TsbmN1} -D ds {TsbmN1} {ksk1_name}", + cwd="ns3", + ) + settime( + f"-g HIDDEN -k OMNIPRESENT {TactN} -z OMNIPRESENT {TactN} {zsk1_name}", + cwd="ns3", + ) + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TpubN1} -r OMNIPRESENT {TpubN1} -d RUMOURED {TsbmN1} -P ds {TsbmN1} {ksk2_name}", + cwd="ns3", + ) + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TpubN1} -z RUMOURED {TpubN1} {zsk2_name}", + cwd="ns3", + ) + # Signing. + fake_lifetime([ksk1_name, zsk1_name]) + render_and_sign_zone(zonename, [ksk1_name, zsk1_name, ksk2_name, zsk2_name]) + + # Step 5: + # The DNSKEY is removed long enough to be HIDDEN. + zonename = f"step5.{zone}" + zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3"))) + isctest.log.info(f"setup {zonename}") + # The time passed since the DNSKEY has been removed is 2 hours. + TpubN1 = "now-12h" + TsbmN1 = "now-5h" + ksk1times = f"-P {TactN} -A {TactN} -P sync {TsbmN} -I {TsbmN1}" + zsk1times = f"-P {TactN} -A {TactN} -I {TsbmN1}" + ksk2times = f"-P {TpubN1} -A {TpubN1} -P sync {TsbmN1}" + zsk2times = f"-P {TpubN1} -A {TpubN1}" + # Key generation. + ksk1_name = keygen( + f"-a RSASHA256 -f KSK {ksk1times} {zonename}", cwd="ns3" + ).strip() + zsk1_name = keygen(f"-a RSASHA256 {zsk1times} {zonename}", cwd="ns3").strip() + ksk2_name = keygen( + f"-a ECDSA256 -f KSK {ksk2times} {zonename}", cwd="ns3" + ).strip() + zsk2_name = keygen(f"-a ECDSA256 {zsk2times} {zonename}", cwd="ns3").strip() + settime( + f"-g HIDDEN -k UNRETENTIVE {TsbmN1} -r UNRETENTIVE {TsbmN1} -d HIDDEN {TsbmN1} {ksk1_name}", + cwd="ns3", + ) + settime( + f"-g HIDDEN -k UNRETENTIVE {TsbmN1} -z UNRETENTIVE {TsbmN1} {zsk1_name}", + cwd="ns3", + ) + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TpubN1} -r OMNIPRESENT {TpubN1} -d OMNIPRESENT {TsbmN1} {ksk2_name}", + cwd="ns3", + ) + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TpubN1} -z RUMOURED {TpubN1} {zsk2_name}", + cwd="ns3", + ) + # Signing. + fake_lifetime([ksk1_name, zsk1_name]) + render_and_sign_zone(zonename, [ksk1_name, zsk1_name, ksk2_name, zsk2_name]) + + # Step 6: + # The RRSIGs have been removed long enough to be HIDDEN. + zonename = f"step6.{zone}" + zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3"))) + isctest.log.info(f"setup {zonename}") + # Additional time passed: 7h. + TpubN1 = "now-19h" + TsbmN1 = "now-12h" + ksk1times = f"-P {TactN} -A {TactN} -P sync {TsbmN} -I {TsbmN1}" + zsk1times = f"-P {TactN} -A {TactN} -I {TsbmN1}" + ksk2times = f"-P {TpubN1} -A {TpubN1} -P sync {TsbmN1}" + zsk2times = f"-P {TpubN1} -A {TpubN1}" + ksk1_name = keygen( + f"-a RSASHA256 -f KSK {ksk1times} {zonename}", cwd="ns3" + ).strip() + zsk1_name = keygen(f"-a RSASHA256 {zsk1times} {zonename}", cwd="ns3").strip() + ksk2_name = keygen( + f"-a ECDSA256 -f KSK {ksk2times} {zonename}", cwd="ns3" + ).strip() + zsk2_name = keygen(f"-a ECDSA256 {zsk2times} {zonename}", cwd="ns3").strip() + settime( + f"-g HIDDEN -k HIDDEN {TsbmN1} -r UNRETENTIVE {TsbmN1} -d HIDDEN {TsbmN1} {ksk1_name}", + cwd="ns3", + ) + settime( + f"-g HIDDEN -k HIDDEN {TsbmN1} -z UNRETENTIVE {TsbmN1} {zsk1_name}", + cwd="ns3", + ) + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TpubN1} -r OMNIPRESENT {TpubN1} -d OMNIPRESENT {TsbmN1} {ksk2_name}", + cwd="ns3", + ) + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TpubN1} -z RUMOURED {TpubN1} {zsk2_name}", + cwd="ns3", + ) + # Signing. + fake_lifetime([ksk1_name, zsk1_name]) + render_and_sign_zone(zonename, [ksk1_name, zsk1_name, ksk2_name, zsk2_name]) return zones From 1635bcf1efe389336282fb457f3b30639a8a5b1c Mon Sep 17 00:00:00 2001 From: Matthijs Mekking Date: Thu, 27 Nov 2025 14:01:28 +0100 Subject: [PATCH 05/16] rollover-csk-roll1: From setup.sh to pytest bootstrap Symlink ns1 and ns2 to rollover/ns1 and rollover/ns2. Symlink ns3/template.db.j2.manual to rollover/ns3/template.db.j2.manual. Since the bootstrapping is done before the templates are rendered automatically, replace @DEFAULT_ALGORITHM@ in ns3/kasp.conf.j2 to ecdsa256 and rename to ns3/kasp.conf. Write a python method to set the key predecessor/successor relationship into the key state files. --- bin/tests/system/rollover-csk-roll1/ns1 | 1 + bin/tests/system/rollover-csk-roll1/ns2 | 1 + .../ns3/{kasp.conf.j2 => kasp.conf} | 4 +- .../rollover-csk-roll1/ns3/template.db.in | 1 - .../ns3/template.db.j2.manual | 1 + .../rollover-csk-roll1/ns3/trusted.conf.j2 | 1 + bin/tests/system/rollover-csk-roll1/setup.sh | 314 ---------------- .../tests_rollover_csk_roll1.py | 32 +- bin/tests/system/rollover/setup.py | 354 ++++++++++++++++++ 9 files changed, 390 insertions(+), 319 deletions(-) create mode 120000 bin/tests/system/rollover-csk-roll1/ns1 create mode 120000 bin/tests/system/rollover-csk-roll1/ns2 rename bin/tests/system/rollover-csk-roll1/ns3/{kasp.conf.j2 => kasp.conf} (90%) delete mode 120000 bin/tests/system/rollover-csk-roll1/ns3/template.db.in create mode 120000 bin/tests/system/rollover-csk-roll1/ns3/template.db.j2.manual create mode 120000 bin/tests/system/rollover-csk-roll1/ns3/trusted.conf.j2 delete mode 100644 bin/tests/system/rollover-csk-roll1/setup.sh 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/setup.py b/bin/tests/system/rollover/setup.py index f52135a83d..c2cacdb200 100644 --- a/bin/tests/system/rollover/setup.py +++ b/bin/tests/system/rollover/setup.py @@ -99,6 +99,20 @@ def fake_lifetime(keys: List[str]): statefile.write("Lifetime: 0\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], extra_options: str = ""): dnskeys = [] privaterrs = [] @@ -507,3 +521,343 @@ def configure_algo_ksk_zsk(tld: str, reconfig: bool = False) -> List[Zone]: 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}" + keygen = CmdHelper("KEYGEN", f"-k {policy} -l kasp.conf") + settime = CmdHelper("SETTIME", "-s") + + # Step 1: + # Introduce the first key. This will immediately be active. + zonename = f"step1.{zone}" + zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3"))) + isctest.log.info(f"setup {zonename}") + TactN = "now-7d" + keytimes = f"-P {TactN} -A {TactN}" + # Key generation. + csk_name = keygen(f"{keytimes} {zonename}", cwd="ns3").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 -G cdnskey,cds:sha384") + + # 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").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 -G cdnskey,cds:sha384") + + # 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").strip() + csk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").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="-z -G cdnskey,cds:sha384" + ) + + # 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").strip() + csk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").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="-z -G cdnskey,cds:sha384" + ) + + # 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").strip() + csk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").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="-z -G cdnskey,cds:sha384" + ) + + # 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").strip() + csk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").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="-z -G cdnskey,cds:sha384" + ) + + # 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").strip() + csk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").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="-z -G cdnskey,cds:sha384" + ) + + # 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").strip() + csk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").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="-z -G cdnskey,cds:sha384" + ) + + return zones From ef7d617e3f6aa0395fca007cb60a903597743d1f Mon Sep 17 00:00:00 2001 From: Matthijs Mekking Date: Thu, 27 Nov 2025 14:36:07 +0100 Subject: [PATCH 06/16] rollover-csk-roll2: From setup.sh to pytest bootstrap Similar to rollover-csk-roll1. --- bin/tests/system/rollover-csk-roll2/ns1 | 1 + bin/tests/system/rollover-csk-roll2/ns2 | 1 + .../ns3/{kasp.conf.j2 => kasp.conf} | 4 +- .../rollover-csk-roll2/ns3/template.db.in | 1 - .../ns3/template.db.j2.manual | 1 + .../rollover-csk-roll2/ns3/trusted.conf.j2 | 1 + bin/tests/system/rollover-csk-roll2/setup.sh | 301 -------------- .../tests_rollover_csk_roll2.py | 30 +- bin/tests/system/rollover/setup.py | 373 +++++++++++++++++- 9 files changed, 388 insertions(+), 325 deletions(-) create mode 120000 bin/tests/system/rollover-csk-roll2/ns1 create mode 120000 bin/tests/system/rollover-csk-roll2/ns2 rename bin/tests/system/rollover-csk-roll2/ns3/{kasp.conf.j2 => kasp.conf} (90%) delete mode 120000 bin/tests/system/rollover-csk-roll2/ns3/template.db.in create mode 120000 bin/tests/system/rollover-csk-roll2/ns3/template.db.j2.manual create mode 120000 bin/tests/system/rollover-csk-roll2/ns3/trusted.conf.j2 delete mode 100644 bin/tests/system/rollover-csk-roll2/setup.sh 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/setup.py b/bin/tests/system/rollover/setup.py index c2cacdb200..2d7f178ca1 100644 --- a/bin/tests/system/rollover/setup.py +++ b/bin/tests/system/rollover/setup.py @@ -528,6 +528,7 @@ def configure_cskroll1(tld: str, policy: str) -> List[Zone]: # (which is essentially a ZSK Pre-Publication / KSK Double-KSK rollover). zones = [] zone = f"csk-roll1.{tld}" + cds = "cdnskey,cds:sha384" keygen = CmdHelper("KEYGEN", f"-k {policy} -l kasp.conf") settime = CmdHelper("SETTIME", "-s") @@ -545,7 +546,7 @@ def configure_cskroll1(tld: str, policy: str) -> List[Zone]: cwd="ns3", ) # Signing. - render_and_sign_zone(zonename, [csk_name], extra_options="-z -G cdnskey,cds:sha384") + render_and_sign_zone(zonename, [csk_name], extra_options=f"-z -G {cds}") # Step 2: # It is time to introduce the new CSK. @@ -577,7 +578,7 @@ def configure_cskroll1(tld: str, policy: str) -> List[Zone]: cwd="ns3", ) # Signing. - render_and_sign_zone(zonename, [csk_name], extra_options="-z -G cdnskey,cds:sha384") + 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. @@ -639,9 +640,7 @@ def configure_cskroll1(tld: str, policy: str) -> List[Zone]: # Set key rollover relationship. set_key_relationship(csk1_name, csk2_name) # Signing. - render_and_sign_zone( - zonename, [csk1_name, csk2_name], extra_options="-z -G cdnskey,cds:sha384" - ) + 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 @@ -694,9 +693,7 @@ def configure_cskroll1(tld: str, policy: str) -> List[Zone]: # Set key rollover relationship. set_key_relationship(csk1_name, csk2_name) # Signing. - render_and_sign_zone( - zonename, [csk1_name, csk2_name], extra_options="-z -G cdnskey,cds:sha384" - ) + 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. @@ -731,9 +728,7 @@ def configure_cskroll1(tld: str, policy: str) -> List[Zone]: # Set key rollover relationship. set_key_relationship(csk1_name, csk2_name) # Signing. - render_and_sign_zone( - zonename, [csk1_name, csk2_name], extra_options="-z -G cdnskey,cds:sha384" - ) + 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 @@ -784,9 +779,7 @@ def configure_cskroll1(tld: str, policy: str) -> List[Zone]: # Set key rollover relationship. set_key_relationship(csk1_name, csk2_name) # Signing. - render_and_sign_zone( - zonename, [csk1_name, csk2_name], extra_options="-z -G cdnskey,cds:sha384" - ) + 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. @@ -820,9 +813,7 @@ def configure_cskroll1(tld: str, policy: str) -> List[Zone]: # Set key rollover relationship. set_key_relationship(csk1_name, csk2_name) # Signing. - render_and_sign_zone( - zonename, [csk1_name, csk2_name], extra_options="-z -G cdnskey,cds:sha384" - ) + render_and_sign_zone(zonename, [csk1_name, csk2_name], extra_options=f"-z -G {cds}") # Step 8: # The predecessor DNSKEY can be purged. @@ -856,8 +847,350 @@ def configure_cskroll1(tld: str, policy: str) -> List[Zone]: # Set key rollover relationship. set_key_relationship(csk1_name, csk2_name) # Signing. - render_and_sign_zone( - zonename, [csk1_name, csk2_name], extra_options="-z -G cdnskey,cds:sha384" - ) + 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 = CmdHelper("KEYGEN", f"-k {policy} -l kasp.conf") + settime = CmdHelper("SETTIME", "-s") + + # Step 1: + # Introduce the first key. This will immediately be active. + zonename = f"step1.{zone}" + zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3"))) + isctest.log.info(f"setup {zonename}") + TactN = "now-7d" + keytimes = f"-P {TactN} -A {TactN}" + # Key generation. + csk_name = keygen(f"{keytimes} {zonename}", cwd="ns3").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").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").strip() + csk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").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").strip() + csk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").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").strip() + csk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").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").strip() + csk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").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").strip() + csk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").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").strip() + csk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").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 From 281f71be6018b3ae4a363f1b6870f266bf445d48 Mon Sep 17 00:00:00 2001 From: Matthijs Mekking Date: Fri, 28 Nov 2025 09:35:03 +0100 Subject: [PATCH 07/16] rollover-dynamic2inline: Update templates This test does not require a trust chain. Merely update the template zonefile to not point to the common template. --- .../ns3/dynamic2inline.kasp.db | 28 ++++++++++++++++++- .../ns3/template.db.in | 1 - 2 files changed, 27 insertions(+), 2 deletions(-) mode change 120000 => 100644 bin/tests/system/rollover-dynamic2inline/ns3/dynamic2inline.kasp.db delete mode 120000 bin/tests/system/rollover-dynamic2inline/ns3/template.db.in diff --git a/bin/tests/system/rollover-dynamic2inline/ns3/dynamic2inline.kasp.db b/bin/tests/system/rollover-dynamic2inline/ns3/dynamic2inline.kasp.db deleted file mode 120000 index f334748d7d..0000000000 --- a/bin/tests/system/rollover-dynamic2inline/ns3/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/ns3/dynamic2inline.kasp.db b/bin/tests/system/rollover-dynamic2inline/ns3/dynamic2inline.kasp.db new file mode 100644 index 0000000000..010b05b3cb --- /dev/null +++ b/bin/tests/system/rollover-dynamic2inline/ns3/dynamic2inline.kasp.db @@ -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-dynamic2inline/ns3/template.db.in b/bin/tests/system/rollover-dynamic2inline/ns3/template.db.in deleted file mode 120000 index ce6d526285..0000000000 --- a/bin/tests/system/rollover-dynamic2inline/ns3/template.db.in +++ /dev/null @@ -1 +0,0 @@ -../../rollover/ns3/template.db.in \ No newline at end of file From ef2a824df68c06344d210c9dda17cb5177e31961 Mon Sep 17 00:00:00 2001 From: Matthijs Mekking Date: Fri, 28 Nov 2025 09:59:51 +0100 Subject: [PATCH 08/16] rollover-enable-dnssec: From setup.sh to pytest bootstrap Symlink ns1 and ns2 to rollover/ns1 and rollover/ns2. Symlink ns3/template.db.j2.manual to rollover/ns3/template.db.j2.manual. Since the bootstrapping is done before the templates are rendered automatically, replace @DEFAULT_ALGORITHM_NUMBER@ in ns3/kasp.conf.j2 to 13 and rename to ns3/kasp.conf. This test introduces an unsigned delegation, adjust render_and_sign_zone and configure_tld accordingly. --- bin/tests/system/rollover-enable-dnssec/ns1 | 1 + bin/tests/system/rollover-enable-dnssec/ns2 | 1 + .../ns3/{kasp.conf.j2 => kasp.conf} | 4 +- .../rollover-enable-dnssec/ns3/template.db.in | 1 - .../ns3/template.db.j2.manual | 1 + .../ns3/trusted.conf.j2 | 1 + .../system/rollover-enable-dnssec/setup.sh | 102 ------------------ .../tests_rollover_enable_dnssec.py | 29 +++++ bin/tests/system/rollover/setup.py | 97 ++++++++++++++++- 9 files changed, 128 insertions(+), 109 deletions(-) create mode 120000 bin/tests/system/rollover-enable-dnssec/ns1 create mode 120000 bin/tests/system/rollover-enable-dnssec/ns2 rename bin/tests/system/rollover-enable-dnssec/ns3/{kasp.conf.j2 => kasp.conf} (89%) delete mode 120000 bin/tests/system/rollover-enable-dnssec/ns3/template.db.in create mode 120000 bin/tests/system/rollover-enable-dnssec/ns3/template.db.j2.manual create mode 120000 bin/tests/system/rollover-enable-dnssec/ns3/trusted.conf.j2 delete mode 100644 bin/tests/system/rollover-enable-dnssec/setup.sh 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/setup.py b/bin/tests/system/rollover/setup.py index 2d7f178ca1..d4b35be615 100644 --- a/bin/tests/system/rollover/setup.py +++ b/bin/tests/system/rollover/setup.py @@ -37,7 +37,11 @@ def configure_tld(zonename: str, delegations: List[Zone]) -> Zone: isctest.log.info(f"create {zonename} zone with delegations and sign") for zone in delegations: - shutil.copy(f"{zone.ns.name}/dsset-{zone.name}.", "ns2/") + 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").strip() zsk_name = keygen(f"{zonename}", cwd="ns2").strip() @@ -113,7 +117,9 @@ def set_key_relationship(key1: str, key2: str): statefile.write(f"Predecessor: {predecessor.tag}\n") -def render_and_sign_zone(zonename: str, keys: List[str], extra_options: str = ""): +def render_and_sign_zone( + zonename: str, keys: List[str], signing: bool = True, extra_options: str = "" +): dnskeys = [] privaterrs = [] for key_name in keys: @@ -132,8 +138,11 @@ def render_and_sign_zone(zonename: str, keys: List[str], extra_options: str = "" } templates.render(f"ns3/{outfile}", tdata, template=f"ns3/{template}") - signer = CmdHelper("SIGNER", "-S -g -x -s now-1h -e now+2w -O raw") - signer(f"{extra_options} -o {zonename} -f {outfile}.signed {outfile}", cwd="ns3") + if signing: + signer = CmdHelper("SIGNER", "-S -g -x -s now-1h -e now+2w -O raw") + signer( + f"{extra_options} -o {zonename} -f {outfile}.signed {outfile}", cwd="ns3" + ) def configure_algo_csk(tld: str, policy: str, reconfig: bool = False) -> List[Zone]: @@ -1194,3 +1203,83 @@ def configure_cskroll2(tld: str, policy: str) -> List[Zone]: 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 = CmdHelper("KEYGEN", f"-k {policy} -l kasp.conf") + settime = CmdHelper("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").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").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").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 From cc4244f38411cfb67aed6467994ac85002ac8756 Mon Sep 17 00:00:00 2001 From: Matthijs Mekking Date: Fri, 28 Nov 2025 10:43:42 +0100 Subject: [PATCH 09/16] rollover-going-insecure: From setup.sh to pytest bootstrap Symlink ns1 and ns2 to rollover/ns1 and rollover/ns2. Symlink ns3/template.db.j2.manual to rollover/ns3/template.db.j2.manual. Since the bootstrapping is done before the templates are rendered automatically, replace @DEFAULT_ALGORITHM@ in ns3/kasp.conf.j2 to ecdsa256 and rename to ns3/kasp.conf. Now we have to fake different lifetimes, so adjust fake_lifetime to update a single key. Note that we have changed the setup slightly: We also sign the step2 zones, but with post validation disabled. This is more accurate because we need to test that the public keys and signatures are being removed from the zone. --- bin/tests/system/rollover-going-insecure/ns1 | 1 + bin/tests/system/rollover-going-insecure/ns2 | 1 + .../ns3/{kasp.conf.j2 => kasp.conf} | 4 +- .../ns3/template.db.in | 1 - .../ns3/template.db.j2.manual | 1 + .../ns3/trusted.conf.j2 | 1 + .../system/rollover-going-insecure/setup.sh | 71 --------------- .../tests_rollover_going_insecure_initial.py | 22 +++++ .../tests_rollover_going_insecure_reconfig.py | 22 +++++ bin/tests/system/rollover/setup.py | 90 ++++++++++++++++--- 10 files changed, 130 insertions(+), 84 deletions(-) create mode 120000 bin/tests/system/rollover-going-insecure/ns1 create mode 120000 bin/tests/system/rollover-going-insecure/ns2 rename bin/tests/system/rollover-going-insecure/ns3/{kasp.conf.j2 => kasp.conf} (78%) delete mode 120000 bin/tests/system/rollover-going-insecure/ns3/template.db.in create mode 120000 bin/tests/system/rollover-going-insecure/ns3/template.db.j2.manual create mode 120000 bin/tests/system/rollover-going-insecure/ns3/trusted.conf.j2 delete mode 100644 bin/tests/system/rollover-going-insecure/setup.sh 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/ns3/kasp.conf.j2 b/bin/tests/system/rollover-going-insecure/ns3/kasp.conf similarity index 78% rename from bin/tests/system/rollover-going-insecure/ns3/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/ns3/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/template.db.in b/bin/tests/system/rollover-going-insecure/ns3/template.db.in deleted file mode 120000 index ce6d526285..0000000000 --- a/bin/tests/system/rollover-going-insecure/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-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/setup.sh b/bin/tests/system/rollover-going-insecure/setup.sh deleted file mode 100644 index 11213c1c83..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 "ns3" - -setup() { - zone="$1" - echo_i "setting up zone: $zone" - zonefile="${zone}.db" - infile="${zone}.db.infile" -} - -# Make lines shorter by storing key states in environment variables. -H="HIDDEN" -R="RUMOURED" -O="OMNIPRESENT" -U="UNRETENTIVE" - -# The 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 61aa583f55..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( 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 9a2d240934..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,6 +23,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=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) diff --git a/bin/tests/system/rollover/setup.py b/bin/tests/system/rollover/setup.py index d4b35be615..b3e5b2fa06 100644 --- a/bin/tests/system/rollover/setup.py +++ b/bin/tests/system/rollover/setup.py @@ -94,13 +94,12 @@ def configure_root(delegations: List[Zone]) -> TrustAnchor: return ksk.into_ta("static-ds") -def fake_lifetime(keys: List[str]): +def fake_lifetime(key: str, lifetime: int): """ - Fake lifetime of old algorithm keys. + Fake lifetime of key. """ - for key in keys: - with open(f"ns3/{key}.state", "a") as statefile: - statefile.write("Lifetime: 0\n") + 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): @@ -363,7 +362,8 @@ def configure_algo_ksk_zsk(tld: str, reconfig: bool = False) -> List[Zone]: cwd="ns3", ) # Signing. - fake_lifetime([ksk1_name, zsk1_name]) + 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: @@ -404,7 +404,8 @@ def configure_algo_ksk_zsk(tld: str, reconfig: bool = False) -> List[Zone]: cwd="ns3", ) # Signing. - fake_lifetime([ksk1_name, zsk1_name]) + 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: @@ -445,7 +446,8 @@ def configure_algo_ksk_zsk(tld: str, reconfig: bool = False) -> List[Zone]: cwd="ns3", ) # Signing. - fake_lifetime([ksk1_name, zsk1_name]) + 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: @@ -486,7 +488,8 @@ def configure_algo_ksk_zsk(tld: str, reconfig: bool = False) -> List[Zone]: cwd="ns3", ) # Signing. - fake_lifetime([ksk1_name, zsk1_name]) + 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: @@ -526,7 +529,8 @@ def configure_algo_ksk_zsk(tld: str, reconfig: bool = False) -> List[Zone]: cwd="ns3", ) # Signing. - fake_lifetime([ksk1_name, zsk1_name]) + 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 @@ -1283,3 +1287,69 @@ def configure_enable_dnssec(tld: str, policy: str) -> List[Zone]: 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 = CmdHelper("KEYGEN", "-a ECDSA256 -L 7200") + settime = CmdHelper("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").strip() + zsk_name = keygen(f"{keytimes} {zonename}", cwd="ns3").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" + ).strip() + zsk_name = keygen(f"{keytimes} {zonename}", cwd="ns3").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 From 08236f4bd65fe4f750f7c093e952a4ff2b596c92 Mon Sep 17 00:00:00 2001 From: Matthijs Mekking Date: Fri, 28 Nov 2025 11:38:06 +0100 Subject: [PATCH 10/16] rollover-ksk-doubleksk: From setup.sh to pytest bootstrap Symlink ns1 and ns2 to rollover/ns1 and rollover/ns2. Symlink ns3/template.db.j2.manual to rollover/ns3/template.db.j2.manual. Since the bootstrapping is done before the templates are rendered automatically, replace @DEFAULT_ALGORITHM@ in ns3/kasp.conf.j2 to ecdsa256 and rename to ns3/kasp.conf. --- .../ns3/{kasp.conf.j2 => kasp.conf} | 0 .../rollover-ksk-3crowd/ns3/template.db.in | 1 - bin/tests/system/rollover-ksk-doubleksk/ns1 | 1 + bin/tests/system/rollover-ksk-doubleksk/ns2 | 1 + .../ns3/{kasp.conf.j2 => kasp.conf} | 8 +- .../rollover-ksk-doubleksk/ns3/template.db.in | 1 - .../ns3/template.db.j2.manual | 1 + .../ns3/trusted.conf.j2 | 1 + .../system/rollover-ksk-doubleksk/setup.sh | 243 ---------------- .../tests_rollover_ksk_doubleksk.py | 30 +- bin/tests/system/rollover/setup.py | 267 ++++++++++++++++++ 11 files changed, 304 insertions(+), 250 deletions(-) rename bin/tests/system/rollover-ksk-3crowd/ns3/{kasp.conf.j2 => kasp.conf} (100%) delete mode 120000 bin/tests/system/rollover-ksk-3crowd/ns3/template.db.in create mode 120000 bin/tests/system/rollover-ksk-doubleksk/ns1 create mode 120000 bin/tests/system/rollover-ksk-doubleksk/ns2 rename bin/tests/system/rollover-ksk-doubleksk/ns3/{kasp.conf.j2 => kasp.conf} (80%) delete mode 120000 bin/tests/system/rollover-ksk-doubleksk/ns3/template.db.in create mode 120000 bin/tests/system/rollover-ksk-doubleksk/ns3/template.db.j2.manual create mode 120000 bin/tests/system/rollover-ksk-doubleksk/ns3/trusted.conf.j2 delete mode 100644 bin/tests/system/rollover-ksk-doubleksk/setup.sh diff --git a/bin/tests/system/rollover-ksk-3crowd/ns3/kasp.conf.j2 b/bin/tests/system/rollover-ksk-3crowd/ns3/kasp.conf similarity index 100% rename from bin/tests/system/rollover-ksk-3crowd/ns3/kasp.conf.j2 rename to bin/tests/system/rollover-ksk-3crowd/ns3/kasp.conf 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-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/setup.py b/bin/tests/system/rollover/setup.py index b3e5b2fa06..e2f31c02a5 100644 --- a/bin/tests/system/rollover/setup.py +++ b/bin/tests/system/rollover/setup.py @@ -1353,3 +1353,270 @@ def configure_going_insecure(tld: str, reconfig: bool = False) -> List[Zone]: render_and_sign_zone(zonename, [ksk_name, zsk_name], extra_options="-P") return zones + + +def configure_ksk_doubleksk(tld: str) -> List[Zone]: + # The zones at ksk-doubleksk.$tld represent the various steps of a KSK + # Double-KSK rollover. + zones = [] + zone = f"ksk-doubleksk.{tld}" + cds = "cds:sha-256" + keygen = CmdHelper("KEYGEN", "-a ECDSAP256SHA256 -L 7200") + settime = CmdHelper("SETTIME", "-s") + + # Step 1: + # Introduce the first key. This will immediately be active. + zonename = f"step1.{zone}" + zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3"))) + isctest.log.info(f"setup {zonename}") + # Timing metadata. + TactN = "now-7d" + keytimes = f"-P {TactN} -A {TactN}" + # Key generation. + ksk_name = keygen(f"-f KSK {keytimes} {zonename}", cwd="ns3").strip() + zsk_name = keygen(f"{keytimes} {zonename}", cwd="ns3").strip() + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -d OMNIPRESENT {TactN} {ksk_name}", + cwd="ns3", + ) + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TactN} -z OMNIPRESENT {TactN} {zsk_name}", + cwd="ns3", + ) + # Signing. + render_and_sign_zone(zonename, [ksk_name, zsk_name], extra_options=f"-G {cds}") + + # Step 2: + # It is time to introduce the new KSK. + zonename = f"step2.{zone}" + zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3"))) + isctest.log.info(f"setup {zonename}") + # Lksk: 60d + # Dreg: n/a + # DprpC: 1h + # TTLds: 1d + # TTLkey: 2h + # publish-safety: 1d + # retire-safety: 2d + # + # According to RFC 7583: + # Tpub(N+1) <= Tact(N) + Lksk - Dreg - IpubC + # IpubC = DprpC + TTLkey (+publish-safety) + # + # IpubC = 27h + # Tact(N) = now - Lksk + Dreg + IpubC = now - 60d + 27h + # = now - 1440h + 27h = now - 1413h + TactN = "now-1413h" + keytimes = f"-P {TactN} -A {TactN}" + # Key generation. + ksk_name = keygen(f"-f KSK {keytimes} {zonename}", cwd="ns3").strip() + zsk_name = keygen(f"{keytimes} {zonename}", cwd="ns3").strip() + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -d OMNIPRESENT {TactN} {ksk_name}", + cwd="ns3", + ) + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TactN} -z OMNIPRESENT {TactN} {zsk_name}", + cwd="ns3", + ) + # Signing. + render_and_sign_zone(zonename, [ksk_name, zsk_name], extra_options=f"-G {cds}") + + # Step 3: + # It is time to submit the DS. + zonename = f"step3.{zone}" + zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3"))) + isctest.log.info(f"setup {zonename}") + # According to RFC 7583: + # Iret = DprpP + TTLds (+retire-safety) + # + # Iret = 50h + # Tpub(N) = now - Lksk = now - 60d = now - 60d + # Tact(N) = now - 1413h + # Tret(N) = now + # Trem(N) = now + Iret = now + 50h + # Tpub(N+1) = now - IpubC = now - 27h + # Tact(N+1) = now + # Tret(N+1) = now + Lksk = now + 60d + # Trem(N+1) = now + Lksk + Iret = now + 60d + 50h + # = now + 1440h + 50h = 1490h + TpubN = "now-60d" + TactN = "now-1413h" + TretN = "now" + TremN = "now+50h" + TpubN1 = "now-27h" + TactN1 = "now" + TretN1 = "now+60d" + TremN1 = "now+1490h" + ksktimes = ( + f"-P {TpubN} -A {TpubN} -P sync {TactN} -I {TretN} -D {TremN} -D sync {TactN1}" + ) + newtimes = f"-P {TpubN1} -A {TactN1} -P sync {TactN1} -I {TretN1} -D {TremN1}" + zsktimes = f"-P {TpubN} -A {TpubN}" + # Key generation. + ksk1_name = keygen(f"-f KSK {ksktimes} {zonename}", cwd="ns3").strip() + ksk2_name = keygen(f"-f KSK {newtimes} {zonename}", cwd="ns3").strip() + zsk_name = keygen(f"{zsktimes} {zonename}", cwd="ns3").strip() + settime( + f"-g HIDDEN -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -d OMNIPRESENT {TactN} {ksk1_name}", + cwd="ns3", + ) + settime( + f"-g OMNIPRESENT -k RUMOURED {TpubN1} -r RUMOURED {TpubN1} -d HIDDEN {TpubN1} {ksk2_name}", + cwd="ns3", + ) + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TpubN} -z OMNIPRESENT {TpubN} {zsk_name}", + cwd="ns3", + ) + # Set key rollover relationship. + set_key_relationship(ksk1_name, ksk2_name) + # Signing. + render_and_sign_zone( + zonename, [ksk1_name, ksk2_name, zsk_name], extra_options=f"-G {cds}" + ) + + # Step 4: + # The DS should be swapped now. + zonename = f"step4.{zone}" + zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3"))) + isctest.log.info(f"setup {zonename}") + # Tpub(N) = now - Lksk - Iret = now - 60d - 50h + # = now - 1440h - 50h = now - 1490h + # Tact(N) = now - 1490h + 27h = now - 1463h + # Tret(N) = now - Iret = now - 50h + # Trem(N) = now + # Tpub(N+1) = now - Iret - IpubC = now - 50h - 27h + # = now - 77h + # Tact(N+1) = Tret(N) + # Tret(N+1) = now + Lksk - Iret = now + 60d - 50h = now + 1390h + # Trem(N+1) = now + Lksk = now + 60d + TpubN = "now-1490h" + TactN = "now-1463h" + TretN = "now-50h" + TremN = "now" + TpubN1 = "now-77h" + TactN1 = TretN + TretN1 = "now+1390h" + TremN1 = "now+60d" + ksktimes = ( + f"-P {TpubN} -A {TpubN} -P sync {TactN} -I {TretN} -D {TremN} -D sync {TactN1}" + ) + newtimes = f"-P {TpubN1} -A {TactN1} -P sync {TactN1} -I {TretN1} -D {TremN1}" + zsktimes = f"-P {TpubN} -A {TpubN}" + # Key generation. + ksk1_name = keygen(f"-f KSK {ksktimes} {zonename}", cwd="ns3").strip() + ksk2_name = keygen(f"-f KSK {newtimes} {zonename}", cwd="ns3").strip() + zsk_name = keygen(f"{zsktimes} {zonename}", cwd="ns3").strip() + settime( + f"-g HIDDEN -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -d UNRETENTIVE {TretN} -D ds {TretN} {ksk1_name}", + cwd="ns3", + ) + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TactN1} -r OMNIPRESENT {TactN1} -d RUMOURED {TactN1} -P ds {TactN1} {ksk2_name}", + cwd="ns3", + ) + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TactN} -z OMNIPRESENT {TactN} {zsk_name}", + cwd="ns3", + ) + # Set key rollover relationship. + set_key_relationship(ksk1_name, ksk2_name) + # Signing. + render_and_sign_zone( + zonename, [ksk1_name, ksk2_name, zsk_name], extra_options=f"-G {cds}" + ) + + # Step 5: + # The predecessor DNSKEY is removed long enough that is has become HIDDEN. + zonename = f"step5.{zone}" + zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3"))) + isctest.log.info(f"setup {zonename}") + # Subtract DNSKEY TTL + zone-propagation-delay from all the times (3h). + # Tpub(N) = now - 1490h - 3h = now - 1493h + # Tact(N) = now - 1463h - 3h = now - 1466h + # Tret(N) = now - 50h - 3h = now - 53h + # Trem(N) = now - 3h + # Tpub(N+1) = now - 77h - 3h = now - 80h + # Tact(N+1) = Tret(N) + # Tret(N+1) = now + 1390h - 3h = now + 1387h + # Trem(N+1) = now + 60d - 3h = now + 1441h + TpubN = "now-1493h" + TactN = "now-1466h" + TretN = "now-53h" + TremN = "now-3h" + TpubN1 = "now-80h" + TactN1 = TretN + TretN1 = "now+1387h" + TremN1 = "now+1441h" + ksktimes = ( + f"-P {TpubN} -A {TpubN} -P sync {TactN} -I {TretN} -D {TremN} -D sync {TactN1}" + ) + newtimes = f"-P {TpubN1} -A {TactN1} -P sync {TactN1} -I {TretN1} -D {TremN1}" + zsktimes = f"-P {TpubN} -A {TpubN}" + # Key generation. + ksk1_name = keygen(f"-f KSK {ksktimes} {zonename}", cwd="ns3").strip() + ksk2_name = keygen(f"-f KSK {newtimes} {zonename}", cwd="ns3").strip() + zsk_name = keygen(f"{zsktimes} {zonename}", cwd="ns3").strip() + settime( + f"-g HIDDEN -k UNRETENTIVE {TretN} -r UNRETENTIVE {TretN} -d HIDDEN {TretN} {ksk1_name}", + cwd="ns3", + ) + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TactN1} -r OMNIPRESENT {TactN1} -d OMNIPRESENT {TactN1} {ksk2_name}", + cwd="ns3", + ) + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TactN} -z OMNIPRESENT {TactN} {zsk_name}", + cwd="ns3", + ) + # Set key rollover relationship. + set_key_relationship(ksk1_name, ksk2_name) + # Signing. + render_and_sign_zone( + zonename, [ksk1_name, ksk2_name, zsk_name], extra_options=f"-G {cds}" + ) + + # Step 6: + # The predecessor DNSKEY can be purged. + zonename = f"step6.{zone}" + zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3"))) + isctest.log.info(f"setup {zonename}") + # Subtract purge-keys interval from all the times (1h). + TpubN = "now-1494h" + TactN = "now-1467h" + TretN = "now-54h" + TremN = "now-4h" + TpubN1 = "now-81h" + TactN1 = TretN + TretN1 = "now+1386h" + TremN1 = "now+1440h" + ksktimes = ( + f"-P {TpubN} -A {TpubN} -P sync {TactN} -I {TretN} -D {TremN} -D sync {TactN1}" + ) + newtimes = f"-P {TpubN1} -A {TactN1} -P sync {TactN1} -I {TretN1} -D {TremN1}" + zsktimes = f"-P {TpubN} -A {TpubN}" + # Key generation. + ksk1_name = keygen(f"-f KSK {ksktimes} {zonename}", cwd="ns3").strip() + ksk2_name = keygen(f"-f KSK {newtimes} {zonename}", cwd="ns3").strip() + zsk_name = keygen(f"{zsktimes} {zonename}", cwd="ns3").strip() + settime( + f"-g HIDDEN -k HIDDEN {TretN} -r HIDDEN {TretN} -d HIDDEN {TretN} {ksk1_name}", + cwd="ns3", + ) + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TactN1} -r OMNIPRESENT {TactN1} -d OMNIPRESENT {TactN1} {ksk2_name}", + cwd="ns3", + ) + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TactN} -z OMNIPRESENT {TactN} {zsk_name}", + cwd="ns3", + ) + # Set key rollover relationship. + set_key_relationship(ksk1_name, ksk2_name) + # Signing. + render_and_sign_zone( + zonename, [ksk1_name, ksk2_name, zsk_name], extra_options=f"-G {cds}" + ) + + return zones From 4ed35f02b13b24e1ca05580b7a7069f6d8b688f6 Mon Sep 17 00:00:00 2001 From: Matthijs Mekking Date: Fri, 28 Nov 2025 11:49:59 +0100 Subject: [PATCH 11/16] rollover-ksk-3crowd: From setup.sh to pytest bootstrap Similar to rollover-ksk-doubleksk. --- bin/tests/system/rollover-ksk-3crowd/ns1 | 1 + bin/tests/system/rollover-ksk-3crowd/ns2 | 1 + .../system/rollover-ksk-3crowd/ns3/kasp.conf | 2 +- .../ns3/template.db.j2.manual | 1 + .../rollover-ksk-3crowd/ns3/trusted.conf.j2 | 1 + bin/tests/system/rollover-ksk-3crowd/setup.sh | 82 ------------------- .../tests_rollover_three_is_a_crowd.py | 22 +++++ bin/tests/system/rollover/setup.py | 61 ++++++++++++++ 8 files changed, 88 insertions(+), 83 deletions(-) create mode 120000 bin/tests/system/rollover-ksk-3crowd/ns1 create mode 120000 bin/tests/system/rollover-ksk-3crowd/ns2 create mode 120000 bin/tests/system/rollover-ksk-3crowd/ns3/template.db.j2.manual create mode 120000 bin/tests/system/rollover-ksk-3crowd/ns3/trusted.conf.j2 delete mode 100644 bin/tests/system/rollover-ksk-3crowd/setup.sh 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 index 138fa68939..ca6c7139f3 120000 --- a/bin/tests/system/rollover-ksk-3crowd/ns3/kasp.conf +++ b/bin/tests/system/rollover-ksk-3crowd/ns3/kasp.conf @@ -1 +1 @@ -../../rollover-ksk-doubleksk/ns3/kasp.conf.j2 \ No newline at end of file +../../rollover-ksk-doubleksk/ns3/kasp.conf \ 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/setup.py b/bin/tests/system/rollover/setup.py index e2f31c02a5..6098739732 100644 --- a/bin/tests/system/rollover/setup.py +++ b/bin/tests/system/rollover/setup.py @@ -1620,3 +1620,64 @@ def configure_ksk_doubleksk(tld: str) -> List[Zone]: ) 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 = CmdHelper("KEYGEN", "-a ECDSAP256SHA256 -L 7200") + settime = CmdHelper("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").strip() + ksk2_name = keygen(f"-f KSK {newtimes} {zonename}", cwd="ns3").strip() + zsk_name = keygen(f"{zsktimes} {zonename}", cwd="ns3").strip() + settime( + f"-g HIDDEN -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -d OMNIPRESENT {TactN} {ksk1_name}", + cwd="ns3", + ) + settime( + f"-g OMNIPRESENT -k RUMOURED {TpubN1} -r RUMOURED {TpubN1} -d HIDDEN {TpubN1} {ksk2_name}", + cwd="ns3", + ) + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TpubN} -z OMNIPRESENT {TpubN} {zsk_name}", + cwd="ns3", + ) + # Set key rollover relationship. + set_key_relationship(ksk1_name, ksk2_name) + # Signing. + render_and_sign_zone( + zonename, [ksk1_name, ksk2_name, zsk_name], extra_options=f"-G {cds}" + ) + + return zones From b6c091d1130c0ba4c49e603b78758dbe493da7e0 Mon Sep 17 00:00:00 2001 From: Matthijs Mekking Date: Fri, 28 Nov 2025 11:59:00 +0100 Subject: [PATCH 12/16] rollover-multisigner: Update templates This test does not require a trust chain. However, it does have a setup script. Rewrite the setup shell script to a pytest bootstrap method. --- .../rollover-lifetime/ns3/limit-lifetime.db | 2 +- .../rollover-lifetime/ns3/longer-lifetime.db | 2 +- .../rollover-lifetime/ns3/shorter-lifetime.db | 2 +- .../rollover-lifetime/ns3/template.db.in | 27 ++++++++ .../rollover-lifetime/ns3/unlimit-lifetime.db | 2 +- .../ns3/template.db.j2.manual | 1 + .../system/rollover-multisigner/setup.sh | 67 ------------------- .../tests_rollover_multisigner.py | 64 ++++++++++++++++++ 8 files changed, 96 insertions(+), 71 deletions(-) create mode 100644 bin/tests/system/rollover-lifetime/ns3/template.db.in create mode 120000 bin/tests/system/rollover-multisigner/ns3/template.db.j2.manual delete mode 100644 bin/tests/system/rollover-multisigner/setup.sh diff --git a/bin/tests/system/rollover-lifetime/ns3/limit-lifetime.db b/bin/tests/system/rollover-lifetime/ns3/limit-lifetime.db index ce6d526285..e9d5917b1f 120000 --- a/bin/tests/system/rollover-lifetime/ns3/limit-lifetime.db +++ b/bin/tests/system/rollover-lifetime/ns3/limit-lifetime.db @@ -1 +1 @@ -../../rollover/ns3/template.db.in \ No newline at end of file +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 index ce6d526285..e9d5917b1f 120000 --- a/bin/tests/system/rollover-lifetime/ns3/longer-lifetime.db +++ b/bin/tests/system/rollover-lifetime/ns3/longer-lifetime.db @@ -1 +1 @@ -../../rollover/ns3/template.db.in \ No newline at end of file +template.db.in \ No newline at end of file diff --git a/bin/tests/system/rollover-lifetime/ns3/shorter-lifetime.db b/bin/tests/system/rollover-lifetime/ns3/shorter-lifetime.db index ce6d526285..e9d5917b1f 120000 --- a/bin/tests/system/rollover-lifetime/ns3/shorter-lifetime.db +++ b/bin/tests/system/rollover-lifetime/ns3/shorter-lifetime.db @@ -1 +1 @@ -../../rollover/ns3/template.db.in \ No newline at end of file +template.db.in \ No newline at end of file diff --git a/bin/tests/system/rollover-lifetime/ns3/template.db.in b/bin/tests/system/rollover-lifetime/ns3/template.db.in new file mode 100644 index 0000000000..010b05b3cb --- /dev/null +++ b/bin/tests/system/rollover-lifetime/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-lifetime/ns3/unlimit-lifetime.db b/bin/tests/system/rollover-lifetime/ns3/unlimit-lifetime.db index ce6d526285..e9d5917b1f 120000 --- a/bin/tests/system/rollover-lifetime/ns3/unlimit-lifetime.db +++ b/bin/tests/system/rollover-lifetime/ns3/unlimit-lifetime.db @@ -1 +1 @@ -../../rollover/ns3/template.db.in \ No newline at end of file +template.db.in \ No newline at end of file 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..ccce44ce3a 100644 --- a/bin/tests/system/rollover-multisigner/tests_rollover_multisigner.py +++ b/bin/tests/system/rollover-multisigner/tests_rollover_multisigner.py @@ -26,6 +26,70 @@ from rollover.common import ( alg, size, ) +from rollover.setup import CmdHelper, fake_lifetime, render_and_sign_zone + + +def bootstrap(): + templates = isctest.template.TemplateEngine(".") + + # Multi-signer zones. + keygen = CmdHelper("KEYGEN", "-a ECDSA256 -L 3600") + settime = CmdHelper("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").strip() + zsk_name = keygen(f"-M 32768:65535 {zonename}", cwd="ns3").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}").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" + ).strip() + zsk_name = keygen(f"-M 0:32767 {keytimes} {zonename}", cwd="ns3").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): From 0016791c91378d9b4d2efaef237e31b5070c3043 Mon Sep 17 00:00:00 2001 From: Matthijs Mekking Date: Fri, 28 Nov 2025 12:14:40 +0100 Subject: [PATCH 13/16] rollover-lifetime: Update templates This test does not require a trust chain. Merely update the template zone files to not point to the common template. --- .../rollover-multisigner/ns3/template.db.in | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) mode change 120000 => 100644 bin/tests/system/rollover-multisigner/ns3/template.db.in 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 + From da04c75cecd708d4076796382d80569ac9e89949 Mon Sep 17 00:00:00 2001 From: Matthijs Mekking Date: Fri, 28 Nov 2025 12:42:21 +0100 Subject: [PATCH 14/16] rollover-straight2none: From setup.sh to pytest bootstrap Similar to rollover-going-insecure. --- bin/tests/system/rollover-straight2none/ns1 | 1 + bin/tests/system/rollover-straight2none/ns2 | 1 + .../rollover-straight2none/ns3/kasp.conf | 1 + .../rollover-straight2none/ns3/kasp.conf.j2 | 1 - .../rollover-straight2none/ns3/template.db.in | 1 - .../ns3/template.db.j2.manual | 1 + .../ns3/trusted.conf.j2 | 1 + .../system/rollover-straight2none/setup.sh | 53 ------------------- .../tests_rollover_straight2none_initial.py | 22 ++++++++ .../tests_rollover_straight2none_reconfig.py | 22 ++++++++ bin/tests/system/rollover/setup.py | 39 ++++++++++++++ 11 files changed, 88 insertions(+), 55 deletions(-) create mode 120000 bin/tests/system/rollover-straight2none/ns1 create mode 120000 bin/tests/system/rollover-straight2none/ns2 create mode 120000 bin/tests/system/rollover-straight2none/ns3/kasp.conf delete mode 120000 bin/tests/system/rollover-straight2none/ns3/kasp.conf.j2 delete mode 120000 bin/tests/system/rollover-straight2none/ns3/template.db.in create mode 120000 bin/tests/system/rollover-straight2none/ns3/template.db.j2.manual create mode 120000 bin/tests/system/rollover-straight2none/ns3/trusted.conf.j2 delete mode 100644 bin/tests/system/rollover-straight2none/setup.sh 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/kasp.conf.j2 b/bin/tests/system/rollover-straight2none/ns3/kasp.conf.j2 deleted file mode 120000 index 909d9909ee..0000000000 --- a/bin/tests/system/rollover-straight2none/ns3/kasp.conf.j2 +++ /dev/null @@ -1 +0,0 @@ -../../rollover-going-insecure/ns3/kasp.conf.j2 \ No newline at end of file diff --git a/bin/tests/system/rollover-straight2none/ns3/template.db.in b/bin/tests/system/rollover-straight2none/ns3/template.db.in deleted file mode 120000 index ce6d526285..0000000000 --- a/bin/tests/system/rollover-straight2none/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-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/setup.sh b/bin/tests/system/rollover-straight2none/setup.sh deleted file mode 100644 index 790b0e22ce..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 "ns3" - -setup() { - zone="$1" - echo_i "setting up zone: $zone" - zonefile="${zone}.db" - infile="${zone}.db.infile" -} - -# Make lines shorter by storing key states in environment variables. -H="HIDDEN" -R="RUMOURED" -O="OMNIPRESENT" -U="UNRETENTIVE" - -# 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_rollover_straight2none_initial.py b/bin/tests/system/rollover-straight2none/tests_rollover_straight2none_initial.py index 098108a6f5..c38e5ddd49 100644 --- a/bin/tests/system/rollover-straight2none/tests_rollover_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( diff --git a/bin/tests/system/rollover-straight2none/tests_rollover_straight2none_reconfig.py b/bin/tests/system/rollover-straight2none/tests_rollover_straight2none_reconfig.py index e5fe16aa3d..5cfb49653b 100644 --- a/bin/tests/system/rollover-straight2none/tests_rollover_straight2none_reconfig.py +++ b/bin/tests/system/rollover-straight2none/tests_rollover_straight2none_reconfig.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.fixture(scope="module", autouse=True) diff --git a/bin/tests/system/rollover/setup.py b/bin/tests/system/rollover/setup.py index 6098739732..047a59dd6e 100644 --- a/bin/tests/system/rollover/setup.py +++ b/bin/tests/system/rollover/setup.py @@ -1355,6 +1355,45 @@ def configure_going_insecure(tld: str, reconfig: bool = False) -> List[Zone]: return zones +def configure_straight2none(tld: str) -> List[Zone]: + # These zones are going straight to "none" policy. This is undefined behavior. + zones = [] + keygen = CmdHelper("KEYGEN", "-k default") + settime = CmdHelper("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").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").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. From e172b4ff1a85922317f76858f6cf3ff4f9b17d15 Mon Sep 17 00:00:00 2001 From: Matthijs Mekking Date: Fri, 28 Nov 2025 13:42:28 +0100 Subject: [PATCH 15/16] rollover-zsk-prepub: From setup.sh to pytest bootstrap Symlink ns1 and ns2 to rollover/ns1 and rollover/ns2. Symlink ns3/template.db.j2.manual to rollover/ns3/template.db.j2.manual. Since the bootstrapping is done before the templates are rendered automatically, replace @DEFAULT_ALGORITHM@ in ns3/kasp.conf.j2 to ecdsa256 and rename to ns3/kasp.conf. --- bin/tests/system/rollover-zsk-prepub/ns1 | 1 + bin/tests/system/rollover-zsk-prepub/ns2 | 1 + .../ns3/{kasp.conf.j2 => kasp.conf} | 8 +- .../rollover-zsk-prepub/ns3/template.db.in | 1 - .../ns3/template.db.j2.manual | 1 + .../rollover-zsk-prepub/ns3/trusted.conf.j2 | 1 + bin/tests/system/rollover-zsk-prepub/setup.sh | 218 ----------------- .../tests_rollover_zsk_prepublication.py | 29 +++ bin/tests/system/rollover/setup.py | 221 ++++++++++++++++++ 9 files changed, 258 insertions(+), 223 deletions(-) create mode 120000 bin/tests/system/rollover-zsk-prepub/ns1 create mode 120000 bin/tests/system/rollover-zsk-prepub/ns2 rename bin/tests/system/rollover-zsk-prepub/ns3/{kasp.conf.j2 => kasp.conf} (78%) delete mode 120000 bin/tests/system/rollover-zsk-prepub/ns3/template.db.in create mode 120000 bin/tests/system/rollover-zsk-prepub/ns3/template.db.j2.manual create mode 120000 bin/tests/system/rollover-zsk-prepub/ns3/trusted.conf.j2 delete mode 100644 bin/tests/system/rollover-zsk-prepub/setup.sh 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/setup.py b/bin/tests/system/rollover/setup.py index 047a59dd6e..48f038101c 100644 --- a/bin/tests/system/rollover/setup.py +++ b/bin/tests/system/rollover/setup.py @@ -1720,3 +1720,224 @@ def configure_ksk_3crowd(tld: str) -> List[Zone]: ) 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 = CmdHelper("KEYGEN", "-a ECDSAP256SHA256 -L 3600") + settime = CmdHelper("SETTIME", "-s") + + # Step 1: + # Introduce the first key. This will immediately be active. + zonename = f"step1.{zone}" + zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3"))) + isctest.log.info(f"setup {zonename}") + # Timing metadata. + TactN = "now-7d" + keytimes = f"-P {TactN} -A {TactN}" + # Key generation. + ksk_name = keygen(f"-f KSK {keytimes} {zonename}", cwd="ns3").strip() + zsk_name = keygen(f"{keytimes} {zonename}", cwd="ns3").strip() + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -d OMNIPRESENT {TactN} {ksk_name}", + cwd="ns3", + ) + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TactN} -z OMNIPRESENT {TactN} {zsk_name}", + cwd="ns3", + ) + # Signing. + render_and_sign_zone(zonename, [ksk_name, zsk_name]) + + # 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").strip() + zsk_name = keygen(f"{keytimes} {zonename}", cwd="ns3").strip() + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -d OMNIPRESENT {TactN} {ksk_name}", + cwd="ns3", + ) + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TactN} -z OMNIPRESENT {TactN} {zsk_name}", + cwd="ns3", + ) + # Signing. + render_and_sign_zone(zonename, [ksk_name, zsk_name]) + + # 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").strip() + zsk1_name = keygen(f"{oldtimes} {zonename}", cwd="ns3").strip() + zsk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").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").strip() + zsk1_name = keygen(f"{oldtimes} {zonename}", cwd="ns3").strip() + zsk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").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").strip() + zsk1_name = keygen(f"{oldtimes} {zonename}", cwd="ns3").strip() + zsk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").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").strip() + zsk1_name = keygen(f"{oldtimes} {zonename}", cwd="ns3").strip() + zsk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").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 From 594ff0816a18c2e46f70a2d5d32e8e33cf359c65 Mon Sep 17 00:00:00 2001 From: Matthijs Mekking Date: Thu, 18 Dec 2025 08:52:09 +0100 Subject: [PATCH 16/16] Drop and replace CmdHelper with EnvCmd A generic helper that calls environment-specified binaries has been added, drop and replace the introduced CmdHelper for the more generic method. --- .../tests_rollover_multisigner.py | 17 +- bin/tests/system/rollover/setup.py | 293 +++++++++--------- .../system/rollover/tests_rollover_manual.py | 14 +- 3 files changed, 166 insertions(+), 158 deletions(-) diff --git a/bin/tests/system/rollover-multisigner/tests_rollover_multisigner.py b/bin/tests/system/rollover-multisigner/tests_rollover_multisigner.py index ccce44ce3a..517992cbde 100644 --- a/bin/tests/system/rollover-multisigner/tests_rollover_multisigner.py +++ b/bin/tests/system/rollover-multisigner/tests_rollover_multisigner.py @@ -21,34 +21,35 @@ 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 CmdHelper, fake_lifetime, render_and_sign_zone +from rollover.setup import fake_lifetime, render_and_sign_zone def bootstrap(): templates = isctest.template.TemplateEngine(".") # Multi-signer zones. - keygen = CmdHelper("KEYGEN", "-a ECDSA256 -L 3600") - settime = CmdHelper("SETTIME", "-s") + 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").strip() - zsk_name = keygen(f"-M 32768:65535 {zonename}", cwd="ns3").strip() + 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}").strip() + zsk_extra = keygen(f"-M 0:32767 {zonename}").out.strip() key = isctest.kasp.Key(zsk_extra) dnskeys.append(key.dnskey) # Render zone file. @@ -74,8 +75,8 @@ def bootstrap(): # Key generation. ksk_name = keygen( f"-M 0:32767 -f KSK {keytimes} {cdstimes} {zonename}", cwd="ns3" - ).strip() - zsk_name = keygen(f"-M 0:32767 {keytimes} {zonename}", cwd="ns3").strip() + ).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", diff --git a/bin/tests/system/rollover/setup.py b/bin/tests/system/rollover/setup.py index 48f038101c..ed4b0d1289 100644 --- a/bin/tests/system/rollover/setup.py +++ b/bin/tests/system/rollover/setup.py @@ -15,24 +15,15 @@ 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 -class CmdHelper: - def __init__(self, env_name: str, base_params: str = ""): - self.bin_path = os.environ[env_name] - self.base_params = base_params - - def __call__(self, params: str, **kwargs): - args = f"{self.base_params} {params}".split() - return isctest.run.cmd([self.bin_path] + args, **kwargs).stdout.decode("utf-8") - - def configure_tld(zonename: str, delegations: List[Zone]) -> Zone: templates = isctest.template.TemplateEngine(".") alg = default_algorithm() - keygen = CmdHelper("KEYGEN", f"-q -a {alg.number} -b {alg.bits} -L 3600") - signer = CmdHelper("SIGNER", "-S -g") + 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") @@ -43,8 +34,8 @@ def configure_tld(zonename: str, delegations: List[Zone]) -> Zone: # Some delegations are unsigned. pass - ksk_name = keygen(f"-f KSK {zonename}", cwd="ns2").strip() - zsk_name = keygen(f"{zonename}", cwd="ns2").strip() + 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] @@ -65,8 +56,8 @@ def configure_tld(zonename: str, delegations: List[Zone]) -> Zone: def configure_root(delegations: List[Zone]) -> TrustAnchor: templates = isctest.template.TemplateEngine(".") alg = default_algorithm() - keygen = CmdHelper("KEYGEN", f"-q -a {alg.number} -b {alg.bits} -L 3600") - signer = CmdHelper("SIGNER", "-S -g") + 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") @@ -74,8 +65,8 @@ def configure_root(delegations: List[Zone]) -> TrustAnchor: for zone in delegations: shutil.copy(f"{zone.ns.name}/dsset-{zone.name}.", "ns1/") - ksk_name = keygen(f"-f KSK {zonename}", cwd="ns1").strip() - zsk_name = keygen(f"{zonename}", cwd="ns1").strip() + 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] @@ -138,7 +129,7 @@ def render_and_sign_zone( templates.render(f"ns3/{outfile}", tdata, template=f"ns3/{template}") if signing: - signer = CmdHelper("SIGNER", "-S -g -x -s now-1h -e now+2w -O raw") + 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" ) @@ -149,8 +140,8 @@ def configure_algo_csk(tld: str, policy: str, reconfig: bool = False) -> List[Zo # of a CSK algorithm rollover. zones = [] zone = f"csk-algorithm-roll.{tld}" - keygen = CmdHelper("KEYGEN", f"-k {policy}") - settime = CmdHelper("SETTIME", "-s") + keygen = EnvCmd("KEYGEN", f"-k {policy}") + settime = EnvCmd("SETTIME", "-s") # Step 1: # Introduce the first key. This will immediately be active. @@ -161,7 +152,7 @@ def configure_algo_csk(tld: str, policy: str, reconfig: bool = False) -> List[Zo TsbmN = "now-161h" csktimes = f"-P {TactN} -A {TactN}" # Key generation. - csk_name = keygen(f"-l csk1.conf {csktimes} {zonename}", cwd="ns3").strip() + 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", @@ -180,8 +171,8 @@ def configure_algo_csk(tld: str, policy: str, reconfig: bool = False) -> List[Zo 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").strip() - csk2_name = keygen(f"-l csk2.conf {newtimes} {zonename}", cwd="ns3").strip() + 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", @@ -204,8 +195,8 @@ def configure_algo_csk(tld: str, policy: str, reconfig: bool = False) -> List[Zo 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").strip() - csk2_name = keygen(f"-l csk2.conf {newtimes} {zonename}", cwd="ns3").strip() + 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", @@ -228,8 +219,8 @@ def configure_algo_csk(tld: str, policy: str, reconfig: bool = False) -> List[Zo 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").strip() - csk2_name = keygen(f"-l csk2.conf {newtimes} {zonename}", cwd="ns3").strip() + 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", @@ -252,8 +243,8 @@ def configure_algo_csk(tld: str, policy: str, reconfig: bool = False) -> List[Zo 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").strip() - csk2_name = keygen(f"-l csk2.conf {newtimes} {zonename}", cwd="ns3").strip() + 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", @@ -276,8 +267,8 @@ def configure_algo_csk(tld: str, policy: str, reconfig: bool = False) -> List[Zo 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").strip() - csk2_name = keygen(f"-l csk2.conf {newtimes} {zonename}", cwd="ns3").strip() + 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", @@ -297,8 +288,8 @@ def configure_algo_ksk_zsk(tld: str, reconfig: bool = False) -> List[Zone]: # algorithm rollover. zones = [] zone = f"algorithm-roll.{tld}" - keygen = CmdHelper("KEYGEN", "-L 3600") - settime = CmdHelper("SETTIME", "-s") + keygen = EnvCmd("KEYGEN", "-L 3600") + settime = EnvCmd("SETTIME", "-s") # Step 1: # Introduce the first key. This will immediately be active. @@ -309,8 +300,10 @@ def configure_algo_ksk_zsk(tld: str, reconfig: bool = False) -> List[Zone]: TsbmN = "now-161h" keytimes = f"-P {TactN} -A {TactN}" # Key generation. - ksk_name = keygen(f"-a RSASHA256 -f KSK {keytimes} {zonename}", cwd="ns3").strip() - zsk_name = keygen(f"-a RSASHA256 {keytimes} {zonename}", cwd="ns3").strip() + 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", @@ -339,12 +332,14 @@ def configure_algo_ksk_zsk(tld: str, reconfig: bool = False) -> List[Zone]: # Key generation. ksk1_name = keygen( f"-a RSASHA256 -f KSK {ksk1times} {zonename}", cwd="ns3" - ).strip() - zsk1_name = keygen(f"-a RSASHA256 {zsk1times} {zonename}", cwd="ns3").strip() + ).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" - ).strip() - zsk2_name = keygen(f"-a ECDSA256 {zsk2times} {zonename}", cwd="ns3").strip() + ).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", @@ -381,12 +376,14 @@ def configure_algo_ksk_zsk(tld: str, reconfig: bool = False) -> List[Zone]: # Key generation. ksk1_name = keygen( f"-a RSASHA256 -f KSK {ksk1times} {zonename}", cwd="ns3" - ).strip() - zsk1_name = keygen(f"-a RSASHA256 {zsk1times} {zonename}", cwd="ns3").strip() + ).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" - ).strip() - zsk2_name = keygen(f"-a ECDSA256 {zsk2times} {zonename}", cwd="ns3").strip() + ).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", @@ -423,12 +420,14 @@ def configure_algo_ksk_zsk(tld: str, reconfig: bool = False) -> List[Zone]: # Key generation. ksk1_name = keygen( f"-a RSASHA256 -f KSK {ksk1times} {zonename}", cwd="ns3" - ).strip() - zsk1_name = keygen(f"-a RSASHA256 {zsk1times} {zonename}", cwd="ns3").strip() + ).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" - ).strip() - zsk2_name = keygen(f"-a ECDSA256 {zsk2times} {zonename}", cwd="ns3").strip() + ).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", @@ -465,12 +464,14 @@ def configure_algo_ksk_zsk(tld: str, reconfig: bool = False) -> List[Zone]: # Key generation. ksk1_name = keygen( f"-a RSASHA256 -f KSK {ksk1times} {zonename}", cwd="ns3" - ).strip() - zsk1_name = keygen(f"-a RSASHA256 {zsk1times} {zonename}", cwd="ns3").strip() + ).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" - ).strip() - zsk2_name = keygen(f"-a ECDSA256 {zsk2times} {zonename}", cwd="ns3").strip() + ).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", @@ -506,12 +507,14 @@ def configure_algo_ksk_zsk(tld: str, reconfig: bool = False) -> List[Zone]: zsk2times = f"-P {TpubN1} -A {TpubN1}" ksk1_name = keygen( f"-a RSASHA256 -f KSK {ksk1times} {zonename}", cwd="ns3" - ).strip() - zsk1_name = keygen(f"-a RSASHA256 {zsk1times} {zonename}", cwd="ns3").strip() + ).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" - ).strip() - zsk2_name = keygen(f"-a ECDSA256 {zsk2times} {zonename}", cwd="ns3").strip() + ).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", @@ -542,8 +545,8 @@ def configure_cskroll1(tld: str, policy: str) -> List[Zone]: zones = [] zone = f"csk-roll1.{tld}" cds = "cdnskey,cds:sha384" - keygen = CmdHelper("KEYGEN", f"-k {policy} -l kasp.conf") - settime = CmdHelper("SETTIME", "-s") + keygen = EnvCmd("KEYGEN", f"-k {policy} -l kasp.conf") + settime = EnvCmd("SETTIME", "-s") # Step 1: # Introduce the first key. This will immediately be active. @@ -553,7 +556,7 @@ def configure_cskroll1(tld: str, policy: str) -> List[Zone]: TactN = "now-7d" keytimes = f"-P {TactN} -A {TactN}" # Key generation. - csk_name = keygen(f"{keytimes} {zonename}", cwd="ns3").strip() + 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", @@ -585,7 +588,7 @@ def configure_cskroll1(tld: str, policy: str) -> List[Zone]: TactN = "now-4461h" keytimes = f"-P {TactN} -A {TactN}" # Key generation. - csk_name = keygen(f"{keytimes} {zonename}", cwd="ns3").strip() + 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", @@ -640,8 +643,8 @@ def configure_cskroll1(tld: str, policy: str) -> List[Zone]: ) newtimes = f"-P {TpubN1} -P sync {TactN1} -A {TactN1} -I {TretN1} -D {TremN1}" # Key generation. - csk1_name = keygen(f"{keytimes} {zonename}", cwd="ns3").strip() - csk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").strip() + 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", @@ -693,8 +696,8 @@ def configure_cskroll1(tld: str, policy: str) -> List[Zone]: ) newtimes = f"-P {TpubN1} -P sync {TactN1} -A {TactN1} -I {TretN1} -D {TremN1}" # Key generation. - csk1_name = keygen(f"{keytimes} {zonename}", cwd="ns3").strip() - csk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").strip() + 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", @@ -728,8 +731,8 @@ def configure_cskroll1(tld: str, policy: str) -> List[Zone]: ) newtimes = f"-P {TpubN1} -P sync {TactN1} -A {TactN1} -I {TretN1} -D {TremN1}" # Key generation. - csk1_name = keygen(f"{keytimes} {zonename}", cwd="ns3").strip() - csk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").strip() + 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", @@ -779,8 +782,8 @@ def configure_cskroll1(tld: str, policy: str) -> List[Zone]: ) newtimes = f"-P {TpubN1} -P sync {TactN1} -A {TactN1} -I {TretN1} -D {TremN1}" # Key generation. - csk1_name = keygen(f"{keytimes} {zonename}", cwd="ns3").strip() - csk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").strip() + 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", @@ -813,8 +816,8 @@ def configure_cskroll1(tld: str, policy: str) -> List[Zone]: ) newtimes = f"-P {TpubN1} -P sync {TactN1} -A {TactN1} -I {TretN1} -D {TremN1}" # Key generation. - csk1_name = keygen(f"{keytimes} {zonename}", cwd="ns3").strip() - csk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").strip() + 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", @@ -847,8 +850,8 @@ def configure_cskroll1(tld: str, policy: str) -> List[Zone]: ) newtimes = f"-P {TpubN1} -P sync {TactN1} -A {TactN1} -I {TretN1} -D {TremN1}" # Key generation. - csk1_name = keygen(f"{keytimes} {zonename}", cwd="ns3").strip() - csk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").strip() + 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", @@ -873,8 +876,8 @@ def configure_cskroll2(tld: str, policy: str) -> List[Zone]: zones = [] zone = f"csk-roll2.{tld}" cds = "cdnskey,cds:sha-256,cds:sha-384" - keygen = CmdHelper("KEYGEN", f"-k {policy} -l kasp.conf") - settime = CmdHelper("SETTIME", "-s") + keygen = EnvCmd("KEYGEN", f"-k {policy} -l kasp.conf") + settime = EnvCmd("SETTIME", "-s") # Step 1: # Introduce the first key. This will immediately be active. @@ -884,7 +887,7 @@ def configure_cskroll2(tld: str, policy: str) -> List[Zone]: TactN = "now-7d" keytimes = f"-P {TactN} -A {TactN}" # Key generation. - csk_name = keygen(f"{keytimes} {zonename}", cwd="ns3").strip() + 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", @@ -916,7 +919,7 @@ def configure_cskroll2(tld: str, policy: str) -> List[Zone]: TactN = "now-4461h" keytimes = f"-P {TactN} -A {TactN}" # Key generation. - csk_name = keygen(f"{keytimes} {zonename}", cwd="ns3").strip() + 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", @@ -971,8 +974,8 @@ def configure_cskroll2(tld: str, policy: str) -> List[Zone]: ) newtimes = f"-P {TpubN1} -P sync {TactN1} -A {TactN1} -I {TretN1} -D {TremN1}" # Key generation. - csk1_name = keygen(f"{keytimes} {zonename}", cwd="ns3").strip() - csk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").strip() + 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", @@ -1026,8 +1029,8 @@ def configure_cskroll2(tld: str, policy: str) -> List[Zone]: ) newtimes = f"-P {TpubN1} -P sync {TactN1} -A {TactN1} -I {TretN1} -D {TremN1}" # Key generation. - csk1_name = keygen(f"{keytimes} {zonename}", cwd="ns3").strip() - csk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").strip() + 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", @@ -1070,8 +1073,8 @@ def configure_cskroll2(tld: str, policy: str) -> List[Zone]: ) newtimes = f"-P {TpubN1} -P sync {TactN1} -A {TactN1} -I {TretN1} -D {TremN1}" # Key generation. - csk1_name = keygen(f"{keytimes} {zonename}", cwd="ns3").strip() - csk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").strip() + 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", @@ -1113,8 +1116,8 @@ def configure_cskroll2(tld: str, policy: str) -> List[Zone]: ) newtimes = f"-P {TpubN1} -P sync {TactN1} -A {TactN1} -I {TretN1} -D {TremN1}" # Key generation. - csk1_name = keygen(f"{keytimes} {zonename}", cwd="ns3").strip() - csk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").strip() + 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", @@ -1157,8 +1160,8 @@ def configure_cskroll2(tld: str, policy: str) -> List[Zone]: ) newtimes = f"-P {TpubN1} -P sync {TactN1} -A {TactN1} -I {TretN1} -D {TremN1}" # Key generation. - csk1_name = keygen(f"{keytimes} {zonename}", cwd="ns3").strip() - csk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").strip() + 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", @@ -1191,8 +1194,8 @@ def configure_cskroll2(tld: str, policy: str) -> List[Zone]: ) newtimes = f"-P {TpubN1} -P sync {TactN1} -A {TactN1} -I {TretN1} -D {TremN1}" # Key generation. - csk1_name = keygen(f"{keytimes} {zonename}", cwd="ns3").strip() - csk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").strip() + 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", @@ -1214,8 +1217,8 @@ def configure_enable_dnssec(tld: str, policy: str) -> List[Zone]: # initial signing of a zone. zones = [] zone = f"enable-dnssec.{tld}" - keygen = CmdHelper("KEYGEN", f"-k {policy} -l kasp.conf") - settime = CmdHelper("SETTIME", "-s") + 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 @@ -1237,7 +1240,7 @@ def configure_enable_dnssec(tld: str, policy: str) -> List[Zone]: TpubN = "now-900s" keytimes = f"-P {TpubN} -A {TpubN}" # Key generation. - csk_name = keygen(f"{keytimes} {zonename}", cwd="ns3").strip() + 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", @@ -1257,7 +1260,7 @@ def configure_enable_dnssec(tld: str, policy: str) -> List[Zone]: TpubN = "now-43500s" keytimes = f"-P {TpubN} -A {TpubN}" # Key generation. - csk_name = keygen(f"{keytimes} {zonename}", cwd="ns3").strip() + 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", @@ -1278,7 +1281,7 @@ def configure_enable_dnssec(tld: str, policy: str) -> List[Zone]: TsbmN = "now-10800s" keytimes = f"-P {TpubN} -A {TpubN} -P sync {TsbmN}" # Key generation. - csk_name = keygen(f"{keytimes} {zonename}", cwd="ns3").strip() + 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", @@ -1291,8 +1294,8 @@ def configure_enable_dnssec(tld: str, policy: str) -> List[Zone]: def configure_going_insecure(tld: str, reconfig: bool = False) -> List[Zone]: zones = [] - keygen = CmdHelper("KEYGEN", "-a ECDSA256 -L 7200") - settime = CmdHelper("SETTIME", "-s") + 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. @@ -1309,8 +1312,10 @@ def configure_going_insecure(tld: str, reconfig: bool = False) -> List[Zone]: keytimes = f"-P {TpubN} -A {TpubN}" cdstimes = f"-P sync {TsbmN}" # Key generation. - ksk_name = keygen(f"-f KSK {keytimes} {cdstimes} {zonename}", cwd="ns3").strip() - zsk_name = keygen(f"{keytimes} {zonename}", cwd="ns3").strip() + 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", @@ -1336,8 +1341,8 @@ def configure_going_insecure(tld: str, reconfig: bool = False) -> List[Zone]: # Key generation. ksk_name = keygen( f"-f KSK {keytimes} {cdstimes} {zonename}", cwd="ns3" - ).strip() - zsk_name = keygen(f"{keytimes} {zonename}", cwd="ns3").strip() + ).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", @@ -1358,8 +1363,8 @@ def configure_going_insecure(tld: str, reconfig: bool = False) -> List[Zone]: def configure_straight2none(tld: str) -> List[Zone]: # These zones are going straight to "none" policy. This is undefined behavior. zones = [] - keygen = CmdHelper("KEYGEN", "-k default") - settime = CmdHelper("SETTIME", "-s") + keygen = EnvCmd("KEYGEN", "-k default") + settime = EnvCmd("SETTIME", "-s") TpubN = "now-10d" TsbmN = "now-12955mi" @@ -1369,7 +1374,7 @@ def configure_straight2none(tld: str) -> List[Zone]: 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").strip() + 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", @@ -1383,7 +1388,7 @@ def configure_straight2none(tld: str) -> List[Zone]: ) isctest.log.info(f"setup {zonename}") # Key generation. - csk_name = keygen(f"-f KSK {keytimes} {zonename}", cwd="ns3").strip() + 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", @@ -1400,8 +1405,8 @@ def configure_ksk_doubleksk(tld: str) -> List[Zone]: zones = [] zone = f"ksk-doubleksk.{tld}" cds = "cds:sha-256" - keygen = CmdHelper("KEYGEN", "-a ECDSAP256SHA256 -L 7200") - settime = CmdHelper("SETTIME", "-s") + keygen = EnvCmd("KEYGEN", "-a ECDSAP256SHA256 -L 7200") + settime = EnvCmd("SETTIME", "-s") # Step 1: # Introduce the first key. This will immediately be active. @@ -1412,8 +1417,8 @@ def configure_ksk_doubleksk(tld: str) -> List[Zone]: TactN = "now-7d" keytimes = f"-P {TactN} -A {TactN}" # Key generation. - ksk_name = keygen(f"-f KSK {keytimes} {zonename}", cwd="ns3").strip() - zsk_name = keygen(f"{keytimes} {zonename}", cwd="ns3").strip() + 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", @@ -1448,8 +1453,8 @@ def configure_ksk_doubleksk(tld: str) -> List[Zone]: TactN = "now-1413h" keytimes = f"-P {TactN} -A {TactN}" # Key generation. - ksk_name = keygen(f"-f KSK {keytimes} {zonename}", cwd="ns3").strip() - zsk_name = keygen(f"{keytimes} {zonename}", cwd="ns3").strip() + 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", @@ -1493,9 +1498,9 @@ def configure_ksk_doubleksk(tld: str) -> List[Zone]: newtimes = f"-P {TpubN1} -A {TactN1} -P sync {TactN1} -I {TretN1} -D {TremN1}" zsktimes = f"-P {TpubN} -A {TpubN}" # Key generation. - ksk1_name = keygen(f"-f KSK {ksktimes} {zonename}", cwd="ns3").strip() - ksk2_name = keygen(f"-f KSK {newtimes} {zonename}", cwd="ns3").strip() - zsk_name = keygen(f"{zsktimes} {zonename}", cwd="ns3").strip() + 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", @@ -1544,9 +1549,9 @@ def configure_ksk_doubleksk(tld: str) -> List[Zone]: newtimes = f"-P {TpubN1} -A {TactN1} -P sync {TactN1} -I {TretN1} -D {TremN1}" zsktimes = f"-P {TpubN} -A {TpubN}" # Key generation. - ksk1_name = keygen(f"-f KSK {ksktimes} {zonename}", cwd="ns3").strip() - ksk2_name = keygen(f"-f KSK {newtimes} {zonename}", cwd="ns3").strip() - zsk_name = keygen(f"{zsktimes} {zonename}", cwd="ns3").strip() + 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", @@ -1594,9 +1599,9 @@ def configure_ksk_doubleksk(tld: str) -> List[Zone]: newtimes = f"-P {TpubN1} -A {TactN1} -P sync {TactN1} -I {TretN1} -D {TremN1}" zsktimes = f"-P {TpubN} -A {TpubN}" # Key generation. - ksk1_name = keygen(f"-f KSK {ksktimes} {zonename}", cwd="ns3").strip() - ksk2_name = keygen(f"-f KSK {newtimes} {zonename}", cwd="ns3").strip() - zsk_name = keygen(f"{zsktimes} {zonename}", cwd="ns3").strip() + 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", @@ -1636,9 +1641,9 @@ def configure_ksk_doubleksk(tld: str) -> List[Zone]: newtimes = f"-P {TpubN1} -A {TactN1} -P sync {TactN1} -I {TretN1} -D {TremN1}" zsktimes = f"-P {TpubN} -A {TpubN}" # Key generation. - ksk1_name = keygen(f"-f KSK {ksktimes} {zonename}", cwd="ns3").strip() - ksk2_name = keygen(f"-f KSK {newtimes} {zonename}", cwd="ns3").strip() - zsk_name = keygen(f"{zsktimes} {zonename}", cwd="ns3").strip() + 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", @@ -1674,8 +1679,8 @@ def configure_ksk_3crowd(tld: str) -> List[Zone]: # zones = [] cds = "cds:sha-256" - keygen = CmdHelper("KEYGEN", "-a ECDSAP256SHA256 -L 7200") - settime = CmdHelper("SETTIME", "-s") + 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. @@ -1697,9 +1702,9 @@ def configure_ksk_3crowd(tld: str) -> List[Zone]: newtimes = f"-P {TpubN1} -A {TactN1} -P sync {TactN1} -I {TretN1} -D {TremN1}" zsktimes = f"-P {TpubN} -A {TpubN}" # Key generation. - ksk1_name = keygen(f"-f KSK {ksktimes} {zonename}", cwd="ns3").strip() - ksk2_name = keygen(f"-f KSK {newtimes} {zonename}", cwd="ns3").strip() - zsk_name = keygen(f"{zsktimes} {zonename}", cwd="ns3").strip() + 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", @@ -1727,8 +1732,8 @@ def configure_zsk_prepub(tld: str) -> List[Zone]: # Pre-Publication rollover. zones = [] zone = f"zsk-prepub.{tld}" - keygen = CmdHelper("KEYGEN", "-a ECDSAP256SHA256 -L 3600") - settime = CmdHelper("SETTIME", "-s") + keygen = EnvCmd("KEYGEN", "-a ECDSAP256SHA256 -L 3600") + settime = EnvCmd("SETTIME", "-s") # Step 1: # Introduce the first key. This will immediately be active. @@ -1739,8 +1744,8 @@ def configure_zsk_prepub(tld: str) -> List[Zone]: TactN = "now-7d" keytimes = f"-P {TactN} -A {TactN}" # Key generation. - ksk_name = keygen(f"-f KSK {keytimes} {zonename}", cwd="ns3").strip() - zsk_name = keygen(f"{keytimes} {zonename}", cwd="ns3").strip() + 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", @@ -1763,8 +1768,8 @@ def configure_zsk_prepub(tld: str) -> List[Zone]: TactN = "now-694h" keytimes = f"-P {TactN} -A {TactN}" # Key generation. - ksk_name = keygen(f"-f KSK {keytimes} {zonename}", cwd="ns3").strip() - zsk_name = keygen(f"{keytimes} {zonename}", cwd="ns3").strip() + 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", @@ -1799,9 +1804,9 @@ def configure_zsk_prepub(tld: str) -> List[Zone]: 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").strip() - zsk1_name = keygen(f"{oldtimes} {zonename}", cwd="ns3").strip() - zsk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").strip() + 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", @@ -1850,9 +1855,9 @@ def configure_zsk_prepub(tld: str) -> List[Zone]: 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").strip() - zsk1_name = keygen(f"{oldtimes} {zonename}", cwd="ns3").strip() - zsk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").strip() + 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", @@ -1889,9 +1894,9 @@ def configure_zsk_prepub(tld: str) -> List[Zone]: 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").strip() - zsk1_name = keygen(f"{oldtimes} {zonename}", cwd="ns3").strip() - zsk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").strip() + 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", @@ -1923,9 +1928,9 @@ def configure_zsk_prepub(tld: str) -> List[Zone]: 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").strip() - zsk1_name = keygen(f"{oldtimes} {zonename}", cwd="ns3").strip() - zsk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").strip() + 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", diff --git a/bin/tests/system/rollover/tests_rollover_manual.py b/bin/tests/system/rollover/tests_rollover_manual.py index 75a705fca1..f2c9871f4d 100644 --- a/bin/tests/system/rollover/tests_rollover_manual.py +++ b/bin/tests/system/rollover/tests_rollover_manual.py @@ -15,10 +15,10 @@ import os import isctest 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 ( - CmdHelper, configure_root, configure_tld, ) @@ -27,9 +27,9 @@ from rollover.setup import ( def setup_zone(zone, ksk_time, ksk_settime, zsk_time, zsk_settime) -> Zone: templates = isctest.template.TemplateEngine(".") alg = default_algorithm() - keygen = CmdHelper("KEYGEN", f"-q -a {alg.number} -b {alg.bits} -L 3600") - signer = CmdHelper("SIGNER", "-S -g") - settime = CmdHelper("SETTIME", "-s") + 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" @@ -40,8 +40,10 @@ def setup_zone(zone, ksk_time, ksk_settime, zsk_time, zsk_settime) -> 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").strip() - zsk_name = keygen(f"-P {zsk_time} -A {zsk_time} {zone}", cwd="ns3").strip() + 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.