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 abf27aca65..5f60cb048c 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 @@ -13,8 +13,11 @@ from datetime import timedelta +import pytest + import isctest from isctest.kasp import Ipub, Iret +from isctest.util import param from rollover.common import ( pytestmark, alg, @@ -62,11 +65,22 @@ 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 test_csk_roll1_step1(alg, size, ns3): - zone = "step1.csk-roll1.autosign" +@pytest.mark.parametrize( + "tld", + [ + param("autosign"), + param("manual"), + ], +) +def test_csk_roll1_step1(tld, alg, size, ns3): + zone = f"step1.csk-roll1.{tld}" + policy = f"{POLICY}-{tld}" isctest.kasp.wait_keymgr_done(ns3, zone) + # manual-mode: Nothing changing in the zone, no 'dnssec -step' required. + # Note that the key was already generated during setup. + step = { # Introduce the first key. This will immediately be active. "zone": zone, @@ -79,14 +93,45 @@ def test_csk_roll1_step1(alg, size, ns3): # registration delay). "nextev": CSK_LIFETIME - IPUB - timedelta(days=7), } - isctest.kasp.check_rollover_step(ns3, CONFIG, POLICY, step) + isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step) -def test_csk_roll1_step2(alg, size, ns3): - zone = "step2.csk-roll1.autosign" +@pytest.mark.parametrize( + "tld", + [ + param("autosign"), + param("manual"), + ], +) +def test_csk_roll1_step2(tld, alg, size, ns3): + zone = f"step2.csk-roll1.{tld}" + policy = f"{POLICY}-{tld}" isctest.kasp.wait_keymgr_done(ns3, zone) + if tld == "manual": + # Same as step 1. + step = { + "zone": zone, + "cdss": CDSS, + "keyprops": [ + f"csk {LIFETIME_POLICY} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{OFFSETS['step2-p']}", + ], + "manual-mode": True, + "nextev": None, + } + keys = isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step) + + # Check logs. + tag = keys[0].key.tag + msg = f"keymgr-manual-mode: block CSK rollover for key {zone}/ECDSAP256SHA256/{tag} (policy {policy})" + ns3.log.expect(msg) + + # Force step. + with ns3.watch_log_from_here() as watcher: + ns3.rndc(f"dnssec -step {zone}") + watcher.wait_for_line(f"keymgr: {zone} done") + step = { # Successor CSK is prepublished (signs DNSKEY RRset, but not yet # other RRsets). @@ -104,14 +149,59 @@ def test_csk_roll1_step2(alg, size, ns3): # Next key event is when the successor CSK becomes OMNIPRESENT. "nextev": IPUB, } - isctest.kasp.check_rollover_step(ns3, CONFIG, POLICY, step) + isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step) -def test_csk_roll1_step3(alg, size, ns3): - zone = "step3.csk-roll1.autosign" +@pytest.mark.parametrize( + "tld", + [ + param("autosign"), + param("manual"), + ], +) +def test_csk_roll1_step3(tld, alg, size, ns3): + zone = f"step3.csk-roll1.{tld}" + policy = f"{POLICY}-{tld}" isctest.kasp.wait_keymgr_done(ns3, zone) + if tld == "manual": + # Same as step 2, but DNSKEY has become OMNIPRESENT. + step = { + "zone": zone, + "cdss": CDSS, + "keyprops": [ + f"csk {LIFETIME_POLICY} {alg} {size} goal:hidden dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{OFFSETS['step3-p']}", + f"csk {LIFETIME_POLICY} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:hidden ds:hidden offset:{OFFSETS['step3-s']}", + ], + "keyrelationships": [0, 1], + "manual-mode": True, + "nextev": None, + } + 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 ZRRSIG state HIDDEN to state RUMOURED" + ns3.log.expect(msg) + + # Force step. + with ns3.watch_log_from_here() as watcher: + ns3.rndc(f"dnssec -step {zone}") + watcher.wait_for_line(f"keymgr: {zone} done") + + # Check logs. + tag = keys[0].key.tag + msg = f"keymgr-manual-mode: block transition CSK {zone}/ECDSAP256SHA256/{tag} type ZRRSIG state OMNIPRESENT to state UNRETENTIVE" + if msg in ns3.log: + # Force step. + isctest.log.debug( + f"keymgr-manual-mode blocking transition CSK {zone}/ECDSAP256SHA256/{tag} type ZRRSIG state OMNIPRESENT to state UNRETENTIVE, step again" + ) + with ns3.watch_log_from_here() as watcher: + ns3.rndc(f"dnssec -step {zone}") + watcher.wait_for_line(f"keymgr: {zone} done") + step = { # Successor CSK becomes omnipresent, meaning we can start signing # the remainder of the zone with the successor CSK, and we can @@ -142,14 +232,50 @@ def test_csk_roll1_step3(alg, size, ns3): # from the predecessor ZSK. "smooth": True, } - isctest.kasp.check_rollover_step(ns3, CONFIG, POLICY, step) + isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step) -def test_csk_roll1_step4(alg, size, ns3): - zone = "step4.csk-roll1.autosign" +@pytest.mark.parametrize( + "tld", + [ + param("autosign"), + param("manual"), + ], +) +def test_csk_roll1_step4(tld, alg, size, ns3): + zone = f"step4.csk-roll1.{tld}" + policy = f"{POLICY}-{tld}" isctest.kasp.wait_keymgr_done(ns3, zone) + if tld == "manual": + # Same as step 3, but DS has become HIDDEN/OMNIPRESENT. + step = { + "zone": zone, + "cdss": CDSS, + "keyprops": [ + f"csk {LIFETIME_POLICY} {alg} {size} goal:hidden dnskey:omnipresent krrsig:omnipresent zrrsig:unretentive ds:hidden offset:{OFFSETS['step4-p']}", + f"csk {LIFETIME_POLICY} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:rumoured ds:omnipresent offset:{OFFSETS['step4-s']}", + ], + "keyrelationships": [0, 1], + "manual-mode": True, + "nextev": None, + # We already swapped the DS in the previous step, so disable ds-swap. + "ds-swap": False, + } + 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}/ECDSAP256SHA256/{tag} type KRRSIG state OMNIPRESENT to state UNRETENTIVE" + + ns3.log.expect(msg) + + # Force step. + with ns3.watch_log_from_here() as watcher: + ns3.rndc(f"dnssec -step {zone}") + watcher.wait_for_line(f"keymgr: {zone} done") + step = { "zone": zone, "cdss": CDSS, @@ -169,14 +295,24 @@ def test_csk_roll1_step4(alg, size, ns3): # We already swapped the DS in the previous step, so disable ds-swap. "ds-swap": False, } - isctest.kasp.check_rollover_step(ns3, CONFIG, POLICY, step) + isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step) -def test_csk_roll1_step5(alg, size, ns3): - zone = "step5.csk-roll1.autosign" +@pytest.mark.parametrize( + "tld", + [ + param("autosign"), + param("manual"), + ], +) +def test_csk_roll1_step5(tld, alg, size, ns3): + zone = f"step5.csk-roll1.{tld}" + policy = f"{POLICY}-{tld}" isctest.kasp.wait_keymgr_done(ns3, zone) + # manual-mode: Nothing changing in the zone, no 'dnssec -step' required. + step = { "zone": zone, "cdss": CDSS, @@ -192,14 +328,25 @@ def test_csk_roll1_step5(alg, size, ns3): # CSK. "nextev": SIGNDELAY, } - isctest.kasp.check_rollover_step(ns3, CONFIG, POLICY, step) + isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step) -def test_csk_roll1_step6(alg, size, ns3): - zone = "step6.csk-roll1.autosign" +@pytest.mark.parametrize( + "tld", + [ + param("autosign"), + param("manual"), + ], +) +def test_csk_roll1_step6(tld, alg, size, ns3): + zone = f"step6.csk-roll1.{tld}" + policy = f"{POLICY}-{tld}" isctest.kasp.wait_keymgr_done(ns3, zone) + if tld == "manual": + return + step = { "zone": zone, "cdss": CDSS, @@ -217,14 +364,24 @@ def test_csk_roll1_step6(alg, size, ns3): # This is the DNSKEY TTL plus zone propagation delay. "nextev": KEYTTLPROP, } - isctest.kasp.check_rollover_step(ns3, CONFIG, POLICY, step) + isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step) -def test_csk_roll1_step7(alg, size, ns3): - zone = "step7.csk-roll1.autosign" +@pytest.mark.parametrize( + "tld", + [ + param("autosign"), + param("manual"), + ], +) +def test_csk_roll1_step7(tld, alg, size, ns3): + zone = f"step7.csk-roll1.{tld}" + policy = f"{POLICY}-{tld}" isctest.kasp.wait_keymgr_done(ns3, zone) + # manual-mode: Nothing changing in the zone, no 'dnssec -step' required. + step = { "zone": zone, "cdss": CDSS, @@ -239,14 +396,24 @@ def test_csk_roll1_step7(alg, size, ns3): # minus the prepublication time. "nextev": CSK_LIFETIME - IRETZSK - IPUB - KEYTTLPROP, } - isctest.kasp.check_rollover_step(ns3, CONFIG, POLICY, step) + isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step) -def test_csk_roll1_step8(alg, size, ns3): - zone = "step8.csk-roll1.autosign" +@pytest.mark.parametrize( + "tld", + [ + param("autosign"), + param("manual"), + ], +) +def test_csk_roll1_step8(tld, alg, size, ns3): + zone = f"step8.csk-roll1.{tld}" + policy = f"{POLICY}-{tld}" isctest.kasp.wait_keymgr_done(ns3, zone) + # manual-mode: Nothing changing in the zone, no 'dnssec -step' required. + step = { "zone": zone, "cdss": CDSS, @@ -255,4 +422,4 @@ def test_csk_roll1_step8(alg, size, ns3): ], "nextev": None, } - isctest.kasp.check_rollover_step(ns3, CONFIG, POLICY, step) + isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step)