Isolate rollover-algo-ksk-zsk test

This commit is contained in:
Nicki Křížek 2025-06-06 16:09:55 +02:00
parent 519f9082df
commit 8be9a8b52a
12 changed files with 533 additions and 361 deletions

View file

@ -0,0 +1 @@
../rollover/common.py

View file

@ -0,0 +1,50 @@
/*
* 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.
*/
dnssec-policy "rsasha256" {
signatures-refresh P5D;
signatures-validity 30d;
signatures-validity-dnskey 30d;
keys {
ksk lifetime unlimited algorithm rsasha256;
zsk lifetime unlimited algorithm rsasha256;
};
dnskey-ttl 1h;
publish-safety PT1H;
retire-safety 2h;
zone-propagation-delay 3600;
max-zone-ttl 6h;
parent-propagation-delay pt1h;
parent-ds-ttl 7200;
};
dnssec-policy "ecdsa256" {
signatures-refresh P5D;
signatures-validity 30d;
signatures-validity-dnskey 30d;
keys {
ksk lifetime unlimited algorithm ecdsa256;
zsk lifetime unlimited algorithm ecdsa256;
};
dnskey-ttl 1h;
publish-safety PT1H;
retire-safety 2h;
zone-propagation-delay 3600;
max-zone-ttl 6h;
parent-propagation-delay pt1h;
parent-ds-ttl 7200;
};

View file

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

View file

@ -0,0 +1,56 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* SPDX-License-Identifier: MPL-2.0
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
{% set alg_roll = alg_roll | default(False) %}
{% set policy = "rsasha256" if not alg_roll else "ecdsa256" %}
include "kasp.conf";
include "named.common.conf";
zone "step1.algorithm-roll.kasp" {
type primary;
file "step1.algorithm-roll.kasp.db";
dnssec-policy @policy@;
};
{% if alg_roll %}
zone "step2.algorithm-roll.kasp" {
type primary;
file "step2.algorithm-roll.kasp.db";
dnssec-policy "ecdsa256";
};
zone "step3.algorithm-roll.kasp" {
type primary;
file "step3.algorithm-roll.kasp.db";
dnssec-policy "ecdsa256";
};
zone "step4.algorithm-roll.kasp" {
type primary;
file "step4.algorithm-roll.kasp.db";
dnssec-policy "ecdsa256";
};
zone "step5.algorithm-roll.kasp" {
type primary;
file "step5.algorithm-roll.kasp.db";
dnssec-policy "ecdsa256";
};
zone "step6.algorithm-roll.kasp" {
type primary;
file "step6.algorithm-roll.kasp.db";
dnssec-policy "ecdsa256";
};
{% endif %}

View file

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

View file

