diff --git a/bin/tests/system/isctest/kasp.py b/bin/tests/system/isctest/kasp.py index 537ebce0ba..1aec27c3f5 100644 --- a/bin/tests/system/isctest/kasp.py +++ b/bin/tests/system/isctest/kasp.py @@ -997,6 +997,15 @@ def check_cdslog_prohibit(server, zone, key, substr): ) +def check_cdsdelete(rrset, expected): + numrrs = 0 + for rr in rrset: + for rdata in rr: + assert expected in f"{rdata}" + numrrs += 1 + assert numrrs == 1 + + def _query_rrset(server, fqdn, qtype, tsig=None): response = _query(server, fqdn, qtype, tsig=tsig) assert response.rcode() == dns.rcode.NOERROR @@ -1019,7 +1028,15 @@ def _query_rrset(server, fqdn, qtype, tsig=None): def check_apex( - server, zone, ksks, zsks, cdss=None, offline_ksk=False, zsk_missing=False, tsig=None + server, + zone, + ksks, + zsks, + cdss=None, + cds_delete=False, + 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. @@ -1052,10 +1069,13 @@ def check_apex( # test cdnskey query cdnskeys, rrsigs = _query_rrset(server, fqdn, dns.rdatatype.CDNSKEY, tsig=tsig) - if "CDNSKEY" in cdss: - check_dnskeys(cdnskeys, ksks, zsks, cdnskey=True) + if cds_delete: + check_cdsdelete(cdnskeys, "0 3 0 AA==") else: - assert len(cdnskeys) == 0 + if "CDNSKEY" in cdss: + check_dnskeys(cdnskeys, ksks, zsks, cdnskey=True) + else: + assert len(cdnskeys) == 0 if len(cdnskeys) > 0: assert len(rrsigs) > 0 @@ -1065,29 +1085,33 @@ def check_apex( # test cds query cds, rrsigs = _query_rrset(server, fqdn, dns.rdatatype.CDS, tsig=tsig) - 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 + if cds_delete: + check_cdsdelete(cds, "0 0 0 00") + else: + 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) - 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) + numcds = 0 - if len(cds) > 0: - assert len(rrsigs) > 0 - check_signatures( - rrsigs, dns.rdatatype.CDS, fqdn, ksks, zsks, offline_ksk=offline_ksk - ) + 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) - assert numcds == len(cdsrrs) + 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( diff --git a/bin/tests/system/kasp/ns6/named.conf.in b/bin/tests/system/kasp/ns6/named.conf.in index b8d36dc6e4..2bee0a04b9 100644 --- a/bin/tests/system/kasp/ns6/named.conf.in +++ b/bin/tests/system/kasp/ns6/named.conf.in @@ -44,82 +44,8 @@ zone "." { file "../../_common/root.hint.blackhole"; }; -/* This zone switch from dynamic to inline-signing. */ -zone "dynamic2inline.kasp" { - type primary; - file "dynamic2inline.kasp.db"; - allow-update { any; }; - dnssec-policy "default"; -}; - -/* These zones are going insecure. */ -zone "step1.going-insecure.kasp" { - type primary; - file "step1.going-insecure.kasp.db"; - dnssec-policy "unsigning"; -}; - -zone "step1.going-insecure-dynamic.kasp" { - type primary; - file "step1.going-insecure-dynamic.kasp.db"; - dnssec-policy "unsigning"; - inline-signing no; - allow-update { any; }; -}; - -zone "step1.going-straight-to-none.kasp" { - type primary; - file "step1.going-straight-to-none.kasp.db"; - dnssec-policy "default"; -}; - -zone "step1.going-straight-to-none-dynamic.kasp" { - type primary; - file "step1.going-straight-to-none-dynamic.kasp.db.signed"; - inline-signing no; - dnssec-policy "default"; - allow-update { any; }; -}; - -/* These are alorithm rollover test zones. */ -zone "step1.algorithm-roll.kasp" { - type primary; - file "step1.algorithm-roll.kasp.db"; - dnssec-policy "rsasha256"; -}; - -zone "step1.csk-algorithm-roll.kasp" { - type primary; - file "step1.csk-algorithm-roll.kasp.db"; - dnssec-policy "csk-algoroll"; -}; - zone example { type primary; file "example.db"; dnssec-policy modified; }; - -zone longer-lifetime { - type primary; - file "longer-lifetime.db"; - dnssec-policy short-lifetime; -}; - -zone shorter-lifetime { - type primary; - file "shorter-lifetime.db"; - dnssec-policy long-lifetime; -}; - -zone limit-lifetime { - type primary; - file "limit-lifetime.db"; - dnssec-policy unlimited-lifetime; -}; - -zone unlimit-lifetime { - type primary; - file "unlimit-lifetime.db"; - dnssec-policy short-lifetime; -}; diff --git a/bin/tests/system/kasp/ns6/named2.conf.in b/bin/tests/system/kasp/ns6/named2.conf.in index 0c9d6b0a89..85af830a3c 100644 --- a/bin/tests/system/kasp/ns6/named2.conf.in +++ b/bin/tests/system/kasp/ns6/named2.conf.in @@ -43,161 +43,8 @@ zone "." { file "../../_common/root.hint.blackhole"; }; -/* This zone switch from dynamic to inline-signing. */ -zone "dynamic2inline.kasp" { - type primary; - file "dynamic2inline.kasp.db"; - allow-update { any; }; - dnssec-policy "default"; -}; - -/* Zones for testing going insecure. */ -zone "step1.going-insecure.kasp" { - type primary; - file "step1.going-insecure.kasp.db"; - dnssec-policy "insecure"; -}; - -zone "step2.going-insecure.kasp" { - type primary; - file "step2.going-insecure.kasp.db"; - dnssec-policy "insecure"; -}; - -zone "step1.going-insecure-dynamic.kasp" { - type primary; - file "step1.going-insecure-dynamic.kasp.db"; - inline-signing no; - dnssec-policy "insecure"; - allow-update { any; }; -}; - -zone "step2.going-insecure-dynamic.kasp" { - type primary; - file "step2.going-insecure-dynamic.kasp.db"; - inline-signing no; - dnssec-policy "insecure"; - allow-update { any; }; -}; - -zone "step1.going-straight-to-none.kasp" { - type primary; - file "step1.going-straight-to-none.kasp.db"; - dnssec-policy "none"; -}; - -zone "step1.going-straight-to-none-dynamic.kasp" { - type primary; - file "step1.going-straight-to-none-dynamic.kasp.db.signed"; - inline-signing no; - dnssec-policy "none"; - allow-update { any; }; -}; - -/* - * Zones for testing KSK/ZSK algorithm roll. - */ -zone "step1.algorithm-roll.kasp" { - type primary; - file "step1.algorithm-roll.kasp.db"; - dnssec-policy "ecdsa256"; -}; - -zone "step2.algorithm-roll.kasp" { - type primary; - file "step2.algorithm-roll.kasp.db"; - dnssec-policy "ecdsa256"; -}; - -zone "step3.algorithm-roll.kasp" { - type primary; - file "step3.algorithm-roll.kasp.db"; - dnssec-policy "ecdsa256"; -}; - -zone "step4.algorithm-roll.kasp" { - type primary; - file "step4.algorithm-roll.kasp.db"; - dnssec-policy "ecdsa256"; -}; - -zone "step5.algorithm-roll.kasp" { - type primary; - file "step5.algorithm-roll.kasp.db"; - dnssec-policy "ecdsa256"; -}; - -zone "step6.algorithm-roll.kasp" { - type primary; - file "step6.algorithm-roll.kasp.db"; - dnssec-policy "ecdsa256"; -}; - -/* - * Zones for testing CSK algorithm roll. - */ -zone "step1.csk-algorithm-roll.kasp" { - type primary; - file "step1.csk-algorithm-roll.kasp.db"; - dnssec-policy "csk-algoroll"; -}; - -zone "step2.csk-algorithm-roll.kasp" { - type primary; - file "step2.csk-algorithm-roll.kasp.db"; - dnssec-policy "csk-algoroll"; -}; - -zone "step3.csk-algorithm-roll.kasp" { - type primary; - file "step3.csk-algorithm-roll.kasp.db"; - dnssec-policy "csk-algoroll"; -}; - -zone "step4.csk-algorithm-roll.kasp" { - type primary; - file "step4.csk-algorithm-roll.kasp.db"; - dnssec-policy "csk-algoroll"; -}; - -zone "step5.csk-algorithm-roll.kasp" { - type primary; - file "step5.csk-algorithm-roll.kasp.db"; - dnssec-policy "csk-algoroll"; -}; - -zone "step6.csk-algorithm-roll.kasp" { - type primary; - file "step6.csk-algorithm-roll.kasp.db"; - dnssec-policy "csk-algoroll"; -}; - zone example { type primary; file "example.db"; dnssec-policy modified; }; - -zone longer-lifetime { - type primary; - file "longer-lifetime.db"; - dnssec-policy long-lifetime; -}; - -zone shorter-lifetime { - type primary; - file "shorter-lifetime.db"; - dnssec-policy short-lifetime; -}; - -zone limit-lifetime { - type primary; - file "limit-lifetime.db"; - dnssec-policy short-lifetime; -}; - -zone unlimit-lifetime { - type primary; - file "unlimit-lifetime.db"; - dnssec-policy unlimited-lifetime; -}; diff --git a/bin/tests/system/kasp/ns6/policies/kasp-fips.conf.in b/bin/tests/system/kasp/ns6/policies/kasp-fips.conf.in index 51c4d88488..b217aa68cc 100644 --- a/bin/tests/system/kasp/ns6/policies/kasp-fips.conf.in +++ b/bin/tests/system/kasp/ns6/policies/kasp-fips.conf.in @@ -11,15 +11,6 @@ * information regarding copyright ownership. */ -dnssec-policy "unsigning" { - dnskey-ttl 7200; - - keys { - ksk key-directory lifetime unlimited algorithm @DEFAULT_ALGORITHM@; - zsk key-directory lifetime P60D algorithm @DEFAULT_ALGORITHM@; - }; -}; - dnssec-policy "nsec3" { nsec3param iterations 0 optout no salt-length 0; }; @@ -46,41 +37,3 @@ dnssec-policy "long-lifetime" { csk lifetime P1Y algorithm @DEFAULT_ALGORITHM@; }; }; - -dnssec-policy "rsasha256" { - signatures-refresh P5D; - signatures-validity 30d; - signatures-validity-dnskey 30d; - - keys { - ksk lifetime unlimited algorithm rsasha256; - zsk lifetime unlimited algorithm rsasha256; - }; - - dnskey-ttl 1h; - publish-safety PT1H; - retire-safety 2h; - zone-propagation-delay 3600; - max-zone-ttl 6h; - parent-propagation-delay pt1h; - parent-ds-ttl 7200; -}; - -dnssec-policy "ecdsa256" { - signatures-refresh P5D; - signatures-validity 30d; - signatures-validity-dnskey 30d; - - keys { - ksk lifetime unlimited algorithm ecdsa256; - zsk lifetime unlimited algorithm ecdsa256; - }; - - dnskey-ttl 1h; - publish-safety PT1H; - retire-safety 2h; - zone-propagation-delay 3600; - max-zone-ttl 6h; - parent-propagation-delay pt1h; - parent-ds-ttl 7200; -}; diff --git a/bin/tests/system/kasp/ns6/setup.sh b/bin/tests/system/kasp/ns6/setup.sh index fcdabad355..e094e7efdd 100644 --- a/bin/tests/system/kasp/ns6/setup.sh +++ b/bin/tests/system/kasp/ns6/setup.sh @@ -16,410 +16,8 @@ echo_i "ns6/setup.sh" -setup() { - zone="$1" - echo_i "setting up zone: $zone" - zonefile="${zone}.db" - infile="${zone}.db.infile" -} - -# Make lines shorter by storing key states in environment variables. -H="HIDDEN" -R="RUMOURED" -O="OMNIPRESENT" -U="UNRETENTIVE" - -for zn in shorter-lifetime longer-lifetime limit-lifetime unlimit-lifetime; do - setup $zn - cp template.db.in $zonefile -done - -# The child zones (step1, step2) beneath these zones represent the various -# steps of unsigning a zone. -for zn in going-insecure.kasp going-insecure-dynamic.kasp; do - # Step 1: - # Set up a zone with dnssec-policy that is going insecure. - setup step1.$zn - echo "$zone" >>zones - T="now-10d" - ksktimes="-P $T -A $T -P sync $T" - zsktimes="-P $T -A $T" - 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) - 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: - # Set up a zone with dnssec-policy that is going insecure. Don't add - # this zone to the zones file, because this zone is no longer expected - # to be fully signed. - setup step2.$zn - # The DS was withdrawn from the parent zone 26 hours ago. - Trem="now-26h" - ksktimes="-P $T -A $T -P sync $T" - zsktimes="-P $T -A $T" - 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 $H -k $O $T -r $O $T -d $U $Trem -D ds $Trem "$KSK" >settime.out.$zone.1 2>&1 - $SETTIME -s -g $H -k $O $T -z $O $T "$ZSK" >settime.out.$zone.2 2>&1 - # Fake lifetime of old algorithm keys. - echo "Lifetime: 0" >>"${KSK}.state" - echo "Lifetime: 5184000" >>"${ZSK}.state" - 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 -done - -# This zone is going straight to "none" policy. This is undefined behavior. -setup step1.going-straight-to-none.kasp -echo "$zone" >>zones -TactN="now" -csktimes="-P ${TactN} -A ${TactN} -P sync ${TactN}" -CSK=$($KEYGEN -k default $csktimes $zone 2>keygen.out.$zone.1) -$SETTIME -s -g $O -k $O $TactN -z $O $TactN -r $O $TactN -d $O $TactN "$CSK" >settime.out.$zone.1 2>&1 -cat template.db.in "${CSK}.key" >"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK" >>"$infile" -cp $infile $zonefile -$SIGNER -S -z -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - -# This zone is going straight to "none" policy. This is undefined behavior. -setup step1.going-straight-to-none-dynamic.kasp -echo "$zone" >>zones -TactN="now" -csktimes="-P ${TactN} -A ${TactN} -P sync ${TactN}" -CSK=$($KEYGEN -k default $csktimes $zone 2>keygen.out.$zone.1) -$SETTIME -s -g $O -k $O $TactN -z $O $TactN -r $O $TactN -d $O $TactN "$CSK" >settime.out.$zone.1 2>&1 -cat template.db.in "${CSK}.key" >"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK" >>"$infile" -cp $infile $zonefile -$SIGNER -S -z -x -s now-1h -e now+2w -o $zone -O full -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - -# -# The zones at algorithm-roll.kasp represent the various steps of a ZSK/KSK -# algorithm rollover. -# - -# Step 1: -# Introduce the first key. This will immediately be active. -setup step1.algorithm-roll.kasp -echo "$zone" >>zones -TactN="now" -ksktimes="-P ${TactN} -A ${TactN} -P sync ${TactN}" -zsktimes="-P ${TactN} -A ${TactN}" -KSK=$($KEYGEN -a RSASHA256 -L 3600 -f KSK $ksktimes $zone 2>keygen.out.$zone.1) -ZSK=$($KEYGEN -a RSASHA256 -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 8 "$KSK" >>"$infile" -private_type_record $zone 8 "$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: -# After the publication interval has passed the DNSKEY is OMNIPRESENT. -setup step2.algorithm-roll.kasp -# The time passed since the new algorithm keys have been introduced is 3 hours. -TactN="now-3h" -TpubN1="now-3h" -# Tsbm(N+1) = TpubN1 + Ipub = now + TTLsig + Dprp = -# now - 3h + 6h + 1h = now + 4h -TsbmN1="now+4h" -ksk1times="-P ${TactN} -A ${TactN} -P sync ${TactN} -I now" -zsk1times="-P ${TactN} -A ${TactN} -I now" -ksk2times="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}" -zsk2times="-P ${TpubN1} -A ${TpubN1}" -KSK1=$($KEYGEN -a RSASHA256 -L 3600 -f KSK $ksk1times $zone 2>keygen.out.$zone.1) -ZSK1=$($KEYGEN -a RSASHA256 -L 3600 $zsk1times $zone 2>keygen.out.$zone.2) -KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $ksk2times $zone 2>keygen.out.$zone.3) -ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $zsk2times $zone 2>keygen.out.$zone.4) -$SETTIME -s -g $H -k $O $TactN -r $O $TactN -d $O $TactN "$KSK1" >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 -r $R $TpubN1 -d $H $TpubN1 "$KSK2" >settime.out.$zone.3 2>&1 -$SETTIME -s -g $O -k $R $TpubN1 -z $R $TpubN1 "$ZSK2" >settime.out.$zone.4 2>&1 -# Fake lifetime of old algorithm keys. -echo "Lifetime: 0" >>"${KSK1}.state" -echo "Lifetime: 0" >>"${ZSK1}.state" -cat template.db.in "${KSK1}.key" "${ZSK1}.key" "${KSK2}.key" "${ZSK2}.key" >"$infile" -private_type_record $zone 8 "$KSK1" >>"$infile" -private_type_record $zone 8 "$ZSK1" >>"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$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 3: -# The zone signatures are also OMNIPRESENT. -setup step3.algorithm-roll.kasp -# The time passed since the new algorithm keys have been introduced is 7 hours. -TactN="now-7h" -TretN="now-3h" -TpubN1="now-7h" -TsbmN1="now" -ksk1times="-P ${TactN} -A ${TactN} -P sync ${TactN} -I ${TretN}" -zsk1times="-P ${TactN} -A ${TactN} -I ${TretN}" -ksk2times="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}" -zsk2times="-P ${TpubN1} -A ${TpubN1}" -KSK1=$($KEYGEN -a RSASHA256 -L 3600 -f KSK $ksk1times $zone 2>keygen.out.$zone.1) -ZSK1=$($KEYGEN -a RSASHA256 -L 3600 $zsk1times $zone 2>keygen.out.$zone.2) -KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $ksk2times $zone 2>keygen.out.$zone.3) -ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $zsk2times $zone 2>keygen.out.$zone.4) -$SETTIME -s -g $H -k $O $TactN -r $O $TactN -d $O $TactN "$KSK1" >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 $O $TpubN1 -r $O $TpubN1 -d $H $TpubN1 "$KSK2" >settime.out.$zone.3 2>&1 -$SETTIME -s -g $O -k $O $TpubN1 -z $R $TpubN1 "$ZSK2" >settime.out.$zone.4 2>&1 -# Fake lifetime of old algorithm keys. -echo "Lifetime: 0" >>"${KSK1}.state" -echo "Lifetime: 0" >>"${ZSK1}.state" -cat template.db.in "${KSK1}.key" "${ZSK1}.key" "${KSK2}.key" "${ZSK2}.key" >"$infile" -private_type_record $zone 8 "$KSK1" >>"$infile" -private_type_record $zone 8 "$ZSK1" >>"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$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: -# The DS is swapped and can become OMNIPRESENT. -setup step4.algorithm-roll.kasp -# The time passed since the DS has been swapped is 29 hours. -TactN="now-36h" -TretN="now-33h" -TpubN1="now-36h" -TsbmN1="now-29h" -TactN1="now-27h" -ksk1times="-P ${TactN} -A ${TactN} -P sync ${TactN} -I ${TretN}" -zsk1times="-P ${TactN} -A ${TactN} -I ${TretN}" -ksk2times="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}" -zsk2times="-P ${TpubN1} -A ${TpubN1}" -KSK1=$($KEYGEN -a RSASHA256 -L 3600 -f KSK $ksk1times $zone 2>keygen.out.$zone.1) -ZSK1=$($KEYGEN -a RSASHA256 -L 3600 $zsk1times $zone 2>keygen.out.$zone.2) -KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $ksk2times $zone 2>keygen.out.$zone.3) -ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $zsk2times $zone 2>keygen.out.$zone.4) -$SETTIME -s -g $H -k $O $TactN -r $O $TactN -d $U $TactN1 -D ds $TactN1 "$KSK1" >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 $O $TpubN1 -r $O $TpubN1 -d $R $TactN1 -P ds $TactN1 "$KSK2" >settime.out.$zone.3 2>&1 -$SETTIME -s -g $O -k $O $TpubN1 -z $R $TpubN1 "$ZSK2" >settime.out.$zone.4 2>&1 -# Fake lifetime of old algorithm keys. -echo "Lifetime: 0" >>"${KSK1}.state" -echo "Lifetime: 0" >>"${ZSK1}.state" -cat template.db.in "${KSK1}.key" "${ZSK1}.key" "${KSK2}.key" "${ZSK2}.key" >"$infile" -private_type_record $zone 8 "$KSK1" >>"$infile" -private_type_record $zone 8 "$ZSK1" >>"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$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 5: -# The DNSKEY is removed long enough to be HIDDEN. -setup step5.algorithm-roll.kasp -# The time passed since the DNSKEY has been removed is 2 hours. -TactN="now-38h" -TretN="now-35h" -TremN="now-2h" -TpubN1="now-38h" -TsbmN1="now-31h" -TactN1="now-29h" -ksk1times="-P ${TactN} -A ${TactN} -P sync ${TactN} -I ${TretN}" -zsk1times="-P ${TactN} -A ${TactN} -I ${TretN}" -ksk2times="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}" -zsk2times="-P ${TpubN1} -A ${TpubN1}" -KSK1=$($KEYGEN -a RSASHA256 -L 3600 -f KSK $ksk1times $zone 2>keygen.out.$zone.1) -ZSK1=$($KEYGEN -a RSASHA256 -L 3600 $zsk1times $zone 2>keygen.out.$zone.2) -KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $ksk2times $zone 2>keygen.out.$zone.3) -ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $zsk2times $zone 2>keygen.out.$zone.4) -$SETTIME -s -g $H -k $U $TremN -r $U $TremN -d $H $TactN1 "$KSK1" >settime.out.$zone.1 2>&1 -$SETTIME -s -g $H -k $U $TremN -z $U $TremN "$ZSK1" >settime.out.$zone.2 2>&1 -$SETTIME -s -g $O -k $O $TpubN1 -r $O $TpubN1 -d $O $TactN1 "$KSK2" >settime.out.$zone.3 2>&1 -$SETTIME -s -g $O -k $O $TpubN1 -z $R $TpubN1 "$ZSK2" >settime.out.$zone.4 2>&1 -# Fake lifetime of old algorithm keys. -echo "Lifetime: 0" >>"${KSK1}.state" -echo "Lifetime: 0" >>"${ZSK1}.state" -cat template.db.in "${KSK1}.key" "${ZSK1}.key" "${KSK2}.key" "${ZSK2}.key" >"$infile" -private_type_record $zone 8 "$KSK1" >>"$infile" -private_type_record $zone 8 "$ZSK1" >>"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$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 RRSIGs have been removed long enough to be HIDDEN. -setup step6.algorithm-roll.kasp -# Additional time passed: 7h. -TactN="now-45h" -TretN="now-42h" -TremN="now-7h" -TpubN1="now-45h" -TsbmN1="now-38h" -TactN1="now-36h" -TdeaN="now-7h" -ksk1times="-P ${TactN} -A ${TactN} -P sync ${TactN} -I ${TretN}" -zsk1times="-P ${TactN} -A ${TactN} -I ${TretN}" -ksk2times="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}" -zsk2times="-P ${TpubN1} -A ${TpubN1}" -KSK1=$($KEYGEN -a RSASHA256 -L 3600 -f KSK $ksk1times $zone 2>keygen.out.$zone.1) -ZSK1=$($KEYGEN -a RSASHA256 -L 3600 $zsk1times $zone 2>keygen.out.$zone.2) -KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $ksk2times $zone 2>keygen.out.$zone.3) -ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $zsk2times $zone 2>keygen.out.$zone.4) -$SETTIME -s -g $H -k $H $TremN -r $U $TdeaN -d $H $TactN1 "$KSK1" >settime.out.$zone.1 2>&1 -$SETTIME -s -g $H -k $H $TremN -z $U $TdeaN "$ZSK1" >settime.out.$zone.2 2>&1 -$SETTIME -s -g $O -k $O $TpubN1 -r $O $TpubN1 -d $O $TactN1 "$KSK2" >settime.out.$zone.3 2>&1 -$SETTIME -s -g $O -k $O $TpubN1 -z $R $TpubN1 "$ZSK2" >settime.out.$zone.4 2>&1 -# Fake lifetime of old algorithm keys. -echo "Lifetime: 0" >>"${KSK1}.state" -echo "Lifetime: 0" >>"${ZSK1}.state" -cat template.db.in "${KSK1}.key" "${ZSK1}.key" "${KSK2}.key" "${ZSK2}.key" >"$infile" -private_type_record $zone 8 "$KSK1" >>"$infile" -private_type_record $zone 8 "$ZSK1" >>"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$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 csk-algorithm-roll.kasp represent the various steps of a CSK -# algorithm rollover. -# - -# Step 1: -# Introduce the first key. This will immediately be active. -setup step1.csk-algorithm-roll.kasp -echo "$zone" >>zones -TactN="now" -csktimes="-P ${TactN} -P sync ${TactN} -A ${TactN}" -CSK=$($KEYGEN -k csk-algoroll -l policies/csk1.conf $csktimes $zone 2>keygen.out.$zone.1) -$SETTIME -s -g $O -k $O $TactN -r $O $TactN -z $O $TactN -d $O $TactN "$CSK" >settime.out.$zone.1 2>&1 -cat template.db.in "${CSK}.key" >"$infile" -private_type_record $zone 5 "$CSK" >>"$infile" -cp $infile $zonefile -$SIGNER -S -x -z -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - -# Step 2: -# After the publication interval has passed the DNSKEY is OMNIPRESENT. -setup step2.csk-algorithm-roll.kasp -# The time passed since the new algorithm keys have been introduced is 3 hours. -TactN="now-3h" -TpubN1="now-3h" -csktimes="-P ${TactN} -A ${TactN} -P sync ${TactN} -I now" -newtimes="-P ${TpubN1} -A ${TpubN1}" -CSK1=$($KEYGEN -k csk-algoroll -l policies/csk1.conf $csktimes $zone 2>keygen.out.$zone.1) -CSK2=$($KEYGEN -k csk-algoroll -l policies/csk2.conf $newtimes $zone 2>keygen.out.$zone.2) -$SETTIME -s -g $H -k $O $TactN -r $O $TactN -z $O $TactN -d $O $TactN "$CSK1" >settime.out.$zone.1 2>&1 -$SETTIME -s -g $O -k $R $TpubN1 -r $R $TpubN1 -z $R $TpubN1 -d $H $TpubN1 "$CSK2" >settime.out.$zone.2 2>&1 -# Fake lifetime of old algorithm keys. -echo "Lifetime: 0" >>"${CSK1}.state" -cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" -private_type_record $zone 5 "$CSK1" >>"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" -cp $infile $zonefile -$SIGNER -S -x -z -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - -# Step 3: -# The zone signatures are also OMNIPRESENT. -setup step3.csk-algorithm-roll.kasp -# The time passed since the new algorithm keys have been introduced is 7 hours. -TactN="now-7h" -TretN="now-3h" -TpubN1="now-7h" -TactN1="now-3h" -csktimes="-P ${TactN} -A ${TactN} -P sync ${TactN} -I ${TretN}" -newtimes="-P ${TpubN1} -A ${TpubN1}" -CSK1=$($KEYGEN -k csk-algoroll -l policies/csk1.conf $csktimes $zone 2>keygen.out.$zone.1) -CSK2=$($KEYGEN -k csk-algoroll -l policies/csk2.conf $newtimes $zone 2>keygen.out.$zone.2) -$SETTIME -s -g $H -k $O $TactN -r $O $TactN -z $O $TactN -d $O $TactN "$CSK1" >settime.out.$zone.1 2>&1 -$SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -z $R $TpubN1 -d $H $TpubN1 "$CSK2" >settime.out.$zone.2 2>&1 -# Fake lifetime of old algorithm keys. -echo "Lifetime: 0" >>"${CSK1}.state" -cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" -private_type_record $zone 5 "$CSK1" >>"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" -cp $infile $zonefile -$SIGNER -S -x -z -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - -# Step 4: -# The DS is swapped and can become OMNIPRESENT. -setup step4.csk-algorithm-roll.kasp -# The time passed since the DS has been swapped is 29 hours. -TactN="now-36h" -TretN="now-33h" -TpubN1="now-36h" -TactN1="now-33h" -TsubN1="now-29h" -csktimes="-P ${TactN} -A ${TactN} -P sync ${TactN} -I ${TretN}" -newtimes="-P ${TpubN1} -A ${TpubN1}" -CSK1=$($KEYGEN -k csk-algoroll -l policies/csk1.conf $csktimes $zone 2>keygen.out.$zone.1) -CSK2=$($KEYGEN -k csk-algoroll -l policies/csk2.conf $newtimes $zone 2>keygen.out.$zone.2) -$SETTIME -s -g $H -k $O $TactN -r $O $TactN -z $O $TactN -d $U $TactN1 -D ds $TactN1 "$CSK1" >settime.out.$zone.1 2>&1 -$SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -z $O $TsubN1 -d $R $TsubN1 -P ds $TsubN1 "$CSK2" >settime.out.$zone.2 2>&1 -# Fake lifetime of old algorithm keys. -echo "Lifetime: 0" >>"${CSK1}.state" -cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" -private_type_record $zone 5 "$CSK1" >>"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" -cp $infile $zonefile -$SIGNER -S -x -z -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - -# Step 5: -# The DNSKEY is removed long enough to be HIDDEN. -setup step5.csk-algorithm-roll.kasp -# The time passed since the DNSKEY has been removed is 2 hours. -TactN="now-38h" -TretN="now-35h" -TremN="now-2h" -TpubN1="now-38h" -TactN1="now-35h" -TsubN1="now-31h" -csktimes="-P ${TactN} -A ${TactN} -P sync ${TactN} -I ${TretN}" -newtimes="-P ${TpubN1} -A ${TpubN1}" -CSK1=$($KEYGEN -k csk-algoroll -l policies/csk1.conf $csktimes $zone 2>keygen.out.$zone.1) -CSK2=$($KEYGEN -k csk-algoroll -l policies/csk2.conf $newtimes $zone 2>keygen.out.$zone.2) -$SETTIME -s -g $H -k $U $TremN -r $U $TremN -z $U $TremN -d $H $TremN "$CSK1" >settime.out.$zone.1 2>&1 -$SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -z $O $TsubN1 -d $O $TremN "$CSK2" >settime.out.$zone.2 2>&1 -# Fake lifetime of old algorithm keys. -echo "Lifetime: 0" >>"${CSK1}.state" -cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" -private_type_record $zone 5 "$CSK1" >>"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" -cp $infile $zonefile -$SIGNER -S -x -z -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - -# Step 6: -# The RRSIGs have been removed long enough to be HIDDEN. -setup step6.csk-algorithm-roll.kasp -# Additional time passed: 7h. -TactN="now-45h" -TretN="now-42h" -TdeaN="now-9h" -TremN="now-7h" -TpubN1="now-45h" -TactN1="now-42h" -TsubN1="now-38h" -csktimes="-P ${TactN} -A ${TactN} -P sync ${TactN} -I ${TretN}" -newtimes="-P ${TpubN1} -A ${TpubN1}" -CSK1=$($KEYGEN -k csk-algoroll -l policies/csk1.conf $csktimes $zone 2>keygen.out.$zone.1) -CSK2=$($KEYGEN -k csk-algoroll -l policies/csk2.conf $newtimes $zone 2>keygen.out.$zone.2) -$SETTIME -s -g $H -k $H $TremN -r $U $TdeaN -z $U $TdeaN -d $H $TactN1 "$CSK1" >settime.out.$zone.1 2>&1 -$SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -z $O $TsubN1 -d $O $TactN1 "$CSK2" >settime.out.$zone.2 2>&1 -# Fake lifetime of old algorithm keys. -echo "Lifetime: 0" >>"${CSK1}.state" -cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" -private_type_record $zone 5 "$CSK1" >>"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" -cp $infile $zonefile -$SIGNER -S -x -z -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - # # Reload testing # echo "example" >>zones cp example.db.in example.db - -setup "dynamic2inline.kasp" -cp template.db.in $zonefile diff --git a/bin/tests/system/kasp/tests.sh b/bin/tests/system/kasp/tests.sh deleted file mode 100644 index 8a64d042bb..0000000000 --- a/bin/tests/system/kasp/tests.sh +++ /dev/null @@ -1,1624 +0,0 @@ -#!/bin/sh - -# Copyright (C) Internet Systems Consortium, Inc. ("ISC") -# -# SPDX-License-Identifier: MPL-2.0 -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, you can obtain one at https://mozilla.org/MPL/2.0/. -# -# See the COPYRIGHT file distributed with this work for additional -# information regarding copyright ownership. - -set -e - -# shellcheck source=conf.sh -. ../conf.sh -# shellcheck source=kasp.sh -. ../kasp.sh - -start_time="$(TZ=UTC date +%s)" -status=0 -n=0 - -############################################################################### -# Utilities # -############################################################################### - -# Call dig with default options. -dig_with_opts() { - - if [ -n "$TSIG" ]; then - "$DIG" +tcp +noadd +nosea +nostat +nocmd +dnssec -p "$PORT" -y "$TSIG" "$@" - else - "$DIG" +tcp +noadd +nosea +nostat +nocmd +dnssec -p "$PORT" "$@" - fi -} - -# RNDC. -rndccmd() { - "$RNDC" -c ../_common/rndc.conf -p "$CONTROLPORT" -s "$@" -} - -# Log error and increment failure rate. -log_error() { - echo_i "error: $1" - ret=$((ret + 1)) -} - -# Default next key event threshold. May be extended by wait periods. -next_key_event_threshold=100 - -############################################################################### -# Tests # -############################################################################### - -# -# named -# - -# The NSEC record at the apex of the zone and its RRSIG records are -# added as part of the last step in signing a zone. We wait for the -# NSEC records to appear before proceeding with a counter to prevent -# infinite loops if there is an error. -n=$((n + 1)) -echo_i "waiting for kasp signing changes to take effect ($n)" -ret=0 - -_wait_for_done_apexnsec() { - while read -r zone; do - dig_with_opts "$zone" @10.53.0.3 nsec >"dig.out.ns3.test$n.$zone" || return 1 - grep "NS SOA" "dig.out.ns3.test$n.$zone" >/dev/null || return 1 - grep "$zone\..*IN.*RRSIG" "dig.out.ns3.test$n.$zone" >/dev/null || return 1 - done "dig.out.ns6.test$n.$zone" || return 1 - grep "NS SOA" "dig.out.ns6.test$n.$zone" >/dev/null || return 1 - grep "$zone\..*IN.*RRSIG" "dig.out.ns6.test$n.$zone" >/dev/null || return 1 - done published.test${n}.key1 - published=$(awk '{print $3}' published.test${n}.key2 - published=$(awk '{print $3}' published.test${n}.key3 - published=$(awk '{print $3}' "keyevent.out.$ZONE.test$n" || return 1 - - # Get the latest next key event. - if [ "${DYNAMIC}" = "yes" ]; then - _time=$(awk '{print $9}' <"keyevent.out.$ZONE.test$n" | tail -1) - else - # inline-signing zone adds "(signed)" - _time=$(awk '{print $10}' <"keyevent.out.$ZONE.test$n" | tail -1) - fi - - # The next key event time must within threshold of the - # expected time. - _expectmin=$((_expect - next_key_event_threshold)) - _expectmax=$((_expect + next_key_event_threshold)) - - test $_expectmin -le "$_time" || return 1 - test $_expectmax -ge "$_time" || return 1 - - return 0 -} - -check_next_key_event() { - n=$((n + 1)) - echo_i "check next key event for zone ${ZONE} ($n)" - ret=0 - - retry_quiet 3 _check_next_key_event $1 || log_error "bad next key event time for zone ${ZONE} (expect ${_expect})" - test "$ret" -eq 0 || echo_i "failed" - status=$((status + ret)) - -} - -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}" -} - -rollover_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}" - [ "$Lksk" = 0 ] || set_retired_removed "KEY1" "${Lksk}" "${IretKSK}" - - _created=$(key_get KEY2 CREATED) - set_addkeytime "KEY2" "PUBLISHED" "${_created}" "${_addtime}" - set_addkeytime "KEY2" "ACTIVE" "${_created}" "${_addtime}" - [ "$Lzsk" = 0 ] || set_retired_removed "KEY2" "${Lzsk}" "${IretZSK}" -} - -csk_rollover_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}" - [ "$Lcsk" = 0 ] || set_retired_removed "KEY1" "${Lcsk}" "${IretCSK}" -} - -# Test dynamic zones that switch to inline-signing. -set_zone "dynamic2inline.kasp" -set_policy "default" "1" "3600" -set_server "ns6" "10.53.0.6" -# Key properties. -key_clear "KEY1" -set_keyrole "KEY1" "csk" -set_keylifetime "KEY1" "0" -set_keyalgorithm "KEY1" "13" "ECDSAP256SHA256" "256" -set_keysigning "KEY1" "yes" -set_zonesigning "KEY1" "yes" -key_clear "KEY2" -key_clear "KEY3" -key_clear "KEY4" - -# The CSK is rumoured. -set_keystate "KEY1" "GOAL" "omnipresent" -set_keystate "KEY1" "STATE_DNSKEY" "rumoured" -set_keystate "KEY1" "STATE_KRRSIG" "rumoured" -set_keystate "KEY1" "STATE_ZRRSIG" "rumoured" -set_keystate "KEY1" "STATE_DS" "hidden" -# Various signing policy checks. -check_keys -check_dnssecstatus "$SERVER" "$POLICY" "$ZONE" -check_apex -check_subdomain -dnssec_verify - -# Test key lifetime changes -set_keytimes_lifetime_update() { - if [ $1 -eq 0 ]; then - set_keytime "KEY1" "RETIRED" "none" - set_keytime "KEY1" "REMOVED" "none" - else - active=$(key_get KEY1 ACTIVE) - set_addkeytime "KEY1" "RETIRED" "${active}" $1 - # The key is removed after the retire time plus max-zone-ttl (1d), - # sign delay (9d), zone propagation delay (5m), retire safety (1h) = - # 777600 + 86400 + 300 + 3600 = 867900 - retired=$(key_get KEY1 RETIRED) - set_addkeytime "KEY1" "REMOVED" "${retired}" 867900 - fi -} - -check_key_lifetime() { - zone=$1 - policy=$2 - lifetime=$3 - - set_zone "$zone" - set_policy "$policy" "1" "3600" - set_server "ns6" "10.53.0.6" - # Key properties. - key_clear "KEY1" - set_keyrole "KEY1" "csk" - set_keylifetime "KEY1" "$lifetime" - set_keyalgorithm "KEY1" "13" "ECDSAP256SHA256" "256" - set_keysigning "KEY1" "yes" - set_zonesigning "KEY1" "yes" - key_clear "KEY2" - key_clear "KEY3" - key_clear "KEY4" - - # The CSK is rumoured. - set_keystate "KEY1" "GOAL" "omnipresent" - set_keystate "KEY1" "STATE_DNSKEY" "rumoured" - set_keystate "KEY1" "STATE_KRRSIG" "rumoured" - set_keystate "KEY1" "STATE_ZRRSIG" "rumoured" - set_keystate "KEY1" "STATE_DS" "hidden" - check_keys - - # Key timings. - set_keytimes_csk_policy - set_keytimes_lifetime_update $lifetime - - # Variuous checks. - check_keytimes - check_dnssecstatus "$SERVER" "$POLICY" "$ZONE" - check_apex - check_subdomain - dnssec_verify -} -check_key_lifetime "shorter-lifetime" "long-lifetime" "31536000" -check_key_lifetime "longer-lifetime" "short-lifetime" "16070400" -check_key_lifetime "limit-lifetime" "unlimited-lifetime" "0" -check_key_lifetime "unlimit-lifetime" "short-lifetime" "16070400" - -# -# Testing algorithm rollover. -# -Lksk=0 -Lzsk=0 -IretKSK=0 -IretZSK=0 - -# -# Zone: step1.algorithm-roll.kasp -# -set_zone "step1.algorithm-roll.kasp" -set_policy "rsasha256" "2" "3600" -set_server "ns6" "10.53.0.6" -# Key properties. -key_clear "KEY1" -set_keyrole "KEY1" "ksk" -set_keylifetime "KEY1" "0" -set_keyalgorithm "KEY1" "8" "RSASHA256" "2048" -set_keysigning "KEY1" "yes" -set_zonesigning "KEY1" "no" - -key_clear "KEY2" -set_keyrole "KEY2" "zsk" -set_keylifetime "KEY2" "0" -set_keyalgorithm "KEY2" "8" "RSASHA256" "2048" -set_keysigning "KEY2" "no" -set_zonesigning "KEY2" "yes" -key_clear "KEY3" -key_clear "KEY4" - -# The 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" - -# 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 keys need to be published. -# Since the lifetime of the keys are unlimited, so default to loadkeys -# interval. -check_next_key_event 3600 - -# -# Zone: step1.csk-algorithm-roll.kasp -# -set_zone "step1.csk-algorithm-roll.kasp" -set_policy "csk-algoroll" "1" "3600" -set_server "ns6" "10.53.0.6" -# Key properties. -key_clear "KEY1" -set_keyrole "KEY1" "csk" -set_keylifetime "KEY1" "0" -set_keyalgorithm "KEY1" "8" "RSASHA256" "2048" -set_keysigning "KEY1" "yes" -set_zonesigning "KEY1" "yes" -key_clear "KEY2" -key_clear "KEY3" -key_clear "KEY4" -# The CSK (KEY1) starts in OMNIPRESENT. -set_keystate "KEY1" "GOAL" "omnipresent" -set_keystate "KEY1" "STATE_DNSKEY" "omnipresent" -set_keystate "KEY1" "STATE_KRRSIG" "omnipresent" -set_keystate "KEY1" "STATE_ZRRSIG" "omnipresent" -set_keystate "KEY1" "STATE_DS" "omnipresent" - -# Various signing policy checks. -check_keys -check_dnssecstatus "$SERVER" "$POLICY" "$ZONE" -# This key is immediately published and activated. -Lcsk=0 -IretCSK=0 -csk_rollover_predecessor_keytimes 0 -check_keytimes -check_apex -check_subdomain -dnssec_verify - -# Next key event is when the successor keys need to be published. -# Since the lifetime of the keys are unlimited, so default to loadkeys -# interval. -check_next_key_event 3600 - -# -# Testing going insecure. -# - -# -# Zone step1.going-insecure.kasp -# -set_zone "step1.going-insecure.kasp" -set_policy "unsigning" "2" "7200" -set_server "ns6" "10.53.0.6" - -# Policy parameters. -# Lksk: 0 -# Lzsk: 60 days (5184000 seconds) -# Iret(KSK): DS TTL (1d) + DprpP (1h) + retire-safety (1h) -# Iret(KSK): 1d2h (93600 seconds) -# Iret(ZSK): RRSIG TTL (1d) + Dprp (5m) + Dsgn (9d) + retire-safety (1h) -# Iret(ZSK): 10d1h5m (867900 seconds) -Lksk=0 -Lzsk=5184000 -IretKSK=93600 -IretZSK=867900 - -init_migration_insecure() { - 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" - - set_keystate "KEY1" "GOAL" "omnipresent" - set_keystate "KEY1" "STATE_DNSKEY" "omnipresent" - set_keystate "KEY1" "STATE_KRRSIG" "omnipresent" - set_keystate "KEY1" "STATE_DS" "omnipresent" - - 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" - - set_keystate "KEY2" "GOAL" "omnipresent" - set_keystate "KEY2" "STATE_DNSKEY" "omnipresent" - set_keystate "KEY2" "STATE_ZRRSIG" "omnipresent" - - key_clear "KEY3" - key_clear "KEY4" -} -init_migration_insecure - -# Various signing policy checks. -check_keys -check_dnssecstatus "$SERVER" "$POLICY" "$ZONE" - -# We have set the timing metadata to now - 10 days (864000 seconds). -rollover_predecessor_keytimes -864000 -check_keytimes -check_apex -check_subdomain -dnssec_verify - -# -# Zone step1.going-insecure-dynamic.kasp -# - -set_zone "step1.going-insecure-dynamic.kasp" -set_dynamic -set_policy "unsigning" "2" "7200" -set_server "ns6" "10.53.0.6" -init_migration_insecure - -# Various signing policy checks. -check_keys -check_dnssecstatus "$SERVER" "$POLICY" "$ZONE" - -# We have set the timing metadata to now - 10 days (864000 seconds). -rollover_predecessor_keytimes -864000 -check_keytimes -check_apex -check_subdomain -dnssec_verify - -# -# Zone step1.going-straight-to-none.kasp -# -set_zone "step1.going-straight-to-none.kasp" -set_policy "default" "1" "3600" -set_server "ns6" "10.53.0.6" -# Key properties. -set_keyrole "KEY1" "csk" -set_keylifetime "KEY1" "0" -set_keyalgorithm "KEY1" "13" "ECDSAP256SHA256" "256" -set_keysigning "KEY1" "yes" -set_zonesigning "KEY1" "yes" -# DNSKEY, RRSIG (ksk), RRSIG (zsk) are published. DS needs to wait. -set_keystate "KEY1" "GOAL" "omnipresent" -set_keystate "KEY1" "STATE_DNSKEY" "omnipresent" -set_keystate "KEY1" "STATE_KRRSIG" "omnipresent" -set_keystate "KEY1" "STATE_ZRRSIG" "omnipresent" -set_keystate "KEY1" "STATE_DS" "omnipresent" -# This policy only has one key. -key_clear "KEY2" -key_clear "KEY3" -key_clear "KEY4" - -check_keys -check_dnssecstatus "$SERVER" "$POLICY" "$ZONE" - -# The first key is immediately published and activated. -created=$(key_get KEY1 CREATED) -set_keytime "KEY1" "PUBLISHED" "${created}" -set_keytime "KEY1" "ACTIVE" "${created}" -set_keytime "KEY1" "SYNCPUBLISH" "${created}" -# Key lifetime is unlimited, so not setting RETIRED and REMOVED. -check_keytimes - -check_apex -check_subdomain -dnssec_verify - -# -# Zone step1.going-straight-to-none-dynamic.kasp -# -set_zone "step1.going-straight-to-none-dynamic.kasp" -set_policy "default" "1" "3600" -set_server "ns6" "10.53.0.6" -# Key properties. -set_keyrole "KEY1" "csk" -set_keylifetime "KEY1" "0" -set_keyalgorithm "KEY1" "13" "ECDSAP256SHA256" "256" -set_keysigning "KEY1" "yes" -set_zonesigning "KEY1" "yes" -# DNSKEY, RRSIG (ksk), RRSIG (zsk) are published. DS needs to wait. -set_keystate "KEY1" "GOAL" "omnipresent" -set_keystate "KEY1" "STATE_DNSKEY" "omnipresent" -set_keystate "KEY1" "STATE_KRRSIG" "omnipresent" -set_keystate "KEY1" "STATE_ZRRSIG" "omnipresent" -set_keystate "KEY1" "STATE_DS" "omnipresent" -# This policy only has one key. -key_clear "KEY2" -key_clear "KEY3" -key_clear "KEY4" - -check_keys -check_dnssecstatus "$SERVER" "$POLICY" "$ZONE" - -# The first key is immediately published and activated. -created=$(key_get KEY1 CREATED) -set_keytime "KEY1" "PUBLISHED" "${created}" -set_keytime "KEY1" "ACTIVE" "${created}" -set_keytime "KEY1" "SYNCPUBLISH" "${created}" -# Key lifetime is unlimited, so not setting RETIRED and REMOVED. -check_keytimes - -check_apex -check_subdomain -dnssec_verify - -# Reconfig dnssec-policy (triggering algorithm roll and other dnssec-policy -# changes). -echo_i "reconfig dnssec-policy to trigger algorithm rollover" -copy_setports ns6/named2.conf.in ns6/named.conf -rndc_reconfig ns6 10.53.0.6 - -# Calculate time passed to correctly check for next key events. -now="$(TZ=UTC date +%s)" -time_passed=$((now - start_time)) -echo_i "${time_passed} seconds passed between start of tests and reconfig" - -# Wait until we have seen "zone_rekey done:" message for this key. -_wait_for_done_signing() { - _zone=$1 - - _ksk=$(key_get $2 KSK) - _zsk=$(key_get $2 ZSK) - if [ "$_ksk" = "yes" ]; then - _role="KSK" - _expect_type=EXPECT_KRRSIG - elif [ "$_zsk" = "yes" ]; then - _role="ZSK" - _expect_type=EXPECT_ZRRSIG - fi - - if [ "$(key_get ${2} $_expect_type)" = "yes" ] && [ "$(key_get $2 $_role)" = "yes" ]; then - _keyid=$(key_get $2 ID) - _keyalg=$(key_get $2 ALG_STR) - echo_i "wait for zone ${_zone} is done signing with $2 ${_zone}/${_keyalg}/${_keyid}" - grep "zone_rekey done: key ${_keyid}/${_keyalg}" "${DIR}/named.run" >/dev/null || return 1 - fi - - return 0 -} - -wait_for_done_signing() { - n=$((n + 1)) - echo_i "wait for zone ${ZONE} is done signing ($n)" - ret=0 - - retry_quiet 30 _wait_for_done_signing ${ZONE} KEY1 || ret=1 - retry_quiet 30 _wait_for_done_signing ${ZONE} KEY2 || ret=1 - retry_quiet 30 _wait_for_done_signing ${ZONE} KEY3 || ret=1 - retry_quiet 30 _wait_for_done_signing ${ZONE} KEY4 || ret=1 - - test "$ret" -eq 0 || echo_i "failed" - status=$((status + ret)) -} - -# Test dynamic zones that switch to inline-signing. -set_zone "dynamic2inline.kasp" -set_policy "default" "1" "3600" -set_server "ns6" "10.53.0.6" -# Key properties. -key_clear "KEY1" -set_keyrole "KEY1" "csk" -set_keylifetime "KEY1" "0" -set_keyalgorithm "KEY1" "13" "ECDSAP256SHA256" "256" -set_keysigning "KEY1" "yes" -set_zonesigning "KEY1" "yes" -key_clear "KEY2" -key_clear "KEY3" -key_clear "KEY4" - -# The CSK is rumoured. -set_keystate "KEY1" "GOAL" "omnipresent" -set_keystate "KEY1" "STATE_DNSKEY" "rumoured" -set_keystate "KEY1" "STATE_KRRSIG" "rumoured" -set_keystate "KEY1" "STATE_ZRRSIG" "rumoured" -set_keystate "KEY1" "STATE_DS" "hidden" -# Various signing policy checks. -check_keys -check_dnssecstatus "$SERVER" "$POLICY" "$ZONE" -check_apex -check_subdomain -dnssec_verify - -# Test key lifetime updates. -check_key_lifetime "shorter-lifetime" "short-lifetime" "16070400" -check_key_lifetime "longer-lifetime" "long-lifetime" "31536000" -check_key_lifetime "limit-lifetime" "short-lifetime" "16070400" -check_key_lifetime "unlimit-lifetime" "unlimited-lifetime" "0" - -# -# Testing going insecure. -# - -# -# Zone: step1.going-insecure.kasp -# -set_zone "step1.going-insecure.kasp" -set_policy "insecure" "2" "3600" -set_server "ns6" "10.53.0.6" -# Expect a CDS/CDNSKEY Delete Record. -set_cdsdelete - -# Key goal states should be HIDDEN. -init_migration_insecure -set_keystate "KEY1" "GOAL" "hidden" -set_keystate "KEY2" "GOAL" "hidden" -# The DS may be removed if we are going insecure. -set_keystate "KEY1" "STATE_DS" "unretentive" - -# Various signing policy checks. -check_keys -wait_for_done_signing -check_dnssecstatus "$SERVER" "$POLICY" "$ZONE" -check_apex -check_subdomain -dnssec_verify - -# Tell named that the DS has been removed. -rndc_checkds "$SERVER" "$DIR" "KEY1" "now" "withdrawn" "$ZONE" -wait_for_done_signing -check_dnssecstatus "$SERVER" "$POLICY" "$ZONE" -check_apex -check_subdomain -dnssec_verify - -# Next key event is when the DS becomes HIDDEN. This happens after the -# parent propagation delay, and DS TTL: -# 1h + 1d = 25h = 90000 seconds. -check_next_key_event 90000 - -# -# Zone: step2.going-insecure.kasp -# -set_zone "step2.going-insecure.kasp" -set_policy "insecure" "2" "3600" -set_server "ns6" "10.53.0.6" - -# The DS is long enough removed from the zone to be considered HIDDEN. -# This means the DNSKEY and the KSK signatures can be removed. -set_keystate "KEY1" "STATE_DS" "hidden" -set_keystate "KEY1" "STATE_DNSKEY" "unretentive" -set_keystate "KEY1" "STATE_KRRSIG" "unretentive" -set_keysigning "KEY1" "no" - -set_keystate "KEY2" "STATE_DNSKEY" "unretentive" -set_keystate "KEY2" "STATE_ZRRSIG" "unretentive" -set_zonesigning "KEY2" "no" - -# Various signing policy checks. -check_keys -check_dnssecstatus "$SERVER" "$POLICY" "$ZONE" -check_apex -check_subdomain - -# Next key event is when the DNSKEY becomes HIDDEN. This happens after the -# propagation delay, plus DNSKEY TTL: -# 5m + 2h = 125m = 7500 seconds. -check_next_key_event 7500 - -# -# Zone: step1.going-insecure-dynamic.kasp -# -set_zone "step1.going-insecure-dynamic.kasp" -set_dynamic -set_policy "insecure" "2" "3600" -set_server "ns6" "10.53.0.6" -# Expect a CDS/CDNSKEY Delete Record. -set_cdsdelete - -# Key goal states should be HIDDEN. -init_migration_insecure -set_keystate "KEY1" "GOAL" "hidden" -set_keystate "KEY2" "GOAL" "hidden" -# The DS may be removed if we are going insecure. -set_keystate "KEY1" "STATE_DS" "unretentive" - -# Various signing policy checks. -check_keys -wait_for_done_signing -check_dnssecstatus "$SERVER" "$POLICY" "$ZONE" -check_apex -check_subdomain -dnssec_verify - -# Tell named that the DS has been removed. -rndc_checkds "$SERVER" "$DIR" "KEY1" "now" "withdrawn" "$ZONE" -wait_for_done_signing -check_dnssecstatus "$SERVER" "$POLICY" "$ZONE" -check_apex -check_subdomain -dnssec_verify - -# Next key event is when the DS becomes HIDDEN. This happens after the -# parent propagation delay, retire safety delay, and DS TTL: -# 1h + 1d = 25h = 90000 seconds. -check_next_key_event 90000 - -# -# Zone: step2.going-insecure-dynamic.kasp -# -set_zone "step2.going-insecure-dynamic.kasp" -set_dynamic -set_policy "insecure" "2" "3600" -set_server "ns6" "10.53.0.6" - -# The DS is long enough removed from the zone to be considered HIDDEN. -# This means the DNSKEY and the KSK signatures can be removed. -set_keystate "KEY1" "STATE_DS" "hidden" -set_keystate "KEY1" "STATE_DNSKEY" "unretentive" -set_keystate "KEY1" "STATE_KRRSIG" "unretentive" -set_keysigning "KEY1" "no" - -set_keystate "KEY2" "STATE_DNSKEY" "unretentive" -set_keystate "KEY2" "STATE_ZRRSIG" "unretentive" -set_zonesigning "KEY2" "no" - -# Various signing policy checks. -check_keys -check_dnssecstatus "$SERVER" "$POLICY" "$ZONE" -check_apex -check_subdomain - -# Next key event is when the DNSKEY becomes HIDDEN. This happens after the -# propagation delay, plus DNSKEY TTL: -# 5m + 2h = 125m = 7500 seconds. -check_next_key_event 7500 - -# -# Zone: step1.going-straight-to-none.kasp -# -set_zone "step1.going-straight-to-none.kasp" -set_policy "none" "1" "3600" -set_server "ns6" "10.53.0.6" - -# The zone will go bogus after signatures expire, but remains validly signed for now. - -# Key properties. -set_keyrole "KEY1" "csk" -set_keylifetime "KEY1" "0" -set_keyalgorithm "KEY1" "13" "ECDSAP256SHA256" "256" -set_keysigning "KEY1" "yes" -set_zonesigning "KEY1" "yes" -# DNSKEY, RRSIG (ksk), RRSIG (zsk) are published. DS needs to wait. -set_keystate "KEY1" "GOAL" "omnipresent" -set_keystate "KEY1" "STATE_DNSKEY" "omnipresent" -set_keystate "KEY1" "STATE_KRRSIG" "omnipresent" -set_keystate "KEY1" "STATE_ZRRSIG" "omnipresent" -set_keystate "KEY1" "STATE_DS" "omnipresent" -# This policy only has one key. -key_clear "KEY2" -key_clear "KEY3" -key_clear "KEY4" - -# Various signing policy checks. -check_keys -check_dnssecstatus "$SERVER" "$POLICY" "$ZONE" -dnssec_verify - -# -# Zone: step1.going-straight-to-none-dynamic.kasp -# -set_zone "step1.going-straight-to-none-dynamic.kasp" -set_policy "none" "1" "3600" -set_server "ns6" "10.53.0.6" - -# The zone will go bogus after signatures expire, but remains validly signed for now. - -# Key properties. -set_keyrole "KEY1" "csk" -set_keylifetime "KEY1" "0" -set_keyalgorithm "KEY1" "13" "ECDSAP256SHA256" "256" -set_keysigning "KEY1" "yes" -set_zonesigning "KEY1" "yes" -# DNSKEY, RRSIG (ksk), RRSIG (zsk) are published. DS needs to wait. -set_keystate "KEY1" "GOAL" "omnipresent" -set_keystate "KEY1" "STATE_DNSKEY" "omnipresent" -set_keystate "KEY1" "STATE_KRRSIG" "omnipresent" -set_keystate "KEY1" "STATE_ZRRSIG" "omnipresent" -set_keystate "KEY1" "STATE_DS" "omnipresent" -# This policy only has one key. -key_clear "KEY2" -key_clear "KEY3" -key_clear "KEY4" - -# Various signing policy checks. -check_keys -check_dnssecstatus "$SERVER" "$POLICY" "$ZONE" -dnssec_verify - -# -# Testing KSK/ZSK algorithm rollover. -# - -# Policy parameters. -# Lksk: unlimited -# Lzsk: unlimited -Lksk=0 -Lzsk=0 - -# -# Zone: step1.algorithm-roll.kasp -# -set_zone "step1.algorithm-roll.kasp" -set_policy "ecdsa256" "4" "3600" -set_server "ns6" "10.53.0.6" -# Old RSASHA1 keys. -key_clear "KEY1" -set_keyrole "KEY1" "ksk" -set_keylifetime "KEY1" "0" -set_keyalgorithm "KEY1" "8" "RSASHA256" "2048" -set_keysigning "KEY1" "yes" -set_zonesigning "KEY1" "no" - -key_clear "KEY2" -set_keyrole "KEY2" "zsk" -set_keylifetime "KEY2" "0" -set_keyalgorithm "KEY2" "8" "RSASHA256" "2048" -set_keysigning "KEY2" "no" -set_zonesigning "KEY2" "yes" -# New ECDSAP256SHA256 keys. -key_clear "KEY3" -set_keyrole "KEY3" "ksk" -set_keylifetime "KEY3" "0" -set_keyalgorithm "KEY3" "13" "ECDSAP256SHA256" "256" -set_keysigning "KEY3" "yes" -set_zonesigning "KEY3" "no" - -key_clear "KEY4" -set_keyrole "KEY4" "zsk" -set_keylifetime "KEY4" "0" -set_keyalgorithm "KEY4" "13" "ECDSAP256SHA256" "256" -set_keysigning "KEY4" "no" -set_zonesigning "KEY4" "yes" -# The RSAHSHA1 keys are outroducing. -set_keystate "KEY1" "GOAL" "hidden" -set_keystate "KEY1" "STATE_DNSKEY" "omnipresent" -set_keystate "KEY1" "STATE_KRRSIG" "omnipresent" -set_keystate "KEY1" "STATE_DS" "omnipresent" -set_keystate "KEY2" "GOAL" "hidden" -set_keystate "KEY2" "STATE_DNSKEY" "omnipresent" -set_keystate "KEY2" "STATE_ZRRSIG" "omnipresent" -# The ECDSAP256SHA256 keys are introducing. -set_keystate "KEY3" "GOAL" "omnipresent" -set_keystate "KEY3" "STATE_DNSKEY" "rumoured" -set_keystate "KEY3" "STATE_KRRSIG" "rumoured" -set_keystate "KEY3" "STATE_DS" "hidden" -set_keystate "KEY4" "GOAL" "omnipresent" -set_keystate "KEY4" "STATE_DNSKEY" "rumoured" -set_keystate "KEY4" "STATE_ZRRSIG" "rumoured" - -# Various signing policy checks. -check_keys -wait_for_done_signing -check_dnssecstatus "$SERVER" "$POLICY" "$ZONE" - -# Set expected key times: -# - The old keys are published and activated. -rollover_predecessor_keytimes 0 -# - KSK must be retired since it no longer matches the policy. -keyfile=$(key_get KEY1 BASEFILE) -grep "; Inactive:" "${keyfile}.key" >retired.test${n}.ksk -retired=$(awk '{print $3}' retired.test${n}.zsk -retired=$(awk '{print $3}' retired.test${n}.ksk -retired=$(awk '{print $3}' >zones + T="now-10d" + S="now-12955mi" + keytimes="-P $T -A $T" + cdstimes="-P sync $S" + KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $keytimes $cdstimes $zone 2>keygen.out.$zone.1) + ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 $keytimes $zone 2>keygen.out.$zone.2) + 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: + # Set up a zone with dnssec-policy that is going insecure. Don't add + # this zone to the zones file, because this zone is no longer expected + # to be fully signed. + setup step2.$zn + # The DS was withdrawn from the parent zone 26 hours ago. + D="now-26h" + keytimes="-P $T -A $T -I $D -D now" + cdstimes="-P sync $S -D sync $D" + KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $keytimes $cdstimes $zone 2>keygen.out.$zone.1) + ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 $keytimes $zone 2>keygen.out.$zone.2) + $SETTIME -s -g $H -k $O $T -r $O $T -d $U $D -D ds $D "$KSK" >settime.out.$zone.1 2>&1 + $SETTIME -s -g $H -k $O $T -z $O $T "$ZSK" >settime.out.$zone.2 2>&1 + # Fake lifetime of old algorithm keys. + echo "Lifetime: 0" >>"${KSK}.state" + echo "Lifetime: 5184000" >>"${ZSK}.state" + 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 +done + +# These zones are going straight to "none" policy. This is undefined behavior. +T="now-10d" +S="now-12955mi" +csktimes="-P $T -A $T -P sync $S" + +setup step1.going-straight-to-none.kasp +echo "$zone" >>zones +CSK=$($KEYGEN -k default $csktimes $zone 2>keygen.out.$zone.1) +$SETTIME -s -g $O -k $O $TactN -z $O $TactN -r $O $TactN -d $O $TactN "$CSK" >settime.out.$zone.1 2>&1 +cat template.db.in "${CSK}.key" >"$infile" +private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK" >>"$infile" +cp $infile $zonefile +$SIGNER -S -z -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 + +setup step1.going-straight-to-none-dynamic.kasp +echo "$zone" >>zones +CSK=$($KEYGEN -k default $csktimes $zone 2>keygen.out.$zone.1) +$SETTIME -s -g $O -k $O $TactN -z $O $TactN -r $O $TactN -d $O $TactN "$CSK" >settime.out.$zone.1 2>&1 +cat template.db.in "${CSK}.key" >"$infile" +private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK" >>"$infile" +cp $infile $zonefile +$SIGNER -S -z -x -s now-1h -e now+2w -o $zone -O full -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 + +# +# The zones at algorithm-roll.kasp represent the various steps of a ZSK/KSK +# algorithm rollover. +# + +# Step 1: +# Introduce the first key. This will immediately be active. +setup step1.algorithm-roll.kasp +echo "$zone" >>zones +TactN="now-7d" +TsbmN="now-161h" +ksktimes="-P ${TactN} -A ${TactN}" +zsktimes="-P ${TactN} -A ${TactN}" +KSK=$($KEYGEN -a RSASHA256 -L 3600 -f KSK $ksktimes $zone 2>keygen.out.$zone.1) +ZSK=$($KEYGEN -a RSASHA256 -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 8 "$KSK" >>"$infile" +private_type_record $zone 8 "$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: +# After the publication interval has passed the DNSKEY is OMNIPRESENT. +setup step2.algorithm-roll.kasp +# The time passed since the new algorithm keys have been introduced is 3 hours. +TpubN1="now-3h" +# Tsbm(N+1) = TpubN1 + Ipub = now + TTLsig + Dprp = now - 3h + 6h + 1h = now + 4h +TsbmN1="now+4h" +ksk1times="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I ${TsbmN1}" +zsk1times="-P ${TactN} -A ${TactN} -I ${TsbmN1}" +ksk2times="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}" +zsk2times="-P ${TpubN1} -A ${TpubN1}" +KSK1=$($KEYGEN -a RSASHA256 -L 3600 -f KSK $ksk1times $zone 2>keygen.out.$zone.1) +ZSK1=$($KEYGEN -a RSASHA256 -L 3600 $zsk1times $zone 2>keygen.out.$zone.2) +KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $ksk2times $zone 2>keygen.out.$zone.3) +ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $zsk2times $zone 2>keygen.out.$zone.4) +$SETTIME -s -g $H -k $O $TactN -r $O $TactN -d $O $TactN "$KSK1" >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 -r $R $TpubN1 -d $H $TpubN1 "$KSK2" >settime.out.$zone.3 2>&1 +$SETTIME -s -g $O -k $R $TpubN1 -z $R $TpubN1 "$ZSK2" >settime.out.$zone.4 2>&1 +# Fake lifetime of old algorithm keys. +echo "Lifetime: 0" >>"${KSK1}.state" +echo "Lifetime: 0" >>"${ZSK1}.state" +cat template.db.in "${KSK1}.key" "${ZSK1}.key" "${KSK2}.key" "${ZSK2}.key" >"$infile" +private_type_record $zone 8 "$KSK1" >>"$infile" +private_type_record $zone 8 "$ZSK1" >>"$infile" +private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$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 3: +# The zone signatures are also OMNIPRESENT. +setup step3.algorithm-roll.kasp +# The time passed since the new algorithm keys have been introduced is 7 hours. +TpubN1="now-7h" +TsbmN1="now" +ksk1times="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I ${TsbmN1}" +zsk1times="-P ${TactN} -A ${TactN} -I ${TsbmN1}" +ksk2times="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}" +zsk2times="-P ${TpubN1} -A ${TpubN1}" +KSK1=$($KEYGEN -a RSASHA256 -L 3600 -f KSK $ksk1times $zone 2>keygen.out.$zone.1) +ZSK1=$($KEYGEN -a RSASHA256 -L 3600 $zsk1times $zone 2>keygen.out.$zone.2) +KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $ksk2times $zone 2>keygen.out.$zone.3) +ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $zsk2times $zone 2>keygen.out.$zone.4) +$SETTIME -s -g $H -k $O $TactN -r $O $TactN -d $O $TactN "$KSK1" >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 $O $TpubN1 -r $O $TpubN1 -d $H $TpubN1 "$KSK2" >settime.out.$zone.3 2>&1 +$SETTIME -s -g $O -k $O $TpubN1 -z $R $TpubN1 "$ZSK2" >settime.out.$zone.4 2>&1 +# Fake lifetime of old algorithm keys. +echo "Lifetime: 0" >>"${KSK1}.state" +echo "Lifetime: 0" >>"${ZSK1}.state" +cat template.db.in "${KSK1}.key" "${ZSK1}.key" "${KSK2}.key" "${ZSK2}.key" >"$infile" +private_type_record $zone 8 "$KSK1" >>"$infile" +private_type_record $zone 8 "$ZSK1" >>"$infile" +private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$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: +# The DS is swapped and can become OMNIPRESENT. +setup step4.algorithm-roll.kasp +# The time passed since the DS has been swapped is 3 hours. +TpubN1="now-10h" +TsbmN1="now-3h" +ksk1times="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I ${TsbmN1}" +zsk1times="-P ${TactN} -A ${TactN} -I ${TsbmN1}" +ksk2times="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}" +zsk2times="-P ${TpubN1} -A ${TpubN1}" +KSK1=$($KEYGEN -a RSASHA256 -L 3600 -f KSK $ksk1times $zone 2>keygen.out.$zone.1) +ZSK1=$($KEYGEN -a RSASHA256 -L 3600 $zsk1times $zone 2>keygen.out.$zone.2) +KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $ksk2times $zone 2>keygen.out.$zone.3) +ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $zsk2times $zone 2>keygen.out.$zone.4) +$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 $H -k $O $TactN -z $O $TactN "$ZSK1" >settime.out.$zone.2 2>&1 +$SETTIME -s -g $O -k $O $TpubN1 -r $O $TpubN1 -d $R $TsbmN1 -P ds $TsbmN1 "$KSK2" >settime.out.$zone.3 2>&1 +$SETTIME -s -g $O -k $O $TpubN1 -z $R $TpubN1 "$ZSK2" >settime.out.$zone.4 2>&1 +# Fake lifetime of old algorithm keys. +echo "Lifetime: 0" >>"${KSK1}.state" +echo "Lifetime: 0" >>"${ZSK1}.state" +cat template.db.in "${KSK1}.key" "${ZSK1}.key" "${KSK2}.key" "${ZSK2}.key" >"$infile" +private_type_record $zone 8 "$KSK1" >>"$infile" +private_type_record $zone 8 "$ZSK1" >>"$infile" +private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$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 5: +# The DNSKEY is removed long enough to be HIDDEN. +setup step5.algorithm-roll.kasp +# The time passed since the DNSKEY has been removed is 2 hours. +TpubN1="now-12h" +TsbmN1="now-5h" +ksk1times="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I ${TsbmN1}" +zsk1times="-P ${TactN} -A ${TactN} -I ${TsbmN1}" +ksk2times="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}" +zsk2times="-P ${TpubN1} -A ${TpubN1}" +KSK1=$($KEYGEN -a RSASHA256 -L 3600 -f KSK $ksk1times $zone 2>keygen.out.$zone.1) +ZSK1=$($KEYGEN -a RSASHA256 -L 3600 $zsk1times $zone 2>keygen.out.$zone.2) +KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $ksk2times $zone 2>keygen.out.$zone.3) +ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $zsk2times $zone 2>keygen.out.$zone.4) +$SETTIME -s -g $H -k $U $TsbmN1 -r $U $TsbmN1 -d $H $TsbmN1 "$KSK1" >settime.out.$zone.1 2>&1 +$SETTIME -s -g $H -k $U $TsbmN1 -z $U $TsbmN1 "$ZSK1" >settime.out.$zone.2 2>&1 +$SETTIME -s -g $O -k $O $TpubN1 -r $O $TpubN1 -d $O $TsbmN1 "$KSK2" >settime.out.$zone.3 2>&1 +$SETTIME -s -g $O -k $O $TpubN1 -z $R $TpubN1 "$ZSK2" >settime.out.$zone.4 2>&1 +# Fake lifetime of old algorithm keys. +echo "Lifetime: 0" >>"${KSK1}.state" +echo "Lifetime: 0" >>"${ZSK1}.state" +cat template.db.in "${KSK1}.key" "${ZSK1}.key" "${KSK2}.key" "${ZSK2}.key" >"$infile" +private_type_record $zone 8 "$KSK1" >>"$infile" +private_type_record $zone 8 "$ZSK1" >>"$infile" +private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$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 RRSIGs have been removed long enough to be HIDDEN. +setup step6.algorithm-roll.kasp +# Additional time passed: 7h. +TpubN1="now-19h" +TsbmN1="now-12h" +ksk1times="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I ${TsbmN1}" +zsk1times="-P ${TactN} -A ${TactN} -I ${TsbmN1}" +ksk2times="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}" +zsk2times="-P ${TpubN1} -A ${TpubN1}" +KSK1=$($KEYGEN -a RSASHA256 -L 3600 -f KSK $ksk1times $zone 2>keygen.out.$zone.1) +ZSK1=$($KEYGEN -a RSASHA256 -L 3600 $zsk1times $zone 2>keygen.out.$zone.2) +KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $ksk2times $zone 2>keygen.out.$zone.3) +ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $zsk2times $zone 2>keygen.out.$zone.4) +$SETTIME -s -g $H -k $H $TsbmN1 -r $U $TsbmN1 -d $H $TsbmN1 "$KSK1" >settime.out.$zone.1 2>&1 +$SETTIME -s -g $H -k $H $TsbmN1 -z $U $TsbmN1 "$ZSK1" >settime.out.$zone.2 2>&1 +$SETTIME -s -g $O -k $O $TpubN1 -r $O $TpubN1 -d $O $TsbmN1 "$KSK2" >settime.out.$zone.3 2>&1 +$SETTIME -s -g $O -k $O $TpubN1 -z $R $TpubN1 "$ZSK2" >settime.out.$zone.4 2>&1 +# Fake lifetime of old algorithm keys. +echo "Lifetime: 0" >>"${KSK1}.state" +echo "Lifetime: 0" >>"${ZSK1}.state" +cat template.db.in "${KSK1}.key" "${ZSK1}.key" "${KSK2}.key" "${ZSK2}.key" >"$infile" +private_type_record $zone 8 "$KSK1" >>"$infile" +private_type_record $zone 8 "$ZSK1" >>"$infile" +private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$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 csk-algorithm-roll.kasp represent the various steps of a CSK +# algorithm rollover. +# + +# Step 1: +# Introduce the first key. This will immediately be active. +setup step1.csk-algorithm-roll.kasp +echo "$zone" >>zones +TactN="now-7d" +TsbmN="now-161h" +csktimes="-P ${TactN} -A ${TactN}" +CSK=$($KEYGEN -k csk-algoroll -l csk1.conf $csktimes $zone 2>keygen.out.$zone.1) +$SETTIME -s -g $O -k $O $TactN -r $O $TactN -z $O $TactN -d $O $TactN "$CSK" >settime.out.$zone.1 2>&1 +cat template.db.in "${CSK}.key" >"$infile" +private_type_record $zone 5 "$CSK" >>"$infile" +cp $infile $zonefile +$SIGNER -S -x -z -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 + +# Step 2: +# After the publication interval has passed the DNSKEY is OMNIPRESENT. +setup step2.csk-algorithm-roll.kasp +# The time passed since the new algorithm keys have been introduced is 3 hours. +TpubN1="now-3h" +# Tsbm(N+1) = TpubN1 + Ipub = now + TTLsig + Dprp = now - 3h + 6h + 1h = now + 4h +TsbmN1="now+4h" +csktimes="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I now" +newtimes="-P ${TpubN1} -A ${TpubN1}" +CSK1=$($KEYGEN -k csk-algoroll -l csk1.conf $csktimes $zone 2>keygen.out.$zone.1) +CSK2=$($KEYGEN -k csk-algoroll -l csk2.conf $newtimes $zone 2>keygen.out.$zone.2) +$SETTIME -s -g $H -k $O $TactN -r $O $TactN -z $O $TactN -d $O $TactN "$CSK1" >settime.out.$zone.1 2>&1 +$SETTIME -s -g $O -k $R $TpubN1 -r $R $TpubN1 -z $R $TpubN1 -d $H $TpubN1 "$CSK2" >settime.out.$zone.2 2>&1 +# Fake lifetime of old algorithm keys. +echo "Lifetime: 0" >>"${CSK1}.state" +cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" +private_type_record $zone 5 "$CSK1" >>"$infile" +private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" +cp $infile $zonefile +$SIGNER -S -x -z -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 + +# Step 3: +# The zone signatures are also OMNIPRESENT. +setup step3.csk-algorithm-roll.kasp +# The time passed since the new algorithm keys have been introduced is 7 hours. +TpubN1="now-7h" +TsbmN1="now" +ckstimes="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I ${TsbmN1}" +newtimes="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}" +CSK1=$($KEYGEN -k csk-algoroll -l csk1.conf $csktimes $zone 2>keygen.out.$zone.1) +CSK2=$($KEYGEN -k csk-algoroll -l csk2.conf $newtimes $zone 2>keygen.out.$zone.2) +$SETTIME -s -g $H -k $O $TactN -r $O $TactN -z $O $TactN -d $O $TactN "$CSK1" >settime.out.$zone.1 2>&1 +$SETTIME -s -g $O -k $O $TpubN1 -r $O $TpubN1 -z $R $TpubN1 -d $H $TpubN1 "$CSK2" >settime.out.$zone.2 2>&1 +# Fake lifetime of old algorithm keys. +echo "Lifetime: 0" >>"${CSK1}.state" +cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" +private_type_record $zone 5 "$CSK1" >>"$infile" +private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" +cp $infile $zonefile +$SIGNER -S -x -z -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 + +# Step 4: +# The DS is swapped and can become OMNIPRESENT. +setup step4.csk-algorithm-roll.kasp +# The time passed since the DS has been swapped is 3 hours. +TpubN1="now-10h" +TsbmN1="now-3h" +csktimes="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I ${TsbmN1}" +newtimes="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}" +CSK1=$($KEYGEN -k csk-algoroll -l csk1.conf $csktimes $zone 2>keygen.out.$zone.1) +CSK2=$($KEYGEN -k csk-algoroll -l csk2.conf $newtimes $zone 2>keygen.out.$zone.2) +$SETTIME -s -g $H -k $O $TactN -r $O $TactN -z $O $TsbmN1 -d $U $TsbmN1 -D ds $TsbmN1 "$CSK1" >settime.out.$zone.1 2>&1 +$SETTIME -s -g $O -k $O $TpubN1 -r $O $TpubN1 -z $O $TsbmN1 -d $R $TsbmN1 -P ds $TsbmN1 "$CSK2" >settime.out.$zone.2 2>&1 +# Fake lifetime of old algorithm keys. +echo "Lifetime: 0" >>"${CSK1}.state" +cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" +private_type_record $zone 5 "$CSK1" >>"$infile" +private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" +cp $infile $zonefile +$SIGNER -S -x -z -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 + +# Step 5: +# The DNSKEY is removed long enough to be HIDDEN. +setup step5.csk-algorithm-roll.kasp +# The time passed since the DNSKEY has been removed is 2 hours. +TpubN1="now-12h" +TsbmN1="now-5h" +csktimes="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I ${TsbmN1}" +newtimes="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}" +CSK1=$($KEYGEN -k csk-algoroll -l csk1.conf $csktimes $zone 2>keygen.out.$zone.1) +CSK2=$($KEYGEN -k csk-algoroll -l csk2.conf $newtimes $zone 2>keygen.out.$zone.2) +$SETTIME -s -g $H -k $U $TactN -r $U $TactN -z $U $TsbmN1 -d $H $TsbmN1 "$CSK1" >settime.out.$zone.1 2>&1 +$SETTIME -s -g $O -k $O $TpubN1 -r $O $TpubN1 -z $O $TsbmN1 -d $O $TsbmN1 "$CSK2" >settime.out.$zone.2 2>&1 +# Fake lifetime of old algorithm keys. +echo "Lifetime: 0" >>"${CSK1}.state" +cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" +private_type_record $zone 5 "$CSK1" >>"$infile" +private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" +cp $infile $zonefile +$SIGNER -S -x -z -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 + +# Step 6: +# The RRSIGs have been removed long enough to be HIDDEN. +setup step6.csk-algorithm-roll.kasp +# Additional time passed: 7h. +TpubN1="now-19h" +TsbmN1="now-12h" +csktimes="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I ${TsbmN1}" +newtimes="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}" +CSK1=$($KEYGEN -k csk-algoroll -l csk1.conf $csktimes $zone 2>keygen.out.$zone.1) +CSK2=$($KEYGEN -k csk-algoroll -l csk2.conf $newtimes $zone 2>keygen.out.$zone.2) +$SETTIME -s -g $H -k $H $TactN -r $U $TactN -z $U $TactN -d $H $TsbmN1 "$CSK1" >settime.out.$zone.1 2>&1 +$SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -z $O $TsubN1 -d $O $TsbmN1 "$CSK2" >settime.out.$zone.2 2>&1 +# Fake lifetime of old algorithm keys. +echo "Lifetime: 0" >>"${CSK1}.state" +cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" +private_type_record $zone 5 "$CSK1" >>"$infile" +private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" +cp $infile $zonefile +$SIGNER -S -x -z -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 diff --git a/bin/tests/system/rollover/ns6/template.db.in b/bin/tests/system/rollover/ns6/template.db.in new file mode 100644 index 0000000000..f1d8b94e5a --- /dev/null +++ b/bin/tests/system/rollover/ns6/template.db.in @@ -0,0 +1,27 @@ +; Copyright (C) Internet Systems Consortium, Inc. ("ISC") +; +; SPDX-License-Identifier: MPL-2.0 +; +; This Source Code Form is subject to the terms of the Mozilla Public +; License, v. 2.0. If a copy of the MPL was not distributed with this +; file, you can obtain one at https://mozilla.org/MPL/2.0/. +; +; See the COPYRIGHT file distributed with this work for additional +; information regarding copyright ownership. + +$TTL 300 +@ IN SOA mname1. . ( + 1 ; serial + 20 ; refresh (20 seconds) + 20 ; retry (20 seconds) + 1814400 ; expire (3 weeks) + 3600 ; minimum (1 hour) + ) + + NS ns6 +ns6 A 10.53.0.6 + +a A 10.0.0.1 +b A 10.0.0.2 +c A 10.0.0.3 + diff --git a/bin/tests/system/rollover/setup.sh b/bin/tests/system/rollover/setup.sh index c72052cf48..56a8979855 100644 --- a/bin/tests/system/rollover/setup.sh +++ b/bin/tests/system/rollover/setup.sh @@ -20,3 +20,7 @@ set -e cd ns3 $SHELL setup.sh ) +( + cd ns6 + $SHELL setup.sh +) diff --git a/bin/tests/system/rollover/tests_rollover.py b/bin/tests/system/rollover/tests_rollover.py index bbfb473891..f30eb2fad9 100644 --- a/bin/tests/system/rollover/tests_rollover.py +++ b/bin/tests/system/rollover/tests_rollover.py @@ -10,6 +10,7 @@ # information regarding copyright ownership. import os +import shutil from datetime import timedelta @@ -386,18 +387,25 @@ def check_rollover_step(server, config, policy, step): keyrelationships = step.get("keyrelationships", None) smooth = step.get("smooth", False) ds_swap = step.get("ds-swap", True) + cds_delete = step.get("cds-delete", False) + check_keytimes = step.get("check-keytimes", True) + zone_signed = step.get("zone-signed", True) isctest.log.info(f"check rollover step {zone}") + if zone_signed: + isctest.kasp.check_dnssec_verify(server, zone) + ttl = int(config["dnskey-ttl"].total_seconds()) expected = isctest.kasp.policy_to_properties(ttl, keyprops) - isctest.kasp.check_dnssec_verify(server, zone) keys = isctest.kasp.keydir_to_keylist(zone, server.identifier) ksks = [k for k in keys if k.is_ksk()] zsks = [k for k in keys if not k.is_ksk()] isctest.kasp.check_keys(zone, keys, expected) for kp in expected: + key = kp.key + # Set expected key timing metadata. kp.set_expected_keytimes(config) @@ -409,12 +417,19 @@ def check_rollover_step(server, config, policy, step): expected[suc].metadata["Predecessor"] = expected[prd].key.tag isctest.kasp.check_keyrelationships(keys, expected) + # Policy changes may retire keys, set expected timing metadata. + if kp.metadata["GoalState"] == "hidden" and "Retired" not in kp.timing: + retired = kp.key.get_timing("Inactive") + kp.timing["Retired"] = retired + kp.timing["Removed"] = retired + Iret( + config, zsk=key.is_zsk(), ksk=key.is_ksk() + ) + # Check that CDS publication/withdrawal is logged. if "KSK" not in kp.metadata: continue if kp.metadata["KSK"] == "no": continue - key = kp.key if ds_swap and kp.metadata["DSState"] == "rumoured": assert cdss is not None @@ -433,9 +448,11 @@ def check_rollover_step(server, config, policy, step): # delay, so set the DS withdraw time to now. server.rndc(f"dnssec -checkds -key {key.tag} withdrawn {zone}") - isctest.kasp.check_keytimes(keys, expected) + if check_keytimes: + isctest.kasp.check_keytimes(keys, expected) + isctest.kasp.check_dnssecstatus(server, zone, keys, policy=policy) - isctest.kasp.check_apex(server, zone, ksks, zsks, cdss=cdss) + isctest.kasp.check_apex(server, zone, ksks, zsks, cdss=cdss, cds_delete=cds_delete) isctest.kasp.check_subdomain(server, zone, ksks, zsks, smooth=smooth) def check_next_key_event(): @@ -1256,3 +1273,543 @@ def test_rollover_csk_roll2(servers): for step in steps: check_rollover_step(server, config, policy, step) + + +def test_rollover_policy_changes(servers): + server = servers["ns6"] + cdss = ["CDNSKEY", "CDS (SHA-256)"] + alg = os.environ["DEFAULT_ALGORITHM_NUMBER"] + size = os.environ["DEFAULT_BITS"] + + default_config = { + "dnskey-ttl": timedelta(hours=1), + "ds-ttl": timedelta(days=1), + "max-zone-ttl": timedelta(days=1), + "parent-propagation-delay": timedelta(hours=1), + "publish-safety": timedelta(hours=1), + "purge-keys": timedelta(days=90), + "retire-safety": timedelta(hours=1), + "signatures-refresh": timedelta(days=5), + "signatures-validity": timedelta(days=14), + "zone-propagation-delay": timedelta(seconds=300), + } + + unsigning_config = default_config.copy() + unsigning_config["dnskey-ttl"] = timedelta(seconds=7200) + + algoroll_config = { + "dnskey-ttl": timedelta(hours=1), + "ds-ttl": timedelta(seconds=7200), + "max-zone-ttl": timedelta(hours=6), + "parent-propagation-delay": timedelta(hours=1), + "publish-safety": timedelta(hours=1), + "purge-keys": timedelta(days=90), + "retire-safety": timedelta(hours=2), + "signatures-refresh": timedelta(days=5), + "signatures-validity": timedelta(days=30), + "zone-propagation-delay": timedelta(seconds=3600), + } + + start_time = KeyTimingMetadata.now() + + # Test dynamic zones that switch to inline-signing. + isctest.log.info("check dynamic zone that switches to inline-signing") + d2i = { + "zone": "dynamic2inline.kasp", + "cdss": cdss, + "config": default_config, + "policy": "default", + "keyprops": [ + f"csk unlimited {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured zrrsig:rumoured ds:hidden", + ], + "nextev": None, + } + steps = [d2i] + + # Test key lifetime changes. + isctest.log.info("check key lifetime changes are updated correctly") + lifetime = { + "P1Y": int(timedelta(days=365).total_seconds()), + "P6M": int(timedelta(days=31 * 6).total_seconds()), + "P60D": int(timedelta(days=60).total_seconds()), + } + lifetime_update_tests = [ + { + "zone": "shorter-lifetime", + "policy": "long-lifetime", + "lifetime": lifetime["P1Y"], + }, + { + "zone": "longer-lifetime", + "policy": "short-lifetime", + "lifetime": lifetime["P6M"], + }, + { + "zone": "limit-lifetime", + "policy": "unlimited-lifetime", + "lifetime": 0, + }, + { + "zone": "unlimit-lifetime", + "policy": "short-lifetime", + "lifetime": lifetime["P6M"], + }, + ] + for lut in lifetime_update_tests: + step = { + "zone": lut["zone"], + "cdss": cdss, + "config": default_config, + "policy": lut["policy"], + "keyprops": [ + f"csk {lut['lifetime']} {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured zrrsig:rumoured ds:hidden", + ], + "nextev": None, + } + steps.append(step) + + # Test going insecure. + isctest.log.info("check going insecure") + offset = -timedelta(days=10) + offval = int(offset.total_seconds()) + zones = [ + "step1.going-insecure.kasp", + "step1.going-insecure-dynamic.kasp", + ] + for zone in zones: + step = { + "zone": zone, + "cdss": cdss, + "config": unsigning_config, + "policy": "unsigning", + "keyprops": [ + f"ksk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{offval}", + f"zsk {lifetime['P60D']} {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{offval}", + ], + "nextev": None, + } + steps.append(step) + + # Test going straight to none. + isctest.log.info("check going straight to none") + zones = [ + "step1.going-straight-to-none.kasp", + "step1.going-straight-to-none-dynamic.kasp", + ] + for zone in zones: + step = { + "zone": zone, + "cdss": cdss, + "config": default_config, + "policy": "default", + "keyprops": [ + f"csk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{offval}", + ], + "nextev": None, + } + steps.append(step) + + # Test algorithm rollover (KSK/ZSK split). + isctest.log.info("check algorithm rollover ksk/zsk split") + offset = -timedelta(days=7) + offval = int(offset.total_seconds()) + step = { + "zone": "step1.algorithm-roll.kasp", + "cdss": cdss, + "config": algoroll_config, + "policy": "rsasha256", + "keyprops": [ + f"ksk 0 8 2048 goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{offval}", + f"zsk 0 8 2048 goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{offval}", + ], + "nextev": timedelta(hours=1), + } + steps.append(step) + + # Test algorithm rollover (CSK). + isctest.log.info("check algorithm rollover csk") + step = { + "zone": "step1.csk-algorithm-roll.kasp", + "cdss": cdss, + "config": algoroll_config, + "policy": "csk-algoroll", + "keyprops": [ + f"csk 0 8 2048 goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{offval}", + ], + "nextev": timedelta(hours=1), + } + steps.append(step) + + for step in steps: + check_rollover_step(server, step["config"], step["policy"], step) + + # Reconfigure, changing DNSSEC policies and other configuration options, + # triggering algorithm rollovers and other dnssec-policy changes. + shutil.copyfile("ns6/named2.conf", "ns6/named.conf") + server.rndc("reconfig") + # Calculate time passed to correctly check for next key events. + now = KeyTimingMetadata.now() + time_passed = now.value - start_time.value + + # Test dynamic zones that switch to inline-signing (after reconfig). + steps = [d2i] + + # Test key lifetime changes (after reconfig). + lifetime_update_tests = [ + { + "zone": "shorter-lifetime", + "policy": "short-lifetime", + "lifetime": lifetime["P6M"], + }, + { + "zone": "longer-lifetime", + "policy": "long-lifetime", + "lifetime": lifetime["P1Y"], + }, + { + "zone": "limit-lifetime", + "policy": "short-lifetime", + "lifetime": lifetime["P6M"], + }, + { + "zone": "unlimit-lifetime", + "policy": "unlimited-lifetime", + "lifetime": 0, + }, + ] + for lut in lifetime_update_tests: + step = { + "zone": lut["zone"], + "cdss": cdss, + "config": default_config, + "policy": lut["policy"], + "keyprops": [ + f"csk {lut['lifetime']} {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured zrrsig:rumoured ds:hidden", + ], + "nextev": None, + } + steps.append(step) + + # Test going insecure (after reconfig). + isctest.log.info("check going insecure (after reconfig)") + oldttl = unsigning_config["dnskey-ttl"] + offset = -timedelta(days=10) + offval = int(offset.total_seconds()) + zones = ["going-insecure.kasp", "going-insecure-dynamic.kasp"] + for parent in zones: + # Step 1. + # Key goal states should be HIDDEN. + # The DS may be removed if we are going insecure. + step = { + "zone": f"step1.{parent}", + "cdss": cdss, + "config": default_config, + "policy": "insecure", + "keyprops": [ + f"ksk 0 {alg} {size} goal:hidden dnskey:omnipresent krrsig:omnipresent ds:unretentive offset:{offval}", + f"zsk {lifetime['P60D']} {alg} {size} goal:hidden dnskey:omnipresent zrrsig:omnipresent offset:{offval}", + ], + # Next key event is when the DS becomes HIDDEN. This + # happens after the# parent propagation delay plus DS TTL. + "nextev": default_config["ds-ttl"] + + default_config["parent-propagation-delay"], + # Going insecure, check for CDS/CDNSKEY DELETE, and skip key timing checks. + "cds-delete": True, + "check-keytimes": False, + } + steps.append(step) + + # Step 2. + # The DS is long enough removed from the zone to be considered + # HIDDEN. This means the DNSKEY and the KSK signatures can be + # removed. + step = { + "zone": f"step2.{parent}", + "cdss": cdss, + "config": default_config, + "policy": "insecure", + "keyprops": [ + f"ksk 0 {alg} {size} goal:hidden dnskey:unretentive krrsig:unretentive ds:hidden offset:{offval}", + f"zsk {lifetime['P60D']} {alg} {size} goal:hidden dnskey:unretentive zrrsig:unretentive offset:{offval}", + ], + # Next key event is when the DNSKEY becomes HIDDEN. + # This happens after the propagation delay, plus DNSKEY TTL. + "nextev": oldttl + default_config["zone-propagation-delay"], + # Zone is no longer signed. + "zone-signed": False, + "check-keytimes": False, + } + steps.append(step) + + # Test going straight to none. + isctest.log.info("check going straight to none (after reconfig)") + zones = [ + "step1.going-straight-to-none.kasp", + "step1.going-straight-to-none-dynamic.kasp", + ] + for zone in zones: + step = { + "zone": zone, + "cdss": cdss, + "config": default_config, + "policy": None, + # These zones will go bogus after signatures expire, but + # remain validly signed for now. + "keyprops": [ + f"csk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{offval}", + ], + "nextev": None, + } + steps.append(step) + + # Test algorithm rollover (KSK/ZSK split) (after reconfig). + isctest.log.info("check algorithm rollover ksk/zsk split (after reconfig)") + offset = -timedelta(days=7) + offval = int(offset.total_seconds()) + ipub = Ipub(algoroll_config) + ipubc = IpubC(algoroll_config, rollover=False) + iret = Iret(algoroll_config, rollover=False) + iretKSK = Iret(algoroll_config, zsk=False, ksk=True, rollover=False) + keyttlprop = ( + algoroll_config["dnskey-ttl"] + algoroll_config["zone-propagation-delay"] + ) + offsets = {} + offsets["step2"] = -int(ipub.total_seconds()) + offsets["step3"] = -int(iret.total_seconds()) + offsets["step4"] = offsets["step3"] - int(iretKSK.total_seconds()) + offsets["step5"] = offsets["step4"] - int(keyttlprop.total_seconds()) + offsets["step6"] = offsets["step5"] - int(iret.total_seconds()) + algo_steps = [ + { + # Step 1. + "zone": "step1.algorithm-roll.kasp", + "cdss": cdss, + "config": algoroll_config, + "policy": "ecdsa256", + "keyprops": [ + # The RSASHA keys are outroducing. + f"ksk 0 8 2048 goal:hidden dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{offval}", + f"zsk 0 8 2048 goal:hidden dnskey:omnipresent zrrsig:omnipresent offset:{offval}", + # The ECDSAP256SHA256 keys are introducing. + f"ksk 0 {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured ds:hidden", + f"zsk 0 {alg} {size} goal:omnipresent dnskey:rumoured zrrsig:rumoured", + ], + # Next key event is when the ecdsa256 keys have been propagated. + "nextev": ipub, + }, + { + # Step 2. + "zone": "step2.algorithm-roll.kasp", + "cdss": cdss, + "config": algoroll_config, + "policy": "ecdsa256", + "keyprops": [ + # The RSASHA keys are outroducing, but need to stay present + # until the new algorithm chain of trust has been established. + # Thus the expected key states of these keys stay the same. + f"ksk 0 8 2048 goal:hidden dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{offval}", + f"zsk 0 8 2048 goal:hidden dnskey:omnipresent zrrsig:omnipresent offset:{offval}", + # The ECDSAP256SHA256 keys are introducing. The DNSKEY RRset is + # omnipresent, but the zone signatures are not. + f"ksk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:hidden offset:{offsets['step2']}", + f"zsk 0 {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:rumoured offset:{offsets['step2']}", + ], + # Next key event is when all zone signatures are signed with the new + # algorithm. This is the max-zone-ttl plus zone propagation delay. But + # the publication interval has already passed. Also, prevent intermittent + # false positives on slow platforms by subtracting the time passed between + # key creation and invoking 'rndc reconfig'. + "nextev": ipubc - ipub - time_passed, + }, + { + # Step 3. + "zone": "step3.algorithm-roll.kasp", + "cdss": cdss, + "config": algoroll_config, + "policy": "ecdsa256", + "keyprops": [ + # The DS can be swapped. + f"ksk 0 8 2048 goal:hidden dnskey:omnipresent krrsig:omnipresent ds:unretentive offset:{offval}", + f"zsk 0 8 2048 goal:hidden dnskey:omnipresent zrrsig:omnipresent offset:{offval}", + f"ksk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:rumoured offset:{offsets['step3']}", + f"zsk 0 {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{offsets['step3']}", + ], + # Next key event is when the DS becomes OMNIPRESENT. This happens + # after the retire interval. + "nextev": iretKSK - time_passed, + }, + { + # Step 4. + "zone": "step4.algorithm-roll.kasp", + "cdss": cdss, + "config": algoroll_config, + "policy": "ecdsa256", + "keyprops": [ + # The old DS is HIDDEN, we can remove the old algorithm records. + f"ksk 0 8 2048 goal:hidden dnskey:unretentive krrsig:unretentive ds:hidden offset:{offval}", + f"zsk 0 8 2048 goal:hidden dnskey:unretentive zrrsig:unretentive offset:{offval}", + f"ksk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{offsets['step4']}", + f"zsk 0 {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{offsets['step4']}", + ], + # Next key event is when the old DNSKEY becomes HIDDEN. + # This happens after the DNSKEY TTL plus zone propagation delay. + "nextev": keyttlprop, + }, + { + # Step 5. + "zone": "step5.algorithm-roll.kasp", + "cdss": cdss, + "config": algoroll_config, + "policy": "ecdsa256", + "keyprops": [ + # The DNSKEY becomes HIDDEN. + f"ksk 0 8 2048 goal:hidden dnskey:hidden krrsig:hidden ds:hidden offset:{offval}", + f"zsk 0 8 2048 goal:hidden dnskey:hidden zrrsig:unretentive offset:{offval}", + f"ksk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{offsets['step5']}", + f"zsk 0 {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{offsets['step5']}", + ], + # Next key event is when the RSASHA signatures become HIDDEN. + # This happens after the max-zone-ttl plus zone propagation delay + # minus the time already passed since the UNRETENTIVE state has + # been reached. Prevent intermittent false positives on slow + # platforms by subtracting the number of seconds which passed + # between key creation and invoking 'rndc reconfig'. + "nextev": iret - iretKSK - keyttlprop - time_passed, + }, + { + # Step 6. + "zone": "step6.algorithm-roll.kasp", + "cdss": cdss, + "config": algoroll_config, + "policy": "ecdsa256", + "keyprops": [ + # The zone signatures are now HIDDEN. + f"ksk 0 8 2048 goal:hidden dnskey:hidden krrsig:hidden ds:hidden offset:{offval}", + f"zsk 0 8 2048 goal:hidden dnskey:hidden zrrsig:hidden offset:{offval}", + f"ksk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{offsets['step6']}", + f"zsk 0 {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{offsets['step6']}", + ], + # Next key event is never since we established the policy and the + # keys have an unlimited lifetime. Fallback to the default + # loadkeys interval. + "nextev": timedelta(hours=1), + }, + ] + steps = steps + algo_steps + + # Test algorithm rollover (CSK) (after reconfig). + isctest.log.info("check algorithm rollover csk (after reconfig)") + offsets = {} + offsets["step2"] = -int(ipub.total_seconds()) + offsets["step3"] = -int(iret.total_seconds()) + offsets["step4"] = offsets["step3"] - int(iretKSK.total_seconds()) + offsets["step5"] = offsets["step4"] - int(keyttlprop.total_seconds()) + offsets["step6"] = offsets["step5"] - int(iret.total_seconds()) + algo_steps = [ + { + # Step 1. + "zone": "step1.csk-algorithm-roll.kasp", + "cdss": cdss, + "config": algoroll_config, + "policy": "csk-algoroll", + "keyprops": [ + # The RSASHA keys are outroducing. + f"csk 0 8 2048 goal:hidden dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{offval}", + # The ECDSAP256SHA256 keys are introducing. + f"csk 0 {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured zrrsig:rumoured ds:hidden", + ], + # Next key event is when the ecdsa256 keys have been propagated. + "nextev": ipub, + }, + { + # Step 2. + "zone": "step2.csk-algorithm-roll.kasp", + "cdss": cdss, + "config": algoroll_config, + "policy": "csk-algoroll", + "keyprops": [ + # The RSASHA keys are outroducing, but need to stay present + # until the new algorithm chain of trust has been established. + # Thus the expected key states of these keys stay the same. + f"csk 0 8 2048 goal:hidden dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{offval}", + # The ECDSAP256SHA256 keys are introducing. The DNSKEY RRset is + # omnipresent, but the zone signatures are not. + f"csk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:rumoured ds:hidden offset:{offsets['step2']}", + ], + # Next key event is when all zone signatures are signed with the + # new algorithm. This is the child publication interval, minus + # the publication interval has already passed. Also, prevent + # intermittent false positives on slow platforms by subtracting + # the time passed between key creation and invoking 'rndc reconfig'. + "nextev": ipubc - ipub - time_passed, + }, + { + # Step 3. + "zone": "step3.csk-algorithm-roll.kasp", + "cdss": cdss, + "config": algoroll_config, + "policy": "csk-algoroll", + "keyprops": [ + # The DS can be swapped. + f"csk 0 8 2048 goal:hidden dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:unretentive offset:{offval}", + f"csk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:rumoured offset:{offsets['step3']}", + ], + # Next key event is when the DS becomes OMNIPRESENT. This happens + # after the publication interval of the parent side. + "nextev": iretKSK - time_passed, + }, + { + # Step 4. + "zone": "step4.csk-algorithm-roll.kasp", + "cdss": cdss, + "config": algoroll_config, + "policy": "csk-algoroll", + "keyprops": [ + # The old DS is HIDDEN, we can remove the old algorithm records. + f"csk 0 8 2048 goal:hidden dnskey:unretentive krrsig:unretentive zrrsig:unretentive ds:hidden offset:{offval}", + f"csk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{offsets['step4']}", + ], + # Next key event is when the old DNSKEY becomes HIDDEN. + # This happens after the DNSKEY TTL plus zone propagation delay. + "nextev": keyttlprop, + }, + { + # Step 5. + "zone": "step5.csk-algorithm-roll.kasp", + "cdss": cdss, + "config": algoroll_config, + "policy": "csk-algoroll", + "keyprops": [ + # The DNSKEY becomes HIDDEN. + f"csk 0 8 2048 goal:hidden dnskey:hidden krrsig:hidden zrrsig:unretentive ds:hidden offset:{offval}", + f"csk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{offsets['step5']}", + ], + # Next key event is when the RSASHA signatures become HIDDEN. + # This happens after the max-zone-ttl plus zone propagation delay + # minus the time already passed since the UNRETENTIVE state has + # been reached. Prevent intermittent false positives on slow + # platforms by subtracting the number of seconds which passed + # between key creation and invoking 'rndc reconfig'. + "nextev": iret - iretKSK - keyttlprop - time_passed, + }, + { + # Step 6. + "zone": "step6.csk-algorithm-roll.kasp", + "cdss": cdss, + "config": algoroll_config, + "policy": "csk-algoroll", + "keyprops": [ + # The zone signatures are now HIDDEN. + f"csk 0 8 2048 goal:hidden dnskey:hidden krrsig:hidden zrrsig:hidden ds:hidden offset:{offval}", + f"csk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{offsets['step6']}", + ], + # Next key event is never since we established the policy and the + # keys have an unlimited lifetime. Fallback to the default + # loadkeys interval. + "nextev": timedelta(hours=1), + }, + ] + steps = steps + algo_steps + + for step in steps: + check_rollover_step(server, step["config"], step["policy"], step)