)
+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
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.
# 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
# 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
-
- for alg in ["SHA-256", "SHA-384"]:
- if f"CDS ({alg})" in cdss:
- numcds += check_cds(cdsrrs, ksks, alg)
- else:
- check_cds_prohibit(cdsrrs, ksks, alg)
+ if 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)
+
+ numcds = 0
+
+ for alg in ["SHA-256", "SHA-384"]:
+ if f"CDS ({alg})" in cdss:
+ numcds += check_cds(cdsrrs, ksks, alg)
+ else:
+ check_cds_prohibit(cdsrrs, ksks, alg)
- if len(cds) > 0:
- assert len(rrsigs) > 0
- check_signatures(
- rrsigs, dns.rdatatype.CDS, fqdn, ksks, zsks, offline_ksk=offline_ksk
- )
+ 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)
+ assert numcds == len(cdsrrs)
def check_subdomain(
file "../../_common/root.hint.blackhole";
};
-/* 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 "../../_common/root.hint.blackhole";
};
-/* 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.
*/
* 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;
};
O="OMNIPRESENT"
U="UNRETENTIVE"
-# 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.
# 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"
status=$((status + ret))
}
-#
-# 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.
#
};
};
+dnssec-policy "unsigning" {
+ dnskey-ttl 7200;
+
+ keys {
+ ksk key-directory lifetime unlimited algorithm @DEFAULT_ALGORITHM@;
+ zsk key-directory lifetime P60D algorithm @DEFAULT_ALGORITHM@;
+ };
+};
+
{% if RSASHA1_SUPPORTED == "1" %}
dnssec-policy "rsasha1" {
signatures-refresh P5D;
file "unlimit-lifetime.db";
dnssec-policy short-lifetime;
};
+
+/* 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; };
+};
file "unlimit-lifetime.db";
dnssec-policy unlimited-lifetime;
};
+
+/* 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; };
+};
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"
+ 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
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)
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
# 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():
"zone-propagation-delay": timedelta(seconds=300),
}
+ unsigning_config = default_config.copy()
+ unsigning_config["dnskey-ttl"] = timedelta(seconds=7200)
+
start_time = KeyTimingMetadata.now()
# Test dynamic zones that switch to inline-signing.
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 = [
{
}
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)
+
for step in steps:
check_rollover_step(server, step["config"], step["policy"], step)
}
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)
+
for step in steps:
check_rollover_step(server, step["config"], step["policy"], step)