@ -0,0 +1,199 @@
#!/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.kasp represent the various steps of a ZSK/KSK
# algorithm rollover.
#
# Step 1:
# Introduce the first key. This will immediately be active.
setup step1.algorithm-roll.kasp
echo "$zone" >>zones
TactN="now-7d"
TsbmN="now-161h"
ksktimes="-P ${TactN} -A ${TactN}"
zsktimes="-P ${TactN} -A ${TactN}"
KSK=$($KEYGEN -a RSASHA256 -L 3600 -f KSK $ksktimes $zone 2>keygen.out.$zone.1)
ZSK=$($KEYGEN -a RSASHA256 -L 3600 $zsktimes $zone 2>keygen.out.$zone.2)
$SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN "$KSK" >settime.out.$zone.1 2>&1
$SETTIME -s -g $O -k $O $TactN -z $O $TactN "$ZSK" >settime.out.$zone.2 2>&1
cat template.db.in "${KSK}.key" "${ZSK}.key" >"$infile"
private_type_record $zone 8 "$KSK" >>"$infile"
private_type_record $zone 8 "$ZSK" >>"$infile"
cp $infile $zonefile
$SIGNER -S -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
# Step 2:
# After the publication interval has passed the DNSKEY is OMNIPRESENT.
setup step2.algorithm-roll.kasp
# The time passed since the new algorithm keys have been introduced is 3 hours.
TpubN1="now-3h"
# Tsbm(N+1) = TpubN1 + Ipub = now + TTLsig + Dprp = now - 3h + 6h + 1h = now + 4h
TsbmN1="now+4h"
ksk1times="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I ${TsbmN1}"
zsk1times="-P ${TactN} -A ${TactN} -I ${TsbmN1}"
ksk2times="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}"
zsk2times="-P ${TpubN1} -A ${TpubN1}"
KSK1=$($KEYGEN -a RSASHA256 -L 3600 -f KSK $ksk1times $zone 2>keygen.out.$zone.1)
ZSK1=$($KEYGEN -a RSASHA256 -L 3600 $zsk1times $zone 2>keygen.out.$zone.2)
KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $ksk2times $zone 2>keygen.out.$zone.3)
ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $zsk2times $zone 2>keygen.out.$zone.4)
$SETTIME -s -g $H -k $O $TactN -r $O $TactN -d $O $TactN "$KSK1" >settime.out.$zone.1 2>&1
$SETTIME -s -g $H -k $O $TactN -z $O $TactN "$ZSK1" >settime.out.$zone.2 2>&1
$SETTIME -s -g $O -k $R $TpubN1 -r $R $TpubN1 -d $H $TpubN1 "$KSK2" >settime.out.$zone.3 2>&1
$SETTIME -s -g $O -k $R $TpubN1 -z $R $TpubN1 "$ZSK2" >settime.out.$zone.4 2>&1
# Fake lifetime of old algorithm keys.
echo "Lifetime: 0" >>"${KSK1}.state"
echo "Lifetime: 0" >>"${ZSK1}.state"
cat template.db.in "${KSK1}.key" "${ZSK1}.key" "${KSK2}.key" "${ZSK2}.key" >"$infile"
private_type_record $zone 8 "$KSK1" >>"$infile"
private_type_record $zone 8 "$ZSK1" >>"$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK2" >>"$infile"
cp $infile $zonefile
$SIGNER -S -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
# Step 3:
# The zone signatures are also OMNIPRESENT.
setup step3.algorithm-roll.kasp
# The time passed since the new algorithm keys have been introduced is 7 hours.
TpubN1="now-7h"
TsbmN1="now"
ksk1times="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I ${TsbmN1}"
zsk1times="-P ${TactN} -A ${TactN} -I ${TsbmN1}"
ksk2times="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}"
zsk2times="-P ${TpubN1} -A ${TpubN1}"
KSK1=$($KEYGEN -a RSASHA256 -L 3600 -f KSK $ksk1times $zone 2>keygen.out.$zone.1)
ZSK1=$($KEYGEN -a RSASHA256 -L 3600 $zsk1times $zone 2>keygen.out.$zone.2)
KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $ksk2times $zone 2>keygen.out.$zone.3)
ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $zsk2times $zone 2>keygen.out.$zone.4)
$SETTIME -s -g $H -k $O $TactN -r $O $TactN -d $O $TactN "$KSK1" >settime.out.$zone.1 2>&1
$SETTIME -s -g $H -k $O $TactN -z $O $TactN "$ZSK1" >settime.out.$zone.2 2>&1
$SETTIME -s -g $O -k $O $TpubN1 -r $O $TpubN1 -d $H $TpubN1 "$KSK2" >settime.out.$zone.3 2>&1
$SETTIME -s -g $O -k $O $TpubN1 -z $R $TpubN1 "$ZSK2" >settime.out.$zone.4 2>&1
# Fake lifetime of old algorithm keys.
echo "Lifetime: 0" >>"${KSK1}.state"
echo "Lifetime: 0" >>"${ZSK1}.state"
cat template.db.in "${KSK1}.key" "${ZSK1}.key" "${KSK2}.key" "${ZSK2}.key" >"$infile"
private_type_record $zone 8 "$KSK1" >>"$infile"
private_type_record $zone 8 "$ZSK1" >>"$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK2" >>"$infile"
cp $infile $zonefile
$SIGNER -S -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
# Step 4:
# The DS is swapped and can become OMNIPRESENT.
setup step4.algorithm-roll.kasp
# The time passed since the DS has been swapped is 3 hours.
TpubN1="now-10h"
TsbmN1="now-3h"
ksk1times="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I ${TsbmN1}"
zsk1times="-P ${TactN} -A ${TactN} -I ${TsbmN1}"
ksk2times="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}"
zsk2times="-P ${TpubN1} -A ${TpubN1}"
KSK1=$($KEYGEN -a RSASHA256 -L 3600 -f KSK $ksk1times $zone 2>keygen.out.$zone.1)
ZSK1=$($KEYGEN -a RSASHA256 -L 3600 $zsk1times $zone 2>keygen.out.$zone.2)
KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $ksk2times $zone 2>keygen.out.$zone.3)
ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $zsk2times $zone 2>keygen.out.$zone.4)
$SETTIME -s -g $H -k $O $TactN -r $O $TactN -d $U $TsbmN1 -D ds $TsbmN1 "$KSK1" >settime.out.$zone.1 2>&1
$SETTIME -s -g $H -k $O $TactN -z $O $TactN "$ZSK1" >settime.out.$zone.2 2>&1
$SETTIME -s -g $O -k $O $TpubN1 -r $O $TpubN1 -d $R $TsbmN1 -P ds $TsbmN1 "$KSK2" >settime.out.$zone.3 2>&1
$SETTIME -s -g $O -k $O $TpubN1 -z $R $TpubN1 "$ZSK2" >settime.out.$zone.4 2>&1
# Fake lifetime of old algorithm keys.
echo "Lifetime: 0" >>"${KSK1}.state"
echo "Lifetime: 0" >>"${ZSK1}.state"
cat template.db.in "${KSK1}.key" "${ZSK1}.key" "${KSK2}.key" "${ZSK2}.key" >"$infile"
private_type_record $zone 8 "$KSK1" >>"$infile"
private_type_record $zone 8 "$ZSK1" >>"$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK2" >>"$infile"
cp $infile $zonefile
$SIGNER -S -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
# Step 5:
# The DNSKEY is removed long enough to be HIDDEN.
setup step5.algorithm-roll.kasp
# The time passed since the DNSKEY has been removed is 2 hours.
TpubN1="now-12h"
TsbmN1="now-5h"
ksk1times="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I ${TsbmN1}"
zsk1times="-P ${TactN} -A ${TactN} -I ${TsbmN1}"
ksk2times="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}"
zsk2times="-P ${TpubN1} -A ${TpubN1}"
KSK1=$($KEYGEN -a RSASHA256 -L 3600 -f KSK $ksk1times $zone 2>keygen.out.$zone.1)
ZSK1=$($KEYGEN -a RSASHA256 -L 3600 $zsk1times $zone 2>keygen.out.$zone.2)
KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $ksk2times $zone 2>keygen.out.$zone.3)
ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $zsk2times $zone 2>keygen.out.$zone.4)
$SETTIME -s -g $H -k $U $TsbmN1 -r $U $TsbmN1 -d $H $TsbmN1 "$KSK1" >settime.out.$zone.1 2>&1
$SETTIME -s -g $H -k $U $TsbmN1 -z $U $TsbmN1 "$ZSK1" >settime.out.$zone.2 2>&1
$SETTIME -s -g $O -k $O $TpubN1 -r $O $TpubN1 -d $O $TsbmN1 "$KSK2" >settime.out.$zone.3 2>&1
$SETTIME -s -g $O -k $O $TpubN1 -z $R $TpubN1 "$ZSK2" >settime.out.$zone.4 2>&1
# Fake lifetime of old algorithm keys.
echo "Lifetime: 0" >>"${KSK1}.state"
echo "Lifetime: 0" >>"${ZSK1}.state"
cat template.db.in "${KSK1}.key" "${ZSK1}.key" "${KSK2}.key" "${ZSK2}.key" >"$infile"
private_type_record $zone 8 "$KSK1" >>"$infile"
private_type_record $zone 8 "$ZSK1" >>"$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK2" >>"$infile"
cp $infile $zonefile
$SIGNER -S -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
# Step 6:
# The RRSIGs have been removed long enough to be HIDDEN.
setup step6.algorithm-roll.kasp
# Additional time passed: 7h.
TpubN1="now-19h"
TsbmN1="now-12h"
ksk1times="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I ${TsbmN1}"
zsk1times="-P ${TactN} -A ${TactN} -I ${TsbmN1}"
ksk2times="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}"
zsk2times="-P ${TpubN1} -A ${TpubN1}"
KSK1=$($KEYGEN -a RSASHA256 -L 3600 -f KSK $ksk1times $zone 2>keygen.out.$zone.1)
ZSK1=$($KEYGEN -a RSASHA256 -L 3600 $zsk1times $zone 2>keygen.out.$zone.2)
KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $ksk2times $zone 2>keygen.out.$zone.3)
ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $zsk2times $zone 2>keygen.out.$zone.4)
$SETTIME -s -g $H -k $H $TsbmN1 -r $U $TsbmN1 -d $H $TsbmN1 "$KSK1" >settime.out.$zone.1 2>&1
$SETTIME -s -g $H -k $H $TsbmN1 -z $U $TsbmN1 "$ZSK1" >settime.out.$zone.2 2>&1
$SETTIME -s -g $O -k $O $TpubN1 -r $O $TpubN1 -d $O $TsbmN1 "$KSK2" >settime.out.$zone.3 2>&1
$SETTIME -s -g $O -k $O $TpubN1 -z $R $TpubN1 "$ZSK2" >settime.out.$zone.4 2>&1
# Fake lifetime of old algorithm keys.
echo "Lifetime: 0" >>"${KSK1}.state"
echo "Lifetime: 0" >>"${ZSK1}.state"
cat template.db.in "${KSK1}.key" "${ZSK1}.key" "${KSK2}.key" "${ZSK2}.key" >"$infile"
private_type_record $zone 8 "$KSK1" >>"$infile"
private_type_record $zone 8 "$ZSK1" >>"$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK2" >>"$infile"
cp $infile $zonefile
$SIGNER -S -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1

