Compare commits

...

4 Commits

Author SHA1 Message Date
Matthijs Mekking
ffd3d82521 Implement dummy 'rndc skr -import' command
Add the code and documentation required to provide KSR import using
rndc.  This is just the command, and the feature is at this point in
time still not implemented.
2024-05-17 11:22:38 +02:00
Matthijs Mekking
53ac7de064 Add a common setup script for ksr
The previous setup.sh has been moved to ns1/setup.sh, we need a common
setup script to invoke ns1/setup.sh.
2024-05-17 11:22:38 +02:00
Matthijs Mekking
20239d0112 Update ksr system test to include server
Prepare the system test for tests that require a server to import
created SKR files.
2024-05-17 11:22:37 +02:00
Matthijs Mekking
9e1e2e42a6 Add offline-ksk option
Add a new configuration option to enable Offline KSK key management.

Offline KSK cannot work with CSK because it splits how keys with the
KSK and ZSK role operate. Therefore, one key cannot have both roles.
Add a configuration check to ensure this.
2024-05-17 11:21:31 +02:00
23 changed files with 370 additions and 104 deletions

View File

@@ -295,6 +295,7 @@ dnssec-policy \"default\" {\n\
cds-digest-types { 2; };\n\
dnskey-ttl " DNS_KASP_KEY_TTL ";\n\
inline-signing yes;\n\
offline-ksk no;\n\
publish-safety " DNS_KASP_PUBLISH_SAFETY "; \n\
retire-safety " DNS_KASP_RETIRE_SAFETY "; \n\
purge-keys " DNS_KASP_PURGE_KEYS "; \n\

View File

