]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Isolate rollover-csk-roll1 test case
authorNicki Křížek <nicki@isc.org>
Mon, 9 Jun 2025 15:42:08 +0000 (17:42 +0200)
committerNicki Křížek <nicki@isc.org>
Fri, 18 Jul 2025 11:37:58 +0000 (13:37 +0200)
bin/tests/system/rollover-csk-roll1/common.py [new symlink]
bin/tests/system/rollover-csk-roll1/ns3/kasp.conf.j2 [new file with mode: 0644]
bin/tests/system/rollover-csk-roll1/ns3/named.common.conf.j2 [new symlink]
bin/tests/system/rollover-csk-roll1/ns3/named.conf.j2 [new file with mode: 0644]
bin/tests/system/rollover-csk-roll1/ns3/template.db.in [new symlink]
bin/tests/system/rollover-csk-roll1/setup.sh [new file with mode: 0644]
bin/tests/system/rollover-csk-roll1/tests_rollover_csk_roll1.py [new file with mode: 0644]
bin/tests/system/rollover/ns3/kasp.conf.j2
bin/tests/system/rollover/ns3/named.conf.j2
bin/tests/system/rollover/ns3/setup.sh
bin/tests/system/rollover/tests_rollover.py

diff --git a/bin/tests/system/rollover-csk-roll1/common.py b/bin/tests/system/rollover-csk-roll1/common.py
new file mode 120000 (symlink)
index 0000000..64b8084
--- /dev/null
@@ -0,0 +1 @@
+../rollover/common.py
\ No newline at end of file
diff --git a/bin/tests/system/rollover-csk-roll1/ns3/kasp.conf.j2 b/bin/tests/system/rollover-csk-roll1/ns3/kasp.conf.j2
new file mode 100644 (file)
index 0000000..3042773
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * 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 "csk-roll1" {
+       signatures-refresh P5D;
+       signatures-validity 30d;
+       signatures-validity-dnskey 30d;
+
+       dnskey-ttl 1h;
+       publish-safety PT1H;
+       retire-safety 2h;
+       purge-keys PT1H;
+
+       cds-digest-types { "sha-384"; }; // use a different digest type for testing purposes
+       keys {
+               csk key-directory lifetime P6M algorithm @DEFAULT_ALGORITHM@;
+       };
+
+       zone-propagation-delay 1h;
+       max-zone-ttl P1D;
+
+       parent-ds-ttl 1h;
+       parent-propagation-delay 1h;
+};
diff --git a/bin/tests/system/rollover-csk-roll1/ns3/named.common.conf.j2 b/bin/tests/system/rollover-csk-roll1/ns3/named.common.conf.j2
new file mode 120000 (symlink)
index 0000000..5dc2617
--- /dev/null
@@ -0,0 +1 @@
+../../rollover/ns3/named.common.conf.j2
\ No newline at end of file
diff --git a/bin/tests/system/rollover-csk-roll1/ns3/named.conf.j2 b/bin/tests/system/rollover-csk-roll1/ns3/named.conf.j2
new file mode 100644 (file)
index 0000000..2c4764e
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * 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.csk-roll1.autosign" {
+       type primary;
+       file "step1.csk-roll1.autosign.db";
+       dnssec-policy "csk-roll1";
+};
+zone "step2.csk-roll1.autosign" {
+       type primary;
+       file "step2.csk-roll1.autosign.db";
+       dnssec-policy "csk-roll1";
+};
+zone "step3.csk-roll1.autosign" {
+       type primary;
+       file "step3.csk-roll1.autosign.db";
+       dnssec-policy "csk-roll1";
+};
+zone "step4.csk-roll1.autosign" {
+       type primary;
+       file "step4.csk-roll1.autosign.db";
+       dnssec-policy "csk-roll1";
+};
+zone "step5.csk-roll1.autosign" {
+       type primary;
+       file "step5.csk-roll1.autosign.db";
+       dnssec-policy "csk-roll1";
+};
+zone "step6.csk-roll1.autosign" {
+       type primary;
+       file "step6.csk-roll1.autosign.db";
+       dnssec-policy "csk-roll1";
+};
+zone "step7.csk-roll1.autosign" {
+       type primary;
+       file "step7.csk-roll1.autosign.db";
+       dnssec-policy "csk-roll1";
+};
+zone "step8.csk-roll1.autosign" {
+       type primary;
+       file "step8.csk-roll1.autosign.db";
+       dnssec-policy "csk-roll1";
+};
diff --git a/bin/tests/system/rollover-csk-roll1/ns3/template.db.in b/bin/tests/system/rollover-csk-roll1/ns3/template.db.in
new file mode 120000 (symlink)
index 0000000..ce6d526
--- /dev/null
@@ -0,0 +1 @@
+../../rollover/ns3/template.db.in
\ No newline at end of file
diff --git a/bin/tests/system/rollover-csk-roll1/setup.sh b/bin/tests/system/rollover-csk-roll1/setup.sh
new file mode 100644 (file)
index 0000000..755876f
--- /dev/null
@@ -0,0 +1,312 @@
+#!/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 csk-roll1.autosign represent the various steps of a CSK rollover
+# (which is essentially a ZSK Pre-Publication / KSK Double-KSK rollover).
+#
+
+# Step 1:
+# Introduce the first key. This will immediately be active.
+setup step1.csk-roll1.autosign
+TactN="now-7d"
+keytimes="-P ${TactN} -A ${TactN}"
+CSK=$($KEYGEN -k csk-roll1 -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1)
+$SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN -z $O $TactN "$CSK" >settime.out.$zone.1 2>&1
+cat template.db.in "${CSK}.key" >"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK" >>"$infile"
+cp $infile $zonefile
+$SIGNER -S -z -x -G "cdnskey,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
+
+# Step 2:
+# It is time to introduce the new CSK.
+setup step2.csk-roll1.autosign
+# According to RFC 7583:
+# KSK: Tpub(N+1) <= Tact(N) + Lksk - IpubC
+# ZSK: Tpub(N+1) <= Tact(N) + Lzsk - Ipub
+# IpubC = DprpC + TTLkey (+publish-safety)
+# Ipub  = IpubC
+# Lcsk = Lksk = Lzsk
+#
+# Lcsk:           6mo (186d, 4464h)
+# Dreg:           N/A
+# DprpC:          1h
+# TTLkey:         1h
+# publish-safety: 1h
+# Ipub:           3h
+#
+# Tact(N) = now - Lcsk + Ipub = now - 186d + 3h
+#         = now - 4464h + 3h  = now - 4461h
+TactN="now-4461h"
+keytimes="-P ${TactN} -A ${TactN}"
+CSK=$($KEYGEN -k csk-roll1 -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1)
+$SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN -z $O $TactN "$CSK" >settime.out.$zone.1 2>&1
+cat template.db.in "${CSK}.key" >"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK" >>"$infile"
+cp $infile $zonefile
+$SIGNER -S -z -x -G "cdnskey,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
+
+# Step 3:
+# It is time to submit the DS and to roll signatures.
+setup step3.csk-roll1.autosign
+# According to RFC 7583:
+#
+# Tsbm(N+1) >= Trdy(N+1)
+# KSK: Tact(N+1) = Tsbm(N+1)
+# ZSK: Tact(N+1) = Tpub(N+1) + Ipub = Tsbm(N+1)
+# KSK: Iret  = DprpP + TTLds (+retire-safety)
+# ZSK: IretZ = Dsgn + Dprp + TTLsig (+retire-safety)
+#
+# Lcsk:           186d
+# Dprp:           1h
+# DprpP:          1h
+# Dreg:           N/A
+# Dsgn:           25d
+# TTLds:          1h
+# TTLsig:         1d
+# retire-safety:  2h
+# Iret:           4h
+# IretZ:          26d3h
+# Ipub:           3h
+#
+# Tpub(N)   = now - Lcsk = now - 186d
+# Tact(N)   = now - Lcsk + Dprp + TTLsig = now - 4439h
+# Tret(N)   = now
+# Trem(N)   = now + IretZ = now + 26d3h = now + 627h
+# Tpub(N+1) = now - Ipub = now - 3h
+# Tact(N+1) = Tret(N)
+# Tret(N+1) = now + Lcsk = now + 186d = now + 186d
+# Trem(N+1) = now + Lcsk + IretZ = now + 186d + 26d3h =
+#           = now + 5091h
+TpubN="now-186d"
+TactN="now-4439h"
+TretN="now"
+TremN="now+627h"
+TpubN1="now-3h"
+TactN1="${TretN}"
+TretN1="now+186d"
+TremN1="now+5091h"
+keytimes="-P ${TpubN}  -P sync ${TactN}  -A ${TpubN}  -I ${TretN}  -D ${TremN} -D sync ${TactN1}"
+newtimes="-P ${TpubN1} -P sync ${TactN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}"
+CSK1=$($KEYGEN -k csk-roll1 -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1)
+CSK2=$($KEYGEN -k csk-roll1 -l kasp.conf $newtimes $zone 2>keygen.out.$zone.2)
+$SETTIME -s -g $H -k $O $TactN -r $O $TactN -d $O $TactN -z $O $TactN "$CSK1" >settime.out.$zone.1 2>&1
+$SETTIME -s -g $O -k $R $TpubN1 -r $R $TpubN1 -d $H $TpubN1 -z $H $TpubN1 "$CSK2" >settime.out.$zone.2 2>&1
+# Set key rollover relationship.
+key_successor $CSK1 $CSK2
+# Sign zone.
+cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >>"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile"
+cp $infile $zonefile
+$SIGNER -S -z -x -G "cdnskey,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
+
+# Step 4:
+# Some time later all the ZRRSIG records should be from the new CSK, and the
+# DS should be swapped.  The ZRRSIG records are all replaced after IretZ
+# (which is 26d3h).  The DS is swapped after Iret (which is 4h).
+# In other words, the DS is swapped before all zone signatures are replaced.
+setup step4.csk-roll1.autosign
+# According to RFC 7583:
+# Trem(N)    = Tret(N) - Iret + IretZ
+# now       = Tsbm(N+1) + Iret
+#
+# Lcsk:   186d
+# Iret:   4h
+# IretZ:  26d3h
+#
+# Tpub(N)   = now - Iret - Lcsk = now - 4h - 186d = now - 4468h
+# Tret(N)   = now - Iret = now - 4h = now - 4h
+# Trem(N)   = now - Iret + IretZ = now - 4h + 26d3h
+#           = now + 623h
+# Tpub(N+1) = now - Iret - IpubC = now - 4h - 3h = now - 7h
+# Tact(N+1) = Tret(N)
+# Tret(N+1) = now - Iret + Lcsk = now - 4h + 186d = now + 4460h
+# Trem(N+1) = now - Iret + Lcsk + IretZ = now - 4h + 186d + 26d3h
+#           = now + 5087h
+TpubN="now-4468h"
+TactN="now-4443h"
+TretN="now-4h"
+TremN="now+623h"
+TpubN1="now-7h"
+TactN1="${TretN}"
+TretN1="now+4460h"
+TremN1="now+5087h"
+keytimes="-P ${TpubN}  -P sync ${TactN}  -A ${TpubN}  -I ${TretN}  -D ${TremN} -D sync ${TactN1}"
+newtimes="-P ${TpubN1} -P sync ${TactN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}"
+CSK1=$($KEYGEN -k csk-roll1 -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1)
+CSK2=$($KEYGEN -k csk-roll1 -l kasp.conf $newtimes $zone 2>keygen.out.$zone.2)
+$SETTIME -s -g $H -k $O $TactN -r $O $TactN -d $U $TactN1 -z $U $TactN1 -D ds $TactN1 "$CSK1" >settime.out.$zone.1 2>&1
+$SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $R $TactN1 -z $R $TactN1 -P ds $TactN1 "$CSK2" >settime.out.$zone.2 2>&1
+# Set key rollover relationship.
+key_successor $CSK1 $CSK2
+# Sign zone.
+cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >>"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile"
+cp $infile $zonefile
+$SIGNER -S -z -x -G "cdnskey,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
+
+# Step 5:
+# After the DS is swapped in step 4, also the KRRSIG records can be removed.
+# At this time these have all become hidden.
+setup step5.csk-roll1.autosign
+# Subtract DNSKEY TTL plus zone propagation delay from all the times (2h).
+TpubN="now-4470h"
+TactN="now-4445h"
+TretN="now-6h"
+TremN="now+621h"
+TpubN1="now-9h"
+TactN1="${TretN}"
+TretN1="now+4458h"
+TremN1="now+5085h"
+keytimes="-P ${TpubN}  -P sync ${TactN}  -A ${TpubN}  -I ${TretN}  -D ${TremN} -D sync ${TactN1}"
+newtimes="-P ${TpubN1} -P sync ${TactN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}"
+CSK1=$($KEYGEN -k csk-roll1 -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1)
+CSK2=$($KEYGEN -k csk-roll1 -l kasp.conf $newtimes $zone 2>keygen.out.$zone.2)
+$SETTIME -s -g $H -k $O $TactN -r $U now-2h -d $H now-2h -z $U $TactN1 "$CSK1" >settime.out.$zone.1 2>&1
+$SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $O now-2h -z $R $TactN1 "$CSK2" >settime.out.$zone.2 2>&1
+# Set key rollover relationship.
+key_successor $CSK1 $CSK2
+# Sign zone.
+cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >>"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile"
+cp $infile $zonefile
+$SIGNER -S -z -x -G "cdnskey,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
+
+# Step 6:
+# After the retire interval has passed the predecessor DNSKEY can be
+# removed from the zone.
+setup step6.csk-roll1.autosign
+# According to RFC 7583:
+# Trem(N) = Tret(N) + IretZ
+# Tret(N) = Tact(N) + Lcsk
+#
+# Lcsk:   186d
+# Iret:   4h
+# IretZ:  26d3h
+#
+# Tpub(N)   = now - IretZ - Lcsk = now - 627h - 186d
+#           = now - 627h - 4464h = now - 5091h
+# Tact(N)   = now - 627h - 186d
+# Tret(N)   = now - IretZ = now - 627h
+# Trem(N)   = now
+# Tpub(N+1) = now - IretZ - Ipub = now - 627h - 3h = now - 630h
+# Tact(N+1) = Tret(N)
+# Tret(N+1) = now - IretZ + Lcsk = now - 627h + 186d = now + 3837h
+# Trem(N+1) = now + Lcsk = now + 186d
+TpubN="now-5091h"
+TactN="now-5066h"
+TretN="now-627h"
+TremN="now"
+TpubN1="now-630h"
+TactN1="${TretN}"
+TretN1="now+3837h"
+TremN1="now+186d"
+keytimes="-P ${TpubN}  -P sync ${TactN}  -A ${TpubN}  -I ${TretN}  -D ${TremN} -D sync ${TactN1}"
+newtimes="-P ${TpubN1} -P sync ${TactN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}"
+CSK1=$($KEYGEN -k csk-roll1 -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1)
+CSK2=$($KEYGEN -k csk-roll1 -l kasp.conf $newtimes $zone 2>keygen.out.$zone.2)
+$SETTIME -s -g $H -k $O $TactN -r $H $TremN -d $H $TremN -z $U $TactN1 "$CSK1" >settime.out.$zone.1 2>&1
+$SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $O $TremN -z $R $TactN1 "$CSK2" >settime.out.$zone.2 2>&1
+# Set key rollover relationship.
+key_successor $CSK1 $CSK2
+# Sign zone.
+cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >>"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile"
+cp $infile $zonefile
+$SIGNER -S -z -x -G "cdnskey,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
+
+# Step 7:
+# Some time later the predecessor DNSKEY enters the HIDDEN state.
+setup step7.csk-roll1.autosign
+# Subtract DNSKEY TTL plus zone propagation delay from all the times (2h).
+TpubN="now-5093h"
+TactN="now-5068h"
+TretN="now-629h"
+TremN="now-2h"
+TpubN1="now-632h"
+TactN1="${TretN}"
+TretN1="now+3835h"
+TremN1="now+4462h"
+keytimes="-P ${TpubN}  -P sync ${TactN}  -A ${TpubN}  -I ${TretN}  -D ${TremN} -D sync ${TactN1}"
+newtimes="-P ${TpubN1} -P sync ${TactN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}"
+CSK1=$($KEYGEN -k csk-roll1 -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1)
+CSK2=$($KEYGEN -k csk-roll1 -l kasp.conf $newtimes $zone 2>keygen.out.$zone.2)
+$SETTIME -s -g $H -k $U $TremN -r $H $TremN -d $H $TremN -z $H $TactN1 "$CSK1" >settime.out.$zone.1 2>&1
+$SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $O $TactN1 -z $O $TactN1 "$CSK2" >settime.out.$zone.2 2>&1
+# Set key rollover relationship.
+key_successor $CSK1 $CSK2
+# Sign zone.
+cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >>"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile"
+cp $infile $zonefile
+$SIGNER -S -z -x -G "cdnskey,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
+
+# Step 8:
+# The predecessor DNSKEY can be purged.
+setup step8.csk-roll1.autosign
+TpubN="now-5094h"
+TactN="now-5069h"
+TretN="now-630h"
+TremN="now-3h"
+TpubN1="now-633h"
+TactN1="${TretN}"
+TretN1="now+3834h"
+TremN1="now+4461h"
+# Subtract purge-keys interval from all the times (1h).
+keytimes="-P ${TpubN}  -P sync ${TactN}  -A ${TpubN}  -I ${TretN}  -D ${TremN} -D sync ${TactN1}"
+newtimes="-P ${TpubN1} -P sync ${TactN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}"
+CSK1=$($KEYGEN -k csk-roll1 -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1)
+CSK2=$($KEYGEN -k csk-roll1 -l kasp.conf $newtimes $zone 2>keygen.out.$zone.2)
+$SETTIME -s -g $H -k $H $TremN -r $H $TremN -d $H $TremN -z $H $TactN1 "$CSK1" >settime.out.$zone.1 2>&1
+$SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $O $TactN1 -z $O $TactN1 "$CSK2" >settime.out.$zone.2 2>&1
+# Set key rollover relationship.
+key_successor $CSK1 $CSK2
+# Sign zone.
+cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >>"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile"
+cp $infile $zonefile
+$SIGNER -S -z -x -G "cdnskey,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
diff --git a/bin/tests/system/rollover-csk-roll1/tests_rollover_csk_roll1.py b/bin/tests/system/rollover-csk-roll1/tests_rollover_csk_roll1.py
new file mode 100644 (file)
index 0000000..9a265a6
--- /dev/null
@@ -0,0 +1,226 @@
+# 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 isctest.kasp import Ipub, Iret
+from common import (
+    pytestmark,
+    alg,
+    size,
+    TIMEDELTA,
+)
+
+
+CDSS = ["CDNSKEY", "CDS (SHA-384)"]
+CONFIG = {
+    "dnskey-ttl": TIMEDELTA["PT1H"],
+    "ds-ttl": TIMEDELTA["PT1H"],
+    "max-zone-ttl": TIMEDELTA["P1D"],
+    "parent-propagation-delay": TIMEDELTA["PT1H"],
+    "publish-safety": TIMEDELTA["PT1H"],
+    "purge-keys": TIMEDELTA["PT1H"],
+    "retire-safety": TIMEDELTA["PT2H"],
+    "signatures-refresh": TIMEDELTA["P5D"],
+    "signatures-validity": TIMEDELTA["P30D"],
+    "zone-propagation-delay": TIMEDELTA["PT1H"],
+}
+POLICY = "csk-roll1"
+CSK_LIFETIME = timedelta(days=31 * 6)
+LIFETIME_POLICY = int(CSK_LIFETIME.total_seconds())
+IPUB = Ipub(CONFIG)
+IRETZSK = Iret(CONFIG)
+IRETKSK = Iret(CONFIG, zsk=False, ksk=True)
+KEYTTLPROP = CONFIG["dnskey-ttl"] + CONFIG["zone-propagation-delay"]
+SIGNDELAY = IRETZSK - IRETKSK - KEYTTLPROP
+OFFSETS = {}
+OFFSETS["step1-p"] = -int(timedelta(days=7).total_seconds())
+OFFSETS["step2-p"] = -int(CSK_LIFETIME.total_seconds() - IPUB.total_seconds())
+OFFSETS["step2-s"] = 0
+OFFSETS["step3-p"] = -int(CSK_LIFETIME.total_seconds())
+OFFSETS["step3-s"] = -int(IPUB.total_seconds())
+OFFSETS["step4-p"] = OFFSETS["step3-p"] - int(IRETKSK.total_seconds())
+OFFSETS["step4-s"] = OFFSETS["step3-s"] - int(IRETKSK.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(SIGNDELAY.total_seconds())
+OFFSETS["step6-s"] = OFFSETS["step5-s"] - int(SIGNDELAY.total_seconds())
+OFFSETS["step7-p"] = OFFSETS["step6-p"] - int(KEYTTLPROP.total_seconds())
+OFFSETS["step7-s"] = OFFSETS["step6-s"] - int(KEYTTLPROP.total_seconds())
+OFFSETS["step8-p"] = OFFSETS["step7-p"] - int(CONFIG["purge-keys"].total_seconds())
+OFFSETS["step8-s"] = OFFSETS["step7-s"] - int(CONFIG["purge-keys"].total_seconds())
+
+
+def test_csk_roll1_step1(alg, size, servers):
+    step = {
+        # Introduce the first key. This will immediately be active.
+        "zone": "step1.csk-roll1.autosign",
+        "cdss": CDSS,
+        "keyprops": [
+            f"csk {LIFETIME_POLICY} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{OFFSETS['step1-p']}",
+        ],
+        # Next key event is when the successor CSK needs to be published
+        # minus time already elapsed. This is Lcsk - Ipub + Dreg (we ignore
+        # registration delay).
+        "nextev": CSK_LIFETIME - IPUB - timedelta(days=7),
+    }
+    isctest.kasp.check_rollover_step(servers["ns3"], CONFIG, POLICY, step)
+
+
+def test_csk_roll1_step2(alg, size, servers):
+    step = {
+        # Successor CSK is prepublished (signs DNSKEY RRset, but not yet
+        # other RRsets).
+        # CSK1 goal: omnipresent -> hidden
+        # CSK2 goal: hidden -> omnipresent
+        # CSK2 dnskey: hidden -> rumoured
+        # CSK2 krrsig: hidden -> rumoured
+        "zone": "step2.csk-roll1.autosign",
+        "cdss": CDSS,
+        "keyprops": [
+            f"csk {LIFETIME_POLICY} {alg} {size} goal:hidden dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{OFFSETS['step2-p']}",
+            f"csk {LIFETIME_POLICY} {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured zrrsig:hidden ds:hidden offset:{OFFSETS['step2-s']}",
+        ],
+        "keyrelationships": [0, 1],
+        # Next key event is when the successor CSK becomes OMNIPRESENT.
+        "nextev": IPUB,
+    }
+    isctest.kasp.check_rollover_step(servers["ns3"], CONFIG, POLICY, step)
+
+
+def test_csk_roll1_step3(alg, size, servers):
+    step = {
+        # Successor CSK becomes omnipresent, meaning we can start signing
+        # the remainder of the zone with the successor CSK, and we can
+        # submit the DS.
+        "zone": "step3.csk-roll1.autosign",
+        "cdss": CDSS,
+        # Predecessor CSK will be removed, so moving to UNRETENTIVE.
+        # CSK1 zrrsig: omnipresent -> unretentive
+        # Successor CSK DNSKEY is OMNIPRESENT, so moving ZRRSIG to RUMOURED.
+        # CSK2 dnskey: rumoured -> omnipresent
+        # CSK2 krrsig: rumoured -> omnipresent
+        # CSK2 zrrsig: hidden -> rumoured
+        # The predecessor DS can be withdrawn and the successor DS can be
+        # introduced.
+        # CSK1 ds: omnipresent -> unretentive
+        # CSK2 ds: hidden -> rumoured
+        "keyprops": [
+            f"csk {LIFETIME_POLICY} {alg} {size} goal:hidden dnskey:omnipresent krrsig:omnipresent zrrsig:unretentive ds:unretentive offset:{OFFSETS['step3-p']}",
+            f"csk {LIFETIME_POLICY} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:rumoured ds:rumoured offset:{OFFSETS['step3-s']}",
+        ],
+        "keyrelationships": [0, 1],
+        # 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": IRETKSK,
+        # Set 'smooth' to true so expected signatures of subdomain are
+        # from the predecessor ZSK.
+        "smooth": True,
+    }
+    isctest.kasp.check_rollover_step(servers["ns3"], CONFIG, POLICY, step)
+
+
+def test_csk_roll1_step4(alg, size, servers):
+    step = {
+        "zone": "step4.csk-roll1.autosign",
+        "cdss": CDSS,
+        # The predecessor CSK is no longer signing the DNSKEY RRset.
+        # CSK1 krrsig: omnipresent -> unretentive
+        # The predecessor DS is hidden. The successor DS is now omnipresent.
+        # CSK1 ds: unretentive -> hidden
+        # CSK2 ds: rumoured -> omnipresent
+        "keyprops": [
+            f"csk {LIFETIME_POLICY} {alg} {size} goal:hidden dnskey:omnipresent krrsig:unretentive zrrsig:unretentive ds:hidden offset:{OFFSETS['step4-p']}",
+            f"csk {LIFETIME_POLICY} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:rumoured ds:omnipresent offset:{OFFSETS['step4-s']}",
+        ],
+        "keyrelationships": [0, 1],
+        # Next key event is when the KRRSIG enters the HIDDEN state.
+        # This is the DNSKEY TTL plus zone propagation delay.
+        "nextev": KEYTTLPROP,
+        # We already swapped the DS in the previous step, so disable ds-swap.
+        "ds-swap": False,
+    }
+    isctest.kasp.check_rollover_step(servers["ns3"], CONFIG, POLICY, step)
+
+
+def test_csk_roll1_step5(alg, size, servers):
+    step = {
+        "zone": "step5.csk-roll1.autosign",
+        "cdss": CDSS,
+        # The predecessor KRRSIG records are now all hidden.
+        # CSK1 krrsig: unretentive -> hidden
+        "keyprops": [
+            f"csk {LIFETIME_POLICY} {alg} {size} goal:hidden dnskey:omnipresent krrsig:hidden zrrsig:unretentive ds:hidden offset:{OFFSETS['step5-p']}",
+            f"csk {LIFETIME_POLICY} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:rumoured ds:omnipresent offset:{OFFSETS['step5-s']}",
+        ],
+        "keyrelationships": [0, 1],
+        # Next key event is when the DNSKEY can be removed.  This is when
+        # all ZRRSIG records have been replaced with signatures of the new
+        # CSK.
+        "nextev": SIGNDELAY,
+    }
+    isctest.kasp.check_rollover_step(servers["ns3"], CONFIG, POLICY, step)
+
+
+def test_csk_roll1_step6(alg, size, servers):
+    step = {
+        "zone": "step6.csk-roll1.autosign",
+        "cdss": CDSS,
+        # The predecessor ZRRSIG records are now all hidden (so the DNSKEY
+        # can be removed).
+        # CSK1 dnskey: omnipresent -> unretentive
+        # CSK1 zrrsig: unretentive -> hidden
+        # CSK2 zrrsig: rumoured -> omnipresent
+        "keyprops": [
+            f"csk {LIFETIME_POLICY} {alg} {size} goal:hidden dnskey:unretentive krrsig:hidden zrrsig:hidden ds:hidden offset:{OFFSETS['step6-p']}",
+            f"csk {LIFETIME_POLICY} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{OFFSETS['step6-s']}",
+        ],
+        "keyrelationships": [0, 1],
+        # 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_csk_roll1_step7(alg, size, servers):
+    step = {
+        "zone": "step7.csk-roll1.autosign",
+        "cdss": CDSS,
+        # The predecessor CSK is now completely HIDDEN.
+        "keyprops": [
+            f"csk {LIFETIME_POLICY} {alg} {size} goal:hidden dnskey:hidden krrsig:hidden zrrsig:hidden ds:hidden offset:{OFFSETS['step7-p']}",
+            f"csk {LIFETIME_POLICY} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{OFFSETS['step7-s']}",
+        ],
+        "keyrelationships": [0, 1],
+        # Next key event is when the new successor needs to be published.
+        # This is the Lcsk, minus time passed since the key started signing,
+        # minus the prepublication time.
+        "nextev": CSK_LIFETIME - IRETZSK - IPUB - KEYTTLPROP,
+    }
+    isctest.kasp.check_rollover_step(servers["ns3"], CONFIG, POLICY, step)
+
+
+def test_csk_roll1_step8(alg, size, servers):
+    step = {
+        "zone": "step8.csk-roll1.autosign",
+        "cdss": CDSS,
+        "keyprops": [
+            f"csk {LIFETIME_POLICY} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{OFFSETS['step8-s']}",
+        ],
+        "nextev": None,
+    }
+    isctest.kasp.check_rollover_step(servers["ns3"], CONFIG, POLICY, step)
index 4a78c5b83f55eba41495a1fb150e6a5efc250753..80e76fae87a2fe46015b5ab21377fab75a249927 100644 (file)
@@ -90,25 +90,3 @@ dnssec-policy "ksk-doubleksk" {
        parent-ds-ttl 3600;
        parent-propagation-delay PT1H;
 };
-
-dnssec-policy "csk-roll1" {
-       signatures-refresh P5D;
-       signatures-validity 30d;
-       signatures-validity-dnskey 30d;
-
-       dnskey-ttl 1h;
-       publish-safety PT1H;
-       retire-safety 2h;
-       purge-keys PT1H;
-
-       cds-digest-types { "sha-384"; }; // use a different digest type for testing purposes
-       keys {
-               csk key-directory lifetime P6M algorithm @DEFAULT_ALGORITHM@;
-       };
-
-       zone-propagation-delay 1h;
-       max-zone-ttl P1D;
-
-       parent-ds-ttl 1h;
-       parent-propagation-delay 1h;
-};
index 6dc2383cce18669005cdec0385d15a67bb44e900..7a19129ccd48098a204f5a16dcd31e209d2035e1 100644 (file)
@@ -145,47 +145,3 @@ zone "three-is-a-crowd.kasp" {
         /* Use same policy as KSK rollover test zones. */
         dnssec-policy "ksk-doubleksk";
 };
-
-/*
- * Zones for testing CSK rollover steps.
- */
-zone "step1.csk-roll1.autosign" {
-       type primary;
-       file "step1.csk-roll1.autosign.db";
-       dnssec-policy "csk-roll1";
-};
-zone "step2.csk-roll1.autosign" {
-       type primary;
-       file "step2.csk-roll1.autosign.db";
-       dnssec-policy "csk-roll1";
-};
-zone "step3.csk-roll1.autosign" {
-       type primary;
-       file "step3.csk-roll1.autosign.db";
-       dnssec-policy "csk-roll1";
-};
-zone "step4.csk-roll1.autosign" {
-       type primary;
-       file "step4.csk-roll1.autosign.db";
-       dnssec-policy "csk-roll1";
-};
-zone "step5.csk-roll1.autosign" {
-       type primary;
-       file "step5.csk-roll1.autosign.db";
-       dnssec-policy "csk-roll1";
-};
-zone "step6.csk-roll1.autosign" {
-       type primary;
-       file "step6.csk-roll1.autosign.db";
-       dnssec-policy "csk-roll1";
-};
-zone "step7.csk-roll1.autosign" {
-       type primary;
-       file "step7.csk-roll1.autosign.db";
-       dnssec-policy "csk-roll1";
-};
-zone "step8.csk-roll1.autosign" {
-       type primary;
-       file "step8.csk-roll1.autosign.db";
-       dnssec-policy "csk-roll1";
-};
index bcb74bcbf144ac93bf5f1e3972aeae86e7fd798c..881e3bd565202e0bd039f3d5c2e4ddad10084da1 100644 (file)
@@ -558,275 +558,3 @@ 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
-
-#
-# The zones at csk-roll1.autosign represent the various steps of a CSK rollover
-# (which is essentially a ZSK Pre-Publication / KSK Double-KSK rollover).
-#
-
-# Step 1:
-# Introduce the first key. This will immediately be active.
-setup step1.csk-roll1.autosign
-TactN="now-7d"
-keytimes="-P ${TactN} -A ${TactN}"
-CSK=$($KEYGEN -k csk-roll1 -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1)
-$SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN -z $O $TactN "$CSK" >settime.out.$zone.1 2>&1
-cat template.db.in "${CSK}.key" >"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK" >>"$infile"
-cp $infile $zonefile
-$SIGNER -S -z -x -G "cdnskey,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
-
-# Step 2:
-# It is time to introduce the new CSK.
-setup step2.csk-roll1.autosign
-# According to RFC 7583:
-# KSK: Tpub(N+1) <= Tact(N) + Lksk - IpubC
-# ZSK: Tpub(N+1) <= Tact(N) + Lzsk - Ipub
-# IpubC = DprpC + TTLkey (+publish-safety)
-# Ipub  = IpubC
-# Lcsk = Lksk = Lzsk
-#
-# Lcsk:           6mo (186d, 4464h)
-# Dreg:           N/A
-# DprpC:          1h
-# TTLkey:         1h
-# publish-safety: 1h
-# Ipub:           3h
-#
-# Tact(N) = now - Lcsk + Ipub = now - 186d + 3h
-#         = now - 4464h + 3h  = now - 4461h
-TactN="now-4461h"
-keytimes="-P ${TactN} -A ${TactN}"
-CSK=$($KEYGEN -k csk-roll1 -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1)
-$SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN -z $O $TactN "$CSK" >settime.out.$zone.1 2>&1
-cat template.db.in "${CSK}.key" >"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK" >>"$infile"
-cp $infile $zonefile
-$SIGNER -S -z -x -G "cdnskey,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
-
-# Step 3:
-# It is time to submit the DS and to roll signatures.
-setup step3.csk-roll1.autosign
-# According to RFC 7583:
-#
-# Tsbm(N+1) >= Trdy(N+1)
-# KSK: Tact(N+1) = Tsbm(N+1)
-# ZSK: Tact(N+1) = Tpub(N+1) + Ipub = Tsbm(N+1)
-# KSK: Iret  = DprpP + TTLds (+retire-safety)
-# ZSK: IretZ = Dsgn + Dprp + TTLsig (+retire-safety)
-#
-# Lcsk:           186d
-# Dprp:           1h
-# DprpP:          1h
-# Dreg:           N/A
-# Dsgn:           25d
-# TTLds:          1h
-# TTLsig:         1d
-# retire-safety:  2h
-# Iret:           4h
-# IretZ:          26d3h
-# Ipub:           3h
-#
-# Tpub(N)   = now - Lcsk = now - 186d
-# Tact(N)   = now - Lcsk + Dprp + TTLsig = now - 4439h
-# Tret(N)   = now
-# Trem(N)   = now + IretZ = now + 26d3h = now + 627h
-# Tpub(N+1) = now - Ipub = now - 3h
-# Tact(N+1) = Tret(N)
-# Tret(N+1) = now + Lcsk = now + 186d = now + 186d
-# Trem(N+1) = now + Lcsk + IretZ = now + 186d + 26d3h =
-#           = now + 5091h
-TpubN="now-186d"
-TactN="now-4439h"
-TretN="now"
-TremN="now+627h"
-TpubN1="now-3h"
-TactN1="${TretN}"
-TretN1="now+186d"
-TremN1="now+5091h"
-keytimes="-P ${TpubN}  -P sync ${TactN}  -A ${TpubN}  -I ${TretN}  -D ${TremN} -D sync ${TactN1}"
-newtimes="-P ${TpubN1} -P sync ${TactN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}"
-CSK1=$($KEYGEN -k csk-roll1 -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1)
-CSK2=$($KEYGEN -k csk-roll1 -l kasp.conf $newtimes $zone 2>keygen.out.$zone.2)
-$SETTIME -s -g $H -k $O $TactN -r $O $TactN -d $O $TactN -z $O $TactN "$CSK1" >settime.out.$zone.1 2>&1
-$SETTIME -s -g $O -k $R $TpubN1 -r $R $TpubN1 -d $H $TpubN1 -z $H $TpubN1 "$CSK2" >settime.out.$zone.2 2>&1
-# Set key rollover relationship.
-key_successor $CSK1 $CSK2
-# Sign zone.
-cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >>"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile"
-cp $infile $zonefile
-$SIGNER -S -z -x -G "cdnskey,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
-
-# Step 4:
-# Some time later all the ZRRSIG records should be from the new CSK, and the
-# DS should be swapped.  The ZRRSIG records are all replaced after IretZ
-# (which is 26d3h).  The DS is swapped after Iret (which is 4h).
-# In other words, the DS is swapped before all zone signatures are replaced.
-setup step4.csk-roll1.autosign
-# According to RFC 7583:
-# Trem(N)    = Tret(N) - Iret + IretZ
-# now       = Tsbm(N+1) + Iret
-#
-# Lcsk:   186d
-# Iret:   4h
-# IretZ:  26d3h
-#
-# Tpub(N)   = now - Iret - Lcsk = now - 4h - 186d = now - 4468h
-# Tret(N)   = now - Iret = now - 4h = now - 4h
-# Trem(N)   = now - Iret + IretZ = now - 4h + 26d3h
-#           = now + 623h
-# Tpub(N+1) = now - Iret - IpubC = now - 4h - 3h = now - 7h
-# Tact(N+1) = Tret(N)
-# Tret(N+1) = now - Iret + Lcsk = now - 4h + 186d = now + 4460h
-# Trem(N+1) = now - Iret + Lcsk + IretZ = now - 4h + 186d + 26d3h
-#           = now + 5087h
-TpubN="now-4468h"
-TactN="now-4443h"
-TretN="now-4h"
-TremN="now+623h"
-TpubN1="now-7h"
-TactN1="${TretN}"
-TretN1="now+4460h"
-TremN1="now+5087h"
-keytimes="-P ${TpubN}  -P sync ${TactN}  -A ${TpubN}  -I ${TretN}  -D ${TremN} -D sync ${TactN1}"
-newtimes="-P ${TpubN1} -P sync ${TactN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}"
-CSK1=$($KEYGEN -k csk-roll1 -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1)
-CSK2=$($KEYGEN -k csk-roll1 -l kasp.conf $newtimes $zone 2>keygen.out.$zone.2)
-$SETTIME -s -g $H -k $O $TactN -r $O $TactN -d $U $TactN1 -z $U $TactN1 -D ds $TactN1 "$CSK1" >settime.out.$zone.1 2>&1
-$SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $R $TactN1 -z $R $TactN1 -P ds $TactN1 "$CSK2" >settime.out.$zone.2 2>&1
-# Set key rollover relationship.
-key_successor $CSK1 $CSK2
-# Sign zone.
-cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >>"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile"
-cp $infile $zonefile
-$SIGNER -S -z -x -G "cdnskey,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
-
-# Step 5:
-# After the DS is swapped in step 4, also the KRRSIG records can be removed.
-# At this time these have all become hidden.
-setup step5.csk-roll1.autosign
-# Subtract DNSKEY TTL plus zone propagation delay from all the times (2h).
-TpubN="now-4470h"
-TactN="now-4445h"
-TretN="now-6h"
-TremN="now+621h"
-TpubN1="now-9h"
-TactN1="${TretN}"
-TretN1="now+4458h"
-TremN1="now+5085h"
-keytimes="-P ${TpubN}  -P sync ${TactN}  -A ${TpubN}  -I ${TretN}  -D ${TremN} -D sync ${TactN1}"
-newtimes="-P ${TpubN1} -P sync ${TactN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}"
-CSK1=$($KEYGEN -k csk-roll1 -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1)
-CSK2=$($KEYGEN -k csk-roll1 -l kasp.conf $newtimes $zone 2>keygen.out.$zone.2)
-$SETTIME -s -g $H -k $O $TactN -r $U now-2h -d $H now-2h -z $U $TactN1 "$CSK1" >settime.out.$zone.1 2>&1
-$SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $O now-2h -z $R $TactN1 "$CSK2" >settime.out.$zone.2 2>&1
-# Set key rollover relationship.
-key_successor $CSK1 $CSK2
-# Sign zone.
-cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >>"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile"
-cp $infile $zonefile
-$SIGNER -S -z -x -G "cdnskey,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
-
-# Step 6:
-# After the retire interval has passed the predecessor DNSKEY can be
-# removed from the zone.
-setup step6.csk-roll1.autosign
-# According to RFC 7583:
-# Trem(N) = Tret(N) + IretZ
-# Tret(N) = Tact(N) + Lcsk
-#
-# Lcsk:   186d
-# Iret:   4h
-# IretZ:  26d3h
-#
-# Tpub(N)   = now - IretZ - Lcsk = now - 627h - 186d
-#           = now - 627h - 4464h = now - 5091h
-# Tact(N)   = now - 627h - 186d
-# Tret(N)   = now - IretZ = now - 627h
-# Trem(N)   = now
-# Tpub(N+1) = now - IretZ - Ipub = now - 627h - 3h = now - 630h
-# Tact(N+1) = Tret(N)
-# Tret(N+1) = now - IretZ + Lcsk = now - 627h + 186d = now + 3837h
-# Trem(N+1) = now + Lcsk = now + 186d
-TpubN="now-5091h"
-TactN="now-5066h"
-TretN="now-627h"
-TremN="now"
-TpubN1="now-630h"
-TactN1="${TretN}"
-TretN1="now+3837h"
-TremN1="now+186d"
-keytimes="-P ${TpubN}  -P sync ${TactN}  -A ${TpubN}  -I ${TretN}  -D ${TremN} -D sync ${TactN1}"
-newtimes="-P ${TpubN1} -P sync ${TactN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}"
-CSK1=$($KEYGEN -k csk-roll1 -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1)
-CSK2=$($KEYGEN -k csk-roll1 -l kasp.conf $newtimes $zone 2>keygen.out.$zone.2)
-$SETTIME -s -g $H -k $O $TactN -r $H $TremN -d $H $TremN -z $U $TactN1 "$CSK1" >settime.out.$zone.1 2>&1
-$SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $O $TremN -z $R $TactN1 "$CSK2" >settime.out.$zone.2 2>&1
-# Set key rollover relationship.
-key_successor $CSK1 $CSK2
-# Sign zone.
-cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >>"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile"
-cp $infile $zonefile
-$SIGNER -S -z -x -G "cdnskey,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
-
-# Step 7:
-# Some time later the predecessor DNSKEY enters the HIDDEN state.
-setup step7.csk-roll1.autosign
-# Subtract DNSKEY TTL plus zone propagation delay from all the times (2h).
-TpubN="now-5093h"
-TactN="now-5068h"
-TretN="now-629h"
-TremN="now-2h"
-TpubN1="now-632h"
-TactN1="${TretN}"
-TretN1="now+3835h"
-TremN1="now+4462h"
-keytimes="-P ${TpubN}  -P sync ${TactN}  -A ${TpubN}  -I ${TretN}  -D ${TremN} -D sync ${TactN1}"
-newtimes="-P ${TpubN1} -P sync ${TactN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}"
-CSK1=$($KEYGEN -k csk-roll1 -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1)
-CSK2=$($KEYGEN -k csk-roll1 -l kasp.conf $newtimes $zone 2>keygen.out.$zone.2)
-$SETTIME -s -g $H -k $U $TremN -r $H $TremN -d $H $TremN -z $H $TactN1 "$CSK1" >settime.out.$zone.1 2>&1
-$SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $O $TactN1 -z $O $TactN1 "$CSK2" >settime.out.$zone.2 2>&1
-# Set key rollover relationship.
-key_successor $CSK1 $CSK2
-# Sign zone.
-cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >>"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile"
-cp $infile $zonefile
-$SIGNER -S -z -x -G "cdnskey,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
-
-# Step 8:
-# The predecessor DNSKEY can be purged.
-setup step8.csk-roll1.autosign
-TpubN="now-5094h"
-TactN="now-5069h"
-TretN="now-630h"
-TremN="now-3h"
-TpubN1="now-633h"
-TactN1="${TretN}"
-TretN1="now+3834h"
-TremN1="now+4461h"
-# Subtract purge-keys interval from all the times (1h).
-keytimes="-P ${TpubN}  -P sync ${TactN}  -A ${TpubN}  -I ${TretN}  -D ${TremN} -D sync ${TactN1}"
-newtimes="-P ${TpubN1} -P sync ${TactN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}"
-CSK1=$($KEYGEN -k csk-roll1 -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1)
-CSK2=$($KEYGEN -k csk-roll1 -l kasp.conf $newtimes $zone 2>keygen.out.$zone.2)
-$SETTIME -s -g $H -k $H $TremN -r $H $TremN -d $H $TremN -z $H $TactN1 "$CSK1" >settime.out.$zone.1 2>&1
-$SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $O $TactN1 -z $O $TactN1 "$CSK2" >settime.out.$zone.2 2>&1
-# Set key rollover relationship.
-key_successor $CSK1 $CSK2
-# Sign zone.
-cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >>"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile"
-cp $infile $zonefile
-$SIGNER -S -z -x -G "cdnskey,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
index 8c37f610261dfb5f0e45d6645bbb551bb215df75..00a318bd4e7e83b123fe69a57f1195bb4a64bac8 100644 (file)
@@ -748,194 +748,3 @@ def test_rollover_ksk_doubleksk(servers):
     isctest.kasp.check_dnssecstatus(server, zone, keys, policy=policy)
     isctest.kasp.check_apex(server, zone, ksks, zsks, cdss=cdss)
     isctest.kasp.check_subdomain(server, zone, ksks, zsks)
-
-
-def test_rollover_csk_roll1(servers):
-    server = servers["ns3"]
-    policy = "csk-roll1"
-    cdss = ["CDNSKEY", "CDS (SHA-384)"]
-    config = {
-        "dnskey-ttl": timedelta(hours=1),
-        "ds-ttl": timedelta(seconds=3600),
-        "max-zone-ttl": timedelta(days=1),
-        "parent-propagation-delay": timedelta(hours=1),
-        "publish-safety": timedelta(hours=1),
-        "purge-keys": timedelta(hours=1),
-        "retire-safety": timedelta(hours=2),
-        "signatures-refresh": timedelta(days=5),
-        "signatures-validity": timedelta(days=30),
-        "zone-propagation-delay": timedelta(hours=1),
-    }
-    alg = os.environ["DEFAULT_ALGORITHM_NUMBER"]
-    size = os.environ["DEFAULT_BITS"]
-    csk_lifetime = timedelta(days=31 * 6)
-    lifetime_policy = int(csk_lifetime.total_seconds())
-
-    ipub = Ipub(config)
-    iretZSK = Iret(config)
-    iretKSK = Iret(config, zsk=False, ksk=True)
-    keyttlprop = config["dnskey-ttl"] + config["zone-propagation-delay"]
-    signdelay = iretZSK - iretKSK - keyttlprop
-    offsets = {}
-    offsets["step1-p"] = -int(timedelta(days=7).total_seconds())
-    offsets["step2-p"] = -int(csk_lifetime.total_seconds() - ipub.total_seconds())
-    offsets["step2-s"] = 0
-    offsets["step3-p"] = -int(csk_lifetime.total_seconds())
-    offsets["step3-s"] = -int(ipub.total_seconds())
-    offsets["step4-p"] = offsets["step3-p"] - int(iretKSK.total_seconds())
-    offsets["step4-s"] = offsets["step3-s"] - int(iretKSK.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(signdelay.total_seconds())
-    offsets["step6-s"] = offsets["step5-s"] - int(signdelay.total_seconds())
-    offsets["step7-p"] = offsets["step6-p"] - int(keyttlprop.total_seconds())
-    offsets["step7-s"] = offsets["step6-s"] - int(keyttlprop.total_seconds())
-    offsets["step8-p"] = offsets["step7-p"] - int(config["purge-keys"].total_seconds())
-    offsets["step8-s"] = offsets["step7-s"] - int(config["purge-keys"].total_seconds())
-
-    steps = [
-        {
-            # Step 1.
-            # Introduce the first key. This will immediately be active.
-            "zone": "step1.csk-roll1.autosign",
-            "cdss": cdss,
-            "keyprops": [
-                f"csk {lifetime_policy} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{offsets['step1-p']}",
-            ],
-            # Next key event is when the successor CSK needs to be published
-            # minus time already elapsed. This is Lcsk - Ipub + Dreg (we ignore
-            # registration delay).
-            "nextev": csk_lifetime - ipub - timedelta(days=7),
-        },
-        {
-            # Step 2.
-            # Successor CSK is prepublished (signs DNSKEY RRset, but not yet
-            # other RRsets).
-            # CSK1 goal: omnipresent -> hidden
-            # CSK2 goal: hidden -> omnipresent
-            # CSK2 dnskey: hidden -> rumoured
-            # CSK2 krrsig: hidden -> rumoured
-            "zone": "step2.csk-roll1.autosign",
-            "cdss": cdss,
-            "keyprops": [
-                f"csk {lifetime_policy} {alg} {size} goal:hidden dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{offsets['step2-p']}",
-                f"csk {lifetime_policy} {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured zrrsig:hidden ds:hidden offset:{offsets['step2-s']}",
-            ],
-            "keyrelationships": [0, 1],
-            # Next key event is when the successor CSK becomes OMNIPRESENT.
-            "nextev": ipub,
-        },
-        {
-            # Step 3.
-            # Successor CSK becomes omnipresent, meaning we can start signing
-            # the remainder of the zone with the successor CSK, and we can
-            # submit the DS.
-            "zone": "step3.csk-roll1.autosign",
-            "cdss": cdss,
-            # Predecessor CSK will be removed, so moving to UNRETENTIVE.
-            # CSK1 zrrsig: omnipresent -> unretentive
-            # Successor CSK DNSKEY is OMNIPRESENT, so moving ZRRSIG to RUMOURED.
-            # CSK2 dnskey: rumoured -> omnipresent
-            # CSK2 krrsig: rumoured -> omnipresent
-            # CSK2 zrrsig: hidden -> rumoured
-            # The predecessor DS can be withdrawn and the successor DS can be
-            # introduced.
-            # CSK1 ds: omnipresent -> unretentive
-            # CSK2 ds: hidden -> rumoured
-            "keyprops": [
-                f"csk {lifetime_policy} {alg} {size} goal:hidden dnskey:omnipresent krrsig:omnipresent zrrsig:unretentive ds:unretentive offset:{offsets['step3-p']}",
-                f"csk {lifetime_policy} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:rumoured ds:rumoured offset:{offsets['step3-s']}",
-            ],
-            "keyrelationships": [0, 1],
-            # 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": iretKSK,
-            # Set 'smooth' to true so expected signatures of subdomain are
-            # from the predecessor ZSK.
-            "smooth": True,
-        },
-        {
-            # Step 4.
-            "zone": "step4.csk-roll1.autosign",
-            "cdss": cdss,
-            # The predecessor CSK is no longer signing the DNSKEY RRset.
-            # CSK1 krrsig: omnipresent -> unretentive
-            # The predecessor DS is hidden. The successor DS is now omnipresent.
-            # CSK1 ds: unretentive -> hidden
-            # CSK2 ds: rumoured -> omnipresent
-            "keyprops": [
-                f"csk {lifetime_policy} {alg} {size} goal:hidden dnskey:omnipresent krrsig:unretentive zrrsig:unretentive ds:hidden offset:{offsets['step4-p']}",
-                f"csk {lifetime_policy} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:rumoured ds:omnipresent offset:{offsets['step4-s']}",
-            ],
-            "keyrelationships": [0, 1],
-            # Next key event is when the KRRSIG enters the HIDDEN state.
-            # This is the DNSKEY TTL plus zone propagation delay.
-            "nextev": keyttlprop,
-            # We already swapped the DS in the previous step, so disable ds-swap.
-            "ds-swap": False,
-        },
-        {
-            # Step 5.
-            "zone": "step5.csk-roll1.autosign",
-            "cdss": cdss,
-            # The predecessor KRRSIG records are now all hidden.
-            # CSK1 krrsig: unretentive -> hidden
-            "keyprops": [
-                f"csk {lifetime_policy} {alg} {size} goal:hidden dnskey:omnipresent krrsig:hidden zrrsig:unretentive ds:hidden offset:{offsets['step5-p']}",
-                f"csk {lifetime_policy} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:rumoured ds:omnipresent offset:{offsets['step5-s']}",
-            ],
-            "keyrelationships": [0, 1],
-            # Next key event is when the DNSKEY can be removed.  This is when
-            # all ZRRSIG records have been replaced with signatures of the new
-            # CSK.
-            "nextev": signdelay,
-        },
-        {
-            # Step 6.
-            "zone": "step6.csk-roll1.autosign",
-            "cdss": cdss,
-            # The predecessor ZRRSIG records are now all hidden (so the DNSKEY
-            # can be removed).
-            # CSK1 dnskey: omnipresent -> unretentive
-            # CSK1 zrrsig: unretentive -> hidden
-            # CSK2 zrrsig: rumoured -> omnipresent
-            "keyprops": [
-                f"csk {lifetime_policy} {alg} {size} goal:hidden dnskey:unretentive krrsig:hidden zrrsig:hidden ds:hidden offset:{offsets['step6-p']}",
-                f"csk {lifetime_policy} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{offsets['step6-s']}",
-            ],
-            "keyrelationships": [0, 1],
-            # Next key event is when the DNSKEY enters the HIDDEN state.
-            # This is the DNSKEY TTL plus zone propagation delay.
-            "nextev": keyttlprop,
-        },
-        {
-            # Step 7.
-            "zone": "step7.csk-roll1.autosign",
-            "cdss": cdss,
-            # The predecessor CSK is now completely HIDDEN.
-            "keyprops": [
-                f"csk {lifetime_policy} {alg} {size} goal:hidden dnskey:hidden krrsig:hidden zrrsig:hidden ds:hidden offset:{offsets['step7-p']}",
-                f"csk {lifetime_policy} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{offsets['step7-s']}",
-            ],
-            "keyrelationships": [0, 1],
-            # Next key event is when the new successor needs to be published.
-            # This is the Lcsk, minus time passed since the key started signing,
-            # minus the prepublication time.
-            "nextev": csk_lifetime - iretZSK - ipub - keyttlprop,
-        },
-        {
-            # Step 8.
-            # Predecessor CSK is now purged.
-            "zone": "step8.csk-roll1.autosign",
-            "cdss": cdss,
-            "keyprops": [
-                f"csk {lifetime_policy} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{offsets['step8-s']}",
-            ],
-            "nextev": None,
-        },
-    ]
-
-    for step in steps:
-        sctest.kasp.check_rollover_step(server, config, policy, step)