View file

@ -0,0 +1,37 @@
# 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.
# pylint: disable=unused-import
import isctest
from common import (
pytestmark,
CDSS,
DURATION,
TIMEDELTA,
ALGOROLL_CONFIG,
)
def test_algoroll_ksk_zsk_initial(servers):
config = ALGOROLL_CONFIG
policy = "rsasha256"
step = {
"zone": "step1.algorithm-roll.kasp",
"cdss": CDSS,
"keyprops": [
f"ksk 0 8 2048 goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{-DURATION['P7D']}",
f"zsk 0 8 2048 goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{-DURATION['P7D']}",
],
"nextev": TIMEDELTA["PT1H"],
}
isctest.kasp.check_rollover_step(servers["ns6"], config, policy, step)

View file

@ -0,0 +1,173 @@
# 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.
# pylint: disable=redefined-outer-name,unused-import
import pytest
import isctest
from isctest.kasp import KeyTimingMetadata
from common import (
pytestmark,
alg,
size,
CDSS,
ALGOROLL_CONFIG,
TIMEDELTA,
)
IPUB = Ipub(ALGOROLL_CONFIG)
IPUBC = IpubC(ALGOROLL_CONFIG, rollover=False)
IRET = Iret(ALGOROLL_CONFIG, rollover=False)
IRETKSK = Iret(ALGOROLL_CONFIG, zsk=False, ksk=True, rollover=False)
KEYTTLPROP = ALGOROLL_CONFIG["dnskey-ttl"] + ALGOROLL_CONFIG["zone-propagation-delay"]
OFFSETS = {}
OFFSETS["step2"] = -int(IPUB.total_seconds())
OFFSETS["step3"] = -int(IRET.total_seconds())
OFFSETS["step4"] = OFFSETS["step3"] - int(IRETKSK.total_seconds())
OFFSETS["step5"] = OFFSETS["step4"] - int(KEYTTLPROP.total_seconds())
OFFSETS["step6"] = OFFSETS["step5"] - int(IRET.total_seconds())
OFFVAL = -DURATION["P7D"]
CONFIG = ALGOROLL_CONFIG
POLICY = "ecdsa256"
TIME_PASSED = 0 # set in reconfigure() fixture
@pytest.fixture(scope="module", autouse=True)
def reconfigure(servers, templates):
global TIME_PASSED # pylint: disable=global-statement
start_time = KeyTimingMetadata.now()
templates.render("ns6/named.conf", {"alg_roll": True})
servers["ns6"].reconfigure()
# Calculate time passed to correctly check for next key events.
TIME_PASSED = KeyTimingMetadata.now().value - start_time.value
def test_algoroll_ksk_zsk_reconfig_step1(servers, alg, size):
step = {
"zone": "step1.algorithm-roll.kasp",
"cdss": CDSS,
"keyprops": [
# The RSASHA keys are outroducing.
f"ksk 0 8 2048 goal:hidden dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{OFFVAL}",
f"zsk 0 8 2048 goal:hidden dnskey:omnipresent zrrsig:omnipresent offset:{OFFVAL}",
# The ECDSAP256SHA256 keys are introducing.
f"ksk 0 {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured ds:hidden",
f"zsk 0 {alg} {size} goal:omnipresent dnskey:rumoured zrrsig:rumoured",
],
# Next key event is when the ecdsa256 keys have been propagated.
"nextev": IPUB,
}
isctest.kasp.check_rollover_step(servers["ns6"], CONFIG, POLICY, step)
def test_algoroll_ksk_zsk_reconfig_step2(servers, alg, size):
step = {
"zone": "step2.algorithm-roll.kasp",
"cdss": CDSS,
"keyprops": [
# The RSASHA keys are outroducing, but need to stay present
# until the new algorithm chain of trust has been established.
# Thus the expected key states of these keys stay the same.
f"ksk 0 8 2048 goal:hidden dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{OFFVAL}",
f"zsk 0 8 2048 goal:hidden dnskey:omnipresent zrrsig:omnipresent offset:{OFFVAL}",
# The ECDSAP256SHA256 keys are introducing. The DNSKEY RRset is
# omnipresent, but the zone signatures are not.
f"ksk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:hidden offset:{OFFSETS['step2']}",
f"zsk 0 {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:rumoured offset:{OFFSETS['step2']}",
],
# Next key event is when all zone signatures are signed with the new
# algorithm. This is the max-zone-ttl plus zone propagation delay. But
# the publication interval has already passed. Also, prevent intermittent
# false positives on slow platforms by subtracting the time passed between
# key creation and invoking 'rndc reconfig'.
"nextev": IPUBC - IPUB - TIME_PASSED,
}
isctest.kasp.check_rollover_step(servers["ns6"], CONFIG, POLICY, step)
def test_algoroll_ksk_zsk_reconfig_step3(servers, alg, size):
step = {
"zone": "step3.algorithm-roll.kasp",
"cdss": CDSS,
"keyprops": [
# The DS can be swapped.
f"ksk 0 8 2048 goal:hidden dnskey:omnipresent krrsig:omnipresent ds:unretentive offset:{OFFVAL}",
f"zsk 0 8 2048 goal:hidden dnskey:omnipresent zrrsig:omnipresent offset:{OFFVAL}",
f"ksk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:rumoured offset:{OFFSETS['step3']}",
f"zsk 0 {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{OFFSETS['step3']}",
],
# Next key event is when the DS becomes OMNIPRESENT. This happens
# after the retire interval.
"nextev": IRETKSK - TIME_PASSED,
}
isctest.kasp.check_rollover_step(servers["ns6"], CONFIG, POLICY, step)
def test_algoroll_ksk_zsk_reconfig_step4(servers, alg, size):
step = {
"zone": "step4.algorithm-roll.kasp",
"cdss": CDSS,
"keyprops": [
# The old DS is HIDDEN, we can remove the old algorithm records.
f"ksk 0 8 2048 goal:hidden dnskey:unretentive krrsig:unretentive ds:hidden offset:{OFFVAL}",
f"zsk 0 8 2048 goal:hidden dnskey:unretentive zrrsig:unretentive offset:{OFFVAL}",
f"ksk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{OFFSETS['step4']}",
f"zsk 0 {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{OFFSETS['step4']}",
],
# Next key event is when the old DNSKEY becomes HIDDEN.
# This happens after the DNSKEY TTL plus zone propagation delay.
"nextev": KEYTTLPROP,
}
isctest.kasp.check_rollover_step(servers["ns6"], CONFIG, POLICY, step)
def test_algoroll_ksk_zsk_reconfig_step5(servers, alg, size):
step = {
"zone": "step5.algorithm-roll.kasp",
"cdss": CDSS,
"keyprops": [
# The DNSKEY becomes HIDDEN.
f"ksk 0 8 2048 goal:hidden dnskey:hidden krrsig:hidden ds:hidden offset:{OFFVAL}",
f"zsk 0 8 2048 goal:hidden dnskey:hidden zrrsig:unretentive offset:{OFFVAL}",
f"ksk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{OFFSETS['step5']}",
f"zsk 0 {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{OFFSETS['step5']}",
],
# Next key event is when the RSASHA signatures become HIDDEN.
# This happens after the max-zone-ttl plus zone propagation delay
# minus the time already passed since the UNRETENTIVE state has
# been reached. Prevent intermittent false positives on slow
# platforms by subtracting the number of seconds which passed
# between key creation and invoking 'rndc reconfig'.
"nextev": IRET - IRETKSK - KEYTTLPROP - TIME_PASSED,
}
isctest.kasp.check_rollover_step(servers["ns6"], CONFIG, POLICY, step)
def test_algoroll_ksk_zsk_reconfig_step6(servers, alg, size):
step = {
"zone": "step6.algorithm-roll.kasp",
"cdss": CDSS,
"keyprops": [
# The zone signatures are now HIDDEN.
f"ksk 0 8 2048 goal:hidden dnskey:hidden krrsig:hidden ds:hidden offset:{OFFVAL}",
f"zsk 0 8 2048 goal:hidden dnskey:hidden zrrsig:hidden offset:{OFFVAL}",
f"ksk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{OFFSETS['step6']}",
f"zsk 0 {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{OFFSETS['step6']}",
],
# Next key event is never since we established the policy and the
# keys have an unlimited lifetime. Fallback to the default
# loadkeys interval.
"nextev": TIMEDELTA["PT1H"],
}
isctest.kasp.check_rollover_step(servers["ns6"], CONFIG, POLICY, step)

