Symlink ns1 and ns2 to rollover/ns1 and rollover/ns2.
Symlink ns3/template.db.j2.manual to rollover/ns3/template.db.j2.manual.
Since the bootstrapping is done before the templates are rendered
automatically, replace @DEFAULT_ALGORITHM@ in ns3/csk2.conf.j2 to
ecdsa256 and rename to ns3/csk2.conf.
--- /dev/null
+../rollover/ns1
\ No newline at end of file
--- /dev/null
+../rollover/ns2
\ No newline at end of file
signatures-validity-dnskey 30d;
keys {
- csk lifetime unlimited algorithm @DEFAULT_ALGORITHM@;
+ csk lifetime unlimited algorithm ecdsa256;
};
dnskey-ttl 1h;
signatures-validity-dnskey 30d;
keys {
- csk lifetime unlimited algorithm @DEFAULT_ALGORITHM@;
+ csk lifetime unlimited algorithm ecdsa256;
};
dnskey-ttl 1h;
+++ /dev/null
-../../rollover/ns3/template.db.in
\ No newline at end of file
--- /dev/null
+../../rollover/ns3/template.db.j2.manual
\ No newline at end of file
--- /dev/null
+../../rollover/ns3/trusted.conf.j2
\ No newline at end of file
+++ /dev/null
-#!/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"
-}
-
-# Make lines shorter by storing key states in environment variables.
-H="HIDDEN"
-R="RUMOURED"
-O="OMNIPRESENT"
-U="UNRETENTIVE"
-
-#
-# The zones at csk-algorithm-roll.$tld represent the various steps of a CSK
-# algorithm rollover.
-#
-
-for tld in kasp manual; do
- # Step 1:
- # Introduce the first key. This will immediately be active.
- setup step1.csk-algorithm-roll.$tld
- echo "$zone" >>zones
- TactN="now-7d"
- TsbmN="now-161h"
- csktimes="-P ${TactN} -A ${TactN}"
- CSK=$($KEYGEN -k csk-algoroll-$tld -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.$tld
- # 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-$tld -l csk1.conf $csktimes $zone 2>keygen.out.$zone.1)
- CSK2=$($KEYGEN -k csk-algoroll-$tld -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.$tld
- # 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-$tld -l csk1.conf $csktimes $zone 2>keygen.out.$zone.1)
- CSK2=$($KEYGEN -k csk-algoroll-$tld -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.$tld
- # 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-$tld -l csk1.conf $csktimes $zone 2>keygen.out.$zone.1)
- CSK2=$($KEYGEN -k csk-algoroll-$tld -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.$tld
- # 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-$tld -l csk1.conf $csktimes $zone 2>keygen.out.$zone.1)
- CSK2=$($KEYGEN -k csk-algoroll-$tld -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.$tld
- # 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-$tld -l csk1.conf $csktimes $zone 2>keygen.out.$zone.1)
- CSK2=$($KEYGEN -k csk-algoroll-$tld -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
-done
TIMEDELTA,
ALGOROLL_CONFIG,
)
+from rollover.setup import (
+ configure_root,
+ configure_tld,
+ configure_algo_csk,
+)
+
+POLICY = "csk-algoroll"
+
+
+def bootstrap():
+ data = {
+ "tlds": [],
+ "trust_anchors": [],
+ }
+
+ tlds = []
+ for tld_name in [
+ "kasp",
+ "manual",
+ ]:
+ delegations = configure_algo_csk(
+ tld_name, f"{POLICY}-{tld_name}", reconfig=False
+ )
+
+ 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, policy",
+ "tld",
[
- param("kasp", "csk-algoroll-kasp"),
- param("manual", "csk-algoroll-manual"),
+ param("kasp"),
+ param("manual"),
],
)
-def test_algoroll_csk_initial(ns3, tld, policy):
+def test_algoroll_csk_initial(tld, ns3):
config = ALGOROLL_CONFIG
zone = f"step1.csk-algorithm-roll.{tld}"
+ policy = f"{POLICY}-{tld}"
isctest.kasp.wait_keymgr_done(ns3, zone)
DURATION,
TIMEDELTA,
)
+from rollover.setup import (
+ configure_root,
+ configure_tld,
+ configure_algo_csk,
+)
CONFIG = ALGOROLL_CONFIG
POLICY = "csk-algoroll"
TIME_PASSED = 0 # set in reconfigure() fixture
+def bootstrap():
+ data = {
+ "tlds": [],
+ "trust_anchors": [],
+ }
+
+ tlds = []
+ for tld_name in [
+ "kasp",
+ "manual",
+ ]:
+ delegations = configure_algo_csk(
+ tld_name, f"{POLICY}-{tld_name}", reconfig=True
+ )
+
+ 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.fixture(scope="module", autouse=True)
def after_servers_start(ns3, templates):
global TIME_PASSED # pylint: disable=global-statement
signer(f"-P -x -O full -o {zonename} -f {outfile} {infile}", cwd="ns1")
return ksk.into_ta("static-ds")
+
+
+def render_and_sign_zone(zonename: str, keys: List[str]):
+ dnskeys = []
+ privaterrs = []
+ for key_name in keys:
+ key = isctest.kasp.Key(key_name, keydir="ns3")
+ privaterr = private_type_record(zonename, key)
+ dnskeys.append(key.dnskey)
+ privaterrs.append(privaterr)
+
+ outfile = f"{zonename}.db"
+ templates = isctest.template.TemplateEngine(".")
+ template = "template.db.j2.manual"
+ tdata = {
+ "fqdn": f"{zonename}.",
+ "dnskeys": dnskeys,
+ "privaterrs": privaterrs,
+ }
+ templates.render(f"ns3/{outfile}", tdata, template=f"ns3/{template}")
+
+ signer = CmdHelper("SIGNER", "-S -g -x -z -s now-1h -e now+2w -O raw")
+ signer(f"-o {zonename} -f {outfile}.signed {outfile}", cwd="ns3")
+
+
+def configure_algo_csk(tld: str, policy: str, reconfig: bool = False) -> List[Zone]:
+ # The zones at csk-algorithm-roll.$tld represent the various steps
+ # of a CSK algorithm rollover.
+ zones = []
+ zone = f"csk-algorithm-roll.{tld}"
+ keygen = CmdHelper("KEYGEN", f"-k {policy}")
+ 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"
+ TsbmN = "now-161h"
+ csktimes = f"-P {TactN} -A {TactN}"
+ # Key generation.
+ csk_name = keygen(f"-l csk1.conf {csktimes} {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])
+
+ if reconfig:
+ # Step 2:
+ # After the publication interval has passed the DNSKEY is OMNIPRESENT.
+ zonename = f"step2.{zone}"
+ zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
+ isctest.log.info(f"setup {zonename}")
+ # The time passed since the new algorithm keys have been introduced is 3 hours.
+ TpubN1 = "now-3h"
+ csktimes = f"-P {TactN} -A {TactN} -P sync {TsbmN} -I now"
+ newtimes = f"-P {TpubN1} -A {TpubN1}"
+ # Key generation.
+ csk1_name = keygen(f"-l csk1.conf {csktimes} {zonename}", cwd="ns3").strip()
+ csk2_name = keygen(f"-l csk2.conf {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 RUMOURED {TpubN1} -d HIDDEN {TpubN1} {csk2_name}",
+ cwd="ns3",
+ )
+ # Signing.
+ render_and_sign_zone(zonename, [csk1_name, csk2_name])
+
+ # Step 3:
+ # The zone signatures are also OMNIPRESENT.
+ zonename = f"step3.{zone}"
+ zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
+ isctest.log.info(f"setup {zonename}")
+ # The time passed since the new algorithm keys have been introduced is 7 hours.
+ TpubN1 = "now-7h"
+ TsbmN1 = "now"
+ csktimes = f"-P {TactN} -A {TactN} -P sync {TsbmN} -I {TsbmN1}"
+ newtimes = f"-P {TpubN1} -A {TpubN1} -P sync {TsbmN1}"
+ # Key generation.
+ csk1_name = keygen(f"-l csk1.conf {csktimes} {zonename}", cwd="ns3").strip()
+ csk2_name = keygen(f"-l csk2.conf {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 OMNIPRESENT {TpubN1} -r OMNIPRESENT {TpubN1} -z RUMOURED {TpubN1} -d HIDDEN {TpubN1} {csk2_name}",
+ cwd="ns3",
+ )
+ # Signing.
+ render_and_sign_zone(zonename, [csk1_name, csk2_name])
+
+ # Step 4:
+ # The DS is swapped and can become OMNIPRESENT.
+ zonename = f"step4.{zone}"
+ zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
+ isctest.log.info(f"setup {zonename}")
+ # The time passed since the DS has been swapped is 3 hours.
+ TpubN1 = "now-10h"
+ TsbmN1 = "now-3h"
+ csktimes = f"-P {TactN} -A {TactN} -P sync {TsbmN} -I {TsbmN1}"
+ newtimes = f"-P {TpubN1} -A {TpubN1} -P sync {TsbmN1}"
+ # Key generation.
+ csk1_name = keygen(f"-l csk1.conf {csktimes} {zonename}", cwd="ns3").strip()
+ csk2_name = keygen(f"-l csk2.conf {newtimes} {zonename}", cwd="ns3").strip()
+ settime(
+ f"-g HIDDEN -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -z OMNIPRESENT {TsbmN1} -d UNRETENTIVE {TsbmN1} -D ds {TsbmN1} {csk1_name}",
+ cwd="ns3",
+ )
+ settime(
+ f"-g OMNIPRESENT -k OMNIPRESENT {TpubN1} -r OMNIPRESENT {TpubN1} -z OMNIPRESENT {TsbmN1} -d RUMOURED {TsbmN1} -P ds {TsbmN1} {csk2_name}",
+ cwd="ns3",
+ )
+ # Signing.
+ render_and_sign_zone(zonename, [csk1_name, csk2_name])
+
+ # Step 5:
+ # The DNSKEY is removed long enough to be HIDDEN.
+ zonename = f"step5.{zone}"
+ zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
+ isctest.log.info(f"setup {zonename}")
+ # The time passed since the DNSKEY has been removed is 2 hours.
+ TpubN1 = "now-12h"
+ TsbmN1 = "now-5h"
+ csktimes = f"-P {TactN} -A {TactN} -P sync {TsbmN} -I {TsbmN1}"
+ newtimes = f"-P {TpubN1} -A {TpubN1} -P sync {TsbmN1}"
+ # Key generation.
+ csk1_name = keygen(f"-l csk1.conf {csktimes} {zonename}", cwd="ns3").strip()
+ csk2_name = keygen(f"-l csk2.conf {newtimes} {zonename}", cwd="ns3").strip()
+ settime(
+ f"-g HIDDEN -k UNRETENTIVE {TactN} -r UNRETENTIVE {TactN} -z UNRETENTIVE {TsbmN1} -d HIDDEN {TsbmN1} {csk1_name}",
+ cwd="ns3",
+ )
+ settime(
+ f"-g OMNIPRESENT -k OMNIPRESENT {TpubN1} -r OMNIPRESENT {TpubN1} -z OMNIPRESENT {TsbmN1} -d OMNIPRESENT {TsbmN1} {csk2_name}",
+ cwd="ns3",
+ )
+ # Signing.
+ render_and_sign_zone(zonename, [csk1_name, csk2_name])
+
+ # Step 6:
+ # The RRSIGs have been removed long enough to be HIDDEN.
+ zonename = f"step6.{zone}"
+ zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
+ isctest.log.info(f"setup {zonename}")
+ # Additional time passed: 7h.
+ TpubN1 = "now-19h"
+ TsbmN1 = "now-12h"
+ csktimes = f"-P {TactN} -A {TactN} -P sync {TsbmN} -I {TsbmN1}"
+ newtimes = f"-P {TpubN1} -A {TpubN1} -P sync {TsbmN1}"
+ # Key generation.
+ csk1_name = keygen(f"-l csk1.conf {csktimes} {zonename}", cwd="ns3").strip()
+ csk2_name = keygen(f"-l csk2.conf {newtimes} {zonename}", cwd="ns3").strip()
+ settime(
+ f"-g HIDDEN -k HIDDEN {TactN} -r UNRETENTIVE {TactN} -z UNRETENTIVE {TactN} -d HIDDEN {TsbmN1} {csk1_name}",
+ cwd="ns3",
+ )
+ settime(
+ f"-g OMNIPRESENT -k OMNIPRESENT {TpubN1} -r OMNIPRESENT {TpubN1} -z OMNIPRESENT {TsbmN1} -d OMNIPRESENT {TsbmN1} {csk2_name}",
+ cwd="ns3",
+ )
+ # Signing.
+ render_and_sign_zone(zonename, [csk1_name, csk2_name])
+
+ return zones