mirror of
https://github.com/isc-projects/bind9.git
synced 2026-05-22 01:56:00 -04:00
Make properties direct attribute of KeyProperties
There is no real reason to keep those in a dictionary.
This commit is contained in:
parent
ade333bb64
commit
2d7ab28ce2
4 changed files with 90 additions and 67 deletions
|
|
@ -171,15 +171,30 @@ class KeyProperties:
|
|||
def __init__(
|
||||
self,
|
||||
name: str,
|
||||
properties: dict,
|
||||
metadata: dict,
|
||||
timing: Dict[str, KeyTimingMetadata],
|
||||
private: bool = True,
|
||||
legacy: bool = False,
|
||||
role: str = "csk",
|
||||
ttl: int = 3600,
|
||||
flags: int = 257,
|
||||
keytag_min: int = 0,
|
||||
keytag_max: int = 65535,
|
||||
offset: Union[timedelta, int] = 0,
|
||||
):
|
||||
self.name = name
|
||||
self.key = None
|
||||
self.properties = properties
|
||||
self.metadata = metadata
|
||||
self.timing = timing
|
||||
# Properties
|
||||
self.private = private
|
||||
self.legacy = legacy
|
||||
self.role = role
|
||||
self.ttl = ttl
|
||||
self.flags = flags
|
||||
self.keytag_min = keytag_min
|
||||
self.keytag_max = keytag_max
|
||||
self.offset = offset
|
||||
|
||||
def __repr__(self):
|
||||
return self.name
|
||||
|
|
@ -189,14 +204,6 @@ class KeyProperties:
|
|||
|
||||
@staticmethod
|
||||
def default(with_state=True) -> "KeyProperties":
|
||||
properties = {
|
||||
"private": True,
|
||||
"legacy": False,
|
||||
"role": "csk",
|
||||
"role_full": "key-signing",
|
||||
"dnskey_ttl": 3600,
|
||||
"flags": 257,
|
||||
}
|
||||
metadata = {
|
||||
"Algorithm": isctest.vars.algorithms.ECDSAP256SHA256.number,
|
||||
"Length": 256,
|
||||
|
|
@ -206,9 +213,7 @@ class KeyProperties:
|
|||
}
|
||||
timing: Dict[str, KeyTimingMetadata] = {}
|
||||
|
||||
result = KeyProperties(
|
||||
name="DEFAULT", properties=properties, metadata=metadata, timing=timing
|
||||
)
|
||||
result = KeyProperties(name="DEFAULT", metadata=metadata, timing=timing)
|
||||
result.name = "DEFAULT"
|
||||
result.key = None
|
||||
if with_state:
|
||||
|
|
@ -220,6 +225,11 @@ class KeyProperties:
|
|||
|
||||
return result
|
||||
|
||||
def role_full(self) -> str:
|
||||
if self.flags == 256:
|
||||
return "zone-signing"
|
||||
return "key-signing"
|
||||
|
||||
def Ipub(self, config):
|
||||
ipub = timedelta(0)
|
||||
|
||||
|
|
@ -257,11 +267,11 @@ class KeyProperties:
|
|||
if self.key is None:
|
||||
raise ValueError("KeyProperties must be attached to a Key")
|
||||
|
||||
if self.properties["legacy"]:
|
||||
if self.legacy:
|
||||
return
|
||||
|
||||
if offset is None:
|
||||
offset = self.properties["offset"]
|
||||
offset = self.offset
|
||||
|
||||
self.timing["Generated"] = self.key.get_timing("Created")
|
||||
self.timing["Published"] = self.key.get_timing("Created")
|
||||
|
|
@ -555,14 +565,14 @@ class Key:
|
|||
# Noop. If file is missing then the get_metadata calls will fail.
|
||||
|
||||
# Check the public key file.
|
||||
role = properties.properties["role_full"]
|
||||
role = properties.role_full()
|
||||
comment = f"This is a {role} key, keyid {self.tag}, for {zone}."
|
||||
if not isctest.util.file_contents_contain(self.keyfile, comment):
|
||||
isctest.log.debug(f"{self.name} COMMENT MISMATCH: expected '{comment}'")
|
||||
return False
|
||||
|
||||
ttl = properties.properties["dnskey_ttl"]
|
||||
flags = properties.properties["flags"]
|
||||
ttl = properties.ttl
|
||||
flags = properties.flags
|
||||
alg = properties.metadata["Algorithm"]
|
||||
dnskey = f"{zone}. {ttl} IN DNSKEY {flags} 3 {alg}"
|
||||
if not isctest.util.file_contents_contain(self.keyfile, dnskey):
|
||||
|
|
@ -570,7 +580,7 @@ class Key:
|
|||
return False
|
||||
|
||||
# Now check the private key file.
|
||||
if properties.properties["private"]:
|
||||
if properties.private:
|
||||
# Retrieve creation date.
|
||||
created = self.get_metadata("Generated")
|
||||
|
||||
|
|
@ -594,7 +604,7 @@ class Key:
|
|||
return False
|
||||
|
||||
# Now check the key state file.
|
||||
if properties.properties["legacy"]:
|
||||
if properties.legacy:
|
||||
return True
|
||||
|
||||
comment = f"This is the state of key {self.tag}, for {zone}."
|
||||
|
|
@ -619,12 +629,10 @@ class Key:
|
|||
return False
|
||||
|
||||
# Check tag range.
|
||||
if "keytag-min" in properties.properties:
|
||||
if self.tag < properties.properties["keytag-min"]:
|
||||
return False
|
||||
if "keytag-max" in properties.properties:
|
||||
if self.tag > properties.properties["keytag-max"]:
|
||||
return False
|
||||
if self.tag < properties.keytag_min:
|
||||
return False
|
||||
if self.tag > properties.keytag_max:
|
||||
return False
|
||||
|
||||
# A match is found.
|
||||
return True
|
||||
|
|
@ -692,7 +700,7 @@ def check_keys(zone, keys, expected):
|
|||
if expected[i].key is None:
|
||||
found = key.match_properties(zone, expected[i])
|
||||
if found:
|
||||
key.external = expected[i].properties["legacy"]
|
||||
key.external = expected[i].legacy
|
||||
expected[i].key = key
|
||||
i += 1
|
||||
if not found:
|
||||
|
|
@ -714,7 +722,7 @@ def check_keytimes(keys, expected):
|
|||
|
||||
for key in keys:
|
||||
for expect in expected:
|
||||
if expect.properties["legacy"]:
|
||||
if expect.legacy:
|
||||
continue
|
||||
|
||||
if not key is expect.key:
|
||||
|
|
@ -739,9 +747,9 @@ def check_keytimes(keys, expected):
|
|||
synonyms["Delete"] = expect.timing["Removed"]
|
||||
|
||||
assert key.match_timingmetadata(synonyms, file=key.keyfile, comment=True)
|
||||
if expect.properties["private"]:
|
||||
if expect.private:
|
||||
assert key.match_timingmetadata(synonyms, file=key.privatefile)
|
||||
if not expect.properties["legacy"]:
|
||||
if not expect.legacy:
|
||||
assert key.match_timingmetadata(expect.timing)
|
||||
|
||||
state_changes = [
|
||||
|
|
@ -762,7 +770,7 @@ def check_keyrelationships(keys, expected):
|
|||
"""
|
||||
for key in keys:
|
||||
for expect in expected:
|
||||
if expect.properties["legacy"]:
|
||||
if expect.legacy:
|
||||
continue
|
||||
|
||||
if not key is expect.key:
|
||||
|
|
@ -1518,59 +1526,75 @@ def policy_to_properties(ttl, keys: List[str]) -> List[KeyProperties]:
|
|||
for key in keys:
|
||||
count += 1
|
||||
line = key.split()
|
||||
keyprop = KeyProperties(f"KEY{count}", {}, {}, {})
|
||||
keyprop.properties["private"] = True
|
||||
keyprop.properties["legacy"] = False
|
||||
keyprop.properties["offset"] = timedelta(0)
|
||||
keyprop.properties["role"] = line[0]
|
||||
if line[0] == "zsk":
|
||||
keyprop.properties["role_full"] = "zone-signing"
|
||||
keyprop.properties["flags"] = 256
|
||||
keyprop.metadata["ZSK"] = "yes"
|
||||
keyprop.metadata["KSK"] = "no"
|
||||
else:
|
||||
keyprop.properties["role_full"] = "key-signing"
|
||||
keyprop.properties["flags"] = 257
|
||||
keyprop.metadata["ZSK"] = "yes" if line[0] == "csk" else "no"
|
||||
keyprop.metadata["KSK"] = "yes"
|
||||
|
||||
keyprop.properties["dnskey_ttl"] = ttl
|
||||
keyprop.metadata["Algorithm"] = line[2]
|
||||
keyprop.metadata["Length"] = line[3]
|
||||
# defaults
|
||||
metadata: Dict[str, Union[str, int]] = {}
|
||||
timing: Dict[str, KeyTimingMetadata] = {}
|
||||
private = True
|
||||
legacy = False
|
||||
keytag_min = 0
|
||||
keytag_max = 65535
|
||||
offset = timedelta(0)
|
||||
|
||||
role = line[0]
|
||||
if role == "zsk":
|
||||
flags = 256
|
||||
metadata["ZSK"] = "yes"
|
||||
metadata["KSK"] = "no"
|
||||
else:
|
||||
flags = 257
|
||||
metadata["ZSK"] = "yes" if role == "csk" else "no"
|
||||
metadata["KSK"] = "yes"
|
||||
|
||||
metadata["Algorithm"] = line[2]
|
||||
metadata["Length"] = line[3]
|
||||
if line[1] == "unlimited":
|
||||
keyprop.metadata["Lifetime"] = 0
|
||||
metadata["Lifetime"] = 0
|
||||
elif line[1] != "-":
|
||||
keyprop.metadata["Lifetime"] = int(line[1])
|
||||
metadata["Lifetime"] = int(line[1])
|
||||
|
||||
for i in range(4, len(line)):
|
||||
if line[i].startswith("goal:"):
|
||||
keyval = line[i].split(":")
|
||||
keyprop.metadata["GoalState"] = keyval[1]
|
||||
metadata["GoalState"] = keyval[1]
|
||||
elif line[i].startswith("dnskey:"):
|
||||
keyval = line[i].split(":")
|
||||
keyprop.metadata["DNSKEYState"] = keyval[1]
|
||||
metadata["DNSKEYState"] = keyval[1]
|
||||
elif line[i].startswith("krrsig:"):
|
||||
keyval = line[i].split(":")
|
||||
keyprop.metadata["KRRSIGState"] = keyval[1]
|
||||
metadata["KRRSIGState"] = keyval[1]
|
||||
elif line[i].startswith("zrrsig:"):
|
||||
keyval = line[i].split(":")
|
||||
keyprop.metadata["ZRRSIGState"] = keyval[1]
|
||||
metadata["ZRRSIGState"] = keyval[1]
|
||||
elif line[i].startswith("ds:"):
|
||||
keyval = line[i].split(":")
|
||||
keyprop.metadata["DSState"] = keyval[1]
|
||||
metadata["DSState"] = keyval[1]
|
||||
elif line[i].startswith("offset:"):
|
||||
keyval = line[i].split(":")
|
||||
keyprop.properties["offset"] = timedelta(seconds=int(keyval[1]))
|
||||
offset = timedelta(seconds=int(keyval[1]))
|
||||
elif line[i].startswith("tag-range:"):
|
||||
keyval = line[i].split(":")
|
||||
tagrange = keyval[1].split("-")
|
||||
keyprop.properties["keytag-min"] = int(tagrange[0])
|
||||
keyprop.properties["keytag-max"] = int(tagrange[1])
|
||||
keytag_min = int(tagrange[0])
|
||||
keytag_max = int(tagrange[1])
|
||||
elif line[i] == "missing":
|
||||
keyprop.properties["private"] = False
|
||||
private = False
|
||||
else:
|
||||
assert False, f"undefined optional data {line[i]}"
|
||||
|
||||
keyprop = KeyProperties(
|
||||
name=f"KEY{count}",
|
||||
metadata=metadata,
|
||||
timing=timing,
|
||||
private=private,
|
||||
legacy=legacy,
|
||||
role=role,
|
||||
ttl=ttl,
|
||||
flags=flags,
|
||||
keytag_min=keytag_min,
|
||||
keytag_max=keytag_max,
|
||||
offset=offset,
|
||||
)
|
||||
proplist.append(keyprop)
|
||||
|
||||
return proplist
|
||||
|
|
|
|||
|
|
@ -912,7 +912,7 @@ def test_kasp_default(ns3):
|
|||
ns3.rndc(f"loadkeys {zone}", log=False)
|
||||
watcher.wait_for_line(f"zone {zone}/IN (signed): {expectmsg}")
|
||||
# Nothing has changed.
|
||||
expected[0].properties["private"] = False
|
||||
expected[0].private = False # noqa
|
||||
isctest.kasp.check_dnssec_verify(ns3, zone)
|
||||
isctest.kasp.check_keys(zone, keys, expected)
|
||||
isctest.kasp.check_keytimes(keys, expected)
|
||||
|
|
|
|||
|
|
@ -333,8 +333,7 @@ def test_migrate2kasp_case(servers, params):
|
|||
|
||||
# Special case: CSK without SEP bit set.
|
||||
if zone == "csk-nosep.kasp":
|
||||
expected[0].properties["role_full"] = "zone-signing"
|
||||
expected[0].properties["flags"] = 256
|
||||
expected[0].flags = 256
|
||||
|
||||
# Key files.
|
||||
keys = isctest.kasp.keydir_to_keylist(zone, params["config"]["key-directory"])
|
||||
|
|
|
|||
|
|
@ -74,8 +74,8 @@ def test_rollover_multisigner(ns3, alg, size):
|
|||
|
||||
newprops = [f"zsk unlimited {alg} {size} tag-range:0-32767"]
|
||||
expected2 = isctest.kasp.policy_to_properties(ttl, newprops)
|
||||
expected2[0].properties["private"] = False
|
||||
expected2[0].properties["legacy"] = True
|
||||
expected2[0].private = False # noqa
|
||||
expected2[0].legacy = True # noqa
|
||||
expected = expected + expected2
|
||||
|
||||
ownkeys = isctest.kasp.keydir_to_keylist(zone, ns3.identifier)
|
||||
|
|
@ -98,8 +98,8 @@ def test_rollover_multisigner(ns3, alg, size):
|
|||
newkeys = isctest.kasp.keystr_to_keylist(out)
|
||||
newprops = [f"zsk unlimited {alg} {size} tag-range:0-32767"]
|
||||
expected2 = isctest.kasp.policy_to_properties(ttl, newprops)
|
||||
expected2[0].properties["private"] = False
|
||||
expected2[0].properties["legacy"] = True
|
||||
expected2[0].private = False # noqa
|
||||
expected2[0].legacy = True # noqa
|
||||
expected = expected + expected2
|
||||
|
||||
dnskey = newkeys[0].dnskey().split()
|
||||
|
|
|
|||
Loading…
Reference in a new issue