return value
def get_signing_state(
- self, offline_ksk=False, zsk_missing=False
+ self, offline_ksk=False, zsk_missing=False, smooth=False
) -> Tuple[bool, bool]:
"""
This returns the signing state derived from the key states, KRRSIGState
If 'zsk_missing' is set to True, it means the ZSK private key file is
missing, and the KSK should take over signing the RRset, and the
expected zone signing state (zsigning) is reversed.
+
+ If 'smooth' is set to True, it means a smooth ZSK rollover is
+ initiated. Signatures are being replaced gradually during a ZSK
+ rollover, so the existing signatures of the predecessor ZSK are still
+ being used, thus the predecessor is expected to be signing.
"""
# Fetch key timing metadata.
now = KeyTimingMetadata.now()
ksigning = krrsigstate in ["rumoured", "omnipresent"]
zrrsigstate = self.get_metadata("ZRRSIGState", must_exist=False)
zsigning = zrrsigstate in ["rumoured", "omnipresent"]
+ if smooth:
+ zsigning = zrrsigstate in ["unretentive", "omnipresent"]
if ksigning:
assert self.is_ksk()
def _check_signatures(
- signatures, covers, fqdn, keys, offline_ksk=False, zsk_missing=False
+ signatures, covers, fqdn, keys, offline_ksk=False, zsk_missing=False, smooth=False
):
numsigs = 0
zrrsig = True
continue
ksigning, zsigning = key.get_signing_state(
- offline_ksk=offline_ksk, zsk_missing=zsk_missing
+ offline_ksk=offline_ksk, zsk_missing=zsk_missing, smooth=smooth
)
alg = key.get_metadata("Algorithm")
def check_signatures(
- rrset, covers, fqdn, ksks, zsks, offline_ksk=False, zsk_missing=False
+ rrset, covers, fqdn, ksks, zsks, offline_ksk=False, zsk_missing=False, smooth=False
):
# Check if signatures with covering type are signed with the right keys.
# The right keys are the ones that expect a signature and have the
signatures.append(rrsig)
numsigs += _check_signatures(
- signatures, covers, fqdn, ksks, offline_ksk=offline_ksk, zsk_missing=zsk_missing
+ signatures,
+ covers,
+ fqdn,
+ ksks,
+ offline_ksk=offline_ksk,
+ zsk_missing=zsk_missing,
+ smooth=smooth,
)
numsigs += _check_signatures(
- signatures, covers, fqdn, zsks, offline_ksk=offline_ksk, zsk_missing=zsk_missing
+ signatures,
+ covers,
+ fqdn,
+ zsks,
+ offline_ksk=offline_ksk,
+ zsk_missing=zsk_missing,
+ smooth=smooth,
)
assert numsigs == len(signatures)
)
-def check_subdomain(server, zone, ksks, zsks, offline_ksk=False, tsig=None):
+def check_subdomain(
+ server, zone, ksks, zsks, offline_ksk=False, smooth=False, tsig=None
+):
# Test an RRset below the apex and verify it is signed correctly.
fqdn = f"{zone}."
qname = f"a.{zone}."
else:
assert match in rrset.to_text()
- check_signatures(rrsigs, qtype, fqdn, ksks, zsks, offline_ksk=offline_ksk)
+ check_signatures(
+ rrsigs, qtype, fqdn, ksks, zsks, offline_ksk=offline_ksk, smooth=smooth
+ )
def verify_update_is_signed(server, fqdn, qname, qtype, rdata, ksks, zsks, tsig=None):
dnssec-policy "autosign";
};
-/*
- * Zones for testing ZSK Pre-Publication steps.
- */
-zone "step1.zsk-prepub.autosign" {
- type primary;
- file "step1.zsk-prepub.autosign.db";
- dnssec-policy "zsk-prepub";
-};
-zone "step2.zsk-prepub.autosign" {
- type primary;
- file "step2.zsk-prepub.autosign.db";
- dnssec-policy "zsk-prepub";
-};
-zone "step3.zsk-prepub.autosign" {
- type primary;
- file "step3.zsk-prepub.autosign.db";
- dnssec-policy "zsk-prepub";
-};
-zone "step4.zsk-prepub.autosign" {
- type primary;
- file "step4.zsk-prepub.autosign.db";
- dnssec-policy "zsk-prepub";
-};
-zone "step5.zsk-prepub.autosign" {
- type primary;
- file "step5.zsk-prepub.autosign.db";
- dnssec-policy "zsk-prepub";
-};
-zone "step6.zsk-prepub.autosign" {
- type primary;
- file "step6.zsk-prepub.autosign.db";
- dnssec-policy "zsk-prepub";
-};
-
/*
* Zones for testing KSK Double-KSK steps.
*/
};
};
-dnssec-policy "zsk-prepub" {
-
- signatures-refresh P1W;
- signatures-validity P2W;
- signatures-validity-dnskey P2W;
-
- dnskey-ttl 3600;
- publish-safety P1D;
- retire-safety P2D;
- purge-keys PT1H;
-
- keys {
- ksk key-directory lifetime P2Y algorithm @DEFAULT_ALGORITHM@;
- zsk key-directory lifetime P30D algorithm @DEFAULT_ALGORITHM@;
- };
-
- zone-propagation-delay PT1H;
- max-zone-ttl 1d;
-};
-
dnssec-policy "ksk-doubleksk" {
signatures-refresh P1W;
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 zsk-prepub.autosign represent the various steps of a ZSK
-# Pre-Publication rollover.
-#
-
-# Step 1:
-# Introduce the first key. This will immediately be active.
-setup step1.zsk-prepub.autosign
-TactN="now"
-ksktimes="-P ${TactN} -A ${TactN} -P sync ${TactN}"
-zsktimes="-P ${TactN} -A ${TactN}"
-KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $ksktimes $zone 2>keygen.out.$zone.1)
-ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $zsktimes $zone 2>keygen.out.$zone.2)
-$SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN "$KSK" >settime.out.$zone.1 2>&1
-$SETTIME -s -g $O -k $O $TactN -z $O $TactN "$ZSK" >settime.out.$zone.2 2>&1
-cat template.db.in "${KSK}.key" "${ZSK}.key" >"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK" >>"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile"
-cp $infile $zonefile
-$SIGNER -S -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
-
-# Step 2:
-# It is time to pre-publish the successor ZSK.
-setup step2.zsk-prepub.autosign
-# According to RFC 7583:
-#
-# Tpub(N+1) <= Tact(N) + Lzsk - Ipub
-# Ipub = Dprp + TTLkey (+publish-safety)
-#
-# |3| |4| |5| |6|
-# | | | |
-# Key N |<-------Lzsk------>|
-# | | | |
-# Key N+1 | |<-Ipub->|<-->|
-# | | | |
-# Key N Tact
-# Key N+1 Tpub Trdy Tact
-#
-# Tnow
-#
-# Lzsk: 30d
-# Dprp: 1h
-# TTLkey: 1h
-# publish-safety: 1d
-# Ipub: 26h
-#
-# Tact(N) = Tnow + Ipub - Lzsk = now + 26h - 30d
-# = now + 26h - 30d = now − 694h
-TactN="now-694h"
-ksktimes="-P ${TactN} -A ${TactN} -P sync ${TactN}"
-zsktimes="-P ${TactN} -A ${TactN}"
-KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $ksktimes $zone 2>keygen.out.$zone.1)
-ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $zsktimes $zone 2>keygen.out.$zone.2)
-$SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN "$KSK" >settime.out.$zone.1 2>&1
-$SETTIME -s -g $O -k $O $TactN -z $O $TactN "$ZSK" >settime.out.$zone.2 2>&1
-cat template.db.in "${KSK}.key" "${ZSK}.key" >"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK" >>"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile"
-cp $infile $zonefile
-$SIGNER -S -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
-
-# Step 3:
-# After the publication interval has passed the DNSKEY of the successor ZSK
-# is OMNIPRESENT and the zone can thus be signed with the successor ZSK.
-setup step3.zsk-prepub.autosign
-# According to RFC 7583:
-#
-# Tpub(N+1) <= Tact(N) + Lzsk - Ipub
-# Tret(N) = Tact(N+1) = Tact(N) + Lzsk
-# Trem(N) = Tret(N) + Iret
-# Iret = Dsgn + Dprp + TTLsig (+retire-safety)
-#
-# |3| |4| |5| |6| |7| |8|
-# | | | | | |
-# Key N |<-------Lzsk------>|<-Iret->|<--->|
-# | | | | | |
-# Key N+1 | |<-Ipub->|<-->|<---Lzsk---- - -
-# | | | | | |
-# Key N Tact Tret Tdea Trem
-# Key N+1 Tpub Trdy Tact
-#
-# Tnow
-#
-# Lzsk: 30d
-# Ipub: 26h
-# Dsgn: 1w
-# Dprp: 1h
-# TTLsig: 1d
-# retire-safety: 2d
-# Iret: 10d1h = 241h
-#
-# Tact(N) = Tnow - Lzsk = now - 30d
-# Tret(N) = now
-# Trem(N) = Tnow + Iret = now + 241h
-# Tpub(N+1) = Tnow - Ipub = now - 26h
-# Tret(N+1) = Tnow + Lzsk = now + 30d
-# Trem(N+1) = Tnow + Lzsk + Iret = now + 30d + 241h
-# = now + 961h
-TactN="now-30d"
-TretN="now"
-TremN="now+241h"
-TpubN1="now-26h"
-TactN1="now"
-TretN1="now+30d"
-TremN1="now+961h"
-ksktimes="-P ${TactN} -A ${TactN} -P sync ${TactN}"
-zsktimes="-P ${TactN} -A ${TactN} -I ${TretN} -D ${TremN}"
-newtimes="-P ${TpubN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}"
-KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $ksktimes $zone 2>keygen.out.$zone.1)
-ZSK1=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $zsktimes $zone 2>keygen.out.$zone.2)
-ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $newtimes $zone 2>keygen.out.$zone.3)
-$SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN "$KSK" >settime.out.$zone.1 2>&1
-$SETTIME -s -g $H -k $O $TactN -z $O $TactN "$ZSK1" >settime.out.$zone.2 2>&1
-$SETTIME -s -g $O -k $R $TpubN1 -z $H $TpubN1 "$ZSK2" >settime.out.$zone.3 2>&1
-# Set key rollover relationship.
-key_successor $ZSK1 $ZSK2
-# Sign zone.
-cat template.db.in "${KSK}.key" "${ZSK1}.key" "${ZSK2}.key" >"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK" >>"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK1" >>"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK2" >>"$infile"
-cp $infile $zonefile
-$SIGNER -S -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
-
-# Step 4:
-# After the retire interval has passed the predecessor DNSKEY can be
-# removed from the zone.
-setup step4.zsk-prepub.autosign
-# According to RFC 7583:
-#
-# Tret(N) = Tact(N) + Lzsk
-# Tdea(N) = Tret(N) + Iret
-#
-# |3| |4| |5| |6| |7| |8|
-# | | | | | |
-# Key N |<-------Lzsk------>|<-Iret->|<--->|
-# | | | | | |
-# Key N+1 | |<-Ipub->|<-->|<---Lzsk---- - -
-# | | | | | |
-# Key N Tact Tret Tdea Trem
-# Key N+1 Tpub Trdy Tact
-#
-# Tnow
-#
-# Lzsk: 30d
-# Ipub: 26h
-# Iret: 241h
-#
-# Tact(N) = Tnow - Iret - Lzsk
-# = now - 241h - 30d = now - 241h - 720h
-# = now - 961h
-# Tret(N) = Tnow - Iret = now - 241h
-# Trem(N) = Tnow
-# Tpub(N+1) = Tnow - Iret - Ipub
-# = now - 241h - 26h
-# = now - 267h
-# Tact(N+1) = Tnow - Iret = Tret(N)
-# Tret(N+1) = Tnow - Iret + Lzsk
-# = now - 241h + 30d = now - 241h + 720h
-# = now + 479h
-# Trem(N+1) = Tnow + Lzsk = now + 30d
-TactN="now-961h"
-TretN="now-241h"
-TremN="now"
-TpubN1="now-267h"
-TactN1="${TretN}"
-TretN1="now+479h"
-TremN1="now+30d"
-ksktimes="-P ${TactN} -A ${TactN} -P sync ${TactN}"
-zsktimes="-P ${TactN} -A ${TactN} -I ${TretN} -D ${TremN}"
-newtimes="-P ${TpubN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}"
-KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $ksktimes $zone 2>keygen.out.$zone.1)
-ZSK1=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $zsktimes $zone 2>keygen.out.$zone.2)
-ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $newtimes $zone 2>keygen.out.$zone.3)
-$SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN "$KSK" >settime.out.$zone.1 2>&1
-$SETTIME -s -g $H -k $O $TactN -z $U $TretN "$ZSK1" >settime.out.$zone.2 2>&1
-$SETTIME -s -g $O -k $O $TactN1 -z $R $TactN1 "$ZSK2" >settime.out.$zone.3 2>&1
-# Set key rollover relationship.
-key_successor $ZSK1 $ZSK2
-# Sign zone.
-cat template.db.in "${KSK}.key" "${ZSK1}.key" "${ZSK2}.key" >"$infile"
-cp $infile $zonefile
-$SIGNER -PS -x -s now-2w -e now-1mi -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
-
-# Step 5:
-# The predecessor DNSKEY is removed long enough that is has become HIDDEN.
-setup step5.zsk-prepub.autosign
-# Subtract DNSKEY TTL from all the times (1h).
-# Tact(N) = now - 961h - 1h = now - 962h
-# Tret(N) = now - 241h - 1h = now - 242h
-# Tdea(N) = now - 2d - 1h = now - 49h
-# Trem(N) = now - 1h
-# Tpub(N+1) = now - 267h - 1h = now - 268h
-# Tact(N+1) = Tret(N)
-# Tret(N+1) = now + 479h - 1h = now + 478h
-# Trem(N+1) = now + 30d - 1h = now + 719h
-TactN="now-962h"
-TretN="now-242h"
-TremN="now-1h"
-TdeaN="now-49h"
-TpubN1="now-268h"
-TactN1="${TretN}"
-TretN1="now+478h"
-TremN1="now+719h"
-ksktimes="-P ${TactN} -A ${TactN} -P sync ${TactN}"
-zsktimes="-P ${TactN} -A ${TactN} -I ${TretN} -D ${TremN}"
-newtimes="-P ${TpubN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}"
-KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $ksktimes $zone 2>keygen.out.$zone.1)
-ZSK1=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $zsktimes $zone 2>keygen.out.$zone.2)
-ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $newtimes $zone 2>keygen.out.$zone.3)
-$SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN "$KSK" >settime.out.$zone.1 2>&1
-$SETTIME -s -g $H -k $U $TdeaN -z $H $TdeaN "$ZSK1" >settime.out.$zone.2 2>&1
-$SETTIME -s -g $O -k $O $TactN1 -z $O $TdeaN "$ZSK2" >settime.out.$zone.3 2>&1
-# Set key rollover relationship.
-key_successor $ZSK1 $ZSK2
-# Sign zone.
-cat template.db.in "${KSK}.key" "${ZSK1}.key" "${ZSK2}.key" >"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK" >>"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK1" >>"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK2" >>"$infile"
-cp $infile $zonefile
-$SIGNER -S -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
-
-# Step 6:
-# The predecessor DNSKEY can be purged.
-setup step6.zsk-prepub.autosign
-# Subtract purge-keys interval from all the times (1h).
-# Tact(N) = now - 962h - 1h = now - 963h
-# Tret(N) = now - 242h - 1h = now - 243h
-# Tdea(N) = now - 49h - 1h = now - 50h
-# Trem(N) = now - 1h - 1h = now - 2h
-# Tpub(N+1) = now - 268h - 1h = now - 269h
-# Tact(N+1) = Tret(N)
-# Tret(N+1) = now + 478h - 1h = now + 477h
-# Trem(N+1) = now + 719h - 1h = now + 718h
-TactN="now-963h"
-TretN="now-243h"
-TremN="now-2h"
-TdeaN="now-50h"
-TpubN1="now-269h"
-TactN1="${TretN}"
-TretN1="now+477h"
-TremN1="now+718h"
-ksktimes="-P ${TactN} -A ${TactN} -P sync ${TactN}"
-zsktimes="-P ${TactN} -A ${TactN} -I ${TretN} -D ${TremN}"
-newtimes="-P ${TpubN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}"
-KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $ksktimes $zone 2>keygen.out.$zone.1)
-ZSK1=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $zsktimes $zone 2>keygen.out.$zone.2)
-ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $newtimes $zone 2>keygen.out.$zone.3)
-$SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN "$KSK" >settime.out.$zone.1 2>&1
-$SETTIME -s -g $H -k $H $TdeaN -z $H $TdeaN "$ZSK1" >settime.out.$zone.2 2>&1
-$SETTIME -s -g $O -k $O $TactN1 -z $O $TdeaN "$ZSK2" >settime.out.$zone.3 2>&1
-# Set key rollover relationship.
-key_successor $ZSK1 $ZSK2
-# Sign zone.
-cat template.db.in "${KSK}.key" "${ZSK1}.key" "${ZSK2}.key" >"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK" >>"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK1" >>"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK2" >>"$infile"
-cp $infile $zonefile
-$SIGNER -S -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
-
#
# The zones at ksk-doubleksk.autosign represent the various steps of a KSK
# Double-KSK rollover.
}
-#
-# Testing ZSK Pre-Publication rollover.
-#
-
-# Policy parameters.
-# Lksk: 2 years (63072000 seconds)
-# Lzsk: 30 days (2592000 seconds)
-# Iret(KSK): DS TTL (1d) + DprpP (1h) + retire-safety (2d)
-# Iret(KSK): 3d1h (262800 seconds)
-# Iret(ZSK): RRSIG TTL (1d) + Dprp (1h) + Dsgn (1w) + retire-safety (2d)
-# Iret(ZSK): 10d1h (867600 seconds)
-Lksk=63072000
-Lzsk=2592000
-IretKSK=262800
-IretZSK=867600
-
-#
-# Zone: step1.zsk-prepub.autosign.
-#
-set_zone "step1.zsk-prepub.autosign"
-set_policy "zsk-prepub" "2" "3600"
-set_server "ns3" "10.53.0.3"
-
set_retired_removed() {
_Lkey=$2
_Iret=$3
[ "$Lzsk" = 0 ] || set_retired_removed "KEY2" "${Lzsk}" "${IretZSK}"
}
-# Key properties.
-key_clear "KEY1"
-set_keyrole "KEY1" "ksk"
-set_keylifetime "KEY1" "${Lksk}"
-set_keyalgorithm "KEY1" "$DEFAULT_ALGORITHM_NUMBER" "$DEFAULT_ALGORITHM" "$DEFAULT_BITS"
-set_keysigning "KEY1" "yes"
-set_zonesigning "KEY1" "no"
-
-key_clear "KEY2"
-set_keyrole "KEY2" "zsk"
-set_keylifetime "KEY2" "${Lzsk}"
-set_keyalgorithm "KEY2" "$DEFAULT_ALGORITHM_NUMBER" "$DEFAULT_ALGORITHM" "$DEFAULT_BITS"
-set_keysigning "KEY2" "no"
-set_zonesigning "KEY2" "yes"
-# Both KSK (KEY1) and ZSK (KEY2) start in OMNIPRESENT.
-set_keystate "KEY1" "GOAL" "omnipresent"
-set_keystate "KEY1" "STATE_DNSKEY" "omnipresent"
-set_keystate "KEY1" "STATE_KRRSIG" "omnipresent"
-set_keystate "KEY1" "STATE_DS" "omnipresent"
-
-set_keystate "KEY2" "GOAL" "omnipresent"
-set_keystate "KEY2" "STATE_DNSKEY" "omnipresent"
-set_keystate "KEY2" "STATE_ZRRSIG" "omnipresent"
-# Initially only two keys.
-key_clear "KEY3"
-key_clear "KEY4"
-
-# Various signing policy checks.
-check_keys
-check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
-# These keys are immediately published and activated.
-rollover_predecessor_keytimes 0
-check_keytimes
-check_apex
-check_subdomain
-dnssec_verify
-
-# Next key event is when the successor ZSK needs to be published. That is
-# the ZSK lifetime - prepublication time. The prepublication time is DNSKEY
-# TTL plus publish safety plus the zone propagation delay. For the
-# zsk-prepub policy that means: 30d - 3600s + 1d + 1h = 2498400 seconds.
-check_next_key_event 2498400
-
-#
-# Zone: step2.zsk-prepub.autosign.
-#
-set_zone "step2.zsk-prepub.autosign"
-set_policy "zsk-prepub" "3" "3600"
-set_server "ns3" "10.53.0.3"
-# New ZSK (KEY3) is prepublished, but not yet signing.
-key_clear "KEY3"
-set_keyrole "KEY3" "zsk"
-set_keylifetime "KEY3" "${Lzsk}"
-set_keyalgorithm "KEY3" "$DEFAULT_ALGORITHM_NUMBER" "$DEFAULT_ALGORITHM" "$DEFAULT_BITS"
-set_keysigning "KEY3" "no"
-set_zonesigning "KEY3" "no"
-# Key states.
-set_keystate "KEY2" "GOAL" "hidden"
-set_keystate "KEY3" "GOAL" "omnipresent"
-set_keystate "KEY3" "STATE_DNSKEY" "rumoured"
-set_keystate "KEY3" "STATE_ZRRSIG" "hidden"
-
-# Various signing policy checks.
-check_keys
-check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
-
-# Set expected key times:
-# - The old keys were activated 694 hours ago (2498400 seconds).
-rollover_predecessor_keytimes -2498400
-# - The new ZSK is published now.
-created=$(key_get KEY3 CREATED)
-set_keytime "KEY3" "PUBLISHED" "${created}"
-# - The new ZSK becomes active when the DNSKEY is OMNIPRESENT.
-# Ipub: TTLkey (1h) + Dprp (1h) + publish-safety (1d)
-# Ipub: 26 hour (93600 seconds).
-IpubZSK=93600
-set_addkeytime "KEY3" "ACTIVE" "${created}" "${IpubZSK}"
-set_retired_removed "KEY3" "${Lzsk}" "${IretZSK}"
-
-# Continue signing policy checks.
-check_keytimes
-check_apex
-check_subdomain
-dnssec_verify
-
-# Next key event is when the successor ZSK becomes OMNIPRESENT. That is the
-# DNSKEY TTL plus the zone propagation delay, plus the publish-safety. For
-# the zsk-prepub policy, this means: 3600s + 1h + 1d = 93600 seconds.
-check_next_key_event 93600
-
-#
-# Zone: step3.zsk-prepub.autosign.
-#
-set_zone "step3.zsk-prepub.autosign"
-set_policy "zsk-prepub" "3" "3600"
-set_server "ns3" "10.53.0.3"
-# ZSK (KEY2) no longer is actively signing, RRSIG state in UNRETENTIVE.
-# New ZSK (KEY3) is now actively signing, RRSIG state in RUMOURED.
-set_zonesigning "KEY2" "no"
-set_keystate "KEY2" "STATE_ZRRSIG" "unretentive"
-set_zonesigning "KEY3" "yes"
-set_keystate "KEY3" "STATE_DNSKEY" "omnipresent"
-set_keystate "KEY3" "STATE_ZRRSIG" "rumoured"
-
-# Various signing policy checks.
-check_keys
-check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
-
-# Set expected key times:
-# - The old keys are activated 30 days ago (2592000 seconds).
-rollover_predecessor_keytimes -2592000
-# - The new ZSK is published 26 hours ago (93600 seconds).
-created=$(key_get KEY3 CREATED)
-set_addkeytime "KEY3" "PUBLISHED" "${created}" -93600
-set_keytime "KEY3" "ACTIVE" "${created}"
-set_retired_removed "KEY3" "${Lzsk}" "${IretZSK}"
-
-# Continue signing policy checks.
-check_keytimes
-check_apex
-# Subdomain still has good signatures of ZSK (KEY2).
-# Set expected zone signing on for KEY2 and off for KEY3,
-# testing whether signatures which are still valid are being reused.
-set_zonesigning "KEY2" "yes"
-set_zonesigning "KEY3" "no"
-check_subdomain
-# Restore the expected zone signing properties.
-set_zonesigning "KEY2" "no"
-set_zonesigning "KEY3" "yes"
-dnssec_verify
-
-# Next key event is when all the RRSIG records have been replaced with
-# signatures of the new ZSK, in other words when ZRRSIG becomes OMNIPRESENT.
-# That is Dsgn plus the maximum zone TTL plus the zone propagation delay plus
-# retire-safety. For the zsk-prepub policy that means: 1w (because 2w validity
-# and refresh within a week) + 1d + 1h + 2d = 10d1h = 867600 seconds.
-check_next_key_event 867600
-
-#
-# Zone: step4.zsk-prepub.autosign.
-#
-set_zone "step4.zsk-prepub.autosign"
-set_policy "zsk-prepub" "3" "3600"
-set_server "ns3" "10.53.0.3"
-# ZSK (KEY2) DNSKEY is no longer needed.
-# ZSK (KEY3) is now actively signing, RRSIG state in RUMOURED.
-set_keystate "KEY2" "STATE_DNSKEY" "unretentive"
-set_keystate "KEY2" "STATE_ZRRSIG" "hidden"
-set_keystate "KEY3" "STATE_ZRRSIG" "omnipresent"
-
-# Various signing policy checks.
-check_keys
-check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
-
-# Set expected key times:
-# - The old keys are activated 961 hours ago (3459600 seconds).
-rollover_predecessor_keytimes -3459600
-# - The new ZSK is published 267 hours ago (961200 seconds).
-created=$(key_get KEY3 CREATED)
-set_addkeytime "KEY3" "PUBLISHED" "${created}" -961200
-published=$(key_get KEY3 PUBLISHED)
-set_addkeytime "KEY3" "ACTIVE" "${published}" "${IpubZSK}"
-set_retired_removed "KEY3" "${Lzsk}" "${IretZSK}"
-
-# 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 zsk-prepub policy this is:
-# 3600s + 1h = 7200s
-check_next_key_event 7200
-
-#
-# Zone: step5.zsk-prepub.autosign.
-#
-set_zone "step5.zsk-prepub.autosign"
-set_policy "zsk-prepub" "3" "3600"
-set_server "ns3" "10.53.0.3"
-# ZSK (KEY2) DNSKEY is now completely HIDDEN and removed.
-set_keystate "KEY2" "STATE_DNSKEY" "hidden"
-
-# Various signing policy checks.
-check_keys
-check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
-
-# Set expected key times:
-# - The old keys are activated 962 hours ago (3463200 seconds).
-rollover_predecessor_keytimes -3463200
-# - The new ZSK is published 268 hours ago (964800 seconds).
-created=$(key_get KEY3 CREATED)
-set_addkeytime "KEY3" "PUBLISHED" "${created}" -964800
-published=$(key_get KEY3 PUBLISHED)
-set_addkeytime "KEY3" "ACTIVE" "${published}" "${IpubZSK}"
-set_retired_removed "KEY3" "${Lzsk}" "${IretZSK}"
-
-# 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
-# ZSK lifetime minus Iret minus Ipub minus DNSKEY TTL. For the zsk-prepub
-# policy this is: 30d - 867600s - 93600s - 3600s = 1627200 seconds.
-check_next_key_event 1627200
-
-#
-# Zone: step6.zsk-prepub.autosign.
-#
-set_zone "step6.zsk-prepub.autosign"
-set_policy "zsk-prepub" "2" "3600"
-set_server "ns3" "10.53.0.3"
-# ZSK (KEY2) DNSKEY is purged.
-key_clear "KEY2"
-
-# Various signing policy checks.
-check_keys
-check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
-check_apex
-check_subdomain
-dnssec_verify
-
#
# Testing KSK Double-KSK rollover.
#
csk lifetime unlimited algorithm @DEFAULT_ALGORITHM_NUMBER@;
};
};
+
+dnssec-policy "zsk-prepub" {
+ signatures-refresh P1W;
+ signatures-validity P2W;
+ signatures-validity-dnskey P2W;
+
+ dnskey-ttl 3600;
+ publish-safety P1D;
+ retire-safety P2D;
+ purge-keys PT1H;
+
+ keys {
+ ksk key-directory lifetime unlimited algorithm @DEFAULT_ALGORITHM@;
+ zsk key-directory lifetime P30D algorithm @DEFAULT_ALGORITHM@;
+ };
+
+ zone-propagation-delay PT1H;
+ max-zone-ttl 1d;
+};
file "step4.enable-dnssec.autosign.db";
dnssec-policy "enable-dnssec";
};
+
+/*
+ * Zones for testing ZSK Pre-Publication steps.
+ */
+zone "step1.zsk-prepub.autosign" {
+ type primary;
+ file "step1.zsk-prepub.autosign.db";
+ dnssec-policy "zsk-prepub";
+};
+zone "step2.zsk-prepub.autosign" {
+ type primary;
+ file "step2.zsk-prepub.autosign.db";
+ dnssec-policy "zsk-prepub";
+};
+zone "step3.zsk-prepub.autosign" {
+ type primary;
+ file "step3.zsk-prepub.autosign.db";
+ dnssec-policy "zsk-prepub";
+};
+zone "step4.zsk-prepub.autosign" {
+ type primary;
+ file "step4.zsk-prepub.autosign.db";
+ dnssec-policy "zsk-prepub";
+};
+zone "step5.zsk-prepub.autosign" {
+ type primary;
+ file "step5.zsk-prepub.autosign.db";
+ dnssec-policy "zsk-prepub";
+};
+zone "step6.zsk-prepub.autosign" {
+ type primary;
+ file "step6.zsk-prepub.autosign.db";
+ dnssec-policy "zsk-prepub";
+};
cp $infile $zonefile
$SIGNER -S -z -x -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
+#
+# The zones at zsk-prepub.autosign represent the various steps of a ZSK
+# Pre-Publication rollover.
+#
+
+# Step 1:
+# Introduce the first key. This will immediately be active.
+setup step1.zsk-prepub.autosign
+TactN="now-7d"
+keytimes="-P ${TactN} -A ${TactN}"
+KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $keytimes $zone 2>keygen.out.$zone.1)
+ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $keytimes $zone 2>keygen.out.$zone.2)
+$SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN "$KSK" >settime.out.$zone.1 2>&1
+$SETTIME -s -g $O -k $O $TactN -z $O $TactN "$ZSK" >settime.out.$zone.2 2>&1
+cat template.db.in "${KSK}.key" "${ZSK}.key" >"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK" >>"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile"
+cp $infile $zonefile
+$SIGNER -S -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
+
+# Step 2:
+# It is time to pre-publish the successor ZSK.
+setup step2.zsk-prepub.autosign
+# According to RFC 7583:
+# Tact(N) = now + Ipub - Lzsk = now + 26h - 30d
+# = now + 26h - 30d = now − 694h
+TactN="now-694h"
+keytimes="-P ${TactN} -A ${TactN}"
+KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $keytimes $zone 2>keygen.out.$zone.1)
+ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $keytimes $zone 2>keygen.out.$zone.2)
+$SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN "$KSK" >settime.out.$zone.1 2>&1
+$SETTIME -s -g $O -k $O $TactN -z $O $TactN "$ZSK" >settime.out.$zone.2 2>&1
+cat template.db.in "${KSK}.key" "${ZSK}.key" >"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK" >>"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile"
+cp $infile $zonefile
+$SIGNER -S -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
+
+# Step 3:
+# After the publication interval has passed the DNSKEY of the successor ZSK
+# is OMNIPRESENT and the zone can thus be signed with the successor ZSK.
+setup step3.zsk-prepub.autosign
+# According to RFC 7583:
+# Tpub(N+1) <= Tact(N) + Lzsk - Ipub
+# Tact(N+1) = Tact(N) + Lzsk
+#
+# Tact(N) = now - Lzsk = now - 30d
+# Tpub(N+1) = now - Ipub = now - 26h
+# Tact(N+1) = now
+# Tret(N) = now
+# Trem(N) = now + Iret = now + Dsign + Dprp + TTLsig + retire-safety = 8d1h = now + 241h
+TactN="now-30d"
+TpubN1="now-26h"
+TactN1="now"
+TremN="now+241h"
+keytimes="-P ${TactN} -A ${TactN}"
+oldtimes="-P ${TactN} -A ${TactN} -I ${TactN1} -D ${TremN}"
+newtimes="-P ${TpubN1} -A ${TactN1}"
+KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $keytimes $zone 2>keygen.out.$zone.1)
+ZSK1=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $oldtimes $zone 2>keygen.out.$zone.2)
+ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $newtimes $zone 2>keygen.out.$zone.3)
+$SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN "$KSK" >settime.out.$zone.1 2>&1
+$SETTIME -s -g $H -k $O $TactN -z $O $TactN "$ZSK1" >settime.out.$zone.2 2>&1
+$SETTIME -s -g $O -k $R $TpubN1 -z $H $TpubN1 "$ZSK2" >settime.out.$zone.3 2>&1
+# Set key rollover relationship.
+key_successor $ZSK1 $ZSK2
+# Sign zone.
+cat template.db.in "${KSK}.key" "${ZSK1}.key" "${ZSK2}.key" >"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK" >>"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK1" >>"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK2" >>"$infile"
+cp $infile $zonefile
+$SIGNER -S -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
+
+# Step 4:
+# After the retire interval has passed the predecessor DNSKEY can be
+# removed from the zone.
+setup step4.zsk-prepub.autosign
+# Lzsk: 30d
+# Ipub: 26h
+# Dsgn: 1w
+# Dprp: 1h
+# TTLsig: 1d
+# retire-safety: 2d
+#
+# According to RFC 7583:
+# Iret = Dsgn + Dprp + TTLsig (+retire-safety)
+# Iret = 1w + 1h + 1d + 2d = 10d1h = 241h
+#
+# Tact(N) = now - Iret - Lzsk
+# = now - 241h - 30d = now - 241h - 720h
+# = now - 961h
+# Tpub(N+1) = now - Iret - Ipub
+# = now - 241h - 26h
+# = now - 267h
+# Tact(N+1) = now - Iret = now - 241h
+TactN="now-961h"
+TpubN1="now-267h"
+TactN1="now-241h"
+TremN="now"
+keytimes="-P ${TactN} -A ${TactN}"
+oldtimes="-P ${TactN} -A ${TactN} -I ${TactN1} -D ${TremN}"
+newtimes="-P ${TpubN1} -A ${TactN1}"
+KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $keytimes $zone 2>keygen.out.$zone.1)
+ZSK1=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $oldtimes $zone 2>keygen.out.$zone.2)
+ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $newtimes $zone 2>keygen.out.$zone.3)
+$SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN "$KSK" >settime.out.$zone.1 2>&1
+$SETTIME -s -g $H -k $O $TactN -z $U $TactN1 "$ZSK1" >settime.out.$zone.2 2>&1
+$SETTIME -s -g $O -k $O $TactN1 -z $R $TactN1 "$ZSK2" >settime.out.$zone.3 2>&1
+# Set key rollover relationship.
+key_successor $ZSK1 $ZSK2
+# Sign zone.
+cat template.db.in "${KSK}.key" "${ZSK1}.key" "${ZSK2}.key" >"$infile"
+cp $infile $zonefile
+$SIGNER -PS -x -s now-2w -e now-1mi -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
+
+# Step 5:
+# The predecessor DNSKEY is removed long enough that is has become HIDDEN.
+setup step5.zsk-prepub.autosign
+# Subtract DNSKEY TTL + zone-propagation-delay from all the times (2h).
+# Tact(N) = now - 961h - 2h = now - 963h
+# Tpub(N+1) = now - 267h - 2h = now - 269h
+# Tact(N+1) = now - 241h - 2h = now - 243h
+# Trem(N) = Tact(N+1) + Iret = now -2h
+TactN="now-963h"
+TremN="now-2h"
+TpubN1="now-269h"
+TactN1="now-243h"
+TremN="now-2h"
+keytimes="-P ${TactN} -A ${TactN}"
+oldtimes="-P ${TactN} -A ${TactN} -I ${TactN1} -D ${TremN}"
+newtimes="-P ${TpubN1} -A ${TactN1}"
+KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $keytimes $zone 2>keygen.out.$zone.1)
+ZSK1=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $oldtimes $zone 2>keygen.out.$zone.2)
+ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $newtimes $zone 2>keygen.out.$zone.3)
+$SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN "$KSK" >settime.out.$zone.1 2>&1
+$SETTIME -s -g $H -k $U $TremN -z $H $TremN "$ZSK1" >settime.out.$zone.2 2>&1
+$SETTIME -s -g $O -k $O $TactN1 -z $O $TremN "$ZSK2" >settime.out.$zone.3 2>&1
+# Set key rollover relationship.
+key_successor $ZSK1 $ZSK2
+# Sign zone.
+cat template.db.in "${KSK}.key" "${ZSK1}.key" "${ZSK2}.key" >"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK" >>"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK1" >>"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK2" >>"$infile"
+cp $infile $zonefile
+$SIGNER -S -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
+
+# Step 6:
+# The predecessor DNSKEY can be purged.
+setup step6.zsk-prepub.autosign
+# Subtract purge-keys interval from all the times (1h).
+TactN="now-964h"
+TremN="now-3h"
+TpubN1="now-270h"
+TactN1="now-244h"
+TremN="now-3h"
+keytimes="-P ${TactN} -A ${TactN}"
+oldtimes="-P ${TactN} -A ${TactN} -I ${TactN1} -D ${TremN}"
+newtimes="-P ${TpubN1} -A ${TactN1}"
+KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $keytimes $zone 2>keygen.out.$zone.1)
+ZSK1=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $oldtimes $zone 2>keygen.out.$zone.2)
+ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $newtimes $zone 2>keygen.out.$zone.3)
+$SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN "$KSK" >settime.out.$zone.1 2>&1
+$SETTIME -s -g $H -k $H $TremN -z $H $TremN "$ZSK1" >settime.out.$zone.2 2>&1
+$SETTIME -s -g $O -k $O $TactN1 -z $O $TremN "$ZSK2" >settime.out.$zone.3 2>&1
+# Set key rollover relationship.
+key_successor $ZSK1 $ZSK2
+# Sign zone.
+cat template.db.in "${KSK}.key" "${ZSK1}.key" "${ZSK2}.key" >"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK" >>"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK1" >>"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK2" >>"$infile"
+cp $infile $zonefile
+$SIGNER -S -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
+
+
isctest.kasp.check_dnssec_verify(server, zone)
-def check_rollover_step(server, zone, config, policy, keyprops, nextev):
+def check_rollover_step(server, config, policy, step):
+ zone = step["zone"]
+ keyprops = step["keyprops"]
+ nextev = step["nextev"]
+ keyrelationships = None
+ if step.get("keyrelationships"):
+ keyrelationships = step["keyrelationships"]
+ smooth = False
+ if step.get("smooth"):
+ smooth = step["smooth"]
+
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_keys(zone, keys, expected)
for kp in expected:
+ # Set expected key timing metadata.
kp.set_expected_keytimes(config)
+ # Set rollover relationships.
+ if keyrelationships is not None:
+ prd = keyrelationships[0]
+ suc = keyrelationships[1]
+ expected[prd].metadata["Successor"] = expected[suc].key.tag
+ expected[suc].metadata["Predecessor"] = expected[prd].key.tag
+ isctest.kasp.check_keyrelationships(keys, expected)
+
# Check that CDS publication/withdrawal is logged.
if "KSK" not in kp.metadata:
continue
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_subdomain(server, zone, ksks, zsks, smooth=smooth)
isctest.kasp.check_dnssec_verify(server, zone)
def check_next_key_event():
]
for step in steps:
- check_rollover_step(
- server, step["zone"], config, policy, step["keyprops"], step["nextev"]
- )
+ check_rollover_step(server, config, policy, step)
+
+
+def test_rollover_zsk_prepublication(servers):
+ server = servers["ns3"]
+ policy = "zsk-prepub"
+ config = {
+ "dnskey-ttl": timedelta(seconds=3600),
+ "ds-ttl": timedelta(days=1),
+ "max-zone-ttl": timedelta(days=1),
+ "parent-propagation-delay": timedelta(hours=1),
+ "publish-safety": timedelta(days=1),
+ "purge-keys": timedelta(hours=1),
+ "retire-safety": timedelta(days=2),
+ "signatures-refresh": timedelta(days=7),
+ "signatures-validity": timedelta(days=14),
+ "zone-propagation-delay": timedelta(hours=1),
+ }
+ alg = os.environ["DEFAULT_ALGORITHM_NUMBER"]
+ size = os.environ["DEFAULT_BITS"]
+ zsk_lifetime = timedelta(days=30)
+ lifetime_policy = int(zsk_lifetime.total_seconds())
+
+ ipub = Ipub(config)
+ iret = Iret(config, rollover=True)
+ keyttlprop = config["dnskey-ttl"] + config["zone-propagation-delay"]
+ offsets = {}
+ offsets["step1-p"] = -int(timedelta(days=7).total_seconds())
+ offsets["step2-p"] = -int(zsk_lifetime.total_seconds() - ipub.total_seconds())
+ offsets["step2-s"] = 0
+ offsets["step3-p"] = -int(zsk_lifetime.total_seconds())
+ offsets["step3-s"] = -int(ipub.total_seconds())
+ offsets["step4-p"] = offsets["step3-p"] - int(iret.total_seconds())
+ offsets["step4-s"] = offsets["step3-s"] - int(iret.total_seconds())
+ offsets["step5-p"] = offsets["step4-p"] - int(keyttlprop.total_seconds())
+ offsets["step5-s"] = offsets["step4-s"] - int(keyttlprop.total_seconds())
+ offsets["step6-p"] = offsets["step5-p"] - int(config["purge-keys"].total_seconds())
+ offsets["step6-s"] = offsets["step5-s"] - int(config["purge-keys"].total_seconds())
+
+ steps = [
+ {
+ # Step 1.
+ # Introduce the first key. This will immediately be active.
+ "zone": "step1.zsk-prepub.autosign",
+ "keyprops": [
+ f"ksk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{offsets['step1-p']}",
+ f"zsk {lifetime_policy} {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{offsets['step1-p']}",
+ ],
+ # Next key event is when the successor ZSK needs to be published.
+ # That is the ZSK lifetime - prepublication time (minus time
+ # already passed).
+ "nextev": zsk_lifetime - ipub - timedelta(days=7),
+ },
+ {
+ # Step 2.
+ # It is time to pre-publish the successor ZSK.
+ # ZSK1 goal: omnipresent -> hidden
+ # ZSK2 goal: hidden -> omnipresent
+ # ZSK2 dnskey: hidden -> rumoured
+ "zone": "step2.zsk-prepub.autosign",
+ "keyprops": [
+ f"ksk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{offsets['step2-p']}",
+ f"zsk {lifetime_policy} {alg} {size} goal:hidden dnskey:omnipresent zrrsig:omnipresent offset:{offsets['step2-p']}",
+ f"zsk {lifetime_policy} {alg} {size} goal:omnipresent dnskey:rumoured zrrsig:hidden offset:{offsets['step2-s']}",
+ ],
+ "keyrelationships": [1, 2],
+ # Next key event is when the successor ZSK becomes OMNIPRESENT.
+ # That is the DNSKEY TTL plus the zone propagation delay
+ "nextev": ipub,
+ },
+ {
+ # Step 3.
+ # Predecessor ZSK is no longer actively signing. Successor ZSK is
+ # now actively signing.
+ # ZSK1 zrrsig: omnipresent -> unretentive
+ # ZSK2 dnskey: rumoured -> omnipresent
+ # ZSK2 zrrsig: hidden -> rumoured
+ "zone": "step3.zsk-prepub.autosign",
+ "keyprops": [
+ f"ksk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{offsets['step3-p']}",
+ f"zsk {lifetime_policy} {alg} {size} goal:hidden dnskey:omnipresent zrrsig:unretentive offset:{offsets['step3-p']}",
+ f"zsk {lifetime_policy} {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:rumoured offset:{offsets['step3-s']}",
+ ],
+ "keyrelationships": [1, 2],
+ # Next key event is when all the RRSIG records have been replaced
+ # with signatures of the new ZSK, in other words when ZRRSIG
+ # becomes OMNIPRESENT.
+ "nextev": iret,
+ # Set 'smooth' to true so expected signatures of subdomain are
+ # from the predecessor ZSK.
+ "smooth": True,
+ },
+ {
+ # Step 4.
+ # Predecessor ZSK is no longer needed. All RRsets are signed with
+ # the successor ZSK.
+ # ZSK1 dnskey: omnipresent -> unretentive
+ # ZSK1 zrrsig: unretentive -> hidden
+ # ZSK2 zrrsig: rumoured -> omnipresent
+ "zone": "step4.zsk-prepub.autosign",
+ "keyprops": [
+ f"ksk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{offsets['step4-p']}",
+ f"zsk {lifetime_policy} {alg} {size} goal:hidden dnskey:unretentive zrrsig:hidden offset:{offsets['step4-p']}",
+ f"zsk {lifetime_policy} {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{offsets['step4-s']}",
+ ],
+ "keyrelationships": [1, 2],
+ # Next key event is when the DNSKEY enters the HIDDEN state.
+ # This is the DNSKEY TTL plus zone propagation delay.
+ "nextev": keyttlprop,
+ },
+ {
+ # Step 5.
+ # Predecessor ZSK is now removed.
+ # ZSK1 dnskey: unretentive -> hidden
+ "zone": "step5.zsk-prepub.autosign",
+ "keyprops": [
+ f"ksk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{offsets['step5-p']}",
+ f"zsk {lifetime_policy} {alg} {size} goal:hidden dnskey:hidden zrrsig:hidden offset:{offsets['step5-p']}",
+ f"zsk {lifetime_policy} {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{offsets['step5-s']}",
+ ],
+ "keyrelationships": [1, 2],
+ # Next key event is when the new successor needs to be published.
+ # This is the ZSK lifetime minus Iret minus Ipub minus time
+ # elapsed.
+ "nextev": zsk_lifetime - iret - ipub - keyttlprop,
+ },
+ {
+ # Step 6.
+ # Predecessor ZSK is now purged.
+ "zone": "step6.zsk-prepub.autosign",
+ "keyprops": [
+ f"ksk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{offsets['step6-p']}",
+ f"zsk {lifetime_policy} {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{offsets['step6-s']}",
+ ],
+ "nextev": None,
+ },
+ ]
+
+ for step in steps:
+ check_rollover_step(server, config, policy, step)