# Introduce the first key. This will immediately be active.
setup step1.zsk-prepub.autosign
TactN="now"
-ksktimes="-P ${TactN} -A ${TactN}"
+ksktimes="-P ${TactN} -A ${TactN} -P sync ${TactN}"
zsktimes="-P ${TactN} -A ${TactN}"
KSK=$($KEYGEN -a ECDSAP256SHA256 -L 3600 -f KSK $ksktimes $zone 2> keygen.out.$zone.1)
ZSK=$($KEYGEN -a ECDSAP256SHA256 -L 3600 $zsktimes $zone 2> keygen.out.$zone.2)
# 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
-# Also: Ipub = Dprp + TTLkey (+publish-safety)
-# so: Tact(N) = Tpub(N+1) + Ipub - Lzsk = now + (1d2h) - 30d =
-# now + 26h - 30d = now − 694h
+# 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}"
+ksktimes="-P ${TactN} -A ${TactN} -P sync ${TactN}"
zsktimes="-P ${TactN} -A ${TactN}"
KSK=$($KEYGEN -a ECDSAP256SHA256 -L 3600 -f KSK $ksktimes $zone 2> keygen.out.$zone.1)
ZSK=$($KEYGEN -a ECDSAP256SHA256 -L 3600 $zsktimes $zone 2> keygen.out.$zone.2)
# 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
-# Also: Tret(N) = Tact(N+1) = Tact(N) + Lzsk
-# so: Tact(N) = Tact(N+1) - Lzsk = now - 30d
-# and: Tpub(N+1) = Tact(N+1) - Ipub = now - 26h
-# and: Tret(N+1) = Tact(N+1) + Lzsk
+# 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"
-ksktimes="-P ${TactN} -A ${TactN}"
-zsktimes="-P ${TactN} -A ${TactN} -I now"
-newtimes="-P ${TpubN1} -A now -I ${TretN1}"
+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 ECDSAP256SHA256 -L 3600 -f KSK $ksktimes $zone 2> keygen.out.$zone.1)
ZSK1=$($KEYGEN -a ECDSAP256SHA256 -L 3600 $zsktimes $zone 2> keygen.out.$zone.2)
ZSK2=$($KEYGEN -a ECDSAP256SHA256 -L 3600 $newtimes $zone 2> keygen.out.$zone.3)
# 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
-# Also: Tdea(N) = Tret(N) + Iret
-# Also: Iret = Dsgn + Dprp + TTLsig (+retire-safety)
-# so: Tact(N) = Tdea(N) - Iret - Lzsk = now - (1w1h1d2d) - 30d =
-# now - (10d1h) - 30d = now - 961h
-# and: Tret(N) = Tdea(N) - Iret = now - (10d1h) = now - 241h
-# and: Tpub(N+1) = Tdea(N) - Iret - Ipub = now - (10d1h) - 26h =
-# now - 267h
-# and: Tact(N+1) = Tdea(N) - Iret = Tret(N)
-# and: Tret(N+1) = Tdea(N) - Iret + Lzsk = now - (10d1h) + 30d =
-# now + 479h
+# 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"
-ksktimes="-P ${TactN} -A ${TactN}"
-zsktimes="-P ${TactN} -A ${TactN} -I ${TretN}"
-newtimes="-P ${TpubN1} -A ${TactN1} -I ${TretN1}"
+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 ECDSAP256SHA256 -L 3600 -f KSK $ksktimes $zone 2> keygen.out.$zone.1)
ZSK1=$($KEYGEN -a ECDSAP256SHA256 -L 3600 $zsktimes $zone 2> keygen.out.$zone.2)
ZSK2=$($KEYGEN -a ECDSAP256SHA256 -L 3600 $newtimes $zone 2> keygen.out.$zone.3)
# 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"
-ksktimes="-P ${TactN} -A ${TactN}"
-zsktimes="-P ${TactN} -A ${TactN} -I ${TretN} -D now"
-newtimes="-P ${TpubN1} -A ${TactN1} -I ${TretN1}"
+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 ECDSAP256SHA256 -L 3600 -f KSK $ksktimes $zone 2> keygen.out.$zone.1)
ZSK1=$($KEYGEN -a ECDSAP256SHA256 -L 3600 $zsktimes $zone 2> keygen.out.$zone.2)
ZSK2=$($KEYGEN -a ECDSAP256SHA256 -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 $TretN -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
+$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.
grep "; Created:" "$KEY_FILE" > "${ZONE}.${KEY_ID}.${_alg_num}.created" || log_error "mismatch created comment in $KEY_FILE"
KEY_CREATED=$(awk '{print $3}' < "${ZONE}.${KEY_ID}.${_alg_num}.created")
- grep "Created: ${_created}" "$PRIVATE_FILE" > /dev/null || log_error "mismatch created in $PRIVATE_FILE"
+ grep "Created: ${KEY_CREATED}" "$PRIVATE_FILE" > /dev/null || log_error "mismatch created in $PRIVATE_FILE"
if [ "$_legacy" == "no" ]; then
- grep "Generated: ${_created}" "$STATE_FILE" > /dev/null || log_error "mismatch generated in $STATE_FILE"
+ grep "Generated: ${KEY_CREATED}" "$STATE_FILE" > /dev/null || log_error "mismatch generated in $STATE_FILE"
fi
test $_log -eq 1 && echo_i "check key file $BASE_FILE"
set_zone "step1.zsk-prepub.autosign"
set_policy "zsk-prepub" "2" "3600"
set_server "ns3" "10.53.0.3"
+# Policy parameters.
+# Lksk: 2 years (63072000 seconds)
+# Lzsk: 30 days (2592000 seconds)
+# Iret(KSK): DS TTL (1d) + Dreg (1d) + DprpP (1h) + retire-safety (2d)
+# Iret(KSK): 4d1h (349200 seconds)
+# Iret(ZSK): 10d1h (867600 seconds).
+Lksk=63072000
+Lzsk=2592000
+IretKSK=349200
+IretZSK=867600
+
+set_retired_removed() {
+ _Lkey=$2
+ _Iret=$3
+
+ _active=$(key_get $1 ACTIVE)
+ set_addkeytime "${1}" "RETIRED" "${_active}" "${_Lkey}"
+ _retired=$(key_get $1 RETIRED)
+ set_addkeytime "${1}" "REMOVED" "${_retired}" "${_Iret}"
+}
+
+zsk_prepub_predecessor_keytimes() {
+ _addtime=$1
+
+ _created=$(key_get KEY1 CREATED)
+ set_addkeytime "KEY1" "PUBLISHED" "${_created}" "${_addtime}"
+ set_addkeytime "KEY1" "SYNCPUBLISH" "${_created}" "${_addtime}"
+ set_addkeytime "KEY1" "ACTIVE" "${_created}" "${_addtime}"
+ set_retired_removed "KEY1" "${Lksk}" "${IretKSK}"
+
+ _created=$(key_get KEY2 CREATED)
+ set_addkeytime "KEY2" "PUBLISHED" "${_created}" "${_addtime}"
+ set_addkeytime "KEY2" "ACTIVE" "${_created}" "${_addtime}"
+ set_retired_removed "KEY2" "${Lzsk}" "${IretZSK}"
+}
+
# Key properties.
key_clear "KEY1"
set_keyrole "KEY1" "ksk"
-set_keylifetime "KEY1" "63072000"
+set_keylifetime "KEY1" "${Lksk}"
set_keyalgorithm "KEY1" "13" "ECDSAP256SHA256" "256"
set_keysigning "KEY1" "yes"
set_zonesigning "KEY1" "no"
key_clear "KEY2"
set_keyrole "KEY2" "zsk"
-set_keylifetime "KEY2" "2592000"
+set_keylifetime "KEY2" "${Lzsk}"
set_keyalgorithm "KEY2" "13" "ECDSAP256SHA256" "256"
set_keysigning "KEY2" "no"
set_zonesigning "KEY2" "yes"
-# Key timings.
-set_keytime "KEY1" "PUBLISHED" "yes"
-set_keytime "KEY1" "ACTIVE" "yes"
-set_keytime "KEY1" "RETIRED" "yes"
-
-set_keytime "KEY2" "PUBLISHED" "yes"
-set_keytime "KEY2" "ACTIVE" "yes"
-set_keytime "KEY2" "RETIRED" "yes"
# Both KSK (KEY1) and ZSK (KEY2) start in OMNIPRESENT.
set_keystate "KEY1" "GOAL" "omnipresent"
set_keystate "KEY1" "STATE_DNSKEY" "omnipresent"
key_clear "KEY4"
check_keys
+
+# These keys are immediately published and activated.
+zsk_prepub_predecessor_keytimes 0
+check_keytimes
+
check_apex
check_subdomain
dnssec_verify
# New ZSK (KEY3) is prepublished, but not yet signing.
key_clear "KEY3"
set_keyrole "KEY3" "zsk"
-set_keylifetime "KEY3" "2592000"
+set_keylifetime "KEY3" "${Lzsk}"
set_keyalgorithm "KEY3" "13" "ECDSAP256SHA256" "256"
set_keysigning "KEY3" "no"
set_zonesigning "KEY3" "no"
-# Key timings.
-set_keytime "KEY3" "PUBLISHED" "yes"
-set_keytime "KEY3" "ACTIVE" "yes"
-set_keytime "KEY3" "RETIRED" "yes"
# Key states.
-set_keystate "KEY3" "GOAL" "omnipresent"
+set_keystate "KEY3" "GOAL" "omnipresent"
set_keystate "KEY3" "STATE_DNSKEY" "rumoured"
set_keystate "KEY3" "STATE_ZRRSIG" "hidden"
check_keys
+
+# The old keys were activated 694 hours ago (2498400 seconds).
+zsk_prepub_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}"
+check_keytimes
+
check_apex
check_subdomain
dnssec_verify
set_keystate "KEY3" "STATE_ZRRSIG" "rumoured"
check_keys
+
+# The old keys are activated 30 days ago (2592000 seconds).
+zsk_prepub_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}"
+check_keytimes
+
check_apex
# Subdomain still has good signatures of ZSK (KEY2).
# Set expected zone signing on for KEY2 and off for KEY3,
set_keystate "KEY3" "STATE_ZRRSIG" "omnipresent"
check_keys
+
+# The old keys are activated 961 hours ago (3459600 seconds).
+zsk_prepub_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}"
+check_keytimes
+
check_apex
check_subdomain
dnssec_verify
set_zone "step5.zsk-prepub.autosign"
set_policy "zsk-prepub" "3" "3600"
set_server "ns3" "10.53.0.3"
-# ZSK (KEY3) DNSKEY is now completely HIDDEN and removed.
-set_keytime "KEY2" "REMOVED" "yes"
+# ZSK (KEY2) DNSKEY is now completely HIDDEN and removed.
set_keystate "KEY2" "STATE_DNSKEY" "hidden"
-# ZSK (KEY3) remains actively signing, staying in OMNIPRESENT.
check_keys
+
+# The old keys are activated 962 hours ago (3463200 seconds).
+zsk_prepub_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}"
+check_keytimes
+
check_apex
check_subdomain
dnssec_verify