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 subprocess
|
||||
import time
|
||||
from typing import Dict, List, Optional, Union
|
||||
from typing import Dict, List, Optional, Tuple, Union
|
||||
|
||||
from datetime import datetime, timedelta, timezone
|
||||
|
||||
@@ -332,6 +332,55 @@ class Key:
|
||||
)
|
||||
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:
|
||||
with open(self.keyfile, "r", encoding="utf-8") as 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
|
||||
|
||||
|
||||
def _check_signatures(signatures, covers, fqdn, keys):
|
||||
now = KeyTimingMetadata.now()
|
||||
def _check_signatures(
|
||||
signatures, covers, fqdn, keys, offline_ksk=False, zsk_missing=False
|
||||
):
|
||||
numsigs = 0
|
||||
zrrsig = True
|
||||
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
|
||||
|
||||
for key in keys:
|
||||
activate = key.get_timing("Activate")
|
||||
inactive = key.get_timing("Inactive", must_exist=False)
|
||||
ksigning, zsigning = key.get_signing_state(
|
||||
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")
|
||||
rtype = dns.rdatatype.to_text(covers)
|
||||
|
||||
expect = rf"IN RRSIG {rtype} {alg} (\d) (\d+) (\d+) (\d+) {key.tag} {fqdn}"
|
||||
|
||||
if not signing:
|
||||
for rrsig in signatures:
|
||||
assert re.search(expect, rrsig) is None
|
||||
continue
|
||||
|
||||
if zrrsig and key.is_zsk():
|
||||
if zrrsig and zsigning:
|
||||
has_rrsig = False
|
||||
for rrsig in signatures:
|
||||
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}"
|
||||
numsigs += 1
|
||||
|
||||
if zrrsig and not key.is_zsk():
|
||||
if zrrsig and not zsigning:
|
||||
for rrsig in signatures:
|
||||
assert re.search(expect, rrsig) is None
|
||||
|
||||
if krrsig and key.is_ksk():
|
||||
if krrsig and ksigning:
|
||||
has_rrsig = False
|
||||
for rrsig in signatures:
|
||||
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}"
|
||||
numsigs += 1
|
||||
|
||||
if krrsig and not key.is_ksk():
|
||||
if krrsig and not ksigning:
|
||||
for rrsig in signatures:
|
||||
assert re.search(expect, rrsig) is None
|
||||
|
||||
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.
|
||||
# The right keys are the ones that expect a signature and have the
|
||||
# correct role.
|
||||
@@ -840,8 +885,12 @@ def check_signatures(rrset, covers, fqdn, ksks, zsks):
|
||||
rrsig = f"{rr.name} {rr.ttl} {rdclass} {rdtype} {rdata}"
|
||||
signatures.append(rrsig)
|
||||
|
||||
numsigs += _check_signatures(signatures, covers, fqdn, ksks)
|
||||
numsigs += _check_signatures(signatures, covers, fqdn, zsks)
|
||||
numsigs += _check_signatures(
|
||||
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)
|
||||
|
||||
@@ -965,7 +1014,9 @@ def _query_rrset(server, fqdn, qtype, tsig=None):
|
||||
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
|
||||
# are signed correctly and with the appropriate keys.
|
||||
fqdn = f"{zone}."
|
||||
@@ -973,30 +1024,44 @@ def check_apex(server, zone, ksks, zsks, tsig=None):
|
||||
# test dnskey query
|
||||
dnskeys, rrsigs = _query_rrset(server, fqdn, dns.rdatatype.DNSKEY, tsig=tsig)
|
||||
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
|
||||
soa, rrsigs = _query_rrset(server, fqdn, dns.rdatatype.SOA, tsig=tsig)
|
||||
assert len(soa) == 1
|
||||
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
|
||||
cdnskeys, rrsigs = _query_rrset(server, fqdn, dns.rdatatype.CDNSKEY, tsig=tsig)
|
||||
check_dnskeys(cdnskeys, ksks, zsks, cdnskey=True)
|
||||
if len(cdnskeys) > 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
|
||||
cds, rrsigs = _query_rrset(server, fqdn, dns.rdatatype.CDS, tsig=tsig)
|
||||
check_cds(cds, ksks)
|
||||
if len(cds) > 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.
|
||||
fqdn = f"{zone}."
|
||||
qname = f"a.{zone}."
|
||||
@@ -1014,7 +1079,7 @@ def check_subdomain(server, zone, ksks, zsks, tsig=None):
|
||||
else:
|
||||
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):
|
||||
@@ -1046,6 +1111,98 @@ def verify_update_is_signed(server, fqdn, qname, qtype, rdata, ksks, zsks, tsig=
|
||||
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):
|
||||
if next_event is None:
|
||||
# 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:
|
||||
- "goal", "dnskey", "krrsig", "zrrsig", "ds", followed by a 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
|
||||
"""
|
||||
proplist = []
|
||||
@@ -1190,6 +1348,8 @@ def policy_to_properties(ttl, keys: List[str]) -> List[KeyProperties]:
|
||||
elif line[i].startswith("offset:"):
|
||||
keyval = line[i].split(":")
|
||||
keyprop.properties["offset"] = timedelta(seconds=int(keyval[1]))
|
||||
elif line[i] == "missing":
|
||||
keyprop.properties["private"] = False
|
||||
else:
|
||||
assert False, f"undefined optional data {line[i]}"
|
||||
|
||||
|
@@ -56,6 +56,12 @@ def with_tsan(*args): # pylint: disable=unused-argument
|
||||
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(
|
||||
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"
|
||||
$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.
|
||||
setup expired-sigs.autosign
|
||||
T="now-6mo"
|
||||
ksktimes="-P $T -A $T -P sync $T"
|
||||
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)
|
||||
KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 300 -f KSK $keytimes $zone 2>keygen.out.$zone.1)
|
||||
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 -k $O $T -z $O $T "$ZSK" >settime.out.$zone.2 2>&1
|
||||
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.
|
||||
setup dnskey-ttl-mismatch.autosign
|
||||
KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 30 -f KSK $ksktimes $zone 2>keygen.out.$zone.1)
|
||||
ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 30 $zsktimes $zone 2>keygen.out.$zone.2)
|
||||
KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 30 -f KSK $keytimes $zone 2>keygen.out.$zone.1)
|
||||
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"
|
||||
cp $infile $zonefile
|
||||
$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.
|
||||
setup fresh-sigs.autosign
|
||||
T="now-6mo"
|
||||
ksktimes="-P $T -A $T -P sync $T"
|
||||
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)
|
||||
KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 300 -f KSK $keytimes $zone 2>keygen.out.$zone.1)
|
||||
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 -k $O $T -z $O $T "$ZSK" >settime.out.$zone.2 2>&1
|
||||
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.
|
||||
setup unfresh-sigs.autosign
|
||||
T="now-6mo"
|
||||
ksktimes="-P $T -A $T -P sync $T"
|
||||
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)
|
||||
KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 300 -f KSK $keytimes $zone 2>keygen.out.$zone.1)
|
||||
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 -k $O $T -z $O $T "$ZSK" >settime.out.$zone.2 2>&1
|
||||
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.
|
||||
setup ksk-missing.autosign
|
||||
T="now-6mo"
|
||||
ksktimes="-P $T -A $T -P sync $T"
|
||||
zsktimes="-P $T -A $T"
|
||||
# KSK file will be gone missing, so we set expected times during setup.
|
||||
TI="now+550d" # Lifetime of 2 years minus 6 months equals 550 days
|
||||
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)
|
||||
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 -k $O $T -z $O $T "$ZSK" >settime.out.$zone.2 2>&1
|
||||
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.
|
||||
setup zsk-missing.autosign
|
||||
T="now-6mo"
|
||||
ksktimes="-P $T -A $T -P sync $T"
|
||||
zsktimes="-P $T -A $T"
|
||||
KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 300 -f KSK $ksktimes $zone 2>keygen.out.$zone.1)
|
||||
# ZSK file will be gone missing, so we set expected times during setup.
|
||||
TI="now+185d" # Lifetime of 1 year minus 6 months equals 185 days
|
||||
TD="now+277985mi" # 185 days plus retire time (sign delay, retire safety, propagation, zone TTL)
|
||||
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)
|
||||
$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
|
||||
@@ -294,11 +294,8 @@ rm -f "${ZSK}".private
|
||||
# These signatures are still good, but the key files will be removed
|
||||
# before a second run of reconfiguring keys.
|
||||
setup keyfiles-missing.autosign
|
||||
T="now-6mo"
|
||||
ksktimes="-P $T -A $T -P sync $T"
|
||||
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)
|
||||
KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 300 -f KSK $keytimes $zone 2>keygen.out.$zone.1)
|
||||
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 -k $O $T -z $O $T "$ZSK" >settime.out.$zone.2 2>&1
|
||||
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.
|
||||
setup zsk-retired.autosign
|
||||
T="now-6mo"
|
||||
ksktimes="-P $T -A $T -P sync $T"
|
||||
zsktimes="-P $T -A $T -I now"
|
||||
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
|
||||
}
|
||||
|
||||
#
|
||||
# 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:
|
||||
# - configuring a zone with too many active keys (should trigger retire).
|
||||
# - 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_keytimes_autosign_policy() {
|
||||
# The KSK was published six months ago (with settime).
|
||||
@@ -889,256 +437,39 @@ set_keytimes_autosign_policy() {
|
||||
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.
|
||||
#
|
||||
set_zone "zsk-retired.autosign"
|
||||
set_policy "autosign" "3" "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"
|
||||
# The third key is not yet expected to be signing.
|
||||
set_keyrole "KEY3" "zsk"
|
||||
set_keylifetime "KEY3" "31536000"
|
||||
@@ -1185,7 +516,7 @@ check_keytimes
|
||||
check_apex
|
||||
check_subdomain
|
||||
dnssec_verify
|
||||
check_rrsig_refresh
|
||||
#check_rrsig_refresh
|
||||
|
||||
# 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)"
|
||||
@@ -1196,164 +527,6 @@ grep "zone $ZONE/IN (signed): zone_rekey:zone_verifykeys failed: some key files
|
||||
test "$ret" -eq 0 || echo_i "failed"
|
||||
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.
|
||||
#
|
||||
|
@@ -21,6 +21,7 @@ import pytest
|
||||
|
||||
pytest.importorskip("dns", minversion="2.0.0")
|
||||
import isctest
|
||||
import isctest.mark
|
||||
from isctest.kasp import (
|
||||
KeyProperties,
|
||||
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_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_dnssec_verify(server, zone)
|
||||
isctest.kasp.check_dnssec_verify(server, zone, tsig=tsig)
|
||||
|
||||
|
||||
def set_keytimes_default_policy(kp):
|
||||
@@ -103,6 +169,522 @@ def set_keytimes_default_policy(kp):
|
||||
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):
|
||||
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")
|
||||
|
||||
# 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 = [
|
||||
f"csk {lifetime['P1Y']} 13 256",
|
||||
f"ksk {lifetime['P1Y']} 8 2048",
|
||||
|
@@ -673,9 +673,9 @@ def test_ksr_common(servers):
|
||||
# - check keys
|
||||
check_keys(overlapping_zsks, lifetime, with_state=True)
|
||||
# - 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
|
||||
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):
|
||||
@@ -748,9 +748,9 @@ def test_ksr_lastbundle(servers):
|
||||
# - check keys
|
||||
check_keys(zsks, lifetime, offset=offset, with_state=True)
|
||||
# - check apex
|
||||
isctest.kasp.check_apex(ns1, zone, ksks, zsks)
|
||||
isctest.kasp.check_apex(ns1, zone, ksks, zsks, offline_ksk=True)
|
||||
# - 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
|
||||
warning = "last bundle in skr, please import new skr file"
|
||||
@@ -828,9 +828,9 @@ def test_ksr_inthemiddle(servers):
|
||||
# - check keys
|
||||
check_keys(zsks, lifetime, offset=offset, with_state=True)
|
||||
# - check apex
|
||||
isctest.kasp.check_apex(ns1, zone, ksks, zsks)
|
||||
isctest.kasp.check_apex(ns1, zone, ksks, zsks, offline_ksk=True)
|
||||
# - 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
|
||||
warning = "last bundle in skr, please import new skr file"
|
||||
@@ -1023,9 +1023,9 @@ def test_ksr_unlimited(servers):
|
||||
# - check keys
|
||||
check_keys(zsks, lifetime, with_state=True)
|
||||
# - check apex
|
||||
isctest.kasp.check_apex(ns1, zone, ksks, zsks)
|
||||
isctest.kasp.check_apex(ns1, zone, ksks, zsks, offline_ksk=True)
|
||||
# - 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):
|
||||
@@ -1141,9 +1141,9 @@ def test_ksr_twotone(servers):
|
||||
lifetime = timedelta(days=31 * 5)
|
||||
check_keys(zsks_altalg, lifetime, alg, size, with_state=True)
|
||||
# - check apex
|
||||
isctest.kasp.check_apex(ns1, zone, ksks, zsks)
|
||||
isctest.kasp.check_apex(ns1, zone, ksks, zsks, offline_ksk=True)
|
||||
# - 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):
|
||||
@@ -1215,6 +1215,6 @@ def test_ksr_kskroll(servers):
|
||||
# - check keys
|
||||
check_keys(zsks, None, with_state=True)
|
||||
# - check apex
|
||||
isctest.kasp.check_apex(ns1, zone, ksks, zsks)
|
||||
isctest.kasp.check_apex(ns1, zone, ksks, zsks, offline_ksk=True)
|
||||
# - 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