chg: test: Update rollover system tests with chain of trust

Merge branch 'matthijs-trust-chain-rollover-system-tests' into 'main'

See merge request isc-projects/bind9!11309
This commit is contained in:
Matthijs Mekking 2025-12-19 12:02:16 +00:00
commit f3cb582b30
136 changed files with 2916 additions and 2056 deletions

View file

@ -1650,3 +1650,19 @@ def wait_keymgr_done(server: NamedInstance, zone: str, reconfig: bool = False) -
messages.append(f"keymgr: {zone} done")
with server.watch_log_from_start(timeout=60) as watcher:
watcher.wait_for_sequence(messages)
def private_type_record(zone: str, key: Key, rrtype: int = 65534) -> str:
"""
Write a private type record recording the state of the signing process for
a given zone and key, print the private type record with given RRtype,
indicating that the signing process for this key is completed.
"""
keyid = key.tag
algorithm = key.get_dnsalg()
secalg = int(key.get_metadata("Algorithm"))
if algorithm < 256:
return f"{zone}. 0 IN TYPE{rrtype} \\# 5 {secalg:02x}{keyid:04x}0000"
return f"{zone}. 0 IN TYPE{rrtype} \\# 7 {secalg:02x}{keyid:04x}0000{algorithm:04x}"

View file

@ -82,6 +82,20 @@ class TemplateEngine:
self.render(template[:-3], data)
@dataclass
class Nameserver:
name: str
ip: str
@dataclass
class Zone:
name: str
filename: str
ns: Nameserver
type: str = "primary"
@dataclass
class TrustAnchor:
domain: str

View file

@ -0,0 +1 @@
../rollover/ns1

View file

@ -0,0 +1 @@
../rollover/ns2

View file

@ -17,7 +17,7 @@ dnssec-policy "csk-algoroll-kasp" {
signatures-validity-dnskey 30d;
keys {
csk lifetime unlimited algorithm @DEFAULT_ALGORITHM@;
csk lifetime unlimited algorithm ecdsa256;
};
dnskey-ttl 1h;
@ -37,7 +37,7 @@ dnssec-policy "csk-algoroll-manual" {
signatures-validity-dnskey 30d;
keys {
csk lifetime unlimited algorithm @DEFAULT_ALGORITHM@;
csk lifetime unlimited algorithm ecdsa256;
};
dnskey-ttl 1h;

View file

@ -0,0 +1 @@
../../rollover/ns3/named.common.conf.j2

View file

@ -0,0 +1 @@
../../rollover/ns3/template.db.j2.manual

View file

@ -0,0 +1 @@
../../rollover/ns3/trusted.conf.j2

View file

@ -1 +0,0 @@
../../rollover-dynamic2inline/ns6/named.common.conf.j2

View file

@ -1 +0,0 @@
../../rollover-dynamic2inline/ns6/template.db.in

View file

@ -1,152 +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 "ns6"
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

View file

@ -22,20 +22,54 @@ from rollover.common import (
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(ns6, 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(ns6, zone)
isctest.kasp.wait_keymgr_done(ns3, zone)
step = {
"zone": zone,
@ -45,4 +79,4 @@ def test_algoroll_csk_initial(ns6, tld, policy):
],
"nextev": TIMEDELTA["PT1H"],
}
isctest.kasp.check_rollover_step(ns6, config, policy, step)
isctest.kasp.check_rollover_step(ns3, config, policy, step)

View file

@ -32,21 +32,52 @@ from rollover.common import (
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(ns6, templates):
def after_servers_start(ns3, templates):
global TIME_PASSED # pylint: disable=global-statement
isctest.kasp.wait_keymgr_done(ns6, "step1.csk-algorithm-roll.kasp")
isctest.kasp.wait_keymgr_done(ns3, "step1.csk-algorithm-roll.kasp")
templates.render("ns6/named.conf", {"csk_roll": True})
templates.render("ns3/named.conf", {"csk_roll": True})
start_time = KeyTimingMetadata.now()
ns6.reconfigure()
ns3.reconfigure()
# Calculate time passed to correctly check for next key events.
TIME_PASSED = KeyTimingMetadata.now().value - start_time.value
@ -59,11 +90,11 @@ def after_servers_start(ns6, templates):
param("manual"),
],
)
def test_algoroll_csk_reconfig_step1(tld, ns6, alg, size):
def test_algoroll_csk_reconfig_step1(tld, ns3, alg, size):
zone = f"step1.csk-algorithm-roll.{tld}"
policy = f"{POLICY}-{tld}"
isctest.kasp.wait_keymgr_done(ns6, zone, reconfig=True)
isctest.kasp.wait_keymgr_done(ns3, zone, reconfig=True)
if tld == "manual":
# Same as initial.
@ -76,18 +107,18 @@ def test_algoroll_csk_reconfig_step1(tld, ns6, alg, size):
"manual-mode": True,
"nextev": None,
}
keys = isctest.kasp.check_rollover_step(ns6, CONFIG, policy, step)
keys = isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step)
# Check logs.
tag = keys[0].key.tag
msg1 = f"keymgr-manual-mode: block retire DNSKEY {zone}/RSASHA256/{tag} (CSK)"
msg2 = f"keymgr-manual-mode: block new key generation for zone {zone} (policy {policy})"
assert msg1 in ns6.log
assert msg2 in ns6.log
assert msg1 in ns3.log
assert msg2 in ns3.log
# Force step.
with ns6.watch_log_from_here() as watcher:
ns6.rndc(f"dnssec -step {zone}")
with ns3.watch_log_from_here() as watcher:
ns3.rndc(f"dnssec -step {zone}")
watcher.wait_for_line(
f"zone {zone}/IN (signed): zone_rekey done: key {tag}/RSASHA256"
)
@ -105,7 +136,7 @@ def test_algoroll_csk_reconfig_step1(tld, ns6, alg, size):
# Next key event is when the ecdsa256 keys have been propagated.
"nextev": ALGOROLL_IPUB,
}
isctest.kasp.check_rollover_step(ns6, CONFIG, policy, step)
isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step)
@pytest.mark.parametrize(
@ -115,11 +146,11 @@ def test_algoroll_csk_reconfig_step1(tld, ns6, alg, size):
param("manual"),
],
)
def test_algoroll_csk_reconfig_step2(tld, ns6, alg, size):
def test_algoroll_csk_reconfig_step2(tld, ns3, alg, size):
zone = f"step2.csk-algorithm-roll.{tld}"
policy = f"{POLICY}-{tld}"
isctest.kasp.wait_keymgr_done(ns6, zone, reconfig=True)
isctest.kasp.wait_keymgr_done(ns3, zone, reconfig=True)
# manual-mode: Nothing changing in the zone, no 'dnssec -step' required.
@ -142,7 +173,7 @@ def test_algoroll_csk_reconfig_step2(tld, ns6, alg, size):
# the time passed between key creation and invoking 'rndc reconfig'.
"nextev": ALGOROLL_IPUBC - ALGOROLL_IPUB - TIME_PASSED,
}
isctest.kasp.check_rollover_step(ns6, CONFIG, policy, step)
isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step)
@pytest.mark.parametrize(
@ -152,11 +183,11 @@ def test_algoroll_csk_reconfig_step2(tld, ns6, alg, size):
param("manual"),
],
)
def test_algoroll_csk_reconfig_step3(tld, ns6, alg, size):
def test_algoroll_csk_reconfig_step3(tld, ns3, alg, size):
zone = f"step3.csk-algorithm-roll.{tld}"
policy = f"{POLICY}-{tld}"
isctest.kasp.wait_keymgr_done(ns6, zone, reconfig=True)
isctest.kasp.wait_keymgr_done(ns3, zone, reconfig=True)
if tld == "manual":
# Same as step 2, but the zone signatures have become OMNIPRESENT.
@ -170,16 +201,16 @@ def test_algoroll_csk_reconfig_step3(tld, ns6, alg, size):
"manual-mode": True,
"nextev": None,
}
keys = isctest.kasp.check_rollover_step(ns6, CONFIG, policy, step)
keys = isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step)
# Check logs.
tag = keys[1].key.tag
msg = f"keymgr-manual-mode: block transition CSK {zone}/ECDSAP256SHA256/{tag} type DS state HIDDEN to state RUMOURED"
assert msg in ns6.log
assert msg in ns3.log
# Force step.
with ns6.watch_log_from_here() as watcher:
ns6.rndc(f"dnssec -step {zone}")
with ns3.watch_log_from_here() as watcher:
ns3.rndc(f"dnssec -step {zone}")
watcher.wait_for_line(
f"zone {zone}/IN (signed): zone_rekey done: key {tag}/ECDSAP256SHA256"
)
@ -187,14 +218,14 @@ def test_algoroll_csk_reconfig_step3(tld, ns6, alg, size):
# Check logs.
tag = keys[0].key.tag
msg = f"keymgr-manual-mode: block transition CSK {zone}/RSASHA256/{tag} type DS state OMNIPRESENT to state UNRETENTIVE"
if msg in ns6.log:
if msg in ns3.log:
# Force step.
isctest.log.debug(
f"keymgr-manual-mode blocking transition CSK {zone}/RSASHA256/{tag} type DS state OMNIPRESENT to state UNRETENTIVE, step again"
)
tag = keys[1].key.tag
with ns6.watch_log_from_here() as watcher:
ns6.rndc(f"dnssec -step {zone}")
with ns3.watch_log_from_here() as watcher:
ns3.rndc(f"dnssec -step {zone}")
watcher.wait_for_line(
f"zone {zone}/IN (signed): zone_rekey done: key {tag}/ECDSAP256SHA256"
)
@ -211,7 +242,7 @@ def test_algoroll_csk_reconfig_step3(tld, ns6, alg, size):
# after the publication interval of the parent side.
"nextev": ALGOROLL_IRETKSK - TIME_PASSED,
}
isctest.kasp.check_rollover_step(ns6, CONFIG, policy, step)
isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step)
@pytest.mark.parametrize(
@ -221,11 +252,11 @@ def test_algoroll_csk_reconfig_step3(tld, ns6, alg, size):
param("manual"),
],
)
def test_algoroll_csk_reconfig_step4(tld, ns6, alg, size):
def test_algoroll_csk_reconfig_step4(tld, ns3, alg, size):
zone = f"step4.csk-algorithm-roll.{tld}"
policy = f"{POLICY}-{tld}"
isctest.kasp.wait_keymgr_done(ns6, zone, reconfig=True)
isctest.kasp.wait_keymgr_done(ns3, zone, reconfig=True)
if tld == "manual":
# Same as step 3, but the DS has become HIDDEN/OMNIPRESENT.
@ -239,17 +270,17 @@ def test_algoroll_csk_reconfig_step4(tld, ns6, alg, size):
"manual-mode": True,
"nextev": None,
}
keys = isctest.kasp.check_rollover_step(ns6, CONFIG, policy, step)
keys = isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step)
# Check logs.
tag = keys[0].key.tag
msg = f"keymgr-manual-mode: block transition CSK {zone}/RSASHA256/{tag} type DNSKEY state OMNIPRESENT to state UNRETENTIVE"
assert msg in ns6.log
assert msg in ns3.log
# Force step.
tag = keys[1].key.tag
with ns6.watch_log_from_here() as watcher:
ns6.rndc(f"dnssec -step {zone}")
with ns3.watch_log_from_here() as watcher:
ns3.rndc(f"dnssec -step {zone}")
watcher.wait_for_line(
f"zone {zone}/IN (signed): zone_rekey done: key {tag}/ECDSAP256SHA256"
)
@ -266,7 +297,7 @@ def test_algoroll_csk_reconfig_step4(tld, ns6, alg, size):
# This happens after the DNSKEY TTL plus zone propagation delay.
"nextev": ALGOROLL_KEYTTLPROP,
}
isctest.kasp.check_rollover_step(ns6, CONFIG, policy, step)
isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step)
@pytest.mark.parametrize(
@ -276,11 +307,11 @@ def test_algoroll_csk_reconfig_step4(tld, ns6, alg, size):
param("manual"),
],
)
def test_algoroll_csk_reconfig_step5(tld, ns6, alg, size):
def test_algoroll_csk_reconfig_step5(tld, ns3, alg, size):
zone = f"step5.csk-algorithm-roll.{tld}"
policy = f"{POLICY}-{tld}"
isctest.kasp.wait_keymgr_done(ns6, zone, reconfig=True)
isctest.kasp.wait_keymgr_done(ns3, zone, reconfig=True)
# manual-mode: Nothing changing in the zone, no 'dnssec -step' required.
@ -300,7 +331,7 @@ def test_algoroll_csk_reconfig_step5(tld, ns6, alg, size):
# between key creation and invoking 'rndc reconfig'.
"nextev": ALGOROLL_IRET - ALGOROLL_IRETKSK - ALGOROLL_KEYTTLPROP - TIME_PASSED,
}
isctest.kasp.check_rollover_step(ns6, CONFIG, policy, step)
isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step)
@pytest.mark.parametrize(
@ -310,11 +341,11 @@ def test_algoroll_csk_reconfig_step5(tld, ns6, alg, size):
param("manual"),
],
)
def test_algoroll_csk_reconfig_step6(tld, ns6, alg, size):
def test_algoroll_csk_reconfig_step6(tld, ns3, alg, size):
zone = f"step6.csk-algorithm-roll.{tld}"
policy = f"{POLICY}-{tld}"
isctest.kasp.wait_keymgr_done(ns6, zone, reconfig=True)
isctest.kasp.wait_keymgr_done(ns3, zone, reconfig=True)
# manual-mode: Nothing changing in the zone, no 'dnssec -step' required.
@ -333,4 +364,4 @@ def test_algoroll_csk_reconfig_step6(tld, ns6, alg, size):
# Include hidden keys in output.
"verbose": True,
}
isctest.kasp.check_rollover_step(ns6, CONFIG, policy, step)
isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step)

