--- /dev/null
+../rollover/common.py
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * SPDX-License-Identifier: MPL-2.0
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, you can obtain one at https://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+dnssec-policy "ksk-doubleksk" {
+ signatures-refresh P1W;
+ signatures-validity P2W;
+ signatures-validity-dnskey P2W;
+
+ dnskey-ttl 2h;
+ publish-safety P1D;
+ retire-safety P2D;
+ purge-keys PT1H;
+
+ cdnskey no;
+ keys {
+ ksk key-directory lifetime P60D algorithm @DEFAULT_ALGORITHM@;
+ zsk key-directory lifetime unlimited algorithm @DEFAULT_ALGORITHM@;
+ };
+
+ zone-propagation-delay PT1H;
+ max-zone-ttl 1d;
+
+ parent-ds-ttl 3600;
+ parent-propagation-delay PT1H;
+};
--- /dev/null
+../../rollover/ns3/named.common.conf.j2
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * SPDX-License-Identifier: MPL-2.0
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, you can obtain one at https://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+include "kasp.conf";
+include "named.common.conf";
+
+zone "step1.ksk-doubleksk.autosign" {
+ type primary;
+ file "step1.ksk-doubleksk.autosign.db";
+ dnssec-policy "ksk-doubleksk";
+};
+zone "step2.ksk-doubleksk.autosign" {
+ type primary;
+ file "step2.ksk-doubleksk.autosign.db";
+ dnssec-policy "ksk-doubleksk";
+};
+zone "step3.ksk-doubleksk.autosign" {
+ type primary;
+ file "step3.ksk-doubleksk.autosign.db";
+ dnssec-policy "ksk-doubleksk";
+};
+zone "step4.ksk-doubleksk.autosign" {
+ type primary;
+ file "step4.ksk-doubleksk.autosign.db";
+ dnssec-policy "ksk-doubleksk";
+};
+zone "step5.ksk-doubleksk.autosign" {
+ type primary;
+ file "step5.ksk-doubleksk.autosign.db";
+ dnssec-policy "ksk-doubleksk";
+};
+zone "step6.ksk-doubleksk.autosign" {
+ type primary;
+ file "step6.ksk-doubleksk.autosign.db";
+ dnssec-policy "ksk-doubleksk";
+};
--- /dev/null
+../../rollover/ns3/template.db.in
\ No newline at end of file
--- /dev/null
+#!/bin/sh -e
+
+# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+#
+# SPDX-License-Identifier: MPL-2.0
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, you can obtain one at https://mozilla.org/MPL/2.0/.
+#
+# See the COPYRIGHT file distributed with this work for additional
+# information regarding copyright ownership.
+
+# shellcheck source=conf.sh
+. ../conf.sh
+
+cd "ns3"
+
+setup() {
+ zone="$1"
+ echo_i "setting up zone: $zone"
+ zonefile="${zone}.db"
+ infile="${zone}.db.infile"
+ echo "$zone" >>zones
+}
+
+# Set in the key state files the Predecessor/Successor fields.
+# Key $1 is the predecessor of key $2.
+key_successor() {
+ id1=$(keyfile_to_key_id "$1")
+ id2=$(keyfile_to_key_id "$2")
+ echo "Predecessor: ${id1}" >>"${2}.state"
+ echo "Successor: ${id2}" >>"${1}.state"
+}
+
+# Make lines shorter by storing key states in environment variables.
+H="HIDDEN"
+R="RUMOURED"
+O="OMNIPRESENT"
+U="UNRETENTIVE"
+
+#
+# The zones at ksk-doubleksk.autosign represent the various steps of a KSK
+# Double-KSK rollover.
+#
+
+# Step 1:
+# Introduce the first key. This will immediately be active.
+setup step1.ksk-doubleksk.autosign
+TactN="now-7d"
+keytimes="-P ${TactN} -A ${TactN}"
+KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $keytimes $zone 2>keygen.out.$zone.1)
+ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 $keytimes $zone 2>keygen.out.$zone.2)
+$SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN "$KSK" >settime.out.$zone.1 2>&1
+$SETTIME -s -g $O -k $O $TactN -z $O $TactN "$ZSK" >settime.out.$zone.2 2>&1
+cat template.db.in "${KSK}.key" "${ZSK}.key" >"$infile"
+cp $infile $zonefile
+$SIGNER -S -x -G "cds:sha-256" -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
+
+# Step 2:
+# It is time to submit the introduce the new KSK.
+setup step2.ksk-doubleksk.autosign
+# Lksk: 60d
+# Dreg: n/a
+# DprpC: 1h
+# TTLds: 1d
+# TTLkey: 2h
+# publish-safety: 1d
+# retire-safety: 2d
+#
+# According to RFC 7583:
+# Tpub(N+1) <= Tact(N) + Lksk - Dreg - IpubC
+# IpubC = DprpC + TTLkey (+publish-safety)
+#
+# IpubC = 27h
+# Tact(N) = now - Lksk + Dreg + IpubC = now - 60d + 27h
+# = now - 1440h + 27h = now - 1413h
+TactN="now-1413h"
+keytimes="-P ${TactN} -A ${TactN}"
+KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $keytimes $zone 2>keygen.out.$zone.1)
+ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 $keytimes $zone 2>keygen.out.$zone.2)
+$SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN "$KSK" >settime.out.$zone.1 2>&1
+$SETTIME -s -g $O -k $O $TactN -z $O $TactN "$ZSK" >settime.out.$zone.2 2>&1
+cat template.db.in "${KSK}.key" "${ZSK}.key" >"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK" >>"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile"
+cp $infile $zonefile
+$SIGNER -S -x -G "cds:sha-256" -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
+
+# Step 3:
+# It is time to submit the DS.
+setup step3.ksk-doubleksk.autosign
+# According to RFC 7583:
+# Iret = DprpP + TTLds (+retire-safety)
+#
+# Iret = 50h
+# Tpub(N) = now - Lksk = now - 60d = now - 60d
+# Tact(N) = now - 1413h
+# Tret(N) = now
+# Trem(N) = now + Iret = now + 50h
+# Tpub(N+1) = now - IpubC = now - 27h
+# Tact(N+1) = now
+# Tret(N+1) = now + Lksk = now + 60d
+# Trem(N+1) = now + Lksk + Iret = now + 60d + 50h
+# = now + 1440h + 50h = 1490h
+TpubN="now-60d"
+TactN="now-1413h"
+TretN="now"
+TremN="now+50h"
+TpubN1="now-27h"
+TactN1="now"
+TretN1="now+60d"
+TremN1="now+1490h"
+ksktimes="-P ${TpubN} -A ${TpubN} -P sync ${TactN} -I ${TretN} -D ${TremN} -D sync ${TactN1}"
+newtimes="-P ${TpubN1} -A ${TactN1} -P sync ${TactN1} -I ${TretN1} -D ${TremN1}"
+zsktimes="-P ${TpubN} -A ${TpubN}"
+KSK1=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $ksktimes $zone 2>keygen.out.$zone.1)
+KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $newtimes $zone 2>keygen.out.$zone.2)
+ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 $zsktimes $zone 2>keygen.out.$zone.3)
+$SETTIME -s -g $H -k $O $TpubN -r $O $TpubN -d $O $TactN "$KSK1" >settime.out.$zone.1 2>&1
+$SETTIME -s -g $O -k $R $TpubN1 -r $R $TpubN1 -d $H $TpubN1 "$KSK2" >settime.out.$zone.2 2>&1
+$SETTIME -s -g $O -k $O $TpubN -z $O $TpubN "$ZSK" >settime.out.$zone.3 2>&1
+# Set key rollover relationship.
+key_successor $KSK1 $KSK2
+# Sign zone.
+cat template.db.in "${KSK1}.key" "${KSK2}.key" "${ZSK}.key" >"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK1" >>"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile"
+cp $infile $zonefile
+$SIGNER -S -x -G "cds:sha-256" -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
+
+# Step 4:
+# The DS should be swapped now.
+setup step4.ksk-doubleksk.autosign
+# Tpub(N) = now - Lksk - Iret = now - 60d - 50h
+# = now - 1440h - 50h = now - 1490h
+# Tact(N) = now - 1490h + 27h = now - 1463h
+# Tret(N) = now - Iret = now - 50h
+# Trem(N) = now
+# Tpub(N+1) = now - Iret - IpubC = now - 50h - 27h
+# = now - 77h
+# Tact(N+1) = Tret(N)
+# Tret(N+1) = now + Lksk - Iret = now + 60d - 50h = now + 1390h
+# Trem(N+1) = now + Lksk = now + 60d
+TpubN="now-1490h"
+TactN="now-1463h"
+TretN="now-50h"
+TremN="now"
+TpubN1="now-77h"
+TactN1="${TretN}"
+TretN1="now+1390h"
+TremN1="now+60d"
+ksktimes="-P ${TpubN} -A ${TpubN} -P sync ${TactN} -I ${TretN} -D ${TremN} -D sync ${TactN1}"
+newtimes="-P ${TpubN1} -A ${TactN1} -P sync ${TactN1} -I ${TretN1} -D ${TremN1}"
+zsktimes="-P ${TpubN} -A ${TpubN}"
+KSK1=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $ksktimes $zone 2>keygen.out.$zone.1)
+KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $newtimes $zone 2>keygen.out.$zone.2)
+ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 $zsktimes $zone 2>keygen.out.$zone.3)
+$SETTIME -s -g $H -k $O $TactN -r $O $TactN -d $U $TretN -D ds $TretN "$KSK1" >settime.out.$zone.1 2>&1
+$SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $R $TactN1 -P ds $TactN1 "$KSK2" >settime.out.$zone.2 2>&1
+$SETTIME -s -g $O -k $O $TactN -z $O $TactN "$ZSK" >settime.out.$zone.3 2>&1
+# Set key rollover relationship.
+key_successor $KSK1 $KSK2
+# Sign zone.
+cat template.db.in "${KSK1}.key" "${KSK2}.key" "${ZSK}.key" >"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK1" >>"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile"
+cp $infile $zonefile
+$SIGNER -S -x -G "cds:sha-256" -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
+
+# Step 5:
+# The predecessor DNSKEY is removed long enough that is has become HIDDEN.
+setup step5.ksk-doubleksk.autosign
+# Subtract DNSKEY TTL + zone-propagation-delay from all the times (3h).
+# Tpub(N) = now - 1490h - 3h = now - 1493h
+# Tact(N) = now - 1463h - 3h = now - 1466h
+# Tret(N) = now - 50h - 3h = now - 53h
+# Trem(N) = now - 3h
+# Tpub(N+1) = now - 77h - 3h = now - 80h
+# Tact(N+1) = Tret(N)
+# Tret(N+1) = now + 1390h - 3h = now + 1387h
+# Trem(N+1) = now + 60d - 3h = now + 1441h
+TpubN="now-1493h"
+TactN="now-1466h"
+TretN="now-53h"
+TremN="now-3h"
+TpubN1="now-80h"
+TactN1="${TretN}"
+TretN1="now+1387h"
+TremN1="now+1441h"
+ksktimes="-P ${TpubN} -A ${TpubN} -P sync ${TactN} -I ${TretN} -D ${TremN} -D sync ${TactN1}"
+newtimes="-P ${TpubN1} -A ${TactN1} -P sync ${TactN1} -I ${TretN1} -D ${TremN1}"
+zsktimes="-P ${TpubN} -A ${TpubN}"
+KSK1=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $ksktimes $zone 2>keygen.out.$zone.1)
+KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $newtimes $zone 2>keygen.out.$zone.2)
+ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 $zsktimes $zone 2>keygen.out.$zone.3)
+$SETTIME -s -g $H -k $U $TretN -r $U $TretN -d $H $TretN "$KSK1" >settime.out.$zone.1 2>&1
+$SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $O $TactN1 "$KSK2" >settime.out.$zone.2 2>&1
+$SETTIME -s -g $O -k $O $TactN -z $O $TactN "$ZSK" >settime.out.$zone.3 2>&1
+# Set key rollover relationship.
+key_successor $KSK1 $KSK2
+# Sign zone.
+cat template.db.in "${KSK1}.key" "${KSK2}.key" "${ZSK}.key" >"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK1" >>"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile"
+cp $infile $zonefile
+$SIGNER -S -x -G "cds:sha-256" -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
+
+# Step 6:
+# The predecessor DNSKEY can be purged.
+setup step6.ksk-doubleksk.autosign
+# Subtract purge-keys interval from all the times (1h).
+TpubN="now-1494h"
+TactN="now-1467h"
+TretN="now-54h"
+TremN="now-4h"
+TpubN1="now-81h"
+TactN1="${TretN}"
+TretN1="now+1386h"
+TremN1="now+1440h"
+ksktimes="-P ${TpubN} -A ${TpubN} -P sync ${TactN} -I ${TretN} -D ${TremN} -D sync ${TactN1}"
+newtimes="-P ${TpubN1} -A ${TactN1} -P sync ${TactN1} -I ${TretN1} -D ${TremN1}"
+zsktimes="-P ${TpubN} -A ${TpubN}"
+KSK1=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $ksktimes $zone 2>keygen.out.$zone.1)
+KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $newtimes $zone 2>keygen.out.$zone.2)
+ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 $zsktimes $zone 2>keygen.out.$zone.3)
+$SETTIME -s -g $H -k $H $TretN -r $H $TretN -d $H $TretN "$KSK1" >settime.out.$zone.1 2>&1
+$SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $O $TactN1 "$KSK2" >settime.out.$zone.2 2>&1
+$SETTIME -s -g $O -k $O $TactN -z $O $TactN "$ZSK" >settime.out.$zone.3 2>&1
+# Set key rollover relationship.
+key_successor $KSK1 $KSK2
+# Sign zone.
+cat template.db.in "${KSK1}.key" "${KSK2}.key" "${ZSK}.key" >"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK1" >>"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile"
+cp $infile $zonefile
+$SIGNER -S -x -G "cds:sha-256" -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
--- /dev/null
+# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+#
+# SPDX-License-Identifier: MPL-2.0
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, you can obtain one at https://mozilla.org/MPL/2.0/.
+#
+# See the COPYRIGHT file distributed with this work for additional
+# information regarding copyright ownership.
+
+# pylint: disable=redefined-outer-name,unused-import
+
+from datetime import timedelta
+
+import isctest
+from common import (
+ pytestmark,
+ alg,
+ size,
+ DEFAULT_CONFIG,
+ TIMEDELTA,
+)
+
+
+CDSS = ["CDS (SHA-256)"]
+CONFIG = {
+ "dnskey-ttl": TIMEDELTA["PT2H"],
+ "ds-ttl": TIMEDELTA["PT1H"],
+ "max-zone-ttl": TIMEDELTA["P1D"],
+ "parent-propagation-delay": TIMEDELTA["PT1H"],
+ "publish-safety": TIMEDELTA["P1D"],
+ "purge-keys": TIMEDELTA["PT1H"],
+ "retire-safety": TIMEDELTA["P2D"],
+ "signatures-refresh": TIMEDELTA["P7D"],
+ "signatures-validity": TIMEDELTA["P14D"],
+ "zone-propagation-delay": TIMEDELTA["PT1H"],
+}
+POLICY = "ksk-doubleksk"
+KSK_LIFETIME = TIMEDELTA["P60D"]
+LIFETIME_POLICY = int(KSK_LIFETIME.total_seconds())
+IPUB = Ipub(CONFIG)
+IPUBC = IpubC(CONFIG)
+IRET = Iret(CONFIG, zsk=False, ksk=True)
+KEYTTLPROP = CONFIG["dnskey-ttl"] + CONFIG["zone-propagation-delay"]
+OFFSETS = {}
+OFFSETS["step1-p"] = -int(TIMEDELTA["P7D"].total_seconds())
+OFFSETS["step2-p"] = -int(KSK_LIFETIME.total_seconds() - IPUBC.total_seconds())
+OFFSETS["step2-s"] = 0
+OFFSETS["step3-p"] = -int(KSK_LIFETIME.total_seconds())
+OFFSETS["step3-s"] = -int(IPUBC.total_seconds())
+OFFSETS["step4-p"] = OFFSETS["step3-p"] - int(IRET.total_seconds())
+OFFSETS["step4-s"] = OFFSETS["step3-s"] - int(IRET.total_seconds())
+OFFSETS["step5-p"] = OFFSETS["step4-p"] - int(KEYTTLPROP.total_seconds())
+OFFSETS["step5-s"] = OFFSETS["step4-s"] - int(KEYTTLPROP.total_seconds())
+OFFSETS["step6-p"] = OFFSETS["step5-p"] - int(CONFIG["purge-keys"].total_seconds())
+OFFSETS["step6-s"] = OFFSETS["step5-s"] - int(CONFIG["purge-keys"].total_seconds())
+
+
+def test_ksk_doubleksk_step1(alg, size, servers):
+ step = {
+ # Introduce the first key. This will immediately be active.
+ "zone": "step1.ksk-doubleksk.autosign",
+ "cdss": CDSS,
+ "keyprops": [
+ f"zsk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{OFFSETS['step1-p']}",
+ f"ksk {LIFETIME_POLICY} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{OFFSETS['step1-p']}",
+ ],
+ # Next key event is when the successor KSK needs to be published.
+ # That is the KSK lifetime - prepublication time (minus time
+ # already passed).
+ "nextev": KSK_LIFETIME - IPUB - timedelta(days=7),
+ }
+ isctest.kasp.check_rollover_step(servers["ns3"], CONFIG, POLICY, step)
+
+
+def test_ksk_doubleksk_step2(alg, size, servers):
+ step = {
+ # Successor KSK is prepublished (and signs DNSKEY RRset).
+ # KSK1 goal: omnipresent -> hidden
+ # KSK2 goal: hidden -> omnipresent
+ # KSK2 dnskey: hidden -> rumoured
+ # KSK2 krrsig: hidden -> rumoured
+ "zone": "step2.ksk-doubleksk.autosign",
+ "cdss": CDSS,
+ "keyprops": [
+ f"zsk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{OFFSETS['step2-p']}",
+ f"ksk {LIFETIME_POLICY} {alg} {size} goal:hidden dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{OFFSETS['step2-p']}",
+ f"ksk {LIFETIME_POLICY} {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured ds:hidden offset:{OFFSETS['step2-s']}",
+ ],
+ "keyrelationships": [1, 2],
+ # Next key event is when the successor KSK becomes OMNIPRESENT.
+ "nextev": IPUB,
+ }
+ isctest.kasp.check_rollover_step(servers["ns3"], CONFIG, POLICY, step)
+
+
+def test_ksk_doubleksk_step3(alg, size, servers):
+ step = {
+ # The successor DNSKEY RRset has become omnipresent. The
+ # predecessor DS can be withdrawn and the successor DS can be
+ # introduced.
+ # KSK1 ds: omnipresent -> unretentive
+ # KSK2 dnskey: rumoured -> omnipresent
+ # KSK2 krrsig: rumoured -> omnipresent
+ # KSK2 ds: hidden -> rumoured
+ "zone": "step3.ksk-doubleksk.autosign",
+ "cdss": CDSS,
+ "keyprops": [
+ f"zsk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{OFFSETS['step3-p']}",
+ f"ksk {LIFETIME_POLICY} {alg} {size} goal:hidden dnskey:omnipresent krrsig:omnipresent ds:unretentive offset:{OFFSETS['step3-p']}",
+ f"ksk {LIFETIME_POLICY} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:rumoured offset:{OFFSETS['step3-s']}",
+ ],
+ "keyrelationships": [1, 2],
+ # Next key event is when the predecessor DS has been replaced with
+ # the successor DS and enough time has passed such that the all
+ # validators that have this DS RRset cached only know about the
+ # successor DS. This is the the retire interval.
+ "nextev": IRET,
+ }
+ isctest.kasp.check_rollover_step(servers["ns3"], CONFIG, POLICY, step)
+
+
+def test_ksk_doubleksk_step4(alg, size, servers):
+ step = {
+ # The predecessor DNSKEY may be removed, the successor DS is
+ # omnipresent.
+ # KSK1 dnskey: omnipresent -> unretentive
+ # KSK1 krrsig: omnipresent -> unretentive
+ # KSK1 ds: unretentive -> hidden
+ # KSK2 ds: rumoured -> omnipresent
+ "zone": "step4.ksk-doubleksk.autosign",
+ "cdss": CDSS,
+ "keyprops": [
+ f"zsk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{OFFSETS['step4-p']}",
+ f"ksk {LIFETIME_POLICY} {alg} {size} goal:hidden dnskey:unretentive krrsig:unretentive ds:hidden offset:{OFFSETS['step4-p']}",
+ f"ksk {LIFETIME_POLICY} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{OFFSETS['step4-s']}",
+ ],
+ "keyrelationships": [1, 2],
+ # Next key event is when the DNSKEY enters the HIDDEN state.
+ # This is the DNSKEY TTL plus zone propagation delay.
+ "nextev": KEYTTLPROP,
+ }
+ isctest.kasp.check_rollover_step(servers["ns3"], CONFIG, POLICY, step)
+
+
+def test_ksk_doubleksk_step5(alg, size, servers):
+ step = {
+ # The predecessor DNSKEY is long enough removed from the zone it
+ # has become hidden.
+ # KSK1 dnskey: unretentive -> hidden
+ # KSK1 krrsig: unretentive -> hidden
+ "zone": "step5.ksk-doubleksk.autosign",
+ "cdss": CDSS,
+ "keyprops": [
+ f"zsk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{OFFSETS['step5-p']}",
+ f"ksk {LIFETIME_POLICY} {alg} {size} goal:hidden dnskey:hidden krrsig:hidden ds:hidden offset:{OFFSETS['step5-p']}",
+ f"ksk {LIFETIME_POLICY} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{OFFSETS['step5-s']}",
+ ],
+ "keyrelationships": [1, 2],
+ # Next key event is when the new successor needs to be published.
+ # This is the KSK lifetime minus Ipub minus Iret minus time elapsed.
+ "nextev": KSK_LIFETIME - IPUB - IRET - KEYTTLPROP,
+ }
+ isctest.kasp.check_rollover_step(servers["ns3"], CONFIG, POLICY, step)
+
+
+def test_ksk_doubleksk_step6(alg, size, servers):
+ step = {
+ # Predecessor KSK is now purged.
+ "zone": "step6.ksk-doubleksk.autosign",
+ "cdss": CDSS,
+ "keyprops": [
+ f"zsk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{OFFSETS['step6-p']}",
+ f"ksk {LIFETIME_POLICY} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{OFFSETS['step6-s']}",
+ ],
+ "nextev": None,
+ }
+ isctest.kasp.check_rollover_step(servers["ns3"], CONFIG, POLICY, step)
"PT6H": timedelta(hours=6),
"PT12H": timedelta(hours=12),
"P1D": timedelta(days=1),
+ "P2D": timedelta(days=2),
"P5D": timedelta(days=5),
"P7D": timedelta(days=7),
"P10D": timedelta(days=10),
dnssec-policy "zsk-prepub";
};
-/*
- * Zones for testing KSK Double-KSK steps.
- */
-zone "step1.ksk-doubleksk.autosign" {
- type primary;
- file "step1.ksk-doubleksk.autosign.db";
- dnssec-policy "ksk-doubleksk";
-};
-zone "step2.ksk-doubleksk.autosign" {
- type primary;
- file "step2.ksk-doubleksk.autosign.db";
- dnssec-policy "ksk-doubleksk";
-};
-zone "step3.ksk-doubleksk.autosign" {
- type primary;
- file "step3.ksk-doubleksk.autosign.db";
- dnssec-policy "ksk-doubleksk";
-};
-zone "step4.ksk-doubleksk.autosign" {
- type primary;
- file "step4.ksk-doubleksk.autosign.db";
- dnssec-policy "ksk-doubleksk";
-};
-zone "step5.ksk-doubleksk.autosign" {
- type primary;
- file "step5.ksk-doubleksk.autosign.db";
- dnssec-policy "ksk-doubleksk";
-};
-zone "step6.ksk-doubleksk.autosign" {
- type primary;
- file "step6.ksk-doubleksk.autosign.db";
- dnssec-policy "ksk-doubleksk";
-};
-
/*
* Zone for testing GL #2375: Three is a crowd.
*/
cp $infile $zonefile
$SIGNER -S -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
-#
-# The zones at ksk-doubleksk.autosign represent the various steps of a KSK
-# Double-KSK rollover.
-#
-
-# Step 1:
-# Introduce the first key. This will immediately be active.
-setup step1.ksk-doubleksk.autosign
-TactN="now-7d"
-keytimes="-P ${TactN} -A ${TactN}"
-KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $keytimes $zone 2>keygen.out.$zone.1)
-ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 $keytimes $zone 2>keygen.out.$zone.2)
-$SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN "$KSK" >settime.out.$zone.1 2>&1
-$SETTIME -s -g $O -k $O $TactN -z $O $TactN "$ZSK" >settime.out.$zone.2 2>&1
-cat template.db.in "${KSK}.key" "${ZSK}.key" >"$infile"
-cp $infile $zonefile
-$SIGNER -S -x -G "cds:sha-256" -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
-
-# Step 2:
-# It is time to submit the introduce the new KSK.
-setup step2.ksk-doubleksk.autosign
-# Lksk: 60d
-# Dreg: n/a
-# DprpC: 1h
-# TTLds: 1d
-# TTLkey: 2h
-# publish-safety: 1d
-# retire-safety: 2d
-#
-# According to RFC 7583:
-# Tpub(N+1) <= Tact(N) + Lksk - Dreg - IpubC
-# IpubC = DprpC + TTLkey (+publish-safety)
-#
-# IpubC = 27h
-# Tact(N) = now - Lksk + Dreg + IpubC = now - 60d + 27h
-# = now - 1440h + 27h = now - 1413h
-TactN="now-1413h"
-keytimes="-P ${TactN} -A ${TactN}"
-KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $keytimes $zone 2>keygen.out.$zone.1)
-ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 $keytimes $zone 2>keygen.out.$zone.2)
-$SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN "$KSK" >settime.out.$zone.1 2>&1
-$SETTIME -s -g $O -k $O $TactN -z $O $TactN "$ZSK" >settime.out.$zone.2 2>&1
-cat template.db.in "${KSK}.key" "${ZSK}.key" >"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK" >>"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile"
-cp $infile $zonefile
-$SIGNER -S -x -G "cds:sha-256" -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
-
-# Step 3:
-# It is time to submit the DS.
-setup step3.ksk-doubleksk.autosign
-# According to RFC 7583:
-# Iret = DprpP + TTLds (+retire-safety)
-#
-# Iret = 50h
-# Tpub(N) = now - Lksk = now - 60d = now - 60d
-# Tact(N) = now - 1413h
-# Tret(N) = now
-# Trem(N) = now + Iret = now + 50h
-# Tpub(N+1) = now - IpubC = now - 27h
-# Tact(N+1) = now
-# Tret(N+1) = now + Lksk = now + 60d
-# Trem(N+1) = now + Lksk + Iret = now + 60d + 50h
-# = now + 1440h + 50h = 1490h
-TpubN="now-60d"
-TactN="now-1413h"
-TretN="now"
-TremN="now+50h"
-TpubN1="now-27h"
-TactN1="now"
-TretN1="now+60d"
-TremN1="now+1490h"
-ksktimes="-P ${TpubN} -A ${TpubN} -P sync ${TactN} -I ${TretN} -D ${TremN} -D sync ${TactN1}"
-newtimes="-P ${TpubN1} -A ${TactN1} -P sync ${TactN1} -I ${TretN1} -D ${TremN1}"
-zsktimes="-P ${TpubN} -A ${TpubN}"
-KSK1=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $ksktimes $zone 2>keygen.out.$zone.1)
-KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $newtimes $zone 2>keygen.out.$zone.2)
-ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 $zsktimes $zone 2>keygen.out.$zone.3)
-$SETTIME -s -g $H -k $O $TpubN -r $O $TpubN -d $O $TactN "$KSK1" >settime.out.$zone.1 2>&1
-$SETTIME -s -g $O -k $R $TpubN1 -r $R $TpubN1 -d $H $TpubN1 "$KSK2" >settime.out.$zone.2 2>&1
-$SETTIME -s -g $O -k $O $TpubN -z $O $TpubN "$ZSK" >settime.out.$zone.3 2>&1
-# Set key rollover relationship.
-key_successor $KSK1 $KSK2
-# Sign zone.
-cat template.db.in "${KSK1}.key" "${KSK2}.key" "${ZSK}.key" >"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK1" >>"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile"
-cp $infile $zonefile
-$SIGNER -S -x -G "cds:sha-256" -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
-
-# Step 4:
-# The DS should be swapped now.
-setup step4.ksk-doubleksk.autosign
-# Tpub(N) = now - Lksk - Iret = now - 60d - 50h
-# = now - 1440h - 50h = now - 1490h
-# Tact(N) = now - 1490h + 27h = now - 1463h
-# Tret(N) = now - Iret = now - 50h
-# Trem(N) = now
-# Tpub(N+1) = now - Iret - IpubC = now - 50h - 27h
-# = now - 77h
-# Tact(N+1) = Tret(N)
-# Tret(N+1) = now + Lksk - Iret = now + 60d - 50h = now + 1390h
-# Trem(N+1) = now + Lksk = now + 60d
-TpubN="now-1490h"
-TactN="now-1463h"
-TretN="now-50h"
-TremN="now"
-TpubN1="now-77h"
-TactN1="${TretN}"
-TretN1="now+1390h"
-TremN1="now+60d"
-ksktimes="-P ${TpubN} -A ${TpubN} -P sync ${TactN} -I ${TretN} -D ${TremN} -D sync ${TactN1}"
-newtimes="-P ${TpubN1} -A ${TactN1} -P sync ${TactN1} -I ${TretN1} -D ${TremN1}"
-zsktimes="-P ${TpubN} -A ${TpubN}"
-KSK1=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $ksktimes $zone 2>keygen.out.$zone.1)
-KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $newtimes $zone 2>keygen.out.$zone.2)
-ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 $zsktimes $zone 2>keygen.out.$zone.3)
-$SETTIME -s -g $H -k $O $TactN -r $O $TactN -d $U $TretN -D ds $TretN "$KSK1" >settime.out.$zone.1 2>&1
-$SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $R $TactN1 -P ds $TactN1 "$KSK2" >settime.out.$zone.2 2>&1
-$SETTIME -s -g $O -k $O $TactN -z $O $TactN "$ZSK" >settime.out.$zone.3 2>&1
-# Set key rollover relationship.
-key_successor $KSK1 $KSK2
-# Sign zone.
-cat template.db.in "${KSK1}.key" "${KSK2}.key" "${ZSK}.key" >"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK1" >>"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile"
-cp $infile $zonefile
-$SIGNER -S -x -G "cds:sha-256" -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
-
-# Step 5:
-# The predecessor DNSKEY is removed long enough that is has become HIDDEN.
-setup step5.ksk-doubleksk.autosign
-# Subtract DNSKEY TTL + zone-propagation-delay from all the times (3h).
-# Tpub(N) = now - 1490h - 3h = now - 1493h
-# Tact(N) = now - 1463h - 3h = now - 1466h
-# Tret(N) = now - 50h - 3h = now - 53h
-# Trem(N) = now - 3h
-# Tpub(N+1) = now - 77h - 3h = now - 80h
-# Tact(N+1) = Tret(N)
-# Tret(N+1) = now + 1390h - 3h = now + 1387h
-# Trem(N+1) = now + 60d - 3h = now + 1441h
-TpubN="now-1493h"
-TactN="now-1466h"
-TretN="now-53h"
-TremN="now-3h"
-TpubN1="now-80h"
-TactN1="${TretN}"
-TretN1="now+1387h"
-TremN1="now+1441h"
-ksktimes="-P ${TpubN} -A ${TpubN} -P sync ${TactN} -I ${TretN} -D ${TremN} -D sync ${TactN1}"
-newtimes="-P ${TpubN1} -A ${TactN1} -P sync ${TactN1} -I ${TretN1} -D ${TremN1}"
-zsktimes="-P ${TpubN} -A ${TpubN}"
-KSK1=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $ksktimes $zone 2>keygen.out.$zone.1)
-KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $newtimes $zone 2>keygen.out.$zone.2)
-ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 $zsktimes $zone 2>keygen.out.$zone.3)
-$SETTIME -s -g $H -k $U $TretN -r $U $TretN -d $H $TretN "$KSK1" >settime.out.$zone.1 2>&1
-$SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $O $TactN1 "$KSK2" >settime.out.$zone.2 2>&1
-$SETTIME -s -g $O -k $O $TactN -z $O $TactN "$ZSK" >settime.out.$zone.3 2>&1
-# Set key rollover relationship.
-key_successor $KSK1 $KSK2
-# Sign zone.
-cat template.db.in "${KSK1}.key" "${KSK2}.key" "${ZSK}.key" >"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK1" >>"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile"
-cp $infile $zonefile
-$SIGNER -S -x -G "cds:sha-256" -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
-
-# Step 6:
-# The predecessor DNSKEY can be purged.
-setup step6.ksk-doubleksk.autosign
-# Subtract purge-keys interval from all the times (1h).
-TpubN="now-1494h"
-TactN="now-1467h"
-TretN="now-54h"
-TremN="now-4h"
-TpubN1="now-81h"
-TactN1="${TretN}"
-TretN1="now+1386h"
-TremN1="now+1440h"
-ksktimes="-P ${TpubN} -A ${TpubN} -P sync ${TactN} -I ${TretN} -D ${TremN} -D sync ${TactN1}"
-newtimes="-P ${TpubN1} -A ${TactN1} -P sync ${TactN1} -I ${TretN1} -D ${TremN1}"
-zsktimes="-P ${TpubN} -A ${TpubN}"
-KSK1=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $ksktimes $zone 2>keygen.out.$zone.1)
-KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $newtimes $zone 2>keygen.out.$zone.2)
-ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 $zsktimes $zone 2>keygen.out.$zone.3)
-$SETTIME -s -g $H -k $H $TretN -r $H $TretN -d $H $TretN "$KSK1" >settime.out.$zone.1 2>&1
-$SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $O $TactN1 "$KSK2" >settime.out.$zone.2 2>&1
-$SETTIME -s -g $O -k $O $TactN -z $O $TactN "$ZSK" >settime.out.$zone.3 2>&1
-# Set key rollover relationship.
-key_successor $KSK1 $KSK2
-# Sign zone.
-cat template.db.in "${KSK1}.key" "${KSK2}.key" "${ZSK}.key" >"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK1" >>"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile"
-cp $infile $zonefile
-$SIGNER -S -x -G "cds:sha-256" -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
-
# Test #2375, the "three is a crowd" bug, where a new key is introduced but the
# previous rollover has not finished yet. In other words, we have a key KEY2
# that is the successor of key KEY1, and we introduce a new key KEY3 that is
lifetime_policy = int(ksk_lifetime.total_seconds())
ipub = Ipub(config)
- ipubc = IpubC(config)
iret = Iret(config, zsk=False, ksk=True)
- keyttlprop = config["dnskey-ttl"] + config["zone-propagation-delay"]
- offsets = {}
- offsets["step1-p"] = -int(timedelta(days=7).total_seconds())
- offsets["step2-p"] = -int(ksk_lifetime.total_seconds() - ipubc.total_seconds())
- offsets["step2-s"] = 0
- offsets["step3-p"] = -int(ksk_lifetime.total_seconds())
- offsets["step3-s"] = -int(ipubc.total_seconds())
- offsets["step4-p"] = offsets["step3-p"] - int(iret.total_seconds())
- offsets["step4-s"] = offsets["step3-s"] - int(iret.total_seconds())
- offsets["step5-p"] = offsets["step4-p"] - int(keyttlprop.total_seconds())
- offsets["step5-s"] = offsets["step4-s"] - int(keyttlprop.total_seconds())
- offsets["step6-p"] = offsets["step5-p"] - int(config["purge-keys"].total_seconds())
- offsets["step6-s"] = offsets["step5-s"] - int(config["purge-keys"].total_seconds())
-
- steps = [
- {
- # Step 1.
- # Introduce the first key. This will immediately be active.
- "zone": "step1.ksk-doubleksk.autosign",
- "cdss": cdss,
- "keyprops": [
- f"zsk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{offsets['step1-p']}",
- f"ksk {lifetime_policy} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{offsets['step1-p']}",
- ],
- # Next key event is when the successor KSK needs to be published.
- # That is the KSK lifetime - prepublication time (minus time
- # already passed).
- "nextev": ksk_lifetime - ipub - timedelta(days=7),
- },
- {
- # Step 2.
- # Successor KSK is prepublished (and signs DNSKEY RRset).
- # KSK1 goal: omnipresent -> hidden
- # KSK2 goal: hidden -> omnipresent
- # KSK2 dnskey: hidden -> rumoured
- # KSK2 krrsig: hidden -> rumoured
- "zone": "step2.ksk-doubleksk.autosign",
- "cdss": cdss,
- "keyprops": [
- f"zsk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{offsets['step2-p']}",
- f"ksk {lifetime_policy} {alg} {size} goal:hidden dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{offsets['step2-p']}",
- f"ksk {lifetime_policy} {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured ds:hidden offset:{offsets['step2-s']}",
- ],
- "keyrelationships": [1, 2],
- # Next key event is when the successor KSK becomes OMNIPRESENT.
- "nextev": ipub,
- },
- {
- # Step 3.
- # The successor DNSKEY RRset has become omnipresent. The
- # predecessor DS can be withdrawn and the successor DS can be
- # introduced.
- # KSK1 ds: omnipresent -> unretentive
- # KSK2 dnskey: rumoured -> omnipresent
- # KSK2 krrsig: rumoured -> omnipresent
- # KSK2 ds: hidden -> rumoured
- "zone": "step3.ksk-doubleksk.autosign",
- "cdss": cdss,
- "keyprops": [
- f"zsk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{offsets['step3-p']}",
- f"ksk {lifetime_policy} {alg} {size} goal:hidden dnskey:omnipresent krrsig:omnipresent ds:unretentive offset:{offsets['step3-p']}",
- f"ksk {lifetime_policy} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:rumoured offset:{offsets['step3-s']}",
- ],
- "keyrelationships": [1, 2],
- # Next key event is when the predecessor DS has been replaced with
- # the successor DS and enough time has passed such that the all
- # validators that have this DS RRset cached only know about the
- # successor DS. This is the the retire interval.
- "nextev": iret,
- },
- {
- # Step 4.
- # The predecessor DNSKEY may be removed, the successor DS is
- # omnipresent.
- # KSK1 dnskey: omnipresent -> unretentive
- # KSK1 krrsig: omnipresent -> unretentive
- # KSK1 ds: unretentive -> hidden
- # KSK2 ds: rumoured -> omnipresent
- "zone": "step4.ksk-doubleksk.autosign",
- "cdss": cdss,
- "keyprops": [
- f"zsk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{offsets['step4-p']}",
- f"ksk {lifetime_policy} {alg} {size} goal:hidden dnskey:unretentive krrsig:unretentive ds:hidden offset:{offsets['step4-p']}",
- f"ksk {lifetime_policy} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{offsets['step4-s']}",
- ],
- "keyrelationships": [1, 2],
- # Next key event is when the DNSKEY enters the HIDDEN state.
- # This is the DNSKEY TTL plus zone propagation delay.
- "nextev": keyttlprop,
- },
- {
- # Step 5.
- # The predecessor DNSKEY is long enough removed from the zone it
- # has become hidden.
- # KSK1 dnskey: unretentive -> hidden
- # KSK1 krrsig: unretentive -> hidden
- "zone": "step5.ksk-doubleksk.autosign",
- "cdss": cdss,
- "keyprops": [
- f"zsk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{offsets['step5-p']}",
- f"ksk {lifetime_policy} {alg} {size} goal:hidden dnskey:hidden krrsig:hidden ds:hidden offset:{offsets['step5-p']}",
- f"ksk {lifetime_policy} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{offsets['step5-s']}",
- ],
- "keyrelationships": [1, 2],
- # Next key event is when the new successor needs to be published.
- # This is the KSK lifetime minus Ipub minus Iret minus time elapsed.
- "nextev": ksk_lifetime - ipub - iret - keyttlprop,
- },
- {
- # Step 6.
- # Predecessor KSK is now purged.
- "zone": "step6.ksk-doubleksk.autosign",
- "cdss": cdss,
- "keyprops": [
- f"zsk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{offsets['step6-p']}",
- f"ksk {lifetime_policy} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{offsets['step6-s']}",
- ],
- "nextev": None,
- },
- ]
-
- for step in steps:
- isctest.kasp.check_rollover_step(server, config, policy, step)
# Test #2375: Scheduled rollovers are happening faster than they can finish.
zone = "three-is-a-crowd.kasp"