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