@@ -224,6 +224,8 @@ named_control_docommand(isccc_sexpr_t *message, bool readonly,
result = named_server_flushnode(named_g_server, lex, true);
} else if (command_compare(command, NAMED_COMMAND_FREEZE)) {
result = named_server_freeze(named_g_server, true, lex, text);
} else if (command_compare(command, NAMED_COMMAND_KSR)) {
result = named_server_ksr(named_g_server, lex, text);
} else if (command_compare(command, NAMED_COMMAND_LOADKEYS) ||
command_compare(command, NAMED_COMMAND_SIGN))
{

View File

@@ -70,6 +70,7 @@
#define NAMED_COMMAND_TCPTIMEOUTS "tcp-timeouts"
#define NAMED_COMMAND_SERVESTALE "serve-stale"
#define NAMED_COMMAND_FETCHLIMIT "fetchlimit"
#define NAMED_COMMAND_KSR "ksr"
isc_result_t
named_controls_create(named_server_t *server, named_controls_t **ctrlsp);

View File

@@ -375,3 +375,9 @@ named_server_servestale(named_server_t *server, isc_lex_t *lex,
isc_result_t
named_server_fetchlimit(named_server_t *server, isc_lex_t *lex,
isc_buffer_t **text);
/*%
* Import KSR file for offline KSK signing.
*/
isc_result_t
named_server_ksr(named_server_t *server, isc_lex_t *lex, isc_buffer_t **text);

View File

@@ -16331,3 +16331,48 @@ cleanup:
return (result);
}
isc_result_t
named_server_ksr(named_server_t *server, isc_lex_t *lex, isc_buffer_t **text) {
isc_result_t result = ISC_R_SUCCESS;
dns_zone_t *zone = NULL;
dns_kasp_t *kasp = NULL;
const char *ptr;
/* Skip the command name. */
ptr = next_token(lex, text);
if (ptr == NULL) {
return (ISC_R_UNEXPECTEDEND);
}
/* Find out what we are to do. */
ptr = next_token(lex, text);
if (ptr == NULL) {
return (ISC_R_UNEXPECTEDEND);
}
if (strcasecmp(ptr, "import") != 0) {
CHECK(DNS_R_SYNTAX);
}
CHECK(zone_from_args(server, lex, NULL, &zone, NULL, text, false));
if (zone == NULL) {
CHECK(ISC_R_UNEXPECTEDEND);
}
kasp = dns_zone_getkasp(zone);
if (!dns_kasp_offlineksk(kasp)) {
CHECK(putstr(text, "zone does not have offline-ksk enabled"));
CHECK(putnull(text));
}
CHECK(putstr(text, "import command not implemented"));
CHECK(putnull(text));
cleanup:
if (zone != NULL) {
dns_zone_detach(&zone);
}
return (result);
}

View File

@@ -132,6 +132,9 @@ command is one of the following:\n\
halt Stop the server without saving pending updates.\n\
halt -p Stop the server without saving pending updates reporting\n\
process id.\n\
ksr -import zone [class [view]]\n\
Import a KSR file for the specified zone, for offline KSK\n\
signing.\n\
loadkeys zone [class [view]]\n\
Update keys without signing immediately.\n\
managed-keys refresh [class [view]]\n\

View File

@@ -257,6 +257,11 @@ Currently supported commands are:
See also :option:`rndc stop`.
.. option:: ksr -import zone [class [view]]
This command allows you to import a KSR file for the specified zone, to
support offline KSK signing.
.. option:: loadkeys [zone [class [view]]]
This command fetches all DNSSEC keys for the given zone from the key directory. If

View File

@@ -30,6 +30,7 @@ dnssec-policy "test" {
};
max-zone-ttl 86400;
nsec3param iterations 0 optout no salt-length 8;
offline-ksk no;
parent-ds-ttl 7200;
parent-propagation-delay PT1H;
publish-safety PT3600S;

View File

@@ -0,0 +1,31 @@
/*
* 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.
*/
/*
* Offline KSK is not possible with CSK
* (even if there are other key roles present).
*/
dnssec-policy "bad-offline-ksk" {
offline-ksk yes;
keys {
ksk lifetime P10Y algorithm rsasha256;
zsk lifetime P10Y algorithm rsasha256;
csk lifetime P10Y algorithm rsasha256;
};
};
zone "example.net" {
type primary;
file "example.db";
dnssec-policy "bad-offline-ksk";
};

View File

@@ -676,6 +676,14 @@ grep "dnssec-policy: key with algorithm rsasha256 has invalid key length 511" <c
if [ $ret -ne 0 ]; then echo_i "failed"; fi
status=$((status + ret))
n=$((n + 1))
echo_i "checking named-checkconf kasp offline-ksk with csk errors ($n)"
ret=0
$CHECKCONF kasp-bad-offline-ksk.conf >checkconf.out$n 2>&1 && ret=1
grep "dnssec-policy: csk keys are not allowed when offline-ksk is enabled" <checkconf.out$n >/dev/null || ret=1
if [ $ret -ne 0 ]; then echo_i "failed"; fi
status=$((status + ret))
n=$((n + 1))
echo_i "checking named-checkconf kasp signatures refresh errors ($n)"
ret=0

View File

@@ -17,15 +17,22 @@ rm -f ./*.ksk*
rm -f ./*.zsk*
rm -f ./created.out
rm -f ./footer.*
rm -f ./keygen.out.*
rm -f ./named.conf
rm -f ./now.out
rm -rf ./offline
rm -f ./ns1/*.db
rm -f ./ns1/*.db.jbk
rm -f ./ns1/*.db.signed
rm -f ./ns1/*.db.signed.jnl
rm -f ./ns1/K*
rm -f ./ns1/keygen.out.*
rm -f ./ns1/named.conf
rm -f ./ns1/named.memstats
rm -f ./ns1/named.run
rm -f ./python.out
rm -f ./settime.out.*
rm -f ./K*
rm -rf ./keydir
rm -f ./ksr.*.err.*
rm -f ./ksr.*.expect
rm -f ./ksr.*.expect.*
rm -f ./ksr.*.out.*
rm -rf ./ns1/keydir
rm -rf ./ns1/offline

View File

@@ -11,7 +11,31 @@
* information regarding copyright ownership.
*/
options {
query-source address 10.53.0.1;
notify-source 10.53.0.1;
transfer-source 10.53.0.1;
port @PORT@;
pid-file "named.pid";
listen-on { 10.53.0.1; };
listen-on-v6 { none; };
allow-transfer { any; };
recursion no;
dnssec-validation no;
allow-new-zones yes;
};
key rndc_key {
secret "1234abcd8765";
algorithm @DEFAULT_HMAC@;
};
controls {
inet 10.53.0.1 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
};
dnssec-policy "common" {
offline-ksk yes;
keys {
ksk lifetime unlimited algorithm @DEFAULT_ALGORITHM@;
zsk lifetime P6M algorithm @DEFAULT_ALGORITHM@;
@@ -19,12 +43,14 @@ dnssec-policy "common" {
};
dnssec-policy "csk" {
offline-ksk no;
keys {
csk lifetime P6M algorithm @DEFAULT_ALGORITHM@;
};
};
dnssec-policy "unlimited" {
offline-ksk yes;
keys {
ksk lifetime unlimited algorithm @DEFAULT_ALGORITHM@;
zsk lifetime unlimited algorithm @DEFAULT_ALGORITHM@;
@@ -32,6 +58,7 @@ dnssec-policy "unlimited" {
};
dnssec-policy "no-cdnskey" {
offline-ksk yes;
keys {
ksk lifetime unlimited algorithm @DEFAULT_ALGORITHM@;
zsk lifetime unlimited algorithm @DEFAULT_ALGORITHM@;
@@ -41,6 +68,7 @@ dnssec-policy "no-cdnskey" {
};
dnssec-policy "no-cds" {
offline-ksk yes;
keys {
ksk lifetime unlimited algorithm @DEFAULT_ALGORITHM@;
zsk lifetime unlimited algorithm @DEFAULT_ALGORITHM@;
@@ -49,6 +77,7 @@ dnssec-policy "no-cds" {
};
dnssec-policy "two-tone" {
offline-ksk yes;
keys {
ksk lifetime unlimited algorithm @DEFAULT_ALGORITHM@;
ksk lifetime unlimited algorithm @ALTERNATIVE_ALGORITHM@;

View File

@@ -0,0 +1,38 @@
#!/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
# Key directories
mkdir keydir
mkdir offline
# Zone files
cp template.db.in common.test.db
# Create KSK for the various policies.
create_ksk() {
KSK=$($KEYGEN -l named.conf -fK -k $2 $1 2>keygen.out.$1)
num=0
for ksk in $KSK; do
num=$(($num + 1))
echo $ksk >"../${1}.ksk${num}.id"
cat "${ksk}.key" | grep -v ";.*" >"../$1.ksk$num"
cp "${ksk}.key" offline/
cp "${ksk}.private" offline/
done
}
create_ksk common.test common
create_ksk unlimited.test unlimited
create_ksk two-tone.test two-tone

View File

@@ -0,0 +1,27 @@
; 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.
$TTL 300
@ IN SOA mname1. . (
1 ; serial
20 ; refresh (20 seconds)
20 ; retry (20 seconds)
1814400 ; expire (3 weeks)
3600 ; minimum (1 hour)
)
NS ns1
ns1 A 10.53.0.1
a A 10.0.0.1
b A 10.0.0.2
c A 10.0.0.3

View File

@@ -18,23 +18,9 @@ set -e
$SHELL clean.sh
mkdir keydir
mkdir offline
copy_setports ns1/named.conf.in ns1/named.conf
copy_setports named.conf.in named.conf
# Create KSK for the various policies.
create_ksk() {
KSK=$($KEYGEN -l named.conf -fK -k $2 $1 2>keygen.out.$1)
num=0
for ksk in $KSK; do
num=$(($num + 1))
echo $ksk >"${1}.ksk${num}.id"
cat "${ksk}.key" | grep -v ";.*" >"$1.ksk$num"
cp "${ksk}.key" offline/
cp "${ksk}.private" offline/
done
}
create_ksk common.test common
create_ksk unlimited.test unlimited
create_ksk two-tone.test two-tone
(
cd ns1
$SHELL setup.sh
)

View File

@@ -18,6 +18,8 @@
set -e
RNDCCMD="$RNDC -c ../_common/rndc.conf -p ${CONTROLPORT} -s"
CDS_SHA1="no"
CDS_SHA256="yes"
CDS_SHA384="no"
@@ -74,7 +76,7 @@ check_keys() (
# removed: 10d1h5m (ttlsig + retire-safety + sign-delay + propagation)
removed=$(addtime $retired 867900)
echo_i "check metadata on $key"
echo_i "check metadata on $key: $alg $size $lifetime $published $active $retired $removed"
statefile="${dir}/${key}.state"
grep "Algorithm: $alg" $statefile >/dev/null || return 1
grep "Length: $size" $statefile >/dev/null || return 1
@@ -116,7 +118,7 @@ print_dnskeys() {
# Call the dnssec-ksr command:
# ksr <policy> [options] <command> <zone>
ksr() {
$KSR -l named.conf -k "$@"
$KSR -l ns1/named.conf -k "$@"
}
# Unknown action.
@@ -146,29 +148,29 @@ status=$((status + ret))
n=$((n + 1))
echo_i "check that 'dnssec-ksr keygen' pregenerates right amount of keys in the common case ($n)"
ret=0
ksr common -i now -e +1y keygen common.test >ksr.keygen.out.$n 2>&1 || ret=1
ksr common -K ns1 -i now -e +1y keygen common.test >ksr.keygen.out.$n 2>&1 || ret=1
num=$(cat ksr.keygen.out.$n | wc -l)
[ $num -eq 2 ] || ret=1
set_zsk $DEFAULT_ALGORITHM_NUMBER $DEFAULT_BITS 16070400
check_keys common.test "." || ret=1
check_keys common.test ns1 || ret=1
cp ksr.keygen.out.$n ksr.keygen.out.expect
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
# save now time
key=$(cat common.test.$DEFAULT_ALGORITHM_NUMBER.zsk1.id)
grep "; Created:" "${key}.key" >now.out || ret=1
grep "; Created:" "ns1/${key}.key" >now.out || ret=1
now=$(awk '{print $3}' <now.out)
n=$((n + 1))
echo_i "check that 'dnssec-ksr keygen' selects pregenerated keys for the same time bundle ($n)"
ret=0
ksr common -e +1y keygen common.test >ksr.keygen.out.$n 2>&1 || ret=1
ksr common -K ns1 -e +1y keygen common.test >ksr.keygen.out.$n 2>&1 || ret=1
diff -w ksr.keygen.out.expect ksr.keygen.out.$n >/dev/null || ret=1
for key in $(cat ksr.keygen.out.$n); do
# Ensure the files are not modified.
diff ${key}.key ${key}.key.expect >/dev/null || ret=1
diff ${key}.private ${key}.private.expect >/dev/null || ret=1
diff ${key}.state ${key}.state.expect >/dev/null || ret=1
diff ns1/${key}.key ${key}.key.expect >/dev/null || ret=1
diff ns1/${key}.private ${key}.private.expect >/dev/null || ret=1
diff ns1/${key}.state ${key}.state.expect >/dev/null || ret=1
done
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
@@ -177,7 +179,7 @@ status=$((status + ret))
n=$((n + 1))
echo_i "check that 'dnssec-ksr request' errors on missing end date ($n)"
ret=0
ksr common request common.test >ksr.request.out.$n 2>&1 && ret=1
ksr common -K ns1 request common.test >ksr.request.out.$n 2>&1 && ret=1
grep "dnssec-ksr: fatal: request requires an end date" ksr.request.out.$n >/dev/null || ret=1
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
@@ -185,20 +187,20 @@ status=$((status + ret))
n=$((n + 1))
echo_i "check that 'dnssec-ksr request' creates correct KSR in the common case ($n)"
ret=0
ksr common -i $now -e +1y request common.test >ksr.request.out.$n 2>&1 || ret=1
ksr common -K ns1 -i $now -e +1y request common.test >ksr.request.out.$n 2>&1 || ret=1
# Bundle 1: KSK + ZSK1
key=$(cat common.test.$DEFAULT_ALGORITHM_NUMBER.zsk1.id)
inception=$(cat $key.state | grep "Generated" | cut -d' ' -f 2-)
inception=$(cat ns1/$key.state | grep "Generated" | cut -d' ' -f 2-)
echo ";; KeySigningRequest 1.0 $inception" >ksr.request.expect.$n
cat common.test.$DEFAULT_ALGORITHM_NUMBER.zsk1 >>ksr.request.expect.$n
# Bundle 2: KSK + ZSK1 + ZSK2
key=$(cat common.test.$DEFAULT_ALGORITHM_NUMBER.zsk2.id)
inception=$(cat $key.state | grep "Published" | cut -d' ' -f 2-)
inception=$(cat ns1/$key.state | grep "Published" | cut -d' ' -f 2-)
echo ";; KeySigningRequest 1.0 $inception" >>ksr.request.expect.$n
print_dnskeys common.test 1 2 $DEFAULT_ALGORITHM_NUMBER ksr.keygen.out.expect
# Bundle 3: KSK + ZSK2
key=$(cat common.test.$DEFAULT_ALGORITHM_NUMBER.zsk1.id)
inception=$(cat $key.state | grep "Removed" | cut -d' ' -f 2-)
inception=$(cat ns1/$key.state | grep "Removed" | cut -d' ' -f 2-)
echo ";; KeySigningRequest 1.0 $inception" >>ksr.request.expect.$n
cat common.test.$DEFAULT_ALGORITHM_NUMBER.zsk2 >>ksr.request.expect.$n
# Footer
@@ -216,7 +218,7 @@ status=$((status + ret))
n=$((n + 1))
echo_i "check that 'dnssec-ksr sign' errors on missing KSR file ($n)"
ret=0
ksr common -i $now -e +1y sign common.test >ksr.sign.out.$n 2>&1 && ret=1
ksr common -K ns1 -i $now -e +1y sign common.test >ksr.sign.out.$n 2>&1 && ret=1
grep "dnssec-ksr: fatal: 'sign' requires a KSR file" ksr.sign.out.$n >/dev/null || ret=1
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
@@ -224,7 +226,7 @@ status=$((status + ret))
n=$((n + 1))
echo_i "check that 'dnssec-ksr sign' creates correct SKR in the common case ($n)"
ret=0
ksr common -i $now -e +1y -K offline -f ksr.request.expect sign common.test >ksr.sign.out.$n 2>&1 || ret=1
ksr common -K ns1 -i $now -e +1y -K ns1/offline -f ksr.request.expect sign common.test >ksr.sign.out.$n 2>&1 || ret=1
_update_expected_zsks() {
zsk=$((zsk + 1))
@@ -235,8 +237,8 @@ _update_expected_zsks() {
key2="${zone}.${DEFAULT_ALGORITHM_NUMBER}.zsk${next}"
zsk1=$(cat $key1.id)
zsk2=$(cat $key2.id)
rollover_start=$(cat $zsk2.state | grep "Published" | awk '{print $2}')
rollover_done=$(cat $zsk1.state | grep "Removed" | awk '{print $2}')
rollover_start=$(cat ns1/$zsk2.state | grep "Published" | awk '{print $2}')
rollover_done=$(cat ns1/$zsk1.state | grep "Removed" | awk '{print $2}')
else
# No more expected rollovers.
key1="${zone}.${DEFAULT_ALGORITHM_NUMBER}.zsk${zsk}"
@@ -249,13 +251,14 @@ _update_expected_zsks() {
check_skr() {
_ret=0
zone=$1
file=$2
start=$3
end=$4
numzsks=$5
cds1=$($DSFROMKEY -T 3600 -a SHA-1 -C -w $(cat "${zone}.ksk1.id"))
cds2=$($DSFROMKEY -T 3600 -a SHA-256 -C -w $(cat "${zone}.ksk1.id"))
cds4=$($DSFROMKEY -T 3600 -a SHA-384 -C -w $(cat "${zone}.ksk1.id"))
dir=$2
file=$3
start=$4
end=$5
numzsks=$6
cds1=$($DSFROMKEY -T 3600 -a SHA-1 -C -w $dir/$(cat "${zone}.ksk1.id"))
cds2=$($DSFROMKEY -T 3600 -a SHA-256 -C -w $dir/$(cat "${zone}.ksk1.id"))
cds4=$($DSFROMKEY -T 3600 -a SHA-384 -C -w $dir/$(cat "${zone}.ksk1.id"))
cdnskey=$(awk '{sub(/DNSKEY/,"CDNSKEY")}1' <${zone}.ksk1)
echo_i "check skr: zone $1 file $2 from $3 to $4 num-zsk $5"
@@ -430,9 +433,9 @@ check_skr() {
}
zsk1=$(cat common.test.$DEFAULT_ALGORITHM_NUMBER.zsk1.id)
start=$(cat $zsk1.state | grep "Generated" | awk '{print $2}')
start=$(cat ns1/$zsk1.state | grep "Generated" | awk '{print $2}')
end=$(addtime $start 31536000) # one year
check_skr "common.test" "ksr.sign.out.$n" $start $end 2 || ret=1
check_skr "common.test" "ns1" "ksr.sign.out.$n" $start $end 2 || ret=1
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
@@ -440,18 +443,18 @@ status=$((status + ret))
n=$((n + 1))
echo_i "check that 'dnssec-ksr keygen' pregenerates keys in the given key-directory ($n)"
ret=0
ksr common -e +1y -K keydir keygen common.test >ksr.keygen.out.$n 2>&1 || ret=1
ksr common -K ns1/keydir -e +1y keygen common.test >ksr.keygen.out.$n 2>&1 || ret=1
num=$(cat ksr.keygen.out.$n | wc -l)
[ $num -eq 2 ] || ret=1
set_zsk $DEFAULT_ALGORITHM_NUMBER $DEFAULT_BITS 16070400
check_keys common.test keydir || ret=1
check_keys common.test ns1/keydir || ret=1
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
n=$((n + 1))
echo_i "check that 'dnssec-ksr keygen' selects generates only necessary keys for overlapping time bundle ($n)"
ret=0
ksr common -e +2y -v 1 keygen common.test >ksr.keygen.out.$n 2>&1 || ret=1
ksr common -K ns1 -e +2y -v 1 keygen common.test >ksr.keygen.out.$n 2>&1 || ret=1
num=$(cat ksr.keygen.out.$n | wc -l)
[ $num -eq 4 ] || ret=1
# 2 selected, 2 generated
@@ -466,11 +469,11 @@ status=$((status + ret))
n=$((n + 1))
echo_i "run 'dnssec-ksr keygen' again with verbosity 0 ($n)"
ret=0
ksr common -i $now -e +2y keygen common.test >ksr.keygen.out.$n 2>&1 || ret=1
ksr common -K ns1 -i $now -e +2y keygen common.test >ksr.keygen.out.$n 2>&1 || ret=1
num=$(cat ksr.keygen.out.$n | wc -l)
[ $num -eq 4 ] || ret=1
set_zsk $DEFAULT_ALGORITHM_NUMBER $DEFAULT_BITS 16070400
check_keys common.test "." || ret=1
check_keys common.test ns1 || ret=1
cp ksr.keygen.out.$n ksr.keygen.out.expect
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
@@ -479,7 +482,7 @@ status=$((status + ret))
n=$((n + 1))
echo_i "check that 'dnssec-ksr request' creates correct KSR if the interval is shorter ($n)"
ret=0
ksr common -i $now -e +1y request common.test >ksr.request.out.$n 2>&1 || ret=1
ksr common -K ns1 -i $now -e +1y request common.test >ksr.request.out.$n 2>&1 || ret=1
# Same as earlier.
cp ksr.request.expect.base ksr.request.expect.$n
grep ";; KeySigningRequest 1.0 generated at" ksr.request.out.$n >footer.$n || ret=1
@@ -491,26 +494,26 @@ status=$((status + ret))
n=$((n + 1))
echo_i "check that 'dnssec-ksr request' creates correct KSR with new interval ($n)"
ret=0
ksr common -i $now -e +2y request common.test >ksr.request.out.$n 2>&1 || ret=1
ksr common -K ns1 -i $now -e +2y request common.test >ksr.request.out.$n 2>&1 || ret=1
cp ksr.request.expect.base ksr.request.expect.$n
# Bundle 4: KSK + ZSK2 + ZSK3
key=$(cat common.test.$DEFAULT_ALGORITHM_NUMBER.zsk3.id)
inception=$(cat $key.state | grep "Published" | cut -d' ' -f 2-)
inception=$(cat ns1/$key.state | grep "Published" | cut -d' ' -f 2-)
echo ";; KeySigningRequest 1.0 $inception" >>ksr.request.expect.$n
print_dnskeys common.test 2 3 $DEFAULT_ALGORITHM_NUMBER ksr.keygen.out.expect
# Bundle 5: KSK + ZSK3
key=$(cat common.test.$DEFAULT_ALGORITHM_NUMBER.zsk2.id)
inception=$(cat $key.state | grep "Removed" | cut -d' ' -f 2-)
inception=$(cat ns1/$key.state | grep "Removed" | cut -d' ' -f 2-)
echo ";; KeySigningRequest 1.0 $inception" >>ksr.request.expect.$n
cat common.test.$DEFAULT_ALGORITHM_NUMBER.zsk3 >>ksr.request.expect.$n
# Bundle 6: KSK + ZSK3 + ZSK4
key=$(cat common.test.$DEFAULT_ALGORITHM_NUMBER.zsk4.id)
inception=$(cat $key.state | grep "Published" | cut -d' ' -f 2-)
inception=$(cat ns1/$key.state | grep "Published" | cut -d' ' -f 2-)
echo ";; KeySigningRequest 1.0 $inception" >>ksr.request.expect.$n
print_dnskeys common.test 3 4 $DEFAULT_ALGORITHM_NUMBER ksr.keygen.out.expect
# Bundle 7: KSK + ZSK4
key=$(cat common.test.$DEFAULT_ALGORITHM_NUMBER.zsk3.id)
inception=$(cat $key.state | grep "Removed" | cut -d' ' -f 2-)
inception=$(cat ns1/$key.state | grep "Removed" | cut -d' ' -f 2-)
echo ";; KeySigningRequest 1.0 $inception" >>ksr.request.expect.$n
cat common.test.$DEFAULT_ALGORITHM_NUMBER.zsk4 >>ksr.request.expect.$n
# Footer
@@ -526,7 +529,7 @@ status=$((status + ret))
n=$((n + 1))
echo_i "check that 'dnssec-ksr request' errors if there are not enough keys ($n)"
ret=0
ksr common -i $now -e +3y request common.test >ksr.request.out.$n 2>ksr.request.err.$n && ret=1
ksr common -K ns1 -i $now -e +3y request common.test >ksr.request.out.$n 2>ksr.request.err.$n && ret=1
grep "dnssec-ksr: fatal: no common.test/ECDSAP256SHA256 zsk key pair found for bundle" ksr.request.err.$n >/dev/null || ret=1
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
@@ -535,10 +538,10 @@ status=$((status + ret))
n=$((n + 1))
echo_i "check that 'dnssec-ksr sign' creates correct SKR with the new interval ($n)"
ret=0
ksr common -i $now -e +2y -K offline -f ksr.request.expect sign common.test >ksr.sign.out.$n 2>&1 || ret=1
start=$(cat $zsk1.state | grep "Generated" | awk '{print $2}')
ksr common -K ns1 -i $now -e +2y -K ns1/offline -f ksr.request.expect sign common.test >ksr.sign.out.$n 2>&1 || ret=1
start=$(cat ns1/$zsk1.state | grep "Generated" | awk '{print $2}')
end=$(addtime $start 63072000) # two years
check_skr "common.test" "ksr.sign.out.$n" $start $end 4 || ret=1
check_skr "common.test" "ns1/offline" "ksr.sign.out.$n" $start $end 4 || ret=1
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
@@ -555,25 +558,25 @@ status=$((status + ret))
n=$((n + 1))
echo_i "check that 'dnssec-ksr keygen' creates only one key for zsk with unlimited lifetime ($n)"
ret=0
ksr unlimited -e +2y keygen unlimited.test >ksr.keygen.out.$n 2>&1 || ret=1
ksr unlimited -K ns1 -e +2y keygen unlimited.test >ksr.keygen.out.$n 2>&1 || ret=1
num=$(cat ksr.keygen.out.$n | wc -l)
[ $num -eq 1 ] || ret=1
key=$(cat ksr.keygen.out.$n)
grep "; Created:" "${key}.key" >created.out || ret=1
grep "; Created:" "ns1/${key}.key" >created.out || ret=1
created=$(awk '{print $3}' <created.out)
active=$created
published=$(addtime $active -7500)
echo_i "check metadata on $key"
grep "Algorithm: $DEFAULT_ALGORITHM_NUMBER" ${key}.state >/dev/null || ret=1
grep "Length: $DEFAULT_BITS" ${key}.state >/dev/null || ret=1
grep "Lifetime: 0" ${key}.state >/dev/null || ret=1
grep "KSK: no" ${key}.state >/dev/null || ret=1
grep "ZSK: yes" ${key}.state >/dev/null || ret=1
grep "Published: $published" ${key}.state >/dev/null || ret=1
grep "Active: $active" ${key}.state >/dev/null || ret=1
grep "Retired:" ${key}.state >/dev/null && ret=1
grep "Removed:" ${key}.state >/dev/null && ret=1
cat ${key}.key | grep -v ";.*" >unlimited.test.$DEFAULT_ALGORITHM_NUMBER.zsk1
grep "Algorithm: $DEFAULT_ALGORITHM_NUMBER" ns1/${key}.state >/dev/null || ret=1
grep "Length: $DEFAULT_BITS" ns1/${key}.state >/dev/null || ret=1
grep "Lifetime: 0" ns1/${key}.state >/dev/null || ret=1
grep "KSK: no" ns1/${key}.state >/dev/null || ret=1
grep "ZSK: yes" ns1/${key}.state >/dev/null || ret=1
grep "Published: $published" ns1/${key}.state >/dev/null || ret=1
grep "Active: $active" ns1/${key}.state >/dev/null || ret=1
grep "Retired:" ns1/${key}.state >/dev/null && ret=1
grep "Removed:" ns1/${key}.state >/dev/null && ret=1
cat ns1/${key}.key | grep -v ";.*" >unlimited.test.$DEFAULT_ALGORITHM_NUMBER.zsk1
echo $key >"unlimited.test.${DEFAULT_ALGORITHM_NUMBER}.zsk1.id"
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
@@ -582,9 +585,9 @@ status=$((status + ret))
n=$((n + 1))
echo_i "check that 'dnssec-ksr request' creates correct KSR with unlimited zsk ($n)"
ret=0
ksr unlimited -i $created -e +4y request unlimited.test >ksr.request.out.$n 2>&1 || ret=1
ksr unlimited -K ns1 -i $created -e +4y request unlimited.test >ksr.request.out.$n 2>&1 || ret=1
# Only one bundle: KSK + ZSK
inception=$(cat $key.state | grep "Generated" | cut -d' ' -f 2-)
inception=$(cat ns1/$key.state | grep "Generated" | cut -d' ' -f 2-)
echo ";; KeySigningRequest 1.0 $inception" >ksr.request.expect.$n
cat unlimited.test.$DEFAULT_ALGORITHM_NUMBER.zsk1 >>ksr.request.expect.$n
# Footer
@@ -600,10 +603,10 @@ status=$((status + ret))
n=$((n + 1))
echo_i "check that 'dnssec-ksr sign' creates correct SKR with unlimited zsk ($n)"
ret=0
ksr unlimited -i $created -e +4y -K offline -f ksr.request.expect sign unlimited.test >ksr.sign.out.$n 2>&1 || ret=1
start=$(cat $key.state | grep "Generated" | awk '{print $2}')
ksr unlimited -K ns1 -i $created -e +4y -K ns1/offline -f ksr.request.expect sign unlimited.test >ksr.sign.out.$n 2>&1 || ret=1
start=$(cat ns1/$key.state | grep "Generated" | awk '{print $2}')
end=$(addtime $start 126144000) # four years
check_skr "unlimited.test" "ksr.sign.out.$n" $start $end 1 || ret=1
check_skr "unlimited.test" "ns1" "ksr.sign.out.$n" $start $end 1 || ret=1
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
@@ -611,14 +614,14 @@ status=$((status + ret))
n=$((n + 1))
echo_i "check that 'dnssec-ksr sign' creates correct SKR with unlimited zsk, no cdnskey ($n)"
ret=0
ksr no-cdnskey -i $created -e +4y -K offline -f ksr.request.expect sign unlimited.test >ksr.sign.out.$n 2>&1 || ret=1
start=$(cat $key.state | grep "Generated" | awk '{print $2}')
ksr no-cdnskey -K ns1 -i $created -e +4y -K ns1/offline -f ksr.request.expect sign unlimited.test >ksr.sign.out.$n 2>&1 || ret=1
start=$(cat ns1/$key.state | grep "Generated" | awk '{print $2}')
end=$(addtime $start 126144000) # four years
CDNSKEY="no"
CDS_SHA1="yes"
CDS_SHA256="yes"
CDS_SHA384="yes"
check_skr "unlimited.test" "ksr.sign.out.$n" $start $end 1 || ret=1
check_skr "unlimited.test" "ns1" "ksr.sign.out.$n" $start $end 1 || ret=1
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
@@ -626,14 +629,14 @@ status=$((status + ret))
n=$((n + 1))
echo_i "check that 'dnssec-ksr sign' creates correct SKR with unlimited zsk, no cds ($n)"
ret=0
ksr no-cds -i $created -e +4y -K offline -f ksr.request.expect sign unlimited.test >ksr.sign.out.$n 2>&1 || ret=1
start=$(cat $key.state | grep "Generated" | awk '{print $2}')
ksr no-cds -K ns1 -i $created -e +4y -K ns1/offline -f ksr.request.expect sign unlimited.test >ksr.sign.out.$n 2>&1 || ret=1
start=$(cat ns1/$key.state | grep "Generated" | awk '{print $2}')
end=$(addtime $start 126144000) # four years
CDNSKEY="yes"
CDS_SHA1="no"
CDS_SHA256="no"
CDS_SHA384="no"
check_skr "unlimited.test" "ksr.sign.out.$n" $start $end 1 || ret=1
check_skr "unlimited.test" "ns1" "ksr.sign.out.$n" $start $end 1 || ret=1
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
@@ -647,13 +650,13 @@ CDS_SHA384="no"
n=$((n + 1))
echo_i "check that 'dnssec-ksr keygen' creates keys for different algorithms ($n)"
ret=0
ksr two-tone -e +1y keygen two-tone.test >ksr.keygen.out.$n 2>&1 || ret=1
ksr two-tone -K ns1 -e +1y keygen two-tone.test >ksr.keygen.out.$n 2>&1 || ret=1
# First algorithm keys have a lifetime of 3 months, so there should be 4 created keys.
alg=$(printf "%03d" "$DEFAULT_ALGORITHM_NUMBER")
num=$(grep "Ktwo-tone.test.+$alg+" ksr.keygen.out.$n | wc -l)
[ $num -eq 4 ] || ret=1
set_zsk $DEFAULT_ALGORITHM_NUMBER $DEFAULT_BITS 8035200
check_keys two-tone.test "." || ret=1
check_keys two-tone.test ns1 || ret=1
cp ksr.keygen.out.$n ksr.keygen.out.expect.$DEFAULT_ALGORITHM_NUMBER
# Second algorithm keys have a lifetime of 5 months, so there should be 3 created keys.
# While only two time bundles of 5 months fit into one year, we need to create an
@@ -662,7 +665,7 @@ alg=$(printf "%03d" "$ALTERNATIVE_ALGORITHM_NUMBER")
num=$(grep "Ktwo-tone.test.+$alg+" ksr.keygen.out.$n | wc -l)
[ $num -eq 3 ] || ret=1
set_zsk $ALTERNATIVE_ALGORITHM_NUMBER $ALTERNATIVE_BITS 13392000
check_keys two-tone.test "." $ALTERNATIVE_ALGORITHM_NUMBER 13392000 || ret=1
check_keys two-tone.test ns1 $ALTERNATIVE_ALGORITHM_NUMBER 13392000 || ret=1
cp ksr.keygen.out.$n ksr.keygen.out.expect.$ALTERNATIVE_ALGORITHM_NUMBER
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
@@ -674,7 +677,7 @@ ret=0
key=$(cat two-tone.test.$DEFAULT_ALGORITHM_NUMBER.zsk1.id)
grep "; Created:" "${key}.key" >created.out || ret=1
created=$(awk '{print $3}' <created.out)
ksr two-tone -i $created -e +6mo request two-tone.test >ksr.request.out.$n 2>&1 || ret=1
ksr two-tone -K ns1 -i $created -e +6mo request two-tone.test >ksr.request.out.$n 2>&1 || ret=1
# The two-tone policy uses two sets of KSK/ZSK with different algorithms. One
# set uses the default algorithm (denoted as A below), the other is using the
# alternative algorithm (denoted as B). The A-ZSKs roll every three months,
@@ -685,31 +688,31 @@ ksr two-tone -i $created -e +6mo request two-tone.test >ksr.request.out.$n 2>&1
#
# Bundle 1: KSK-A1, KSK-B1, ZSK-A1, ZSK-B1
key=$(cat two-tone.test.$DEFAULT_ALGORITHM_NUMBER.zsk1.id)
inception=$(cat $key.state | grep "Generated" | cut -d' ' -f 2-)
inception=$(cat ns1/$key.state | grep "Generated" | cut -d' ' -f 2-)
echo ";; KeySigningRequest 1.0 $inception" >ksr.request.expect.$n
cat two-tone.test.$DEFAULT_ALGORITHM_NUMBER.zsk1 >>ksr.request.expect.$n
cat two-tone.test.$ALTERNATIVE_ALGORITHM_NUMBER.zsk1 >>ksr.request.expect.$n
# Bundle 2: KSK-A1, KSK-B1, ZSK-A1 + ZSK-A2, ZSK-B1
key=$(cat two-tone.test.$DEFAULT_ALGORITHM_NUMBER.zsk2.id)
inception=$(cat $key.state | grep "Published" | cut -d' ' -f 2-)
inception=$(cat ns1/$key.state | grep "Published" | cut -d' ' -f 2-)
echo ";; KeySigningRequest 1.0 $inception" >>ksr.request.expect.$n
print_dnskeys two-tone.test 1 2 $DEFAULT_ALGORITHM_NUMBER ksr.keygen.out.expect.$DEFAULT_ALGORITHM_NUMBER >>ksr.request.expect.$n
cat two-tone.test.$ALTERNATIVE_ALGORITHM_NUMBER.zsk1 >>ksr.request.expect.$n
# Bundle 3: KSK-A1, KSK-B1, ZSK-A2, ZSK-B1
key=$(cat two-tone.test.$DEFAULT_ALGORITHM_NUMBER.zsk1.id)
inception=$(cat $key.state | grep "Removed" | cut -d' ' -f 2-)
inception=$(cat ns1/$key.state | grep "Removed" | cut -d' ' -f 2-)
echo ";; KeySigningRequest 1.0 $inception" >>ksr.request.expect.$n
cat two-tone.test.$DEFAULT_ALGORITHM_NUMBER.zsk2 >>ksr.request.expect.$n
cat two-tone.test.$ALTERNATIVE_ALGORITHM_NUMBER.zsk1 >>ksr.request.expect.$n
# Bundle 4: KSK-A1, KSK-B1, ZSK-A2, ZSK-B1 + ZSK-B2
key=$(cat two-tone.test.$ALTERNATIVE_ALGORITHM_NUMBER.zsk2.id)
inception=$(cat $key.state | grep "Published" | cut -d' ' -f 2-)
inception=$(cat ns1/$key.state | grep "Published" | cut -d' ' -f 2-)
echo ";; KeySigningRequest 1.0 $inception" >>ksr.request.expect.$n
cat two-tone.test.$DEFAULT_ALGORITHM_NUMBER.zsk2 >>ksr.request.expect.$n
print_dnskeys two-tone.test 1 2 $ALTERNATIVE_ALGORITHM_NUMBER ksr.keygen.out.expect.$ALTERNATIVE_ALGORITHM_NUMBER >>ksr.request.expect.$n
# Bundle 5: KSK-A1, KSK-B1, ZSK-A2, ZSK-B2
key=$(cat two-tone.test.$ALTERNATIVE_ALGORITHM_NUMBER.zsk1.id)
inception=$(cat $key.state | grep "Removed" | cut -d' ' -f 2-)
inception=$(cat ns1/$key.state | grep "Removed" | cut -d' ' -f 2-)
echo ";; KeySigningRequest 1.0 $inception" >>ksr.request.expect.$n
cat two-tone.test.$DEFAULT_ALGORITHM_NUMBER.zsk2 >>ksr.request.expect.$n
cat two-tone.test.$ALTERNATIVE_ALGORITHM_NUMBER.zsk2 >>ksr.request.expect.$n
@@ -744,7 +747,7 @@ num_occurrences() {
n=$((n + 1))
echo_i "check that 'dnssec-ksr sign' creates correct SKR with multiple algorithms ($n)"
ret=0
ksr two-tone -i $created -e +6mo -K offline -f ksr.request.expect sign two-tone.test >ksr.sign.out.$n 2>&1 || ret=1
ksr two-tone -K ns1 -i $created -e +6mo -K ns1/offline -f ksr.request.expect sign two-tone.test >ksr.sign.out.$n 2>&1 || ret=1
test "$ret" -eq 0 || echo_i "failed"
# Weak testing:
zone="two-tone.test"

View File

@@ -6448,6 +6448,20 @@ The following options can be specified in a :any:`dnssec-policy` statement:
``insecure``. In this specific case you should move the existing key files
to the zone's ``key-directory`` from the new configuration.
.. namedconf:statement:: offline-ksk
:tags: dnssec
:short: Specifies whether the DNSKEY, CDS, and CDNSKEY RRsets are being signed offline.
If enabled, BIND 9 will not generate signatures for the DNSKEY, CDS, and
CDNSKEY RRsets. Instead, the signed DNSKEY, CDS and CDNSKEY RRsets are
being looked up from Signed Key Response (SKR) files.
Any existing DNSKEY, CDS, and CDNSKEY RRsets in the unsigned version of the
zone will be filtered and replaced with RRsets from the SKR file.
This feature is off by default. Configuring ``offline-ksk`` in conjunction
with a CSK is a configuration error.
.. namedconf:statement:: purge-keys
:tags: dnssec
:short: Specifies the amount of time after which DNSSEC keys that have been deleted from the zone can be removed from disk.

View File

@@ -13,6 +13,7 @@
dnssec-policy "default" {
// Keys
offline-ksk no;
keys {
csk key-directory lifetime unlimited algorithm 13;
};

View File

@@ -18,6 +18,7 @@ dnssec-policy <string> {
keys { ( csk | ksk | zsk ) [ key-directory | key-store <string> ] lifetime <duration_or_unlimited> algorithm <string> [ <integer> ]; ... };
max-zone-ttl <duration>;
nsec3param [ iterations <integer> ] [ optout <boolean> ] [ salt-length <integer> ];
offline-ksk <boolean>;
parent-ds-ttl <duration>;
parent-propagation-delay <duration>;
publish-safety <duration>;

View File

@@ -90,6 +90,7 @@ struct dns_kasp {
uint32_t signatures_validity_dnskey;
/* Configuration: Keys */
bool offlineksk;
bool cdnskey;
dns_kasp_digestlist_t digests;
dns_kasp_keylist_t keys;
@@ -809,6 +810,28 @@ dns_kasp_setnsec3param(dns_kasp_t *kasp, uint8_t iter, bool optout,
*
*/
bool
dns_kasp_offlineksk(dns_kasp_t *kasp);
/*%<
* Should we be using Offline KSK key management?
*
* Requires:
*
*\li 'kasp' is a valid, frozen kasp.
*
*/
void
dns_kasp_setofflineksk(dns_kasp_t *kasp, bool offlineksk);
/*%<
* Enable/disable Offline KSK.
*
* Requires:
*
*\li 'kasp' is a valid, unfrozen kasp.
*
*/
bool
dns_kasp_cdnskey(dns_kasp_t *kasp);
/*%<
@@ -823,7 +846,7 @@ dns_kasp_cdnskey(dns_kasp_t *kasp);
void
dns_kasp_setcdnskey(dns_kasp_t *kasp, bool cdnskey);
/*%<
* Set to enable publication of CDNSKEY records.
* Enable/disable publication of CDNSKEY records.
*
* Requires:
*

View File

@@ -595,6 +595,22 @@ dns_kasp_setnsec3param(dns_kasp_t *kasp, uint8_t iter, bool optout,
kasp->nsec3param.saltlen = saltlen;
}
bool
dns_kasp_offlineksk(dns_kasp_t *kasp) {
REQUIRE(kasp != NULL);
REQUIRE(kasp->frozen);
return kasp->offlineksk;
}
void
dns_kasp_setofflineksk(dns_kasp_t *kasp, bool offlineksk) {
REQUIRE(kasp != NULL);
REQUIRE(!kasp->frozen);
kasp->offlineksk = offlineksk;
}
bool
dns_kasp_cdnskey(dns_kasp_t *kasp) {
REQUIRE(kasp != NULL);

View File

@@ -112,8 +112,8 @@ get_string(const cfg_obj_t **maps, const char *option) {
*/
static isc_result_t
cfg_kaspkey_fromconfig(const cfg_obj_t *config, dns_kasp_t *kasp,
bool check_algorithms, isc_log_t *logctx,
dns_keystorelist_t *keystorelist,
bool check_algorithms, bool offline_ksk,
isc_log_t *logctx, dns_keystorelist_t *keystorelist,
uint32_t ksk_min_lifetime, uint32_t zsk_min_lifetime) {
isc_result_t result;
dns_kasp_key_t *key = NULL;
@@ -126,6 +126,7 @@ cfg_kaspkey_fromconfig(const cfg_obj_t *config, dns_kasp_t *kasp,
if (config == NULL) {
/* We are creating a key reference for the default kasp. */
INSIST(!offline_ksk);
key->role |= DNS_KASP_KEY_ROLE_KSK | DNS_KASP_KEY_ROLE_ZSK;
key->lifetime = 0; /* unlimited */
key->algorithm = DNS_KEYALG_ECDSA256;
@@ -149,6 +150,14 @@ cfg_kaspkey_fromconfig(const cfg_obj_t *config, dns_kasp_t *kasp,
} else if (strcmp(rolestr, "zsk") == 0) {
key->role |= DNS_KASP_KEY_ROLE_ZSK;
} else if (strcmp(rolestr, "csk") == 0) {
if (offline_ksk) {
cfg_obj_log(
config, logctx, ISC_LOG_ERROR,
"dnssec-policy: csk keys are not "
"allowed when offline-ksk is enabled");
result = ISC_R_FAILURE;
goto cleanup;
}
key->role |= DNS_KASP_KEY_ROLE_KSK;
key->role |= DNS_KASP_KEY_ROLE_ZSK;
}
@@ -418,6 +427,7 @@ cfg_kasp_fromconfig(const cfg_obj_t *config, dns_kasp_t *default_kasp,
uint32_t zonepropdelay = 0, parentpropdelay = 0;
uint32_t ipub = 0, iret = 0;
uint32_t ksk_min_lifetime = 0, zsk_min_lifetime = 0;
bool offline_ksk = false;
REQUIRE(config != NULL);
REQUIRE(kaspp != NULL && *kaspp == NULL);
@@ -539,6 +549,13 @@ cfg_kasp_fromconfig(const cfg_obj_t *config, dns_kasp_t *default_kasp,
dns_kasp_setparentpropagationdelay(kasp, parentpropdelay);
/* Configuration: Keys */
obj = NULL;
(void)confget(maps, "offline-ksk", &obj);
if (obj != NULL) {
offline_ksk = cfg_obj_asboolean(obj);
}
dns_kasp_setofflineksk(kasp, offline_ksk);
obj = NULL;
(void)confget(maps, "cdnskey", &obj);
if (obj != NULL) {
@@ -595,8 +612,8 @@ cfg_kasp_fromconfig(const cfg_obj_t *config, dns_kasp_t *default_kasp,
{
cfg_obj_t *kobj = cfg_listelt_value(element);
result = cfg_kaspkey_fromconfig(
kobj, kasp, check_algorithms, logctx,
keystorelist, ksk_min_lifetime,
kobj, kasp, check_algorithms, offline_ksk,
logctx, keystorelist, ksk_min_lifetime,
zsk_min_lifetime);
if (result != ISC_R_SUCCESS) {
cfg_obj_log(kobj, logctx, ISC_LOG_ERROR,

View File

@@ -2274,6 +2274,7 @@ static cfg_clausedef_t dnssecpolicy_clauses[] = {
{ "keys", &cfg_type_kaspkeys, 0 },
{ "max-zone-ttl", &cfg_type_duration, 0 },
{ "nsec3param", &cfg_type_nsec3, 0 },
{ "offline-ksk", &cfg_type_boolean, 0 },
{ "parent-ds-ttl", &cfg_type_duration, 0 },
{ "parent-propagation-delay", &cfg_type_duration, 0 },
{ "parent-registration-delay", &cfg_type_duration,