From: Matthijs Mekking Date: Thu, 27 Nov 2025 13:36:07 +0000 (+0100) Subject: rollover-csk-roll2: From setup.sh to pytest bootstrap X-Git-Tag: v9.21.17~22^2~10 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ef7d617e3f6aa0395fca007cb60a903597743d1f;p=thirdparty%2Fbind9.git rollover-csk-roll2: From setup.sh to pytest bootstrap Similar to rollover-csk-roll1. --- diff --git a/bin/tests/system/rollover-csk-roll2/ns1 b/bin/tests/system/rollover-csk-roll2/ns1 new file mode 120000 index 00000000000..76608beaedd --- /dev/null +++ b/bin/tests/system/rollover-csk-roll2/ns1 @@ -0,0 +1 @@ +../rollover/ns1 \ No newline at end of file diff --git a/bin/tests/system/rollover-csk-roll2/ns2 b/bin/tests/system/rollover-csk-roll2/ns2 new file mode 120000 index 00000000000..41a09bb648b --- /dev/null +++ b/bin/tests/system/rollover-csk-roll2/ns2 @@ -0,0 +1 @@ +../rollover/ns2 \ No newline at end of file diff --git a/bin/tests/system/rollover-csk-roll2/ns3/kasp.conf.j2 b/bin/tests/system/rollover-csk-roll2/ns3/kasp.conf similarity index 90% rename from bin/tests/system/rollover-csk-roll2/ns3/kasp.conf.j2 rename to bin/tests/system/rollover-csk-roll2/ns3/kasp.conf index cf1708f3eba..30b96679c34 100644 --- a/bin/tests/system/rollover-csk-roll2/ns3/kasp.conf.j2 +++ b/bin/tests/system/rollover-csk-roll2/ns3/kasp.conf @@ -23,7 +23,7 @@ dnssec-policy "csk-roll2-autosign" { cds-digest-types { "sha-256"; "sha-384"; }; // use two digest type for testing purposes keys { - csk key-directory lifetime P6M algorithm @DEFAULT_ALGORITHM@; + csk key-directory lifetime P6M algorithm ecdsa256; }; zone-propagation-delay PT1H; @@ -47,7 +47,7 @@ dnssec-policy "csk-roll2-manual" { cds-digest-types { "sha-256"; "sha-384"; }; // use two digest type for testing purposes keys { - csk key-directory lifetime P6M algorithm @DEFAULT_ALGORITHM@; + csk key-directory lifetime P6M algorithm ecdsa256; }; zone-propagation-delay PT1H; diff --git a/bin/tests/system/rollover-csk-roll2/ns3/template.db.in b/bin/tests/system/rollover-csk-roll2/ns3/template.db.in deleted file mode 120000 index ce6d526285a..00000000000 --- a/bin/tests/system/rollover-csk-roll2/ns3/template.db.in +++ /dev/null @@ -1 +0,0 @@ -../../rollover/ns3/template.db.in \ No newline at end of file diff --git a/bin/tests/system/rollover-csk-roll2/ns3/template.db.j2.manual b/bin/tests/system/rollover-csk-roll2/ns3/template.db.j2.manual new file mode 120000 index 00000000000..38619a01b24 --- /dev/null +++ b/bin/tests/system/rollover-csk-roll2/ns3/template.db.j2.manual @@ -0,0 +1 @@ +../../rollover/ns3/template.db.j2.manual \ No newline at end of file diff --git a/bin/tests/system/rollover-csk-roll2/ns3/trusted.conf.j2 b/bin/tests/system/rollover-csk-roll2/ns3/trusted.conf.j2 new file mode 120000 index 00000000000..cb0be77b220 --- /dev/null +++ b/bin/tests/system/rollover-csk-roll2/ns3/trusted.conf.j2 @@ -0,0 +1 @@ +../../_common/trusted.conf.j2 \ No newline at end of file diff --git a/bin/tests/system/rollover-csk-roll2/setup.sh b/bin/tests/system/rollover-csk-roll2/setup.sh deleted file mode 100644 index da1e2d8bfe0..00000000000 --- a/bin/tests/system/rollover-csk-roll2/setup.sh +++ /dev/null @@ -1,301 +0,0 @@ -#!/bin/sh -e - -# 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. - -# shellcheck source=conf.sh -. ../conf.sh - -cd "ns3" - -setup() { - zone="$1" - echo_i "setting up zone: $zone" - zonefile="${zone}.db" - infile="${zone}.db.infile" - echo "$zone" >>zones -} - -# Set in the key state files the Predecessor/Successor fields. -# Key $1 is the predecessor of key $2. -key_successor() { - id1=$(keyfile_to_key_id "$1") - id2=$(keyfile_to_key_id "$2") - echo "Predecessor: ${id1}" >>"${2}.state" - echo "Successor: ${id2}" >>"${1}.state" -} - -# Make lines shorter by storing key states in environment variables. -H="HIDDEN" -R="RUMOURED" -O="OMNIPRESENT" -U="UNRETENTIVE" - -# -# The zones at csk-roll2.$tld represent the various steps of a CSK rollover -# (which is essentially a ZSK Pre-Publication / KSK Double-KSK rollover). -# This scenario differs from the csk-roll1 one because the zone signatures (ZRRSIG) -# are replaced with the new key sooner than the DS is swapped. -# - -for tld in autosign manual; do - # Step 1: - # Introduce the first key. This will immediately be active. - setup step1.csk-roll2.$tld - TactN="now-7d" - keytimes="-P ${TactN} -A ${TactN}" - CSK=$($KEYGEN -k csk-roll2-$tld -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1) - $SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN -z $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 -G "cdnskey,cds:sha-256,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - - # Step 2: - # It is time to introduce the new CSK. - setup step2.csk-roll2.$tld - # According to RFC 7583: - # KSK: Tpub(N+1) <= Tact(N) + Lksk - IpubC - # ZSK: Tpub(N+1) <= Tact(N) + Lzsk - Ipub - # IpubC = DprpC + TTLkey (+publish-safety) - # Ipub = IpubC - # Lcsk = Lksk = Lzsk - # - # Lcsk: 6mo (186d, 4464h) - # Dreg: N/A - # DprpC: 1h - # TTLkey: 1h - # publish-safety: 1h - # Ipub: 3h - # - # Tact(N) = now - Lcsk + Ipub = now - 186d + 3h - # = now - 4464h + 3h = now - 4461h - TactN="now-4461h" - keytimes="-P ${TactN} -A ${TactN}" - CSK=$($KEYGEN -k csk-roll2-$tld -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1) - $SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN -z $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 -G "cdnskey,cds:sha-256,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - - # Step 3: - # It is time to submit the DS and to roll signatures. - setup step3.csk-roll2.$tld - # According to RFC 7583: - # - # Tsbm(N+1) >= Trdy(N+1) - # KSK: Tact(N+1) = Tsbm(N+1) - # ZSK: Tact(N+1) = Tpub(N+1) + Ipub = Tsbm(N+1) - # KSK: Iret = DprpP + TTLds (+retire-safety) - # ZSK: IretZ = Dsgn + Dprp + TTLsig (+retire-safety) - # - # Lcsk: 186d - # Dprp: 1h - # DprpP: 1w - # Dreg: N/A - # Dsgn: 12h - # TTLds: 1h - # TTLsig: 1d - # retire-safety: 1h - # Iret: 170h - # IretZ: 38h - # Ipub: 3h - # - # Tpub(N) = now - Lcsk = now - 186d - # Tact(N) = now - Lcsk + Dprp + TTLsig = now - 4439h - # Tret(N) = now - # Trem(N) = now + Iret = now + 170h - # Tpub(N+1) = now - Ipub = now - 3h - # Tact(N+1) = Tret(N) - # Tret(N+1) = now + Lcsk = now + 186d - # Trem(N+1) = now + Lcsk + Iret = now + 186d + 170h = - # = now + 4464h + 170h = now + 4634h - TpubN="now-186d" - TactN="now-4439h" - TretN="now" - TremN="now+170h" - TpubN1="now-3h" - TactN1="${TretN}" - TretN1="now+186d" - TremN1="now+4634h" - keytimes="-P ${TpubN} -P sync ${TactN} -A ${TpubN} -I ${TretN} -D ${TremN} -D sync ${TactN1}" - newtimes="-P ${TpubN1} -P sync ${TactN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}" - CSK1=$($KEYGEN -k csk-roll2-$tld -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1) - CSK2=$($KEYGEN -k csk-roll2-$tld -l kasp.conf $newtimes $zone 2>keygen.out.$zone.2) - $SETTIME -s -g $H -k $O $TactN -r $O $TactN -d $O $TactN -z $O $TactN "$CSK1" >settime.out.$zone.1 2>&1 - $SETTIME -s -g $O -k $R $TpubN1 -r $R $TpubN1 -d $H $TpubN1 -z $H $TpubN1 "$CSK2" >settime.out.$zone.2 2>&1 - # Set key rollover relationship. - key_successor $CSK1 $CSK2 - # Sign zone. - cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >>"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" - cp $infile $zonefile - $SIGNER -S -z -x -G "cdnskey,cds:sha-256,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - - # Step 4: - # Some time later all the ZRRSIG records should be from the new CSK, and the - # DS should be swapped. The ZRRSIG records are all replaced after IretZ (38h). - # The DS is swapped after Dreg + Iret (1w3h). In other words, the zone - # signatures are replaced before the DS is swapped. - setup step4.csk-roll2.$tld - # According to RFC 7583: - # Trem(N) = Tret(N) + IretZ - # - # Lcsk: 186d - # Dreg: N/A - # Iret: 170h - # IretZ: 38h - # - # Tpub(N) = now - IretZ - Lcsk = now - 38h - 186d - # = now - 38h - 4464h = now - 4502h - # Tact(N) = now - Iret - Lcsk + TTLsig = now - 4502h + 25h = now - 4477h - # Tret(N) = now - IretZ = now - 38h - # Trem(N) = now - IretZ + Iret = now - 38h + 170h = now + 132h - # Tpub(N+1) = now - IretZ - IpubC = now - 38h - 3h = now - 41h - # Tact(N+1) = Tret(N) - # Tret(N+1) = now - IretZ + Lcsk = now - 38h + 186d - # = now + 4426h - # Trem(N+1) = now - IretZ + Lcsk + Iret - # = now + 4426h + 3h = now + 4429h - TpubN="now-4502h" - TactN="now-4477h" - TretN="now-38h" - TremN="now+132h" - TpubN1="now-41h" - TactN1="${TretN}" - TretN1="now+4426h" - TremN1="now+4429h" - keytimes="-P ${TpubN} -P sync ${TactN} -A ${TpubN} -I ${TretN} -D ${TremN} -D sync ${TactN1}" - newtimes="-P ${TpubN1} -P sync ${TactN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}" - CSK1=$($KEYGEN -k csk-roll2-$tld -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1) - CSK2=$($KEYGEN -k csk-roll2-$tld -l kasp.conf $newtimes $zone 2>keygen.out.$zone.2) - $SETTIME -s -g $H -k $O $TactN -r $O $TactN -z $U $TretN -d $U $TactN1 -D ds $TactN1 "$CSK1" >settime.out.$zone.1 2>&1 - $SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -z $R $TactN1 -d $R $TactN1 -P ds $TactN1 "$CSK2" >settime.out.$zone.2 2>&1 - # Set key rollover relationship. - key_successor $CSK1 $CSK2 - # Sign zone. - cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >>"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" - cp $infile $zonefile - $SIGNER -S -z -x -G "cdnskey,cds:sha-256,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - - # Step 5: - # Some time later the DS can be swapped and the old DNSKEY can be removed from - # the zone. - setup step5.csk-roll2.$tld - # Subtract Iret (170h) - IretZ (38h) = 132h. - # - # Tpub(N) = now - 4502h - 132h = now - 4634h - # Tact(N) = now - 4477h - 132h = now - 4609h - # Tret(N) = now - 38h - 132h = now - 170h - # Trem(N) = now + 132h - 132h = now - # Tpub(N+1) = now - 41h - 132h = now - 173h - # Tact(N+1) = Tret(N) - # Tret(N+1) = now + 4426h - 132h = now + 4294h - # Trem(N+1) = now + 4492h - 132h = now + 4360h - TpubN="now-4634h" - TactN="now-4609h" - TretN="now-170h" - TremN="now" - TpubN1="now-173h" - TactN1="${TretN}" - TretN1="now+4294h" - TremN1="now+4360h" - keytimes="-P ${TpubN} -P sync ${TactN} -A ${TpubN} -I ${TretN} -D ${TremN} -D sync ${TactN1}" - newtimes="-P ${TpubN1} -P sync ${TactN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}" - CSK1=$($KEYGEN -k csk-roll2-$tld -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1) - CSK2=$($KEYGEN -k csk-roll2-$tld -l kasp.conf $newtimes $zone 2>keygen.out.$zone.2) - $SETTIME -s -g $H -k $O $TactN -r $O $TactN -z $H now-133h -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 now-133h -d $R $TactN1 -P ds $TactN1 "$CSK2" >settime.out.$zone.2 2>&1 - # Set key rollover relationship. - key_successor $CSK1 $CSK2 - # Sign zone. - cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >>"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" - cp $infile $zonefile - $SIGNER -S -z -x -G "cdnskey,cds:sha-256,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - - # Step 6: - # Some time later the predecessor DNSKEY enters the HIDDEN state. - setup step6.csk-roll2.$tld - # Subtract DNSKEY TTL plus zone propagation delay (2h). - # - # Tpub(N) = now - 4634h - 2h = now - 4636h - # Tact(N) = now - 4609h - 2h = now - 4611h - # Tret(N) = now - 170h - 2h = now - 172h - # Trem(N) = now - 2h - # Tpub(N+1) = now - 173h - 2h = now - 175h - # Tact(N+1) = Tret(N) - # Tret(N+1) = now + 4294h - 2h = now + 4292h - # Trem(N+1) = now + 4360h - 2h = now + 4358h - TpubN="now-4636h" - TactN="now-4611h" - TretN="now-172h" - TremN="now-2h" - TpubN1="now-175h" - TactN1="${TretN}" - TretN1="now+4292h" - TremN1="now+4358h" - keytimes="-P ${TpubN} -P sync ${TactN} -A ${TpubN} -I ${TretN} -D ${TremN} -D sync ${TactN1}" - newtimes="-P ${TpubN1} -P sync ${TactN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}" - CSK1=$($KEYGEN -k csk-roll2-$tld -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1) - CSK2=$($KEYGEN -k csk-roll2-$tld -l kasp.conf $newtimes $zone 2>keygen.out.$zone.2) - $SETTIME -s -g $H -k $U $TremN -r $U $TremN -d $H $TremN -z $H now-135h "$CSK1" >settime.out.$zone.1 2>&1 - $SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $O $TremN -z $O now-135h "$CSK2" >settime.out.$zone.2 2>&1 - # Set key rollover relationship. - key_successor $CSK1 $CSK2 - # Sign zone. - cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >>"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" - cp $infile $zonefile - $SIGNER -S -z -x -G "cdnskey,cds:sha-256,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - - # Step 7: - # The predecessor DNSKEY can be purged, but purge-keys is disabled. - setup step7.csk-roll2.$tld - # Subtract 90 days (default, 2160h) from all the times. - # - # Tpub(N) = now - 4636h - 2160h = now - 6796h - # Tact(N) = now - 4611h - 2160h = now - 6771h - # Tret(N) = now - 172h - 2160h = now - 2332h - # Trem(N) = now - 2h - 2160h = now - 2162h - # Tpub(N+1) = now - 175h - 2160h = now - 2335h - # Tact(N+1) = Tret(N) - # Tret(N+1) = now + 4292h - 2160h = now + 2132h - # Trem(N+1) = now + 4358h - 2160h = now + 2198h - TpubN="now-6796h" - TactN="now-6771h" - TretN="now-2332h" - TremN="now-2162h" - TpubN1="now-2335h" - TactN1="${TretN}" - TretN1="now+2132h" - TremN1="now+2198h" - keytimes="-P ${TpubN} -P sync ${TactN} -A ${TpubN} -I ${TretN} -D ${TremN} -D sync ${TactN1}" - newtimes="-P ${TpubN1} -P sync ${TactN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}" - CSK1=$($KEYGEN -k csk-roll2-$tld -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1) - CSK2=$($KEYGEN -k csk-roll2-$tld -l kasp.conf $newtimes $zone 2>keygen.out.$zone.2) - $SETTIME -s -g $H -k $U $TremN -r $U $TremN -d $H $TremN -z $H now-135h "$CSK1" >settime.out.$zone.1 2>&1 - $SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $O $TremN -z $O now-135h "$CSK2" >settime.out.$zone.2 2>&1 - # Set key rollover relationship. - key_successor $CSK1 $CSK2 - # Sign zone. - cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >>"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" - cp $infile $zonefile - $SIGNER -S -z -x -G "cdnskey,cds:sha-256,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 -done diff --git a/bin/tests/system/rollover-csk-roll2/tests_rollover_csk_roll2.py b/bin/tests/system/rollover-csk-roll2/tests_rollover_csk_roll2.py index 5a3ae2205f4..529fd836eef 100644 --- a/bin/tests/system/rollover-csk-roll2/tests_rollover_csk_roll2.py +++ b/bin/tests/system/rollover-csk-roll2/tests_rollover_csk_roll2.py @@ -24,7 +24,11 @@ from rollover.common import ( size, TIMEDELTA, ) - +from rollover.setup import ( + configure_root, + configure_tld, + configure_cskroll2, +) CDSS = ["CDNSKEY", "CDS (SHA-256)", "CDS (SHA-384)"] CONFIG = { @@ -68,6 +72,30 @@ OFFSETS["step7-p"] = OFFSETS["step6-p"] - int(timedelta(days=90).total_seconds() OFFSETS["step7-s"] = OFFSETS["step6-s"] - int(timedelta(days=90).total_seconds()) +def bootstrap(): + data = { + "tlds": [], + "trust_anchors": [], + } + + tlds = [] + for tld_name in [ + "autosign", + "manual", + ]: + delegations = configure_cskroll2(tld_name, f"{POLICY}-{tld_name}") + + tld = configure_tld(tld_name, delegations) + tlds.append(tld) + + data["tlds"].append(tld_name) + + ta = configure_root(tlds) + data["trust_anchors"].append(ta) + + return data + + @pytest.mark.parametrize( "tld", [ diff --git a/bin/tests/system/rollover/setup.py b/bin/tests/system/rollover/setup.py index c2cacdb2009..2d7f178ca17 100644 --- a/bin/tests/system/rollover/setup.py +++ b/bin/tests/system/rollover/setup.py @@ -528,6 +528,7 @@ def configure_cskroll1(tld: str, policy: str) -> List[Zone]: # (which is essentially a ZSK Pre-Publication / KSK Double-KSK rollover). zones = [] zone = f"csk-roll1.{tld}" + cds = "cdnskey,cds:sha384" keygen = CmdHelper("KEYGEN", f"-k {policy} -l kasp.conf") settime = CmdHelper("SETTIME", "-s") @@ -545,7 +546,7 @@ def configure_cskroll1(tld: str, policy: str) -> List[Zone]: cwd="ns3", ) # Signing. - render_and_sign_zone(zonename, [csk_name], extra_options="-z -G cdnskey,cds:sha384") + render_and_sign_zone(zonename, [csk_name], extra_options=f"-z -G {cds}") # Step 2: # It is time to introduce the new CSK. @@ -577,7 +578,7 @@ def configure_cskroll1(tld: str, policy: str) -> List[Zone]: cwd="ns3", ) # Signing. - render_and_sign_zone(zonename, [csk_name], extra_options="-z -G cdnskey,cds:sha384") + render_and_sign_zone(zonename, [csk_name], extra_options=f"-z -G {cds}") # Step 3: # It is time to submit the DS and to roll signatures. @@ -639,9 +640,7 @@ def configure_cskroll1(tld: str, policy: str) -> List[Zone]: # Set key rollover relationship. set_key_relationship(csk1_name, csk2_name) # Signing. - render_and_sign_zone( - zonename, [csk1_name, csk2_name], extra_options="-z -G cdnskey,cds:sha384" - ) + render_and_sign_zone(zonename, [csk1_name, csk2_name], extra_options=f"-z -G {cds}") # Step 4: # Some time later all the ZRRSIG records should be from the new CSK, and the @@ -694,9 +693,7 @@ def configure_cskroll1(tld: str, policy: str) -> List[Zone]: # Set key rollover relationship. set_key_relationship(csk1_name, csk2_name) # Signing. - render_and_sign_zone( - zonename, [csk1_name, csk2_name], extra_options="-z -G cdnskey,cds:sha384" - ) + render_and_sign_zone(zonename, [csk1_name, csk2_name], extra_options=f"-z -G {cds}") # Step 5: # After the DS is swapped in step 4, also the KRRSIG records can be removed. @@ -731,9 +728,7 @@ def configure_cskroll1(tld: str, policy: str) -> List[Zone]: # Set key rollover relationship. set_key_relationship(csk1_name, csk2_name) # Signing. - render_and_sign_zone( - zonename, [csk1_name, csk2_name], extra_options="-z -G cdnskey,cds:sha384" - ) + render_and_sign_zone(zonename, [csk1_name, csk2_name], extra_options=f"-z -G {cds}") # Step 6: # After the retire interval has passed the predecessor DNSKEY can be @@ -784,9 +779,7 @@ def configure_cskroll1(tld: str, policy: str) -> List[Zone]: # Set key rollover relationship. set_key_relationship(csk1_name, csk2_name) # Signing. - render_and_sign_zone( - zonename, [csk1_name, csk2_name], extra_options="-z -G cdnskey,cds:sha384" - ) + render_and_sign_zone(zonename, [csk1_name, csk2_name], extra_options=f"-z -G {cds}") # Step 7: # Some time later the predecessor DNSKEY enters the HIDDEN state. @@ -820,9 +813,7 @@ def configure_cskroll1(tld: str, policy: str) -> List[Zone]: # Set key rollover relationship. set_key_relationship(csk1_name, csk2_name) # Signing. - render_and_sign_zone( - zonename, [csk1_name, csk2_name], extra_options="-z -G cdnskey,cds:sha384" - ) + render_and_sign_zone(zonename, [csk1_name, csk2_name], extra_options=f"-z -G {cds}") # Step 8: # The predecessor DNSKEY can be purged. @@ -856,8 +847,350 @@ def configure_cskroll1(tld: str, policy: str) -> List[Zone]: # Set key rollover relationship. set_key_relationship(csk1_name, csk2_name) # Signing. - render_and_sign_zone( - zonename, [csk1_name, csk2_name], extra_options="-z -G cdnskey,cds:sha384" + render_and_sign_zone(zonename, [csk1_name, csk2_name], extra_options=f"-z -G {cds}") + + return zones + + +def configure_cskroll2(tld: str, policy: str) -> List[Zone]: + # The zones at csk-roll2.$tld represent the various steps of a CSK rollover + # (which is essentially a ZSK Pre-Publication / KSK Double-KSK rollover). + # This scenario differs from the csk-roll1 one because the zone signatures (ZRRSIG) + # are replaced with the new key sooner than the DS is swapped. + zones = [] + zone = f"csk-roll2.{tld}" + cds = "cdnskey,cds:sha-256,cds:sha-384" + keygen = CmdHelper("KEYGEN", f"-k {policy} -l kasp.conf") + settime = CmdHelper("SETTIME", "-s") + + # Step 1: + # Introduce the first key. This will immediately be active. + zonename = f"step1.{zone}" + zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3"))) + isctest.log.info(f"setup {zonename}") + TactN = "now-7d" + keytimes = f"-P {TactN} -A {TactN}" + # Key generation. + csk_name = keygen(f"{keytimes} {zonename}", cwd="ns3").strip() + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -z OMNIPRESENT {TactN} -d OMNIPRESENT {TactN} {csk_name}", + cwd="ns3", + ) + # Signing. + render_and_sign_zone(zonename, [csk_name], extra_options=f"-z -G {cds}") + + # Step 2: + # It is time to introduce the new CSK. + zonename = f"step2.{zone}" + zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3"))) + isctest.log.info(f"setup {zonename}") + # According to RFC 7583: + # KSK: Tpub(N+1) <= Tact(N) + Lksk - IpubC + # ZSK: Tpub(N+1) <= Tact(N) + Lzsk - Ipub + # IpubC = DprpC + TTLkey (+publish-safety) + # Ipub = IpubC + # Lcsk = Lksk = Lzsk + # + # Lcsk: 6mo (186d, 4464h) + # Dreg: N/A + # DprpC: 1h + # TTLkey: 1h + # publish-safety: 1h + # Ipub: 3h + # + # Tact(N) = now - Lcsk + Ipub = now - 186d + 3h + # = now - 4464h + 3h = now - 4461h + TactN = "now-4461h" + keytimes = f"-P {TactN} -A {TactN}" + # Key generation. + csk_name = keygen(f"{keytimes} {zonename}", cwd="ns3").strip() + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -z OMNIPRESENT {TactN} -d OMNIPRESENT {TactN} {csk_name}", + cwd="ns3", + ) + # Signing. + render_and_sign_zone(zonename, [csk_name], extra_options=f"-z -G {cds}") + + # Step 3: + # It is time to submit the DS and to roll signatures. + zonename = f"step3.{zone}" + zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3"))) + isctest.log.info(f"setup {zonename}") + # According to RFC 7583: + # + # Tsbm(N+1) >= Trdy(N+1) + # KSK: Tact(N+1) = Tsbm(N+1) + # ZSK: Tact(N+1) = Tpub(N+1) + Ipub = Tsbm(N+1) + # KSK: Iret = DprpP + TTLds (+retire-safety) + # ZSK: IretZ = Dsgn + Dprp + TTLsig (+retire-safety) + # + # Lcsk: 186d + # Dprp: 1h + # DprpP: 1w + # Dreg: N/A + # Dsgn: 12h + # TTLds: 1h + # TTLsig: 1d + # retire-safety: 1h + # Iret: 170h + # IretZ: 38h + # Ipub: 3h + # + # Tpub(N) = now - Lcsk = now - 186d + # Tact(N) = now - Lcsk + Dprp + TTLsig = now - 4439h + # Tret(N) = now + # Trem(N) = now + IretZ = now + 26d3h = now + 627h + # Tpub(N+1) = now - Ipub = now - 3h + # Tact(N+1) = Tret(N) + # Tret(N+1) = now + Lcsk = now + 186d = now + 186d + # Trem(N+1) = now + Lcsk + IretZ = now + 186d + 26d3h = + # = now + 5091h + TpubN = "now-186d" + TactN = "now-4439h" + TretN = "now" + TremN = "now+170h" + TpubN1 = "now-3h" + TactN1 = TretN + TretN1 = "now+186d" + TremN1 = "now+4634h" + keytimes = ( + f"-P {TpubN} -P sync {TactN} -A {TpubN} -I {TretN} -D {TremN} -D sync {TactN1}" + ) + newtimes = f"-P {TpubN1} -P sync {TactN1} -A {TactN1} -I {TretN1} -D {TremN1}" + # Key generation. + csk1_name = keygen(f"{keytimes} {zonename}", cwd="ns3").strip() + csk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").strip() + settime( + f"-g HIDDEN -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -z OMNIPRESENT {TactN} -d OMNIPRESENT {TactN} {csk1_name}", + cwd="ns3", + ) + settime( + f"-g OMNIPRESENT -k RUMOURED {TpubN1} -r RUMOURED {TpubN1} -z HIDDEN {TpubN1} -d HIDDEN {TpubN1} {csk2_name}", + cwd="ns3", + ) + # Set key rollover relationship. + set_key_relationship(csk1_name, csk2_name) + # Signing. + render_and_sign_zone(zonename, [csk1_name, csk2_name], extra_options=f"-z -G {cds}") + + # Step 4: + # Some time later all the ZRRSIG records should be from the new CSK, and the + # DS should be swapped. The ZRRSIG records are all replaced after IretZ (38h). + # The DS is swapped after Dreg + Iret (1w3h). In other words, the zone + # signatures are replaced before the DS is swapped. + zonename = f"step4.{zone}" + zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3"))) + isctest.log.info(f"setup {zonename}") + # According to RFC 7583: + # Trem(N) = Tret(N) + IretZ + # + # Lcsk: 186d + # Dreg: N/A + # Iret: 170h + # IretZ: 38h + # + # Tpub(N) = now - IretZ - Lcsk = now - 38h - 186d + # = now - 38h - 4464h = now - 4502h + # Tact(N) = now - Iret - Lcsk + TTLsig = now - 4502h + 25h = now - 4477h + # Tret(N) = now - IretZ = now - 38h + # Trem(N) = now - IretZ + Iret = now - 38h + 170h = now + 132h + # Tpub(N+1) = now - IretZ - IpubC = now - 38h - 3h = now - 41h + # Tact(N+1) = Tret(N) + # Tret(N+1) = now - IretZ + Lcsk = now - 38h + 186d + # = now + 4426h + # Trem(N+1) = now - IretZ + Lcsk + Iret + # = now + 4426h + 3h = now + 4429h + TpubN = "now-4502h" + TactN = "now-4477h" + TretN = "now-38h" + TremN = "now+132h" + TpubN1 = "now-41h" + TactN1 = TretN + TretN1 = "now+4426h" + TremN1 = "now+4429h" + keytimes = ( + f"-P {TpubN} -P sync {TactN} -A {TpubN} -I {TretN} -D {TremN} -D sync {TactN1}" + ) + newtimes = f"-P {TpubN1} -P sync {TactN1} -A {TactN1} -I {TretN1} -D {TremN1}" + # Key generation. + csk1_name = keygen(f"{keytimes} {zonename}", cwd="ns3").strip() + csk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").strip() + settime( + f"-g HIDDEN -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -z UNRETENTIVE {TretN} -d UNRETENTIVE {TretN} -D ds {TretN} {csk1_name}", + cwd="ns3", + ) + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TactN1} -r OMNIPRESENT {TactN1} -z RUMOURED {TactN1} -d RUMOURED {TactN1} -P ds {TactN1} {csk2_name}", + cwd="ns3", + ) + # Set key rollover relationship. + set_key_relationship(csk1_name, csk2_name) + # Signing. + render_and_sign_zone(zonename, [csk1_name, csk2_name], extra_options=f"-z -G {cds}") + + # Step 5: + # Some time later the DS can be swapped and the old DNSKEY can be removed from + # the zone. + zonename = f"step5.{zone}" + zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3"))) + isctest.log.info(f"setup {zonename}") + # Subtract Iret (170h) - IretZ (38h) = 132h. + # + # Tpub(N) = now - 4502h - 132h = now - 4634h + # Tact(N) = now - 4477h - 132h = now - 4609h + # Tret(N) = now - 38h - 132h = now - 170h + # Trem(N) = now + 132h - 132h = now + # Tpub(N+1) = now - 41h - 132h = now - 173h + # Tact(N+1) = Tret(N) + # Tret(N+1) = now + 4426h - 132h = now + 4294h + # Trem(N+1) = now + 4492h - 132h = now + 4360h + TpubN = "now-4634h" + TactN = "now-4609h" + TretN = "now-170h" + TremN = "now" + TpubN1 = "now-173h" + TactN1 = TretN + TretN1 = "now+4294h" + TremN1 = "now+4360h" + keytimes = ( + f"-P {TpubN} -P sync {TactN} -A {TpubN} -I {TretN} -D {TremN} -D sync {TactN1}" + ) + newtimes = f"-P {TpubN1} -P sync {TactN1} -A {TactN1} -I {TretN1} -D {TremN1}" + # Key generation. + csk1_name = keygen(f"{keytimes} {zonename}", cwd="ns3").strip() + csk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").strip() + settime( + f"-g HIDDEN -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -z HIDDEN now-133h -d UNRETENTIVE {TactN1} -D ds {TactN1} {csk1_name}", + cwd="ns3", + ) + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TactN1} -r OMNIPRESENT {TactN1} -z OMNIPRESENT now-133h -d RUMOURED {TactN1} -P ds {TactN1} {csk2_name}", + cwd="ns3", + ) + # Set key rollover relationship. + set_key_relationship(csk1_name, csk2_name) + # Signing. + render_and_sign_zone(zonename, [csk1_name, csk2_name], extra_options=f"-z -G {cds}") + + # Step 6: + # Some time later the predecessor DNSKEY enters the HIDDEN state. + zonename = f"step6.{zone}" + zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3"))) + isctest.log.info(f"setup {zonename}") + # Subtract DNSKEY TTL plus zone propagation delay (2h). + # + # Tpub(N) = now - 4634h - 2h = now - 4636h + # Tact(N) = now - 4609h - 2h = now - 4611h + # Tret(N) = now - 170h - 2h = now - 172h + # Trem(N) = now - 2h + # Tpub(N+1) = now - 173h - 2h = now - 175h + # Tact(N+1) = Tret(N) + # Tret(N+1) = now + 4294h - 2h = now + 4292h + # Trem(N+1) = now + 4360h - 2h = now + 4358h + TpubN = "now-4636h" + TactN = "now-4611h" + TretN = "now-172h" + TremN = "now-2h" + TpubN1 = "now-175h" + TactN1 = TretN + TretN1 = "now+4292h" + TremN1 = "now+4358h" + keytimes = ( + f"-P {TpubN} -P sync {TactN} -A {TpubN} -I {TretN} -D {TremN} -D sync {TactN1}" ) + newtimes = f"-P {TpubN1} -P sync {TactN1} -A {TactN1} -I {TretN1} -D {TremN1}" + # Key generation. + csk1_name = keygen(f"{keytimes} {zonename}", cwd="ns3").strip() + csk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").strip() + settime( + f"-g HIDDEN -k UNRETENTIVE {TremN} -r UNRETENTIVE {TremN} -z HIDDEN now-135h -d HIDDEN {TremN} {csk1_name}", + cwd="ns3", + ) + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TactN1} -r OMNIPRESENT {TactN1} -z OMNIPRESENT now-135h -d OMNIPRESENT {TremN} {csk2_name}", + cwd="ns3", + ) + # Set key rollover relationship. + set_key_relationship(csk1_name, csk2_name) + # Signing. + render_and_sign_zone(zonename, [csk1_name, csk2_name], extra_options=f"-z -G {cds}") + + # Step 7: + # The predecessor DNSKEY can be purged, but purge-keys is disabled. + zonename = f"step7.{zone}" + zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3"))) + isctest.log.info(f"setup {zonename}") + # Subtract 90 days (default, 2160h) from all the times. + # + # Tpub(N) = now - 4636h - 2160h = now - 6796h + # Tact(N) = now - 4611h - 2160h = now - 6771h + # Tret(N) = now - 172h - 2160h = now - 2332h + # Trem(N) = now - 2h - 2160h = now - 2162h + # Tpub(N+1) = now - 175h - 2160h = now - 2335h + # Tact(N+1) = Tret(N) + # Tret(N+1) = now + 4292h - 2160h = now + 2132h + # Trem(N+1) = now + 4358h - 2160h = now + 2198h + TpubN = "now-6796h" + TactN = "now-6771h" + TretN = "now-2332h" + TremN = "now-2162h" + TpubN1 = "now-2335h" + TactN1 = TretN + TretN1 = "now+2132h" + TremN1 = "now+2198h" + + keytimes = ( + f"-P {TpubN} -P sync {TactN} -A {TpubN} -I {TretN} -D {TremN} -D sync {TactN1}" + ) + newtimes = f"-P {TpubN1} -P sync {TactN1} -A {TactN1} -I {TretN1} -D {TremN1}" + # Key generation. + csk1_name = keygen(f"{keytimes} {zonename}", cwd="ns3").strip() + csk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").strip() + settime( + f"-g HIDDEN -k UNRETENTIVE {TremN} -r HIDDEN {TremN} -z HIDDEN {TactN1} -d HIDDEN {TremN} {csk1_name}", + cwd="ns3", + ) + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TactN1} -r OMNIPRESENT {TactN1} -z OMNIPRESENT {TactN1} -d OMNIPRESENT {TremN} {csk2_name}", + cwd="ns3", + ) + # Set key rollover relationship. + set_key_relationship(csk1_name, csk2_name) + # Signing. + render_and_sign_zone(zonename, [csk1_name, csk2_name], extra_options=f"-z -G {cds}") + + # Step 8: + # The predecessor DNSKEY can be purged. + zonename = f"step8.{zone}" + zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3"))) + isctest.log.info(f"setup {zonename}") + # Subtract purge-keys interval from all the times (1h). + TpubN = "now-5094h" + TactN = "now-5069h" + TretN = "now-630h" + TremN = "now-3h" + TpubN1 = "now-633h" + TactN1 = TretN + TretN1 = "now+3834h" + TremN1 = "now+4461h" + keytimes = ( + f"-P {TpubN} -P sync {TactN} -A {TpubN} -I {TretN} -D {TremN} -D sync {TactN1}" + ) + newtimes = f"-P {TpubN1} -P sync {TactN1} -A {TactN1} -I {TretN1} -D {TremN1}" + # Key generation. + csk1_name = keygen(f"{keytimes} {zonename}", cwd="ns3").strip() + csk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").strip() + settime( + f"-g HIDDEN -k UNRETENTIVE {TremN} -r UNRETENTIVE {TremN} -z HIDDEN now-2295h -d HIDDEN {TremN} {csk1_name}", + cwd="ns3", + ) + settime( + f"-g OMNIPRESENT -k OMNIPRESENT {TactN1} -r OMNIPRESENT {TactN1} -z OMNIPRESENT now-2295h -d OMNIPRESENT {TremN} {csk2_name}", + cwd="ns3", + ) + # Set key rollover relationship. + set_key_relationship(csk1_name, csk2_name) + # Signing. + render_and_sign_zone(zonename, [csk1_name, csk2_name], extra_options=f"-z -G {cds}") return zones