--- /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 "rsasha256" {
+ signatures-refresh P5D;
+ signatures-validity 30d;
+ signatures-validity-dnskey 30d;
+
+ keys {
+ ksk lifetime unlimited algorithm rsasha256;
+ zsk lifetime unlimited algorithm rsasha256;
+ };
+
+ dnskey-ttl 1h;
+ publish-safety PT1H;
+ retire-safety 2h;
+ zone-propagation-delay 3600;
+ max-zone-ttl 6h;
+ parent-propagation-delay pt1h;
+ parent-ds-ttl 7200;
+};
+
+dnssec-policy "ecdsa256" {
+ signatures-refresh P5D;
+ signatures-validity 30d;
+ signatures-validity-dnskey 30d;
+
+ keys {
+ ksk lifetime unlimited algorithm ecdsa256;
+ zsk lifetime unlimited algorithm ecdsa256;
+ };
+
+ dnskey-ttl 1h;
+ publish-safety PT1H;
+ retire-safety 2h;
+ zone-propagation-delay 3600;
+ max-zone-ttl 6h;
+ parent-propagation-delay pt1h;
+ parent-ds-ttl 7200;
+};
--- /dev/null
+../../rollover-dynamic2inline/ns6/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.
+ */
+
+{% set alg_roll = alg_roll | default(False) %}
+{% set policy = "rsasha256" if not alg_roll else "ecdsa256" %}
+
+include "kasp.conf";
+include "named.common.conf";
+
+zone "step1.algorithm-roll.kasp" {
+ type primary;
+ file "step1.algorithm-roll.kasp.db";
+ dnssec-policy @policy@;
+};
+
+{% if alg_roll %}
+zone "step2.algorithm-roll.kasp" {
+ type primary;
+ file "step2.algorithm-roll.kasp.db";
+ dnssec-policy "ecdsa256";
+};
+
+zone "step3.algorithm-roll.kasp" {
+ type primary;
+ file "step3.algorithm-roll.kasp.db";
+ dnssec-policy "ecdsa256";
+};
+
+zone "step4.algorithm-roll.kasp" {
+ type primary;
+ file "step4.algorithm-roll.kasp.db";
+ dnssec-policy "ecdsa256";
+};
+
+zone "step5.algorithm-roll.kasp" {
+ type primary;
+ file "step5.algorithm-roll.kasp.db";
+ dnssec-policy "ecdsa256";
+};
+
+zone "step6.algorithm-roll.kasp" {
+ type primary;
+ file "step6.algorithm-roll.kasp.db";
+ dnssec-policy "ecdsa256";
+};
+{% endif %}
--- /dev/null
+../../rollover-dynamic2inline/ns6/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 "ns6"
+
+setup() {
+ zone="$1"
+ echo_i "setting up zone: $zone"
+ zonefile="${zone}.db"
+ infile="${zone}.db.infile"
+}
+
+# Make lines shorter by storing key states in environment variables.
+H="HIDDEN"
+R="RUMOURED"
+O="OMNIPRESENT"
+U="UNRETENTIVE"
+
+#
+# The zones at algorithm-roll.kasp represent the various steps of a ZSK/KSK
+# algorithm rollover.
+#
+
+# Step 1:
+# Introduce the first key. This will immediately be active.
+setup step1.algorithm-roll.kasp
+echo "$zone" >>zones
+TactN="now-7d"
+TsbmN="now-161h"
+ksktimes="-P ${TactN} -A ${TactN}"
+zsktimes="-P ${TactN} -A ${TactN}"
+KSK=$($KEYGEN -a RSASHA256 -L 3600 -f KSK $ksktimes $zone 2>keygen.out.$zone.1)
+ZSK=$($KEYGEN -a RSASHA256 -L 3600 $zsktimes $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 8 "$KSK" >>"$infile"
+private_type_record $zone 8 "$ZSK" >>"$infile"
+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
+
+# Step 2:
+# After the publication interval has passed the DNSKEY is OMNIPRESENT.
+setup step2.algorithm-roll.kasp
+# The time passed since the new algorithm keys have been introduced is 3 hours.
+TpubN1="now-3h"
+# Tsbm(N+1) = TpubN1 + Ipub = now + TTLsig + Dprp = now - 3h + 6h + 1h = now + 4h
+TsbmN1="now+4h"
+ksk1times="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I ${TsbmN1}"
+zsk1times="-P ${TactN} -A ${TactN} -I ${TsbmN1}"
+ksk2times="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}"
+zsk2times="-P ${TpubN1} -A ${TpubN1}"
+KSK1=$($KEYGEN -a RSASHA256 -L 3600 -f KSK $ksk1times $zone 2>keygen.out.$zone.1)
+ZSK1=$($KEYGEN -a RSASHA256 -L 3600 $zsk1times $zone 2>keygen.out.$zone.2)
+KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $ksk2times $zone 2>keygen.out.$zone.3)
+ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $zsk2times $zone 2>keygen.out.$zone.4)
+$SETTIME -s -g $H -k $O $TactN -r $O $TactN -d $O $TactN "$KSK1" >settime.out.$zone.1 2>&1
+$SETTIME -s -g $H -k $O $TactN -z $O $TactN "$ZSK1" >settime.out.$zone.2 2>&1
+$SETTIME -s -g $O -k $R $TpubN1 -r $R $TpubN1 -d $H $TpubN1 "$KSK2" >settime.out.$zone.3 2>&1
+$SETTIME -s -g $O -k $R $TpubN1 -z $R $TpubN1 "$ZSK2" >settime.out.$zone.4 2>&1
+# Fake lifetime of old algorithm keys.
+echo "Lifetime: 0" >>"${KSK1}.state"
+echo "Lifetime: 0" >>"${ZSK1}.state"
+cat template.db.in "${KSK1}.key" "${ZSK1}.key" "${KSK2}.key" "${ZSK2}.key" >"$infile"
+private_type_record $zone 8 "$KSK1" >>"$infile"
+private_type_record $zone 8 "$ZSK1" >>"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK2" >>"$infile"
+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
+
+# Step 3:
+# The zone signatures are also OMNIPRESENT.
+setup step3.algorithm-roll.kasp
+# The time passed since the new algorithm keys have been introduced is 7 hours.
+TpubN1="now-7h"
+TsbmN1="now"
+ksk1times="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I ${TsbmN1}"
+zsk1times="-P ${TactN} -A ${TactN} -I ${TsbmN1}"
+ksk2times="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}"
+zsk2times="-P ${TpubN1} -A ${TpubN1}"
+KSK1=$($KEYGEN -a RSASHA256 -L 3600 -f KSK $ksk1times $zone 2>keygen.out.$zone.1)
+ZSK1=$($KEYGEN -a RSASHA256 -L 3600 $zsk1times $zone 2>keygen.out.$zone.2)
+KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $ksk2times $zone 2>keygen.out.$zone.3)
+ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $zsk2times $zone 2>keygen.out.$zone.4)
+$SETTIME -s -g $H -k $O $TactN -r $O $TactN -d $O $TactN "$KSK1" >settime.out.$zone.1 2>&1
+$SETTIME -s -g $H -k $O $TactN -z $O $TactN "$ZSK1" >settime.out.$zone.2 2>&1
+$SETTIME -s -g $O -k $O $TpubN1 -r $O $TpubN1 -d $H $TpubN1 "$KSK2" >settime.out.$zone.3 2>&1
+$SETTIME -s -g $O -k $O $TpubN1 -z $R $TpubN1 "$ZSK2" >settime.out.$zone.4 2>&1
+# Fake lifetime of old algorithm keys.
+echo "Lifetime: 0" >>"${KSK1}.state"
+echo "Lifetime: 0" >>"${ZSK1}.state"
+cat template.db.in "${KSK1}.key" "${ZSK1}.key" "${KSK2}.key" "${ZSK2}.key" >"$infile"
+private_type_record $zone 8 "$KSK1" >>"$infile"
+private_type_record $zone 8 "$ZSK1" >>"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK2" >>"$infile"
+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
+
+# Step 4:
+# The DS is swapped and can become OMNIPRESENT.
+setup step4.algorithm-roll.kasp
+# The time passed since the DS has been swapped is 3 hours.
+TpubN1="now-10h"
+TsbmN1="now-3h"
+ksk1times="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I ${TsbmN1}"
+zsk1times="-P ${TactN} -A ${TactN} -I ${TsbmN1}"
+ksk2times="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}"
+zsk2times="-P ${TpubN1} -A ${TpubN1}"
+KSK1=$($KEYGEN -a RSASHA256 -L 3600 -f KSK $ksk1times $zone 2>keygen.out.$zone.1)
+ZSK1=$($KEYGEN -a RSASHA256 -L 3600 $zsk1times $zone 2>keygen.out.$zone.2)
+KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $ksk2times $zone 2>keygen.out.$zone.3)
+ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $zsk2times $zone 2>keygen.out.$zone.4)
+$SETTIME -s -g $H -k $O $TactN -r $O $TactN -d $U $TsbmN1 -D ds $TsbmN1 "$KSK1" >settime.out.$zone.1 2>&1
+$SETTIME -s -g $H -k $O $TactN -z $O $TactN "$ZSK1" >settime.out.$zone.2 2>&1
+$SETTIME -s -g $O -k $O $TpubN1 -r $O $TpubN1 -d $R $TsbmN1 -P ds $TsbmN1 "$KSK2" >settime.out.$zone.3 2>&1
+$SETTIME -s -g $O -k $O $TpubN1 -z $R $TpubN1 "$ZSK2" >settime.out.$zone.4 2>&1
+# Fake lifetime of old algorithm keys.
+echo "Lifetime: 0" >>"${KSK1}.state"
+echo "Lifetime: 0" >>"${ZSK1}.state"
+cat template.db.in "${KSK1}.key" "${ZSK1}.key" "${KSK2}.key" "${ZSK2}.key" >"$infile"
+private_type_record $zone 8 "$KSK1" >>"$infile"
+private_type_record $zone 8 "$ZSK1" >>"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK2" >>"$infile"
+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
+
+# Step 5:
+# The DNSKEY is removed long enough to be HIDDEN.
+setup step5.algorithm-roll.kasp
+# The time passed since the DNSKEY has been removed is 2 hours.
+TpubN1="now-12h"
+TsbmN1="now-5h"
+ksk1times="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I ${TsbmN1}"
+zsk1times="-P ${TactN} -A ${TactN} -I ${TsbmN1}"
+ksk2times="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}"
+zsk2times="-P ${TpubN1} -A ${TpubN1}"
+KSK1=$($KEYGEN -a RSASHA256 -L 3600 -f KSK $ksk1times $zone 2>keygen.out.$zone.1)
+ZSK1=$($KEYGEN -a RSASHA256 -L 3600 $zsk1times $zone 2>keygen.out.$zone.2)
+KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $ksk2times $zone 2>keygen.out.$zone.3)
+ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $zsk2times $zone 2>keygen.out.$zone.4)
+$SETTIME -s -g $H -k $U $TsbmN1 -r $U $TsbmN1 -d $H $TsbmN1 "$KSK1" >settime.out.$zone.1 2>&1
+$SETTIME -s -g $H -k $U $TsbmN1 -z $U $TsbmN1 "$ZSK1" >settime.out.$zone.2 2>&1
+$SETTIME -s -g $O -k $O $TpubN1 -r $O $TpubN1 -d $O $TsbmN1 "$KSK2" >settime.out.$zone.3 2>&1
+$SETTIME -s -g $O -k $O $TpubN1 -z $R $TpubN1 "$ZSK2" >settime.out.$zone.4 2>&1
+# Fake lifetime of old algorithm keys.
+echo "Lifetime: 0" >>"${KSK1}.state"
+echo "Lifetime: 0" >>"${ZSK1}.state"
+cat template.db.in "${KSK1}.key" "${ZSK1}.key" "${KSK2}.key" "${ZSK2}.key" >"$infile"
+private_type_record $zone 8 "$KSK1" >>"$infile"
+private_type_record $zone 8 "$ZSK1" >>"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK2" >>"$infile"
+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
+
+# Step 6:
+# The RRSIGs have been removed long enough to be HIDDEN.
+setup step6.algorithm-roll.kasp
+# Additional time passed: 7h.
+TpubN1="now-19h"
+TsbmN1="now-12h"
+ksk1times="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I ${TsbmN1}"
+zsk1times="-P ${TactN} -A ${TactN} -I ${TsbmN1}"
+ksk2times="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}"
+zsk2times="-P ${TpubN1} -A ${TpubN1}"
+KSK1=$($KEYGEN -a RSASHA256 -L 3600 -f KSK $ksk1times $zone 2>keygen.out.$zone.1)
+ZSK1=$($KEYGEN -a RSASHA256 -L 3600 $zsk1times $zone 2>keygen.out.$zone.2)
+KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $ksk2times $zone 2>keygen.out.$zone.3)
+ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $zsk2times $zone 2>keygen.out.$zone.4)
+$SETTIME -s -g $H -k $H $TsbmN1 -r $U $TsbmN1 -d $H $TsbmN1 "$KSK1" >settime.out.$zone.1 2>&1
+$SETTIME -s -g $H -k $H $TsbmN1 -z $U $TsbmN1 "$ZSK1" >settime.out.$zone.2 2>&1
+$SETTIME -s -g $O -k $O $TpubN1 -r $O $TpubN1 -d $O $TsbmN1 "$KSK2" >settime.out.$zone.3 2>&1
+$SETTIME -s -g $O -k $O $TpubN1 -z $R $TpubN1 "$ZSK2" >settime.out.$zone.4 2>&1
+# Fake lifetime of old algorithm keys.
+echo "Lifetime: 0" >>"${KSK1}.state"
+echo "Lifetime: 0" >>"${ZSK1}.state"
+cat template.db.in "${KSK1}.key" "${ZSK1}.key" "${KSK2}.key" "${ZSK2}.key" >"$infile"
+private_type_record $zone 8 "$KSK1" >>"$infile"
+private_type_record $zone 8 "$ZSK1" >>"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK2" >>"$infile"
+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
--- /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=unused-import
+
+import isctest
+from common import (
+ pytestmark,
+ CDSS,
+ DURATION,
+ TIMEDELTA,
+ ALGOROLL_CONFIG,
+)
+
+
+def test_algoroll_ksk_zsk_initial(servers):
+ config = ALGOROLL_CONFIG
+ policy = "rsasha256"
+
+ step = {
+ "zone": "step1.algorithm-roll.kasp",
+ "cdss": CDSS,
+ "keyprops": [
+ f"ksk 0 8 2048 goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{-DURATION['P7D']}",
+ f"zsk 0 8 2048 goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{-DURATION['P7D']}",
+ ],
+ "nextev": TIMEDELTA["PT1H"],
+ }
+ isctest.kasp.check_rollover_step(servers["ns6"], config, policy, step)
--- /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
+
+import pytest
+
+import isctest
+from isctest.kasp import KeyTimingMetadata
+from common import (
+ pytestmark,
+ alg,
+ size,
+ CDSS,
+ ALGOROLL_CONFIG,
+ TIMEDELTA,
+)
+
+IPUB = Ipub(ALGOROLL_CONFIG)
+IPUBC = IpubC(ALGOROLL_CONFIG, rollover=False)
+IRET = Iret(ALGOROLL_CONFIG, rollover=False)
+IRETKSK = Iret(ALGOROLL_CONFIG, zsk=False, ksk=True, rollover=False)
+KEYTTLPROP = ALGOROLL_CONFIG["dnskey-ttl"] + ALGOROLL_CONFIG["zone-propagation-delay"]
+OFFSETS = {}
+OFFSETS["step2"] = -int(IPUB.total_seconds())
+OFFSETS["step3"] = -int(IRET.total_seconds())
+OFFSETS["step4"] = OFFSETS["step3"] - int(IRETKSK.total_seconds())
+OFFSETS["step5"] = OFFSETS["step4"] - int(KEYTTLPROP.total_seconds())
+OFFSETS["step6"] = OFFSETS["step5"] - int(IRET.total_seconds())
+OFFVAL = -DURATION["P7D"]
+CONFIG = ALGOROLL_CONFIG
+POLICY = "ecdsa256"
+TIME_PASSED = 0 # set in reconfigure() fixture
+
+
+@pytest.fixture(scope="module", autouse=True)
+def reconfigure(servers, templates):
+ global TIME_PASSED # pylint: disable=global-statement
+ start_time = KeyTimingMetadata.now()
+
+ templates.render("ns6/named.conf", {"alg_roll": True})
+ servers["ns6"].reconfigure()
+
+ # Calculate time passed to correctly check for next key events.
+ TIME_PASSED = KeyTimingMetadata.now().value - start_time.value
+
+
+def test_algoroll_ksk_zsk_reconfig_step1(servers, alg, size):
+ step = {
+ "zone": "step1.algorithm-roll.kasp",
+ "cdss": CDSS,
+ "keyprops": [
+ # The RSASHA keys are outroducing.
+ f"ksk 0 8 2048 goal:hidden dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{OFFVAL}",
+ f"zsk 0 8 2048 goal:hidden dnskey:omnipresent zrrsig:omnipresent offset:{OFFVAL}",
+ # The ECDSAP256SHA256 keys are introducing.
+ f"ksk 0 {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured ds:hidden",
+ f"zsk 0 {alg} {size} goal:omnipresent dnskey:rumoured zrrsig:rumoured",
+ ],
+ # Next key event is when the ecdsa256 keys have been propagated.
+ "nextev": IPUB,
+ }
+ isctest.kasp.check_rollover_step(servers["ns6"], CONFIG, POLICY, step)
+
+
+def test_algoroll_ksk_zsk_reconfig_step2(servers, alg, size):
+ step = {
+ "zone": "step2.algorithm-roll.kasp",
+ "cdss": CDSS,
+ "keyprops": [
+ # The RSASHA keys are outroducing, but need to stay present
+ # until the new algorithm chain of trust has been established.
+ # Thus the expected key states of these keys stay the same.
+ f"ksk 0 8 2048 goal:hidden dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{OFFVAL}",
+ f"zsk 0 8 2048 goal:hidden dnskey:omnipresent zrrsig:omnipresent offset:{OFFVAL}",
+ # The ECDSAP256SHA256 keys are introducing. The DNSKEY RRset is
+ # omnipresent, but the zone signatures are not.
+ f"ksk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:hidden offset:{OFFSETS['step2']}",
+ f"zsk 0 {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:rumoured offset:{OFFSETS['step2']}",
+ ],
+ # Next key event is when all zone signatures are signed with the new
+ # algorithm. This is the max-zone-ttl plus zone propagation delay. But
+ # the publication interval has already passed. Also, prevent intermittent
+ # false positives on slow platforms by subtracting the time passed between
+ # key creation and invoking 'rndc reconfig'.
+ "nextev": IPUBC - IPUB - TIME_PASSED,
+ }
+ isctest.kasp.check_rollover_step(servers["ns6"], CONFIG, POLICY, step)
+
+
+def test_algoroll_ksk_zsk_reconfig_step3(servers, alg, size):
+ step = {
+ "zone": "step3.algorithm-roll.kasp",
+ "cdss": CDSS,
+ "keyprops": [
+ # The DS can be swapped.
+ f"ksk 0 8 2048 goal:hidden dnskey:omnipresent krrsig:omnipresent ds:unretentive offset:{OFFVAL}",
+ f"zsk 0 8 2048 goal:hidden dnskey:omnipresent zrrsig:omnipresent offset:{OFFVAL}",
+ f"ksk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:rumoured offset:{OFFSETS['step3']}",
+ f"zsk 0 {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{OFFSETS['step3']}",
+ ],
+ # Next key event is when the DS becomes OMNIPRESENT. This happens
+ # after the retire interval.
+ "nextev": IRETKSK - TIME_PASSED,
+ }
+ isctest.kasp.check_rollover_step(servers["ns6"], CONFIG, POLICY, step)
+
+
+def test_algoroll_ksk_zsk_reconfig_step4(servers, alg, size):
+ step = {
+ "zone": "step4.algorithm-roll.kasp",
+ "cdss": CDSS,
+ "keyprops": [
+ # The old DS is HIDDEN, we can remove the old algorithm records.
+ f"ksk 0 8 2048 goal:hidden dnskey:unretentive krrsig:unretentive ds:hidden offset:{OFFVAL}",
+ f"zsk 0 8 2048 goal:hidden dnskey:unretentive zrrsig:unretentive offset:{OFFVAL}",
+ f"ksk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{OFFSETS['step4']}",
+ f"zsk 0 {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{OFFSETS['step4']}",
+ ],
+ # Next key event is when the old DNSKEY becomes HIDDEN.
+ # This happens after the DNSKEY TTL plus zone propagation delay.
+ "nextev": KEYTTLPROP,
+ }
+ isctest.kasp.check_rollover_step(servers["ns6"], CONFIG, POLICY, step)
+
+
+def test_algoroll_ksk_zsk_reconfig_step5(servers, alg, size):
+ step = {
+ "zone": "step5.algorithm-roll.kasp",
+ "cdss": CDSS,
+ "keyprops": [
+ # The DNSKEY becomes HIDDEN.
+ f"ksk 0 8 2048 goal:hidden dnskey:hidden krrsig:hidden ds:hidden offset:{OFFVAL}",
+ f"zsk 0 8 2048 goal:hidden dnskey:hidden zrrsig:unretentive offset:{OFFVAL}",
+ f"ksk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{OFFSETS['step5']}",
+ f"zsk 0 {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{OFFSETS['step5']}",
+ ],
+ # Next key event is when the RSASHA signatures become HIDDEN.
+ # This happens after the max-zone-ttl plus zone propagation delay
+ # minus the time already passed since the UNRETENTIVE state has
+ # been reached. Prevent intermittent false positives on slow
+ # platforms by subtracting the number of seconds which passed
+ # between key creation and invoking 'rndc reconfig'.
+ "nextev": IRET - IRETKSK - KEYTTLPROP - TIME_PASSED,
+ }
+ isctest.kasp.check_rollover_step(servers["ns6"], CONFIG, POLICY, step)
+
+
+def test_algoroll_ksk_zsk_reconfig_step6(servers, alg, size):
+ step = {
+ "zone": "step6.algorithm-roll.kasp",
+ "cdss": CDSS,
+ "keyprops": [
+ # The zone signatures are now HIDDEN.
+ f"ksk 0 8 2048 goal:hidden dnskey:hidden krrsig:hidden ds:hidden offset:{OFFVAL}",
+ f"zsk 0 8 2048 goal:hidden dnskey:hidden zrrsig:hidden offset:{OFFVAL}",
+ f"ksk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{OFFSETS['step6']}",
+ f"zsk 0 {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{OFFSETS['step6']}",
+ ],
+ # Next key event is never since we established the policy and the
+ # keys have an unlimited lifetime. Fallback to the default
+ # loadkeys interval.
+ "nextev": TIMEDELTA["PT1H"],
+ }
+ isctest.kasp.check_rollover_step(servers["ns6"], CONFIG, POLICY, step)
"PT5M": timedelta(minutes=5),
"PT1H": timedelta(hours=1),
"PT2H": timedelta(hours=2),
+ "PT6H": timedelta(hours=6),
"P1D": timedelta(days=1),
"P5D": timedelta(days=5),
+ "P7D": timedelta(days=7),
"P10D": timedelta(days=10),
"P14D": timedelta(days=14),
+ "P30D": timedelta(days=30),
"P60D": timedelta(days=60),
"P90D": timedelta(days=90),
"P6M": timedelta(days=31 * 6),
}
UNSIGNING_CONFIG = DEFAULT_CONFIG.copy()
UNSIGNING_CONFIG["dnskey-ttl"] = TIMEDELTA["PT2H"]
+ALGOROLL_CONFIG = {
+ "dnskey-ttl": TIMEDELTA["PT1H"],
+ "ds-ttl": TIMEDELTA["PT2H"],
+ "max-zone-ttl": TIMEDELTA["PT6H"],
+ "parent-propagation-delay": TIMEDELTA["PT1H"],
+ "publish-safety": TIMEDELTA["PT1H"],
+ "purge-keys": TIMEDELTA["P90D"],
+ "retire-safety": TIMEDELTA["PT2H"],
+ "signatures-refresh": TIMEDELTA["P5D"],
+ "signatures-validity": TIMEDELTA["P30D"],
+ "zone-propagation-delay": TIMEDELTA["PT1H"],
+}
@pytest.fixture
include "named.common.conf";
-/* Zones for testing KSK/ZSK algorithm roll. */
-{% set _policy = "rsasha256" if not csk_roll else "ecdsa256" %}
-zone "step1.algorithm-roll.kasp" {
- type primary;
- file "step1.algorithm-roll.kasp.db";
- dnssec-policy @_policy@;
-};
-
-{% if csk_roll %}
-zone "step2.algorithm-roll.kasp" {
- type primary;
- file "step2.algorithm-roll.kasp.db";
- dnssec-policy "ecdsa256";
-};
-
-zone "step3.algorithm-roll.kasp" {
- type primary;
- file "step3.algorithm-roll.kasp.db";
- dnssec-policy "ecdsa256";
-};
-
-zone "step4.algorithm-roll.kasp" {
- type primary;
- file "step4.algorithm-roll.kasp.db";
- dnssec-policy "ecdsa256";
-};
-
-zone "step5.algorithm-roll.kasp" {
- type primary;
- file "step5.algorithm-roll.kasp.db";
- dnssec-policy "ecdsa256";
-};
-
-zone "step6.algorithm-roll.kasp" {
- type primary;
- file "step6.algorithm-roll.kasp.db";
- dnssec-policy "ecdsa256";
-};
-{% endif %}
-
zone "step1.csk-algorithm-roll.kasp" {
type primary;
file "step1.csk-algorithm-roll.kasp.db";
O="OMNIPRESENT"
U="UNRETENTIVE"
-#
-# The zones at algorithm-roll.kasp represent the various steps of a ZSK/KSK
-# algorithm rollover.
-#
-
-# Step 1:
-# Introduce the first key. This will immediately be active.
-setup step1.algorithm-roll.kasp
-echo "$zone" >>zones
-TactN="now-7d"
-TsbmN="now-161h"
-ksktimes="-P ${TactN} -A ${TactN}"
-zsktimes="-P ${TactN} -A ${TactN}"
-KSK=$($KEYGEN -a RSASHA256 -L 3600 -f KSK $ksktimes $zone 2>keygen.out.$zone.1)
-ZSK=$($KEYGEN -a RSASHA256 -L 3600 $zsktimes $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 8 "$KSK" >>"$infile"
-private_type_record $zone 8 "$ZSK" >>"$infile"
-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
-
-# Step 2:
-# After the publication interval has passed the DNSKEY is OMNIPRESENT.
-setup step2.algorithm-roll.kasp
-# The time passed since the new algorithm keys have been introduced is 3 hours.
-TpubN1="now-3h"
-# Tsbm(N+1) = TpubN1 + Ipub = now + TTLsig + Dprp = now - 3h + 6h + 1h = now + 4h
-TsbmN1="now+4h"
-ksk1times="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I ${TsbmN1}"
-zsk1times="-P ${TactN} -A ${TactN} -I ${TsbmN1}"
-ksk2times="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}"
-zsk2times="-P ${TpubN1} -A ${TpubN1}"
-KSK1=$($KEYGEN -a RSASHA256 -L 3600 -f KSK $ksk1times $zone 2>keygen.out.$zone.1)
-ZSK1=$($KEYGEN -a RSASHA256 -L 3600 $zsk1times $zone 2>keygen.out.$zone.2)
-KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $ksk2times $zone 2>keygen.out.$zone.3)
-ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $zsk2times $zone 2>keygen.out.$zone.4)
-$SETTIME -s -g $H -k $O $TactN -r $O $TactN -d $O $TactN "$KSK1" >settime.out.$zone.1 2>&1
-$SETTIME -s -g $H -k $O $TactN -z $O $TactN "$ZSK1" >settime.out.$zone.2 2>&1
-$SETTIME -s -g $O -k $R $TpubN1 -r $R $TpubN1 -d $H $TpubN1 "$KSK2" >settime.out.$zone.3 2>&1
-$SETTIME -s -g $O -k $R $TpubN1 -z $R $TpubN1 "$ZSK2" >settime.out.$zone.4 2>&1
-# Fake lifetime of old algorithm keys.
-echo "Lifetime: 0" >>"${KSK1}.state"
-echo "Lifetime: 0" >>"${ZSK1}.state"
-cat template.db.in "${KSK1}.key" "${ZSK1}.key" "${KSK2}.key" "${ZSK2}.key" >"$infile"
-private_type_record $zone 8 "$KSK1" >>"$infile"
-private_type_record $zone 8 "$ZSK1" >>"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK2" >>"$infile"
-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
-
-# Step 3:
-# The zone signatures are also OMNIPRESENT.
-setup step3.algorithm-roll.kasp
-# The time passed since the new algorithm keys have been introduced is 7 hours.
-TpubN1="now-7h"
-TsbmN1="now"
-ksk1times="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I ${TsbmN1}"
-zsk1times="-P ${TactN} -A ${TactN} -I ${TsbmN1}"
-ksk2times="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}"
-zsk2times="-P ${TpubN1} -A ${TpubN1}"
-KSK1=$($KEYGEN -a RSASHA256 -L 3600 -f KSK $ksk1times $zone 2>keygen.out.$zone.1)
-ZSK1=$($KEYGEN -a RSASHA256 -L 3600 $zsk1times $zone 2>keygen.out.$zone.2)
-KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $ksk2times $zone 2>keygen.out.$zone.3)
-ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $zsk2times $zone 2>keygen.out.$zone.4)
-$SETTIME -s -g $H -k $O $TactN -r $O $TactN -d $O $TactN "$KSK1" >settime.out.$zone.1 2>&1
-$SETTIME -s -g $H -k $O $TactN -z $O $TactN "$ZSK1" >settime.out.$zone.2 2>&1
-$SETTIME -s -g $O -k $O $TpubN1 -r $O $TpubN1 -d $H $TpubN1 "$KSK2" >settime.out.$zone.3 2>&1
-$SETTIME -s -g $O -k $O $TpubN1 -z $R $TpubN1 "$ZSK2" >settime.out.$zone.4 2>&1
-# Fake lifetime of old algorithm keys.
-echo "Lifetime: 0" >>"${KSK1}.state"
-echo "Lifetime: 0" >>"${ZSK1}.state"
-cat template.db.in "${KSK1}.key" "${ZSK1}.key" "${KSK2}.key" "${ZSK2}.key" >"$infile"
-private_type_record $zone 8 "$KSK1" >>"$infile"
-private_type_record $zone 8 "$ZSK1" >>"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK2" >>"$infile"
-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
-
-# Step 4:
-# The DS is swapped and can become OMNIPRESENT.
-setup step4.algorithm-roll.kasp
-# The time passed since the DS has been swapped is 3 hours.
-TpubN1="now-10h"
-TsbmN1="now-3h"
-ksk1times="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I ${TsbmN1}"
-zsk1times="-P ${TactN} -A ${TactN} -I ${TsbmN1}"
-ksk2times="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}"
-zsk2times="-P ${TpubN1} -A ${TpubN1}"
-KSK1=$($KEYGEN -a RSASHA256 -L 3600 -f KSK $ksk1times $zone 2>keygen.out.$zone.1)
-ZSK1=$($KEYGEN -a RSASHA256 -L 3600 $zsk1times $zone 2>keygen.out.$zone.2)
-KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $ksk2times $zone 2>keygen.out.$zone.3)
-ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $zsk2times $zone 2>keygen.out.$zone.4)
-$SETTIME -s -g $H -k $O $TactN -r $O $TactN -d $U $TsbmN1 -D ds $TsbmN1 "$KSK1" >settime.out.$zone.1 2>&1
-$SETTIME -s -g $H -k $O $TactN -z $O $TactN "$ZSK1" >settime.out.$zone.2 2>&1
-$SETTIME -s -g $O -k $O $TpubN1 -r $O $TpubN1 -d $R $TsbmN1 -P ds $TsbmN1 "$KSK2" >settime.out.$zone.3 2>&1
-$SETTIME -s -g $O -k $O $TpubN1 -z $R $TpubN1 "$ZSK2" >settime.out.$zone.4 2>&1
-# Fake lifetime of old algorithm keys.
-echo "Lifetime: 0" >>"${KSK1}.state"
-echo "Lifetime: 0" >>"${ZSK1}.state"
-cat template.db.in "${KSK1}.key" "${ZSK1}.key" "${KSK2}.key" "${ZSK2}.key" >"$infile"
-private_type_record $zone 8 "$KSK1" >>"$infile"
-private_type_record $zone 8 "$ZSK1" >>"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK2" >>"$infile"
-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
-
-# Step 5:
-# The DNSKEY is removed long enough to be HIDDEN.
-setup step5.algorithm-roll.kasp
-# The time passed since the DNSKEY has been removed is 2 hours.
-TpubN1="now-12h"
-TsbmN1="now-5h"
-ksk1times="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I ${TsbmN1}"
-zsk1times="-P ${TactN} -A ${TactN} -I ${TsbmN1}"
-ksk2times="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}"
-zsk2times="-P ${TpubN1} -A ${TpubN1}"
-KSK1=$($KEYGEN -a RSASHA256 -L 3600 -f KSK $ksk1times $zone 2>keygen.out.$zone.1)
-ZSK1=$($KEYGEN -a RSASHA256 -L 3600 $zsk1times $zone 2>keygen.out.$zone.2)
-KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $ksk2times $zone 2>keygen.out.$zone.3)
-ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $zsk2times $zone 2>keygen.out.$zone.4)
-$SETTIME -s -g $H -k $U $TsbmN1 -r $U $TsbmN1 -d $H $TsbmN1 "$KSK1" >settime.out.$zone.1 2>&1
-$SETTIME -s -g $H -k $U $TsbmN1 -z $U $TsbmN1 "$ZSK1" >settime.out.$zone.2 2>&1
-$SETTIME -s -g $O -k $O $TpubN1 -r $O $TpubN1 -d $O $TsbmN1 "$KSK2" >settime.out.$zone.3 2>&1
-$SETTIME -s -g $O -k $O $TpubN1 -z $R $TpubN1 "$ZSK2" >settime.out.$zone.4 2>&1
-# Fake lifetime of old algorithm keys.
-echo "Lifetime: 0" >>"${KSK1}.state"
-echo "Lifetime: 0" >>"${ZSK1}.state"
-cat template.db.in "${KSK1}.key" "${ZSK1}.key" "${KSK2}.key" "${ZSK2}.key" >"$infile"
-private_type_record $zone 8 "$KSK1" >>"$infile"
-private_type_record $zone 8 "$ZSK1" >>"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK2" >>"$infile"
-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
-
-# Step 6:
-# The RRSIGs have been removed long enough to be HIDDEN.
-setup step6.algorithm-roll.kasp
-# Additional time passed: 7h.
-TpubN1="now-19h"
-TsbmN1="now-12h"
-ksk1times="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I ${TsbmN1}"
-zsk1times="-P ${TactN} -A ${TactN} -I ${TsbmN1}"
-ksk2times="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}"
-zsk2times="-P ${TpubN1} -A ${TpubN1}"
-KSK1=$($KEYGEN -a RSASHA256 -L 3600 -f KSK $ksk1times $zone 2>keygen.out.$zone.1)
-ZSK1=$($KEYGEN -a RSASHA256 -L 3600 $zsk1times $zone 2>keygen.out.$zone.2)
-KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $ksk2times $zone 2>keygen.out.$zone.3)
-ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $zsk2times $zone 2>keygen.out.$zone.4)
-$SETTIME -s -g $H -k $H $TsbmN1 -r $U $TsbmN1 -d $H $TsbmN1 "$KSK1" >settime.out.$zone.1 2>&1
-$SETTIME -s -g $H -k $H $TsbmN1 -z $U $TsbmN1 "$ZSK1" >settime.out.$zone.2 2>&1
-$SETTIME -s -g $O -k $O $TpubN1 -r $O $TpubN1 -d $O $TsbmN1 "$KSK2" >settime.out.$zone.3 2>&1
-$SETTIME -s -g $O -k $O $TpubN1 -z $R $TpubN1 "$ZSK2" >settime.out.$zone.4 2>&1
-# Fake lifetime of old algorithm keys.
-echo "Lifetime: 0" >>"${KSK1}.state"
-echo "Lifetime: 0" >>"${ZSK1}.state"
-cat template.db.in "${KSK1}.key" "${ZSK1}.key" "${KSK2}.key" "${ZSK2}.key" >"$infile"
-private_type_record $zone 8 "$KSK1" >>"$infile"
-private_type_record $zone 8 "$ZSK1" >>"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK2" >>"$infile"
-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 csk-algorithm-roll.kasp represent the various steps of a CSK
# algorithm rollover.
start_time = KeyTimingMetadata.now()
- # Test algorithm rollover (KSK/ZSK split).
- isctest.log.info("check algorithm rollover ksk/zsk split")
- offset = -timedelta(days=7)
- offval = int(offset.total_seconds())
- step = {
- "zone": "step1.algorithm-roll.kasp",
- "cdss": cdss,
- "config": algoroll_config,
- "policy": "rsasha256",
- "keyprops": [
- f"ksk 0 8 2048 goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{offval}",
- f"zsk 0 8 2048 goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{offval}",
- ],
- "nextev": timedelta(hours=1),
- }
- steps.append(step)
-
# Test algorithm rollover (CSK).
isctest.log.info("check algorithm rollover csk")
step = {
now = KeyTimingMetadata.now()
time_passed = now.value - start_time.value
- # Test algorithm rollover (KSK/ZSK split) (after reconfig).
- isctest.log.info("check algorithm rollover ksk/zsk split (after reconfig)")
- offset = -timedelta(days=7)
- offval = int(offset.total_seconds())
- ipub = Ipub(algoroll_config)
- ipubc = IpubC(algoroll_config, rollover=False)
- iret = Iret(algoroll_config, rollover=False)
- iretKSK = Iret(algoroll_config, zsk=False, ksk=True, rollover=False)
- keyttlprop = (
- algoroll_config["dnskey-ttl"] + algoroll_config["zone-propagation-delay"]
- )
- offsets = {}
- offsets["step2"] = -int(ipub.total_seconds())
- offsets["step3"] = -int(iret.total_seconds())
- offsets["step4"] = offsets["step3"] - int(iretKSK.total_seconds())
- offsets["step5"] = offsets["step4"] - int(keyttlprop.total_seconds())
- offsets["step6"] = offsets["step5"] - int(iret.total_seconds())
- algo_steps = [
- {
- # Step 1.
- "zone": "step1.algorithm-roll.kasp",
- "cdss": cdss,
- "config": algoroll_config,
- "policy": "ecdsa256",
- "keyprops": [
- # The RSASHA keys are outroducing.
- f"ksk 0 8 2048 goal:hidden dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{offval}",
- f"zsk 0 8 2048 goal:hidden dnskey:omnipresent zrrsig:omnipresent offset:{offval}",
- # The ECDSAP256SHA256 keys are introducing.
- f"ksk 0 {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured ds:hidden",
- f"zsk 0 {alg} {size} goal:omnipresent dnskey:rumoured zrrsig:rumoured",
- ],
- # Next key event is when the ecdsa256 keys have been propagated.
- "nextev": ipub,
- },
- {
- # Step 2.
- "zone": "step2.algorithm-roll.kasp",
- "cdss": cdss,
- "config": algoroll_config,
- "policy": "ecdsa256",
- "keyprops": [
- # The RSASHA keys are outroducing, but need to stay present
- # until the new algorithm chain of trust has been established.
- # Thus the expected key states of these keys stay the same.
- f"ksk 0 8 2048 goal:hidden dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{offval}",
- f"zsk 0 8 2048 goal:hidden dnskey:omnipresent zrrsig:omnipresent offset:{offval}",
- # The ECDSAP256SHA256 keys are introducing. The DNSKEY RRset is
- # omnipresent, but the zone signatures are not.
- f"ksk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:hidden offset:{offsets['step2']}",
- f"zsk 0 {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:rumoured offset:{offsets['step2']}",
- ],
- # Next key event is when all zone signatures are signed with the new
- # algorithm. This is the max-zone-ttl plus zone propagation delay. But
- # the publication interval has already passed. Also, prevent intermittent
- # false positives on slow platforms by subtracting the time passed between
- # key creation and invoking 'rndc reconfig'.
- "nextev": ipubc - ipub - time_passed,
- },
- {
- # Step 3.
- "zone": "step3.algorithm-roll.kasp",
- "cdss": cdss,
- "config": algoroll_config,
- "policy": "ecdsa256",
- "keyprops": [
- # The DS can be swapped.
- f"ksk 0 8 2048 goal:hidden dnskey:omnipresent krrsig:omnipresent ds:unretentive offset:{offval}",
- f"zsk 0 8 2048 goal:hidden dnskey:omnipresent zrrsig:omnipresent offset:{offval}",
- f"ksk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:rumoured offset:{offsets['step3']}",
- f"zsk 0 {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{offsets['step3']}",
- ],
- # Next key event is when the DS becomes OMNIPRESENT. This happens
- # after the retire interval.
- "nextev": iretKSK - time_passed,
- },
- {
- # Step 4.
- "zone": "step4.algorithm-roll.kasp",
- "cdss": cdss,
- "config": algoroll_config,
- "policy": "ecdsa256",
- "keyprops": [
- # The old DS is HIDDEN, we can remove the old algorithm records.
- f"ksk 0 8 2048 goal:hidden dnskey:unretentive krrsig:unretentive ds:hidden offset:{offval}",
- f"zsk 0 8 2048 goal:hidden dnskey:unretentive zrrsig:unretentive offset:{offval}",
- f"ksk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{offsets['step4']}",
- f"zsk 0 {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{offsets['step4']}",
- ],
- # Next key event is when the old DNSKEY becomes HIDDEN.
- # This happens after the DNSKEY TTL plus zone propagation delay.
- "nextev": keyttlprop,
- },
- {
- # Step 5.
- "zone": "step5.algorithm-roll.kasp",
- "cdss": cdss,
- "config": algoroll_config,
- "policy": "ecdsa256",
- "keyprops": [
- # The DNSKEY becomes HIDDEN.
- f"ksk 0 8 2048 goal:hidden dnskey:hidden krrsig:hidden ds:hidden offset:{offval}",
- f"zsk 0 8 2048 goal:hidden dnskey:hidden zrrsig:unretentive offset:{offval}",
- f"ksk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{offsets['step5']}",
- f"zsk 0 {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{offsets['step5']}",
- ],
- # Next key event is when the RSASHA signatures become HIDDEN.
- # This happens after the max-zone-ttl plus zone propagation delay
- # minus the time already passed since the UNRETENTIVE state has
- # been reached. Prevent intermittent false positives on slow
- # platforms by subtracting the number of seconds which passed
- # between key creation and invoking 'rndc reconfig'.
- "nextev": iret - iretKSK - keyttlprop - time_passed,
- },
- {
- # Step 6.
- "zone": "step6.algorithm-roll.kasp",
- "cdss": cdss,
- "config": algoroll_config,
- "policy": "ecdsa256",
- "keyprops": [
- # The zone signatures are now HIDDEN.
- f"ksk 0 8 2048 goal:hidden dnskey:hidden krrsig:hidden ds:hidden offset:{offval}",
- f"zsk 0 8 2048 goal:hidden dnskey:hidden zrrsig:hidden offset:{offval}",
- f"ksk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{offsets['step6']}",
- f"zsk 0 {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{offsets['step6']}",
- ],
- # Next key event is never since we established the policy and the
- # keys have an unlimited lifetime. Fallback to the default
- # loadkeys interval.
- "nextev": timedelta(hours=1),
- },
- ]
- steps = steps + algo_steps
-
# Test algorithm rollover (CSK) (after reconfig).
isctest.log.info("check algorithm rollover csk (after reconfig)")
offsets = {}