View file

@ -0,0 +1 @@
../rollover/ns1

View file

@ -0,0 +1 @@
../rollover/ns2

View file

@ -0,0 +1 @@
../../rollover/ns3/named.common.conf.j2

View file

@ -0,0 +1 @@
../../rollover/ns3/template.db.j2.manual

View file

@ -0,0 +1 @@
../../_common/trusted.conf.j2

View file

@ -1 +0,0 @@
../../rollover-dynamic2inline/ns6/named.common.conf.j2

View file

@ -1 +0,0 @@
../../rollover-dynamic2inline/ns6/template.db.in

View file

@ -1,201 +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 "ns6"
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 algorithm-roll.$tld represent the various steps of a ZSK/KSK
# algorithm rollover.
#
for tld in kasp manual; do
# Step 1:
# Introduce the first key. This will immediately be active.
setup step1.algorithm-roll.$tld
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.$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"
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.$tld
# 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.$tld
# 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.$tld
# 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.$tld
# 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
done

View file

@ -22,6 +22,35 @@ from rollover.common import (
TIMEDELTA,
ALGOROLL_CONFIG,
)
from rollover.setup import (
configure_root,
configure_tld,
configure_algo_ksk_zsk,
)
def bootstrap():
data = {
"tlds": [],
"trust_anchors": [],
}
tlds = []
for tld_name in [
"kasp",
"manual",
]:
delegations = configure_algo_ksk_zsk(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(
@ -31,12 +60,12 @@ from rollover.common import (
param("manual"),
],
)
def test_algoroll_ksk_zsk_initial(ns6, tld):
def test_algoroll_ksk_zsk_initial(tld, ns3):
config = ALGOROLL_CONFIG
policy = f"rsasha256-{tld}"
zone = f"step1.algorithm-roll.{tld}"
isctest.kasp.wait_keymgr_done(ns6, zone)
isctest.kasp.wait_keymgr_done(ns3, zone)
step = {
"zone": zone,
@ -47,4 +76,4 @@ def test_algoroll_ksk_zsk_initial(ns6, tld):
],
"nextev": TIMEDELTA["PT1H"],
}
isctest.kasp.check_rollover_step(ns6, config, policy, step)
isctest.kasp.check_rollover_step(ns3, config, policy, step)

View file

