]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Convert csk rollover test cases to pytest
authorMatthijs Mekking <matthijs@isc.org>
Wed, 19 Mar 2025 09:10:13 +0000 (10:10 +0100)
committerMatthijs Mekking <matthijs@isc.org>
Mon, 2 Jun 2025 09:21:06 +0000 (09:21 +0000)
Move the 'csk-roll1' and 'csk-roll2' zones to the rollover test dir and
convert CSK rollover tests to pytest.

The DS swap spans multiple steps. Only the first time we should check
if the "CDS is now published" log is there, and only the first time we
should run 'rndc dnssec -checkds' on the keys. Add a new key to the
step dictionary to disable the DS swap checks.

This made me realize that we need to check for "is not None" in case
the value in the dictionary is False. Update check_rollover_step()
accordingly, and also add a log message which step/zone we are currently
checking.

bin/tests/system/kasp/ns3/named-fips.conf.in
bin/tests/system/kasp/ns3/policies/autosign.conf.in
bin/tests/system/kasp/ns3/setup.sh
bin/tests/system/kasp/tests.sh
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

index b93efa4ae06d97afcf3cc3afd3b7673f9dd99c81..109f3ad811fd9660d9afcc2fd352dd26ce4d967a 100644 (file)
@@ -312,83 +312,3 @@ zone "zsk-retired.autosign" {
        file "zsk-retired.autosign.db";
        dnssec-policy "autosign";
 };
-
-/*
- * Zones for testing CSK rollover steps.
- */
-zone "step1.csk-roll.autosign" {
-       type primary;
-       file "step1.csk-roll.autosign.db";
-       dnssec-policy "csk-roll";
-};
-zone "step2.csk-roll.autosign" {
-       type primary;
-       file "step2.csk-roll.autosign.db";
-       dnssec-policy "csk-roll";
-};
-zone "step3.csk-roll.autosign" {
-       type primary;
-       file "step3.csk-roll.autosign.db";
-       dnssec-policy "csk-roll";
-};
-zone "step4.csk-roll.autosign" {
-       type primary;
-       file "step4.csk-roll.autosign.db";
-       dnssec-policy "csk-roll";
-};
-zone "step5.csk-roll.autosign" {
-       type primary;
-       file "step5.csk-roll.autosign.db";
-       dnssec-policy "csk-roll";
-};
-zone "step6.csk-roll.autosign" {
-       type primary;
-       file "step6.csk-roll.autosign.db";
-       dnssec-policy "csk-roll";
-};
-zone "step7.csk-roll.autosign" {
-       type primary;
-       file "step7.csk-roll.autosign.db";
-       dnssec-policy "csk-roll";
-};
-zone "step8.csk-roll.autosign" {
-       type primary;
-       file "step8.csk-roll.autosign.db";
-       dnssec-policy "csk-roll";
-};
-
-zone "step1.csk-roll2.autosign" {
-       type primary;
-       file "step1.csk-roll2.autosign.db";
-       dnssec-policy "csk-roll2";
-};
-zone "step2.csk-roll2.autosign" {
-       type primary;
-       file "step2.csk-roll2.autosign.db";
-       dnssec-policy "csk-roll2";
-};
-zone "step3.csk-roll2.autosign" {
-       type primary;
-       file "step3.csk-roll2.autosign.db";
-       dnssec-policy "csk-roll2";
-};
-zone "step4.csk-roll2.autosign" {
-       type primary;
-       file "step4.csk-roll2.autosign.db";
-       dnssec-policy "csk-roll2";
-};
-zone "step5.csk-roll2.autosign" {
-       type primary;
-       file "step5.csk-roll2.autosign.db";
-       dnssec-policy "csk-roll2";
-};
-zone "step6.csk-roll2.autosign" {
-       type primary;
-       file "step6.csk-roll2.autosign.db";
-       dnssec-policy "csk-roll2";
-};
-zone "step7.csk-roll2.autosign" {
-       type primary;
-       file "step7.csk-roll2.autosign.db";
-       dnssec-policy "csk-roll2";
-};
index 5d1b0e47506484046eef4ae1ef5ae58a9e43aef7..c54786247f6722ad5d455ae4ddbe4d45d43906b2 100644 (file)
@@ -24,49 +24,3 @@ dnssec-policy "autosign" {
                zsk key-directory lifetime P1Y algorithm @DEFAULT_ALGORITHM@;
        };
 };
-
-dnssec-policy "csk-roll" {
-
-       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;
-};
-
-dnssec-policy "csk-roll2" {
-
-       signatures-refresh 12h;
-       signatures-validity P1D;
-       signatures-validity-dnskey P1D;
-
-       dnskey-ttl 1h;
-       publish-safety PT1H;
-       retire-safety 1h;
-       purge-keys 0;
-
-       cds-digest-types { "sha-256"; "sha-384"; }; // use two digest type for testing purposes
-       keys {
-               csk key-directory lifetime P6M algorithm @DEFAULT_ALGORITHM@;
-       };
-
-       zone-propagation-delay PT1H;
-       max-zone-ttl 1d;
-
-       parent-ds-ttl PT1H;
-       parent-propagation-delay P1W;
-};
index 86c16e4293b1a0d03700ec1fd8b83f5a46eb944d..4e521aa7696a08f76830a6fbbe9d764e8ad81c54 100644 (file)
@@ -280,558 +280,3 @@ T2="now-2y"
 oldtimes="-P $T2 -A $T2 -I $T1 -D $T1"
 OLD=$($KEYGEN -a $DEFAULT_ALGORITHM -L 300 $oldtimes $zone 2>keygen.out.$zone.3)
 $SETTIME -s -g $H -k $H $T1 -z $H $T1 "$OLD" >settime.out.$zone.3 2>&1
