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,
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,
# 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).
# 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
# 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,
# 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,
# 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,
# 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,
# 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,
],
"nextev": None,
}
- isctest.kasp.check_rollover_step(ns3, CONFIG, POLICY, step)
+ isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step)