import isctest
from isctest.kasp import KeyTimingMetadata
+from isctest.util import param
from rollover.common import (
pytestmark,
alg,
ALGOROLL_KEYTTLPROP,
ALGOROLL_OFFSETS,
ALGOROLL_OFFVAL,
+ DURATION,
TIMEDELTA,
)
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,
# 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,
# 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,
# 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,
# 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,
# 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,
# loadkeys interval.
"nextev": TIMEDELTA["PT1H"],
}
- isctest.kasp.check_rollover_step(ns6, CONFIG, POLICY, step)
+ isctest.kasp.check_rollover_step(ns6, CONFIG, policy, step)