mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-30 14:07:59 +00:00
[9.20] chg: test: Rewrite kasp system test to pytest (3)
Write python-based tests for the many test cases from the kasp system test with the same pattern. Backport of MR !10268 Merge branch 'backport-matthijs-pytest-rewrite-kasp-system-test-3-9.20' into 'bind-9.20' See merge request isc-projects/bind9!10421
This commit is contained in:
@@ -16,7 +16,7 @@ from pathlib import Path
|
|||||||
import re
|
import re
|
||||||
import subprocess
|
import subprocess
|
||||||
import time
|
import time
|
||||||
from typing import Dict, List, Optional, Union
|
from typing import Dict, List, Optional, Tuple, Union
|
||||||
|
|
||||||
from datetime import datetime, timedelta, timezone
|
from datetime import datetime, timedelta, timezone
|
||||||
|
|
||||||
@@ -332,6 +332,55 @@ class Key:
|
|||||||
)
|
)
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
def get_signing_state(
|
||||||
|
self, offline_ksk=False, zsk_missing=False
|
||||||
|
) -> Tuple[bool, bool]:
|
||||||
|
"""
|
||||||
|
This returns the signing state derived from the key states, KRRSIGState
|
||||||
|
and ZRRSIGState.
|
||||||
|
|
||||||
|
If 'offline_ksk' is set to True, we determine the signing state from
|
||||||
|
the timing metadata. If 'zsigning' is True, ensure the current time is
|
||||||
|
between the Active and Retired timing metadata.
|
||||||
|
|
||||||
|
If 'zsk_missing' is set to True, it means the ZSK private key file is
|
||||||
|
missing, and the KSK should take over signing the RRset, and the
|
||||||
|
expected zone signing state (zsigning) is reversed.
|
||||||
|
"""
|
||||||
|
# Fetch key timing metadata.
|
||||||
|
now = KeyTimingMetadata.now()
|
||||||
|
activate = self.get_timing("Activate")
|
||||||
|
assert activate is not None # to silence mypy - its implied by line above
|
||||||
|
inactive = self.get_timing("Inactive", must_exist=False)
|
||||||
|
|
||||||
|
active = now >= activate
|
||||||
|
retired = inactive is not None and inactive <= now
|
||||||
|
signing = active and not retired
|
||||||
|
|
||||||
|
# Fetch key state metadata.
|
||||||
|
krrsigstate = self.get_metadata("KRRSIGState", must_exist=False)
|
||||||
|
ksigning = krrsigstate in ["rumoured", "omnipresent"]
|
||||||
|
zrrsigstate = self.get_metadata("ZRRSIGState", must_exist=False)
|
||||||
|
zsigning = zrrsigstate in ["rumoured", "omnipresent"]
|
||||||
|
|
||||||
|
if ksigning:
|
||||||
|
assert self.is_ksk()
|
||||||
|
if zsigning:
|
||||||
|
assert self.is_zsk()
|
||||||
|
|
||||||
|
# If the ZSK private key file is missing, revers the zone signing state.
|
||||||
|
if zsk_missing:
|
||||||
|
zsigning = not zsigning
|
||||||
|
|
||||||
|
# If testing offline KSK, retrieve the signing state from the key timing
|
||||||
|
# metadata.
|
||||||
|
if offline_ksk and signing and self.is_zsk():
|
||||||
|
assert zsigning
|
||||||
|
if offline_ksk and signing and self.is_ksk():
|
||||||
|
ksigning = signing
|
||||||
|
|
||||||
|
return ksigning, zsigning
|
||||||
|
|
||||||
def ttl(self) -> int:
|
def ttl(self) -> int:
|
||||||
with open(self.keyfile, "r", encoding="utf-8") as file:
|
with open(self.keyfile, "r", encoding="utf-8") as file:
|
||||||
for line in file:
|
for line in file:
|
||||||
@@ -772,8 +821,9 @@ def check_dnssecstatus(server, zone, keys, policy=None, view=None):
|
|||||||
assert f"key: {key.tag}" in response
|
assert f"key: {key.tag}" in response
|
||||||
|
|
||||||
|
|
||||||
def _check_signatures(signatures, covers, fqdn, keys):
|
def _check_signatures(
|
||||||
now = KeyTimingMetadata.now()
|
signatures, covers, fqdn, keys, offline_ksk=False, zsk_missing=False
|
||||||
|
):
|
||||||
numsigs = 0
|
numsigs = 0
|
||||||
zrrsig = True
|
zrrsig = True
|
||||||
if covers in [dns.rdatatype.DNSKEY, dns.rdatatype.CDNSKEY, dns.rdatatype.CDS]:
|
if covers in [dns.rdatatype.DNSKEY, dns.rdatatype.CDNSKEY, dns.rdatatype.CDS]:
|
||||||
@@ -781,23 +831,16 @@ def _check_signatures(signatures, covers, fqdn, keys):
|
|||||||
krrsig = not zrrsig
|
krrsig = not zrrsig
|
||||||
|
|
||||||
for key in keys:
|
for key in keys:
|
||||||
activate = key.get_timing("Activate")
|
ksigning, zsigning = key.get_signing_state(
|
||||||
inactive = key.get_timing("Inactive", must_exist=False)
|
offline_ksk=offline_ksk, zsk_missing=zsk_missing
|
||||||
|
)
|
||||||
|
|
||||||
active = now >= activate
|
|
||||||
retired = inactive is not None and inactive <= now
|
|
||||||
signing = active and not retired
|
|
||||||
alg = key.get_metadata("Algorithm")
|
alg = key.get_metadata("Algorithm")
|
||||||
rtype = dns.rdatatype.to_text(covers)
|
rtype = dns.rdatatype.to_text(covers)
|
||||||
|
|
||||||
expect = rf"IN RRSIG {rtype} {alg} (\d) (\d+) (\d+) (\d+) {key.tag} {fqdn}"
|
expect = rf"IN RRSIG {rtype} {alg} (\d) (\d+) (\d+) (\d+) {key.tag} {fqdn}"
|
||||||
|
|
||||||
if not signing:
|
if zrrsig and zsigning:
|
||||||
for rrsig in signatures:
|
|
||||||
assert re.search(expect, rrsig) is None
|
|
||||||
continue
|
|
||||||
|
|
||||||
if zrrsig and key.is_zsk():
|
|
||||||
has_rrsig = False
|
has_rrsig = False
|
||||||
for rrsig in signatures:
|
for rrsig in signatures:
|
||||||
if re.search(expect, rrsig) is not None:
|
if re.search(expect, rrsig) is not None:
|
||||||
@@ -806,11 +849,11 @@ def _check_signatures(signatures, covers, fqdn, keys):
|
|||||||
assert has_rrsig, f"Expected signature but not found: {expect}"
|
assert has_rrsig, f"Expected signature but not found: {expect}"
|
||||||
numsigs += 1
|
numsigs += 1
|
||||||
|
|
||||||
if zrrsig and not key.is_zsk():
|
if zrrsig and not zsigning:
|
||||||
for rrsig in signatures:
|
for rrsig in signatures:
|
||||||
assert re.search(expect, rrsig) is None
|
assert re.search(expect, rrsig) is None
|
||||||
|
|
||||||
if krrsig and key.is_ksk():
|
if krrsig and ksigning:
|
||||||
has_rrsig = False
|
has_rrsig = False
|
||||||
for rrsig in signatures:
|
for rrsig in signatures:
|
||||||
if re.search(expect, rrsig) is not None:
|
if re.search(expect, rrsig) is not None:
|
||||||
@@ -819,14 +862,16 @@ def _check_signatures(signatures, covers, fqdn, keys):
|
|||||||
assert has_rrsig, f"Expected signature but not found: {expect}"
|
assert has_rrsig, f"Expected signature but not found: {expect}"
|
||||||
numsigs += 1
|
numsigs += 1
|
||||||
|
|
||||||
if krrsig and not key.is_ksk():
|
if krrsig and not ksigning:
|
||||||
for rrsig in signatures:
|
for rrsig in signatures:
|
||||||
assert re.search(expect, rrsig) is None
|
assert re.search(expect, rrsig) is None
|
||||||
|
|
||||||
return numsigs
|
return numsigs
|
||||||
|
|
||||||
|
|
||||||
def check_signatures(rrset, covers, fqdn, ksks, zsks):
|
def check_signatures(
|
||||||
|
rrset, covers, fqdn, ksks, zsks, offline_ksk=False, zsk_missing=False
|
||||||
|
):
|
||||||
# Check if signatures with covering type are signed with the right keys.
|
# Check if signatures with covering type are signed with the right keys.
|
||||||
# The right keys are the ones that expect a signature and have the
|
# The right keys are the ones that expect a signature and have the
|
||||||
# correct role.
|
# correct role.
|
||||||
@@ -840,8 +885,12 @@ def check_signatures(rrset, covers, fqdn, ksks, zsks):
|
|||||||
rrsig = f"{rr.name} {rr.ttl} {rdclass} {rdtype} {rdata}"
|
rrsig = f"{rr.name} {rr.ttl} {rdclass} {rdtype} {rdata}"
|
||||||
signatures.append(rrsig)
|
signatures.append(rrsig)
|
||||||
|
|
||||||
numsigs += _check_signatures(signatures, covers, fqdn, ksks)
|
numsigs += _check_signatures(
|
||||||
numsigs += _check_signatures(signatures, covers, fqdn, zsks)
|
signatures, covers, fqdn, ksks, offline_ksk=offline_ksk, zsk_missing=zsk_missing
|
||||||
|
)
|
||||||
|
numsigs += _check_signatures(
|
||||||
|
signatures, covers, fqdn, zsks, offline_ksk=offline_ksk, zsk_missing=zsk_missing
|
||||||
|
)
|
||||||
|
|
||||||
assert numsigs == len(signatures)
|
assert numsigs == len(signatures)
|
||||||
|
|
||||||
@@ -965,7 +1014,9 @@ def _query_rrset(server, fqdn, qtype, tsig=None):
|
|||||||
return rrs, rrsigs
|
return rrs, rrsigs
|
||||||
|
|
||||||
|
|
||||||
def check_apex(server, zone, ksks, zsks, tsig=None):
|
def check_apex(
|
||||||
|
server, zone, ksks, zsks, offline_ksk=False, zsk_missing=False, tsig=None
|
||||||
|
):
|
||||||
# Test the apex of a zone. This checks that the SOA and DNSKEY RRsets
|
# Test the apex of a zone. This checks that the SOA and DNSKEY RRsets
|
||||||
# are signed correctly and with the appropriate keys.
|
# are signed correctly and with the appropriate keys.
|
||||||
fqdn = f"{zone}."
|
fqdn = f"{zone}."
|
||||||
@@ -973,30 +1024,44 @@ def check_apex(server, zone, ksks, zsks, tsig=None):
|
|||||||
# test dnskey query
|
# test dnskey query
|
||||||
dnskeys, rrsigs = _query_rrset(server, fqdn, dns.rdatatype.DNSKEY, tsig=tsig)
|
dnskeys, rrsigs = _query_rrset(server, fqdn, dns.rdatatype.DNSKEY, tsig=tsig)
|
||||||
check_dnskeys(dnskeys, ksks, zsks)
|
check_dnskeys(dnskeys, ksks, zsks)
|
||||||
check_signatures(rrsigs, dns.rdatatype.DNSKEY, fqdn, ksks, zsks)
|
check_signatures(
|
||||||
|
rrsigs, dns.rdatatype.DNSKEY, fqdn, ksks, zsks, offline_ksk=offline_ksk
|
||||||
|
)
|
||||||
|
|
||||||
# test soa query
|
# test soa query
|
||||||
soa, rrsigs = _query_rrset(server, fqdn, dns.rdatatype.SOA, tsig=tsig)
|
soa, rrsigs = _query_rrset(server, fqdn, dns.rdatatype.SOA, tsig=tsig)
|
||||||
assert len(soa) == 1
|
assert len(soa) == 1
|
||||||
assert f"{zone}. {DEFAULT_TTL} IN SOA" in soa[0].to_text()
|
assert f"{zone}. {DEFAULT_TTL} IN SOA" in soa[0].to_text()
|
||||||
check_signatures(rrsigs, dns.rdatatype.SOA, fqdn, ksks, zsks)
|
check_signatures(
|
||||||
|
rrsigs,
|
||||||
|
dns.rdatatype.SOA,
|
||||||
|
fqdn,
|
||||||
|
ksks,
|
||||||
|
zsks,
|
||||||
|
offline_ksk=offline_ksk,
|
||||||
|
zsk_missing=zsk_missing,
|
||||||
|
)
|
||||||
|
|
||||||
# test cdnskey query
|
# test cdnskey query
|
||||||
cdnskeys, rrsigs = _query_rrset(server, fqdn, dns.rdatatype.CDNSKEY, tsig=tsig)
|
cdnskeys, rrsigs = _query_rrset(server, fqdn, dns.rdatatype.CDNSKEY, tsig=tsig)
|
||||||
check_dnskeys(cdnskeys, ksks, zsks, cdnskey=True)
|
check_dnskeys(cdnskeys, ksks, zsks, cdnskey=True)
|
||||||
if len(cdnskeys) > 0:
|
if len(cdnskeys) > 0:
|
||||||
assert len(rrsigs) > 0
|
assert len(rrsigs) > 0
|
||||||
check_signatures(rrsigs, dns.rdatatype.CDNSKEY, fqdn, ksks, zsks)
|
check_signatures(
|
||||||
|
rrsigs, dns.rdatatype.CDNSKEY, fqdn, ksks, zsks, offline_ksk=offline_ksk
|
||||||
|
)
|
||||||
|
|
||||||
# test cds query
|
# test cds query
|
||||||
cds, rrsigs = _query_rrset(server, fqdn, dns.rdatatype.CDS, tsig=tsig)
|
cds, rrsigs = _query_rrset(server, fqdn, dns.rdatatype.CDS, tsig=tsig)
|
||||||
check_cds(cds, ksks)
|
check_cds(cds, ksks)
|
||||||
if len(cds) > 0:
|
if len(cds) > 0:
|
||||||
assert len(rrsigs) > 0
|
assert len(rrsigs) > 0
|
||||||
check_signatures(rrsigs, dns.rdatatype.CDS, fqdn, ksks, zsks)
|
check_signatures(
|
||||||
|
rrsigs, dns.rdatatype.CDS, fqdn, ksks, zsks, offline_ksk=offline_ksk
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def check_subdomain(server, zone, ksks, zsks, tsig=None):
|
def check_subdomain(server, zone, ksks, zsks, offline_ksk=False, tsig=None):
|
||||||
# Test an RRset below the apex and verify it is signed correctly.
|
# Test an RRset below the apex and verify it is signed correctly.
|
||||||
fqdn = f"{zone}."
|
fqdn = f"{zone}."
|
||||||
qname = f"a.{zone}."
|
qname = f"a.{zone}."
|
||||||
@@ -1014,7 +1079,7 @@ def check_subdomain(server, zone, ksks, zsks, tsig=None):
|
|||||||
else:
|
else:
|
||||||
assert match in rrset.to_text()
|
assert match in rrset.to_text()
|
||||||
|
|
||||||
check_signatures(rrsigs, qtype, fqdn, ksks, zsks)
|
check_signatures(rrsigs, qtype, fqdn, ksks, zsks, offline_ksk=offline_ksk)
|
||||||
|
|
||||||
|
|
||||||
def verify_update_is_signed(server, fqdn, qname, qtype, rdata, ksks, zsks, tsig=None):
|
def verify_update_is_signed(server, fqdn, qname, qtype, rdata, ksks, zsks, tsig=None):
|
||||||
@@ -1046,6 +1111,98 @@ def verify_update_is_signed(server, fqdn, qname, qtype, rdata, ksks, zsks, tsig=
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def verify_rrsig_is_refreshed(
|
||||||
|
server, fqdn, zonefile, qname, qtype, ksks, zsks, tsig=None
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Verify signature for RRset has been refreshed.
|
||||||
|
"""
|
||||||
|
response = _query(server, qname, qtype, tsig=tsig)
|
||||||
|
|
||||||
|
if response.rcode() != dns.rcode.NOERROR:
|
||||||
|
return False
|
||||||
|
|
||||||
|
rrtype = dns.rdatatype.to_text(qtype)
|
||||||
|
match = f"{qname}. {DEFAULT_TTL} IN {rrtype}"
|
||||||
|
rrsigs = []
|
||||||
|
for rrset in response.answer:
|
||||||
|
if rrset.match(
|
||||||
|
dns.name.from_text(qname), dns.rdataclass.IN, dns.rdatatype.RRSIG, qtype
|
||||||
|
):
|
||||||
|
rrsigs.append(rrset)
|
||||||
|
elif not match in rrset.to_text():
|
||||||
|
return False
|
||||||
|
|
||||||
|
if len(rrsigs) == 0:
|
||||||
|
return False
|
||||||
|
|
||||||
|
tmp_zonefile = f"{zonefile}.tmp"
|
||||||
|
isctest.run.cmd(
|
||||||
|
[
|
||||||
|
os.environ["CHECKZONE"],
|
||||||
|
"-D",
|
||||||
|
"-q",
|
||||||
|
"-o",
|
||||||
|
tmp_zonefile,
|
||||||
|
"-f",
|
||||||
|
"raw",
|
||||||
|
fqdn,
|
||||||
|
zonefile,
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
zone = dns.zone.from_file(tmp_zonefile, fqdn)
|
||||||
|
for rrsig in rrsigs:
|
||||||
|
if isctest.util.zone_contains(zone, rrsig):
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Zone is updated, ready to verify the signatures.
|
||||||
|
check_signatures(rrsigs, qtype, fqdn, ksks, zsks)
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def verify_rrsig_is_reused(server, fqdn, zonefile, qname, qtype, ksks, zsks, tsig=None):
|
||||||
|
"""
|
||||||
|
Verify signature for RRset has been reused.
|
||||||
|
"""
|
||||||
|
response = _query(server, qname, qtype, tsig=tsig)
|
||||||
|
|
||||||
|
assert response.rcode() == dns.rcode.NOERROR
|
||||||
|
|
||||||
|
rrtype = dns.rdatatype.to_text(qtype)
|
||||||
|
match = f"{qname}. {DEFAULT_TTL} IN {rrtype}"
|
||||||
|
rrsigs = []
|
||||||
|
for rrset in response.answer:
|
||||||
|
if rrset.match(
|
||||||
|
dns.name.from_text(qname), dns.rdataclass.IN, dns.rdatatype.RRSIG, qtype
|
||||||
|
):
|
||||||
|
rrsigs.append(rrset)
|
||||||
|
else:
|
||||||
|
assert match in rrset.to_text()
|
||||||
|
|
||||||
|
tmp_zonefile = f"{zonefile}.tmp"
|
||||||
|
isctest.run.cmd(
|
||||||
|
[
|
||||||
|
os.environ["CHECKZONE"],
|
||||||
|
"-D",
|
||||||
|
"-q",
|
||||||
|
"-o",
|
||||||
|
tmp_zonefile,
|
||||||
|
"-f",
|
||||||
|
"raw",
|
||||||
|
fqdn,
|
||||||
|
zonefile,
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
zone = dns.zone.from_file(tmp_zonefile, dns.name.from_text(fqdn), relativize=False)
|
||||||
|
for rrsig in rrsigs:
|
||||||
|
assert isctest.util.zone_contains(zone, rrsig)
|
||||||
|
|
||||||
|
check_signatures(rrsigs, qtype, fqdn, ksks, zsks)
|
||||||
|
|
||||||
|
|
||||||
def next_key_event_equals(server, zone, next_event):
|
def next_key_event_equals(server, zone, next_event):
|
||||||
if next_event is None:
|
if next_event is None:
|
||||||
# No next key event check.
|
# No next key event check.
|
||||||
@@ -1140,6 +1297,7 @@ def policy_to_properties(ttl, keys: List[str]) -> List[KeyProperties]:
|
|||||||
Then, optional data for specific tests may follow:
|
Then, optional data for specific tests may follow:
|
||||||
- "goal", "dnskey", "krrsig", "zrrsig", "ds", followed by a value,
|
- "goal", "dnskey", "krrsig", "zrrsig", "ds", followed by a value,
|
||||||
sets the given state to the specific value
|
sets the given state to the specific value
|
||||||
|
- "missing", set if the private key file for this key is not available.
|
||||||
- "offset", an offset for testing key rollover timings
|
- "offset", an offset for testing key rollover timings
|
||||||
"""
|
"""
|
||||||
proplist = []
|
proplist = []
|
||||||
@@ -1190,6 +1348,8 @@ def policy_to_properties(ttl, keys: List[str]) -> List[KeyProperties]:
|
|||||||
elif line[i].startswith("offset:"):
|
elif line[i].startswith("offset:"):
|
||||||
keyval = line[i].split(":")
|
keyval = line[i].split(":")
|
||||||
keyprop.properties["offset"] = timedelta(seconds=int(keyval[1]))
|
keyprop.properties["offset"] = timedelta(seconds=int(keyval[1]))
|
||||||
|
elif line[i] == "missing":
|
||||||
|
keyprop.properties["private"] = False
|
||||||
else:
|
else:
|
||||||
assert False, f"undefined optional data {line[i]}"
|
assert False, f"undefined optional data {line[i]}"
|
||||||
|
|
||||||
|
@@ -56,6 +56,12 @@ def with_tsan(*args): # pylint: disable=unused-argument
|
|||||||
return feature_test("--tsan")
|
return feature_test("--tsan")
|
||||||
|
|
||||||
|
|
||||||
|
def with_algorithm(name: str):
|
||||||
|
key = f"{name}_SUPPORTED"
|
||||||
|
assert key in os.environ, f"{key} env variable undefined"
|
||||||
|
return pytest.mark.skipif(os.getenv(key) != "1", reason=f"{name} is not supported")
|
||||||
|
|
||||||
|
|
||||||
without_fips = pytest.mark.skipif(
|
without_fips = pytest.mark.skipif(
|
||||||
feature_test("--have-fips-mode"), reason="FIPS support enabled in the build"
|
feature_test("--have-fips-mode"), reason="FIPS support enabled in the build"
|
||||||
)
|
)
|
||||||
|
@@ -200,13 +200,14 @@ $SETTIME -s -g $O -k $O $T -z $O $T "$ZSK" >settime.out.$zone.2 2>&1
|
|||||||
cat template.db.in "${KSK}.key" "${ZSK}.key" >"$infile"
|
cat template.db.in "${KSK}.key" "${ZSK}.key" >"$infile"
|
||||||
$SIGNER -PS -z -x -s now-2w -e now-1mi -o $zone -f "${zonefile}" $infile >signer.out.$zone.1 2>&1
|
$SIGNER -PS -z -x -s now-2w -e now-1mi -o $zone -f "${zonefile}" $infile >signer.out.$zone.1 2>&1
|
||||||
|
|
||||||
|
# Treat the next zones as if they were signed six months ago.
|
||||||
|
T="now-6mo"
|
||||||
|
keytimes="-P $T -A $T"
|
||||||
|
|
||||||
# These signatures are set to expire long in the past, update immediately.
|
# These signatures are set to expire long in the past, update immediately.
|
||||||
setup expired-sigs.autosign
|
setup expired-sigs.autosign
|
||||||
T="now-6mo"
|
KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 300 -f KSK $keytimes $zone 2>keygen.out.$zone.1)
|
||||||
ksktimes="-P $T -A $T -P sync $T"
|
ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 300 $keytimes $zone 2>keygen.out.$zone.2)
|
||||||
zsktimes="-P $T -A $T"
|
|
||||||
KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 300 -f KSK $ksktimes $zone 2>keygen.out.$zone.1)
|
|
||||||
ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 300 $zsktimes $zone 2>keygen.out.$zone.2)
|
|
||||||
$SETTIME -s -g $O -d $O $T -k $O $T -r $O $T "$KSK" >settime.out.$zone.1 2>&1
|
$SETTIME -s -g $O -d $O $T -k $O $T -r $O $T "$KSK" >settime.out.$zone.1 2>&1
|
||||||
$SETTIME -s -g $O -k $O $T -z $O $T "$ZSK" >settime.out.$zone.2 2>&1
|
$SETTIME -s -g $O -k $O $T -z $O $T "$ZSK" >settime.out.$zone.2 2>&1
|
||||||
cat template.db.in "${KSK}.key" "${ZSK}.key" >"$infile"
|
cat template.db.in "${KSK}.key" "${ZSK}.key" >"$infile"
|
||||||
@@ -217,19 +218,18 @@ $SIGNER -PS -x -s now-2mo -e now-1mo -o $zone -O raw -f "${zonefile}.signed" $in
|
|||||||
|
|
||||||
# The DNSKEY's TTLs do not match the policy.
|
# The DNSKEY's TTLs do not match the policy.
|
||||||
setup dnskey-ttl-mismatch.autosign
|
setup dnskey-ttl-mismatch.autosign
|
||||||
KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 30 -f KSK $ksktimes $zone 2>keygen.out.$zone.1)
|
KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 30 -f KSK $keytimes $zone 2>keygen.out.$zone.1)
|
||||||
ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 30 $zsktimes $zone 2>keygen.out.$zone.2)
|
ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 30 $keytimes $zone 2>keygen.out.$zone.2)
|
||||||
|
$SETTIME -s -g $O -d $O $T -k $O $T -r $O $T "$KSK" >settime.out.$zone.1 2>&1
|
||||||
|
$SETTIME -s -g $O -k $O $T -z $O $T "$ZSK " >settime.out.$zone.2 2>&1
|
||||||
cat template.db.in "${KSK}.key" "${ZSK}.key" >"$infile"
|
cat template.db.in "${KSK}.key" "${ZSK}.key" >"$infile"
|
||||||
cp $infile $zonefile
|
cp $infile $zonefile
|
||||||
$SIGNER -PS -x -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
|
$SIGNER -PS -x -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
|
||||||
|
|
||||||
# These signatures are still good, and can be reused.
|
# These signatures are still good, and can be reused.
|
||||||
setup fresh-sigs.autosign
|
setup fresh-sigs.autosign
|
||||||
T="now-6mo"
|
KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 300 -f KSK $keytimes $zone 2>keygen.out.$zone.1)
|
||||||
ksktimes="-P $T -A $T -P sync $T"
|
ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 300 $keytimes $zone 2>keygen.out.$zone.2)
|
||||||
zsktimes="-P $T -A $T"
|
|
||||||
KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 300 -f KSK $ksktimes $zone 2>keygen.out.$zone.1)
|
|
||||||
ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 300 $zsktimes $zone 2>keygen.out.$zone.2)
|
|
||||||
$SETTIME -s -g $O -d $O $T -k $O $T -r $O $T "$KSK" >settime.out.$zone.1 2>&1
|
$SETTIME -s -g $O -d $O $T -k $O $T -r $O $T "$KSK" >settime.out.$zone.1 2>&1
|
||||||
$SETTIME -s -g $O -k $O $T -z $O $T "$ZSK" >settime.out.$zone.2 2>&1
|
$SETTIME -s -g $O -k $O $T -z $O $T "$ZSK" >settime.out.$zone.2 2>&1
|
||||||
cat template.db.in "${KSK}.key" "${ZSK}.key" >"$infile"
|
cat template.db.in "${KSK}.key" "${ZSK}.key" >"$infile"
|
||||||
@@ -240,11 +240,8 @@ $SIGNER -S -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infil
|
|||||||
|
|
||||||
# These signatures are still good, but not fresh enough, update immediately.
|
# These signatures are still good, but not fresh enough, update immediately.
|
||||||
setup unfresh-sigs.autosign
|
setup unfresh-sigs.autosign
|
||||||
T="now-6mo"
|
KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 300 -f KSK $keytimes $zone 2>keygen.out.$zone.1)
|
||||||
ksktimes="-P $T -A $T -P sync $T"
|
ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 300 $keytimes $zone 2>keygen.out.$zone.2)
|
||||||
zsktimes="-P $T -A $T"
|
|
||||||
KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 300 -f KSK $ksktimes $zone 2>keygen.out.$zone.1)
|
|
||||||
ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 300 $zsktimes $zone 2>keygen.out.$zone.2)
|
|
||||||
$SETTIME -s -g $O -d $O $T -k $O $T -r $O $T "$KSK" >settime.out.$zone.1 2>&1
|
$SETTIME -s -g $O -d $O $T -k $O $T -r $O $T "$KSK" >settime.out.$zone.1 2>&1
|
||||||
$SETTIME -s -g $O -k $O $T -z $O $T "$ZSK" >settime.out.$zone.2 2>&1
|
$SETTIME -s -g $O -k $O $T -z $O $T "$ZSK" >settime.out.$zone.2 2>&1
|
||||||
cat template.db.in "${KSK}.key" "${ZSK}.key" >"$infile"
|
cat template.db.in "${KSK}.key" "${ZSK}.key" >"$infile"
|
||||||
@@ -255,11 +252,13 @@ $SIGNER -S -x -s now-1w -e now+1w -o $zone -O raw -f "${zonefile}.signed" $infil
|
|||||||
|
|
||||||
# These signatures are still good, but the private KSK is missing.
|
# These signatures are still good, but the private KSK is missing.
|
||||||
setup ksk-missing.autosign
|
setup ksk-missing.autosign
|
||||||
T="now-6mo"
|
# KSK file will be gone missing, so we set expected times during setup.
|
||||||
ksktimes="-P $T -A $T -P sync $T"
|
TI="now+550d" # Lifetime of 2 years minus 6 months equals 550 days
|
||||||
zsktimes="-P $T -A $T"
|
TD="now+13226h" # 550 days plus retire time of 1 day 2 hours equals 13226 hours
|
||||||
|
TS="now-257755mi" # 6 months minus 1 day, 5 minutes equals 257695 minutes
|
||||||
|
ksktimes="$keytimes -P sync $TS -I $TI -D $TD"
|
||||||
KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 300 -f KSK $ksktimes $zone 2>keygen.out.$zone.1)
|
KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 300 -f KSK $ksktimes $zone 2>keygen.out.$zone.1)
|
||||||
ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 300 $zsktimes $zone 2>keygen.out.$zone.2)
|
ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 300 $keytimes $zone 2>keygen.out.$zone.2)
|
||||||
$SETTIME -s -g $O -d $O $T -k $O $T -r $O $T "$KSK" >settime.out.$zone.1 2>&1
|
$SETTIME -s -g $O -d $O $T -k $O $T -r $O $T "$KSK" >settime.out.$zone.1 2>&1
|
||||||
$SETTIME -s -g $O -k $O $T -z $O $T "$ZSK" >settime.out.$zone.2 2>&1
|
$SETTIME -s -g $O -k $O $T -z $O $T "$ZSK" >settime.out.$zone.2 2>&1
|
||||||
cat template.db.in "${KSK}.key" "${ZSK}.key" >"$infile"
|
cat template.db.in "${KSK}.key" "${ZSK}.key" >"$infile"
|
||||||
@@ -274,10 +273,11 @@ rm -f "${KSK}".private
|
|||||||
|
|
||||||
# These signatures are still good, but the private ZSK is missing.
|
# These signatures are still good, but the private ZSK is missing.
|
||||||
setup zsk-missing.autosign
|
setup zsk-missing.autosign
|
||||||
T="now-6mo"
|
# ZSK file will be gone missing, so we set expected times during setup.
|
||||||
ksktimes="-P $T -A $T -P sync $T"
|
TI="now+185d" # Lifetime of 1 year minus 6 months equals 185 days
|
||||||
zsktimes="-P $T -A $T"
|
TD="now+277985mi" # 185 days plus retire time (sign delay, retire safety, propagation, zone TTL)
|
||||||
KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 300 -f KSK $ksktimes $zone 2>keygen.out.$zone.1)
|
zsktimes="$keytimes -I $TI -D $TD"
|
||||||
|
KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 300 -f KSK $keytimes $zone 2>keygen.out.$zone.1)
|
||||||
ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 300 $zsktimes $zone 2>keygen.out.$zone.2)
|
ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 300 $zsktimes $zone 2>keygen.out.$zone.2)
|
||||||
$SETTIME -s -g $O -d $O $T -k $O $T -r $O $T "$KSK" >settime.out.$zone.1 2>&1
|
$SETTIME -s -g $O -d $O $T -k $O $T -r $O $T "$KSK" >settime.out.$zone.1 2>&1
|
||||||
$SETTIME -s -g $O -k $O $T -z $O $T "$ZSK" >settime.out.$zone.2 2>&1
|
$SETTIME -s -g $O -k $O $T -z $O $T "$ZSK" >settime.out.$zone.2 2>&1
|
||||||
@@ -294,11 +294,8 @@ rm -f "${ZSK}".private
|
|||||||
# These signatures are still good, but the key files will be removed
|
# These signatures are still good, but the key files will be removed
|
||||||
# before a second run of reconfiguring keys.
|
# before a second run of reconfiguring keys.
|
||||||
setup keyfiles-missing.autosign
|
setup keyfiles-missing.autosign
|
||||||
T="now-6mo"
|
KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 300 -f KSK $keytimes $zone 2>keygen.out.$zone.1)
|
||||||
ksktimes="-P $T -A $T -P sync $T"
|
ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 300 $keytimes $zone 2>keygen.out.$zone.2)
|
||||||
zsktimes="-P $T -A $T"
|
|
||||||
KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 300 -f KSK $ksktimes $zone 2>keygen.out.$zone.1)
|
|
||||||
ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 300 $zsktimes $zone 2>keygen.out.$zone.2)
|
|
||||||
$SETTIME -s -g $O -d $O $T -k $O $T -r $O $T "$KSK" >settime.out.$zone.1 2>&1
|
$SETTIME -s -g $O -d $O $T -k $O $T -r $O $T "$KSK" >settime.out.$zone.1 2>&1
|
||||||
$SETTIME -s -g $O -k $O $T -z $O $T "$ZSK" >settime.out.$zone.2 2>&1
|
$SETTIME -s -g $O -k $O $T -z $O $T "$ZSK" >settime.out.$zone.2 2>&1
|
||||||
cat template.db.in "${KSK}.key" "${ZSK}.key" >"$infile"
|
cat template.db.in "${KSK}.key" "${ZSK}.key" >"$infile"
|
||||||
@@ -309,7 +306,6 @@ $SIGNER -S -x -s now-1w -e now+1w -o $zone -O raw -f "${zonefile}.signed" $infil
|
|||||||
|
|
||||||
# These signatures are already expired, and the private ZSK is retired.
|
# These signatures are already expired, and the private ZSK is retired.
|
||||||
setup zsk-retired.autosign
|
setup zsk-retired.autosign
|
||||||
T="now-6mo"
|
|
||||||
ksktimes="-P $T -A $T -P sync $T"
|
ksktimes="-P $T -A $T -P sync $T"
|
||||||
zsktimes="-P $T -A $T -I now"
|
zsktimes="-P $T -A $T -I now"
|
||||||
KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 300 -f KSK $ksktimes $zone 2>keygen.out.$zone.1)
|
KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 300 -f KSK $ksktimes $zone 2>keygen.out.$zone.1)
|
||||||
|
@@ -400,462 +400,10 @@ set_keytimes_algorithm_policy() {
|
|||||||
set_addkeytime "KEY3" "REMOVED" "${retired}" 867900
|
set_addkeytime "KEY3" "REMOVED" "${retired}" 867900
|
||||||
}
|
}
|
||||||
|
|
||||||
#
|
|
||||||
# Zone: rsasha1.kasp.
|
|
||||||
#
|
|
||||||
if [ $RSASHA1_SUPPORTED = 1 ]; then
|
|
||||||
set_zone "rsasha1.kasp"
|
|
||||||
set_policy "rsasha1" "3" "1234"
|
|
||||||
set_server "ns3" "10.53.0.3"
|
|
||||||
# Key properties.
|
|
||||||
key_clear "KEY1"
|
|
||||||
set_keyrole "KEY1" "ksk"
|
|
||||||
set_keylifetime "KEY1" "315360000"
|
|
||||||
set_keyalgorithm "KEY1" "5" "RSASHA1" "2048"
|
|
||||||
set_keysigning "KEY1" "yes"
|
|
||||||
set_zonesigning "KEY1" "no"
|
|
||||||
|
|
||||||
key_clear "KEY2"
|
|
||||||
set_keyrole "KEY2" "zsk"
|
|
||||||
set_keylifetime "KEY2" "157680000"
|
|
||||||
set_keyalgorithm "KEY2" "5" "RSASHA1" "2048"
|
|
||||||
set_keysigning "KEY2" "no"
|
|
||||||
set_zonesigning "KEY2" "yes"
|
|
||||||
|
|
||||||
key_clear "KEY3"
|
|
||||||
set_keyrole "KEY3" "zsk"
|
|
||||||
set_keylifetime "KEY3" "31536000"
|
|
||||||
set_keyalgorithm "KEY3" "5" "RSASHA1" "2000"
|
|
||||||
set_keysigning "KEY3" "no"
|
|
||||||
set_zonesigning "KEY3" "yes"
|
|
||||||
|
|
||||||
# KSK: DNSKEY, RRSIG (ksk) published. DS needs to wait.
|
|
||||||
# ZSK: DNSKEY, RRSIG (zsk) published.
|
|
||||||
set_keystate "KEY1" "GOAL" "omnipresent"
|
|
||||||
set_keystate "KEY1" "STATE_DNSKEY" "rumoured"
|
|
||||||
set_keystate "KEY1" "STATE_KRRSIG" "rumoured"
|
|
||||||
set_keystate "KEY1" "STATE_DS" "hidden"
|
|
||||||
|
|
||||||
set_keystate "KEY2" "GOAL" "omnipresent"
|
|
||||||
set_keystate "KEY2" "STATE_DNSKEY" "rumoured"
|
|
||||||
set_keystate "KEY2" "STATE_ZRRSIG" "rumoured"
|
|
||||||
|
|
||||||
set_keystate "KEY3" "GOAL" "omnipresent"
|
|
||||||
set_keystate "KEY3" "STATE_DNSKEY" "rumoured"
|
|
||||||
set_keystate "KEY3" "STATE_ZRRSIG" "rumoured"
|
|
||||||
# Three keys only.
|
|
||||||
key_clear "KEY4"
|
|
||||||
|
|
||||||
check_keys
|
|
||||||
check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
|
|
||||||
set_keytimes_algorithm_policy
|
|
||||||
check_keytimes
|
|
||||||
check_apex
|
|
||||||
check_subdomain
|
|
||||||
dnssec_verify
|
|
||||||
fi
|
|
||||||
|
|
||||||
#
|
|
||||||
# Zone: unlimited.kasp.
|
|
||||||
#
|
|
||||||
set_zone "unlimited.kasp"
|
|
||||||
set_policy "unlimited" "1" "1234"
|
|
||||||
set_server "ns3" "10.53.0.3"
|
|
||||||
key_clear "KEY1"
|
|
||||||
key_clear "KEY2"
|
|
||||||
key_clear "KEY3"
|
|
||||||
key_clear "KEY4"
|
|
||||||
# Key properties.
|
|
||||||
set_keyrole "KEY1" "csk"
|
|
||||||
set_keylifetime "KEY1" "0"
|
|
||||||
set_keyalgorithm "KEY1" "13" "ECDSAP256SHA256" "256"
|
|
||||||
set_keysigning "KEY1" "yes"
|
|
||||||
set_zonesigning "KEY1" "yes"
|
|
||||||
# DNSKEY, RRSIG (ksk), RRSIG (zsk) are published. DS needs to wait.
|
|
||||||
set_keystate "KEY1" "GOAL" "omnipresent"
|
|
||||||
set_keystate "KEY1" "STATE_DNSKEY" "rumoured"
|
|
||||||
set_keystate "KEY1" "STATE_KRRSIG" "rumoured"
|
|
||||||
set_keystate "KEY1" "STATE_ZRRSIG" "rumoured"
|
|
||||||
set_keystate "KEY1" "STATE_DS" "hidden"
|
|
||||||
|
|
||||||
check_keys
|
|
||||||
check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
|
|
||||||
set_keytimes_csk_policy
|
|
||||||
check_keytimes
|
|
||||||
check_apex
|
|
||||||
check_subdomain
|
|
||||||
dnssec_verify
|
|
||||||
|
|
||||||
#
|
|
||||||
# Zone: keystore.kasp.
|
|
||||||
#
|
|
||||||
set_zone "keystore.kasp"
|
|
||||||
set_policy "keystore" "2" "303"
|
|
||||||
set_server "ns3" "10.53.0.3"
|
|
||||||
# Key properties.
|
|
||||||
key_clear "KEY1"
|
|
||||||
set_keyrole "KEY1" "ksk"
|
|
||||||
set_keylifetime "KEY1" "0"
|
|
||||||
set_keydir "KEY1" "ns3/ksk"
|
|
||||||
set_keyalgorithm "KEY1" "$DEFAULT_ALGORITHM_NUMBER" "$DEFAULT_ALGORITHM" "$DEFAULT_BITS"
|
|
||||||
set_keysigning "KEY1" "yes"
|
|
||||||
set_zonesigning "KEY1" "no"
|
|
||||||
|
|
||||||
key_clear "KEY2"
|
|
||||||
set_keyrole "KEY2" "zsk"
|
|
||||||
set_keylifetime "KEY2" "0"
|
|
||||||
set_keydir "KEY2" "ns3/zsk"
|
|
||||||
set_keyalgorithm "KEY2" "$DEFAULT_ALGORITHM_NUMBER" "$DEFAULT_ALGORITHM" "$DEFAULT_BITS"
|
|
||||||
set_keysigning "KEY2" "no"
|
|
||||||
set_zonesigning "KEY2" "yes"
|
|
||||||
|
|
||||||
# KSK: DNSKEY, RRSIG (ksk) published. DS needs to wait.
|
|
||||||
# ZSK: DNSKEY, RRSIG (zsk) published.
|
|
||||||
set_keystate "KEY1" "GOAL" "omnipresent"
|
|
||||||
set_keystate "KEY1" "STATE_DNSKEY" "rumoured"
|
|
||||||
set_keystate "KEY1" "STATE_KRRSIG" "rumoured"
|
|
||||||
set_keystate "KEY1" "STATE_DS" "hidden"
|
|
||||||
|
|
||||||
set_keystate "KEY2" "GOAL" "omnipresent"
|
|
||||||
set_keystate "KEY2" "STATE_DNSKEY" "rumoured"
|
|
||||||
set_keystate "KEY2" "STATE_ZRRSIG" "rumoured"
|
|
||||||
# Two keys only.
|
|
||||||
key_clear "KEY3"
|
|
||||||
key_clear "KEY4"
|
|
||||||
|
|
||||||
check_keys
|
|
||||||
check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
|
|
||||||
# Reuse set_keytimes_csk_policy to set the KEY1 keytimes.
|
|
||||||
set_keytimes_csk_policy
|
|
||||||
created=$(key_get KEY2 CREATED)
|
|
||||||
set_keytime "KEY2" "PUBLISHED" "${created}"
|
|
||||||
set_keytime "KEY2" "ACTIVE" "${created}"
|
|
||||||
check_keytimes
|
|
||||||
check_apex
|
|
||||||
check_subdomain
|
|
||||||
dnssec_verify
|
|
||||||
|
|
||||||
#
|
|
||||||
# Zone: inherit.kasp.
|
|
||||||
#
|
|
||||||
set_zone "inherit.kasp"
|
|
||||||
set_policy "rsasha256" "3" "1234"
|
|
||||||
set_server "ns3" "10.53.0.3"
|
|
||||||
|
|
||||||
# Key properties.
|
|
||||||
key_clear "KEY1"
|
|
||||||
set_keyrole "KEY1" "ksk"
|
|
||||||
set_keylifetime "KEY1" "315360000"
|
|
||||||
set_keyalgorithm "KEY1" "8" "RSASHA256" "2048"
|
|
||||||
set_keysigning "KEY1" "yes"
|
|
||||||
set_zonesigning "KEY1" "no"
|
|
||||||
|
|
||||||
key_clear "KEY2"
|
|
||||||
set_keyrole "KEY2" "zsk"
|
|
||||||
set_keylifetime "KEY2" "157680000"
|
|
||||||
set_keyalgorithm "KEY2" "8" "RSASHA256" "2048"
|
|
||||||
set_keysigning "KEY2" "no"
|
|
||||||
set_zonesigning "KEY2" "yes"
|
|
||||||
|
|
||||||
key_clear "KEY3"
|
|
||||||
set_keyrole "KEY3" "zsk"
|
|
||||||
set_keylifetime "KEY3" "31536000"
|
|
||||||
set_keyalgorithm "KEY3" "8" "RSASHA256" "3072"
|
|
||||||
set_keysigning "KEY3" "no"
|
|
||||||
set_zonesigning "KEY3" "yes"
|
|
||||||
# KSK: DNSKEY, RRSIG (ksk) published. DS needs to wait.
|
|
||||||
# ZSK: DNSKEY, RRSIG (zsk) published.
|
|
||||||
set_keystate "KEY1" "GOAL" "omnipresent"
|
|
||||||
set_keystate "KEY1" "STATE_DNSKEY" "rumoured"
|
|
||||||
set_keystate "KEY1" "STATE_KRRSIG" "rumoured"
|
|
||||||
set_keystate "KEY1" "STATE_DS" "hidden"
|
|
||||||
|
|
||||||
set_keystate "KEY2" "GOAL" "omnipresent"
|
|
||||||
set_keystate "KEY2" "STATE_DNSKEY" "rumoured"
|
|
||||||
set_keystate "KEY2" "STATE_ZRRSIG" "rumoured"
|
|
||||||
|
|
||||||
set_keystate "KEY3" "GOAL" "omnipresent"
|
|
||||||
set_keystate "KEY3" "STATE_DNSKEY" "rumoured"
|
|
||||||
set_keystate "KEY3" "STATE_ZRRSIG" "rumoured"
|
|
||||||
# Three keys only.
|
|
||||||
key_clear "KEY4"
|
|
||||||
|
|
||||||
check_keys
|
|
||||||
check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
|
|
||||||
set_keytimes_algorithm_policy
|
|
||||||
check_keytimes
|
|
||||||
check_apex
|
|
||||||
check_subdomain
|
|
||||||
dnssec_verify
|
|
||||||
|
|
||||||
#
|
|
||||||
# Zone: dnssec-keygen.kasp.
|
|
||||||
#
|
|
||||||
set_zone "dnssec-keygen.kasp"
|
|
||||||
set_policy "rsasha256" "3" "1234"
|
|
||||||
set_server "ns3" "10.53.0.3"
|
|
||||||
# Key properties, timings and states same as above.
|
|
||||||
|
|
||||||
check_keys
|
|
||||||
check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
|
|
||||||
set_keytimes_algorithm_policy
|
|
||||||
check_keytimes
|
|
||||||
check_apex
|
|
||||||
check_subdomain
|
|
||||||
dnssec_verify
|
|
||||||
|
|
||||||
#
|
|
||||||
# Zone: some-keys.kasp.
|
|
||||||
#
|
|
||||||
set_zone "some-keys.kasp"
|
|
||||||
set_policy "rsasha256" "3" "1234"
|
|
||||||
set_server "ns3" "10.53.0.3"
|
|
||||||
# Key properties, timings and states same as above.
|
|
||||||
|
|
||||||
check_keys
|
|
||||||
check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
|
|
||||||
set_keytimes_algorithm_policy "pregenerated"
|
|
||||||
check_keytimes
|
|
||||||
check_apex
|
|
||||||
check_subdomain
|
|
||||||
dnssec_verify
|
|
||||||
|
|
||||||
#
|
|
||||||
# Zone: pregenerated.kasp.
|
|
||||||
#
|
|
||||||
# There are more pregenerated keys than needed, hence the number of keys is
|
|
||||||
# six, not three.
|
|
||||||
set_zone "pregenerated.kasp"
|
|
||||||
set_policy "rsasha256" "6" "1234"
|
|
||||||
set_server "ns3" "10.53.0.3"
|
|
||||||
# Key properties, timings and states same as above.
|
|
||||||
|
|
||||||
check_keys
|
|
||||||
check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
|
|
||||||
set_keytimes_algorithm_policy "pregenerated"
|
|
||||||
check_keytimes
|
|
||||||
check_apex
|
|
||||||
check_subdomain
|
|
||||||
dnssec_verify
|
|
||||||
|
|
||||||
#
|
|
||||||
# Zone: rumoured.kasp.
|
|
||||||
#
|
|
||||||
# There are three keys in rumoured state.
|
|
||||||
set_zone "rumoured.kasp"
|
|
||||||
set_policy "rsasha256" "3" "1234"
|
|
||||||
set_server "ns3" "10.53.0.3"
|
|
||||||
# Key properties, timings and states same as above.
|
|
||||||
|
|
||||||
check_keys
|
|
||||||
check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
|
|
||||||
set_keytimes_algorithm_policy
|
|
||||||
# Activation date is a day later.
|
|
||||||
set_addkeytime "KEY1" "ACTIVE" $(key_get KEY1 ACTIVE) 86400
|
|
||||||
set_addkeytime "KEY1" "RETIRED" $(key_get KEY1 RETIRED) 86400
|
|
||||||
set_addkeytime "KEY1" "REMOVED" $(key_get KEY1 REMOVED) 86400
|
|
||||||
set_addkeytime "KEY2" "ACTIVE" $(key_get KEY2 ACTIVE) 86400
|
|
||||||
set_addkeytime "KEY2" "RETIRED" $(key_get KEY2 RETIRED) 86400
|
|
||||||
set_addkeytime "KEY2" "REMOVED" $(key_get KEY2 REMOVED) 86400
|
|
||||||
set_addkeytime "KEY3" "ACTIVE" $(key_get KEY3 ACTIVE) 86400
|
|
||||||
set_addkeytime "KEY3" "RETIRED" $(key_get KEY3 RETIRED) 86400
|
|
||||||
set_addkeytime "KEY3" "REMOVED" $(key_get KEY3 REMOVED) 86400
|
|
||||||
check_keytimes
|
|
||||||
check_apex
|
|
||||||
check_subdomain
|
|
||||||
dnssec_verify
|
|
||||||
|
|
||||||
#
|
|
||||||
# Zone: secondary.kasp.
|
|
||||||
#
|
|
||||||
set_zone "secondary.kasp"
|
|
||||||
set_policy "rsasha256" "3" "1234"
|
|
||||||
set_server "ns3" "10.53.0.3"
|
|
||||||
# Key properties, timings and states same as above.
|
|
||||||
|
|
||||||
check_keys
|
|
||||||
check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
|
|
||||||
set_keytimes_algorithm_policy
|
|
||||||
check_keytimes
|
|
||||||
check_apex
|
|
||||||
check_subdomain
|
|
||||||
dnssec_verify
|
|
||||||
|
|
||||||
# Update zone.
|
|
||||||
n=$((n + 1))
|
|
||||||
echo_i "check that we correctly sign the zone after IXFR for zone ${ZONE} ($n)"
|
|
||||||
ret=0
|
|
||||||
cp ns2/secondary.kasp.db.in2 ns2/secondary.kasp.db
|
|
||||||
rndccmd 10.53.0.2 reload "$ZONE" >/dev/null || log_error "rndc reload zone ${ZONE} failed"
|
|
||||||
|
|
||||||
_wait_for_done_subdomains() {
|
|
||||||
ret=0
|
|
||||||
dig_with_opts "a.${ZONE}" "@${SERVER}" A >"dig.out.$DIR.test$n.a" || return 1
|
|
||||||
grep "status: NOERROR" "dig.out.$DIR.test$n.a" >/dev/null || return 1
|
|
||||||
grep "a.${ZONE}\..*${DEFAULT_TTL}.*IN.*A.*10\.0\.0\.11" "dig.out.$DIR.test$n.a" >/dev/null || return 1
|
|
||||||
check_signatures $_qtype "dig.out.$DIR.test$n.a" "ZSK"
|
|
||||||
if [ $ret -gt 0 ]; then return $ret; fi
|
|
||||||
|
|
||||||
dig_with_opts "d.${ZONE}" "@${SERVER}" A >"dig.out.$DIR.test$n.d" || return 1
|
|
||||||
grep "status: NOERROR" "dig.out.$DIR.test$n.d" >/dev/null || return 1
|
|
||||||
grep "d.${ZONE}\..*${DEFAULT_TTL}.*IN.*A.*10\.0\.0\.4" "dig.out.$DIR.test$n.d" >/dev/null || return 1
|
|
||||||
check_signatures $_qtype "dig.out.$DIR.test$n.d" "ZSK"
|
|
||||||
return $ret
|
|
||||||
}
|
|
||||||
retry_quiet 5 _wait_for_done_subdomains || ret=1
|
|
||||||
test "$ret" -eq 0 || echo_i "failed"
|
|
||||||
status=$((status + ret))
|
|
||||||
|
|
||||||
# TODO: we might want to test:
|
# TODO: we might want to test:
|
||||||
# - configuring a zone with too many active keys (should trigger retire).
|
# - configuring a zone with too many active keys (should trigger retire).
|
||||||
# - configuring a zone with keys not matching the policy.
|
# - configuring a zone with keys not matching the policy.
|
||||||
|
|
||||||
#
|
|
||||||
# Zone: rsasha1-nsec3.kasp.
|
|
||||||
#
|
|
||||||
if [ $RSASHA1_SUPPORTED = 1 ]; then
|
|
||||||
set_zone "rsasha1-nsec3.kasp"
|
|
||||||
set_policy "rsasha1-nsec3" "3" "1234"
|
|
||||||
set_server "ns3" "10.53.0.3"
|
|
||||||
# Key properties.
|
|
||||||
set_keyalgorithm "KEY1" "7" "NSEC3RSASHA1" "2048"
|
|
||||||
set_keyalgorithm "KEY2" "7" "NSEC3RSASHA1" "2048"
|
|
||||||
set_keyalgorithm "KEY3" "7" "NSEC3RSASHA1" "2000"
|
|
||||||
# Key timings and states same as above.
|
|
||||||
|
|
||||||
check_keys
|
|
||||||
check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
|
|
||||||
set_keytimes_algorithm_policy
|
|
||||||
check_keytimes
|
|
||||||
check_apex
|
|
||||||
check_subdomain
|
|
||||||
dnssec_verify
|
|
||||||
fi
|
|
||||||
|
|
||||||
#
|
|
||||||
# Zone: rsasha256.kasp.
|
|
||||||
#
|
|
||||||
set_zone "rsasha256.kasp"
|
|
||||||
set_policy "rsasha256" "3" "1234"
|
|
||||||
set_server "ns3" "10.53.0.3"
|
|
||||||
# Key properties.
|
|
||||||
set_keyalgorithm "KEY1" "8" "RSASHA256" "2048"
|
|
||||||
set_keyalgorithm "KEY2" "8" "RSASHA256" "2048"
|
|
||||||
set_keyalgorithm "KEY3" "8" "RSASHA256" "3072"
|
|
||||||
# Key timings and states same as above.
|
|
||||||
|
|
||||||
check_keys
|
|
||||||
check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
|
|
||||||
set_keytimes_algorithm_policy
|
|
||||||
check_keytimes
|
|
||||||
check_apex
|
|
||||||
check_subdomain
|
|
||||||
dnssec_verify
|
|
||||||
|
|
||||||
#
|
|
||||||
# Zone: rsasha512.kasp.
|
|
||||||
#
|
|
||||||
set_zone "rsasha512.kasp"
|
|
||||||
set_policy "rsasha512" "3" "1234"
|
|
||||||
set_server "ns3" "10.53.0.3"
|
|
||||||
# Key properties.
|
|
||||||
set_keyalgorithm "KEY1" "10" "RSASHA512" "2048"
|
|
||||||
set_keyalgorithm "KEY2" "10" "RSASHA512" "2048"
|
|
||||||
set_keyalgorithm "KEY3" "10" "RSASHA512" "3072"
|
|
||||||
# Key timings and states same as above.
|
|
||||||
|
|
||||||
check_keys
|
|
||||||
check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
|
|
||||||
set_keytimes_algorithm_policy
|
|
||||||
check_keytimes
|
|
||||||
check_apex
|
|
||||||
check_subdomain
|
|
||||||
dnssec_verify
|
|
||||||
|
|
||||||
#
|
|
||||||
# Zone: ecdsa256.kasp.
|
|
||||||
#
|
|
||||||
set_zone "ecdsa256.kasp"
|
|
||||||
set_policy "ecdsa256" "3" "1234"
|
|
||||||
set_server "ns3" "10.53.0.3"
|
|
||||||
# Key properties.
|
|
||||||
set_keyalgorithm "KEY1" "13" "ECDSAP256SHA256" "256"
|
|
||||||
set_keyalgorithm "KEY2" "13" "ECDSAP256SHA256" "256"
|
|
||||||
set_keyalgorithm "KEY3" "13" "ECDSAP256SHA256" "256"
|
|
||||||
# Key timings and states same as above.
|
|
||||||
|
|
||||||
check_keys
|
|
||||||
check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
|
|
||||||
set_keytimes_algorithm_policy
|
|
||||||
check_keytimes
|
|
||||||
check_apex
|
|
||||||
check_subdomain
|
|
||||||
dnssec_verify
|
|
||||||
|
|
||||||
#
|
|
||||||
# Zone: ecdsa512.kasp.
|
|
||||||
#
|
|
||||||
set_zone "ecdsa384.kasp"
|
|
||||||
set_policy "ecdsa384" "3" "1234"
|
|
||||||
set_server "ns3" "10.53.0.3"
|
|
||||||
# Key properties.
|
|
||||||
set_keyalgorithm "KEY1" "14" "ECDSAP384SHA384" "384"
|
|
||||||
set_keyalgorithm "KEY2" "14" "ECDSAP384SHA384" "384"
|
|
||||||
set_keyalgorithm "KEY3" "14" "ECDSAP384SHA384" "384"
|
|
||||||
# Key timings and states same as above.
|
|
||||||
|
|
||||||
check_keys
|
|
||||||
check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
|
|
||||||
set_keytimes_algorithm_policy
|
|
||||||
check_keytimes
|
|
||||||
check_apex
|
|
||||||
check_subdomain
|
|
||||||
dnssec_verify
|
|
||||||
|
|
||||||
#
|
|
||||||
# Zone: ed25519.kasp.
|
|
||||||
#
|
|
||||||
if [ $ED25519_SUPPORTED = 1 ]; then
|
|
||||||
set_zone "ed25519.kasp"
|
|
||||||
set_policy "ed25519" "3" "1234"
|
|
||||||
set_server "ns3" "10.53.0.3"
|
|
||||||
# Key properties.
|
|
||||||
set_keyalgorithm "KEY1" "15" "ED25519" "256"
|
|
||||||
set_keyalgorithm "KEY2" "15" "ED25519" "256"
|
|
||||||
set_keyalgorithm "KEY3" "15" "ED25519" "256"
|
|
||||||
# Key timings and states same as above.
|
|
||||||
|
|
||||||
check_keys
|
|
||||||
check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
|
|
||||||
set_keytimes_algorithm_policy
|
|
||||||
check_keytimes
|
|
||||||
check_apex
|
|
||||||
check_subdomain
|
|
||||||
dnssec_verify
|
|
||||||
fi
|
|
||||||
|
|
||||||
#
|
|
||||||
# Zone: ed448.kasp.
|
|
||||||
#
|
|
||||||
if [ $ED448_SUPPORTED = 1 ]; then
|
|
||||||
set_zone "ed448.kasp"
|
|
||||||
set_policy "ed448" "3" "1234"
|
|
||||||
set_server "ns3" "10.53.0.3"
|
|
||||||
# Key properties.
|
|
||||||
set_keyalgorithm "KEY1" "16" "ED448" "456"
|
|
||||||
set_keyalgorithm "KEY2" "16" "ED448" "456"
|
|
||||||
set_keyalgorithm "KEY3" "16" "ED448" "456"
|
|
||||||
# Key timings and states same as above.
|
|
||||||
|
|
||||||
check_keys
|
|
||||||
check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
|
|
||||||
set_keytimes_algorithm_policy
|
|
||||||
check_keytimes
|
|
||||||
check_apex
|
|
||||||
check_subdomain
|
|
||||||
dnssec_verify
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Set key times for 'autosign' policy.
|
# Set key times for 'autosign' policy.
|
||||||
set_keytimes_autosign_policy() {
|
set_keytimes_autosign_policy() {
|
||||||
# The KSK was published six months ago (with settime).
|
# The KSK was published six months ago (with settime).
|
||||||
@@ -889,256 +437,39 @@ set_keytimes_autosign_policy() {
|
|||||||
set_addkeytime "KEY2" "REMOVED" "${retired}" 695100
|
set_addkeytime "KEY2" "REMOVED" "${retired}" 695100
|
||||||
}
|
}
|
||||||
|
|
||||||
#
|
|
||||||
# Zone: expired-sigs.autosign.
|
|
||||||
#
|
|
||||||
set_zone "expired-sigs.autosign"
|
|
||||||
set_policy "autosign" "2" "300"
|
|
||||||
set_server "ns3" "10.53.0.3"
|
|
||||||
# Key properties.
|
|
||||||
key_clear "KEY1"
|
|
||||||
set_keyrole "KEY1" "ksk"
|
|
||||||
set_keylifetime "KEY1" "63072000"
|
|
||||||
set_keyalgorithm "KEY1" "$DEFAULT_ALGORITHM_NUMBER" "$DEFAULT_ALGORITHM" "$DEFAULT_BITS"
|
|
||||||
set_keysigning "KEY1" "yes"
|
|
||||||
set_zonesigning "KEY1" "no"
|
|
||||||
|
|
||||||
key_clear "KEY2"
|
|
||||||
set_keyrole "KEY2" "zsk"
|
|
||||||
set_keylifetime "KEY2" "31536000"
|
|
||||||
set_keyalgorithm "KEY2" "$DEFAULT_ALGORITHM_NUMBER" "$DEFAULT_ALGORITHM" "$DEFAULT_BITS"
|
|
||||||
set_keysigning "KEY2" "no"
|
|
||||||
set_zonesigning "KEY2" "yes"
|
|
||||||
|
|
||||||
# Both KSK and ZSK stay OMNIPRESENT.
|
|
||||||
set_keystate "KEY1" "GOAL" "omnipresent"
|
|
||||||
set_keystate "KEY1" "STATE_DNSKEY" "omnipresent"
|
|
||||||
set_keystate "KEY1" "STATE_KRRSIG" "omnipresent"
|
|
||||||
set_keystate "KEY1" "STATE_DS" "omnipresent"
|
|
||||||
|
|
||||||
set_keystate "KEY2" "GOAL" "omnipresent"
|
|
||||||
set_keystate "KEY2" "STATE_DNSKEY" "omnipresent"
|
|
||||||
set_keystate "KEY2" "STATE_ZRRSIG" "omnipresent"
|
|
||||||
# Expect only two keys.
|
|
||||||
key_clear "KEY3"
|
|
||||||
key_clear "KEY4"
|
|
||||||
|
|
||||||
check_keys
|
|
||||||
check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
|
|
||||||
set_keytimes_autosign_policy
|
|
||||||
check_keytimes
|
|
||||||
check_apex
|
|
||||||
check_subdomain
|
|
||||||
dnssec_verify
|
|
||||||
|
|
||||||
# Verify all signatures have been refreshed.
|
|
||||||
check_rrsig_refresh() {
|
|
||||||
# Apex.
|
|
||||||
_qtypes="DNSKEY SOA NS NSEC"
|
|
||||||
for _qtype in $_qtypes; do
|
|
||||||
n=$((n + 1))
|
|
||||||
echo_i "check ${_qtype} rrsig is refreshed correctly for zone ${ZONE} ($n)"
|
|
||||||
ret=0
|
|
||||||
dig_with_opts "$ZONE" "@${SERVER}" "$_qtype" >"dig.out.$DIR.test$n" || log_error "dig ${ZONE} ${_qtype} failed"
|
|
||||||
grep "status: NOERROR" "dig.out.$DIR.test$n" >/dev/null || log_error "mismatch status in DNS response"
|
|
||||||
grep "${ZONE}\..*IN.*RRSIG.*${_qtype}.*${ZONE}" "dig.out.$DIR.test$n" >"rrsig.out.$ZONE.$_qtype" || log_error "missing RRSIG (${_qtype}) record in response"
|
|
||||||
# If this exact RRSIG is also in the zone file it is not refreshed.
|
|
||||||
_rrsig=$(cat "rrsig.out.$ZONE.$_qtype")
|
|
||||||
grep "${_rrsig}" "${DIR}/${ZONE}.db" >/dev/null && log_error "RRSIG (${_qtype}) not refreshed in zone ${ZONE}"
|
|
||||||
test "$ret" -eq 0 || echo_i "failed"
|
|
||||||
status=$((status + ret))
|
|
||||||
done
|
|
||||||
|
|
||||||
# Below apex.
|
|
||||||
_labels="a b c ns3"
|
|
||||||
for _label in $_labels; do
|
|
||||||
_qtypes="A NSEC"
|
|
||||||
for _qtype in $_qtypes; do
|
|
||||||
n=$((n + 1))
|
|
||||||
echo_i "check ${_label} ${_qtype} rrsig is refreshed correctly for zone ${ZONE} ($n)"
|
|
||||||
ret=0
|
|
||||||
dig_with_opts "${_label}.${ZONE}" "@${SERVER}" "$_qtype" >"dig.out.$DIR.test$n" || log_error "dig ${_label}.${ZONE} ${_qtype} failed"
|
|
||||||
grep "status: NOERROR" "dig.out.$DIR.test$n" >/dev/null || log_error "mismatch status in DNS response"
|
|
||||||
grep "${ZONE}\..*IN.*RRSIG.*${_qtype}.*${ZONE}" "dig.out.$DIR.test$n" >"rrsig.out.$ZONE.$_qtype" || log_error "missing RRSIG (${_qtype}) record in response"
|
|
||||||
_rrsig=$(cat "rrsig.out.$ZONE.$_qtype")
|
|
||||||
grep "${_rrsig}" "${DIR}/${ZONE}.db" >/dev/null && log_error "RRSIG (${_qtype}) not refreshed in zone ${ZONE}"
|
|
||||||
test "$ret" -eq 0 || echo_i "failed"
|
|
||||||
status=$((status + ret))
|
|
||||||
done
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
check_rrsig_refresh
|
|
||||||
|
|
||||||
#
|
|
||||||
# Zone: dnskey-ttl-mismatch.autosign
|
|
||||||
#
|
|
||||||
set_zone "dnskey-ttl-mismatch.autosign"
|
|
||||||
set_policy "autosign" "2" "300"
|
|
||||||
set_server "ns3" "10.53.0.3"
|
|
||||||
# Key properties.
|
|
||||||
key_clear "KEY1"
|
|
||||||
set_keyrole "KEY1" "ksk"
|
|
||||||
set_keylifetime "KEY1" "63072000"
|
|
||||||
set_keyalgorithm "KEY1" "$DEFAULT_ALGORITHM_NUMBER" "$DEFAULT_ALGORITHM" "$DEFAULT_BITS"
|
|
||||||
set_keysigning "KEY1" "yes"
|
|
||||||
set_zonesigning "KEY1" "no"
|
|
||||||
|
|
||||||
key_clear "KEY2"
|
|
||||||
set_keyrole "KEY2" "zsk"
|
|
||||||
set_keylifetime "KEY2" "31536000"
|
|
||||||
set_keyalgorithm "KEY2" "$DEFAULT_ALGORITHM_NUMBER" "$DEFAULT_ALGORITHM" "$DEFAULT_BITS"
|
|
||||||
set_keysigning "KEY2" "no"
|
|
||||||
set_zonesigning "KEY2" "yes"
|
|
||||||
|
|
||||||
# Both KSK and ZSK stay OMNIPRESENT.
|
|
||||||
set_keystate "KEY1" "GOAL" "omnipresent"
|
|
||||||
set_keystate "KEY1" "STATE_DNSKEY" "omnipresent"
|
|
||||||
set_keystate "KEY1" "STATE_KRRSIG" "omnipresent"
|
|
||||||
set_keystate "KEY1" "STATE_DS" "omnipresent"
|
|
||||||
|
|
||||||
set_keystate "KEY2" "GOAL" "omnipresent"
|
|
||||||
set_keystate "KEY2" "STATE_DNSKEY" "omnipresent"
|
|
||||||
set_keystate "KEY2" "STATE_ZRRSIG" "omnipresent"
|
|
||||||
# Expect only two keys.
|
|
||||||
key_clear "KEY3"
|
|
||||||
key_clear "KEY4"
|
|
||||||
|
|
||||||
check_keys
|
|
||||||
check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
|
|
||||||
set_keytimes_autosign_policy
|
|
||||||
check_keytimes
|
|
||||||
check_apex
|
|
||||||
check_subdomain
|
|
||||||
dnssec_verify
|
|
||||||
|
|
||||||
#
|
|
||||||
# Zone: fresh-sigs.autosign.
|
|
||||||
#
|
|
||||||
set_zone "fresh-sigs.autosign"
|
|
||||||
set_policy "autosign" "2" "300"
|
|
||||||
set_server "ns3" "10.53.0.3"
|
|
||||||
# Key properties, timings and states same as above.
|
|
||||||
|
|
||||||
check_keys
|
|
||||||
check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
|
|
||||||
set_keytimes_autosign_policy
|
|
||||||
check_keytimes
|
|
||||||
check_apex
|
|
||||||
check_subdomain
|
|
||||||
dnssec_verify
|
|
||||||
|
|
||||||
# Verify signature reuse.
|
|
||||||
check_rrsig_reuse() {
|
|
||||||
# Apex.
|
|
||||||
_qtypes="NS NSEC"
|
|
||||||
for _qtype in $_qtypes; do
|
|
||||||
n=$((n + 1))
|
|
||||||
echo_i "check ${_qtype} rrsig is reused correctly for zone ${ZONE} ($n)"
|
|
||||||
ret=0
|
|
||||||
dig_with_opts "$ZONE" "@${SERVER}" "$_qtype" >"dig.out.$DIR.test$n" || log_error "dig ${ZONE} ${_qtype} failed"
|
|
||||||
grep "status: NOERROR" "dig.out.$DIR.test$n" >/dev/null || log_error "mismatch status in DNS response"
|
|
||||||
grep "${ZONE}\..*IN.*RRSIG.*${_qtype}.*${ZONE}" "dig.out.$DIR.test$n" >"rrsig.out.$ZONE.$_qtype" || log_error "missing RRSIG (${_qtype}) record in response"
|
|
||||||
# If this exact RRSIG is also in the signed zone file it is not refreshed.
|
|
||||||
_rrsig=$(awk '{print $5, $6, $7, $8, $9, $10, $11, $12, $13, $14;}' <"rrsig.out.$ZONE.$_qtype")
|
|
||||||
$CHECKZONE -f raw -F text -s full -o zone.out.${ZONE}.test$n "${ZONE}" "${DIR}/${ZONE}.db.signed" >/dev/null
|
|
||||||
grep "${_rrsig}" zone.out.${ZONE}.test$n >/dev/null || log_error "RRSIG (${_qtype}) not reused in zone ${ZONE}"
|
|
||||||
test "$ret" -eq 0 || echo_i "failed"
|
|
||||||
status=$((status + ret))
|
|
||||||
done
|
|
||||||
|
|
||||||
# Below apex.
|
|
||||||
_labels="a b c ns3"
|
|
||||||
for _label in $_labels; do
|
|
||||||
_qtypes="A NSEC"
|
|
||||||
for _qtype in $_qtypes; do
|
|
||||||
n=$((n + 1))
|
|
||||||
echo_i "check ${_label} ${_qtype} rrsig is reused correctly for zone ${ZONE} ($n)"
|
|
||||||
ret=0
|
|
||||||
dig_with_opts "${_label}.${ZONE}" "@${SERVER}" "$_qtype" >"dig.out.$DIR.test$n" || log_error "dig ${_label}.${ZONE} ${_qtype} failed"
|
|
||||||
grep "status: NOERROR" "dig.out.$DIR.test$n" >/dev/null || log_error "mismatch status in DNS response"
|
|
||||||
grep "${ZONE}\..*IN.*RRSIG.*${_qtype}.*${ZONE}" "dig.out.$DIR.test$n" >"rrsig.out.$ZONE.$_qtype" || log_error "missing RRSIG (${_qtype}) record in response"
|
|
||||||
# If this exact RRSIG is also in the signed zone file it is not refreshed.
|
|
||||||
_rrsig=$(awk '{print $5, $6, $7, $8, $9, $10, $11, $12, $13, $14;}' <"rrsig.out.$ZONE.$_qtype")
|
|
||||||
$CHECKZONE -f raw -F text -s full -o zone.out.${ZONE}.test$n "${ZONE}" "${DIR}/${ZONE}.db.signed" >/dev/null
|
|
||||||
grep "${_rrsig}" zone.out.${ZONE}.test$n >/dev/null || log_error "RRSIG (${_qtype}) not reused in zone ${ZONE}"
|
|
||||||
test "$ret" -eq 0 || echo_i "failed"
|
|
||||||
status=$((status + ret))
|
|
||||||
done
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
check_rrsig_reuse
|
|
||||||
|
|
||||||
#
|
|
||||||
# Zone: unfresh-sigs.autosign.
|
|
||||||
#
|
|
||||||
set_zone "unfresh-sigs.autosign"
|
|
||||||
set_policy "autosign" "2" "300"
|
|
||||||
set_server "ns3" "10.53.0.3"
|
|
||||||
# Key properties, timings and states same as above.
|
|
||||||
|
|
||||||
check_keys
|
|
||||||
check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
|
|
||||||
set_keytimes_autosign_policy
|
|
||||||
check_keytimes
|
|
||||||
check_apex
|
|
||||||
check_subdomain
|
|
||||||
dnssec_verify
|
|
||||||
check_rrsig_refresh
|
|
||||||
|
|
||||||
#
|
|
||||||
# Zone: ksk-missing.autosign.
|
|
||||||
#
|
|
||||||
set_zone "ksk-missing.autosign"
|
|
||||||
set_policy "autosign" "2" "300"
|
|
||||||
set_server "ns3" "10.53.0.3"
|
|
||||||
# Key properties, timings and states same as above.
|
|
||||||
# Skip checking the private file, because it is missing.
|
|
||||||
key_set "KEY1" "PRIVATE" "no"
|
|
||||||
|
|
||||||
check_keys
|
|
||||||
check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
|
|
||||||
check_apex
|
|
||||||
check_subdomain
|
|
||||||
dnssec_verify
|
|
||||||
|
|
||||||
# Restore the PRIVATE variable.
|
|
||||||
key_set "KEY1" "PRIVATE" "yes"
|
|
||||||
|
|
||||||
#
|
|
||||||
# Zone: zsk-missing.autosign.
|
|
||||||
#
|
|
||||||
set_zone "zsk-missing.autosign"
|
|
||||||
set_policy "autosign" "2" "300"
|
|
||||||
set_server "ns3" "10.53.0.3"
|
|
||||||
# Key properties, timings and states same as above.
|
|
||||||
# Skip checking the private file, because it is missing.
|
|
||||||
key_set "KEY2" "PRIVATE" "no"
|
|
||||||
|
|
||||||
check_keys
|
|
||||||
check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
|
|
||||||
# For the apex, we expect the SOA to be signed with the KSK because the ZSK is
|
|
||||||
# offline. Temporary treat KEY1 as a zone signing key too.
|
|
||||||
set_keyrole "KEY1" "csk"
|
|
||||||
set_zonesigning "KEY1" "yes"
|
|
||||||
set_zonesigning "KEY2" "no"
|
|
||||||
check_apex
|
|
||||||
set_keyrole "KEY1" "ksk"
|
|
||||||
set_zonesigning "KEY1" "no"
|
|
||||||
set_zonesigning "KEY2" "yes"
|
|
||||||
check_subdomain
|
|
||||||
dnssec_verify
|
|
||||||
|
|
||||||
# Restore the PRIVATE variable.
|
|
||||||
key_set "KEY2" "PRIVATE" "yes"
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Zone: zsk-retired.autosign.
|
# Zone: zsk-retired.autosign.
|
||||||
#
|
#
|
||||||
set_zone "zsk-retired.autosign"
|
set_zone "zsk-retired.autosign"
|
||||||
set_policy "autosign" "3" "300"
|
set_policy "autosign" "3" "300"
|
||||||
set_server "ns3" "10.53.0.3"
|
set_server "ns3" "10.53.0.3"
|
||||||
|
# Key properties.
|
||||||
|
key_clear "KEY1"
|
||||||
|
set_keyrole "KEY1" "ksk"
|
||||||
|
set_keylifetime "KEY1" "63072000"
|
||||||
|
set_keyalgorithm "KEY1" "$DEFAULT_ALGORITHM_NUMBER" "$DEFAULT_ALGORITHM" "$DEFAULT_BITS"
|
||||||
|
set_keysigning "KEY1" "yes"
|
||||||
|
set_zonesigning "KEY1" "no"
|
||||||
|
|
||||||
|
key_clear "KEY2"
|
||||||
|
set_keyrole "KEY2" "zsk"
|
||||||
|
set_keylifetime "KEY2" "31536000"
|
||||||
|
set_keyalgorithm "KEY2" "$DEFAULT_ALGORITHM_NUMBER" "$DEFAULT_ALGORITHM" "$DEFAULT_BITS"
|
||||||
|
set_keysigning "KEY2" "no"
|
||||||
|
set_zonesigning "KEY2" "yes"
|
||||||
|
|
||||||
|
# Both KSK and ZSK stay OMNIPRESENT.
|
||||||
|
set_keystate "KEY1" "GOAL" "omnipresent"
|
||||||
|
set_keystate "KEY1" "STATE_DNSKEY" "omnipresent"
|
||||||
|
set_keystate "KEY1" "STATE_KRRSIG" "omnipresent"
|
||||||
|
set_keystate "KEY1" "STATE_DS" "omnipresent"
|
||||||
|
|
||||||
|
set_keystate "KEY2" "GOAL" "omnipresent"
|
||||||
|
set_keystate "KEY2" "STATE_DNSKEY" "omnipresent"
|
||||||
|
set_keystate "KEY2" "STATE_ZRRSIG" "omnipresent"
|
||||||
|
# Expect only two keys.
|
||||||
|
key_clear "KEY3"
|
||||||
|
key_clear "KEY4"
|
||||||
# The third key is not yet expected to be signing.
|
# The third key is not yet expected to be signing.
|
||||||
set_keyrole "KEY3" "zsk"
|
set_keyrole "KEY3" "zsk"
|
||||||
set_keylifetime "KEY3" "31536000"
|
set_keylifetime "KEY3" "31536000"
|
||||||
@@ -1185,7 +516,7 @@ check_keytimes
|
|||||||
check_apex
|
check_apex
|
||||||
check_subdomain
|
check_subdomain
|
||||||
dnssec_verify
|
dnssec_verify
|
||||||
check_rrsig_refresh
|
#check_rrsig_refresh
|
||||||
|
|
||||||
# Load again, make sure the purged key is not an issue when verifying keys.
|
# Load again, make sure the purged key is not an issue when verifying keys.
|
||||||
echo_i "load keys for $ZONE, making sure a recently purged key is not an issue when verifying keys ($n)"
|
echo_i "load keys for $ZONE, making sure a recently purged key is not an issue when verifying keys ($n)"
|
||||||
@@ -1196,164 +527,6 @@ grep "zone $ZONE/IN (signed): zone_rekey:zone_verifykeys failed: some key files
|
|||||||
test "$ret" -eq 0 || echo_i "failed"
|
test "$ret" -eq 0 || echo_i "failed"
|
||||||
status=$((status + ret))
|
status=$((status + ret))
|
||||||
|
|
||||||
#
|
|
||||||
# Zone: legacy-keys.kasp.
|
|
||||||
#
|
|
||||||
set_zone "legacy-keys.kasp"
|
|
||||||
# This zone has two active keys and two old keys left in key directory, so
|
|
||||||
# expect 4 key files.
|
|
||||||
set_policy "migrate-to-dnssec-policy" "4" "1234"
|
|
||||||
set_server "ns3" "10.53.0.3"
|
|
||||||
|
|
||||||
# Key properties.
|
|
||||||
key_clear "KEY1"
|
|
||||||
set_keyrole "KEY1" "ksk"
|
|
||||||
set_keylifetime "KEY1" "16070400"
|
|
||||||
set_keyalgorithm "KEY1" "8" "RSASHA256" "2048"
|
|
||||||
set_keysigning "KEY1" "yes"
|
|
||||||
set_zonesigning "KEY1" "no"
|
|
||||||
|
|
||||||
key_clear "KEY2"
|
|
||||||
set_keyrole "KEY2" "zsk"
|
|
||||||
set_keylifetime "KEY2" "16070400"
|
|
||||||
set_keyalgorithm "KEY2" "8" "RSASHA256" "2048"
|
|
||||||
set_keysigning "KEY2" "no"
|
|
||||||
set_zonesigning "KEY2" "yes"
|
|
||||||
# KSK: DNSKEY, RRSIG (ksk) published. DS needs to wait.
|
|
||||||
# ZSK: DNSKEY, RRSIG (zsk) published.
|
|
||||||
set_keystate "KEY1" "GOAL" "omnipresent"
|
|
||||||
set_keystate "KEY1" "STATE_DNSKEY" "rumoured"
|
|
||||||
set_keystate "KEY1" "STATE_KRRSIG" "rumoured"
|
|
||||||
set_keystate "KEY1" "STATE_DS" "hidden"
|
|
||||||
|
|
||||||
set_keystate "KEY2" "GOAL" "omnipresent"
|
|
||||||
set_keystate "KEY2" "STATE_DNSKEY" "rumoured"
|
|
||||||
set_keystate "KEY2" "STATE_ZRRSIG" "rumoured"
|
|
||||||
# Two keys only.
|
|
||||||
key_clear "KEY3"
|
|
||||||
key_clear "KEY4"
|
|
||||||
|
|
||||||
check_keys
|
|
||||||
check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
|
|
||||||
|
|
||||||
# Make sure the correct legacy keys were used (and not the removed predecessor
|
|
||||||
# keys).
|
|
||||||
n=$((n + 1))
|
|
||||||
echo_i "check correct keys were used when migrating zone ${ZONE} to dnssec-policy ($n)"
|
|
||||||
ret=0
|
|
||||||
kskfile=$(cat ns3/legacy-keys.kasp.ksk)
|
|
||||||
basefile=$(key_get KEY1 BASEFILE)
|
|
||||||
echo_i "filename: $basefile (expect $kskfile)"
|
|
||||||
test "$DIR/$kskfile" = "$basefile" || ret=1
|
|
||||||
zskfile=$(cat ns3/legacy-keys.kasp.zsk)
|
|
||||||
basefile=$(key_get KEY2 BASEFILE)
|
|
||||||
echo_i "filename: $basefile (expect $zskfile)"
|
|
||||||
test "$DIR/$zskfile" = "$basefile" || ret=1
|
|
||||||
test "$ret" -eq 0 || echo_i "failed"
|
|
||||||
status=$((status + ret))
|
|
||||||
|
|
||||||
# KSK times.
|
|
||||||
created=$(key_get KEY1 CREATED)
|
|
||||||
keyfile=$(key_get KEY1 BASEFILE)
|
|
||||||
grep "; Publish:" "${keyfile}.key" >published.test${n}.key1
|
|
||||||
published=$(awk '{print $3}' <published.test${n}.key1)
|
|
||||||
set_keytime "KEY1" "PUBLISHED" "${published}"
|
|
||||||
set_keytime "KEY1" "ACTIVE" "${published}"
|
|
||||||
published=$(key_get KEY1 PUBLISHED)
|
|
||||||
# The DS can be published if the zone is fully signed.
|
|
||||||
# This happens after max-zone-ttl (1d) plus
|
|
||||||
# zone-propagation-delay (300s) = 86400 + 300 = 86700.
|
|
||||||
set_addkeytime "KEY1" "SYNCPUBLISH" "${published}" 86700
|
|
||||||
# Key lifetime is 6 months, 315360000 seconds.
|
|
||||||
set_addkeytime "KEY1" "RETIRED" "${published}" 16070400
|
|
||||||
# The key is removed after the retire time plus DS TTL (1d), parent
|
|
||||||
# propagation delay (1h), and retire safety (1h) = 86400 + 3600 + 3600 = 93600.
|
|
||||||
retired=$(key_get KEY1 RETIRED)
|
|
||||||
set_addkeytime "KEY1" "REMOVED" "${retired}" 93600
|
|
||||||
|
|
||||||
# ZSK times.
|
|
||||||
created=$(key_get KEY2 CREATED)
|
|
||||||
keyfile=$(key_get KEY2 BASEFILE)
|
|
||||||
grep "; Publish:" "${keyfile}.key" >published.test${n}.key2
|
|
||||||
published=$(awk '{print $3}' <published.test${n}.key2)
|
|
||||||
set_keytime "KEY2" "PUBLISHED" "${published}"
|
|
||||||
set_keytime "KEY2" "ACTIVE" "${published}"
|
|
||||||
published=$(key_get KEY2 PUBLISHED)
|
|
||||||
# Key lifetime is 6 months, 315360000 seconds.
|
|
||||||
set_addkeytime "KEY2" "RETIRED" "${published}" 16070400
|
|
||||||
# The key is removed after the retire time plus max zone ttl (1d), zone
|
|
||||||
# propagation delay (300s), retire safety (1h), and sign delay (signature
|
|
||||||
# validity minus refresh, 9d) = 86400 + 300 + 3600 + 777600 = 867900.
|
|
||||||
retired=$(key_get KEY2 RETIRED)
|
|
||||||
set_addkeytime "KEY2" "REMOVED" "${retired}" 867900
|
|
||||||
|
|
||||||
check_keytimes
|
|
||||||
check_apex
|
|
||||||
check_subdomain
|
|
||||||
dnssec_verify
|
|
||||||
|
|
||||||
#
|
|
||||||
# Zone: keyfiles-missing.autosign.
|
|
||||||
#
|
|
||||||
set_zone "keyfiles-missing.autosign"
|
|
||||||
set_policy "autosign" "2" "300"
|
|
||||||
set_server "ns3" "10.53.0.3"
|
|
||||||
# Key properties.
|
|
||||||
key_clear "KEY1"
|
|
||||||
set_keyrole "KEY1" "ksk"
|
|
||||||
set_keylifetime "KEY1" "63072000"
|
|
||||||
set_keyalgorithm "KEY1" "$DEFAULT_ALGORITHM_NUMBER" "$DEFAULT_ALGORITHM" "$DEFAULT_BITS"
|
|
||||||
set_keysigning "KEY1" "yes"
|
|
||||||
set_zonesigning "KEY1" "no"
|
|
||||||
|
|
||||||
key_clear "KEY2"
|
|
||||||
set_keyrole "KEY2" "zsk"
|
|
||||||
set_keylifetime "KEY2" "31536000"
|
|
||||||
set_keyalgorithm "KEY2" "$DEFAULT_ALGORITHM_NUMBER" "$DEFAULT_ALGORITHM" "$DEFAULT_BITS"
|
|
||||||
set_keysigning "KEY2" "no"
|
|
||||||
set_zonesigning "KEY2" "yes"
|
|
||||||
|
|
||||||
# Both KSK and ZSK stay OMNIPRESENT.
|
|
||||||
set_keystate "KEY1" "GOAL" "omnipresent"
|
|
||||||
set_keystate "KEY1" "STATE_DNSKEY" "omnipresent"
|
|
||||||
set_keystate "KEY1" "STATE_KRRSIG" "omnipresent"
|
|
||||||
set_keystate "KEY1" "STATE_DS" "omnipresent"
|
|
||||||
|
|
||||||
set_keystate "KEY2" "GOAL" "omnipresent"
|
|
||||||
set_keystate "KEY2" "STATE_DNSKEY" "omnipresent"
|
|
||||||
set_keystate "KEY2" "STATE_ZRRSIG" "omnipresent"
|
|
||||||
|
|
||||||
check_keys
|
|
||||||
check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
|
|
||||||
set_keytimes_autosign_policy
|
|
||||||
check_keytimes
|
|
||||||
check_apex
|
|
||||||
check_subdomain
|
|
||||||
dnssec_verify
|
|
||||||
# All good, now remove key files and reload keys.
|
|
||||||
rm_keyfiles() {
|
|
||||||
_basefile=$(key_get "$1" BASEFILE)
|
|
||||||
echo_i "remove key files $_basefile"
|
|
||||||
_keyfile="${_basefile}.key"
|
|
||||||
_privatefile="${_basefile}.private"
|
|
||||||
_statefile="${_basefile}.state"
|
|
||||||
rm -f $_keyfile
|
|
||||||
rm -f $_privatefile
|
|
||||||
rm -f $_statefile
|
|
||||||
}
|
|
||||||
rm_keyfiles "KEY1"
|
|
||||||
rm_keyfiles "KEY2"
|
|
||||||
|
|
||||||
rndccmd 10.53.0.3 loadkeys "$ZONE" >/dev/null || log_error "rndc loadkeys zone ${ZONE} failed"
|
|
||||||
wait_for_log 3 "zone $ZONE/IN (signed): zone_rekey:zone_verifykeys failed: some key files are missing" $DIR/named.run || ret=1
|
|
||||||
# Check keys again, make sure no new keys are created.
|
|
||||||
set_policy "autosign" "0" "300"
|
|
||||||
key_clear "KEY1"
|
|
||||||
key_clear "KEY2"
|
|
||||||
check_keys
|
|
||||||
# Zone is still signed correctly.
|
|
||||||
dnssec_verify
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Test dnssec-policy inheritance.
|
# Test dnssec-policy inheritance.
|
||||||
#
|
#
|
||||||
|
@@ -21,6 +21,7 @@ import pytest
|
|||||||
|
|
||||||
pytest.importorskip("dns", minversion="2.0.0")
|
pytest.importorskip("dns", minversion="2.0.0")
|
||||||
import isctest
|
import isctest
|
||||||
|
import isctest.mark
|
||||||
from isctest.kasp import (
|
from isctest.kasp import (
|
||||||
KeyProperties,
|
KeyProperties,
|
||||||
KeyTimingMetadata,
|
KeyTimingMetadata,
|
||||||
@@ -80,11 +81,76 @@ pytestmark = pytest.mark.extra_artifacts(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def check_all(server, zone, policy, ksks, zsks, tsig=None):
|
kasp_config = {
|
||||||
|
"dnskey-ttl": timedelta(seconds=1234),
|
||||||
|
"ds-ttl": timedelta(days=1),
|
||||||
|
"key-directory": "{keydir}",
|
||||||
|
"max-zone-ttl": timedelta(days=1),
|
||||||
|
"parent-propagation-delay": timedelta(hours=1),
|
||||||
|
"publish-safety": timedelta(hours=1),
|
||||||
|
"retire-safety": timedelta(hours=1),
|
||||||
|
"signatures-refresh": timedelta(days=5),
|
||||||
|
"signatures-validity": timedelta(days=14),
|
||||||
|
"zone-propagation-delay": timedelta(minutes=5),
|
||||||
|
}
|
||||||
|
|
||||||
|
autosign_config = {
|
||||||
|
"dnskey-ttl": timedelta(seconds=300),
|
||||||
|
"ds-ttl": timedelta(days=1),
|
||||||
|
"key-directory": "{keydir}",
|
||||||
|
"max-zone-ttl": timedelta(days=1),
|
||||||
|
"parent-propagation-delay": timedelta(hours=1),
|
||||||
|
"publish-safety": timedelta(hours=1),
|
||||||
|
"retire-safety": timedelta(hours=1),
|
||||||
|
"signatures-refresh": timedelta(days=7),
|
||||||
|
"signatures-validity": timedelta(days=14),
|
||||||
|
"zone-propagation-delay": timedelta(minutes=5),
|
||||||
|
}
|
||||||
|
|
||||||
|
lifetime = {
|
||||||
|
"P10Y": int(timedelta(days=10 * 365).total_seconds()),
|
||||||
|
"P5Y": int(timedelta(days=5 * 365).total_seconds()),
|
||||||
|
"P2Y": int(timedelta(days=2 * 365).total_seconds()),
|
||||||
|
"P1Y": int(timedelta(days=365).total_seconds()),
|
||||||
|
"P30D": int(timedelta(days=30).total_seconds()),
|
||||||
|
"P6M": int(timedelta(days=31 * 6).total_seconds()),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def autosign_properties(alg, size):
|
||||||
|
return [
|
||||||
|
f"ksk {lifetime['P2Y']} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent",
|
||||||
|
f"zsk {lifetime['P1Y']} {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def rsa1_properties(alg):
|
||||||
|
return [
|
||||||
|
f"ksk {lifetime['P10Y']} {alg} 2048 goal:omnipresent dnskey:rumoured krrsig:rumoured ds:hidden",
|
||||||
|
f"zsk {lifetime['P5Y']} {alg} 2048 goal:omnipresent dnskey:rumoured zrrsig:rumoured",
|
||||||
|
f"zsk {lifetime['P1Y']} {alg} 2000 goal:omnipresent dnskey:rumoured zrrsig:rumoured",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def fips_properties(alg, bits=None):
|
||||||
|
sizes = [2048, 2048, 3072]
|
||||||
|
if bits is not None:
|
||||||
|
sizes = [bits, bits, bits]
|
||||||
|
|
||||||
|
return [
|
||||||
|
f"ksk {lifetime['P10Y']} {alg} {sizes[0]} goal:omnipresent dnskey:rumoured krrsig:rumoured ds:hidden",
|
||||||
|
f"zsk {lifetime['P5Y']} {alg} {sizes[1]} goal:omnipresent dnskey:rumoured zrrsig:rumoured",
|
||||||
|
f"zsk {lifetime['P1Y']} {alg} {sizes[2]} goal:omnipresent dnskey:rumoured zrrsig:rumoured",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def check_all(server, zone, policy, ksks, zsks, zsk_missing=False, tsig=None):
|
||||||
isctest.kasp.check_dnssecstatus(server, zone, ksks + zsks, policy=policy)
|
isctest.kasp.check_dnssecstatus(server, zone, ksks + zsks, policy=policy)
|
||||||
isctest.kasp.check_apex(server, zone, ksks, zsks, tsig=tsig)
|
isctest.kasp.check_apex(
|
||||||
|
server, zone, ksks, zsks, zsk_missing=zsk_missing, tsig=tsig
|
||||||
|
)
|
||||||
isctest.kasp.check_subdomain(server, zone, ksks, zsks, tsig=tsig)
|
isctest.kasp.check_subdomain(server, zone, ksks, zsks, tsig=tsig)
|
||||||
isctest.kasp.check_dnssec_verify(server, zone)
|
isctest.kasp.check_dnssec_verify(server, zone, tsig=tsig)
|
||||||
|
|
||||||
|
|
||||||
def set_keytimes_default_policy(kp):
|
def set_keytimes_default_policy(kp):
|
||||||
@@ -103,6 +169,522 @@ def set_keytimes_default_policy(kp):
|
|||||||
kp.timing["ZRRSIGChange"] = kp.timing["Active"]
|
kp.timing["ZRRSIGChange"] = kp.timing["Active"]
|
||||||
|
|
||||||
|
|
||||||
|
def cb_ixfr_is_signed(expected_updates, params, ksks=None, zsks=None):
|
||||||
|
zone = params["zone"]
|
||||||
|
policy = params["policy"]
|
||||||
|
servers = params["servers"]
|
||||||
|
|
||||||
|
isctest.log.info(f"check that the zone {zone} is correctly signed after ixfr")
|
||||||
|
isctest.log.debug(
|
||||||
|
f"expected updates {expected_updates} policy {policy} ksks {ksks} zsks {zsks}"
|
||||||
|
)
|
||||||
|
shutil.copyfile(f"ns2/{zone}.db.in2", f"ns2/{zone}.db")
|
||||||
|
servers["ns2"].rndc(f"reload {zone}", log=False)
|
||||||
|
|
||||||
|
def update_is_signed():
|
||||||
|
parts = update.split()
|
||||||
|
qname = parts[0]
|
||||||
|
qtype = dns.rdatatype.from_text(parts[1])
|
||||||
|
rdata = parts[2]
|
||||||
|
return isctest.kasp.verify_update_is_signed(
|
||||||
|
servers["ns3"], zone, qname, qtype, rdata, ksks, zsks
|
||||||
|
)
|
||||||
|
|
||||||
|
for update in expected_updates:
|
||||||
|
isctest.run.retry_with_timeout(update_is_signed, timeout=5)
|
||||||
|
|
||||||
|
|
||||||
|
def cb_rrsig_refresh(params, ksks=None, zsks=None):
|
||||||
|
zone = params["zone"]
|
||||||
|
servers = params["servers"]
|
||||||
|
|
||||||
|
isctest.log.info(f"check that the zone {zone} refreshes expired signatures")
|
||||||
|
|
||||||
|
def rrsig_is_refreshed():
|
||||||
|
parts = query.split()
|
||||||
|
qname = parts[0]
|
||||||
|
qtype = dns.rdatatype.from_text(parts[1])
|
||||||
|
return isctest.kasp.verify_rrsig_is_refreshed(
|
||||||
|
servers["ns3"], zone, f"ns3/{zone}.db.signed", qname, qtype, ksks, zsks
|
||||||
|
)
|
||||||
|
|
||||||
|
queries = [
|
||||||
|
f"{zone} DNSKEY",
|
||||||
|
f"{zone} SOA",
|
||||||
|
f"{zone} NS",
|
||||||
|
f"{zone} NSEC",
|
||||||
|
f"a.{zone} A",
|
||||||
|
f"a.{zone} NSEC",
|
||||||
|
f"b.{zone} A",
|
||||||
|
f"b.{zone} NSEC",
|
||||||
|
f"c.{zone} A",
|
||||||
|
f"c.{zone} NSEC",
|
||||||
|
f"ns3.{zone} A",
|
||||||
|
f"ns3.{zone} NSEC",
|
||||||
|
]
|
||||||
|
|
||||||
|
for query in queries:
|
||||||
|
isctest.run.retry_with_timeout(rrsig_is_refreshed, timeout=5)
|
||||||
|
|
||||||
|
|
||||||
|
def cb_rrsig_reuse(params, ksks=None, zsks=None):
|
||||||
|
zone = params["zone"]
|
||||||
|
servers = params["servers"]
|
||||||
|
|
||||||
|
isctest.log.info(f"check that the zone {zone} reuses fresh signatures")
|
||||||
|
|
||||||
|
def rrsig_is_reused():
|
||||||
|
parts = query.split()
|
||||||
|
qname = parts[0]
|
||||||
|
qtype = dns.rdatatype.from_text(parts[1])
|
||||||
|
return isctest.kasp.verify_rrsig_is_reused(
|
||||||
|
servers["ns3"], zone, f"ns3/{zone}.db.signed", qname, qtype, ksks, zsks
|
||||||
|
)
|
||||||
|
|
||||||
|
queries = [
|
||||||
|
f"{zone} NS",
|
||||||
|
f"{zone} NSEC",
|
||||||
|
f"a.{zone} A",
|
||||||
|
f"a.{zone} NSEC",
|
||||||
|
f"b.{zone} A",
|
||||||
|
f"b.{zone} NSEC",
|
||||||
|
f"c.{zone} A",
|
||||||
|
f"c.{zone} NSEC",
|
||||||
|
f"ns3.{zone} A",
|
||||||
|
f"ns3.{zone} NSEC",
|
||||||
|
]
|
||||||
|
|
||||||
|
for query in queries:
|
||||||
|
rrsig_is_reused()
|
||||||
|
|
||||||
|
|
||||||
|
def cb_legacy_keys(params, ksks=None, zsks=None):
|
||||||
|
zone = params["zone"]
|
||||||
|
keydir = params["config"]["key-directory"]
|
||||||
|
|
||||||
|
isctest.log.info(f"check that the zone {zone} uses correct legacy keys")
|
||||||
|
|
||||||
|
assert len(ksks) == 1
|
||||||
|
assert len(zsks) == 1
|
||||||
|
|
||||||
|
# This assumes the zone has a policy that dictates one KSK and one ZSK.
|
||||||
|
# The right keys to be used are stored in "{zone}.ksk" and "{zone}.zsk".
|
||||||
|
with open(f"{keydir}/{zone}.ksk", "r", encoding="utf-8") as file:
|
||||||
|
kskfile = file.read()
|
||||||
|
with open(f"{keydir}/{zone}.zsk", "r", encoding="utf-8") as file:
|
||||||
|
zskfile = file.read()
|
||||||
|
|
||||||
|
assert f"{keydir}/{kskfile}".strip() == ksks[0].path
|
||||||
|
assert f"{keydir}/{zskfile}".strip() == zsks[0].path
|
||||||
|
|
||||||
|
|
||||||
|
def cb_remove_keyfiles(params, ksks=None, zsks=None):
|
||||||
|
zone = params["zone"]
|
||||||
|
servers = params["servers"]
|
||||||
|
keydir = params["config"]["key-directory"]
|
||||||
|
|
||||||
|
isctest.log.info(
|
||||||
|
"check that removing key files does not create new keys to be generated"
|
||||||
|
)
|
||||||
|
|
||||||
|
for k in ksks + zsks:
|
||||||
|
os.remove(k.keyfile)
|
||||||
|
os.remove(k.privatefile)
|
||||||
|
os.remove(k.statefile)
|
||||||
|
|
||||||
|
with servers["ns3"].watch_log_from_here() as watcher:
|
||||||
|
servers["ns3"].rndc(f"loadkeys {zone}", log=False)
|
||||||
|
watcher.wait_for_line(
|
||||||
|
f"zone {zone}/IN (signed): zone_rekey:zone_verifykeys failed: some key files are missing"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Check keys again, make sure no new keys are created.
|
||||||
|
keys = isctest.kasp.keydir_to_keylist(zone, keydir)
|
||||||
|
isctest.kasp.check_keys(zone, keys, [])
|
||||||
|
# Zone is still signed correctly.
|
||||||
|
isctest.kasp.check_dnssec_verify(servers["ns3"], zone)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"params",
|
||||||
|
[
|
||||||
|
pytest.param(
|
||||||
|
{
|
||||||
|
"zone": "rsasha1.kasp",
|
||||||
|
"policy": "rsasha1",
|
||||||
|
"config": kasp_config,
|
||||||
|
"key-properties": rsa1_properties(5),
|
||||||
|
},
|
||||||
|
id="rsasha1.kasp",
|
||||||
|
marks=isctest.mark.with_algorithm("RSASHA1"),
|
||||||
|
),
|
||||||
|
pytest.param(
|
||||||
|
{
|
||||||
|
"zone": "rsasha1-nsec3.kasp",
|
||||||
|
"policy": "rsasha1",
|
||||||
|
"config": kasp_config,
|
||||||
|
"key-properties": rsa1_properties(7),
|
||||||
|
},
|
||||||
|
id="rsasha1-nsec3.kasp",
|
||||||
|
marks=isctest.mark.with_algorithm("RSASHA1"),
|
||||||
|
),
|
||||||
|
pytest.param(
|
||||||
|
{
|
||||||
|
"zone": "dnskey-ttl-mismatch.autosign",
|
||||||
|
"policy": "autosign",
|
||||||
|
"config": autosign_config,
|
||||||
|
"offset": -timedelta(days=30 * 6),
|
||||||
|
"key-properties": autosign_properties(
|
||||||
|
os.environ["DEFAULT_ALGORITHM_NUMBER"], os.environ["DEFAULT_BITS"]
|
||||||
|
),
|
||||||
|
},
|
||||||
|
id="dnskey-ttl-mismatch.autosign",
|
||||||
|
),
|
||||||
|
pytest.param(
|
||||||
|
{
|
||||||
|
"zone": "expired-sigs.autosign",
|
||||||
|
"policy": "autosign",
|
||||||
|
"config": autosign_config,
|
||||||
|
"offset": -timedelta(days=30 * 6),
|
||||||
|
"key-properties": autosign_properties(
|
||||||
|
os.environ["DEFAULT_ALGORITHM_NUMBER"], os.environ["DEFAULT_BITS"]
|
||||||
|
),
|
||||||
|
"additional-tests": [
|
||||||
|
{
|
||||||
|
"callback": cb_rrsig_refresh,
|
||||||
|
"arguments": [],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
id="expired-sigs.autosign",
|
||||||
|
),
|
||||||
|
pytest.param(
|
||||||
|
{
|
||||||
|
"zone": "fresh-sigs.autosign",
|
||||||
|
"policy": "autosign",
|
||||||
|
"config": autosign_config,
|
||||||
|
"offset": -timedelta(days=30 * 6),
|
||||||
|
"key-properties": autosign_properties(
|
||||||
|
os.environ["DEFAULT_ALGORITHM_NUMBER"], os.environ["DEFAULT_BITS"]
|
||||||
|
),
|
||||||
|
"additional-tests": [
|
||||||
|
{
|
||||||
|
"callback": cb_rrsig_reuse,
|
||||||
|
"arguments": [],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
id="fresh-sigs.autosign",
|
||||||
|
),
|
||||||
|
pytest.param(
|
||||||
|
{
|
||||||
|
"zone": "unfresh-sigs.autosign",
|
||||||
|
"policy": "autosign",
|
||||||
|
"config": autosign_config,
|
||||||
|
"offset": -timedelta(days=30 * 6),
|
||||||
|
"key-properties": autosign_properties(
|
||||||
|
os.environ["DEFAULT_ALGORITHM_NUMBER"], os.environ["DEFAULT_BITS"]
|
||||||
|
),
|
||||||
|
"additional-tests": [
|
||||||
|
{
|
||||||
|
"callback": cb_rrsig_refresh,
|
||||||
|
"arguments": [],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
id="unfresh-sigs.autosign",
|
||||||
|
),
|
||||||
|
pytest.param(
|
||||||
|
{
|
||||||
|
"zone": "keyfiles-missing.autosign",
|
||||||
|
"policy": "autosign",
|
||||||
|
"config": autosign_config,
|
||||||
|
"offset": -timedelta(days=30 * 6),
|
||||||
|
"key-properties": autosign_properties(
|
||||||
|
os.environ["DEFAULT_ALGORITHM_NUMBER"], os.environ["DEFAULT_BITS"]
|
||||||
|
),
|
||||||
|
"additional-tests": [
|
||||||
|
{
|
||||||
|
"callback": cb_remove_keyfiles,
|
||||||
|
"arguments": [],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
id="keyfiles-missing.autosign",
|
||||||
|
),
|
||||||
|
pytest.param(
|
||||||
|
{
|
||||||
|
"zone": "ksk-missing.autosign",
|
||||||
|
"policy": "autosign",
|
||||||
|
"config": autosign_config,
|
||||||
|
"offset": -timedelta(days=30 * 6),
|
||||||
|
"key-properties": [
|
||||||
|
f"ksk 63072000 {os.environ['DEFAULT_ALGORITHM_NUMBER']} {os.environ['DEFAULT_BITS']} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent missing",
|
||||||
|
f"zsk 31536000 {os.environ['DEFAULT_ALGORITHM_NUMBER']} {os.environ['DEFAULT_BITS']} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
id="ksk-missing.autosign",
|
||||||
|
),
|
||||||
|
pytest.param(
|
||||||
|
{
|
||||||
|
"zone": "zsk-missing.autosign",
|
||||||
|
"policy": "autosign",
|
||||||
|
"config": autosign_config,
|
||||||
|
"offset": -timedelta(days=30 * 6),
|
||||||
|
"key-properties": [
|
||||||
|
f"ksk 63072000 {os.environ['DEFAULT_ALGORITHM_NUMBER']} {os.environ['DEFAULT_BITS']} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent",
|
||||||
|
f"zsk 31536000 {os.environ['DEFAULT_ALGORITHM_NUMBER']} {os.environ['DEFAULT_BITS']} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent missing",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
id="zsk-missing.autosign",
|
||||||
|
),
|
||||||
|
pytest.param(
|
||||||
|
{
|
||||||
|
"zone": "dnssec-keygen.kasp",
|
||||||
|
"policy": "rsasha256",
|
||||||
|
"config": kasp_config,
|
||||||
|
"key-properties": fips_properties(8),
|
||||||
|
},
|
||||||
|
id="dnssec-keygen.kasp",
|
||||||
|
),
|
||||||
|
pytest.param(
|
||||||
|
{
|
||||||
|
"zone": "ecdsa256.kasp",
|
||||||
|
"policy": "ecdsa256",
|
||||||
|
"config": kasp_config,
|
||||||
|
"key-properties": fips_properties(13, bits=256),
|
||||||
|
},
|
||||||
|
id="ecdsa256.kasp",
|
||||||
|
),
|
||||||
|
pytest.param(
|
||||||
|
{
|
||||||
|
"zone": "ecdsa384.kasp",
|
||||||
|
"policy": "ecdsa384",
|
||||||
|
"config": kasp_config,
|
||||||
|
"key-properties": fips_properties(14, bits=384),
|
||||||
|
},
|
||||||
|
id="ecdsa384.kasp",
|
||||||
|
),
|
||||||
|
pytest.param(
|
||||||
|
{
|
||||||
|
"zone": "inherit.kasp",
|
||||||
|
"policy": "rsasha256",
|
||||||
|
"config": kasp_config,
|
||||||
|
"key-properties": fips_properties(8),
|
||||||
|
},
|
||||||
|
id="inherit.kasp",
|
||||||
|
),
|
||||||
|
pytest.param(
|
||||||
|
{
|
||||||
|
"zone": "keystore.kasp",
|
||||||
|
"policy": "keystore",
|
||||||
|
"config": {
|
||||||
|
"dnskey-ttl": timedelta(seconds=303),
|
||||||
|
"ds-ttl": timedelta(days=1),
|
||||||
|
"key-directory": "{keydir}",
|
||||||
|
"max-zone-ttl": timedelta(days=1),
|
||||||
|
"parent-propagation-delay": timedelta(hours=1),
|
||||||
|
"publish-safety": timedelta(hours=1),
|
||||||
|
"retire-safety": timedelta(hours=1),
|
||||||
|
"signatures-refresh": timedelta(days=5),
|
||||||
|
"signatures-validity": timedelta(days=14),
|
||||||
|
"zone-propagation-delay": timedelta(minutes=5),
|
||||||
|
},
|
||||||
|
"key-directories": ["{keydir}/ksk", "{keydir}/zsk"],
|
||||||
|
"key-properties": [
|
||||||
|
f"ksk unlimited {os.environ['DEFAULT_ALGORITHM_NUMBER']} {os.environ['DEFAULT_BITS']} goal:omnipresent dnskey:rumoured krrsig:rumoured ds:hidden",
|
||||||
|
f"zsk unlimited {os.environ['DEFAULT_ALGORITHM_NUMBER']} {os.environ['DEFAULT_BITS']} goal:omnipresent dnskey:rumoured zrrsig:rumoured",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
id="keystore.kasp",
|
||||||
|
),
|
||||||
|
pytest.param(
|
||||||
|
{
|
||||||
|
"zone": "legacy-keys.kasp",
|
||||||
|
"policy": "migrate-to-dnssec-policy",
|
||||||
|
"config": kasp_config,
|
||||||
|
"pregenerated": True,
|
||||||
|
"key-properties": [
|
||||||
|
"ksk 16070400 8 2048 goal:omnipresent dnskey:rumoured krrsig:rumoured ds:hidden",
|
||||||
|
"zsk 16070400 8 2048 goal:omnipresent dnskey:rumoured zrrsig:rumoured",
|
||||||
|
],
|
||||||
|
"additional-tests": [
|
||||||
|
{
|
||||||
|
"callback": cb_legacy_keys,
|
||||||
|
"arguments": [],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
id="legacy-keys.kasp",
|
||||||
|
),
|
||||||
|
pytest.param(
|
||||||
|
{
|
||||||
|
"zone": "pregenerated.kasp",
|
||||||
|
"policy": "rsasha256",
|
||||||
|
"config": kasp_config,
|
||||||
|
"pregenerated": True,
|
||||||
|
"key-properties": fips_properties(8),
|
||||||
|
},
|
||||||
|
id="pregenerated.kasp",
|
||||||
|
),
|
||||||
|
pytest.param(
|
||||||
|
{
|
||||||
|
"zone": "rsasha256.kasp",
|
||||||
|
"policy": "rsasha256",
|
||||||
|
"config": kasp_config,
|
||||||
|
"key-properties": fips_properties(8),
|
||||||
|
},
|
||||||
|
id="rsasha256.kasp",
|
||||||
|
),
|
||||||
|
pytest.param(
|
||||||
|
{
|
||||||
|
"zone": "rsasha512.kasp",
|
||||||
|
"policy": "rsasha512",
|
||||||
|
"config": kasp_config,
|
||||||
|
"key-properties": fips_properties(10),
|
||||||
|
},
|
||||||
|
id="rsasha512.kasp",
|
||||||
|
),
|
||||||
|
pytest.param(
|
||||||
|
{
|
||||||
|
"zone": "rumoured.kasp",
|
||||||
|
"policy": "rsasha256",
|
||||||
|
"config": kasp_config,
|
||||||
|
"rumoured": True,
|
||||||
|
"key-properties": fips_properties(8),
|
||||||
|
},
|
||||||
|
id="rumoured.kasp",
|
||||||
|
),
|
||||||
|
pytest.param(
|
||||||
|
{
|
||||||
|
"zone": "secondary.kasp",
|
||||||
|
"policy": "rsasha256",
|
||||||
|
"config": kasp_config,
|
||||||
|
"key-properties": fips_properties(8),
|
||||||
|
"additional-tests": [
|
||||||
|
{
|
||||||
|
"callback": cb_ixfr_is_signed,
|
||||||
|
"arguments": [
|
||||||
|
[
|
||||||
|
"a.secondary.kasp. A 10.0.0.11",
|
||||||
|
"d.secondary.kasp. A 10.0.0.4",
|
||||||
|
],
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
id="secondary.kasp",
|
||||||
|
),
|
||||||
|
pytest.param(
|
||||||
|
{
|
||||||
|
"zone": "some-keys.kasp",
|
||||||
|
"policy": "rsasha256",
|
||||||
|
"config": kasp_config,
|
||||||
|
"pregenerated": True,
|
||||||
|
"key-properties": fips_properties(8),
|
||||||
|
},
|
||||||
|
id="some-keys.kasp",
|
||||||
|
),
|
||||||
|
pytest.param(
|
||||||
|
{
|
||||||
|
"zone": "unlimited.kasp",
|
||||||
|
"policy": "unlimited",
|
||||||
|
"config": kasp_config,
|
||||||
|
"key-properties": [
|
||||||
|
f"csk 0 {os.environ['DEFAULT_ALGORITHM_NUMBER']} {os.environ['DEFAULT_BITS']} goal:omnipresent dnskey:rumoured krrsig:rumoured zrrsig:rumoured ds:hidden",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
id="unlimited.kasp",
|
||||||
|
),
|
||||||
|
pytest.param(
|
||||||
|
{
|
||||||
|
"zone": "ed25519.kasp",
|
||||||
|
"policy": "ed25519",
|
||||||
|
"config": kasp_config,
|
||||||
|
"key-properties": fips_properties(15, bits=256),
|
||||||
|
},
|
||||||
|
id="ed25519.kasp",
|
||||||
|
marks=isctest.mark.with_algorithm("ED25519"),
|
||||||
|
),
|
||||||
|
pytest.param(
|
||||||
|
{
|
||||||
|
"zone": "ed448.kasp",
|
||||||
|
"policy": "ed448",
|
||||||
|
"config": kasp_config,
|
||||||
|
"key-properties": fips_properties(16, bits=456),
|
||||||
|
},
|
||||||
|
id="ed448.kasp",
|
||||||
|
marks=isctest.mark.with_algorithm("ED448"),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_kasp_case(servers, params):
|
||||||
|
# Test many different configurations and expected keys and states after
|
||||||
|
# initial startup.
|
||||||
|
server = servers["ns3"]
|
||||||
|
keydir = server.identifier
|
||||||
|
|
||||||
|
# Get test parameters.
|
||||||
|
zone = params["zone"]
|
||||||
|
policy = params["policy"]
|
||||||
|
|
||||||
|
params["config"]["key-directory"] = params["config"]["key-directory"].replace(
|
||||||
|
"{keydir}", keydir
|
||||||
|
)
|
||||||
|
if "key-directories" in params:
|
||||||
|
for i, val in enumerate(params["key-directories"]):
|
||||||
|
params["key-directories"][i] = val.replace("{keydir}", keydir)
|
||||||
|
|
||||||
|
ttl = int(params["config"]["dnskey-ttl"].total_seconds())
|
||||||
|
pregenerated = False
|
||||||
|
if params.get("pregenerated"):
|
||||||
|
pregenerated = params["pregenerated"]
|
||||||
|
zsk_missing = zone == "zsk-missing.autosign"
|
||||||
|
|
||||||
|
# Test case.
|
||||||
|
isctest.log.info(f"check test case zone {zone} policy {policy}")
|
||||||
|
|
||||||
|
# First make sure the zone is signed.
|
||||||
|
isctest.kasp.check_zone_is_signed(server, zone)
|
||||||
|
|
||||||
|
# Key properties.
|
||||||
|
expected = isctest.kasp.policy_to_properties(ttl=ttl, keys=params["key-properties"])
|
||||||
|
# Key files.
|
||||||
|
if "key-directories" in params:
|
||||||
|
kdir = params["key-directories"][0]
|
||||||
|
ksks = isctest.kasp.keydir_to_keylist(zone, kdir, in_use=pregenerated)
|
||||||
|
kdir = params["key-directories"][1]
|
||||||
|
zsks = isctest.kasp.keydir_to_keylist(zone, kdir, in_use=pregenerated)
|
||||||
|
keys = ksks + zsks
|
||||||
|
else:
|
||||||
|
keys = isctest.kasp.keydir_to_keylist(
|
||||||
|
zone, params["config"]["key-directory"], in_use=pregenerated
|
||||||
|
)
|
||||||
|
ksks = [k for k in keys if k.is_ksk()]
|
||||||
|
zsks = [k for k in keys if not k.is_ksk()]
|
||||||
|
|
||||||
|
isctest.kasp.check_keys(zone, keys, expected)
|
||||||
|
|
||||||
|
offset = params["offset"] if "offset" in params else None
|
||||||
|
|
||||||
|
for kp in expected:
|
||||||
|
kp.set_expected_keytimes(
|
||||||
|
params["config"], offset=offset, pregenerated=pregenerated
|
||||||
|
)
|
||||||
|
|
||||||
|
if "rumoured" not in params:
|
||||||
|
isctest.kasp.check_keytimes(keys, expected)
|
||||||
|
|
||||||
|
check_all(server, zone, policy, ksks, zsks, zsk_missing=zsk_missing)
|
||||||
|
|
||||||
|
if "additional-tests" in params:
|
||||||
|
params["servers"] = servers
|
||||||
|
for additional_test in params["additional-tests"]:
|
||||||
|
callback = additional_test["callback"]
|
||||||
|
arguments = additional_test["arguments"]
|
||||||
|
callback(*arguments, params=params, ksks=ksks, zsks=zsks)
|
||||||
|
|
||||||
|
|
||||||
def test_kasp_default(servers):
|
def test_kasp_default(servers):
|
||||||
server = servers["ns3"]
|
server = servers["ns3"]
|
||||||
|
|
||||||
@@ -404,11 +986,6 @@ def test_kasp_dnssec_keygen():
|
|||||||
return isctest.run.cmd(keygen_command, log_stdout=True).stdout.decode("utf-8")
|
return isctest.run.cmd(keygen_command, log_stdout=True).stdout.decode("utf-8")
|
||||||
|
|
||||||
# check that 'dnssec-keygen -k' (configured policy) creates valid files.
|
# check that 'dnssec-keygen -k' (configured policy) creates valid files.
|
||||||
lifetime = {
|
|
||||||
"P1Y": int(timedelta(days=365).total_seconds()),
|
|
||||||
"P30D": int(timedelta(days=30).total_seconds()),
|
|
||||||
"P6M": int(timedelta(days=31 * 6).total_seconds()),
|
|
||||||
}
|
|
||||||
keyprops = [
|
keyprops = [
|
||||||
f"csk {lifetime['P1Y']} 13 256",
|
f"csk {lifetime['P1Y']} 13 256",
|
||||||
f"ksk {lifetime['P1Y']} 8 2048",
|
f"ksk {lifetime['P1Y']} 8 2048",
|
||||||
|
@@ -673,9 +673,9 @@ def test_ksr_common(servers):
|
|||||||
# - check keys
|
# - check keys
|
||||||
check_keys(overlapping_zsks, lifetime, with_state=True)
|
check_keys(overlapping_zsks, lifetime, with_state=True)
|
||||||
# - check apex
|
# - check apex
|
||||||
isctest.kasp.check_apex(ns1, zone, ksks, overlapping_zsks)
|
isctest.kasp.check_apex(ns1, zone, ksks, overlapping_zsks, offline_ksk=True)
|
||||||
# - check subdomain
|
# - check subdomain
|
||||||
isctest.kasp.check_subdomain(ns1, zone, ksks, overlapping_zsks)
|
isctest.kasp.check_subdomain(ns1, zone, ksks, overlapping_zsks, offline_ksk=True)
|
||||||
|
|
||||||
|
|
||||||
def test_ksr_lastbundle(servers):
|
def test_ksr_lastbundle(servers):
|
||||||
@@ -748,9 +748,9 @@ def test_ksr_lastbundle(servers):
|
|||||||
# - check keys
|
# - check keys
|
||||||
check_keys(zsks, lifetime, offset=offset, with_state=True)
|
check_keys(zsks, lifetime, offset=offset, with_state=True)
|
||||||
# - check apex
|
# - check apex
|
||||||
isctest.kasp.check_apex(ns1, zone, ksks, zsks)
|
isctest.kasp.check_apex(ns1, zone, ksks, zsks, offline_ksk=True)
|
||||||
# - check subdomain
|
# - check subdomain
|
||||||
isctest.kasp.check_subdomain(ns1, zone, ksks, zsks)
|
isctest.kasp.check_subdomain(ns1, zone, ksks, zsks, offline_ksk=True)
|
||||||
|
|
||||||
# check that last bundle warning is logged
|
# check that last bundle warning is logged
|
||||||
warning = "last bundle in skr, please import new skr file"
|
warning = "last bundle in skr, please import new skr file"
|
||||||
@@ -828,9 +828,9 @@ def test_ksr_inthemiddle(servers):
|
|||||||
# - check keys
|
# - check keys
|
||||||
check_keys(zsks, lifetime, offset=offset, with_state=True)
|
check_keys(zsks, lifetime, offset=offset, with_state=True)
|
||||||
# - check apex
|
# - check apex
|
||||||
isctest.kasp.check_apex(ns1, zone, ksks, zsks)
|
isctest.kasp.check_apex(ns1, zone, ksks, zsks, offline_ksk=True)
|
||||||
# - check subdomain
|
# - check subdomain
|
||||||
isctest.kasp.check_subdomain(ns1, zone, ksks, zsks)
|
isctest.kasp.check_subdomain(ns1, zone, ksks, zsks, offline_ksk=True)
|
||||||
|
|
||||||
# check that no last bundle warning is logged
|
# check that no last bundle warning is logged
|
||||||
warning = "last bundle in skr, please import new skr file"
|
warning = "last bundle in skr, please import new skr file"
|
||||||
@@ -1023,9 +1023,9 @@ def test_ksr_unlimited(servers):
|
|||||||
# - check keys
|
# - check keys
|
||||||
check_keys(zsks, lifetime, with_state=True)
|
check_keys(zsks, lifetime, with_state=True)
|
||||||
# - check apex
|
# - check apex
|
||||||
isctest.kasp.check_apex(ns1, zone, ksks, zsks)
|
isctest.kasp.check_apex(ns1, zone, ksks, zsks, offline_ksk=True)
|
||||||
# - check subdomain
|
# - check subdomain
|
||||||
isctest.kasp.check_subdomain(ns1, zone, ksks, zsks)
|
isctest.kasp.check_subdomain(ns1, zone, ksks, zsks, offline_ksk=True)
|
||||||
|
|
||||||
|
|
||||||
def test_ksr_twotone(servers):
|
def test_ksr_twotone(servers):
|
||||||
@@ -1141,9 +1141,9 @@ def test_ksr_twotone(servers):
|
|||||||
lifetime = timedelta(days=31 * 5)
|
lifetime = timedelta(days=31 * 5)
|
||||||
check_keys(zsks_altalg, lifetime, alg, size, with_state=True)
|
check_keys(zsks_altalg, lifetime, alg, size, with_state=True)
|
||||||
# - check apex
|
# - check apex
|
||||||
isctest.kasp.check_apex(ns1, zone, ksks, zsks)
|
isctest.kasp.check_apex(ns1, zone, ksks, zsks, offline_ksk=True)
|
||||||
# - check subdomain
|
# - check subdomain
|
||||||
isctest.kasp.check_subdomain(ns1, zone, ksks, zsks)
|
isctest.kasp.check_subdomain(ns1, zone, ksks, zsks, offline_ksk=True)
|
||||||
|
|
||||||
|
|
||||||
def test_ksr_kskroll(servers):
|
def test_ksr_kskroll(servers):
|
||||||
@@ -1215,6 +1215,6 @@ def test_ksr_kskroll(servers):
|
|||||||
# - check keys
|
# - check keys
|
||||||
check_keys(zsks, None, with_state=True)
|
check_keys(zsks, None, with_state=True)
|
||||||
# - check apex
|
# - check apex
|
||||||
isctest.kasp.check_apex(ns1, zone, ksks, zsks)
|
isctest.kasp.check_apex(ns1, zone, ksks, zsks, offline_ksk=True)
|
||||||
# - check subdomain
|
# - check subdomain
|
||||||
isctest.kasp.check_subdomain(ns1, zone, ksks, zsks)
|
isctest.kasp.check_subdomain(ns1, zone, ksks, zsks, offline_ksk=True)
|
||||||
|
Reference in New Issue
Block a user