mirror of
https://github.com/isc-projects/bind9.git
synced 2026-05-28 04:34:54 -04:00
chg: test: Add isctest.kasp.Key.SettimeOptions
Merge branch 'matthijs-pytest-settime' into 'main' See merge request isc-projects/bind9!11388
This commit is contained in:
commit
ab9899455b
6 changed files with 895 additions and 426 deletions
|
|
@ -21,6 +21,7 @@ from dns import dnssec, name, rdataclass, rdatatype, update
|
|||
import pytest
|
||||
|
||||
pytest.importorskip("dns", minversion="2.0.0")
|
||||
from isctest.kasp import SettimeOptions
|
||||
import isctest
|
||||
|
||||
|
||||
|
|
@ -60,10 +61,9 @@ def keygen(*args):
|
|||
|
||||
|
||||
# run dnssec-settime
|
||||
def settime(*args):
|
||||
settime_cmd = [os.environ.get("SETTIME")]
|
||||
settime_cmd.extend(args)
|
||||
return isctest.run.cmd(settime_cmd).out.strip()
|
||||
def setkeytimes(key_name: str, options: SettimeOptions, keydir=None):
|
||||
key = isctest.kasp.Key(key_name, keydir=keydir)
|
||||
key.settime(options)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
|
|
@ -482,7 +482,8 @@ def test_offline_ksk_signing(ns2):
|
|||
# set key state for KSK. the ZSK rollovers below assume that there is a
|
||||
# chain of trust established, so we tell named that the DS is in
|
||||
# omnipresent state.
|
||||
settime("-s", "-d", "OMNIPRESENT", "now", "-Kns2", KSK)
|
||||
timings = SettimeOptions(d="OMNIPRESENT now")
|
||||
setkeytimes(KSK, timings, keydir="ns2")
|
||||
|
||||
isctest.log.info("check state before KSK is made offline")
|
||||
isctest.log.info("make sure certain types are signed with KSK only")
|
||||
|
|
@ -509,8 +510,15 @@ def test_offline_ksk_signing(ns2):
|
|||
isctest.run.retry_with_timeout(check_zskcount, 5)
|
||||
|
||||
isctest.log.info("make the new ZSK active")
|
||||
settime("-sKns2", "-Inow", ZSK)
|
||||
settime("-sKns2", "-Anow", "-k", "OMNIPRESENT", "now", ZSK2)
|
||||
|
||||
timings = SettimeOptions(I="now")
|
||||
setkeytimes(ZSK, timings, keydir="ns2")
|
||||
timings = SettimeOptions(
|
||||
A="now",
|
||||
k="OMNIPRESENT now",
|
||||
)
|
||||
setkeytimes(ZSK2, timings, keydir="ns2")
|
||||
|
||||
loadkeys()
|
||||
|
||||
with ns2.watch_log_from_start() as watcher:
|
||||
|
|
@ -557,8 +565,19 @@ def test_offline_ksk_signing(ns2):
|
|||
ZSKID3 = getkeyid(ZSK3)
|
||||
|
||||
isctest.log.info("delete old ZSK, schedule ZSK2 inactive, pre-publish ZSK3")
|
||||
settime("-sKns2", "-k", "HIDDEN", "now", "-z", "HIDDEN", "now", "-Dnow", ZSK)
|
||||
settime("-sKns2", "-k", "OMNIPRESENT", "now", "-z", "OMNIPRESENT", "now", ZSK2)
|
||||
|
||||
timings = SettimeOptions(
|
||||
k="HIDDEN now",
|
||||
z="HIDDEN now",
|
||||
D="now",
|
||||
)
|
||||
setkeytimes(ZSK, timings, keydir="ns2")
|
||||
timings = SettimeOptions(
|
||||
k="OMNIPRESENT now",
|
||||
z="OMNIPRESENT now",
|
||||
)
|
||||
setkeytimes(ZSK2, timings, keydir="ns2")
|
||||
|
||||
loadkeys()
|
||||
ns2.rndc(f"dnssec -rollover -key {ZSKID2} {zone}")
|
||||
|
||||
|
|
@ -591,8 +610,15 @@ def test_offline_ksk_signing(ns2):
|
|||
ksk_recover()
|
||||
|
||||
isctest.log.info("make ZSK3 active")
|
||||
settime("-sKns2", "-Inow", ZSK2)
|
||||
settime("-sKns2", "-k", "OMNIPRESENT", "now", "-Anow", ZSK3)
|
||||
|
||||
timings = SettimeOptions(I="now")
|
||||
setkeytimes(ZSK2, timings, keydir="ns2")
|
||||
timings = SettimeOptions(
|
||||
k="OMNIPRESENT now",
|
||||
A="now",
|
||||
)
|
||||
setkeytimes(ZSK3, timings, keydir="ns2")
|
||||
|
||||
loadkeys()
|
||||
|
||||
with ns2.watch_log_from_start() as watcher:
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
# See the COPYRIGHT file distributed with this work for additional
|
||||
# information regarding copyright ownership.
|
||||
|
||||
from dataclasses import dataclass
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from functools import total_ordering
|
||||
import glob
|
||||
|
|
@ -33,6 +34,7 @@ import isctest.util
|
|||
from isctest.compat import DSDigest
|
||||
from isctest.instance import NamedInstance
|
||||
from isctest.template import TrustAnchor
|
||||
from isctest.run import EnvCmd
|
||||
from isctest.vars.algorithms import Algorithm, ALL_ALGORITHMS_BY_NUM
|
||||
|
||||
DEFAULT_TTL = 300
|
||||
|
|
@ -315,6 +317,63 @@ class KeyProperties:
|
|||
self.timing["ZRRSIGChange"] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class SettimeOptions:
|
||||
|
||||
P: Optional[str] = None
|
||||
"""-P date/[+-]offset/none: set/unset key publication date"""
|
||||
|
||||
P_ds: Optional[str] = None
|
||||
"""-P ds date/[+-]offset/none: set/unset DS publication date"""
|
||||
|
||||
P_sync: Optional[str] = None
|
||||
"""-P sync date/[+-]offset/none: set/unset CDS and CDNSKEY publication date"""
|
||||
|
||||
A: Optional[str] = None
|
||||
"""-A date/[+-]offset/none: set/unset key activation date"""
|
||||
|
||||
R: Optional[str] = None
|
||||
"""-R date/[+-]offset/none: set/unset key revocation date"""
|
||||
|
||||
I: Optional[str] = None
|
||||
"""-I date/[+-]offset/none: set/unset key inactivation date"""
|
||||
|
||||
D: Optional[str] = None
|
||||
"""-D date/[+-]offset/none: set/unset key deletion date"""
|
||||
|
||||
D_ds: Optional[str] = None
|
||||
"""-D ds date/[+-]offset/none: set/unset DS deletion date"""
|
||||
|
||||
D_sync: Optional[str] = None
|
||||
"""-D sync date/[+-]offset/none: set/unset CDS and CDNSKEY deletion date"""
|
||||
|
||||
g: Optional[str] = None
|
||||
"""-g state: set the goal state for this key"""
|
||||
|
||||
d: Optional[str] = None
|
||||
"""-d state date/[+-]offset: set the DS state"""
|
||||
|
||||
k: Optional[str] = None
|
||||
"""-k state date/[+-]offset: set the DNSKEY state"""
|
||||
|
||||
r: Optional[str] = None
|
||||
"""-r state date/[+-]offset: set the RRSIG (KSK) state"""
|
||||
|
||||
z: Optional[str] = None
|
||||
"""-z state date/[+-]offset: set the RRSIG (ZSK) state"""
|
||||
|
||||
def __str__(self):
|
||||
args = []
|
||||
for opt, value in self.__dict__.items():
|
||||
if value is None:
|
||||
continue
|
||||
if not isinstance(value, str):
|
||||
raise ValueError(f"{opt}: invalid option value, only string supported")
|
||||
opt_str = opt.replace("_", " ")
|
||||
args.append(f"-{opt_str} {value}")
|
||||
return " ".join(args)
|
||||
|
||||
|
||||
@total_ordering
|
||||
class Key:
|
||||
"""
|
||||
|
|
@ -700,6 +759,14 @@ class Key:
|
|||
|
||||
return True
|
||||
|
||||
def settime(self, options: SettimeOptions, with_state=True):
|
||||
if with_state:
|
||||
settime_cmd = EnvCmd("SETTIME", "-s")
|
||||
else:
|
||||
settime_cmd = EnvCmd("SETTIME")
|
||||
|
||||
settime_cmd(f"{options} {self.path}")
|
||||
|
||||
def __lt__(self, other: "Key"):
|
||||
return self.name < other.name
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ import isctest.mark
|
|||
from isctest.kasp import (
|
||||
KeyProperties,
|
||||
KeyTimingMetadata,
|
||||
SettimeOptions,
|
||||
)
|
||||
from isctest.util import param
|
||||
from isctest.vars.algorithms import ECDSAP256SHA256, ECDSAP384SHA384
|
||||
|
|
@ -1322,13 +1323,8 @@ def test_kasp_dnssec_keygen():
|
|||
|
||||
created = key.get_timing("Created")
|
||||
publish = key.get_timing("Publish") + timedelta(hours=1)
|
||||
settime = [
|
||||
os.environ.get("SETTIME"),
|
||||
"-P",
|
||||
str(publish),
|
||||
key.path,
|
||||
]
|
||||
isctest.run.cmd(settime)
|
||||
timings = SettimeOptions(P=f"{publish}")
|
||||
key.settime(timings, with_state=False)
|
||||
|
||||
isctest.check.file_contents_equal(f"{key.statefile}", f"{key.statefile}.backup")
|
||||
assert key.get_metadata("Publish", file=key.privatefile) == str(publish)
|
||||
|
|
@ -1358,28 +1354,16 @@ def test_kasp_dnssec_keygen():
|
|||
"DSChange": now,
|
||||
}
|
||||
|
||||
settime = [
|
||||
os.environ.get("SETTIME"),
|
||||
"-s",
|
||||
"-P",
|
||||
str(now),
|
||||
"-g",
|
||||
goal,
|
||||
"-k",
|
||||
dnskey,
|
||||
str(now),
|
||||
"-r",
|
||||
krrsig,
|
||||
str(now),
|
||||
"-z",
|
||||
zrrsig,
|
||||
str(now),
|
||||
"-d",
|
||||
ds,
|
||||
str(now),
|
||||
key.path,
|
||||
]
|
||||
isctest.run.cmd(settime)
|
||||
timings = SettimeOptions(
|
||||
P=f"{now}",
|
||||
g=f"{goal}",
|
||||
k=f"{dnskey} {now}",
|
||||
r=f"{krrsig} {now}",
|
||||
z=f"{zrrsig} {now}",
|
||||
d=f"{ds} {now}",
|
||||
)
|
||||
key.settime(timings)
|
||||
|
||||
isctest.kasp.check_keys("kasp", keys, expected)
|
||||
isctest.kasp.check_keytimes(keys, expected)
|
||||
|
||||
|
|
@ -1395,28 +1379,16 @@ def test_kasp_dnssec_keygen():
|
|||
"Active": created,
|
||||
}
|
||||
|
||||
settime = [
|
||||
os.environ.get("SETTIME"),
|
||||
"-s",
|
||||
"-P",
|
||||
"none",
|
||||
"-g",
|
||||
"none",
|
||||
"-k",
|
||||
"none",
|
||||
str(now),
|
||||
"-z",
|
||||
"none",
|
||||
str(now),
|
||||
"-r",
|
||||
"none",
|
||||
str(now),
|
||||
"-d",
|
||||
"none",
|
||||
str(now),
|
||||
key.path,
|
||||
]
|
||||
isctest.run.cmd(settime)
|
||||
timings = SettimeOptions(
|
||||
P="none",
|
||||
g="none",
|
||||
k=f"none {now}",
|
||||
r=f"none {now}",
|
||||
z=f"none {now}",
|
||||
d=f"none {now}",
|
||||
)
|
||||
key.settime(timings)
|
||||
|
||||
isctest.kasp.check_keys("kasp", keys, expected)
|
||||
isctest.kasp.check_keytimes(keys, expected)
|
||||
|
||||
|
|
@ -1443,28 +1415,16 @@ def test_kasp_dnssec_keygen():
|
|||
"DSChange": soon,
|
||||
}
|
||||
|
||||
settime = [
|
||||
os.environ.get("SETTIME"),
|
||||
"-s",
|
||||
"-A",
|
||||
str(soon),
|
||||
"-g",
|
||||
"HIDDEN",
|
||||
"-k",
|
||||
"UNRETENTIVE",
|
||||
str(soon),
|
||||
"-z",
|
||||
"UNRETENTIVE",
|
||||
str(soon),
|
||||
"-r",
|
||||
"OMNIPRESENT",
|
||||
str(soon),
|
||||
"-d",
|
||||
"OMNIPRESENT",
|
||||
str(soon),
|
||||
key.path,
|
||||
]
|
||||
isctest.run.cmd(settime)
|
||||
timings = SettimeOptions(
|
||||
A=f"{soon}",
|
||||
g="HIDDEN",
|
||||
k=f"UNRETENTIVE {soon}",
|
||||
z=f"UNRETENTIVE {soon}",
|
||||
r=f"OMNIPRESENT {soon}",
|
||||
d=f"OMNIPRESENT {soon}",
|
||||
)
|
||||
key.settime(timings)
|
||||
|
||||
isctest.kasp.check_keys("kasp", keys, expected)
|
||||
isctest.kasp.check_keytimes(keys, expected)
|
||||
|
||||
|
|
|
|||
|
|
@ -20,14 +20,14 @@ pytest.importorskip("dns", minversion="2.0.0")
|
|||
import dns.update
|
||||
|
||||
import isctest
|
||||
from isctest.kasp import Iret
|
||||
from isctest.kasp import Iret, SettimeOptions
|
||||
from isctest.run import EnvCmd
|
||||
from rollover.common import (
|
||||
pytestmark,
|
||||
alg,
|
||||
size,
|
||||
)
|
||||
from rollover.setup import fake_lifetime, render_and_sign_zone
|
||||
from rollover.setup import fake_lifetime, render_and_sign_zone, setkeytimes
|
||||
|
||||
|
||||
def bootstrap():
|
||||
|
|
@ -35,7 +35,6 @@ def bootstrap():
|
|||
|
||||
# Multi-signer zones.
|
||||
keygen = EnvCmd("KEYGEN", "-a ECDSA256 -L 3600")
|
||||
settime = EnvCmd("SETTIME", "-s")
|
||||
|
||||
# Model 2.
|
||||
zonename = "multisigner-model2.kasp"
|
||||
|
|
@ -77,14 +76,21 @@ def bootstrap():
|
|||
f"-M 0:32767 -f KSK {keytimes} {cdstimes} {zonename}", cwd="ns3"
|
||||
).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",
|
||||
|
||||
# Key state timing metadata.
|
||||
timings = SettimeOptions(
|
||||
g="OMNIPRESENT",
|
||||
k=f"OMNIPRESENT {TpubN}",
|
||||
r=f"OMNIPRESENT {TpubN}",
|
||||
d=f"OMNIPRESENT {TpubN}",
|
||||
)
|
||||
settime(
|
||||
f"-g OMNIPRESENT -k OMNIPRESENT {TpubN} -z OMNIPRESENT {TpubN} {zsk_name}",
|
||||
cwd="ns3",
|
||||
setkeytimes(ksk_name, timings)
|
||||
timings = SettimeOptions(
|
||||
g="OMNIPRESENT",
|
||||
k=f"OMNIPRESENT {TpubN}",
|
||||
z=f"OMNIPRESENT {TpubN}",
|
||||
)
|
||||
setkeytimes(zsk_name, timings)
|
||||
# Signing.
|
||||
fake_lifetime(ksk_name, 0)
|
||||
fake_lifetime(zsk_name, 0)
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -13,7 +13,13 @@ from datetime import timedelta
|
|||
import os
|
||||
|
||||
import isctest
|
||||
from isctest.kasp import KeyTimingMetadata, Ipub, Iret, private_type_record
|
||||
from isctest.kasp import (
|
||||
KeyTimingMetadata,
|
||||
Ipub,
|
||||
Iret,
|
||||
private_type_record,
|
||||
SettimeOptions,
|
||||
)
|
||||
from isctest.template import Nameserver, Zone
|
||||
from isctest.run import EnvCmd
|
||||
|
||||
|
|
@ -21,15 +27,15 @@ from rollover.common import default_algorithm
|
|||
from rollover.setup import (
|
||||
configure_root,
|
||||
configure_tld,
|
||||
setkeytimes,
|
||||
)
|
||||
|
||||
|
||||
def setup_zone(zone, ksk_time, ksk_settime, zsk_time, zsk_settime) -> Zone:
|
||||
def setup_zone(zone, ksk_time, ksk_timings, zsk_time, zsk_timings) -> Zone:
|
||||
templates = isctest.template.TemplateEngine(".")
|
||||
alg = default_algorithm()
|
||||
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"
|
||||
|
|
@ -44,8 +50,9 @@ def setup_zone(zone, ksk_time, ksk_settime, zsk_time, zsk_settime) -> Zone:
|
|||
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")
|
||||
# Key state timing metadata.
|
||||
setkeytimes(ksk_name, ksk_timings)
|
||||
setkeytimes(zsk_name, zsk_timings)
|
||||
# Signing.
|
||||
ksk = isctest.kasp.Key(ksk_name, keydir="ns3")
|
||||
zsk = isctest.kasp.Key(zsk_name, keydir="ns3")
|
||||
|
|
@ -70,15 +77,27 @@ def bootstrap():
|
|||
|
||||
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))
|
||||
ksk_timings = SettimeOptions(
|
||||
g="OMNIPRESENT",
|
||||
k=f"OMNIPRESENT {when}",
|
||||
r=f"OMNIPRESENT {when}",
|
||||
d=f"OMNIPRESENT {when}",
|
||||
)
|
||||
zsk_timings = SettimeOptions(
|
||||
g="OMNIPRESENT",
|
||||
k=f"OMNIPRESENT {when}",
|
||||
z=f"OMNIPRESENT {when}",
|
||||
)
|
||||
zones.append(setup_zone(zone, when, ksk_timings, when, zsk_timings))
|
||||
|
||||
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))
|
||||
zsk_timings = SettimeOptions(
|
||||
g="OMNIPRESENT",
|
||||
k=f"OMNIPRESENT {then}",
|
||||
z=f"RUMOURED {then}",
|
||||
)
|
||||
zones.append(setup_zone(zone, when, ksk_timings, then, zsk_timings))
|
||||
|
||||
# Chain of trust.
|
||||
data = {
|
||||
|
|
|
|||
Loading…
Reference in a new issue