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 6058780de0..9646dce7af 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 @@ -15,6 +15,7 @@ import pytest import isctest from isctest.kasp import KeyTimingMetadata +from isctest.util import param from rollover.common import ( pytestmark, alg, @@ -28,6 +29,7 @@ from rollover.common import ( ALGOROLL_KEYTTLPROP, ALGOROLL_OFFSETS, ALGOROLL_OFFVAL, + DURATION, TIMEDELTA, ) @@ -50,11 +52,48 @@ def reconfigure(ns6, templates): TIME_PASSED = KeyTimingMetadata.now().value - start_time.value -def test_algoroll_ksk_zsk_reconfig_step1(ns6, alg, size): - zone = "step1.algorithm-roll.kasp" +@pytest.mark.parametrize( + "tld", + [ + param("kasp"), + param("manual"), + ], +) +def test_algoroll_ksk_zsk_reconfig_step1(tld, ns6, alg, size): + zone = f"step1.algorithm-roll.{tld}" + policy = f"{POLICY}-{tld}" isctest.kasp.wait_keymgr_done(ns6, zone, reconfig=True) + if tld == "manual": + # Same as initial. + step = { + "zone": zone, + "cdss": CDSS, + "keyprops": [ + f"ksk 0 8 2048 goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{-DURATION['P7D']}", + f"zsk 0 8 2048 goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{-DURATION['P7D']}", + ], + "manual-mode": True, + "nextev": None, + } + keys = isctest.kasp.check_rollover_step(ns6, CONFIG, policy, step) + + # Check logs. + ktag = keys[0].key.tag + ztag = keys[1].key.tag + 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 + ns6.log.expect(msg1) + ns6.log.expect(msg2) + ns6.log.expect(msg3) + + # Force step. + with ns6.watch_log_from_here() as watcher: + ns6.rndc(f"dnssec -step {zone}") + watcher.wait_for_line(f"keymgr: {zone} done") + step = { "zone": zone, "cdss": CDSS, @@ -69,14 +108,24 @@ def test_algoroll_ksk_zsk_reconfig_step1(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(ns6, CONFIG, policy, step) -def test_algoroll_ksk_zsk_reconfig_step2(ns6, alg, size): - zone = "step2.algorithm-roll.kasp" +@pytest.mark.parametrize( + "tld", + [ + param("kasp"), + param("manual"), + ], +) +def test_algoroll_ksk_zsk_reconfig_step2(tld, ns6, alg, size): + zone = f"step2.algorithm-roll.{tld}" + policy = f"{POLICY}-{tld}" isctest.kasp.wait_keymgr_done(ns6, zone, reconfig=True) + # manual-mode: Nothing changing in the zone, no 'dnssec -step' required. + step = { "zone": zone, "cdss": CDSS, @@ -98,14 +147,60 @@ def test_algoroll_ksk_zsk_reconfig_step2(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(ns6, CONFIG, policy, step) -def test_algoroll_ksk_zsk_reconfig_step3(ns6, alg, size): - zone = "step3.algorithm-roll.kasp" +@pytest.mark.parametrize( + "tld", + [ + param("kasp"), + param("manual"), + ], +) +def test_algoroll_ksk_zsk_reconfig_step3(tld, ns6, alg, size): + zone = f"step3.algorithm-roll.{tld}" + policy = f"{POLICY}-{tld}" isctest.kasp.wait_keymgr_done(ns6, zone, reconfig=True) + if tld == "manual": + # Same as step 2, but the zone signatures have become OMNIPRESENT. + step = { + "zone": zone, + "cdss": CDSS, + "keyprops": [ + f"ksk 0 8 2048 goal:hidden dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{ALGOROLL_OFFVAL}", + f"zsk 0 8 2048 goal:hidden dnskey:omnipresent zrrsig:omnipresent offset:{ALGOROLL_OFFVAL}", + f"ksk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:hidden offset:{ALGOROLL_OFFSETS['step3']}", + f"zsk 0 {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{ALGOROLL_OFFSETS['step3']}", + ], + "manual-mode": True, + "nextev": None, + } + keys = isctest.kasp.check_rollover_step(ns6, 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" + ns6.log.expect(msg) + + # Force step. + with ns6.watch_log_from_here() as watcher: + ns6.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 KSK {zone}/RSASHA256/{tag} type DS state OMNIPRESENT to state UNRETENTIVE" + if msg in ns6.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" + ) + with ns6.watch_log_from_here() as watcher: + ns6.rndc(f"dnssec -step {zone}") + watcher.wait_for_line(f"keymgr: {zone} done") + step = { "zone": zone, "cdss": CDSS, @@ -120,14 +215,51 @@ def test_algoroll_ksk_zsk_reconfig_step3(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(ns6, CONFIG, policy, step) -def test_algoroll_ksk_zsk_reconfig_step4(ns6, alg, size): - zone = "step4.algorithm-roll.kasp" +@pytest.mark.parametrize( + "tld", + [ + param("kasp"), + param("manual"), + ], +) +def test_algoroll_ksk_zsk_reconfig_step4(tld, ns6, alg, size): + zone = f"step4.algorithm-roll.{tld}" + policy = f"{POLICY}-{tld}" isctest.kasp.wait_keymgr_done(ns6, zone, reconfig=True) + if tld == "manual": + # Same as step 3, but the DS has become HIDDEN/OMNIPRESENT. + step = { + "zone": zone, + "cdss": CDSS, + "keyprops": [ + f"ksk 0 8 2048 goal:hidden dnskey:omnipresent krrsig:omnipresent ds:hidden offset:{ALGOROLL_OFFVAL}", + f"zsk 0 8 2048 goal:hidden dnskey:omnipresent zrrsig:omnipresent offset:{ALGOROLL_OFFVAL}", + f"ksk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{ALGOROLL_OFFSETS['step4']}", + f"zsk 0 {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{ALGOROLL_OFFSETS['step4']}", + ], + "manual-mode": True, + "nextev": None, + } + keys = isctest.kasp.check_rollover_step(ns6, 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" + ns6.log.expect(msg1) + ns6.log.expect(msg2) + + # Force step. + with ns6.watch_log_from_here() as watcher: + ns6.rndc(f"dnssec -step {zone}") + watcher.wait_for_line(f"keymgr: {zone} done") + step = { "zone": zone, "cdss": CDSS, @@ -142,14 +274,24 @@ def test_algoroll_ksk_zsk_reconfig_step4(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(ns6, CONFIG, policy, step) -def test_algoroll_ksk_zsk_reconfig_step5(ns6, alg, size): - zone = "step5.algorithm-roll.kasp" +@pytest.mark.parametrize( + "tld", + [ + param("kasp"), + param("manual"), + ], +) +def test_algoroll_ksk_zsk_reconfig_step5(tld, ns6, alg, size): + zone = f"step5.algorithm-roll.{tld}" + policy = f"{POLICY}-{tld}" isctest.kasp.wait_keymgr_done(ns6, zone, reconfig=True) + # manual-mode: Nothing changing in the zone, no 'dnssec -step' required. + step = { "zone": zone, "cdss": CDSS, @@ -168,14 +310,24 @@ def test_algoroll_ksk_zsk_reconfig_step5(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(ns6, CONFIG, policy, step) -def test_algoroll_ksk_zsk_reconfig_step6(ns6, alg, size): - zone = "step6.algorithm-roll.kasp" +@pytest.mark.parametrize( + "tld", + [ + param("kasp"), + param("manual"), + ], +) +def test_algoroll_ksk_zsk_reconfig_step6(tld, ns6, alg, size): + zone = f"step6.algorithm-roll.{tld}" + policy = f"{POLICY}-{tld}" isctest.kasp.wait_keymgr_done(ns6, zone, reconfig=True) + # manual-mode: Nothing changing in the zone, no 'dnssec -step' required. + step = { "zone": zone, "cdss": CDSS, @@ -191,4 +343,4 @@ def test_algoroll_ksk_zsk_reconfig_step6(ns6, alg, size): # loadkeys interval. "nextev": TIMEDELTA["PT1H"], } - isctest.kasp.check_rollover_step(ns6, CONFIG, POLICY, step) + isctest.kasp.check_rollover_step(ns6, CONFIG, policy, step)