self.keyfile = f"{self.path}.key"
self.statefile = f"{self.path}.state"
self.tag = int(self.name[-5:])
+ self.external = False
def get_timing(
self, metadata: str, must_exist: bool = True
if not self.is_metadata_consistent(key, properties.metadata):
return False
+ # Check tag range.
+ if "keytag-min" in properties.properties:
+ if self.tag < properties.properties["keytag-min"]:
+ return False
+ if "keytag-max" in properties.properties:
+ if self.tag > properties.properties["keytag-max"]:
+ return False
+
# A match is found.
return True
assert f"dnssec-policy: {policy}" in response
for key in keys:
- assert f"key: {key.tag}" in response
+ if not key.external:
+ assert f"key: {key.tag}" in response
def _check_signatures(
krrsig = not zrrsig
for key in keys:
+ if key.external:
+ continue
+
ksigning, zsigning = key.get_signing_state(
offline_ksk=offline_ksk, zsk_missing=zsk_missing
)
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
+ - "tag-range", followed by <min>-<max> to test key tag ranges
"""
proplist = []
count = 0
elif line[i].startswith("offset:"):
keyval = line[i].split(":")
keyprop.properties["offset"] = timedelta(seconds=int(keyval[1]))
+ elif line[i].startswith("tag-range:"):
+ keyval = line[i].split(":")
+ tagrange = keyval[1].split("-")
+ keyprop.properties["keytag-min"] = int(tagrange[0])
+ keyprop.properties["keytag-max"] = int(tagrange[1])
elif line[i] == "missing":
keyprop.properties["private"] = False
else:
dnssec-policy "rsasha256";
};
-/* RFC 8901 Multi-signer Model 2. */
-zone "multisigner-model2.kasp" {
- type primary;
- file "multisigner-model2.kasp.db";
- dnssec-policy "multisigner-model2";
- allow-update { any; };
-};
-
-/*
- * A zone that starts with keys that have tags that are
- * outside of the desired multi-signer key tag range.
- */
-zone "single-to-multisigner.kasp" {
- type primary;
- file "single-to-multisigner.kasp.db";
- dnssec-policy "multisigner-model2";
- allow-update { any; };
-};
-
/*
* Different algorithms.
*/
inline-signing no;
};
-dnssec-policy "multisigner-model2" {
- dnskey-ttl 3600;
- inline-signing no;
-
- keys {
- ksk key-directory lifetime unlimited algorithm @DEFAULT_ALGORITHM@ tag-range 32768 65535;
- zsk key-directory lifetime unlimited algorithm @DEFAULT_ALGORITHM@ tag-range 32768 65535;
- };
-};
-
dnssec-policy "migrate-to-dnssec-policy" {
dnskey-ttl 1234;
rumoured rsasha256 rsasha512 ecdsa256 ecdsa384 \
dynamic dynamic-inline-signing inline-signing \
checkds-ksk checkds-doubleksk checkds-csk inherit unlimited \
- multisigner-model2 keystore; do
+ keystore; do
setup "${zn}.kasp"
cp template.db.in "$zonefile"
done
$KEYGEN -G -k rsasha256 -l policies/kasp.conf $zone >keygen.out.$zone.1 2>&1
$KEYGEN -G -k rsasha256 -l policies/kasp.conf $zone >keygen.out.$zone.2 2>&1
-zone="multisigner-model2.kasp"
-echo_i "setting up zone: $zone"
-KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -f KSK -L 3600 -M 32768:65535 $zone 2>keygen.out.$zone.1)
-ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -M 32768:65535 $zone 2>keygen.out.$zone.2)
-cat "${KSK}.key" | grep -v ";.*" >>"${zone}.db"
-cat "${ZSK}.key" | grep -v ";.*" >>"${zone}.db"
-# Import the ZSK sets of the other providers into their DNSKEY RRset.
-# ZSK1 is from a different provider and is added to the unsigned zonefile.
-# ZSK2 is also from a different provider and is added with a Dynamic Update.
-ZSK1=$($KEYGEN -K ../ -a $DEFAULT_ALGORITHM -L 3600 -M 0:32767 $zone 2>keygen.out.$zone.3)
-ZSK2=$($KEYGEN -K ../ -a $DEFAULT_ALGORITHM -L 3600 -M 0:32767 $zone 2>keygen.out.$zone.4)
-cat "../${ZSK1}.key" | grep -v ";.*" >>"${zone}.db"
-cat "../${ZSK1}.key" | grep -v ";.*" >"${zone}.zsk1"
-cat "../${ZSK2}.key" | grep -v ";.*" >"${zone}.zsk2"
-rm -f "../${ZSK1}.*"
-rm -f "../${ZSK2}.*"
-
zone="rumoured.kasp"
echo_i "setting up zone: $zone"
Tpub="now"
cp $infile $zonefile
$SIGNER -PS -K keys -z -x -s now-2w -e now-1mi -o $zone -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
-# We are changing an existing single-signed zone to multi-signed
-# zone where the key tags do not match the dnssec-policy key tag range
-setup single-to-multisigner.kasp
-T="now-1d"
-KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -M 0:32767 -L 3600 -f KSK $ksktimes $zone 2>keygen.out.$zone.1)
-ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -M 0:32767 -L 3600 $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
-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"
set_addkeytime "KEY2" "REMOVED" "${retired}" 695100
}
-#
-# Testing RFC 8901 Multi-Signer Model 2.
-#
-set_zone "multisigner-model2.kasp"
-set_policy "multisigner-model2" "2" "3600"
-set_server "ns3" "10.53.0.3"
-key_clear "KEY1"
-key_clear "KEY2"
-key_clear "KEY3"
-key_clear "KEY4"
-
-# Key properties.
-set_keyrole "KEY1" "ksk"
-set_keylifetime "KEY1" "0"
-set_keyalgorithm "KEY1" "$DEFAULT_ALGORITHM_NUMBER" "$DEFAULT_ALGORITHM" "$DEFAULT_BITS"
-set_keysigning "KEY1" "yes"
-set_zonesigning "KEY1" "no"
-
-set_keyrole "KEY2" "zsk"
-set_keylifetime "KEY2" "0"
-set_keyalgorithm "KEY2" "$DEFAULT_ALGORITHM_NUMBER" "$DEFAULT_ALGORITHM" "$DEFAULT_BITS"
-set_keysigning "KEY2" "no"
-set_zonesigning "KEY2" "yes"
-
-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"
-
-check_keys
-check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
-check_apex
-check_subdomain
-dnssec_verify
-
-# Check that the ZSKs from the other providers are published.
-zsks_are_published() {
- num=$1
- dig_with_opts +short "$ZONE" "@${SERVER}" DNSKEY >"dig.out.$DIR.test$n" || return 1
- # We should have three ZSKs.
- lines=$(grep "256 3 13" dig.out.$DIR.test$n | wc -l)
- test "$lines" -eq $num || return 1
- # And one KSK.
- lines=$(grep "257 3 13" dig.out.$DIR.test$n | wc -l)
- test "$lines" -eq 1 || return 1
-}
-n=$((n + 1))
-echo_i "check initial number of ZSKs (one from us and one from another provider) for zone ${ZONE} ($n)"
-ret=0
-retry_quiet 10 zsks_are_published 2 || ret=1
-test "$ret" -eq 0 || echo_i "failed"
-status=$((status + ret))
-
-n=$((n + 1))
-echo_i "update zone with ZSK from another provider for zone ${ZONE} ($n)"
-ret=0
-(
- echo zone ${ZONE}
- echo server 10.53.0.3 "$PORT"
- echo update add $(cat "${DIR}/${ZONE}.zsk2")
- echo send
-) | $NSUPDATE
-retry_quiet 10 zsks_are_published 3 || ret=1
-test "$ret" -eq 0 || echo_i "failed"
-status=$((status + ret))
-
-n=$((n + 1))
-echo_i "remove ZSKs from the other providers for zone ${ZONE} ($n)"
-ret=0
-(
- echo zone ${ZONE}
- echo server 10.53.0.3 "$PORT"
- echo update del $(cat "${DIR}/${ZONE}.zsk1")
- echo update del $(cat "${DIR}/${ZONE}.zsk2")
- echo send
-) | $NSUPDATE
-retry_quiet 10 zsks_are_published 1 || ret=1
-test "$ret" -eq 0 || echo_i "failed"
-status=$((status + ret))
-
-#
-# A zone transitioning from single-signed to multi-signed.
-# We should have the old omnipresent keys outside of the
-# desired key range and the new keys in the desired key range
-# KEY1 and KEY2 are the new keys. KEY3 and KEY4 are the old keys.
-#
-set_zone "single-to-multisigner.kasp"
-set_policy "multisigner-model2" "4" "3600"
-set_server "ns3" "10.53.0.3"
-key_clear "KEY1"
-key_clear "KEY2"
-key_clear "KEY3"
-key_clear "KEY4"
-
-# Key properties.
-set_keyrole "KEY1" "ksk"
-set_keylifetime "KEY1" "0"
-set_keyalgorithm "KEY1" "$DEFAULT_ALGORITHM_NUMBER" "$DEFAULT_ALGORITHM" "$DEFAULT_BITS"
-set_keysigning "KEY1" "yes"
-set_zonesigning "KEY1" "no"
-
-set_keyrole "KEY2" "zsk"
-set_keylifetime "KEY2" "0"
-set_keyalgorithm "KEY2" "$DEFAULT_ALGORITHM_NUMBER" "$DEFAULT_ALGORITHM" "$DEFAULT_BITS"
-set_keysigning "KEY2" "no"
-set_zonesigning "KEY2" "no" # waiting for DNSKEY to be omnipresent
-
-set_keyrole "KEY3" "ksk"
-set_keyalgorithm "KEY3" "$DEFAULT_ALGORITHM_NUMBER" "$DEFAULT_ALGORITHM" "$DEFAULT_BITS"
-set_keysigning "KEY3" "yes"
-set_zonesigning "KEY3" "no"
-
-set_keyrole "KEY4" "zsk"
-set_keyalgorithm "KEY4" "$DEFAULT_ALGORITHM_NUMBER" "$DEFAULT_ALGORITHM" "$DEFAULT_BITS"
-set_keysigning "KEY4" "no"
-set_zonesigning "KEY4" "yes"
-
-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" "hidden" # waiting for DNSKEY to be omnipresent
-
-set_keystate "KEY3" "GOAL" "hidden"
-set_keystate "KEY3" "STATE_DNSKEY" "omnipresent"
-set_keystate "KEY3" "STATE_KRRSIG" "omnipresent"
-set_keystate "KEY3" "STATE_DS" "omnipresent"
-
-set_keystate "KEY4" "GOAL" "hidden"
-set_keystate "KEY4" "STATE_DNSKEY" "omnipresent"
-set_keystate "KEY4" "STATE_ZRRSIG" "omnipresent"
-
-check_keys
-check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
-check_apex
-check_subdomain
-dnssec_verify
-
-# KEY1 tag range 32768 65535
-# KEY2 tag range 32768 65535
-# KEY3 tag range 0 32767
-# KEY4 tag range 0 32767
-n=$((n + 1))
-echo_i "check that the key IDs are in the expected ranges ($n)"
-ret=0
-test $(key_get KEY1 ID) -ge 32768 -a $(key_get KEY1 ID) -le 65535 || ret=1
-test $(key_get KEY2 ID) -ge 32768 -a $(key_get KEY2 ID) -le 65535 || ret=1
-test $(key_get KEY3 ID) -ge 0 -a $(key_get KEY3 ID) -le 32767 || ret=1
-test $(key_get KEY4 ID) -ge 0 -a $(key_get KEY4 ID) -le 32767 || ret=1
-
-test $(key_get KEY1 RID) -ge 32768 -a $(key_get KEY1 RID) -le 65535 || ret=1
-test $(key_get KEY2 RID) -ge 32768 -a $(key_get KEY2 RID) -le 65535 || ret=1
-test $(key_get KEY3 RID) -ge 0 -a $(key_get KEY3 RID) -le 32767 || ret=1
-test $(key_get KEY4 RID) -ge 0 -a $(key_get KEY4 RID) -le 32767 || ret=1
-test "$ret" -eq 0 || echo_i "failed"
-status=$((status + ret))
-
#
# Testing DNSSEC introduction.
#
zsk key-directory lifetime unlimited algorithm @DEFAULT_ALGORITHM@;
};
};
+
+dnssec-policy "multisigner-model2" {
+ dnskey-ttl 3600;
+ inline-signing no;
+
+ keys {
+ ksk key-directory lifetime unlimited algorithm @DEFAULT_ALGORITHM@ tag-range 32768 65535;
+ zsk key-directory lifetime unlimited algorithm @DEFAULT_ALGORITHM@ tag-range 32768 65535;
+ };
+};
file "manual-rollover.kasp.db";
dnssec-policy "manual-rollover";
};
+
+/* RFC 8901 Multi-signer Model 2. */
+zone "multisigner-model2.kasp" {
+ type primary;
+ file "multisigner-model2.kasp.db";
+ dnssec-policy "multisigner-model2";
+ allow-update { any; };
+};
+
+/*
+ * A zone that starts with keys that have tags that are
+ * outside of the desired multi-signer key tag range.
+ */
+zone "single-to-multisigner.kasp" {
+ type primary;
+ file "single-to-multisigner.kasp.db";
+ dnssec-policy "multisigner-model2";
+ allow-update { any; };
+};
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile"
cp $infile $zonefile
$SIGNER -PS -x -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
+
+# Multi-signer zones.
+setup "multisigner-model2.kasp"
+cp template.db.in "$zonefile"
+KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -f KSK -L 3600 -M 32768:65535 $zone 2>keygen.out.$zone.1)
+ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -M 32768:65535 $zone 2>keygen.out.$zone.2)
+cat "${KSK}.key" | grep -v ";.*" >>"${zone}.db"
+cat "${ZSK}.key" | grep -v ";.*" >>"${zone}.db"
+# Import a ZSK of another provider into the DNSKEY RRset.
+ZSK1=$($KEYGEN -K ../ -a $DEFAULT_ALGORITHM -L 3600 -M 0:32767 $zone 2>keygen.out.$zone.3)
+cat "../${ZSK1}.key" | grep -v ";.*" >>"${zone}.db"
+
+# We are changing an existing single-signed zone to multi-signed
+# zone where the key tags do not match the dnssec-policy key tag range
+setup single-to-multisigner.kasp
+T="now-7d"
+S="now-8635mi" # T - 1d5m
+keytimes="-P $T -A $T"
+cdstimes="-P sync $S"
+KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -M 0:32767 -L 3600 -f KSK $keytimes $cdstimes $zone 2>keygen.out.$zone.1)
+ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -M 0:32767 -L 3600 $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"
+$SIGNER -PS -z -x -s now-2w -e now-1mi -o $zone -f "${zonefile}" $infile >signer.out.$zone.1 2>&1
+echo "Lifetime: 0" >>"${KSK}".state
+echo "Lifetime: 0" >>"${ZSK}".state
[
"*.axfr*",
"dig.out*",
+ "K*.key*",
+ "K*.private*",
"ns*/*.db",
"ns*/*.db.infile",
+ "ns*/*.db.jnl",
"ns*/*.db.jbk",
"ns*/*.db.signed",
"ns*/*.db.signed.jnl",
zsk = expected[3].key
response = server.rndc(f"dnssec -rollover -key {zsk.tag} {zone}")
assert "key is not actively signing" in response
+
+
+def test_rollover_multisigner(servers):
+ server = servers["ns3"]
+ policy = "multisigner-model2"
+ config = {
+ "dnskey-ttl": timedelta(hours=1),
+ "ds-ttl": timedelta(days=1),
+ "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),
+ }
+ ttl = int(config["dnskey-ttl"].total_seconds())
+ alg = os.environ["DEFAULT_ALGORITHM_NUMBER"]
+ size = os.environ["DEFAULT_BITS"]
+
+ offset = -timedelta(days=7)
+ offval = int(offset.total_seconds())
+
+ def keygen(zone):
+ keygen_command = [
+ os.environ.get("KEYGEN"),
+ "-a",
+ alg,
+ "-L",
+ "3600",
+ "-M",
+ "0:32767",
+ zone,
+ ]
+
+ return isctest.run.cmd(keygen_command, log_stdout=True).stdout.decode("utf-8")
+
+ def nsupdate(updates):
+ message = dns.update.UpdateMessage(zone)
+ for update in updates:
+ if update[0] == 0:
+ message.delete(update[1], update[2], update[3])
+ else:
+ message.add(update[1], update[2], update[3], update[4])
+
+ try:
+ response = isctest.query.udp(
+ message, server.ip, server.ports.dns, timeout=3
+ )
+ assert response.rcode() == dns.rcode.NOERROR
+ except dns.exception.Timeout:
+ isctest.log.info(f"error: update timeout for {zone}")
+
+ zone = "multisigner-model2.kasp"
+ key_properties = [
+ f"ksk unlimited {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured ds:hidden tag-range:32768-65535",
+ f"zsk unlimited {alg} {size} goal:omnipresent dnskey:rumoured zrrsig:rumoured tag-range:32768-65535",
+ ]
+ expected = isctest.kasp.policy_to_properties(ttl, key_properties)
+
+ newprops = [f"zsk unlimited {alg} {size} tag-range:0-32767"]
+ expected2 = isctest.kasp.policy_to_properties(ttl, newprops)
+ expected2[0].properties["private"] = False
+ expected2[0].properties["legacy"] = True
+ expected = expected + expected2
+
+ ownkeys = isctest.kasp.keydir_to_keylist(zone, server.identifier)
+ extkeys = isctest.kasp.keydir_to_keylist(zone)
+ keys = ownkeys + extkeys
+ ksks = [k for k in ownkeys if k.is_ksk()]
+ zsks = [k for k in ownkeys if not k.is_ksk()]
+ zsks = zsks + extkeys
+
+ isctest.kasp.check_zone_is_signed(server, zone)
+ isctest.kasp.check_keys(zone, keys, expected)
+ for kp in expected:
+ kp.set_expected_keytimes(config)
+ isctest.kasp.check_keytimes(keys, expected)
+ isctest.kasp.check_dnssecstatus(server, zone, keys, policy=policy)
+ isctest.kasp.check_apex(server, zone, ksks, zsks)
+ isctest.kasp.check_subdomain(server, zone, ksks, zsks)
+ isctest.kasp.check_dnssec_verify(server, zone)
+
+ # Update zone with ZSK from another provider for zone.
+ out = keygen(zone)
+ newkeys = isctest.kasp.keystr_to_keylist(out)
+ newprops = [f"zsk unlimited {alg} {size} tag-range:0-32767"]
+ expected2 = isctest.kasp.policy_to_properties(ttl, newprops)
+ expected2[0].properties["private"] = False
+ expected2[0].properties["legacy"] = True
+ expected = expected + expected2
+
+ dnskey = newkeys[0].dnskey().split()
+ rdata = " ".join(dnskey[4:])
+
+ updates = [[1, f"{dnskey[0]}", 3600, "DNSKEY", rdata]]
+ nsupdate(updates)
+
+ keys = keys + newkeys
+ zsks = zsks + newkeys
+ isctest.kasp.check_keys(zone, keys, expected)
+ isctest.kasp.check_apex(server, zone, ksks, zsks)
+ isctest.kasp.check_subdomain(server, zone, ksks, zsks)
+ isctest.kasp.check_dnssec_verify(server, zone)
+
+ # Remove ZSKs from the other providers for zone.
+ dnskey2 = extkeys[0].dnskey().split()
+ rdata2 = " ".join(dnskey2[4:])
+ updates = [
+ [0, f"{dnskey[0]}", "DNSKEY", rdata],
+ [0, f"{dnskey2[0]}", "DNSKEY", rdata2],
+ ]
+ nsupdate(updates)
+
+ expected = isctest.kasp.policy_to_properties(ttl, key_properties)
+ keys = ownkeys
+ ksks = [k for k in ownkeys if k.is_ksk()]
+ zsks = [k for k in ownkeys if not k.is_ksk()]
+ isctest.kasp.check_keys(zone, keys, expected)
+ isctest.kasp.check_apex(server, zone, ksks, zsks)
+ isctest.kasp.check_subdomain(server, zone, ksks, zsks)
+ isctest.kasp.check_dnssec_verify(server, zone)
+
+ # A zone transitioning from single-signed to multi-signed. We should have
+ # the old omnipresent keys outside of the desired key range and the new
+ # keys in the desired key range.
+ zone = "single-to-multisigner.kasp"
+ key_properties = [
+ f"ksk unlimited {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured ds:hidden tag-range:32768-65535",
+ f"zsk unlimited {alg} {size} goal:omnipresent dnskey:rumoured zrrsig:hidden tag-range:32768-65535",
+ f"ksk unlimited {alg} {size} goal:hidden dnskey:omnipresent krrsig:omnipresent ds:omnipresent tag-range:0-32767 offset:{offval}",
+ f"zsk unlimited {alg} {size} goal:hidden dnskey:omnipresent zrrsig:omnipresent tag-range:0-32767 offset:{offval}",
+ ]
+ expected = isctest.kasp.policy_to_properties(ttl, key_properties)
+ keys = isctest.kasp.keydir_to_keylist(zone, server.identifier)
+ ksks = [k for k in keys if k.is_ksk()]
+ zsks = [k for k in keys if not k.is_ksk()]
+
+ isctest.kasp.check_zone_is_signed(server, zone)
+ isctest.kasp.check_keys(zone, keys, expected)
+
+ for kp in expected:
+ kp.set_expected_keytimes(config)
+
+ start = expected[0].key.get_timing("Created")
+ expected[2].timing["Retired"] = start
+ expected[2].timing["Removed"] = expected[2].timing["Retired"] + Iret(
+ config, zsk=False, ksk=True
+ )
+ expected[3].timing["Retired"] = start
+ expected[3].timing["Removed"] = expected[3].timing["Retired"] + Iret(
+ config, zsk=True, ksk=False
+ )
+
+ isctest.kasp.check_keytimes(keys, expected)
+ isctest.kasp.check_dnssecstatus(server, zone, keys, policy=policy)
+ isctest.kasp.check_apex(server, zone, ksks, zsks)
+ isctest.kasp.check_subdomain(server, zone, ksks, zsks)
+ isctest.kasp.check_dnssec_verify(server, zone)