@ -32,21 +32,50 @@ from rollover.common import (
DURATION,
TIMEDELTA,
)
from rollover.setup import (
configure_root,
configure_tld,
configure_algo_ksk_zsk,
)
CONFIG = ALGOROLL_CONFIG
POLICY = "ecdsa256"
TIME_PASSED = 0 # set in reconfigure() fixture
def bootstrap():
data = {
"tlds": [],
"trust_anchors": [],
}
tlds = []
for tld_name in [
"kasp",
"manual",
]:
delegations = configure_algo_ksk_zsk(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(ns6, templates):
def after_servers_start(ns3, templates):
global TIME_PASSED # pylint: disable=global-statement
isctest.kasp.wait_keymgr_done(ns6, "step1.algorithm-roll.kasp")
isctest.kasp.wait_keymgr_done(ns3, "step1.algorithm-roll.kasp")
templates.render("ns6/named.conf", {"alg_roll": True})
templates.render("ns3/named.conf", {"alg_roll": True})
start_time = KeyTimingMetadata.now()
ns6.reconfigure()
ns3.reconfigure()
# Calculate time passed to correctly check for next key events.
TIME_PASSED = KeyTimingMetadata.now().value - start_time.value
@ -59,11 +88,11 @@ def after_servers_start(ns6, templates):
param("manual"),
],
)
def test_algoroll_ksk_zsk_reconfig_step1(tld, ns6, alg, size):
def test_algoroll_ksk_zsk_reconfig_step1(tld, ns3, alg, size):
zone = f"step1.algorithm-roll.{tld}"
policy = f"{POLICY}-{tld}"
isctest.kasp.wait_keymgr_done(ns6, zone, reconfig=True)
isctest.kasp.wait_keymgr_done(ns3, zone, reconfig=True)
if tld == "manual":
# Same as initial.
@ -77,7 +106,7 @@ def test_algoroll_ksk_zsk_reconfig_step1(tld, ns6, alg, size):
"manual-mode": True,
"nextev": None,
}
keys = isctest.kasp.check_rollover_step(ns6, CONFIG, policy, step)
keys = isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step)
# Check logs.
ktag = keys[0].key.tag
@ -85,13 +114,13 @@ def test_algoroll_ksk_zsk_reconfig_step1(tld, ns6, alg, size):
msg1 = f"keymgr-manual-mode: block retire DNSKEY {zone}/RSASHA256/{ktag} (KSK)"
msg2 = f"keymgr-manual-mode: block retire DNSKEY {zone}/RSASHA256/{ztag} (ZSK)"
msg3 = f"keymgr-manual-mode: block new key generation for zone {zone} (policy {policy})" # twice
assert msg1 in ns6.log
assert msg2 in ns6.log
assert len(ns6.log.grep(msg3)) >= 2
assert msg1 in ns3.log
assert msg2 in ns3.log
assert len(ns3.log.grep(msg3)) == 2
# Force step.
with ns6.watch_log_from_here() as watcher:
ns6.rndc(f"dnssec -step {zone}")
with ns3.watch_log_from_here() as watcher:
ns3.rndc(f"dnssec -step {zone}")
watcher.wait_for_line(
f"zone {zone}/IN (signed): zone_rekey done: key {ktag}/RSASHA256"
)
@ -110,7 +139,7 @@ def test_algoroll_ksk_zsk_reconfig_step1(tld, ns6, alg, size):
# Next key event is when the ecdsa256 keys have been propagated.
"nextev": ALGOROLL_IPUB,
}
isctest.kasp.check_rollover_step(ns6, CONFIG, policy, step)
isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step)
@pytest.mark.parametrize(
@ -120,11 +149,11 @@ def test_algoroll_ksk_zsk_reconfig_step1(tld, ns6, alg, size):
param("manual"),
],
)
def test_algoroll_ksk_zsk_reconfig_step2(tld, ns6, alg, size):
def test_algoroll_ksk_zsk_reconfig_step2(tld, ns3, alg, size):
zone = f"step2.algorithm-roll.{tld}"
policy = f"{POLICY}-{tld}"
isctest.kasp.wait_keymgr_done(ns6, zone, reconfig=True)
isctest.kasp.wait_keymgr_done(ns3, zone, reconfig=True)
# manual-mode: Nothing changing in the zone, no 'dnssec -step' required.
@ -149,7 +178,7 @@ def test_algoroll_ksk_zsk_reconfig_step2(tld, ns6, alg, size):
# key creation and invoking 'rndc reconfig'.
"nextev": ALGOROLL_IPUBC - ALGOROLL_IPUB - TIME_PASSED,
}
isctest.kasp.check_rollover_step(ns6, CONFIG, policy, step)
isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step)
@pytest.mark.parametrize(
@ -159,11 +188,11 @@ def test_algoroll_ksk_zsk_reconfig_step2(tld, ns6, alg, size):
param("manual"),
],
)
def test_algoroll_ksk_zsk_reconfig_step3(tld, ns6, alg, size):
def test_algoroll_ksk_zsk_reconfig_step3(tld, ns3, alg, size):
zone = f"step3.algorithm-roll.{tld}"
policy = f"{POLICY}-{tld}"
isctest.kasp.wait_keymgr_done(ns6, zone, reconfig=True)
isctest.kasp.wait_keymgr_done(ns3, zone, reconfig=True)
if tld == "manual":
# Same as step 2, but the zone signatures have become OMNIPRESENT.
@ -179,16 +208,16 @@ def test_algoroll_ksk_zsk_reconfig_step3(tld, ns6, alg, size):
"manual-mode": True,
"nextev": None,
}
keys = isctest.kasp.check_rollover_step(ns6, CONFIG, policy, step)
keys = isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step)
# Check logs.
tag = keys[2].key.tag
msg = f"keymgr-manual-mode: block transition KSK {zone}/ECDSAP256SHA256/{tag} type DS state HIDDEN to state RUMOURED"
assert msg in ns6.log
assert msg in ns3.log
# Force step.
with ns6.watch_log_from_here() as watcher:
ns6.rndc(f"dnssec -step {zone}")
with ns3.watch_log_from_here() as watcher:
ns3.rndc(f"dnssec -step {zone}")
watcher.wait_for_line(
f"zone {zone}/IN (signed): zone_rekey done: key {tag}/ECDSAP256SHA256"
)
@ -196,14 +225,14 @@ def test_algoroll_ksk_zsk_reconfig_step3(tld, ns6, alg, size):
# Check logs.
tag = keys[0].key.tag
msg = f"keymgr-manual-mode: block transition KSK {zone}/RSASHA256/{tag} type DS state OMNIPRESENT to state UNRETENTIVE"
if msg in ns6.log:
if msg in ns3.log:
# Force step.
isctest.log.debug(
f"keymgr-manual-mode blocking transition CSK {zone}/RSASHA256/{tag} type DS state OMNIPRESENT to state UNRETENTIVE, step again"
)
tag = keys[2].key.tag
with ns6.watch_log_from_here() as watcher:
ns6.rndc(f"dnssec -step {zone}")
with ns3.watch_log_from_here() as watcher:
ns3.rndc(f"dnssec -step {zone}")
watcher.wait_for_line(
f"zone {zone}/IN (signed): zone_rekey done: key {tag}/ECDSAP256SHA256"
)
@ -222,7 +251,7 @@ def test_algoroll_ksk_zsk_reconfig_step3(tld, ns6, alg, size):
# after the retire interval.
"nextev": ALGOROLL_IRETKSK - TIME_PASSED,
}
isctest.kasp.check_rollover_step(ns6, CONFIG, policy, step)
isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step)
@pytest.mark.parametrize(
@ -232,11 +261,11 @@ def test_algoroll_ksk_zsk_reconfig_step3(tld, ns6, alg, size):
param("manual"),
],
)
def test_algoroll_ksk_zsk_reconfig_step4(tld, ns6, alg, size):
def test_algoroll_ksk_zsk_reconfig_step4(tld, ns3, alg, size):
zone = f"step4.algorithm-roll.{tld}"
policy = f"{POLICY}-{tld}"
isctest.kasp.wait_keymgr_done(ns6, zone, reconfig=True)
isctest.kasp.wait_keymgr_done(ns3, zone, reconfig=True)
if tld == "manual":
# Same as step 3, but the DS has become HIDDEN/OMNIPRESENT.
@ -252,20 +281,20 @@ def test_algoroll_ksk_zsk_reconfig_step4(tld, ns6, alg, size):
"manual-mode": True,
"nextev": None,
}
keys = isctest.kasp.check_rollover_step(ns6, CONFIG, policy, step)
keys = isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step)
# Check logs.
ktag = keys[0].key.tag
ztag = keys[1].key.tag
msg1 = f"keymgr-manual-mode: block transition KSK {zone}/RSASHA256/{ktag} type DNSKEY state OMNIPRESENT to state UNRETENTIVE"
msg2 = f"keymgr-manual-mode: block transition ZSK {zone}/RSASHA256/{ztag} type DNSKEY state OMNIPRESENT to state UNRETENTIVE"
assert msg1 in ns6.log
assert msg2 in ns6.log
assert msg1 in ns3.log
assert msg2 in ns3.log
# Force step.
ktag = keys[3].key.tag
with ns6.watch_log_from_here() as watcher:
ns6.rndc(f"dnssec -step {zone}")
with ns3.watch_log_from_here() as watcher:
ns3.rndc(f"dnssec -step {zone}")
watcher.wait_for_line(
f"zone {zone}/IN (signed): zone_rekey done: key {ktag}/ECDSAP256SHA256"
)
@ -284,7 +313,7 @@ def test_algoroll_ksk_zsk_reconfig_step4(tld, ns6, alg, size):
# This happens after the DNSKEY TTL plus zone propagation delay.
"nextev": ALGOROLL_KEYTTLPROP,
}
isctest.kasp.check_rollover_step(ns6, CONFIG, policy, step)
isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step)
@pytest.mark.parametrize(
@ -294,11 +323,11 @@ def test_algoroll_ksk_zsk_reconfig_step4(tld, ns6, alg, size):
param("manual"),
],
)
def test_algoroll_ksk_zsk_reconfig_step5(tld, ns6, alg, size):
def test_algoroll_ksk_zsk_reconfig_step5(tld, ns3, alg, size):
zone = f"step5.algorithm-roll.{tld}"
policy = f"{POLICY}-{tld}"
isctest.kasp.wait_keymgr_done(ns6, zone, reconfig=True)
isctest.kasp.wait_keymgr_done(ns3, zone, reconfig=True)
# manual-mode: Nothing changing in the zone, no 'dnssec -step' required.
@ -322,7 +351,7 @@ def test_algoroll_ksk_zsk_reconfig_step5(tld, ns6, alg, size):
# Include hidden keys in output.
"verbose": True,
}
isctest.kasp.check_rollover_step(ns6, CONFIG, policy, step)
isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step)
@pytest.mark.parametrize(
@ -332,11 +361,11 @@ def test_algoroll_ksk_zsk_reconfig_step5(tld, ns6, alg, size):
param("manual"),
],
)
def test_algoroll_ksk_zsk_reconfig_step6(tld, ns6, alg, size):
def test_algoroll_ksk_zsk_reconfig_step6(tld, ns3, alg, size):
zone = f"step6.algorithm-roll.{tld}"
policy = f"{POLICY}-{tld}"
isctest.kasp.wait_keymgr_done(ns6, zone, reconfig=True)
isctest.kasp.wait_keymgr_done(ns3, zone, reconfig=True)
# manual-mode: Nothing changing in the zone, no 'dnssec -step' required.
@ -357,4 +386,4 @@ def test_algoroll_ksk_zsk_reconfig_step6(tld, ns6, alg, size):
# Include hidden keys in output.
"verbose": True,
}
isctest.kasp.check_rollover_step(ns6, CONFIG, policy, step)
isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step)

