has_dnskey = True
break
- if not cdnskey:
- assert has_dnskey
+ if not published or removed:
+ if not cdnskey:
+ assert has_dnskey
if has_dnskey:
numkeys += 1
assert numkeys == len(dnskeys)
-def check_cds(rrset, keys):
+def check_cds(cdss, keys, alg):
# Check if the correct CDS records are published. If the current time
# is between the timing metadata 'publish' and 'delete', the key must have
- # a DNSKEY record published. If 'cdnskey' is True, check against CDNSKEY
- # records instead.
+ # a CDS record published.
now = KeyTimingMetadata.now()
numcds = 0
- cdss = []
- for rr in rrset:
- for rdata in rr:
- rdclass = dns.rdataclass.to_text(rr.rdclass)
- rdtype = dns.rdatatype.to_text(rr.rdtype)
- cds = f"{rr.name} {rr.ttl} {rdclass} {rdtype} {rdata}"
- cdss.append(cds)
-
for key in keys:
assert key.is_ksk()
removed = delete is not None and delete <= now
if not published or removed:
for cds in cdss:
- assert not key.cds_equals(cds, "SHA-256")
+ assert not key.cds_equals(cds, alg)
continue
has_cds = False
for cds in cdss:
- if key.cds_equals(cds, "SHA-256"):
+ if key.cds_equals(cds, alg):
has_cds = True
break
- assert has_cds
- numcds += 1
+ if not published or removed:
+ assert has_cds
+
+ if has_cds:
+ numcds += 1
+
+ return numcds
- assert numcds == len(cdss)
+
+def check_cds_prohibit(cdss, keys, alg):
+ # Check if the CDS records are not published. This does not take into
+ # account the timing metadata, just making sure that the given algorithm
+ # does not get published.
+ for key in keys:
+ for cds in cdss:
+ assert not key.cds_equals(cds, alg)
def check_cdslog(server, zone, key, substr):
def check_apex(
- server, zone, ksks, zsks, offline_ksk=False, zsk_missing=False, tsig=None
+ server, zone, ksks, zsks, cdss=None, offline_ksk=False, zsk_missing=False, tsig=None
):
# Test the apex of a zone. This checks that the SOA and DNSKEY RRsets
# are signed correctly and with the appropriate keys.
fqdn = f"{zone}."
+ if cdss is None:
+ cdss = ["CDNSKEY", "CDS (SHA-256)"]
+
# test dnskey query
dnskeys, rrsigs = _query_rrset(server, fqdn, dns.rdatatype.DNSKEY, tsig=tsig)
check_dnskeys(dnskeys, ksks, zsks)
# test cdnskey query
cdnskeys, rrsigs = _query_rrset(server, fqdn, dns.rdatatype.CDNSKEY, tsig=tsig)
- check_dnskeys(cdnskeys, ksks, zsks, cdnskey=True)
+
+ if "CDNSKEY" in cdss:
+ check_dnskeys(cdnskeys, ksks, zsks, cdnskey=True)
+ else:
+ assert len(cdnskeys) == 0
+
if len(cdnskeys) > 0:
assert len(rrsigs) > 0
check_signatures(
# test cds query
cds, rrsigs = _query_rrset(server, fqdn, dns.rdatatype.CDS, tsig=tsig)
- check_cds(cds, ksks)
+ cdsrrs = []
+ for rr in cds:
+ for rdata in rr:
+ rdclass = dns.rdataclass.to_text(rr.rdclass)
+ rdtype = dns.rdatatype.to_text(rr.rdtype)
+ cds = f"{rr.name} {rr.ttl} {rdclass} {rdtype} {rdata}"
+ cdsrrs.append(cds)
+
+ numcds = 0
+
+ for alg in ["SHA-256", "SHA-384"]:
+ if f"CDS ({alg})" in cdss:
+ numcds += check_cds(cdsrrs, ksks, alg)
+ else:
+ check_cds_prohibit(cdsrrs, ksks, alg)
+
if len(cds) > 0:
assert len(rrsigs) > 0
check_signatures(
rrsigs, dns.rdatatype.CDS, fqdn, ksks, zsks, offline_ksk=offline_ksk
)
+ assert numcds == len(cdsrrs)
+
def check_subdomain(
server, zone, ksks, zsks, offline_ksk=False, smooth=False, tsig=None
dnssec-policy "autosign";
};
-/*
- * Zones for testing KSK Double-KSK steps.
- */
-zone "step1.ksk-doubleksk.autosign" {
- type primary;
- file "step1.ksk-doubleksk.autosign.db";
- dnssec-policy "ksk-doubleksk";
-};
-zone "step2.ksk-doubleksk.autosign" {
- type primary;
- file "step2.ksk-doubleksk.autosign.db";
- dnssec-policy "ksk-doubleksk";
-};
-zone "step3.ksk-doubleksk.autosign" {
- type primary;
- file "step3.ksk-doubleksk.autosign.db";
- dnssec-policy "ksk-doubleksk";
-};
-zone "step4.ksk-doubleksk.autosign" {
- type primary;
- file "step4.ksk-doubleksk.autosign.db";
- dnssec-policy "ksk-doubleksk";
-};
-zone "step5.ksk-doubleksk.autosign" {
- type primary;
- file "step5.ksk-doubleksk.autosign.db";
- dnssec-policy "ksk-doubleksk";
-};
-zone "step6.ksk-doubleksk.autosign" {
- type primary;
- file "step6.ksk-doubleksk.autosign.db";
- dnssec-policy "ksk-doubleksk";
-};
-
/*
* Zones for testing CSK rollover steps.
*/
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 ksk-doubleksk.autosign represent the various steps of a KSK
-# Double-KSK rollover.
-#
-
-# Step 1:
-# Introduce the first key. This will immediately be active.
-setup step1.ksk-doubleksk.autosign
-TactN="now"
-ksktimes="-P ${TactN} -A ${TactN} -P sync ${TactN}"
-zsktimes="-P ${TactN} -A ${TactN}"
-KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $ksktimes $zone 2>keygen.out.$zone.1)
-ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 $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"
-cp $infile $zonefile
-$SIGNER -S -x -G "cds:sha-256" -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
-
-# Step 2:
-# It is time to submit the introduce the new KSK.
-setup step2.ksk-doubleksk.autosign
-# According to RFC 7583:
-#
-# Tpub(N+1) <= Tact(N) + Lksk - Dreg - IpubC
-# IpubC = DprpC + TTLkey (+publish-safety)
-#
-# |1| |2| |3| |4|
-# | | | |
-# Key N |<-IpubC->|<--->|<-Dreg->|<-----Lksk--- - -
-# | | | |
-# Key N+1 | | | |
-# | | | |
-# Key N Tpub Trdy Tsbm Tact
-# Key N+1
-#
-# (continued ...)
-#
-# |5| |6| |7| |8| |9| |10|
-# | | | | | |
-# Key N - - --------------Lksk------->|<-Iret->|<----->|
-# | | | | | |
-# Key N+1 |<-IpubC->|<--->|<-Dreg->|<--------Lksk----- - -
-# | | | | | |
-# Key N Tret Tdea Trem
-# Key N+1 Tpub Trdy Tsbm Tact
-#
-# Tnow
-#
-# Lksk: 60d
-# Dreg: 1d
-# DprpC: 1h
-# TTLkey: 2h
-# publish-safety: 1d
-# IpubC: 27h
-#
-# Tact(N) = Tnow - Lksk + Dreg + IpubC = now - 60d + 27h
-# = now - 1440h + 27h = now - 1413h
-TactN="now-1413h"
-ksktimes="-P ${TactN} -A ${TactN} -P sync ${TactN}"
-zsktimes="-P ${TactN} -A ${TactN}"
-KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $ksktimes $zone 2>keygen.out.$zone.1)
-ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 $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 -G "cds:sha-256" -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
-
-# Step 3:
-# It is time to submit the DS.
-setup step3.ksk-doubleksk.autosign
-# According to RFC 7583:
-#
-# Tsbm(N+1) >= Trdy(N+1)
-# Tact(N+1) = Tsbm(N+1) + Dreg
-# Iret = DprpP + TTLds (+retire-safety)
-#
-# |5| |6| |7| |8| |9| |10|
-# | | | | | |
-# Key N - - --------------Lksk------->|<-Iret->|<----->|
-# | | | | | |
-# Key N+1 |<-IpubC->|<--->|<-Dreg->|<--------Lksk----- - -
-# | | | | | |
-# Key N Tret Tdea Trem
-# Key N+1 Tpub Trdy Tsbm Tact
-#
-# Tnow
-#
-# Lksk: 60d
-# Dreg: N/A
-# DprpP: 1h
-# TTLds: 1h
-# retire-safety: 2d
-# Iret: 50h
-# DprpC: 1h
-# TTLkey: 2h
-# publish-safety: 1d
-# IpubC: 27h
-#
-# Tact(N) = Tnow + Lksk = now - 60d = now - 60d
-# Tret(N) = now
-# Trem(N) = Tnow + Iret = now + 50h
-# Tpub(N+1) = Tnow - IpubC = now - 27h
-# Tsbm(N+1) = now
-# Tact(N+1) = Tret(N)
-# Tret(N+1) = Tnow + Lksk = now + 60d
-# Trem(N+1) = Tnow + Lksk + Iret = now + 60d + 50h
-# = now + 1440h + 50h = 1490h
-TactN="now-60d"
-TretN="now"
-TremN="now+50h"
-TpubN1="now-27h"
-TsbmN1="now"
-TactN1="${TretN}"
-TretN1="now+60d"
-TremN1="now+1490h"
-ksktimes="-P ${TactN} -A ${TactN} -P sync ${TactN} -I ${TretN} -D ${TremN}"
-newtimes="-P ${TpubN1} -A ${TactN1} -P sync ${TsbmN1} -I ${TretN1} -D ${TremN1}"
-zsktimes="-P ${TactN} -A ${TactN}"
-KSK1=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $ksktimes $zone 2>keygen.out.$zone.1)
-KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $newtimes $zone 2>keygen.out.$zone.2)
-ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 $zsktimes $zone 2>keygen.out.$zone.3)
-$SETTIME -s -g $H -k $O $TactN -r $O $TactN -d $O $TactN "$KSK1" >settime.out.$zone.1 2>&1
-$SETTIME -s -g $O -k $R $TpubN1 -r $R $TpubN1 -d $H $TpubN1 "$KSK2" >settime.out.$zone.2 2>&1
-$SETTIME -s -g $O -k $O $TactN -z $O $TactN "$ZSK" >settime.out.$zone.3 2>&1
-# Set key rollover relationship.
-key_successor $KSK1 $KSK2
-# Sign zone.
-cat template.db.in "${KSK1}.key" "${KSK2}.key" "${ZSK}.key" >"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK1" >>"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile"
-cp $infile $zonefile
-$SIGNER -S -x -G "cds:sha-256" -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
-
-# Step 4:
-# The DS should be swapped now.
-setup step4.ksk-doubleksk.autosign
-# According to RFC 7583:
-#
-# Tret(N) = Tsbm(N+1)
-# Tdea(N) = Tret(N) + Iret
-# Tact(N+1) = Tret(N)
-#
-# |5| |6| |7| |8| |9| |10|
-# | | | | | |
-# Key N - - --------------Lksk------->|<-Iret->|<----->|
-# | | | | | |
-# Key N+1 |<-IpubC->|<--->|<-Dreg->|<--------Lksk----- - -
-# | | | | | |
-# Key N Tret Tdea Trem
-# Key N+1 Tpub Trdy Tsbm Tact
-#
-# Tnow
-#
-# Lksk: 60d
-# Dreg: N/A
-# Iret: 50h
-#
-# Tact(N) = Tnow - Lksk - Iret = now - 60d - 50h
-# = now - 1440h - 50h = now - 1490h
-# Tret(N) = Tnow - Iret = now - 50h
-# Trem(N) = Tnow
-# Tpub(N+1) = Tnow - Iret - IpubC = now - 50h - 27h
-# = now - 77h
-# Tsbm(N+1) = Tnow - Iret = now - 50h
-# Tact(N+1) = Tret(N)
-# Tret(N+1) = Tnow + Lksk - Iret = now + 60d - 50h = now + 1390h
-# Trem(N+1) = Tnow + Lksk = now + 60d
-TactN="now-1490h"
-TretN="now-50h"
-TremN="now"
-TpubN1="now-77h"
-TsbmN1="now-50h"
-TactN1="${TretN}"
-TretN1="now+1390h"
-TremN1="now+60d"
-ksktimes="-P ${TactN} -A ${TactN} -P sync ${TactN} -I ${TretN} -D ${TremN}"
-newtimes="-P ${TpubN1} -A ${TretN} -P sync ${TsbmN1} -I ${TretN1} -D ${TremN1}"
-zsktimes="-P ${TactN} -A ${TactN}"
-KSK1=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $ksktimes $zone 2>keygen.out.$zone.1)
-KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $newtimes $zone 2>keygen.out.$zone.2)
-ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 $zsktimes $zone 2>keygen.out.$zone.3)
-$SETTIME -s -g $H -k $O $TactN -r $O $TactN -d $U $TsbmN1 -D ds $TsbmN1 "$KSK1" >settime.out.$zone.1 2>&1
-$SETTIME -s -g $O -k $O $TsbmN1 -r $O $TsbmN1 -d $R $TsbmN1 -P ds $TsbmN1 "$KSK2" >settime.out.$zone.2 2>&1
-$SETTIME -s -g $O -k $O $TactN -z $O $TactN "$ZSK" >settime.out.$zone.3 2>&1
-# Set key rollover relationship.
-key_successor $KSK1 $KSK2
-# Sign zone.
-cat template.db.in "${KSK1}.key" "${KSK2}.key" "${ZSK}.key" >"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK1" >>"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile"
-cp $infile $zonefile
-$SIGNER -S -x -G "cds:sha-256" -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
-
-# Step 5:
-# The predecessor DNSKEY is removed long enough that is has become HIDDEN.
-setup step5.ksk-doubleksk.autosign
-# Subtract DNSKEY TTL from all the times (2h).
-# Tact(N) = now - 1490h - 2h = now - 1492h
-# Tret(N) = now - 50h - 2h = now - 52h
-# Trem(N) = now - 2h
-# Tpub(N+1) = now - 77h - 2h = now - 79h
-# Tsbm(N+1) = now - 50h - 2h = now - 52h
-# Tact(N+1) = Tret(N)
-# Tret(N+1) = now + 1390h - 2h = now + 1388h
-# Trem(N+1) = now + 60d - 2h = now + 1442h
-TactN="now-1492h"
-TretN="now-52h"
-TremN="now-2h"
-TpubN1="now-79h"
-TsbmN1="now-52h"
-TactN1="${TretN}"
-TretN1="now+1388h"
-TremN1="now+1442h"
-ksktimes="-P ${TactN} -A ${TactN} -P sync ${TactN} -I ${TretN} -D ${TremN}"
-newtimes="-P ${TpubN1} -A ${TretN} -P sync ${TsbmN1} -I ${TretN1} -D ${TremN1}"
-zsktimes="-P ${TactN} -A ${TactN}"
-KSK1=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $ksktimes $zone 2>keygen.out.$zone.1)
-KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $newtimes $zone 2>keygen.out.$zone.2)
-ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 $zsktimes $zone 2>keygen.out.$zone.3)
-$SETTIME -s -g $H -k $U $TretN -r $U $TretN -d $H $TretN "$KSK1" >settime.out.$zone.1 2>&1
-$SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $O $TactN1 "$KSK2" >settime.out.$zone.2 2>&1
-$SETTIME -s -g $O -k $O $TactN -z $O $TactN "$ZSK" >settime.out.$zone.3 2>&1
-# Set key rollover relationship.
-key_successor $KSK1 $KSK2
-# Sign zone.
-cat template.db.in "${KSK1}.key" "${KSK2}.key" "${ZSK}.key" >"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK1" >>"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile"
-cp $infile $zonefile
-$SIGNER -S -x -G "cds:sha-256" -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
-
-# Step 6:
-# The predecessor DNSKEY can be purged.
-setup step6.ksk-doubleksk.autosign
-# Subtract purge-keys interval from all the times (1h).
-# Tact(N) = now - 1492h - 1h = now - 1493h
-# Tret(N) = now - 52h - 1h = now - 53h
-# Trem(N) = now - 2h - 1h = now - 3h
-# Tpub(N+1) = now - 79h - 1h = now - 80h
-# Tsbm(N+1) = now - 52h - 1h = now - 53h
-# Tact(N+1) = Tret(N)
-# Tret(N+1) = now + 1388h - 1h = now + 1387h
-# Trem(N+1) = now + 1442h - 1h = now + 1441h
-TactN="now-1493h"
-TretN="now-53h"
-TremN="now-3h"
-TpubN1="now-80h"
-TsbmN1="now-53h"
-TactN1="${TretN}"
-TretN1="now+1387h"
-TremN1="now+1441h"
-ksktimes="-P ${TactN} -A ${TactN} -P sync ${TactN} -I ${TretN} -D ${TremN}"
-newtimes="-P ${TpubN1} -A ${TretN} -P sync ${TsbmN1} -I ${TretN1} -D ${TremN1}"
-zsktimes="-P ${TactN} -A ${TactN}"
-KSK1=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $ksktimes $zone 2>keygen.out.$zone.1)
-KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $newtimes $zone 2>keygen.out.$zone.2)
-ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 $zsktimes $zone 2>keygen.out.$zone.3)
-$SETTIME -s -g $H -k $H $TretN -r $H $TretN -d $H $TretN "$KSK1" >settime.out.$zone.1 2>&1
-$SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $O $TactN1 "$KSK2" >settime.out.$zone.2 2>&1
-$SETTIME -s -g $O -k $O $TactN -z $O $TactN "$ZSK" >settime.out.$zone.3 2>&1
-# Set key rollover relationship.
-key_successor $KSK1 $KSK2
-# Sign zone.
-cat template.db.in "${KSK1}.key" "${KSK2}.key" "${ZSK}.key" >"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK1" >>"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile"
-private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile"
-cp $infile $zonefile
-$SIGNER -S -x -G "cds:sha-256" -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
-
#
# 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).
[ "$Lzsk" = 0 ] || set_retired_removed "KEY2" "${Lzsk}" "${IretZSK}"
}
-#
-# Testing KSK Double-KSK rollover.
-#
-
-# Policy parameters.
-# Lksk: 60 days (16070400 seconds)
-# Lzsk: 1 year (31536000 seconds)
-# Iret(KSK): DS TTL (1h) + DprpP (1h) + retire-safety (2d)
-# Iret(KSK): 50h (180000 seconds)
-# Iret(ZSK): RRSIG TTL (1d) + Dprp (1h) + Dsgn (1w) + retire-safety (2d)
-# Iret(ZSK): 10d1h (867600 seconds)
-Lksk=5184000
-Lzsk=31536000
-IretKSK=180000
-IretZSK=867600
-
-#
-# Zone: step1.ksk-doubleksk.autosign.
-#
-set_zone "step1.ksk-doubleksk.autosign"
-set_policy "ksk-doubleksk" "2" "7200"
-CDNSKEY="no"
-set_server "ns3" "10.53.0.3"
-# 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 KSK needs to be published. That is
-# the KSK lifetime - prepublication time. The prepublication time is
-# DNSKEY TTL plus publish safety plus the zone propagation delay.
-# For the ksk-doubleksk policy that means: 60d - (1d3h) = 5086800 seconds.
-check_next_key_event 5086800
-
-#
-# Zone: step2.ksk-doubleksk.autosign.
-#
-set_zone "step2.ksk-doubleksk.autosign"
-set_policy "ksk-doubleksk" "3" "7200"
-CDNSKEY="no"
-set_server "ns3" "10.53.0.3"
-# New KSK (KEY3) is prepublished (and signs DNSKEY RRset).
-key_clear "KEY3"
-set_keyrole "KEY3" "ksk"
-set_keylifetime "KEY3" "${Lksk}"
-set_keyalgorithm "KEY3" "$DEFAULT_ALGORITHM_NUMBER" "$DEFAULT_ALGORITHM" "$DEFAULT_BITS"
-set_keysigning "KEY3" "yes"
-set_zonesigning "KEY3" "no"
-# Key states.
-set_keystate "KEY1" "GOAL" "hidden"
-set_keystate "KEY3" "GOAL" "omnipresent"
-set_keystate "KEY3" "STATE_DNSKEY" "rumoured"
-set_keystate "KEY3" "STATE_KRRSIG" "rumoured"
-set_keystate "KEY3" "STATE_DS" "hidden"
-
-# Various signing policy checks.
-check_keys
-check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
-
-# Set expected key times:
-# - The old keys were activated 1413 hours ago (5086800 seconds).
-rollover_predecessor_keytimes -5086800
-# - The new KSK is published now.
-created=$(key_get KEY3 CREATED)
-set_keytime "KEY3" "PUBLISHED" "${created}"
-# The new KSK should publish the CDS after the prepublication time.
-# TTLkey: 2h
-# DprpC: 1h
-# publish-safety: 1d
-# IpubC: 27h (97200 seconds)
-IpubC=97200
-set_addkeytime "KEY3" "SYNCPUBLISH" "${created}" "${IpubC}"
-set_addkeytime "KEY3" "ACTIVE" "${created}" "${IpubC}"
-set_retired_removed "KEY3" "${Lksk}" "${IretKSK}"
-
-# Continue signing policy checks.
-check_keytimes
-check_apex
-check_subdomain
-dnssec_verify
-
-# Next key event is when the successor KSK becomes OMNIPRESENT. That is the
-# DNSKEY TTL plus the zone propagation delay, plus the publish-safety. For
-# the ksk-doubleksk policy, this means: 7200s + 1h + 1d = 97200 seconds.
-check_next_key_event 97200
-
-#
-# Zone: step3.ksk-doubleksk.autosign.
-#
-set_zone "step3.ksk-doubleksk.autosign"
-set_policy "ksk-doubleksk" "3" "7200"
-CDNSKEY="no"
-set_server "ns3" "10.53.0.3"
-
-# The DNSKEY RRset has become omnipresent.
-# Check keys before we tell named that we saw the DS has been replaced.
-set_keystate "KEY3" "STATE_DNSKEY" "omnipresent"
-set_keystate "KEY3" "STATE_KRRSIG" "omnipresent"
-# The old DS (KEY1) can be withdrawn and the new DS (KEY3) can be introduced.
-set_keystate "KEY1" "STATE_DS" "unretentive"
-set_keystate "KEY3" "STATE_DS" "rumoured"
-
-# Various signing policy checks.
-check_keys
-check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
-# Check that CDS publication is logged.
-check_cdslog "$DIR" "$ZONE" KEY3
-
-# Set expected key times:
-# - The old keys were activated 60 days ago (5184000 seconds).
-rollover_predecessor_keytimes -5184000
-# - The new KSK is published 27 hours ago (97200 seconds).
-created=$(key_get KEY3 CREATED)
-set_addkeytime "KEY3" "PUBLISHED" "${created}" -97200
-# - The new KSK CDS is published now.
-set_keytime "KEY3" "SYNCPUBLISH" "${created}"
-syncpub=$(key_get KEY3 SYNCPUBLISH)
-set_keytime "KEY3" "ACTIVE" "${syncpub}"
-set_retired_removed "KEY3" "${Lksk}" "${IretKSK}"
-
-# Continue signing policy checks.
-check_keytimes
-check_apex
-check_subdomain
-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" KEY3 "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 ksk-double-ksk policy this means:
-# 1h + 3600s + 2d = 2d2h = 180000 seconds.
-check_next_key_event 180000
-
-#
-# Zone: step4.ksk-doubleksk.autosign.
-#
-set_zone "step4.ksk-doubleksk.autosign"
-set_policy "ksk-doubleksk" "3" "7200"
-CDNSKEY="no"
-set_server "ns3" "10.53.0.3"
-# KSK (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"
-# New KSK (KEY3) DS is now OMNIPRESENT.
-set_keystate "KEY3" "STATE_DS" "omnipresent"
-
-# Various signing policy checks.
-check_keys
-check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
-
-# Set expected key times:
-# - The old keys were activated 1490 hours ago (5364000 seconds).
-rollover_predecessor_keytimes -5364000
-# - The new KSK is published 77 hours ago (277200 seconds).
-created=$(key_get KEY3 CREATED)
-set_addkeytime "KEY3" "PUBLISHED" "${created}" -277200
-published=$(key_get KEY3 PUBLISHED)
-set_addkeytime "KEY3" "SYNCPUBLISH" "${published}" "${IpubC}"
-syncpub=$(key_get KEY3 SYNCPUBLISH)
-set_keytime "KEY3" "ACTIVE" "${syncpub}"
-set_retired_removed "KEY3" "${Lksk}" "${IretKSK}"
-
-# 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 ksk-doubleksk policy this is:
-# 7200s + 1h = 10800s
-check_next_key_event 10800
-
-#
-# Zone: step5.ksk-doubleksk.autosign.
-#
-set_zone "step5.ksk-doubleksk.autosign"
-set_policy "ksk-doubleksk" "3" "7200"
-CDNSKEY="no"
-set_server "ns3" "10.53.0.3"
-# KSK (KEY1) DNSKEY is now 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:
-# - The old KSK is activated 1492 hours ago (5371200 seconds).
-rollover_predecessor_keytimes -5371200
-# - The new KSK is published 79 hours ago (284400 seconds).
-created=$(key_get KEY3 CREATED)
-set_addkeytime "KEY3" "PUBLISHED" "${created}" -284400
-published=$(key_get KEY3 PUBLISHED)
-set_addkeytime "KEY3" "SYNCPUBLISH" "${published}" "${IpubC}"
-syncpub=$(key_get KEY3 SYNCPUBLISH)
-set_keytime "KEY3" "ACTIVE" "${syncpub}"
-set_retired_removed "KEY3" "${Lksk}" "${IretKSK}"
-
-# Various 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
-# KSK lifetime minus Ipub minus Iret minus DNSKEY TTL. For the
-# ksk-doubleksk this is: 60d - 1d3h - 1d - 2d2h - 2h =
-# 5184000 - 97200 - 180000 - 7200 = 4813200 seconds.
-check_next_key_event 4899600
-
-#
-# Zone: step6.ksk-doubleksk.autosign.
-#
-set_zone "step6.ksk-doubleksk.autosign"
-set_policy "ksk-doubleksk" "2" "7200"
-CDNSKEY="no"
-set_server "ns3" "10.53.0.3"
-# KSK (KEY1) DNSKEY 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 (1).
#
zone-propagation-delay PT1H;
max-zone-ttl 1d;
};
+
+dnssec-policy "ksk-doubleksk" {
+ signatures-refresh P1W;
+ signatures-validity P2W;
+ signatures-validity-dnskey P2W;
+
+ dnskey-ttl 2h;
+ publish-safety P1D;
+ retire-safety P2D;
+ purge-keys PT1H;
+
+ cdnskey no;
+ keys {
+ ksk key-directory lifetime P60D algorithm @DEFAULT_ALGORITHM@;
+ zsk key-directory lifetime unlimited algorithm @DEFAULT_ALGORITHM@;
+ };
+
+ zone-propagation-delay PT1H;
+ max-zone-ttl 1d;
+
+ parent-ds-ttl 3600;
+ parent-propagation-delay PT1H;
+};
file "step6.zsk-prepub.autosign.db";
dnssec-policy "zsk-prepub";
};
+
+/*
+ * Zones for testing KSK Double-KSK steps.
+ */
+zone "step1.ksk-doubleksk.autosign" {
+ type primary;
+ file "step1.ksk-doubleksk.autosign.db";
+ dnssec-policy "ksk-doubleksk";
+};
+zone "step2.ksk-doubleksk.autosign" {
+ type primary;
+ file "step2.ksk-doubleksk.autosign.db";
+ dnssec-policy "ksk-doubleksk";
+};
+zone "step3.ksk-doubleksk.autosign" {
+ type primary;
+ file "step3.ksk-doubleksk.autosign.db";
+ dnssec-policy "ksk-doubleksk";
+};
+zone "step4.ksk-doubleksk.autosign" {
+ type primary;
+ file "step4.ksk-doubleksk.autosign.db";
+ dnssec-policy "ksk-doubleksk";
+};
+zone "step5.ksk-doubleksk.autosign" {
+ type primary;
+ file "step5.ksk-doubleksk.autosign.db";
+ dnssec-policy "ksk-doubleksk";
+};
+zone "step6.ksk-doubleksk.autosign" {
+ type primary;
+ file "step6.ksk-doubleksk.autosign.db";
+ dnssec-policy "ksk-doubleksk";
+};
cp $infile $zonefile
$SIGNER -S -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
+#
+# The zones at ksk-doubleksk.autosign represent the various steps of a KSK
+# Double-KSK rollover.
+#
+
+# Step 1:
+# Introduce the first key. This will immediately be active.
+setup step1.ksk-doubleksk.autosign
+TactN="now-7d"
+keytimes="-P ${TactN} -A ${TactN}"
+KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $keytimes $zone 2>keygen.out.$zone.1)
+ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 $keytimes $zone 2>keygen.out.$zone.2)
+$SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN "$KSK" >settime.out.$zone.1 2>&1
+$SETTIME -s -g $O -k $O $TactN -z $O $TactN "$ZSK" >settime.out.$zone.2 2>&1
+cat template.db.in "${KSK}.key" "${ZSK}.key" >"$infile"
+cp $infile $zonefile
+$SIGNER -S -x -G "cds:sha-256" -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
+
+# Step 2:
+# It is time to submit the introduce the new KSK.
+setup step2.ksk-doubleksk.autosign
+# Lksk: 60d
+# Dreg: n/a
+# DprpC: 1h
+# TTLds: 1d
+# TTLkey: 2h
+# publish-safety: 1d
+# retire-safety: 2d
+#
+# According to RFC 7583:
+# Tpub(N+1) <= Tact(N) + Lksk - Dreg - IpubC
+# IpubC = DprpC + TTLkey (+publish-safety)
+#
+# IpubC = 27h
+# Tact(N) = now - Lksk + Dreg + IpubC = now - 60d + 27h
+# = now - 1440h + 27h = now - 1413h
+TactN="now-1413h"
+keytimes="-P ${TactN} -A ${TactN}"
+KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $keytimes $zone 2>keygen.out.$zone.1)
+ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 $keytimes $zone 2>keygen.out.$zone.2)
+$SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN "$KSK" >settime.out.$zone.1 2>&1
+$SETTIME -s -g $O -k $O $TactN -z $O $TactN "$ZSK" >settime.out.$zone.2 2>&1
+cat template.db.in "${KSK}.key" "${ZSK}.key" >"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK" >>"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile"
+cp $infile $zonefile
+$SIGNER -S -x -G "cds:sha-256" -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
+
+# Step 3:
+# It is time to submit the DS.
+setup step3.ksk-doubleksk.autosign
+# According to RFC 7583:
+# Iret = DprpP + TTLds (+retire-safety)
+#
+# Iret = 50h
+# Tpub(N) = now - Lksk = now - 60d = now - 60d
+# Tact(N) = now - 1413h
+# Tret(N) = now
+# Trem(N) = now + Iret = now + 50h
+# Tpub(N+1) = now - IpubC = now - 27h
+# Tact(N+1) = now
+# Tret(N+1) = now + Lksk = now + 60d
+# Trem(N+1) = now + Lksk + Iret = now + 60d + 50h
+# = now + 1440h + 50h = 1490h
+TpubN="now-60d"
+TactN="now-1413h"
+TretN="now"
+TremN="now+50h"
+TpubN1="now-27h"
+TactN1="now"
+TretN1="now+60d"
+TremN1="now+1490h"
+ksktimes="-P ${TpubN} -A ${TpubN} -P sync ${TactN} -I ${TretN} -D ${TremN} -D sync ${TactN1}"
+newtimes="-P ${TpubN1} -A ${TactN1} -P sync ${TactN1} -I ${TretN1} -D ${TremN1}"
+zsktimes="-P ${TpubN} -A ${TpubN}"
+KSK1=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $ksktimes $zone 2>keygen.out.$zone.1)
+KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $newtimes $zone 2>keygen.out.$zone.2)
+ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 $zsktimes $zone 2>keygen.out.$zone.3)
+$SETTIME -s -g $H -k $O $TpubN -r $O $TpubN -d $O $TactN "$KSK1" >settime.out.$zone.1 2>&1
+$SETTIME -s -g $O -k $R $TpubN1 -r $R $TpubN1 -d $H $TpubN1 "$KSK2" >settime.out.$zone.2 2>&1
+$SETTIME -s -g $O -k $O $TpubN -z $O $TpubN "$ZSK" >settime.out.$zone.3 2>&1
+# Set key rollover relationship.
+key_successor $KSK1 $KSK2
+# Sign zone.
+cat template.db.in "${KSK1}.key" "${KSK2}.key" "${ZSK}.key" >"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK1" >>"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile"
+cp $infile $zonefile
+$SIGNER -S -x -G "cds:sha-256" -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
+
+# Step 4:
+# The DS should be swapped now.
+setup step4.ksk-doubleksk.autosign
+# Tpub(N) = now - Lksk - Iret = now - 60d - 50h
+# = now - 1440h - 50h = now - 1490h
+# Tact(N) = now - 1490h + 27h = now - 1463h
+# Tret(N) = now - Iret = now - 50h
+# Trem(N) = now
+# Tpub(N+1) = now - Iret - IpubC = now - 50h - 27h
+# = now - 77h
+# Tact(N+1) = Tret(N)
+# Tret(N+1) = now + Lksk - Iret = now + 60d - 50h = now + 1390h
+# Trem(N+1) = now + Lksk = now + 60d
+TpubN="now-1490h"
+TactN="now-1463h"
+TretN="now-50h"
+TremN="now"
+TpubN1="now-77h"
+TactN1="${TretN}"
+TretN1="now+1390h"
+TremN1="now+60d"
+ksktimes="-P ${TpubN} -A ${TpubN} -P sync ${TactN} -I ${TretN} -D ${TremN} -D sync ${TactN1}"
+newtimes="-P ${TpubN1} -A ${TactN1} -P sync ${TactN1} -I ${TretN1} -D ${TremN1}"
+zsktimes="-P ${TpubN} -A ${TpubN}"
+KSK1=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $ksktimes $zone 2>keygen.out.$zone.1)
+KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $newtimes $zone 2>keygen.out.$zone.2)
+ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 $zsktimes $zone 2>keygen.out.$zone.3)
+$SETTIME -s -g $H -k $O $TactN -r $O $TactN -d $U $TretN -D ds $TretN "$KSK1" >settime.out.$zone.1 2>&1
+$SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $R $TactN1 -P ds $TactN1 "$KSK2" >settime.out.$zone.2 2>&1
+$SETTIME -s -g $O -k $O $TactN -z $O $TactN "$ZSK" >settime.out.$zone.3 2>&1
+# Set key rollover relationship.
+key_successor $KSK1 $KSK2
+# Sign zone.
+cat template.db.in "${KSK1}.key" "${KSK2}.key" "${ZSK}.key" >"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK1" >>"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile"
+cp $infile $zonefile
+$SIGNER -S -x -G "cds:sha-256" -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
+# Step 5:
+# The predecessor DNSKEY is removed long enough that is has become HIDDEN.
+setup step5.ksk-doubleksk.autosign
+# Subtract DNSKEY TTL + zone-propagation-delay from all the times (3h).
+# Tpub(N) = now - 1490h - 3h = now - 1493h
+# Tact(N) = now - 1463h - 3h = now - 1466h
+# Tret(N) = now - 50h - 3h = now - 53h
+# Trem(N) = now - 3h
+# Tpub(N+1) = now - 77h - 3h = now - 80h
+# Tact(N+1) = Tret(N)
+# Tret(N+1) = now + 1390h - 3h = now + 1387h
+# Trem(N+1) = now + 60d - 3h = now + 1441h
+TpubN="now-1493h"
+TactN="now-1466h"
+TretN="now-53h"
+TremN="now-3h"
+TpubN1="now-80h"
+TactN1="${TretN}"
+TretN1="now+1387h"
+TremN1="now+1441h"
+ksktimes="-P ${TpubN} -A ${TpubN} -P sync ${TactN} -I ${TretN} -D ${TremN} -D sync ${TactN1}"
+newtimes="-P ${TpubN1} -A ${TactN1} -P sync ${TactN1} -I ${TretN1} -D ${TremN1}"
+zsktimes="-P ${TpubN} -A ${TpubN}"
+KSK1=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $ksktimes $zone 2>keygen.out.$zone.1)
+KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $newtimes $zone 2>keygen.out.$zone.2)
+ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 $zsktimes $zone 2>keygen.out.$zone.3)
+$SETTIME -s -g $H -k $U $TretN -r $U $TretN -d $H $TretN "$KSK1" >settime.out.$zone.1 2>&1
+$SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $O $TactN1 "$KSK2" >settime.out.$zone.2 2>&1
+$SETTIME -s -g $O -k $O $TactN -z $O $TactN "$ZSK" >settime.out.$zone.3 2>&1
+# Set key rollover relationship.
+key_successor $KSK1 $KSK2
+# Sign zone.
+cat template.db.in "${KSK1}.key" "${KSK2}.key" "${ZSK}.key" >"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK1" >>"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile"
+cp $infile $zonefile
+$SIGNER -S -x -G "cds:sha-256" -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
+
+# Step 6:
+# The predecessor DNSKEY can be purged.
+setup step6.ksk-doubleksk.autosign
+# Subtract purge-keys interval from all the times (1h).
+TpubN="now-1494h"
+TactN="now-1467h"
+TretN="now-54h"
+TremN="now-4h"
+TpubN1="now-81h"
+TactN1="${TretN}"
+TretN1="now+1386h"
+TremN1="now+1440h"
+ksktimes="-P ${TpubN} -A ${TpubN} -P sync ${TactN} -I ${TretN} -D ${TremN} -D sync ${TactN1}"
+newtimes="-P ${TpubN1} -A ${TactN1} -P sync ${TactN1} -I ${TretN1} -D ${TremN1}"
+zsktimes="-P ${TpubN} -A ${TpubN}"
+KSK1=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $ksktimes $zone 2>keygen.out.$zone.1)
+KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $newtimes $zone 2>keygen.out.$zone.2)
+ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 $zsktimes $zone 2>keygen.out.$zone.3)
+$SETTIME -s -g $H -k $H $TretN -r $H $TretN -d $H $TretN "$KSK1" >settime.out.$zone.1 2>&1
+$SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $O $TactN1 "$KSK2" >settime.out.$zone.2 2>&1
+$SETTIME -s -g $O -k $O $TactN -z $O $TactN "$ZSK" >settime.out.$zone.3 2>&1
+# Set key rollover relationship.
+key_successor $KSK1 $KSK2
+# Sign zone.
+cat template.db.in "${KSK1}.key" "${KSK2}.key" "${ZSK}.key" >"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK1" >>"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile"
+private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile"
+cp $infile $zonefile
+$SIGNER -S -x -G "cds:sha-256" -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
zone = step["zone"]
keyprops = step["keyprops"]
nextev = step["nextev"]
+ cdss = []
+ if step.get("cdss"):
+ cdss = step["cdss"]
keyrelationships = None
if step.get("keyrelationships"):
keyrelationships = step["keyrelationships"]
key = kp.key
if kp.metadata["DSState"] == "rumoured":
- isctest.kasp.check_cdslog(server, zone, key, "CDS (SHA-256)")
- isctest.kasp.check_cdslog(server, zone, key, "CDNSKEY")
- isctest.kasp.check_cdslog_prohibit(server, zone, key, "CDS (SHA-384)")
+ 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)
+ else:
+ isctest.kasp.check_cdslog_prohibit(server, zone, key, algstr)
# The DS can be introduced. We ignore any parent registration delay,
# so set the DS publish time to now.
def test_rollover_enable_dnssec(servers):
server = servers["ns3"]
policy = "enable-dnssec"
+ cdss = ["CDNSKEY", "CDS (SHA-256)"]
config = {
"dnskey-ttl": timedelta(seconds=300),
"ds-ttl": timedelta(hours=2),
{
# Step 1.
"zone": "step1.enable-dnssec.autosign",
+ "cdss": cdss,
"keyprops": [
f"csk unlimited {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured zrrsig:rumoured ds:hidden offset:{offsets['step1']}",
],
{
# Step 2.
"zone": "step2.enable-dnssec.autosign",
+ "cdss": cdss,
# The DNSKEY is omnipresent, but the zone signatures not yet.
# Thus, the DS remains hidden.
# dnskey: rumoured -> omnipresent
{
# Step 3.
"zone": "step3.enable-dnssec.autosign",
+ "cdss": cdss,
# All signatures should be omnipresent, so the DS can be submitted.
# zrrsig: rumoured -> omnipresent
# ds: hidden -> rumoured
{
# Step 4.
"zone": "step4.enable-dnssec.autosign",
+ "cdss": cdss,
# DS has been published long enough.
# ds: rumoured -> omnipresent
"keyprops": [
for step in steps:
check_rollover_step(server, config, policy, step)
+
+
+def test_rollover_ksk_doubleksk(servers):
+ server = servers["ns3"]
+ policy = "ksk-doubleksk"
+ cdss = ["CDS (SHA-256)"]
+ config = {
+ "dnskey-ttl": timedelta(hours=2),
+ "ds-ttl": timedelta(seconds=3600),
+ "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),
+ }
+ ttl = int(config["dnskey-ttl"].total_seconds())
+ alg = os.environ["DEFAULT_ALGORITHM_NUMBER"]
+ size = os.environ["DEFAULT_BITS"]
+ ksk_lifetime = timedelta(days=60)
+ lifetime_policy = int(ksk_lifetime.total_seconds())
+
+ ipub = Ipub(config)
+ ipubc = IpubC(config)
+ iret = Iret(config, zsk=False, ksk=True)
+ keyttlprop = config["dnskey-ttl"] + config["zone-propagation-delay"]
+ offsets = {}
+ offsets["step1-p"] = -int(timedelta(days=7).total_seconds())
+ offsets["step2-p"] = -int(ksk_lifetime.total_seconds() - ipubc.total_seconds())
+ offsets["step2-s"] = 0
+ offsets["step3-p"] = -int(ksk_lifetime.total_seconds())
+ offsets["step3-s"] = -int(ipubc.total_seconds())
+ offsets["step4-p"] = offsets["step3-p"] - int(iret.total_seconds())
+ offsets["step4-s"] = offsets["step3-s"] - int(iret.total_seconds())
+ offsets["step5-p"] = offsets["step4-p"] - int(keyttlprop.total_seconds())
+ offsets["step5-s"] = offsets["step4-s"] - int(keyttlprop.total_seconds())
+ offsets["step6-p"] = offsets["step5-p"] - int(config["purge-keys"].total_seconds())
+ offsets["step6-s"] = offsets["step5-s"] - int(config["purge-keys"].total_seconds())
+
+ steps = [
+ {
+ # Step 1.
+ # Introduce the first key. This will immediately be active.
+ "zone": "step1.ksk-doubleksk.autosign",
+ "cdss": cdss,
+ "keyprops": [
+ f"zsk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{offsets['step1-p']}",
+ f"ksk {lifetime_policy} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{offsets['step1-p']}",
+ ],
+ # Next key event is when the successor KSK needs to be published.
+ # That is the KSK lifetime - prepublication time (minus time
+ # already passed).
+ "nextev": ksk_lifetime - ipub - timedelta(days=7),
+ },
+ {
+ # Step 2.
+ # Successor KSK is prepublished (and signs DNSKEY RRset).
+ # KSK1 goal: omnipresent -> hidden
+ # KSK2 goal: hidden -> omnipresent
+ # KSK2 dnskey: hidden -> rumoured
+ # KSK2 krrsig: hidden -> rumoured
+ "zone": "step2.ksk-doubleksk.autosign",
+ "cdss": cdss,
+ "keyprops": [
+ f"zsk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{offsets['step2-p']}",
+ f"ksk {lifetime_policy} {alg} {size} goal:hidden dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{offsets['step2-p']}",
+ f"ksk {lifetime_policy} {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured ds:hidden offset:{offsets['step2-s']}",
+ ],
+ "keyrelationships": [1, 2],
+ # Next key event is when the successor KSK becomes OMNIPRESENT.
+ "nextev": ipub,
+ },
+ {
+ # Step 3.
+ # The successor DNSKEY RRset has become omnipresent. The
+ # predecessor DS can be withdrawn and the successor DS can be
+ # introduced.
+ # KSK1 ds: omnipresent -> unretentive
+ # KSK2 dnskey: rumoured -> omnipresent
+ # KSK2 krrsig: rumoured -> omnipresent
+ # KSK2 ds: hidden -> rumoured
+ "zone": "step3.ksk-doubleksk.autosign",
+ "cdss": cdss,
+ "keyprops": [
+ f"zsk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{offsets['step3-p']}",
+ f"ksk {lifetime_policy} {alg} {size} goal:hidden dnskey:omnipresent krrsig:omnipresent ds:unretentive offset:{offsets['step3-p']}",
+ f"ksk {lifetime_policy} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:rumoured offset:{offsets['step3-s']}",
+ ],
+ "keyrelationships": [1, 2],
+ # Next key event is when the predecessor DS has been replaced with
+ # the successor DS and enough time has passed such that the all
+ # validators that have this DS RRset cached only know about the
+ # successor DS. This is the the retire interval.
+ "nextev": iret,
+ },
+ {
+ # Step 4.
+ # The predecessor DNSKEY may be removed, the successor DS is
+ # omnipresent.
+ # KSK1 dnskey: omnipresent -> unretentive
+ # KSK1 krrsig: omnipresent -> unretentive
+ # KSK1 ds: unretentive -> hidden
+ # KSK2 ds: rumoured -> omnipresent
+ "zone": "step4.ksk-doubleksk.autosign",
+ "cdss": cdss,
+ "keyprops": [
+ f"zsk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{offsets['step4-p']}",
+ f"ksk {lifetime_policy} {alg} {size} goal:hidden dnskey:unretentive krrsig:unretentive ds:hidden offset:{offsets['step4-p']}",
+ f"ksk {lifetime_policy} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{offsets['step4-s']}",
+ ],
+ "keyrelationships": [1, 2],
+ # Next key event is when the DNSKEY enters the HIDDEN state.
+ # This is the DNSKEY TTL plus zone propagation delay.
+ "nextev": keyttlprop,
+ },
+ {
+ # Step 5.
+ # The predecessor DNSKEY is long enough removed from the zone it
+ # has become hidden.
+ # KSK1 dnskey: unretentive -> hidden
+ # KSK1 krrsig: unretentive -> hidden
+ "zone": "step5.ksk-doubleksk.autosign",
+ "cdss": cdss,
+ "keyprops": [
+ f"zsk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{offsets['step5-p']}",
+ f"ksk {lifetime_policy} {alg} {size} goal:hidden dnskey:hidden krrsig:hidden ds:hidden offset:{offsets['step5-p']}",
+ f"ksk {lifetime_policy} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{offsets['step5-s']}",
+ ],
+ "keyrelationships": [1, 2],
+ # Next key event is when the new successor needs to be published.
+ # This is the KSK lifetime minus Ipub minus Iret minus time elapsed.
+ "nextev": ksk_lifetime - ipub - iret - keyttlprop,
+ },
+ {
+ # Step 6.
+ # Predecessor KSK is now purged.
+ "zone": "step6.ksk-doubleksk.autosign",
+ "cdss": cdss,
+ "keyprops": [
+ f"zsk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{offsets['step6-p']}",
+ f"ksk {lifetime_policy} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{offsets['step6-s']}",
+ ],
+ "nextev": None,
+ },
+ ]
+
+ for step in steps:
+ check_rollover_step(server, config, policy, step)