View file

@ -44,10 +44,13 @@ TIMEDELTA = {
"PT5M": timedelta(minutes=5),
"PT1H": timedelta(hours=1),
"PT2H": timedelta(hours=2),
"PT6H": timedelta(hours=6),
"P1D": timedelta(days=1),
"P5D": timedelta(days=5),
"P7D": timedelta(days=7),
"P10D": timedelta(days=10),
"P14D": timedelta(days=14),
"P30D": timedelta(days=30),
"P60D": timedelta(days=60),
"P90D": timedelta(days=90),
"P6M": timedelta(days=31 * 6),
@ -69,6 +72,18 @@ DEFAULT_CONFIG = {
}
UNSIGNING_CONFIG = DEFAULT_CONFIG.copy()
UNSIGNING_CONFIG["dnskey-ttl"] = TIMEDELTA["PT2H"]
ALGOROLL_CONFIG = {
"dnskey-ttl": TIMEDELTA["PT1H"],
"ds-ttl": TIMEDELTA["PT2H"],
"max-zone-ttl": TIMEDELTA["PT6H"],
"parent-propagation-delay": TIMEDELTA["PT1H"],
"publish-safety": TIMEDELTA["PT1H"],
"purge-keys": TIMEDELTA["P90D"],
"retire-safety": TIMEDELTA["PT2H"],
"signatures-refresh": TIMEDELTA["P5D"],
"signatures-validity": TIMEDELTA["P30D"],
"zone-propagation-delay": TIMEDELTA["PT1H"],
}
@pytest.fixture

View file

@ -21,46 +21,6 @@ include "@_csk_file@";
include "named.common.conf";
/* Zones for testing KSK/ZSK algorithm roll. */
{% set _policy = "rsasha256" if not csk_roll else "ecdsa256" %}
zone "step1.algorithm-roll.kasp" {
type primary;
file "step1.algorithm-roll.kasp.db";
dnssec-policy @_policy@;
};
{% if csk_roll %}
zone "step2.algorithm-roll.kasp" {
type primary;
file "step2.algorithm-roll.kasp.db";
dnssec-policy "ecdsa256";
};
zone "step3.algorithm-roll.kasp" {
type primary;
file "step3.algorithm-roll.kasp.db";
dnssec-policy "ecdsa256";
};
zone "step4.algorithm-roll.kasp" {
type primary;
file "step4.algorithm-roll.kasp.db";
dnssec-policy "ecdsa256";
};
zone "step5.algorithm-roll.kasp" {
type primary;
file "step5.algorithm-roll.kasp.db";
dnssec-policy "ecdsa256";
};
zone "step6.algorithm-roll.kasp" {
type primary;
file "step6.algorithm-roll.kasp.db";
dnssec-policy "ecdsa256";
};
{% endif %}
zone "step1.csk-algorithm-roll.kasp" {
type primary;
file "step1.csk-algorithm-roll.kasp.db";

View file

@ -29,175 +29,6 @@ R="RUMOURED"
O="OMNIPRESENT"
U="UNRETENTIVE"
#
# The zones at algorithm-roll.kasp represent the various steps of a ZSK/KSK
# algorithm rollover.
#
# Step 1:
# Introduce the first key. This will immediately be active.
setup step1.algorithm-roll.kasp
echo "$zone" >>zones
TactN="now-7d"
TsbmN="now-161h"
ksktimes="-P ${TactN} -A ${TactN}"
zsktimes="-P ${TactN} -A ${TactN}"
KSK=$($KEYGEN -a RSASHA256 -L 3600 -f KSK $ksktimes $zone 2>keygen.out.$zone.1)
ZSK=$($KEYGEN -a RSASHA256 -L 3600 $zsktimes $zone 2>keygen.out.$zone.2)
$SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN "$KSK" >settime.out.$zone.1 2>&1
$SETTIME -s -g $O -k $O $TactN -z $O $TactN "$ZSK" >settime.out.$zone.2 2>&1
cat template.db.in "${KSK}.key" "${ZSK}.key" >"$infile"
private_type_record $zone 8 "$KSK" >>"$infile"
private_type_record $zone 8 "$ZSK" >>"$infile"
cp $infile $zonefile
$SIGNER -S -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
# Step 2:
# After the publication interval has passed the DNSKEY is OMNIPRESENT.
setup step2.algorithm-roll.kasp
# The time passed since the new algorithm keys have been introduced is 3 hours.
TpubN1="now-3h"
# Tsbm(N+1) = TpubN1 + Ipub = now + TTLsig + Dprp = now - 3h + 6h + 1h = now + 4h
TsbmN1="now+4h"
ksk1times="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I ${TsbmN1}"
zsk1times="-P ${TactN} -A ${TactN} -I ${TsbmN1}"
ksk2times="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}"
zsk2times="-P ${TpubN1} -A ${TpubN1}"
KSK1=$($KEYGEN -a RSASHA256 -L 3600 -f KSK $ksk1times $zone 2>keygen.out.$zone.1)
ZSK1=$($KEYGEN -a RSASHA256 -L 3600 $zsk1times $zone 2>keygen.out.$zone.2)
KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $ksk2times $zone 2>keygen.out.$zone.3)
ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $zsk2times $zone 2>keygen.out.$zone.4)
$SETTIME -s -g $H -k $O $TactN -r $O $TactN -d $O $TactN "$KSK1" >settime.out.$zone.1 2>&1
$SETTIME -s -g $H -k $O $TactN -z $O $TactN "$ZSK1" >settime.out.$zone.2 2>&1
$SETTIME -s -g $O -k $R $TpubN1 -r $R $TpubN1 -d $H $TpubN1 "$KSK2" >settime.out.$zone.3 2>&1
$SETTIME -s -g $O -k $R $TpubN1 -z $R $TpubN1 "$ZSK2" >settime.out.$zone.4 2>&1
# Fake lifetime of old algorithm keys.
echo "Lifetime: 0" >>"${KSK1}.state"
echo "Lifetime: 0" >>"${ZSK1}.state"
cat template.db.in "${KSK1}.key" "${ZSK1}.key" "${KSK2}.key" "${ZSK2}.key" >"$infile"
private_type_record $zone 8 "$KSK1" >>"$infile"
private_type_record $zone 8 "$ZSK1" >>"$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK2" >>"$infile"
cp $infile $zonefile
$SIGNER -S -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
# Step 3:
# The zone signatures are also OMNIPRESENT.
setup step3.algorithm-roll.kasp
# The time passed since the new algorithm keys have been introduced is 7 hours.
TpubN1="now-7h"
TsbmN1="now"
ksk1times="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I ${TsbmN1}"
zsk1times="-P ${TactN} -A ${TactN} -I ${TsbmN1}"
ksk2times="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}"
zsk2times="-P ${TpubN1} -A ${TpubN1}"
KSK1=$($KEYGEN -a RSASHA256 -L 3600 -f KSK $ksk1times $zone 2>keygen.out.$zone.1)
ZSK1=$($KEYGEN -a RSASHA256 -L 3600 $zsk1times $zone 2>keygen.out.$zone.2)
KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $ksk2times $zone 2>keygen.out.$zone.3)
ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $zsk2times $zone 2>keygen.out.$zone.4)
$SETTIME -s -g $H -k $O $TactN -r $O $TactN -d $O $TactN "$KSK1" >settime.out.$zone.1 2>&1
$SETTIME -s -g $H -k $O $TactN -z $O $TactN "$ZSK1" >settime.out.$zone.2 2>&1
$SETTIME -s -g $O -k $O $TpubN1 -r $O $TpubN1 -d $H $TpubN1 "$KSK2" >settime.out.$zone.3 2>&1
$SETTIME -s -g $O -k $O $TpubN1 -z $R $TpubN1 "$ZSK2" >settime.out.$zone.4 2>&1
# Fake lifetime of old algorithm keys.
echo "Lifetime: 0" >>"${KSK1}.state"
echo "Lifetime: 0" >>"${ZSK1}.state"
cat template.db.in "${KSK1}.key" "${ZSK1}.key" "${KSK2}.key" "${ZSK2}.key" >"$infile"
private_type_record $zone 8 "$KSK1" >>"$infile"
private_type_record $zone 8 "$ZSK1" >>"$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK2" >>"$infile"
cp $infile $zonefile
$SIGNER -S -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
# Step 4:
# The DS is swapped and can become OMNIPRESENT.
setup step4.algorithm-roll.kasp
# The time passed since the DS has been swapped is 3 hours.
TpubN1="now-10h"
TsbmN1="now-3h"
ksk1times="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I ${TsbmN1}"
zsk1times="-P ${TactN} -A ${TactN} -I ${TsbmN1}"
ksk2times="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}"
zsk2times="-P ${TpubN1} -A ${TpubN1}"
KSK1=$($KEYGEN -a RSASHA256 -L 3600 -f KSK $ksk1times $zone 2>keygen.out.$zone.1)
ZSK1=$($KEYGEN -a RSASHA256 -L 3600 $zsk1times $zone 2>keygen.out.$zone.2)
KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $ksk2times $zone 2>keygen.out.$zone.3)
ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $zsk2times $zone 2>keygen.out.$zone.4)
$SETTIME -s -g $H -k $O $TactN -r $O $TactN -d $U $TsbmN1 -D ds $TsbmN1 "$KSK1" >settime.out.$zone.1 2>&1
$SETTIME -s -g $H -k $O $TactN -z $O $TactN "$ZSK1" >settime.out.$zone.2 2>&1
$SETTIME -s -g $O -k $O $TpubN1 -r $O $TpubN1 -d $R $TsbmN1 -P ds $TsbmN1 "$KSK2" >settime.out.$zone.3 2>&1
$SETTIME -s -g $O -k $O $TpubN1 -z $R $TpubN1 "$ZSK2" >settime.out.$zone.4 2>&1
# Fake lifetime of old algorithm keys.
echo "Lifetime: 0" >>"${KSK1}.state"
echo "Lifetime: 0" >>"${ZSK1}.state"
cat template.db.in "${KSK1}.key" "${ZSK1}.key" "${KSK2}.key" "${ZSK2}.key" >"$infile"
private_type_record $zone 8 "$KSK1" >>"$infile"
private_type_record $zone 8 "$ZSK1" >>"$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK2" >>"$infile"
cp $infile $zonefile
$SIGNER -S -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
# Step 5:
# The DNSKEY is removed long enough to be HIDDEN.
setup step5.algorithm-roll.kasp
# The time passed since the DNSKEY has been removed is 2 hours.
TpubN1="now-12h"
TsbmN1="now-5h"
ksk1times="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I ${TsbmN1}"
zsk1times="-P ${TactN} -A ${TactN} -I ${TsbmN1}"
ksk2times="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}"
zsk2times="-P ${TpubN1} -A ${TpubN1}"
KSK1=$($KEYGEN -a RSASHA256 -L 3600 -f KSK $ksk1times $zone 2>keygen.out.$zone.1)
ZSK1=$($KEYGEN -a RSASHA256 -L 3600 $zsk1times $zone 2>keygen.out.$zone.2)
KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $ksk2times $zone 2>keygen.out.$zone.3)
ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $zsk2times $zone 2>keygen.out.$zone.4)
$SETTIME -s -g $H -k $U $TsbmN1 -r $U $TsbmN1 -d $H $TsbmN1 "$KSK1" >settime.out.$zone.1 2>&1
$SETTIME -s -g $H -k $U $TsbmN1 -z $U $TsbmN1 "$ZSK1" >settime.out.$zone.2 2>&1
$SETTIME -s -g $O -k $O $TpubN1 -r $O $TpubN1 -d $O $TsbmN1 "$KSK2" >settime.out.$zone.3 2>&1
$SETTIME -s -g $O -k $O $TpubN1 -z $R $TpubN1 "$ZSK2" >settime.out.$zone.4 2>&1
# Fake lifetime of old algorithm keys.
echo "Lifetime: 0" >>"${KSK1}.state"
echo "Lifetime: 0" >>"${ZSK1}.state"
cat template.db.in "${KSK1}.key" "${ZSK1}.key" "${KSK2}.key" "${ZSK2}.key" >"$infile"
private_type_record $zone 8 "$KSK1" >>"$infile"
private_type_record $zone 8 "$ZSK1" >>"$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK2" >>"$infile"
cp $infile $zonefile
$SIGNER -S -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
# Step 6:
# The RRSIGs have been removed long enough to be HIDDEN.
setup step6.algorithm-roll.kasp
# Additional time passed: 7h.
TpubN1="now-19h"
TsbmN1="now-12h"
ksk1times="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I ${TsbmN1}"
zsk1times="-P ${TactN} -A ${TactN} -I ${TsbmN1}"
ksk2times="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}"
zsk2times="-P ${TpubN1} -A ${TpubN1}"
KSK1=$($KEYGEN -a RSASHA256 -L 3600 -f KSK $ksk1times $zone 2>keygen.out.$zone.1)
ZSK1=$($KEYGEN -a RSASHA256 -L 3600 $zsk1times $zone 2>keygen.out.$zone.2)
KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $ksk2times $zone 2>keygen.out.$zone.3)
ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $zsk2times $zone 2>keygen.out.$zone.4)
$SETTIME -s -g $H -k $H $TsbmN1 -r $U $TsbmN1 -d $H $TsbmN1 "$KSK1" >settime.out.$zone.1 2>&1
$SETTIME -s -g $H -k $H $TsbmN1 -z $U $TsbmN1 "$ZSK1" >settime.out.$zone.2 2>&1
$SETTIME -s -g $O -k $O $TpubN1 -r $O $TpubN1 -d $O $TsbmN1 "$KSK2" >settime.out.$zone.3 2>&1
$SETTIME -s -g $O -k $O $TpubN1 -z $R $TpubN1 "$ZSK2" >settime.out.$zone.4 2>&1
# Fake lifetime of old algorithm keys.
echo "Lifetime: 0" >>"${KSK1}.state"
echo "Lifetime: 0" >>"${ZSK1}.state"
cat template.db.in "${KSK1}.key" "${ZSK1}.key" "${KSK2}.key" "${ZSK2}.key" >"$infile"
private_type_record $zone 8 "$KSK1" >>"$infile"
private_type_record $zone 8 "$ZSK1" >>"$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK2" >>"$infile"
cp $infile $zonefile
$SIGNER -S -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
#
# The zones at csk-algorithm-roll.kasp represent the various steps of a CSK
# algorithm rollover.