View file

@ -0,0 +1 @@
../rollover/ns1

View file

@ -0,0 +1 @@
../rollover/ns2

View file

@ -23,7 +23,7 @@ dnssec-policy "csk-roll1-autosign" {
cds-digest-types { "sha-384"; }; // use a different digest type for testing purposes
keys {
csk key-directory lifetime P6M algorithm @DEFAULT_ALGORITHM@;
csk key-directory lifetime P6M algorithm ecdsa256;
};
zone-propagation-delay 1h;
@ -47,7 +47,7 @@ dnssec-policy "csk-roll1-manual" {
cds-digest-types { "sha-384"; }; // use a different digest type for testing purposes
keys {
csk key-directory lifetime P6M algorithm @DEFAULT_ALGORITHM@;
csk key-directory lifetime P6M algorithm ecdsa256;
};
zone-propagation-delay 1h;

View file

@ -1 +0,0 @@
../../rollover/ns3/template.db.in

View file

@ -0,0 +1 @@
../../rollover/ns3/template.db.j2.manual

View file

@ -0,0 +1 @@
../../_common/trusted.conf.j2

View file

@ -1,314 +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-roll1.$tld represent the various steps of a CSK rollover
# (which is essentially a ZSK Pre-Publication / KSK Double-KSK rollover).
#
for tld in autosign manual; do
# Step 1:
# Introduce the first key. This will immediately be active.
setup step1.csk-roll1.$tld
TactN="now-7d"
keytimes="-P ${TactN} -A ${TactN}"
CSK=$($KEYGEN -k csk-roll1-$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-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-roll1.$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-roll1-$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-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-roll1.$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: 1h
# Dreg: N/A
# Dsgn: 25d
# TTLds: 1h
# TTLsig: 1d
# retire-safety: 2h
# Iret: 4h
# IretZ: 26d3h
# 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+627h"
TpubN1="now-3h"
TactN1="${TretN}"
TretN1="now+186d"
TremN1="now+5091h"
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-roll1-$tld -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1)
CSK2=$($KEYGEN -k csk-roll1-$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-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
# (which is 26d3h). The DS is swapped after Iret (which is 4h).
# In other words, the DS is swapped before all zone signatures are replaced.
setup step4.csk-roll1.$tld
# According to RFC 7583:
# Trem(N) = Tret(N) - Iret + IretZ
# now = Tsbm(N+1) + Iret
#
# Lcsk: 186d
# Iret: 4h
# IretZ: 26d3h
#
# Tpub(N) = now - Iret - Lcsk = now - 4h - 186d = now - 4468h
# Tret(N) = now - Iret = now - 4h = now - 4h
# Trem(N) = now - Iret + IretZ = now - 4h + 26d3h
# = now + 623h
# Tpub(N+1) = now - Iret - IpubC = now - 4h - 3h = now - 7h
# Tact(N+1) = Tret(N)
# Tret(N+1) = now - Iret + Lcsk = now - 4h + 186d = now + 4460h
# Trem(N+1) = now - Iret + Lcsk + IretZ = now - 4h + 186d + 26d3h
# = now + 5087h
TpubN="now-4468h"
TactN="now-4443h"
TretN="now-4h"
TremN="now+623h"
TpubN1="now-7h"
TactN1="${TretN}"
TretN1="now+4460h"
TremN1="now+5087h"
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-roll1-$tld -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1)
CSK2=$($KEYGEN -k csk-roll1-$tld -l kasp.conf $newtimes $zone 2>keygen.out.$zone.2)
$SETTIME -s -g $H -k $O $TactN -r $O $TactN -d $U $TactN1 -z $U $TactN1 -D ds $TactN1 "$CSK1" >settime.out.$zone.1 2>&1
$SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $R $TactN1 -z $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-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
# Step 5:
# After the DS is swapped in step 4, also the KRRSIG records can be removed.
# At this time these have all become hidden.
setup step5.csk-roll1.$tld
# Subtract DNSKEY TTL plus zone propagation delay from all the times (2h).
TpubN="now-4470h"
TactN="now-4445h"
TretN="now-6h"
TremN="now+621h"
TpubN1="now-9h"
TactN1="${TretN}"
TretN1="now+4458h"
TremN1="now+5085h"
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-roll1-$tld -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1)
CSK2=$($KEYGEN -k csk-roll1-$tld -l kasp.conf $newtimes $zone 2>keygen.out.$zone.2)
$SETTIME -s -g $H -k $O $TactN -r $U now-2h -d $H now-2h -z $U $TactN1 "$CSK1" >settime.out.$zone.1 2>&1
$SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $O now-2h -z $R $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-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
# Step 6:
# After the retire interval has passed the predecessor DNSKEY can be
# removed from the zone.
setup step6.csk-roll1.$tld
# According to RFC 7583:
# Trem(N) = Tret(N) + IretZ
# Tret(N) = Tact(N) + Lcsk
#
# Lcsk: 186d
# Iret: 4h
# IretZ: 26d3h
#
# Tpub(N) = now - IretZ - Lcsk = now - 627h - 186d
# = now - 627h - 4464h = now - 5091h
# Tact(N) = now - 627h - 186d
# Tret(N) = now - IretZ = now - 627h
# Trem(N) = now
# Tpub(N+1) = now - IretZ - Ipub = now - 627h - 3h = now - 630h
# Tact(N+1) = Tret(N)
# Tret(N+1) = now - IretZ + Lcsk = now - 627h + 186d = now + 3837h
# Trem(N+1) = now + Lcsk = now + 186d
TpubN="now-5091h"
TactN="now-5066h"
TretN="now-627h"
TremN="now"
TpubN1="now-630h"
TactN1="${TretN}"
TretN1="now+3837h"
TremN1="now+186d"
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-roll1-$tld -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1)
CSK2=$($KEYGEN -k csk-roll1-$tld -l kasp.conf $newtimes $zone 2>keygen.out.$zone.2)
$SETTIME -s -g $H -k $O $TactN -r $H $TremN -d $H $TremN -z $U $TactN1 "$CSK1" >settime.out.$zone.1 2>&1
$SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $O $TremN -z $R $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-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
# Step 7:
# Some time later the predecessor DNSKEY enters the HIDDEN state.
setup step7.csk-roll1.$tld
# Subtract DNSKEY TTL plus zone propagation delay from all the times (2h).
TpubN="now-5093h"
TactN="now-5068h"
TretN="now-629h"
TremN="now-2h"
TpubN1="now-632h"
TactN1="${TretN}"
TretN1="now+3835h"
TremN1="now+4462h"
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-roll1-$tld -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1)
CSK2=$($KEYGEN -k csk-roll1-$tld -l kasp.conf $newtimes $zone 2>keygen.out.$zone.2)
$SETTIME -s -g $H -k $U $TremN -r $H $TremN -d $H $TremN -z $H $TactN1 "$CSK1" >settime.out.$zone.1 2>&1
$SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $O $TactN1 -z $O $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-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
# Step 8:
# The predecessor DNSKEY can be purged.
setup step8.csk-roll1.$tld
TpubN="now-5094h"
TactN="now-5069h"
TretN="now-630h"
TremN="now-3h"
TpubN1="now-633h"
TactN1="${TretN}"
TretN1="now+3834h"
TremN1="now+4461h"
# Subtract purge-keys interval from all the times (1h).
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-roll1-$tld -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1)
CSK2=$($KEYGEN -k csk-roll1-$tld -l kasp.conf $newtimes $zone 2>keygen.out.$zone.2)
$SETTIME -s -g $H -k $H $TremN -r $H $TremN -d $H $TremN -z $H $TactN1 "$CSK1" >settime.out.$zone.1 2>&1
$SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $O $TactN1 -z $O $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-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
done