-
-#
-# The zones at csk-roll.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-roll.autosign
-TactN="now"
-csktimes="-P ${TactN} -P sync ${TactN} -A ${TactN}"
-CSK=$($KEYGEN -k csk-roll -l policies/autosign.conf $csktimes $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-roll.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) = Tnow - Lcsk + Ipub = now - 186d + 3h
-#         = now - 4464h + 3h = now - 4461h
-TactN="now-4461h"
-csktimes="-P ${TactN} -P sync ${TactN} -A ${TactN}"
-CSK=$($KEYGEN -k csk-roll -l policies/autosign.conf $csktimes $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-roll.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
-#
-# Tact(N)   = Tnow - Lcsk = now - 186d
-# Tret(N)   = now
-# Trem(N)   = Tnow + IretZ = now + 26d3h = now + 627h
-# Tpub(N+1) = Tnow - Ipub = now - 3h
-# Tsbm(N+1) = Tret(N)
-# Tact(N+1) = Tret(N)
-# Tret(N+1) = Tnow + Lcsk = now + 186d = now + 186d
-# Trem(N+1) = Tnow + Lcsk + IretZ = now + 186d + 26d3h =
-#           = now + 5091h
-TactN="now-186d"
-TretN="now"
-TremN="now+627h"
-TpubN1="now-3h"
-TsbmN1="now"
-TactN1="${TretN}"
-TretN1="now+186d"
-TremN1="now+5091h"
-csktimes="-P ${TactN}  -P sync ${TactN}  -A ${TactN}  -I ${TretN}  -D ${TremN}"
-newtimes="-P ${TpubN1} -P sync ${TsbmN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}"
-CSK1=$($KEYGEN -k csk-roll -l policies/autosign.conf $csktimes $zone 2>keygen.out.$zone.1)
-CSK2=$($KEYGEN -k csk-roll -l policies/autosign.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-roll.autosign
-# According to RFC 7583:
-# Trem(N)    = Tret(N) - Iret + IretZ
-# Tnow       = Tsbm(N+1) + Iret
-#
-# Lcsk:   186d
-# Iret:   4h
-# IretZ:  26d3h
-#
-# Tact(N)   = Tnow - Iret - Lcsk = now - 4h - 186d = now - 4468h
-# Tret(N)   = Tnow - Iret = now - 4h = now - 4h
-# Trem(N)   = Tnow - Iret + IretZ = now - 4h + 26d3h
-#           = now + 623h
-# Tpub(N+1) = Tnow - Iret - IpubC = now - 4h - 3h = now - 7h
-# Tsbm(N+1) = Tret(N)
-# Tact(N+1) = Tret(N)
-# Tret(N+1) = Tnow - Iret + Lcsk = now - 4h + 186d = now + 4460h
-# Trem(N+1) = Tnow - Iret + Lcsk + IretZ = now - 4h + 186d + 26d3h
-#          = now + 5087h
-TactN="now-4468h"
-TretN="now-4h"
-TremN="now+623h"
-TpubN1="now-7h"
-TsbmN1="${TretN}"
-TactN1="${TretN}"
-TretN1="now+4460h"
-TremN1="now+5087h"
-csktimes="-P ${TactN}  -P sync ${TactN}  -A ${TactN}  -I ${TretN}  -D ${TremN}"
-newtimes="-P ${TpubN1} -P sync ${TsbmN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}"
-CSK1=$($KEYGEN -k csk-roll -l policies/autosign.conf $csktimes $zone 2>keygen.out.$zone.1)
-CSK2=$($KEYGEN -k csk-roll -l policies/autosign.conf $newtimes $zone 2>keygen.out.$zone.2)
-$SETTIME -s -g $H -k $O $TactN -r $O $TactN -d $U $TsbmN1 -z $U $TsbmN1 -D ds $TsbmN1 "$CSK1" >settime.out.$zone.1 2>&1
-$SETTIME -s -g $O -k $O $TsbmN1 -r $O $TsbmN1 -d $R $TsbmN1 -z $R $TsbmN1 -P ds $TsbmN1 "$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-roll.autosign
-# Subtract DNSKEY TTL plus zone propagation delay from all the times (2h).
-# Tact(N)   = now - 4468h - 2h = now - 4470h
-# Tret(N)   = now - 4h - 2h = now - 6h
-# Trem(N)   = now + 623h - 2h = now + 621h
-# Tpub(N+1) = now - 7h - 2h = now - 9h
-# Tsbm(N+1) = Tret(N)
-# Tact(N+1) = Tret(N)
-# Tret(N+1) = now + 4460h - 2h = now + 4458h
-# Trem(N+1) = now + 5087h - 2h = now + 5085h
-TactN="now-4470h"
-TretN="now-6h"
-TremN="now+621h"
-TpubN1="now-9h"
-TsbmN1="${TretN}"
-TactN1="${TretN}"
-TretN1="now+4458h"
-TremN1="now+5085h"
-csktimes="-P ${TactN}  -P sync ${TactN}  -A ${TactN}  -I ${TretN}  -D ${TremN}"
-newtimes="-P ${TpubN1} -P sync ${TsbmN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}"
-CSK1=$($KEYGEN -k csk-roll -l policies/autosign.conf $csktimes $zone 2>keygen.out.$zone.1)
-CSK2=$($KEYGEN -k csk-roll -l policies/autosign.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 $TsbmN1 -r $O $TsbmN1 -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-roll.autosign
-# According to RFC 7583:
-# Trem(N) = Tret(N) + IretZ
-# Tret(N) = Tact(N) + Lcsk
-#
-# Lcsk:   186d
-# Iret:   4h
-# IretZ:  26d3h
-#
-# Tact(N)   = Tnow - IretZ - Lcsk = now - 627h - 186d
-#           = now - 627h - 4464h = now - 5091h
-# Tret(N)   = Tnow - IretZ = now - 627h
-# Trem(N)   = Tnow
-# Tpub(N+1) = Tnow - IretZ - Ipub = now - 627h - 3h = now - 630h
-# Tsbm(N+1) = Tret(N)
-# Tact(N+1) = Tret(N)
-# Tret(N+1) = Tnow - IretZ + Lcsk = now - 627h + 186d = now + 3837h
-# Trem(N+1) = Tnow + Lcsk = now + 186d
-TactN="now-5091h"
-TretN="now-627h"
-TremN="now"
-TpubN1="now-630h"
-TsbmN1="${TretN}"
-TactN1="${TretN}"
-TretN1="now+3837h"
-TremN1="now+186d"
-csktimes="-P ${TactN}  -P sync ${TactN}  -A ${TactN}  -I ${TretN}  -D ${TremN}"
-newtimes="-P ${TpubN1} -P sync ${TsbmN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}"
-CSK1=$($KEYGEN -k csk-roll -l policies/autosign.conf $csktimes $zone 2>keygen.out.$zone.1)
-CSK2=$($KEYGEN -k csk-roll -l policies/autosign.conf $newtimes $zone 2>keygen.out.$zone.2)
-$SETTIME -s -g $H -k $O $TactN -r $H $TremN -d $H $TremN -z $U $TsbmN1 "$CSK1" >settime.out.$zone.1 2>&1
-$SETTIME -s -g $O -k $O $TsbmN1 -r $O $TsbmN1 -d $O $TremN -z $R $TsbmN1 "$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-roll.autosign
-# Subtract DNSKEY TTL plus zone propagation delay from all the times (2h).
-# Tact(N) = now - 5091h - 2h = now - 5093h
-# Tret(N) = now - 627h - 2h  = now - 629h
-# Trem(N) = now - 2h
-# Tpub(N+1) = now - 630h - 2h = now - 632h
-# Tsbm(N+1) = Tret(N)
-# Tact(N+1) = Tret(N)
-# Tret(N+1) = now + 3837h - 2h = now + 3835h
-# Trem(N+1) = now + 186d - 2h = now + 4462h
-TactN="now-5093h"
-TretN="now-629h"
-TremN="now-2h"
-TpubN1="now-632h"
-TsbmN1="${TretN}"
-TactN1="${TretN}"
-TretN1="now+3835h"
-TremN1="now+4462h"
-csktimes="-P ${TactN}  -P sync ${TactN}  -A ${TactN}  -I ${TretN}  -D ${TremN}"
-newtimes="-P ${TpubN1} -P sync ${TsbmN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}"
-CSK1=$($KEYGEN -k csk-roll -l policies/autosign.conf $csktimes $zone 2>keygen.out.$zone.1)
-CSK2=$($KEYGEN -k csk-roll -l policies/autosign.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 $TsbmN1 -r $O $TsbmN1 -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-roll.autosign
-# Subtract purge-keys interval from all the times (1h).
-# Tact(N) = now - 5093h - 1h = now - 5094h
-# Tret(N) = now - 629h - 1h  = now - 630h
-# Trem(N) = now - 2h - 1h = now - 3h
-# Tpub(N+1) = now - 632h - 1h = now - 633h
-# Tsbm(N+1) = Tret(N)
-# Tact(N+1) = Tret(N)
-# Tret(N+1) = now + 3835h - 1h = now + 3834h
-# Trem(N+1) = now + 4462h - 1h = now + 4461h
-TactN="now-5094h"
-TretN="now-630h"
-TremN="now-3h"
-TpubN1="now-633h"
-TsbmN1="${TretN}"
-TactN1="${TretN}"
-TretN1="now+3834h"
-TremN1="now+4461h"
-csktimes="-P ${TactN}  -P sync ${TactN}  -A ${TactN}  -I ${TretN}  -D ${TremN}"
-newtimes="-P ${TpubN1} -P sync ${TsbmN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}"
-CSK1=$($KEYGEN -k csk-roll -l policies/autosign.conf $csktimes $zone 2>keygen.out.$zone.1)
-CSK2=$($KEYGEN -k csk-roll -l policies/autosign.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 $TsbmN1 -r $O $TsbmN1 -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
-
-#
-# The zones at csk-roll2.autosign represent the various steps of a CSK rollover
-# (which is essentially a ZSK Pre-Publication / KSK Double-KSK rollover).
-# This scenario differs from the above one because the zone signatures (ZRRSIG)
-# are replaced with the new key sooner than the DS is swapped.
-#
-
-# Step 1:
-# Introduce the first key. This will immediately be active.
-setup step1.csk-roll2.autosign
-TactN="now"
-csktimes="-P ${TactN} -P sync ${TactN} -A ${TactN}"
-CSK=$($KEYGEN -k csk-roll2 -l policies/autosign.conf $csktimes $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-256,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-roll2.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)  = Tnow - Lcsk + Ipub = now - 186d + 3h
-#          = now - 4464h + 3h = now - 4461h
-TactN="now-4461h"
-csktimes="-P ${TactN} -P sync ${TactN} -A ${TactN}"
-CSK=$($KEYGEN -k csk-roll2 -l policies/autosign.conf $csktimes $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-256,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-roll2.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:          1w
-# Dreg:           N/A
-# Dsgn:           12h
-# TTLds:          1h
-# TTLsig:         1d
-# retire-safety:  1h
-# Iret:           170h
-# IretZ:          38h
-# Ipub:           3h
-#
-# Tact(N)   = Tnow - Lcsk = now - 186d
-# Tret(N)   = now
-# Trem(N)   = Tnow + Iret = now + 170h
-# Tpub(N+1) = Tnow - Ipub = now - 3h
-# Tsbm(N+1) = Tret(N)
-# Tact(N+1) = Tret(N)
-# Tret(N+1) = Tnow + Lcsk = now + 186d
-# Trem(N+1) = Tnow + Lcsk + Iret = now + 186d + 170h =
-#           = now + 4464h + 170h = now + 4634h
-TactN="now-186d"
-TretN="now"
-TremN="now+170h"
-TpubN1="now-3h"
-TsbmN1="${TretN}"
-TactN1="${TretN}"
-TretN1="now+186d"
-TremN1="now+4634h"
-csktimes="-P ${TactN}  -P sync ${TactN}  -A ${TactN}  -I ${TretN}  -D ${TremN}"
-newtimes="-P ${TpubN1} -P sync ${TsbmN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}"
-CSK1=$($KEYGEN -k csk-roll2 -l policies/autosign.conf $csktimes $zone 2>keygen.out.$zone.1)
-CSK2=$($KEYGEN -k csk-roll2 -l policies/autosign.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-256,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 (38h).
-# The DS is swapped after Dreg + Iret (1w3h). In other words, the zone
-# signatures are replaced before the DS is swapped.
-setup step4.csk-roll2.autosign
-# According to RFC 7583:
-# Trem(N)    = Tret(N) + IretZ
-#
-# Lcsk:   186d
-# Dreg:   N/A
-# Iret:   170h
-# IretZ:  38h
-#
-# Tact(N)    = Tnow - IretZ = Lcsk = now - 38h - 186d
-#            = now - 38h - 4464h = now - 4502h
-# Tret(N)    = Tnow - IretZ = now - 38h
-# Trem(N)    = Tnow - IretZ + Iret = now - 38h + 170h = now + 132h
-# Tpub(N+1)  = Tnow - IretZ - IpubC = now - 38h - 3h = now - 41h
-# Tsbm(N+1)  = Tret(N)
-# Tact(N+1)  = Tret(N)
-# Tret(N+1)  = Tnow - IretZ + Lcsk = now - 38h + 186d
-#            = now + 4426h
-# Trem(N+1)  = Tnow - IretZ + Lcsk + Iret
-#            = now + 4426h + 3h = now + 4429h
-TactN="now-4502h"
-TretN="now-38h"
-TremN="now+132h"
-TpubN1="now-41h"
-TsbmN1="${TretN}"
-TactN1="${TretN}"
-TretN1="now+4426h"
-TremN1="now+4429h"
-csktimes="-P ${TactN}  -P sync ${TactN}  -A ${TactN}  -I ${TretN}  -D ${TremN}"
-newtimes="-P ${TpubN1} -P sync ${TsbmN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}"
-CSK1=$($KEYGEN -k csk-roll2 -l policies/autosign.conf $csktimes $zone 2>keygen.out.$zone.1)
-CSK2=$($KEYGEN -k csk-roll2 -l policies/autosign.conf $newtimes $zone 2>keygen.out.$zone.2)
-$SETTIME -s -g $H -k $O $TactN -r $O $TactN -z $U $TretN -d $U $TsbmN1 -D ds $TsbmN1 "$CSK1" >settime.out.$zone.1 2>&1
-$SETTIME -s -g $O -k $O $TsbmN1 -r $O $TsbmN1 -z $R $TactN1 -d $R $TsbmN1 -P ds $TsbmN1 "$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-256,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:
-# Some time later the DS can be swapped and the old DNSKEY can be removed from
-# the zone.
-setup step5.csk-roll2.autosign
-# Subtract Iret (170h) - IretZ (38h) = 132h.
-#
-# Tact(N)   = now - 4502h - 132h = now - 4634h
-# Tret(N)   = now - 38h - 132h = now - 170h
-# Trem(N)   = now + 132h - 132h = now
-# Tpub(N+1) = now - 41h - 132h = now - 173h
-# Tsbm(N+1) = Tret(N)
-# Tact(N+1) = Tret(N)
-# Tret(N+1) = now + 4426h - 132h = now + 4294h
-# Trem(N+1) = now + 4492h - 132h = now + 4360h
-TactN="now-4634h"
-TretN="now-170h"
-TremN="now"
-TpubN1="now-173h"
-TsbmN1="${TretN}"
-TactN1="${TretN}"
-TretN1="now+4294h"
-TremN1="now+4360h"
-csktimes="-P ${TactN}  -P sync ${TactN}  -A ${TactN}  -I ${TretN}  -D ${TremN}"
-newtimes="-P ${TpubN1} -P sync ${TsbmN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}"
-CSK1=$($KEYGEN -k csk-roll2 -l policies/autosign.conf $csktimes $zone 2>keygen.out.$zone.1)
-CSK2=$($KEYGEN -k csk-roll2 -l policies/autosign.conf $newtimes $zone 2>keygen.out.$zone.2)
-$SETTIME -s -g $H -k $O $TactN -r $O $TactN -z $H now-133h -d $U $TsbmN1 -D ds $TsbmN1 "$CSK1" >settime.out.$zone.1 2>&1
-$SETTIME -s -g $O -k $O $TsbmN1 -r $O $TsbmN1 -z $O now-133h -d $R $TsbmN1 -P ds $TsbmN1 "$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-256,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:
-# Some time later the predecessor DNSKEY enters the HIDDEN state.
-setup step6.csk-roll2.autosign
-# Subtract DNSKEY TTL plus zone propagation delay (2h).
-#
-# Tact(N)   = now - 4634h - 2h = now - 4636h
-# Tret(N)   = now - 170h - 2h = now - 172h
-# Trem(N)   = now - 2h
-# Tpub(N+1) = now - 173h - 2h = now - 175h
-# Tsbm(N+1) = Tret(N)
-# Tact(N+1) = Tret(N)
-# Tret(N+1) = now + 4294h - 2h = now + 4292h
-# Trem(N+1) = now + 4360h - 2h = now + 4358h
-TactN="now-4636h"
-TretN="now-172h"
-TremN="now-2h"
-TpubN1="now-175h"
-TsbmN1="${TretN}"
-TactN1="${TretN}"
-TretN1="now+4292h"
-TremN1="now+4358h"
-csktimes="-P ${TactN}  -P sync ${TactN}  -A ${TactN}  -I ${TretN}  -D ${TremN}"
-newtimes="-P ${TpubN1} -P sync ${TsbmN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}"
-CSK1=$($KEYGEN -k csk-roll2 -l policies/autosign.conf $csktimes $zone 2>keygen.out.$zone.1)
-CSK2=$($KEYGEN -k csk-roll2 -l policies/autosign.conf $newtimes $zone 2>keygen.out.$zone.2)
-$SETTIME -s -g $H -k $U $TremN -r $U $TremN -d $H $TremN -z $H now-135h "$CSK1" >settime.out.$zone.1 2>&1
-$SETTIME -s -g $O -k $O $TsbmN1 -r $O $TsbmN1 -d $O $TremN -z $O now-135h "$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-256,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:
-# The predecessor DNSKEY can be purged, but purge-keys is disabled.
-setup step7.csk-roll2.autosign
-# Subtract 90 days (default, 2160h) from all the times.
-# Tact(N)   = now - 4636h - 2160h = now - 6796h
-# Tret(N)   = now - 172h - 2160h = now - 2332h
-# Trem(N)   = now - 2h - 2160h = now - 2162h
-# Tpub(N+1) = now - 175h - 2160h = now - 2335h
-# Tsbm(N+1) = Tret(N)
-# Tact(N+1) = Tret(N)
-# Tret(N+1) = now + 4294h - 2160h = now + 2134h
-# Trem(N+1) = now + 4360h - 2160h = now + 2200h
-TactN="now-6796h"
-TretN="now-2332h"
-TremN="now-2162h"
-TpubN1="now-2335h"
-TsbmN1="${TretN}"
-TactN1="${TretN}"
-TretN1="now+2134h"
-TremN1="now+2200h"
-csktimes="-P ${TactN}  -P sync ${TactN}  -A ${TactN}  -I ${TretN}  -D ${TremN}"
-newtimes="-P ${TpubN1} -P sync ${TsbmN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}"
-CSK1=$($KEYGEN -k csk-roll2 -l policies/autosign.conf $csktimes $zone 2>keygen.out.$zone.1)
-CSK2=$($KEYGEN -k csk-roll2 -l policies/autosign.conf $newtimes $zone 2>keygen.out.$zone.2)
-$SETTIME -s -g $H -k $U $TremN -r $U $TremN -d $H $TremN -z $H now-135h "$CSK1" >settime.out.$zone.1 2>&1
-$SETTIME -s -g $O -k $O $TsbmN1 -r $O $TsbmN1 -d $O $TremN -z $O now-135h "$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-256,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
index 573e8c640491a1e3245e192f473930668d394dbd..094df0cefe60a5a0c27e00a1efd9685fcaa63f54 100644 (file)
@@ -266,21 +266,6 @@ rollover_predecessor_keytimes() {
   [ "$Lzsk" = 0 ] || set_retired_removed "KEY2" "${Lzsk}" "${IretZSK}"
 }
 
-#
-# Testing CSK key rollover (1).
-#
-
-# Policy parameters.
-# Lcsk:      186 days (5184000 seconds)
-# Iret(KSK): DS TTL (1h) + DprpP (1h) + retire-safety (2h)
-# Iret(KSK): 4h (14400 seconds)
-# Iret(ZSK): RRSIG TTL (1d) + Dprp (1h) + Dsgn (25d) + retire-safety (2h)
-# Iret(ZSK): 26d3h (2257200 seconds)
-Lcsk=16070400
-IretKSK=14400
-IretZSK=2257200
-IretCSK=$IretZSK
-
 csk_rollover_predecessor_keytimes() {
   _addtime=$1
 
@@ -291,654 +276,6 @@ csk_rollover_predecessor_keytimes() {
   [ "$Lcsk" = 0 ] || set_retired_removed "KEY1" "${Lcsk}" "${IretCSK}"
 }
 
-#
-# Zone: step1.csk-roll.autosign.
-#
-set_zone "step1.csk-roll.autosign"
-set_policy "csk-roll" "1" "3600"
-CDS_SHA256="no"
-CDS_SHA384="yes"
-set_server "ns3" "10.53.0.3"
-# Key properties.
-key_clear "KEY1"
-set_keyrole "KEY1" "csk"
-set_keylifetime "KEY1" "${Lcsk}"
-set_keyalgorithm "KEY1" "$DEFAULT_ALGORITHM_NUMBER" "$DEFAULT_ALGORITHM" "$DEFAULT_BITS"
-set_keysigning "KEY1" "yes"
-set_zonesigning "KEY1" "yes"
-# The CSK (KEY1) starts in OMNIPRESENT.
-set_keystate "KEY1" "GOAL" "omnipresent"
-set_keystate "KEY1" "STATE_DNSKEY" "omnipresent"
-set_keystate "KEY1" "STATE_KRRSIG" "omnipresent"
-set_keystate "KEY1" "STATE_ZRRSIG" "omnipresent"
-set_keystate "KEY1" "STATE_DS" "omnipresent"
-# Initially only one key.
-key_clear "KEY2"
-key_clear "KEY3"
-key_clear "KEY4"
-
-# Various signing policy checks.
-check_keys
-check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
-# This key is immediately published and activated.
-csk_rollover_predecessor_keytimes 0
-check_keytimes
-check_apex
-check_subdomain
-dnssec_verify
-
-# Next key event is when the successor CSK needs to be published.
-# This is Lcsk - Ipub - Dreg.
-# Lcsk: 186d (16070400 seconds)
-# Ipub: 3h   (10800 seconds)
-check_next_key_event 16059600
-
-#
-# Zone: step2.csk-roll.autosign.
-#
-set_zone "step2.csk-roll.autosign"
-set_policy "csk-roll" "2" "3600"
-CDS_SHA256="no"
-CDS_SHA384="yes"
-set_server "ns3" "10.53.0.3"
-# New CSK (KEY2) is prepublished (signs DNSKEY RRset, but not yet other RRsets).
-key_clear "KEY2"
-set_keyrole "KEY2" "csk"
-set_keylifetime "KEY2" "16070400"
-set_keyalgorithm "KEY2" "$DEFAULT_ALGORITHM_NUMBER" "$DEFAULT_ALGORITHM" "$DEFAULT_BITS"
-set_keysigning "KEY2" "yes"
-set_zonesigning "KEY2" "no"
-# Key states.
-set_keystate "KEY1" "GOAL" "hidden"
-set_keystate "KEY2" "GOAL" "omnipresent"
-set_keystate "KEY2" "STATE_DNSKEY" "rumoured"
-set_keystate "KEY2" "STATE_KRRSIG" "rumoured"
-set_keystate "KEY2" "STATE_ZRRSIG" "hidden"
-set_keystate "KEY2" "STATE_DS" "hidden"
-
-# Various signing policy checks.
-check_keys
-check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
-
-# Set expected key times:
-# - This key was activated 4461 hours ago (16059600 seconds).
-csk_rollover_predecessor_keytimes -16059600
-# - The new CSK is published now.
-created=$(key_get KEY2 CREATED)
-set_keytime "KEY2" "PUBLISHED" "${created}"
-# - The new CSK should publish the CDS after the prepublication time.
-#   Ipub: 3 hour (10800 seconds)
-Ipub="10800"
-set_addkeytime "KEY2" "SYNCPUBLISH" "${created}" "${Ipub}"
-set_addkeytime "KEY2" "ACTIVE" "${created}" "${Ipub}"
-set_retired_removed "KEY2" "${Lcsk}" "${IretCSK}"
-
-# Continue signing policy checks.
-check_keytimes
-check_apex
-check_subdomain
-dnssec_verify
-
-# Next key event is when the successor CSK becomes OMNIPRESENT.  That is the
-# DNSKEY TTL plus the zone propagation delay, plus the publish-safety. For
-# the csk-roll policy, this means 3 hours = 10800 seconds.
-check_next_key_event 10800
-
-#
-# Zone: step3.csk-roll.autosign.
-#
-set_zone "step3.csk-roll.autosign"
-set_policy "csk-roll" "2" "3600"
-CDS_SHA256="no"
-CDS_SHA384="yes"
-set_server "ns3" "10.53.0.3"
-# Swap zone signing role.
-set_zonesigning "KEY1" "no"
-set_zonesigning "KEY2" "yes"
-# CSK (KEY1) will be removed, so moving to UNRETENTIVE.
-set_keystate "KEY1" "STATE_ZRRSIG" "unretentive"
-# New CSK (KEY2) DNSKEY is OMNIPRESENT, so moving ZRRSIG to RUMOURED.
-set_keystate "KEY2" "STATE_DNSKEY" "omnipresent"
-set_keystate "KEY2" "STATE_KRRSIG" "omnipresent"
-set_keystate "KEY2" "STATE_ZRRSIG" "rumoured"
-# The old DS (KEY1) can be withdrawn and the new DS (KEY2) can be introduced.
-set_keystate "KEY1" "STATE_DS" "unretentive"
-set_keystate "KEY2" "STATE_DS" "rumoured"
-
-# Various signing policy checks.
-check_keys
-check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
-# Check that CDS publication is logged.
-check_cdslog "$DIR" "$ZONE" KEY2
-
-# Set expected key times:
-# - This key was activated 186 days ago (16070400 seconds).
-csk_rollover_predecessor_keytimes -16070400
-# - The new CSK is published three hours ago, CDS must be published now.
-created=$(key_get KEY2 CREATED)
-set_addkeytime "KEY2" "PUBLISHED" "${created}" "-${Ipub}"
-set_keytime "KEY2" "SYNCPUBLISH" "${created}"
-# - Also signatures are being introduced now.
-set_keytime "KEY2" "ACTIVE" "${created}"
-set_retired_removed "KEY2" "${Lcsk}" "${IretCSK}"
-
-# Continue signing policy checks.
-check_keytimes
-check_apex
-# Subdomain still has good signatures of old CSK (KEY1).
-# Set expected zone signing on for KEY1 and off for KEY2,
-# testing whether signatures which are still valid are being reused.
-set_zonesigning "KEY1" "yes"
-set_zonesigning "KEY2" "no"
-check_subdomain
-# Restore the expected zone signing properties.
-set_zonesigning "KEY1" "no"
-set_zonesigning "KEY2" "yes"
-dnssec_verify
-
-# We ignore any parent registration delay, so set the DS publish time to now.
-rndc_checkds "$SERVER" "$DIR" KEY1 "now" "withdrawn" "$ZONE"
-rndc_checkds "$SERVER" "$DIR" KEY2 "now" "published" "$ZONE"
-# 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, which is the parent propagation delay plus the DS TTL
-# plus the retire-safety.  For the csk-roll policy this means:
-# 1h + 1h + 2h = 4h = 14400 seconds.
-check_next_key_event 14400
-
-#
-# Zone: step4.csk-roll.autosign.
-#
-set_zone "step4.csk-roll.autosign"
-set_policy "csk-roll" "2" "3600"
-CDS_SHA256="no"
-CDS_SHA384="yes"
-set_server "ns3" "10.53.0.3"
-# The old CSK (KEY1) is no longer signing the DNSKEY RRset.
-set_keysigning "KEY1" "no"
-# The old CSK (KEY1) DS is hidden.  We still need to keep the DNSKEY public
-# but can remove the KRRSIG records.
-set_keystate "KEY1" "STATE_KRRSIG" "unretentive"
-set_keystate "KEY1" "STATE_DS" "hidden"
-# The new CSK (KEY2) DS is now OMNIPRESENT.
-set_keystate "KEY2" "STATE_DS" "omnipresent"
-
-# Various signing policy checks.
-check_keys
-check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
-
-# Set expected key times:
-# - This key was activated 4468 hours ago (16084800 seconds).
-csk_rollover_predecessor_keytimes -16084800
-# - The new CSK started signing 4h ago (14400 seconds).
-created=$(key_get KEY2 CREATED)
-set_addkeytime "KEY2" "ACTIVE" "${created}" -14400
-set_addkeytime "KEY2" "SYNCPUBLISH" "${created}" -14400
-syncpub=$(key_get KEY2 SYNCPUBLISH)
-set_addkeytime "KEY2" "PUBLISHED" "${syncpub}" "-${Ipub}"
-set_retired_removed "KEY2" "${Lcsk}" "${IretCSK}"
-
-# Continue signing policy checks.
-check_keytimes
-check_apex
-check_subdomain
-dnssec_verify
-
-# Next key event is when the KRRSIG enters the HIDDEN state.  This is the
-# DNSKEY TTL plus zone propagation delay. For the csk-roll policy this is:
-# 1h + 1h = 7200 seconds.
-check_next_key_event 7200
-
-#
-# Zone: step5.csk-roll.autosign.
-#
-set_zone "step5.csk-roll.autosign"
-set_policy "csk-roll" "2" "3600"
-CDS_SHA256="no"
-CDS_SHA384="yes"
-set_server "ns3" "10.53.0.3"
-# The old CSK (KEY1) KRRSIG records are now all hidden.
-set_keystate "KEY1" "STATE_KRRSIG" "hidden"
-
-# Various signing policy checks.
-check_keys
-check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
-
-# Set expected key times:
-# - This key was activated 4470 hours ago (16092000 seconds).
-csk_rollover_predecessor_keytimes -16092000
-# - The new CSK started signing 6h ago (21600 seconds).
-created=$(key_get KEY2 CREATED)
-set_addkeytime "KEY2" "ACTIVE" "${created}" -21600
-set_addkeytime "KEY2" "SYNCPUBLISH" "${created}" -21600
-syncpub=$(key_get KEY2 SYNCPUBLISH)
-set_addkeytime "KEY2" "PUBLISHED" "${syncpub}" "-${Ipub}"
-set_retired_removed "KEY2" "${Lcsk}" "${IretCSK}"
-
-# Continue signing policy checks.
-check_keytimes
-check_apex
-check_subdomain
-dnssec_verify
-
-# 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.  We have
-# calculated the interval to be 26d3h of which 4h (Iret(KSK)) plus
-# 2h (DNSKEY TTL + Dprp) have already passed.  So next key event is in
-# 26d3h - 4h - 2h = 621h = 2235600 seconds.
-check_next_key_event 2235600
-
-#
-# Zone: step6.csk-roll.autosign.
-#
-set_zone "step6.csk-roll.autosign"
-set_policy "csk-roll" "2" "3600"
-CDS_SHA256="no"
-CDS_SHA384="yes"
-set_server "ns3" "10.53.0.3"
-# The old CSK (KEY1) ZRRSIG records are now all hidden (so the DNSKEY can
-# be removed).
-set_keystate "KEY1" "STATE_DNSKEY" "unretentive"
-set_keystate "KEY1" "STATE_ZRRSIG" "hidden"
-# The new CSK (KEY2) is now fully OMNIPRESENT.
-set_keystate "KEY2" "STATE_ZRRSIG" "omnipresent"
-
-# Various signing policy checks.
-check_keys
-check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
-
-# Set expected key times
-# - This key was activated 5091 hours ago (18327600 seconds).
-csk_rollover_predecessor_keytimes -18327600
-# - The new CSK is activated 627 hours ago (2257200 seconds).
-created=$(key_get KEY2 CREATED)
-set_addkeytime "KEY2" "ACTIVE" "${created}" -2257200
-set_addkeytime "KEY2" "SYNCPUBLISH" "${created}" -2257200
-syncpub=$(key_get KEY2 SYNCPUBLISH)
-set_addkeytime "KEY2" "PUBLISHED" "${syncpub}" "-${Ipub}"
-set_retired_removed "KEY2" "${Lcsk}" "${IretCSK}"
-
-# Continue signing policy checks.
-check_keytimes
-check_apex
-check_subdomain
-dnssec_verify
-
-# Next key event is when the DNSKEY enters the HIDDEN state.  This is the
-# DNSKEY TTL plus zone propagation delay. For the csk-roll policy this is:
-# 1h + 1h = 7200 seconds.
-check_next_key_event 7200
-
-#
-# Zone: step7.csk-roll.autosign.
-#
-set_zone "step7.csk-roll.autosign"
-set_policy "csk-roll" "2" "3600"
-CDS_SHA256="no"
-CDS_SHA384="yes"
-set_server "ns3" "10.53.0.3"
-# The old CSK (KEY1) is now completely HIDDEN.
-set_keystate "KEY1" "STATE_DNSKEY" "hidden"
-
-# Various signing policy checks.
-check_keys
-check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
-
-# Set expected key times:
-# - This key was activated 5093 hours ago (18334800 seconds).
-csk_rollover_predecessor_keytimes -18334800
-# - The new CSK is activated 629 hours ago (2264400 seconds).
-created=$(key_get KEY2 CREATED)
-set_addkeytime "KEY2" "ACTIVE" "${created}" -2264400
-set_addkeytime "KEY2" "SYNCPUBLISH" "${created}" -2264400
-syncpub=$(key_get KEY2 SYNCPUBLISH)
-set_addkeytime "KEY2" "PUBLISHED" "${syncpub}" "-${Ipub}"
-set_retired_removed "KEY2" "${Lcsk}" "${IretCSK}"
-
-# Continue signing policy checks.
-check_keytimes
-check_apex
-check_subdomain
-dnssec_verify
-
-# 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.
-# Lcsk:        186d (16070400 seconds)
-# Time passed: 629h (2264400 seconds)
-# Ipub:        3h   (10800 seconds)
-check_next_key_event 13795200
-
-#
-# Zone: step8.csk-roll.autosign.
-#
-set_zone "step8.csk-roll.autosign"
-set_policy "csk-roll" "1" "3600"
-CDS_SHA256="no"
-CDS_SHA384="yes"
-set_server "ns3" "10.53.0.3"
-# The old CSK (KEY1) is purged.
-key_clear "KEY1"
-
-# Various signing policy checks.
-check_keys
-check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
-check_apex
-check_subdomain
-dnssec_verify
-
-#
-# Testing CSK key rollover (2).
-#
-
-# Policy parameters.
-# Lcsk:      186 days (16070400 seconds)
-# Dreg:      N/A
-# Iret(KSK): DS TTL (1h) + DprpP (1w) + retire-safety (1h)
-# Iret(KSK): 170h (61200 seconds)
-# Iret(ZSK): RRSIG TTL (1d) + Dprp (1h) + Dsgn (12h) + retire-safety (1h)
-# Iret(ZSK): 38h (136800 seconds)
-Lcsk=16070400
-IretKSK=612000
-IretZSK=136800
-IretCSK=$IretKSK
-
-#
-# Zone: step1.csk-roll2.autosign.
-#
-set_zone "step1.csk-roll2.autosign"
-set_policy "csk-roll2" "1" "3600"
-CDS_SHA384="yes"
-set_server "ns3" "10.53.0.3"
-# Key properties.
-key_clear "KEY1"
-set_keyrole "KEY1" "csk"
-set_keylifetime "KEY1" "16070400"
-set_keyalgorithm "KEY1" "$DEFAULT_ALGORITHM_NUMBER" "$DEFAULT_ALGORITHM" "$DEFAULT_BITS"
-set_keysigning "KEY1" "yes"
-set_zonesigning "KEY1" "yes"
-# The CSK (KEY1) starts in OMNIPRESENT.
-set_keystate "KEY1" "GOAL" "omnipresent"
-set_keystate "KEY1" "STATE_DNSKEY" "omnipresent"
-set_keystate "KEY1" "STATE_KRRSIG" "omnipresent"
-set_keystate "KEY1" "STATE_ZRRSIG" "omnipresent"
-set_keystate "KEY1" "STATE_DS" "omnipresent"
-# Initially only one key.
-key_clear "KEY2"
-key_clear "KEY3"
-key_clear "KEY4"
-
-# Various signing policy checks.
-check_keys
-check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
-# This key is immediately published and activated.
-csk_rollover_predecessor_keytimes 0
-check_keytimes
-check_apex
-check_subdomain
-dnssec_verify
-
-# Next key event is when the successor CSK needs to be published.
-# This is Lcsk - Ipub.
-# Lcsk:  186d   (16070400 seconds)
-# Ipub:  3h     (10800 seconds)
-# Total: 186d3h (16059600 seconds)
-check_next_key_event 16059600
-
-#
-# Zone: step2.csk-roll2.autosign.
-#
-set_zone "step2.csk-roll2.autosign"
-set_policy "csk-roll2" "2" "3600"
-CDS_SHA384="yes"
-set_server "ns3" "10.53.0.3"
-# New CSK (KEY2) is prepublished (signs DNSKEY RRset, but not yet other RRsets).
-key_clear "KEY2"
-set_keyrole "KEY2" "csk"
-set_keylifetime "KEY2" "16070400"
-set_keyalgorithm "KEY2" "$DEFAULT_ALGORITHM_NUMBER" "$DEFAULT_ALGORITHM" "$DEFAULT_BITS"
-set_keysigning "KEY2" "yes"
-set_zonesigning "KEY2" "no"
-# Key states.
-set_keystate "KEY1" "GOAL" "hidden"
-set_keystate "KEY2" "GOAL" "omnipresent"
-set_keystate "KEY2" "STATE_DNSKEY" "rumoured"
-set_keystate "KEY2" "STATE_KRRSIG" "rumoured"
-set_keystate "KEY2" "STATE_ZRRSIG" "hidden"
-set_keystate "KEY2" "STATE_DS" "hidden"
-
-# Various signing policy checks.
-check_keys
-check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
-
-# Set expected key times:
-# - This key was activated 4461 hours ago (16059600 seconds).
-csk_rollover_predecessor_keytimes -16059600
-# - The new CSK is published now.
-created=$(key_get KEY2 CREATED)
-set_keytime "KEY2" "PUBLISHED" "${created}"
-# - The new CSK should publish the CDS after the prepublication time.
-# - Ipub: 3 hour (10800 seconds)
-Ipub="10800"
-set_addkeytime "KEY2" "SYNCPUBLISH" "${created}" "${Ipub}"
-set_addkeytime "KEY2" "ACTIVE" "${created}" "${Ipub}"
-set_retired_removed "KEY2" "${Lcsk}" "${IretCSK}"
-
-# Continue signing policy checks.
-check_apex
-check_subdomain
-dnssec_verify
-
-# Next key event is when the successor CSK becomes OMNIPRESENT.  That is the
-# DNSKEY TTL plus the zone propagation delay, plus the publish-safety. For
-# the csk-roll2 policy, this means 3h hours = 10800 seconds.
-check_next_key_event 10800
-
-#
-# Zone: step3.csk-roll2.autosign.
-#
-set_zone "step3.csk-roll2.autosign"
-set_policy "csk-roll2" "2" "3600"
-CDS_SHA384="yes"
-set_server "ns3" "10.53.0.3"
-# CSK (KEY1) can be removed, so move to UNRETENTIVE.
-set_zonesigning "KEY1" "no"
-set_keystate "KEY1" "STATE_ZRRSIG" "unretentive"
-# New CSK (KEY2) DNSKEY is OMNIPRESENT, so move ZRRSIG to RUMOURED state.
-set_zonesigning "KEY2" "yes"
-set_keystate "KEY2" "STATE_DNSKEY" "omnipresent"
-set_keystate "KEY2" "STATE_KRRSIG" "omnipresent"
-set_keystate "KEY2" "STATE_ZRRSIG" "rumoured"
-# The old DS (KEY1) can be withdrawn and the new DS (KEY2) can be introduced.
-set_keystate "KEY1" "STATE_DS" "unretentive"
-set_keystate "KEY2" "STATE_DS" "rumoured"
-
-# Various signing policy checks.
-check_keys
-check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
-# Check that CDS publication is logged.
-check_cdslog "$DIR" "$ZONE" KEY2
-
-# Set expected key times:
-# - This key was activated 186 days ago (16070400 seconds).
-csk_rollover_predecessor_keytimes -16070400
-# - The new CSK is published three hours ago, CDS must be published now.
-created=$(key_get KEY2 CREATED)
-set_addkeytime "KEY2" "PUBLISHED" "${created}" "-${Ipub}"
-set_keytime "KEY2" "SYNCPUBLISH" "${created}"
-# - Also signatures are being introduced now.
-set_keytime "KEY2" "ACTIVE" "${created}"
-set_retired_removed "KEY2" "${Lcsk}" "${IretCSK}"
-
-# Continue signing policy checks.
-check_keytimes
-check_apex
-# Subdomain still has good signatures of old CSK (KEY1).
-# Set expected zone signing on for KEY1 and off for KEY2,
-# testing whether signatures which are still valid are being reused.
-set_zonesigning "KEY1" "yes"
-set_zonesigning "KEY2" "no"
-check_subdomain
-# Restore the expected zone signing properties.
-set_zonesigning "KEY1" "no"
-set_zonesigning "KEY2" "yes"
-dnssec_verify
-
-# We ignore any parent registration delay, so set the DS publish time to now.
-rndc_checkds "$SERVER" "$DIR" KEY1 "now" "withdrawn" "$ZONE"
-rndc_checkds "$SERVER" "$DIR" KEY2 "now" "published" "$ZONE"
-# Next key event is when the predecessor ZRRSIG records have been replaced
-# with that of the successor and enough time has passed such that the all
-# validators that have such signed RRsets in cache only know about the
-# successor signatures.  This is the retire interval: Dsgn plus the
-# maximum zone TTL plus the zone propagation delay plus retire-safety. For the
-# csk-roll2 policy that means: 12h (because 1d validity and refresh within
-# 12 hours) + 1d + 1h + 1h = 38h = 136800 seconds.  Prevent intermittent false
-# positives on slow platforms by subtracting the number of seconds which
-# passed between key creation and invoking 'rndc dnssec -checkds'.
-now="$(TZ=UTC date +%s)"
-time_passed=$((now - start_time))
-next_time=$((136800 - time_passed))
-check_next_key_event $next_time
-
-#
-# Zone: step4.csk-roll2.autosign.
-#
-set_zone "step4.csk-roll2.autosign"
-set_policy "csk-roll2" "2" "3600"
-CDS_SHA384="yes"
-set_server "ns3" "10.53.0.3"
-# The old CSK (KEY1) ZRRSIG is now HIDDEN.
-set_keystate "KEY1" "STATE_ZRRSIG" "hidden"
-# The new CSK (KEY2) ZRRSIG is now OMNIPRESENT.
-set_keystate "KEY2" "STATE_ZRRSIG" "omnipresent"
-
-# Various signing policy checks.
-check_keys
-check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
-
-# Set expected key times:
-# - This key was activated 4502 hours ago (16207200 seconds).
-csk_rollover_predecessor_keytimes -16207200
-# - The new CSK was published 41 hours (147600 seconds) ago.
-created=$(key_get KEY2 CREATED)
-set_addkeytime "KEY2" "PUBLISHED" "${created}" -147600
-published=$(key_get KEY2 PUBLISHED)
-set_addkeytime "KEY2" "SYNCPUBLISH" "${published}" "${Ipub}"
-set_addkeytime "KEY2" "ACTIVE" "${published}" "${Ipub}"
-set_retired_removed "KEY2" "${Lcsk}" "${IretCSK}"
-
-# Continue signing policy checks.
-check_keytimes
-check_apex
-check_subdomain
-dnssec_verify
-
-# 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
-# registration delay plus the retire interval, which is the parent
-# propagation delay plus the DS TTL plus the retire-safety.  For the
-# csk-roll2 policy this means: 1w + 1h + 1h = 170h = 612000 seconds.
-# However, 136800 seconds have passed already, so 478800 seconds left.
-check_next_key_event 475200
-
-#
-# Zone: step5.csk-roll2.autosign.
-#
-set_zone "step5.csk-roll2.autosign"
-set_policy "csk-roll2" "2" "3600"
-CDS_SHA384="yes"
-set_server "ns3" "10.53.0.3"
-# The old CSK (KEY1) DNSKEY can be removed.
-set_keysigning "KEY1" "no"
-set_keystate "KEY1" "STATE_DNSKEY" "unretentive"
-set_keystate "KEY1" "STATE_KRRSIG" "unretentive"
-set_keystate "KEY1" "STATE_DS" "hidden"
-# The new CSK (KEY2) is now fully OMNIPRESENT.
-set_keystate "KEY2" "STATE_DS" "omnipresent"
-
-# Various signing policy checks.
-check_keys
-check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
-
-# Set expected key times:
-# - This key was activated 4634 hours ago (16682400 seconds).
-csk_rollover_predecessor_keytimes -16682400
-# - The new CSK was published 173 hours (622800 seconds) ago.
-created=$(key_get KEY2 CREATED)
-set_addkeytime "KEY2" "PUBLISHED" "${created}" -622800
-published=$(key_get KEY2 PUBLISHED)
-set_addkeytime "KEY2" "SYNCPUBLISH" "${published}" "${Ipub}"
-set_addkeytime "KEY2" "ACTIVE" "${published}" "${Ipub}"
-set_retired_removed "KEY2" "${Lcsk}" "${IretCSK}"
-
-# Continue signing policy checks.
-check_keytimes
-check_apex
-check_subdomain
-dnssec_verify
-
-# Next key event is when the DNSKEY enters the HIDDEN state.  This is the
-# DNSKEY TTL plus zone propagation delay. For the csk-roll policy this is:
-# 1h + 1h = 7200 seconds.
-check_next_key_event 7200
-
-#
-# Zone: step6.csk-roll2.autosign.
-#
-set_zone "step6.csk-roll2.autosign"
-set_policy "csk-roll2" "2" "3600"
-CDS_SHA384="yes"
-set_server "ns3" "10.53.0.3"
-# The old CSK (KEY1) is now completely HIDDEN.
-set_keystate "KEY1" "STATE_DNSKEY" "hidden"
-set_keystate "KEY1" "STATE_KRRSIG" "hidden"
-
-# Various signing policy checks.
-check_keys
-check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
-
-# Set expected key times:
-# - This key was activated 4636 hours ago (16689600 seconds).
-csk_rollover_predecessor_keytimes -16689600
-# - The new CSK was published 175 hours (630000 seconds) ago.
-created=$(key_get KEY2 CREATED)
-set_addkeytime "KEY2" "PUBLISHED" "${created}" -630000
-published=$(key_get KEY2 PUBLISHED)
-set_addkeytime "KEY2" "SYNCPUBLISH" "${published}" "${Ipub}"
-set_addkeytime "KEY2" "ACTIVE" "${published}" "${Ipub}"
-set_retired_removed "KEY2" "${Lcsk}" "${IretCSK}"
-
-# Continue signing policy checks.
-check_keytimes
-check_apex
-check_subdomain
-dnssec_verify
-
-# Next key event is when the new successor needs to be published.
-# This is the Lcsk, minus time passed since the key was published.
-# Lcsk:        186d (16070400 seconds)
-# Time passed: 175h (630000 seconds)
-check_next_key_event 15440400
-
-#
-# Zone: step7.csk-roll2.autosign.
-#
-set_zone "step7.csk-roll2.autosign"
-set_policy "csk-roll2" "2" "3600"
-CDS_SHA384="yes"
-set_server "ns3" "10.53.0.3"
-# The old CSK (KEY1) could have been purged, but purge-keys is disabled.
-
-# Various signing policy checks.
-check_keys
-check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
-check_apex
-check_subdomain
-dnssec_verify
-
 # Test dynamic zones that switch to inline-signing.
 set_zone "dynamic2inline.kasp"
 set_policy "default" "1" "3600"
index 80e76fae87a2fe46015b5ab21377fab75a249927..e3ed534a519569eb88aeabe593412cb80ea84599 100644 (file)
@@ -90,3 +90,47 @@ 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;
+};
+
+dnssec-policy "csk-roll2" {
+       signatures-refresh 12h;
+       signatures-validity P1D;
+       signatures-validity-dnskey P1D;
+
+       dnskey-ttl 1h;
+       publish-safety PT1H;
+       retire-safety 1h;
+       purge-keys 0;
+
+       cds-digest-types { "sha-256"; "sha-384"; }; // use two digest type for testing purposes
+       keys {
+               csk key-directory lifetime P6M algorithm @DEFAULT_ALGORITHM@;
+       };
+
+       zone-propagation-delay PT1H;
+       max-zone-ttl 1d;
+
+       parent-ds-ttl PT1H;
+       parent-propagation-delay P1W;
+};
index c183ac8975988d61220c22b6b5e54fdbb39ed05c..06679deb161504e89cd372117067de560ee86bf8 100644 (file)
@@ -170,3 +170,83 @@ 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";
+};
+
+zone "step1.csk-roll2.autosign" {
+       type primary;
+       file "step1.csk-roll2.autosign.db";
+       dnssec-policy "csk-roll2";
+};
+zone "step2.csk-roll2.autosign" {
+       type primary;
+       file "step2.csk-roll2.autosign.db";
+       dnssec-policy "csk-roll2";
+};
+zone "step3.csk-roll2.autosign" {
+       type primary;
+       file "step3.csk-roll2.autosign.db";
+       dnssec-policy "csk-roll2";
+};
+zone "step4.csk-roll2.autosign" {
+       type primary;
+       file "step4.csk-roll2.autosign.db";
+       dnssec-policy "csk-roll2";
+};
+zone "step5.csk-roll2.autosign" {
+       type primary;
+       file "step5.csk-roll2.autosign.db";
+       dnssec-policy "csk-roll2";
+};
+zone "step6.csk-roll2.autosign" {
+       type primary;
+       file "step6.csk-roll2.autosign.db";
+       dnssec-policy "csk-roll2";
+};
+zone "step7.csk-roll2.autosign" {
+       type primary;
+       file "step7.csk-roll2.autosign.db";
+       dnssec-policy "csk-roll2";
+};
index 881e3bd565202e0bd039f3d5c2e4ddad10084da1..a2454b6bf5755206b784eed71791059036beb94a 100644 (file)
@@ -558,3 +558,534 @@ 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
+
+#
+# The zones at csk-roll2.autosign represent the various steps of a CSK rollover
+# (which is essentially a ZSK Pre-Publication / KSK Double-KSK rollover).
+# This scenario differs from the above one because the zone signatures (ZRRSIG)
+# are replaced with the new key sooner than the DS is swapped.
+#
+
+# Step 1:
+# Introduce the first key. This will immediately be active.
+setup step1.csk-roll2.autosign
+TactN="now-7d"
+keytimes="-P ${TactN} -A ${TactN}"
+CSK=$($KEYGEN -k csk-roll2 -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-256,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-roll2.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-roll2 -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-256,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-roll2.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:          1w
+# Dreg:           N/A
+# Dsgn:           12h
+# TTLds:          1h
+# TTLsig:         1d
+# retire-safety:  1h
+# Iret:           170h
+# IretZ:          38h
+# Ipub:           3h
+#
+# Tpub(N)   = now - Lcsk = now - 186d
+# Tact(N)   = now - Lcsk + Dprp + TTLsig = now - 4439h
+# Tret(N)   = now
+# Trem(N)   = now + Iret = now + 170h
+# Tpub(N+1) = now - Ipub = now - 3h
+# Tact(N+1) = Tret(N)
+# Tret(N+1) = now + Lcsk = now + 186d
+# Trem(N+1) = now + Lcsk + Iret = now + 186d + 170h =
+#           = now + 4464h + 170h = now + 4634h
+TpubN="now-186d"
+TactN="now-4439h"
+TretN="now"
+TremN="now+170h"
+TpubN1="now-3h"
+TactN1="${TretN}"
+TretN1="now+186d"
+TremN1="now+4634h"
+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-roll2 -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1)
+CSK2=$($KEYGEN -k csk-roll2 -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-256,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 (38h).
+# The DS is swapped after Dreg + Iret (1w3h). In other words, the zone
+# signatures are replaced before the DS is swapped.
+setup step4.csk-roll2.autosign
+# According to RFC 7583:
+# Trem(N)    = Tret(N) + IretZ
+#
+# Lcsk:   186d
+# Dreg:   N/A
+# Iret:   170h
+# IretZ:  38h
+#
+# Tpub(N)    = now - IretZ - Lcsk = now - 38h - 186d
+#            = now - 38h - 4464h = now - 4502h
+# Tact(N)    = now - Iret - Lcsk + TTLsig = now - 4502h + 25h = now - 4477h
+# Tret(N)    = now - IretZ = now - 38h
+# Trem(N)    = now - IretZ + Iret = now - 38h + 170h = now + 132h
+# Tpub(N+1)  = now - IretZ - IpubC = now - 38h - 3h = now - 41h
+# Tact(N+1)  = Tret(N)
+# Tret(N+1)  = now - IretZ + Lcsk = now - 38h + 186d
+#            = now + 4426h
+# Trem(N+1)  = now - IretZ + Lcsk + Iret
+#            = now + 4426h + 3h = now + 4429h
+TpubN="now-4502h"
+TactN="now-4477h"
+TretN="now-38h"
+TremN="now+132h"
+TpubN1="now-41h"
+TactN1="${TretN}"
+TretN1="now+4426h"
+TremN1="now+4429h"
+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-roll2 -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1)
+CSK2=$($KEYGEN -k csk-roll2 -l kasp.conf $newtimes $zone 2>keygen.out.$zone.2)
+$SETTIME -s -g $H -k $O $TactN -r $O $TactN -z $U $TretN -d $U $TactN1 -D ds $TactN1 "$CSK1" >settime.out.$zone.1 2>&1
+$SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -z $R $TactN1 -d $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-256,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:
+# Some time later the DS can be swapped and the old DNSKEY can be removed from
+# the zone.
+setup step5.csk-roll2.autosign
+# Subtract Iret (170h) - IretZ (38h) = 132h.
+#
+# Tpub(N)   = now - 4502h - 132h = now - 4634h
+# Tact(N)   = now - 4477h - 132h = now - 4609h
+# Tret(N)   = now - 38h - 132h = now - 170h
+# Trem(N)   = now + 132h - 132h = now
+# Tpub(N+1) = now - 41h - 132h = now - 173h
+# Tact(N+1) = Tret(N)
+# Tret(N+1) = now + 4426h - 132h = now + 4294h
+# Trem(N+1) = now + 4492h - 132h = now + 4360h
+TpubN="now-4634h"
+TactN="now-4609h"
+TretN="now-170h"
+TremN="now"
+TpubN1="now-173h"
+TactN1="${TretN}"
+TretN1="now+4294h"
+TremN1="now+4360h"
+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-roll2 -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1)
+CSK2=$($KEYGEN -k csk-roll2 -l kasp.conf $newtimes $zone 2>keygen.out.$zone.2)
+$SETTIME -s -g $H -k $O $TactN -r $O $TactN -z $H now-133h -d $U $TactN1 -D ds $TactN1 "$CSK1" >settime.out.$zone.1 2>&1
+$SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -z $O now-133h -d $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-256,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:
+# Some time later the predecessor DNSKEY enters the HIDDEN state.
+setup step6.csk-roll2.autosign
+# Subtract DNSKEY TTL plus zone propagation delay (2h).
+#
+# Tpub(N)   = now - 4634h - 2h = now - 4636h
+# Tact(N)   = now - 4609h - 2h = now - 4611h
+# Tret(N)   = now - 170h - 2h = now - 172h
+# Trem(N)   = now - 2h
+# Tpub(N+1) = now - 173h - 2h = now - 175h
+# Tact(N+1) = Tret(N)
+# Tret(N+1) = now + 4294h - 2h = now + 4292h
+# Trem(N+1) = now + 4360h - 2h = now + 4358h
+TpubN="now-4636h"
+TactN="now-4611h"
+TretN="now-172h"
+TremN="now-2h"
+TpubN1="now-175h"
+TactN1="${TretN}"
+TretN1="now+4292h"
+TremN1="now+4358h"
+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-roll2 -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1)
+CSK2=$($KEYGEN -k csk-roll2 -l kasp.conf $newtimes $zone 2>keygen.out.$zone.2)
+$SETTIME -s -g $H -k $U $TremN -r $U $TremN -d $H $TremN -z $H now-135h "$CSK1" >settime.out.$zone.1 2>&1
+$SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $O $TremN -z $O now-135h "$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-256,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:
+# The predecessor DNSKEY can be purged, but purge-keys is disabled.
+setup step7.csk-roll2.autosign
+# Subtract 90 days (default, 2160h) from all the times.
+#
+# Tpub(N)   = now - 4636h - 2160h = now - 6796h
+# Tact(N)   = now - 4611h - 2160h = now - 6771h
+# Tret(N)   = now - 172h - 2160h = now - 2332h
+# Trem(N)   = now - 2h - 2160h = now - 2162h
+# Tpub(N+1) = now - 175h - 2160h = now - 2335h
+# Tact(N+1) = Tret(N)
+# Tret(N+1) = now + 4292h - 2160h = now + 2132h
+# Trem(N+1) = now + 4358h - 2160h = now + 2198h
+TpubN="now-6796h"
+TactN="now-6771h"
+TretN="now-2332h"
+TremN="now-2162h"
+TpubN1="now-2335h"
+TactN1="${TretN}"
+TretN1="now+2132h"
+TremN1="now+2198h"
+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-roll2 -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1)
+CSK2=$($KEYGEN -k csk-roll2 -l kasp.conf $newtimes $zone 2>keygen.out.$zone.2)
+$SETTIME -s -g $H -k $U $TremN -r $U $TremN -d $H $TremN -z $H now-135h "$CSK1" >settime.out.$zone.1 2>&1
+$SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $O $TremN -z $O now-135h "$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-256,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
index 27c6ee458c77d468ecf7a771787e5d4a20060539..0eec2932bd352bc7cce1e810660317c02a95a7cb 100644 (file)
@@ -109,8 +109,10 @@ def test_rollover_manual(servers):
     ttl = int(config["dnskey-ttl"].total_seconds())
     alg = os.environ["DEFAULT_ALGORITHM_NUMBER"]
     size = os.environ["DEFAULT_BITS"]
-
     zone = "manual-rollover.kasp"
+
+    isctest.kasp.check_dnssec_verify(server, zone)
+
     key_properties = [
         f"ksk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent",
         f"zsk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent",
@@ -120,7 +122,6 @@ def test_rollover_manual(servers):
     ksks = [k for k in keys if k.is_ksk()]
     zsks = [k for k in keys if not k.is_ksk()]
 
-    isctest.kasp.check_zone_is_signed(server, zone)
     isctest.kasp.check_keys(zone, keys, expected)
 
     offset = -timedelta(days=7)
@@ -131,7 +132,6 @@ def test_rollover_manual(servers):
     isctest.kasp.check_dnssecstatus(server, zone, keys, policy=policy)
     isctest.kasp.check_apex(server, zone, ksks, zsks)
     isctest.kasp.check_subdomain(server, zone, ksks, zsks)
-    isctest.kasp.check_dnssec_verify(server, zone)
 
     # Schedule KSK rollover in six months.
     assert len(ksks) == 1
@@ -146,12 +146,12 @@ def test_rollover_manual(servers):
         server.rndc(f"dnssec -rollover -key {ksk.tag} -when {startroll} {zone}")
         watcher.wait_for_line(f"keymgr: {zone} done")
 
+    isctest.kasp.check_dnssec_verify(server, zone)
     isctest.kasp.check_keys(zone, keys, expected)
     isctest.kasp.check_keytimes(keys, expected)
     isctest.kasp.check_dnssecstatus(server, zone, keys, policy=policy)
     isctest.kasp.check_apex(server, zone, ksks, zsks)
     isctest.kasp.check_subdomain(server, zone, ksks, zsks)
-    isctest.kasp.check_dnssec_verify(server, zone)
 
     # Schedule KSK rollover now.
     now = KeyTimingMetadata.now()
@@ -159,6 +159,8 @@ def test_rollover_manual(servers):
         server.rndc(f"dnssec -rollover -key {ksk.tag} -when {now} {zone}")
         watcher.wait_for_line(f"keymgr: {zone} done")
 
+    isctest.kasp.check_dnssec_verify(server, zone)
+
     key_properties = [
         f"ksk unlimited {alg} {size} goal:hidden dnskey:omnipresent krrsig:omnipresent ds:omnipresent",
         f"ksk unlimited {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured ds:hidden",
@@ -190,7 +192,6 @@ def test_rollover_manual(servers):
     isctest.kasp.check_dnssecstatus(server, zone, keys, policy=policy)
     isctest.kasp.check_apex(server, zone, ksks, zsks)
     isctest.kasp.check_subdomain(server, zone, ksks, zsks)
-    isctest.kasp.check_dnssec_verify(server, zone)
 
     # Schedule ZSK rollover now.
     assert len(zsks) == 1
@@ -200,6 +201,8 @@ def test_rollover_manual(servers):
         server.rndc(f"dnssec -rollover -key {zsk.tag} -when {now} {zone}")
         watcher.wait_for_line(f"keymgr: {zone} done")
 
+    isctest.kasp.check_dnssec_verify(server, zone)
+
     key_properties = [
         f"ksk unlimited {alg} {size} goal:hidden dnskey:omnipresent krrsig:omnipresent ds:omnipresent",
         f"ksk unlimited {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured ds:hidden",
@@ -277,6 +280,9 @@ def test_rollover_multisigner(servers):
             isctest.log.info(f"error: update timeout for {zone}")
 
     zone = "multisigner-model2.kasp"
+
+    isctest.kasp.check_dnssec_verify(server, zone)
+
     key_properties = [
         f"ksk unlimited {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured ds:hidden tag-range:32768-65535",
         f"zsk unlimited {alg} {size} goal:omnipresent dnskey:rumoured zrrsig:rumoured tag-range:32768-65535",
@@ -296,7 +302,6 @@ def test_rollover_multisigner(servers):
     zsks = [k for k in ownkeys if not k.is_ksk()]
     zsks = zsks + extkeys
 
-    isctest.kasp.check_zone_is_signed(server, zone)
     isctest.kasp.check_keys(zone, keys, expected)
     for kp in expected:
         kp.set_expected_keytimes(config)
@@ -304,7 +309,6 @@ def test_rollover_multisigner(servers):
     isctest.kasp.check_dnssecstatus(server, zone, keys, policy=policy)
     isctest.kasp.check_apex(server, zone, ksks, zsks)
     isctest.kasp.check_subdomain(server, zone, ksks, zsks)
-    isctest.kasp.check_dnssec_verify(server, zone)
 
     # Update zone with ZSK from another provider for zone.
     out = keygen(zone)
@@ -321,12 +325,13 @@ def test_rollover_multisigner(servers):
     updates = [[1, f"{dnskey[0]}", 3600, "DNSKEY", rdata]]
     nsupdate(updates)
 
+    isctest.kasp.check_dnssec_verify(server, zone)
+
     keys = keys + newkeys
     zsks = zsks + newkeys
     isctest.kasp.check_keys(zone, keys, expected)
     isctest.kasp.check_apex(server, zone, ksks, zsks)
     isctest.kasp.check_subdomain(server, zone, ksks, zsks)
-    isctest.kasp.check_dnssec_verify(server, zone)
 
     # Remove ZSKs from the other providers for zone.
     dnskey2 = extkeys[0].dnskey().split()
@@ -337,6 +342,8 @@ def test_rollover_multisigner(servers):
     ]
     nsupdate(updates)
 
+    isctest.kasp.check_dnssec_verify(server, zone)
+
     expected = isctest.kasp.policy_to_properties(ttl, key_properties)
     keys = ownkeys
     ksks = [k for k in ownkeys if k.is_ksk()]
@@ -344,12 +351,14 @@ def test_rollover_multisigner(servers):
     isctest.kasp.check_keys(zone, keys, expected)
     isctest.kasp.check_apex(server, zone, ksks, zsks)
     isctest.kasp.check_subdomain(server, zone, ksks, zsks)
-    isctest.kasp.check_dnssec_verify(server, zone)
 
     # A zone transitioning from single-signed to multi-signed. We should have
     # the old omnipresent keys outside of the desired key range and the new
     # keys in the desired key range.
     zone = "single-to-multisigner.kasp"
+
+    isctest.kasp.check_dnssec_verify(server, zone)
+
     key_properties = [
         f"ksk unlimited {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured ds:hidden tag-range:32768-65535",
         f"zsk unlimited {alg} {size} goal:omnipresent dnskey:rumoured zrrsig:hidden tag-range:32768-65535",
@@ -361,7 +370,6 @@ def test_rollover_multisigner(servers):
     ksks = [k for k in keys if k.is_ksk()]
     zsks = [k for k in keys if not k.is_ksk()]
 
-    isctest.kasp.check_zone_is_signed(server, zone)
     isctest.kasp.check_keys(zone, keys, expected)
 
     for kp in expected:
@@ -381,26 +389,22 @@ def test_rollover_multisigner(servers):
     isctest.kasp.check_dnssecstatus(server, zone, keys, policy=policy)
     isctest.kasp.check_apex(server, zone, ksks, zsks)
     isctest.kasp.check_subdomain(server, zone, ksks, zsks)
-    isctest.kasp.check_dnssec_verify(server, zone)
 
 
 def check_rollover_step(server, config, policy, step):
     zone = step["zone"]
     keyprops = step["keyprops"]
     nextev = step["nextev"]
-    cdss = None
-    if step.get("cdss"):
-        cdss = step["cdss"]
-    keyrelationships = None
-    if step.get("keyrelationships"):
-        keyrelationships = step["keyrelationships"]
-    smooth = False
-    if step.get("smooth"):
-        smooth = step["smooth"]
+    cdss = step.get("cdss", None)
+    keyrelationships = step.get("keyrelationships", None)
+    smooth = step.get("smooth", False)
+    ds_swap = step.get("ds-swap", True)
+
+    isctest.log.info(f"check rollover step {zone}")
 
     ttl = int(config["dnskey-ttl"].total_seconds())
     expected = isctest.kasp.policy_to_properties(ttl, keyprops)
-    isctest.kasp.check_zone_is_signed(server, zone)
+    isctest.kasp.check_dnssec_verify(server, zone)
     keys = isctest.kasp.keydir_to_keylist(zone, server.identifier)
     ksks = [k for k in keys if k.is_ksk()]
     zsks = [k for k in keys if not k.is_ksk()]
@@ -425,9 +429,8 @@ def check_rollover_step(server, config, policy, step):
             continue
         key = kp.key
 
-        if kp.metadata["DSState"] == "rumoured":
+        if ds_swap and kp.metadata["DSState"] == "rumoured":
             assert cdss is not None
-
             for algstr in ["CDNSKEY", "CDS (SHA-256)", "CDS (SHA-384)"]:
                 if algstr in cdss:
                     isctest.kasp.check_cdslog(server, zone, key, algstr)
@@ -438,7 +441,7 @@ def check_rollover_step(server, config, policy, step):
             # so set the DS publish time to now.
             server.rndc(f"dnssec -checkds -key {key.tag} published {zone}")
 
-        if kp.metadata["DSState"] == "unretentive":
+        if ds_swap and kp.metadata["DSState"] == "unretentive":
             # The DS can be withdrawn. We ignore any parent registration
             # delay, so set the DS withdraw time to now.
             server.rndc(f"dnssec -checkds -key {key.tag} withdrawn {zone}")
@@ -447,7 +450,6 @@ def check_rollover_step(server, config, policy, step):
     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, smooth=smooth)
-    isctest.kasp.check_dnssec_verify(server, zone)
 
     def check_next_key_event():
         return isctest.kasp.next_key_event_equals(server, zone, nextev)
@@ -839,6 +841,7 @@ def test_rollover_ksk_doubleksk(servers):
     )
     offset1 = -int(timedelta(days=60).total_seconds())
     offset2 = -int(timedelta(hours=27).total_seconds())
+    isctest.kasp.check_dnssec_verify(server, zone)
     keyprops = [
         f"ksk {lifetime_policy} {alg} {size} goal:hidden dnskey:omnipresent krrsig:omnipresent ds:unretentive offset:{offset1}",
         f"ksk {lifetime_policy} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:rumoured offset:{offset2}",
@@ -858,13 +861,13 @@ 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)
-    isctest.kasp.check_dnssec_verify(server, zone)
     # Rollover successor KSK (with DS in rumoured state).
     key = expected[1].key
     now = KeyTimingMetadata.now()
     with server.watch_log_from_here() as watcher:
         server.rndc(f"dnssec -rollover -key {key.tag} -when {now} {zone}")
         watcher.wait_for_line(f"keymgr: {zone} done")
+    isctest.kasp.check_dnssec_verify(server, zone)
     # We now expect four keys (3x KSK, 1x ZSK).
     keyprops = [
         f"ksk {lifetime_policy} {alg} {size} goal:hidden dnskey:omnipresent krrsig:omnipresent ds:unretentive offset:{offset1}",
@@ -892,4 +895,377 @@ 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)
-    isctest.kasp.check_dnssec_verify(server, zone)
+
+
+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:
+        check_rollover_step(server, config, policy, step)
+
+
+def test_rollover_csk_roll2(servers):
+    server = servers["ns3"]
+    policy = "csk-roll2"
+    cdss = ["CDNSKEY", "CDS (SHA-256)", "CDS (SHA-384)"]
+    config = {
+        "dnskey-ttl": timedelta(hours=1),
+        "ds-ttl": timedelta(seconds=3600),
+        "max-zone-ttl": timedelta(days=1),
+        "parent-propagation-delay": timedelta(days=7),
+        "publish-safety": timedelta(hours=1),
+        "purge-keys": timedelta(0),
+        "retire-safety": timedelta(hours=1),
+        "signatures-refresh": timedelta(hours=12),
+        "signatures-validity": timedelta(days=1),
+        "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)
+    iret = Iret(config, zsk=True, ksk=True)
+    iretZSK = Iret(config)
+    iretKSK = Iret(config, ksk=True)
+    keyttlprop = config["dnskey-ttl"] + config["zone-propagation-delay"]
+    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(iretZSK.total_seconds())
+    offsets["step4-s"] = offsets["step3-s"] - int(iretZSK.total_seconds())
+    offsets["step5-p"] = offsets["step4-p"] - int(
+        iretKSK.total_seconds() - iretZSK.total_seconds()
+    )
+    offsets["step5-s"] = offsets["step4-s"] - int(
+        iretKSK.total_seconds() - iretZSK.total_seconds()
+    )
+    offsets["step6-p"] = offsets["step5-p"] - int(keyttlprop.total_seconds())
+    offsets["step6-s"] = offsets["step5-s"] - int(keyttlprop.total_seconds())
+    offsets["step7-p"] = offsets["step6-p"] - int(timedelta(days=90).total_seconds())
+    offsets["step7-s"] = offsets["step6-s"] - int(timedelta(days=90).total_seconds())
+
+    steps = [
+        {
+            # Step 1.
+            # Introduce the first key. This will immediately be active.
+            "zone": "step1.csk-roll2.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-roll2.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-roll2.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": iretZSK,
+            # Set 'smooth' to true so expected signatures of subdomain are
+            # from the predecessor ZSK.
+            "smooth": True,
+        },
+        {
+            # Step 4.
+            "zone": "step4.csk-roll2.autosign",
+            "cdss": cdss,
+            # The predecessor ZRRSIG is HIDDEN. The successor ZRRSIG is
+            # OMNIPRESENT.
+            # CSK1 zrrsig: unretentive -> hidden
+            # CSK2 zrrsig: rumoured -> omnipresent
+            "keyprops": [
+                f"csk {lifetime_policy} {alg} {size} goal:hidden dnskey:omnipresent krrsig:omnipresent zrrsig:hidden ds:unretentive offset:{offsets['step4-p']}",
+                f"csk {lifetime_policy} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:rumoured offset:{offsets['step4-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 retire interval of the KSK part (minus)
+            # time already elapsed).
+            "nextev": iret - iretZSK,
+            # We already swapped the DS in the previous step, so disable ds-swap.
+            "ds-swap": False,
+        },
+        {
+            # Step 5.
+            "zone": "step5.csk-roll2.autosign",
+            "cdss": cdss,
+            # The predecessor DNSKEY can be removed.
+            # CSK1 dnskey: omnipresent -> unretentive
+            # CSK1 krrsig: omnipresent -> unretentive
+            # CSK1 ds: unretentive -> hidden
+            # The successor key is now fully OMNIPRESENT.
+            # CSK2 ds: rumoured -> omnipresent
+            "keyprops": [
+                f"csk {lifetime_policy} {alg} {size} goal:hidden dnskey:unretentive krrsig:unretentive zrrsig:hidden ds:hidden offset:{offsets['step5-p']}",
+                f"csk {lifetime_policy} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{offsets['step5-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 6.
+            "zone": "step6.csk-roll2.autosign",
+            "cdss": cdss,
+            # The predecessor CSK is now completely HIDDEN.
+            # CSK1 dnskey: unretentive -> hidden
+            # CSK1 krrsig: unretentive -> hidden
+            "keyprops": [
+                f"csk {lifetime_policy} {alg} {size} goal:hidden dnskey:hidden 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 new successor needs to be published.
+            # This is the Lcsk, minus time passed since the key was published.
+            "nextev": csk_lifetime - iret - ipub - keyttlprop,
+        },
+        {
+            # Step 7.
+            "zone": "step7.csk-roll2.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],
+            "nextev": None,
+        },
+    ]
+
+    for step in steps:
+        check_rollover_step(server, config, policy, step)