View file

@ -1161,23 +1161,6 @@ def test_rollover_policy_changes(servers, templates):
start_time = KeyTimingMetadata.now()
# Test algorithm rollover (KSK/ZSK split).
isctest.log.info("check algorithm rollover ksk/zsk split")
offset = -timedelta(days=7)
offval = int(offset.total_seconds())
step = {
"zone": "step1.algorithm-roll.kasp",
"cdss": cdss,
"config": algoroll_config,
"policy": "rsasha256",
"keyprops": [
f"ksk 0 8 2048 goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{offval}",
f"zsk 0 8 2048 goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{offval}",
],
"nextev": timedelta(hours=1),
}
steps.append(step)
# Test algorithm rollover (CSK).
isctest.log.info("check algorithm rollover csk")
step = {
@ -1203,141 +1186,6 @@ def test_rollover_policy_changes(servers, templates):
now = KeyTimingMetadata.now()
time_passed = now.value - start_time.value
# Test algorithm rollover (KSK/ZSK split) (after reconfig).
isctest.log.info("check algorithm rollover ksk/zsk split (after reconfig)")
offset = -timedelta(days=7)
offval = int(offset.total_seconds())
ipub = Ipub(algoroll_config)
ipubc = IpubC(algoroll_config, rollover=False)
iret = Iret(algoroll_config, rollover=False)
iretKSK = Iret(algoroll_config, zsk=False, ksk=True, rollover=False)
keyttlprop = (
algoroll_config["dnskey-ttl"] + algoroll_config["zone-propagation-delay"]
)
offsets = {}
offsets["step2"] = -int(ipub.total_seconds())
offsets["step3"] = -int(iret.total_seconds())
offsets["step4"] = offsets["step3"] - int(iretKSK.total_seconds())
offsets["step5"] = offsets["step4"] - int(keyttlprop.total_seconds())
offsets["step6"] = offsets["step5"] - int(iret.total_seconds())
algo_steps = [
{
# Step 1.
"zone": "step1.algorithm-roll.kasp",
"cdss": cdss,
"config": algoroll_config,
"policy": "ecdsa256",
"keyprops": [
# The RSASHA keys are outroducing.
f"ksk 0 8 2048 goal:hidden dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{offval}",
f"zsk 0 8 2048 goal:hidden dnskey:omnipresent zrrsig:omnipresent offset:{offval}",
# The ECDSAP256SHA256 keys are introducing.
f"ksk 0 {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured ds:hidden",
f"zsk 0 {alg} {size} goal:omnipresent dnskey:rumoured zrrsig:rumoured",
],
# Next key event is when the ecdsa256 keys have been propagated.
"nextev": ipub,
},
{
# Step 2.
"zone": "step2.algorithm-roll.kasp",
"cdss": cdss,
"config": algoroll_config,
"policy": "ecdsa256",
"keyprops": [
# The RSASHA keys are outroducing, but need to stay present
# until the new algorithm chain of trust has been established.
# Thus the expected key states of these keys stay the same.
f"ksk 0 8 2048 goal:hidden dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{offval}",
f"zsk 0 8 2048 goal:hidden dnskey:omnipresent zrrsig:omnipresent offset:{offval}",
# The ECDSAP256SHA256 keys are introducing. The DNSKEY RRset is
# omnipresent, but the zone signatures are not.
f"ksk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:hidden offset:{offsets['step2']}",
f"zsk 0 {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:rumoured offset:{offsets['step2']}",
],
# Next key event is when all zone signatures are signed with the new
# algorithm. This is the max-zone-ttl plus zone propagation delay. But
# the publication interval has already passed. Also, prevent intermittent
# false positives on slow platforms by subtracting the time passed between
# key creation and invoking 'rndc reconfig'.
"nextev": ipubc - ipub - time_passed,
},
{
# Step 3.
"zone": "step3.algorithm-roll.kasp",
"cdss": cdss,
"config": algoroll_config,
"policy": "ecdsa256",
"keyprops": [
# The DS can be swapped.
f"ksk 0 8 2048 goal:hidden dnskey:omnipresent krrsig:omnipresent ds:unretentive offset:{offval}",
f"zsk 0 8 2048 goal:hidden dnskey:omnipresent zrrsig:omnipresent offset:{offval}",
f"ksk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:rumoured offset:{offsets['step3']}",
f"zsk 0 {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{offsets['step3']}",
],
# Next key event is when the DS becomes OMNIPRESENT. This happens
# after the retire interval.
"nextev": iretKSK - time_passed,
},
{
# Step 4.
"zone": "step4.algorithm-roll.kasp",
"cdss": cdss,
"config": algoroll_config,
"policy": "ecdsa256",
"keyprops": [
# The old DS is HIDDEN, we can remove the old algorithm records.
f"ksk 0 8 2048 goal:hidden dnskey:unretentive krrsig:unretentive ds:hidden offset:{offval}",
f"zsk 0 8 2048 goal:hidden dnskey:unretentive zrrsig:unretentive offset:{offval}",
f"ksk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{offsets['step4']}",
f"zsk 0 {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{offsets['step4']}",
],
# Next key event is when the old DNSKEY becomes HIDDEN.
# This happens after the DNSKEY TTL plus zone propagation delay.
"nextev": keyttlprop,
},
{
# Step 5.
"zone": "step5.algorithm-roll.kasp",
"cdss": cdss,
"config": algoroll_config,
"policy": "ecdsa256",
"keyprops": [
# The DNSKEY becomes HIDDEN.
f"ksk 0 8 2048 goal:hidden dnskey:hidden krrsig:hidden ds:hidden offset:{offval}",
f"zsk 0 8 2048 goal:hidden dnskey:hidden zrrsig:unretentive offset:{offval}",
f"ksk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{offsets['step5']}",
f"zsk 0 {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{offsets['step5']}",
],
# Next key event is when the RSASHA signatures become HIDDEN.
# This happens after the max-zone-ttl plus zone propagation delay
# minus the time already passed since the UNRETENTIVE state has
# been reached. Prevent intermittent false positives on slow
# platforms by subtracting the number of seconds which passed
# between key creation and invoking 'rndc reconfig'.
"nextev": iret - iretKSK - keyttlprop - time_passed,
},
{
# Step 6.
"zone": "step6.algorithm-roll.kasp",
"cdss": cdss,
"config": algoroll_config,
"policy": "ecdsa256",
"keyprops": [
# The zone signatures are now HIDDEN.
f"ksk 0 8 2048 goal:hidden dnskey:hidden krrsig:hidden ds:hidden offset:{offval}",
f"zsk 0 8 2048 goal:hidden dnskey:hidden zrrsig:hidden offset:{offval}",
f"ksk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{offsets['step6']}",
f"zsk 0 {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{offsets['step6']}",
],
# Next key event is never since we established the policy and the
# keys have an unlimited lifetime. Fallback to the default
# loadkeys interval.
"nextev": timedelta(hours=1),
},
]
steps = steps + algo_steps
# Test algorithm rollover (CSK) (after reconfig).
isctest.log.info("check algorithm rollover csk (after reconfig)")
offsets = {}