View file

@ -24,7 +24,11 @@ from rollover.common import (
size,
TIMEDELTA,
)
from rollover.setup import (
configure_root,
configure_tld,
configure_cskroll1,
)
CDSS = ["CDNSKEY", "CDS (SHA-384)"]
CONFIG = {
@ -65,6 +69,30 @@ OFFSETS["step8-p"] = OFFSETS["step7-p"] - int(CONFIG["purge-keys"].total_seconds
OFFSETS["step8-s"] = OFFSETS["step7-s"] - int(CONFIG["purge-keys"].total_seconds())
def bootstrap():
data = {
"tlds": [],
"trust_anchors": [],
}
tlds = []
for tld_name in [
"autosign",
"manual",
]:
delegations = configure_cskroll1(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",
[
@ -72,7 +100,7 @@ OFFSETS["step8-s"] = OFFSETS["step7-s"] - int(CONFIG["purge-keys"].total_seconds
param("manual"),
],
)
def test_csk_roll1_step1(tld, alg, size, ns3):
def test_csk_roll1_step1(tld, ns3, alg, size):
zone = f"step1.csk-roll1.{tld}"
policy = f"{POLICY}-{tld}"

View file

@ -0,0 +1 @@
../rollover/ns1

View file

@ -0,0 +1 @@
../rollover/ns2

View file

@ -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;

View file

@ -1 +0,0 @@
../../rollover/ns3/template.db.in

View file

@ -0,0 +1 @@
../../rollover/ns3/template.db.j2.manual

View file

@ -0,0 +1 @@
../../_common/trusted.conf.j2

View file

@ -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

View file

@ -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",
[

View file

@ -0,0 +1 @@
../../rollover/ns3/named.common.conf.j2

View file

@ -1 +0,0 @@
./template.db.in

View file

@ -21,12 +21,12 @@ from rollover.common import (
)
def test_dynamic2inline(alg, size, ns6, templates):
def test_dynamic2inline(alg, size, ns3, templates):
config = DEFAULT_CONFIG
policy = "default"
zone = "dynamic2inline.kasp"
isctest.kasp.wait_keymgr_done(ns6, zone)
isctest.kasp.wait_keymgr_done(ns3, zone)
step = {
"zone": zone,
@ -37,10 +37,10 @@ def test_dynamic2inline(alg, size, ns6, templates):
"nextev": None,
}
isctest.kasp.check_rollover_step(ns6, config, policy, step)
isctest.kasp.check_rollover_step(ns3, config, policy, step)
templates.render("ns6/named.conf", {"change_lifetime": True})
ns6.reconfigure()
isctest.kasp.wait_keymgr_done(ns6, zone, reconfig=True)
templates.render("ns3/named.conf", {"change_lifetime": True})
ns3.reconfigure()
isctest.kasp.wait_keymgr_done(ns3, zone, reconfig=True)
isctest.kasp.check_rollover_step(ns6, config, policy, step)
isctest.kasp.check_rollover_step(ns3, config, policy, step)

View file

@ -0,0 +1 @@
../rollover/ns1

View file

@ -0,0 +1 @@
../rollover/ns2

View file

@ -26,7 +26,7 @@ dnssec-policy "enable-dnssec-autosign" {
parent-ds-ttl 2h;
keys {
csk lifetime unlimited algorithm @DEFAULT_ALGORITHM_NUMBER@;
csk lifetime unlimited algorithm 13;
};
};
@ -47,6 +47,6 @@ dnssec-policy "enable-dnssec-manual" {
parent-ds-ttl 2h;
keys {
csk lifetime unlimited algorithm @DEFAULT_ALGORITHM_NUMBER@;
csk lifetime unlimited algorithm 13;
};
};

View file

@ -1 +0,0 @@
../../rollover/ns3/template.db.in

View file

@ -0,0 +1 @@
../../rollover/ns3/template.db.j2.manual

View file

@ -0,0 +1 @@
../../_common/trusted.conf.j2

View file

@ -1,102 +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 enable-dnssec.$tld represent the various steps of the
# initial signing of a zone.
#
for tld in autosign manual; do
# Step 1:
# This is an unsigned zone and named should perform the initial steps of
# introducing the DNSSEC records in the right order.
setup step1.enable-dnssec.$tld
cp template.db.in $zonefile
# Step 2:
# The DNSKEY has been published long enough to become OMNIPRESENT.
setup step2.enable-dnssec.$tld
# DNSKEY TTL: 300 seconds
# zone-propagation-delay: 5 minutes (300 seconds)
# publish-safety: 5 minutes (300 seconds)
# Total: 900 seconds
TpubN="now-900s"
keytimes="-P ${TpubN} -A ${TpubN}"
CSK=$($KEYGEN -k enable-dnssec-$tld -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1)
$SETTIME -s -g $O -k $R $TpubN -r $R $TpubN -d $H $TpubN -z $R $TpubN "$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+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
# Step 3:
# The zone signatures have been published long enough to become OMNIPRESENT.
setup step3.enable-dnssec.$tld
# Passed time since publication:
# max-zone-ttl: 12 hours (43200 seconds)
# zone-propagation-delay: 5 minutes (300 seconds)
TpubN="now-43500s"
# We can submit the DS now.
keytimes="-P ${TpubN} -A ${TpubN}"
CSK=$($KEYGEN -k enable-dnssec-$tld -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1)
$SETTIME -s -g $O -k $O $TpubN -r $O $TpubN -d $H $TpubN -z $R $TpubN "$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+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
# Step 4:
# The DS has been submitted long enough ago to become OMNIPRESENT.
setup step4.enable-dnssec.$tld
# DS TTL: 2 hour (7200 seconds)
# parent-propagation-delay: 1 hour (3600 seconds)
# Total aditional time: 10800 seconds
# 43500 + 10800 = 54300
TpubN="now-54300s"
TsbmN="now-10800s"
keytimes="-P ${TpubN} -A ${TpubN} -P sync ${TsbmN}"
CSK=$($KEYGEN -k enable-dnssec-$tld -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1)
$SETTIME -s -g $O -P ds $TsbmN -k $O $TpubN -r $O $TpubN -d $R $TpubN -z $O $TsbmN "$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+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
done

View file

@ -23,6 +23,11 @@ from rollover.common import (
CDSS,
TIMEDELTA,
)
from rollover.setup import (
configure_root,
configure_tld,
configure_enable_dnssec,
)
CONFIG = {
"dnskey-ttl": TIMEDELTA["PT5M"],
@ -47,6 +52,30 @@ OFFSETS["step3"] = -int(IRETZSK.total_seconds())
OFFSETS["step4"] = -int(IPUBC.total_seconds() + IRETKSK.total_seconds())
def bootstrap():
data = {
"tlds": [],
"trust_anchors": [],
}
tlds = []
for tld_name in [
"autosign",
"manual",
]:
delegations = configure_enable_dnssec(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",
[

View file

@ -0,0 +1 @@
../rollover/ns1

View file

@ -0,0 +1 @@
../rollover/ns2

View file

@ -15,7 +15,7 @@ dnssec-policy "unsigning" {
dnskey-ttl 7200;
keys {
ksk key-directory lifetime unlimited algorithm @DEFAULT_ALGORITHM@;
zsk key-directory lifetime P60D algorithm @DEFAULT_ALGORITHM@;
ksk key-directory lifetime unlimited algorithm ecdsa256;
zsk key-directory lifetime P60D algorithm ecdsa256;
};
};

View file

@ -0,0 +1 @@
../../rollover/ns3/named.common.conf.j2

View file

@ -0,0 +1 @@
../../rollover/ns3/template.db.j2.manual

View file

@ -0,0 +1 @@
../../_common/trusted.conf.j2

View file

@ -1 +0,0 @@
../../rollover-dynamic2inline/ns6/named.common.conf.j2

View file

@ -1 +0,0 @@
../../rollover-dynamic2inline/ns6/template.db.in

View file

@ -1,71 +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 "ns6"
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 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
done

View file

@ -22,6 +22,28 @@ from rollover.common import (
DURATION,
UNSIGNING_CONFIG,
)
from rollover.setup import (
configure_root,
configure_tld,
configure_going_insecure,
)
def bootstrap():
data = {
"tlds": [],
"trust_anchors": [],
}
tlds = []
tld_name = "kasp"
delegations = configure_going_insecure(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(
@ -31,12 +53,12 @@ from rollover.common import (
"going-insecure-dynamic.kasp",
],
)
def test_going_insecure_initial(zone, ns6, alg, size):
def test_going_insecure_initial(zone, ns3, alg, size):
config = UNSIGNING_CONFIG
policy = "unsigning"
zone = f"step1.{zone}"
isctest.kasp.wait_keymgr_done(ns6, zone)
isctest.kasp.wait_keymgr_done(ns3, zone)
step = {
"zone": zone,
@ -47,4 +69,4 @@ def test_going_insecure_initial(zone, ns6, alg, size):
],
"nextev": None,
}
isctest.kasp.check_rollover_step(ns6, config, policy, step)
isctest.kasp.check_rollover_step(ns3, config, policy, step)

View file

@ -23,12 +23,34 @@ from rollover.common import (
DURATION,
UNSIGNING_CONFIG,
)
from rollover.setup import (
configure_root,
configure_tld,
configure_going_insecure,
)
def bootstrap():
data = {
"tlds": [],
"trust_anchors": [],
}
tlds = []
tld_name = "kasp"
delegations = configure_going_insecure(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(ns6, templates):
templates.render("ns6/named.conf", {"policy": "insecure"})
ns6.reconfigure() # move from "unsigning" to "insecure"
def after_servers_start(ns3, templates):
templates.render("ns3/named.conf", {"policy": "insecure"})
ns3.reconfigure() # move from "unsigning" to "insecure"
@pytest.mark.parametrize(
@ -38,12 +60,12 @@ def after_servers_start(ns6, templates):
"going-insecure-dynamic.kasp",
],
)
def test_going_insecure_reconfig_step1(zone, alg, size, ns6):
def test_going_insecure_reconfig_step1(zone, alg, size, ns3):
config = DEFAULT_CONFIG
policy = "insecure"
zone = f"step1.{zone}"
isctest.kasp.wait_keymgr_done(ns6, zone, reconfig=True)
isctest.kasp.wait_keymgr_done(ns3, zone, reconfig=True)
# Key goal states should be HIDDEN.
# The DS may be removed if we are going insecure.
@ -61,7 +83,7 @@ def test_going_insecure_reconfig_step1(zone, alg, size, ns6):
"cds-delete": True,
"check-keytimes": False,
}
isctest.kasp.check_rollover_step(ns6, config, policy, step)
isctest.kasp.check_rollover_step(ns3, config, policy, step)
@pytest.mark.parametrize(
@ -71,12 +93,12 @@ def test_going_insecure_reconfig_step1(zone, alg, size, ns6):
"going-insecure-dynamic.kasp",
],
)
def test_going_insecure_reconfig_step2(zone, alg, size, ns6):
def test_going_insecure_reconfig_step2(zone, alg, size, ns3):
config = DEFAULT_CONFIG
policy = "insecure"
zone = f"step2.{zone}"
isctest.kasp.wait_keymgr_done(ns6, zone, reconfig=True)
isctest.kasp.wait_keymgr_done(ns3, zone, reconfig=True)
# The DS is long enough removed from the zone to be considered
# HIDDEN. This means the DNSKEY and the KSK signatures can be
@ -96,4 +118,4 @@ def test_going_insecure_reconfig_step2(zone, alg, size, ns6):
"zone-signed": False,
"check-keytimes": False,
}
isctest.kasp.check_rollover_step(ns6, config, policy, step)
isctest.kasp.check_rollover_step(ns3, config, policy, step)

View file

@ -0,0 +1 @@
../rollover/ns1

View file

@ -0,0 +1 @@
../rollover/ns2

View file

@ -0,0 +1 @@
../../rollover-ksk-doubleksk/ns3/kasp.conf

View file

@ -1 +0,0 @@
../../rollover-ksk-doubleksk/ns3/kasp.conf.j2

View file

@ -1 +0,0 @@
../../rollover/ns3/template.db.in

View file

@ -0,0 +1 @@
../../rollover/ns3/template.db.j2.manual

View file

@ -0,0 +1 @@
../../_common/trusted.conf.j2

View file

@ -1,82 +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"
# Test #2375, the "three is a crowd" bug, where a new key is introduced but the
# previous rollover has not finished yet. In other words, we have a key KEY2
# that is the successor of key KEY1, and we introduce a new key KEY3 that is
# the successor of key KEY2:
#
# KEY1 < KEY2 < KEY3.
#
# The expected behavior is that all three keys remain in the zone, and not
# the bug behavior where KEY2 is removed and immediately replaced with KEY3.
#
# Set up a zone that has a KSK (KEY1) and have the successor key (KEY2)
# published as well.
setup three-is-a-crowd.kasp
# These times are the same as step3.ksk-doubleksk.autosign.
TpubN="now-60d"
TactN="now-1413h"
TretN="now"
TremN="now+50h"
TpubN1="now-27h"
TsbmN1="now"
TactN1="${TretN}"
TretN1="now+60d"
TremN1="now+1490h"
ksktimes="-P ${TpubN} -A ${TpubN} -P sync ${TactN} -I ${TretN} -D ${TremN} -D sync ${TactN1}"
newtimes="-P ${TpubN1} -A ${TactN1} -P sync ${TsbmN1} -I ${TretN1} -D ${TremN1}"
zsktimes="-P ${TpubN} -A ${TpubN}"
KSK1=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $ksktimes $zone 2>keygen.out.$zone.1)
KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $newtimes $zone 2>keygen.out.$zone.2)
ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 $zsktimes $zone 2>keygen.out.$zone.3)
$SETTIME -s -g $H -k $O $TactN -r $O $TactN -d $O $TactN "$KSK1" >settime.out.$zone.1 2>&1
$SETTIME -s -g $O -k $R $TpubN1 -r $R $TpubN1 -d $H $TpubN1 "$KSK2" >settime.out.$zone.2 2>&1
$SETTIME -s -g $O -k $O $TactN -z $O $TactN "$ZSK" >settime.out.$zone.3 2>&1
# Set key rollover relationship.
key_successor $KSK1 $KSK2
# Sign zone.
cat template.db.in "${KSK1}.key" "${KSK2}.key" "${ZSK}.key" >"$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK1" >>"$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile"
cp $infile $zonefile
$SIGNER -S -x -G "cds:sha-256" -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1

View file

@ -24,6 +24,11 @@ from rollover.common import (
KSK_IPUB,
KSK_IRET,
)
from rollover.setup import (
configure_root,
configure_tld,
configure_ksk_3crowd,
)
CDSS = ["CDS (SHA-256)"]
@ -33,6 +38,23 @@ OFFSET2 = -int(timedelta(hours=27).total_seconds())
TTL = int(KSK_CONFIG["dnskey-ttl"].total_seconds())
def bootstrap():
data = {
"tlds": [],
"trust_anchors": [],
}
tlds = []
tld_name = "kasp"
delegations = configure_ksk_3crowd(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
def test_rollover_ksk_three_is_a_crowd(alg, size, ns3):
"""Test #2375: Scheduled rollovers are happening faster than they can finish."""
zone = "three-is-a-crowd.kasp"

View file

@ -0,0 +1 @@
../rollover/ns1

View file

@ -0,0 +1 @@
../rollover/ns2

View file

@ -23,8 +23,8 @@ dnssec-policy "ksk-doubleksk-autosign" {
cdnskey no;
keys {
ksk key-directory lifetime P60D algorithm @DEFAULT_ALGORITHM@;
zsk key-directory lifetime unlimited algorithm @DEFAULT_ALGORITHM@;
ksk key-directory lifetime P60D algorithm ecdsa256;
zsk key-directory lifetime unlimited algorithm ecdsa256;
};
zone-propagation-delay PT1H;
@ -48,8 +48,8 @@ dnssec-policy "ksk-doubleksk-manual" {
cdnskey no;
keys {
ksk key-directory lifetime P60D algorithm @DEFAULT_ALGORITHM@;
zsk key-directory lifetime unlimited algorithm @DEFAULT_ALGORITHM@;
ksk key-directory lifetime P60D algorithm ecdsa256;
zsk key-directory lifetime unlimited algorithm ecdsa256;
};
zone-propagation-delay PT1H;

View file

@ -1 +0,0 @@
../../rollover/ns3/template.db.in

View file

@ -0,0 +1 @@
../../rollover/ns3/template.db.j2.manual

View file

@ -0,0 +1 @@
../../_common/trusted.conf.j2

View file

@ -1,243 +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 ksk-doubleksk.$tld represent the various steps of a KSK
# Double-KSK rollover.
#
for tld in autosign manual; do
# Step 1:
# Introduce the first key. This will immediately be active.
setup step1.ksk-doubleksk.$tld
TactN="now-7d"
keytimes="-P ${TactN} -A ${TactN}"
KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $keytimes $zone 2>keygen.out.$zone.1)
ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 $keytimes $zone 2>keygen.out.$zone.2)
$SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN "$KSK" >settime.out.$zone.1 2>&1
$SETTIME -s -g $O -k $O $TactN -z $O $TactN "$ZSK" >settime.out.$zone.2 2>&1
cat template.db.in "${KSK}.key" "${ZSK}.key" >"$infile"
cp $infile $zonefile
$SIGNER -S -x -G "cds:sha-256" -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
# Step 2:
# It is time to submit the introduce the new KSK.
setup step2.ksk-doubleksk.$tld
# Lksk: 60d
# Dreg: n/a
# DprpC: 1h
# TTLds: 1d
# TTLkey: 2h
# publish-safety: 1d
# retire-safety: 2d
#
# According to RFC 7583:
# Tpub(N+1) <= Tact(N) + Lksk - Dreg - IpubC
# IpubC = DprpC + TTLkey (+publish-safety)
#
# IpubC = 27h
# Tact(N) = now - Lksk + Dreg + IpubC = now - 60d + 27h
# = now - 1440h + 27h = now - 1413h
TactN="now-1413h"
keytimes="-P ${TactN} -A ${TactN}"
KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $keytimes $zone 2>keygen.out.$zone.1)
ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 $keytimes $zone 2>keygen.out.$zone.2)
$SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN "$KSK" >settime.out.$zone.1 2>&1
$SETTIME -s -g $O -k $O $TactN -z $O $TactN "$ZSK" >settime.out.$zone.2 2>&1
cat template.db.in "${KSK}.key" "${ZSK}.key" >"$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK" >>"$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile"
cp $infile $zonefile
$SIGNER -S -x -G "cds:sha-256" -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
# Step 3:
# It is time to submit the DS.
setup step3.ksk-doubleksk.$tld
# According to RFC 7583:
# Iret = DprpP + TTLds (+retire-safety)
#
# Iret = 50h
# Tpub(N) = now - Lksk = now - 60d = now - 60d
# Tact(N) = now - 1413h
# Tret(N) = now
# Trem(N) = now + Iret = now + 50h
# Tpub(N+1) = now - IpubC = now - 27h
# Tact(N+1) = now
# Tret(N+1) = now + Lksk = now + 60d
# Trem(N+1) = now + Lksk + Iret = now + 60d + 50h
# = now + 1440h + 50h = 1490h
TpubN="now-60d"
TactN="now-1413h"
TretN="now"
TremN="now+50h"
TpubN1="now-27h"
TactN1="now"
TretN1="now+60d"
TremN1="now+1490h"
ksktimes="-P ${TpubN} -A ${TpubN} -P sync ${TactN} -I ${TretN} -D ${TremN} -D sync ${TactN1}"
newtimes="-P ${TpubN1} -A ${TactN1} -P sync ${TactN1} -I ${TretN1} -D ${TremN1}"
zsktimes="-P ${TpubN} -A ${TpubN}"
KSK1=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $ksktimes $zone 2>keygen.out.$zone.1)
KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $newtimes $zone 2>keygen.out.$zone.2)
ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 $zsktimes $zone 2>keygen.out.$zone.3)
$SETTIME -s -g $H -k $O $TpubN -r $O $TpubN -d $O $TactN "$KSK1" >settime.out.$zone.1 2>&1
$SETTIME -s -g $O -k $R $TpubN1 -r $R $TpubN1 -d $H $TpubN1 "$KSK2" >settime.out.$zone.2 2>&1
$SETTIME -s -g $O -k $O $TpubN -z $O $TpubN "$ZSK" >settime.out.$zone.3 2>&1
# Set key rollover relationship.
key_successor $KSK1 $KSK2
# Sign zone.
cat template.db.in "${KSK1}.key" "${KSK2}.key" "${ZSK}.key" >"$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK1" >>"$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile"
cp $infile $zonefile
$SIGNER -S -x -G "cds:sha-256" -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
# Step 4:
# The DS should be swapped now.
setup step4.ksk-doubleksk.$tld
# Tpub(N) = now - Lksk - Iret = now - 60d - 50h
# = now - 1440h - 50h = now - 1490h
# Tact(N) = now - 1490h + 27h = now - 1463h
# Tret(N) = now - Iret = now - 50h
# Trem(N) = now
# Tpub(N+1) = now - Iret - IpubC = now - 50h - 27h
# = now - 77h
# Tact(N+1) = Tret(N)
# Tret(N+1) = now + Lksk - Iret = now + 60d - 50h = now + 1390h
# Trem(N+1) = now + Lksk = now + 60d
TpubN="now-1490h"
TactN="now-1463h"
TretN="now-50h"
TremN="now"
TpubN1="now-77h"
TactN1="${TretN}"
TretN1="now+1390h"
TremN1="now+60d"
ksktimes="-P ${TpubN} -A ${TpubN} -P sync ${TactN} -I ${TretN} -D ${TremN} -D sync ${TactN1}"
newtimes="-P ${TpubN1} -A ${TactN1} -P sync ${TactN1} -I ${TretN1} -D ${TremN1}"
zsktimes="-P ${TpubN} -A ${TpubN}"
KSK1=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $ksktimes $zone 2>keygen.out.$zone.1)
KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $newtimes $zone 2>keygen.out.$zone.2)
ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 $zsktimes $zone 2>keygen.out.$zone.3)
$SETTIME -s -g $H -k $O $TactN -r $O $TactN -d $U $TretN -D ds $TretN "$KSK1" >settime.out.$zone.1 2>&1
$SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $R $TactN1 -P ds $TactN1 "$KSK2" >settime.out.$zone.2 2>&1
$SETTIME -s -g $O -k $O $TactN -z $O $TactN "$ZSK" >settime.out.$zone.3 2>&1
# Set key rollover relationship.
key_successor $KSK1 $KSK2
# Sign zone.
cat template.db.in "${KSK1}.key" "${KSK2}.key" "${ZSK}.key" >"$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK1" >>"$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile"
cp $infile $zonefile
$SIGNER -S -x -G "cds:sha-256" -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
# Step 5:
# The predecessor DNSKEY is removed long enough that is has become HIDDEN.
setup step5.ksk-doubleksk.$tld
# Subtract DNSKEY TTL + zone-propagation-delay from all the times (3h).
# Tpub(N) = now - 1490h - 3h = now - 1493h
# Tact(N) = now - 1463h - 3h = now - 1466h
# Tret(N) = now - 50h - 3h = now - 53h
# Trem(N) = now - 3h
# Tpub(N+1) = now - 77h - 3h = now - 80h
# Tact(N+1) = Tret(N)
# Tret(N+1) = now + 1390h - 3h = now + 1387h
# Trem(N+1) = now + 60d - 3h = now + 1441h
TpubN="now-1493h"
TactN="now-1466h"
TretN="now-53h"
TremN="now-3h"
TpubN1="now-80h"
TactN1="${TretN}"
TretN1="now+1387h"
TremN1="now+1441h"
ksktimes="-P ${TpubN} -A ${TpubN} -P sync ${TactN} -I ${TretN} -D ${TremN} -D sync ${TactN1}"
newtimes="-P ${TpubN1} -A ${TactN1} -P sync ${TactN1} -I ${TretN1} -D ${TremN1}"
zsktimes="-P ${TpubN} -A ${TpubN}"
KSK1=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $ksktimes $zone 2>keygen.out.$zone.1)
KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $newtimes $zone 2>keygen.out.$zone.2)
ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 $zsktimes $zone 2>keygen.out.$zone.3)
$SETTIME -s -g $H -k $U $TretN -r $U $TretN -d $H $TretN "$KSK1" >settime.out.$zone.1 2>&1
$SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $O $TactN1 "$KSK2" >settime.out.$zone.2 2>&1
$SETTIME -s -g $O -k $O $TactN -z $O $TactN "$ZSK" >settime.out.$zone.3 2>&1
# Set key rollover relationship.
key_successor $KSK1 $KSK2
# Sign zone.
cat template.db.in "${KSK1}.key" "${KSK2}.key" "${ZSK}.key" >"$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK1" >>"$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile"
cp $infile $zonefile
$SIGNER -S -x -G "cds:sha-256" -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
# Step 6:
# The predecessor DNSKEY can be purged.
setup step6.ksk-doubleksk.$tld
# Subtract purge-keys interval from all the times (1h).
TpubN="now-1494h"
TactN="now-1467h"
TretN="now-54h"
TremN="now-4h"
TpubN1="now-81h"
TactN1="${TretN}"
TretN1="now+1386h"
TremN1="now+1440h"
ksktimes="-P ${TpubN} -A ${TpubN} -P sync ${TactN} -I ${TretN} -D ${TremN} -D sync ${TactN1}"
newtimes="-P ${TpubN1} -A ${TactN1} -P sync ${TactN1} -I ${TretN1} -D ${TremN1}"
zsktimes="-P ${TpubN} -A ${TpubN}"
KSK1=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $ksktimes $zone 2>keygen.out.$zone.1)
KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $newtimes $zone 2>keygen.out.$zone.2)
ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 $zsktimes $zone 2>keygen.out.$zone.3)
$SETTIME -s -g $H -k $H $TretN -r $H $TretN -d $H $TretN "$KSK1" >settime.out.$zone.1 2>&1
$SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $O $TactN1 "$KSK2" >settime.out.$zone.2 2>&1
$SETTIME -s -g $O -k $O $TactN -z $O $TactN "$ZSK" >settime.out.$zone.3 2>&1
# Set key rollover relationship.
key_successor $KSK1 $KSK2
# Sign zone.
cat template.db.in "${KSK1}.key" "${KSK2}.key" "${ZSK}.key" >"$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK1" >>"$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile"
cp $infile $zonefile
$SIGNER -S -x -G "cds:sha-256" -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
done

View file

@ -30,7 +30,11 @@ from rollover.common import (
KSK_KEYTTLPROP,
TIMEDELTA,
)
from rollover.setup import (
configure_root,
configure_tld,
configure_ksk_doubleksk,
)
CDSS = ["CDS (SHA-256)"]
POLICY = "ksk-doubleksk"
@ -48,6 +52,30 @@ OFFSETS["step6-p"] = OFFSETS["step5-p"] - int(KSK_CONFIG["purge-keys"].total_sec
OFFSETS["step6-s"] = OFFSETS["step5-s"] - int(KSK_CONFIG["purge-keys"].total_seconds())
def bootstrap():
data = {
"tlds": [],
"trust_anchors": [],
}
tlds = []
for tld_name in [
"autosign",
"manual",
]:
delegations = configure_ksk_doubleksk(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",
[

View file

@ -0,0 +1 @@
template.db.in

View file

@ -0,0 +1 @@
template.db.in

View file

@ -0,0 +1 @@
../../rollover/ns3/named.common.conf.j2

View file

@ -20,25 +20,25 @@
include "kasp.conf";
include "named.common.conf";
zone longer-lifetime {
zone longer-lifetime.kasp {
type primary;
file "longer-lifetime.db";
dnssec-policy @longer@;
};
zone shorter-lifetime {
zone shorter-lifetime.kasp {
type primary;
file "shorter-lifetime.db";
dnssec-policy @shorter@;
};
zone limit-lifetime {
zone limit-lifetime.kasp {
type primary;
file "limit-lifetime.db";
dnssec-policy @limit@;
};
zone unlimit-lifetime {
zone unlimit-lifetime.kasp {
type primary;
file "unlimit-lifetime.db";
dnssec-policy @unlimit@;

View file

@ -0,0 +1 @@
template.db.in

View file

@ -18,8 +18,8 @@ $TTL 300
3600 ; minimum (1 hour)
)
NS ns6
ns6 A 10.53.0.6
NS ns3
ns3 A 10.53.0.3
a A 10.0.0.1
b A 10.0.0.2

View file

@ -0,0 +1 @@
template.db.in

View file

@ -1 +0,0 @@
../../rollover-dynamic2inline/ns6/template.db.in

View file

@ -1 +0,0 @@
../../rollover-dynamic2inline/ns6/template.db.in

View file

@ -1 +0,0 @@
../../rollover-dynamic2inline/ns6/named.common.conf.j2

View file

@ -1 +0,0 @@
../../rollover-dynamic2inline/ns6/template.db.in

View file

@ -1 +0,0 @@
../../rollover-dynamic2inline/ns6/template.db.in

View file

@ -34,17 +34,17 @@ from rollover.common import (
param("unlimit-lifetime", "short-lifetime", "P6M"),
],
)
def test_lifetime_initial(zone, policy, lifetime, alg, size, ns6):
def test_lifetime_initial(zone, policy, lifetime, alg, size, ns3):
config = DEFAULT_CONFIG
isctest.kasp.wait_keymgr_done(ns6, zone)
isctest.kasp.wait_keymgr_done(ns3, f"{zone}.kasp")
step = {
"zone": zone,
"zone": f"{zone}.kasp",
"cdss": CDSS,
"keyprops": [
f"csk {DURATION[lifetime]} {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured zrrsig:rumoured ds:hidden",
],
"nextev": None,
}
isctest.kasp.check_rollover_step(ns6, config, policy, step)
isctest.kasp.check_rollover_step(ns3, config, policy, step)

View file

@ -26,14 +26,14 @@ from rollover.common import (
@pytest.fixture(scope="module", autouse=True)
def after_servers_start(ns6, templates):
isctest.kasp.wait_keymgr_done(ns6, "shorter-lifetime")
isctest.kasp.wait_keymgr_done(ns6, "longer-lifetime")
isctest.kasp.wait_keymgr_done(ns6, "limit-lifetime")
isctest.kasp.wait_keymgr_done(ns6, "unlimit-lifetime")
def after_servers_start(ns3, templates):
isctest.kasp.wait_keymgr_done(ns3, "shorter-lifetime.kasp")
isctest.kasp.wait_keymgr_done(ns3, "longer-lifetime.kasp")
isctest.kasp.wait_keymgr_done(ns3, "limit-lifetime.kasp")
isctest.kasp.wait_keymgr_done(ns3, "unlimit-lifetime.kasp")
templates.render("ns6/named.conf", {"change_lifetime": True})
ns6.reconfigure()
templates.render("ns3/named.conf", {"change_lifetime": True})
ns3.reconfigure()
@pytest.mark.parametrize(
@ -49,17 +49,17 @@ def after_servers_start(ns6, templates):
param("unlimit-lifetime", "unlimited-lifetime", 0),
],
)
def test_lifetime_reconfig(zone, policy, lifetime, alg, size, ns6):
def test_lifetime_reconfig(zone, policy, lifetime, alg, size, ns3):
config = DEFAULT_CONFIG
isctest.kasp.wait_keymgr_done(ns6, zone, reconfig=True)
isctest.kasp.wait_keymgr_done(ns3, f"{zone}.kasp", reconfig=True)
step = {
"zone": zone,
"zone": f"{zone}.kasp",
"cdss": CDSS,
"keyprops": [
f"csk {DURATION[lifetime]} {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured zrrsig:rumoured ds:hidden",
],
"nextev": None,
}
isctest.kasp.check_rollover_step(ns6, config, policy, step)
isctest.kasp.check_rollover_step(ns3, config, policy, step)

Some files were not shown because too many files have changed in this diff Show more