]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Add ksr system test
authorMatthijs Mekking <matthijs@isc.org>
Wed, 9 Aug 2023 12:04:54 +0000 (14:04 +0200)
committerMatthijs Mekking <matthijs@isc.org>
Fri, 19 Apr 2024 08:41:04 +0000 (10:41 +0200)
Add a system test for testing dnssec-ksr, initally for the keygen
command. This should be able to create or select key files given a
DNSSEC policy and a time window.

bin/tests/system/Makefile.am
bin/tests/system/ksr/clean.sh [new file with mode: 0644]
bin/tests/system/ksr/named.conf.in [new file with mode: 0644]
bin/tests/system/ksr/setup.sh [new file with mode: 0644]
bin/tests/system/ksr/tests.sh [new file with mode: 0644]
bin/tests/system/ksr/tests_sh_ksr.py [new file with mode: 0644]

index d640bda038620270400a679507ecee24d7349a23..842bb5db8b9caf90c9712d2ebeed2ffab8d46c7c 100644 (file)
@@ -128,6 +128,7 @@ TESTS =                             \
        kasp                    \
        keepalive               \
        keyfromlabel            \
+       ksr                     \
        legacy                  \
        limits                  \
        logfileconfig           \
diff --git a/bin/tests/system/ksr/clean.sh b/bin/tests/system/ksr/clean.sh
new file mode 100644 (file)
index 0000000..9c19a7d
--- /dev/null
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# 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 -e
+
+rm -f ./created.out
+rm -f ./python.out
+rm -f ./named.conf
+rm -f ./K*
+rm -f ./ksr.out.*
+rm -rf ./keydir
diff --git a/bin/tests/system/ksr/named.conf.in b/bin/tests/system/ksr/named.conf.in
new file mode 100644 (file)
index 0000000..abc64fb
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * 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 "common" {
+       keys {
+               ksk lifetime unlimited algorithm @DEFAULT_ALGORITHM@;
+               zsk lifetime P6M algorithm @DEFAULT_ALGORITHM@;
+       };
+};
+
+dnssec-policy "csk" {
+       keys {
+               csk lifetime P6M algorithm @DEFAULT_ALGORITHM@;
+       };
+};
+
+dnssec-policy "unlimited" {
+       keys {
+               ksk lifetime unlimited algorithm @DEFAULT_ALGORITHM@;
+               zsk lifetime unlimited algorithm @DEFAULT_ALGORITHM@;
+       };
+};
+
+dnssec-policy "two-tone" {
+       keys {
+               ksk lifetime unlimited algorithm @DEFAULT_ALGORITHM@;
+               ksk lifetime unlimited algorithm @ALTERNATIVE_ALGORITHM@;
+               zsk lifetime P3M algorithm @DEFAULT_ALGORITHM@;
+               zsk lifetime P5M algorithm @ALTERNATIVE_ALGORITHM@;
+       };
+};
diff --git a/bin/tests/system/ksr/setup.sh b/bin/tests/system/ksr/setup.sh
new file mode 100644 (file)
index 0000000..3e95924
--- /dev/null
@@ -0,0 +1,23 @@
+#!/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
+
+set -e
+
+$SHELL clean.sh
+
+mkdir keydir
+
+copy_setports named.conf.in named.conf
diff --git a/bin/tests/system/ksr/tests.sh b/bin/tests/system/ksr/tests.sh
new file mode 100644 (file)
index 0000000..6d3d7c9
--- /dev/null
@@ -0,0 +1,232 @@
+#!/bin/sh
+
+# 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
+# shellcheck source=kasp.sh
+. ../kasp.sh
+
+set -e
+
+status=0
+n=0
+
+# Get timing metadata from a value plus additional time.
+# $1: Value
+# $2: Additional time
+addtime() {
+        if [ -x "$PYTHON" ]; then
+                # Convert "%Y%m%d%H%M%S" format to epoch seconds.
+                # Then, add the additional time (can be negative).
+                _value=$1
+                _plus=$2
+                $PYTHON > python.out <<EOF
+from datetime import datetime
+from datetime import timedelta
+_now = datetime.strptime("$_value", "%Y%m%d%H%M%S")
+_delta = timedelta(seconds=$_plus)
+_then = _now + _delta
+print(_then.strftime("%Y%m%d%H%M%S"));
+EOF
+                cat python.out
+        fi
+}
+
+# Check keys that were created. The keys created are listed in the latest ksr output
+# file, ksr.out.$n.
+# $1: zone name
+# $2: key directory
+check_keys () (
+       zone=$1
+       dir=$2
+       lifetime=$LIFETIME
+       alg=$ALG
+       size=$SIZE
+       inception=0
+       pad=$(printf "%03d" "$alg")
+
+       for key in $(grep "K${zone}.+$pad+" ksr.out.$n)
+       do
+               grep "; Created:" "${dir}/${key}.key" > created.out || return 1
+               created=$(awk '{print $3}' < created.out)
+               # active: created + inception
+               active=$(addtime $created $inception)
+               # published: 2h5m (dnskey-ttl + publish-safety + propagation)
+               published=$(addtime $active -7500)
+               # retired: zsk-lifetime
+               retired=$(addtime $active $lifetime)
+               # removed: 10d1h5m (ttlsig + retire-safety + sign-delay + propagation)
+               removed=$(addtime $retired 867900)
+
+               echo_i "check metadata on $key"
+               statefile="${dir}/${key}.state"
+               grep "Algorithm: $alg" $statefile > /dev/null || return 1
+               grep "Length: $size" $statefile > /dev/null || return 1
+               grep "Lifetime: $lifetime" $statefile > /dev/null || return 1
+               grep "KSK: no" $statefile > /dev/null || return 1
+               grep "ZSK: yes" $statefile > /dev/null || return 1
+               grep "Published: $published" $statefile > /dev/null || return 1
+               grep "Active: $active" $statefile > /dev/null || return 1
+               grep "Retired: $retired" $statefile > /dev/null || return 1
+               grep "Removed: $removed" $statefile > /dev/null || return 1
+
+               inception=$((inception+lifetime))
+
+               cp ${dir}/${key}.key ${key}.key.expect
+               cp ${dir}/${key}.private ${key}.private.expect
+               cp ${dir}/${key}.state ${key}.state.expect
+       done
+
+       return 0
+)
+
+
+# Call the dnssec-ksr command:
+# ksr <policy> [options] <command> <zone>
+ksr () {
+       $KSR -l named.conf -k "$@"
+}
+
+# Unknown action.
+n=$((n+1))
+echo_i "check that 'dnssec-ksr' errors on unknown action ($n)"
+ret=0
+ksr common foobar common.test > ksr.out.$n 2>&1 && ret=1
+grep "dnssec-ksr: fatal: unknown command 'foobar'" ksr.out.$n > /dev/null || ret=1
+test "$ret" -eq 0 || echo_i "failed"
+status=$((status+ret))
+
+# Key generation.
+set_zsk () {
+       ALG=$1
+       SIZE=$2
+       LIFETIME=$3
+}
+
+n=$((n+1))
+echo_i "check that 'dnssec-ksr' errors on missing end date ($n)"
+ret=0
+ksr common keygen common.test > ksr.out.$n 2>&1 && ret=1
+grep "dnssec-ksr: fatal: keygen requires an end date" ksr.out.$n > /dev/null|| ret=1
+test "$ret" -eq 0 || echo_i "failed"
+status=$((status+ret))
+
+n=$((n+1))
+echo_i "check that 'dnssec-ksr' pregenerates right amount of keys in the common case ($n)"
+ret=0
+ksr common -i now -e +1y keygen common.test > ksr.out.$n 2>&1 || ret=1
+num=$(cat ksr.out.$n | wc -l)
+[ $num -eq 2 ] || ret=1
+set_zsk $DEFAULT_ALGORITHM_NUMBER $DEFAULT_BITS 16070400
+check_keys common.test "." || ret=1
+cp ksr.out.$n ksr.out.expect
+test "$ret" -eq 0 || echo_i "failed"
+status=$((status+ret))
+
+n=$((n+1))
+echo_i "check that 'dnssec-ksr' selects pregenerated keys for the same time bundle ($n)"
+ret=0
+ksr common -e +1y keygen common.test > ksr.out.$n 2>&1 || ret=1
+diff ksr.out.expect ksr.out.$n > /dev/null|| ret=1
+for key in $(cat ksr.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
+done
+test "$ret" -eq 0 || echo_i "failed"
+status=$((status+ret))
+
+n=$((n+1))
+echo_i "check that 'dnssec-ksr' selects generates only necessary keys for overlapping time bundle ($n)"
+ret=0
+ksr common -e +2y -v 1 keygen common.test > ksr.out.$n 2>&1 || ret=1
+num=$(cat ksr.out.$n | wc -l)
+[ $num -eq 4 ] || ret=1
+# 2 selected, 2 generated
+num=$(grep "Selecting" ksr.out.$n | wc -l)
+[ $num -eq 2 ] || ret=1
+num=$(grep "Generating" ksr.out.$n | wc -l)
+[ $num -eq 2 ] || ret=1
+set_zsk $DEFAULT_ALGORITHM_NUMBER $DEFAULT_BITS 16070400
+check_keys "." || ret=1
+test "$ret" -eq 0 || echo_i "failed"
+status=$((status+ret))
+
+n=$((n+1))
+echo_i "check that 'dnssec-ksr' pregenerates keys in the given key-directory ($n)"
+ret=0
+ksr common -i now -e +1y -K keydir keygen common.test > ksr.out.$n 2>&1 || ret=1
+num=$(cat ksr.out.$n | wc -l)
+[ $num -eq 2 ] || ret=1
+set_zsk $DEFAULT_ALGORITHM_NUMBER $DEFAULT_BITS 16070400
+check_keys "keydir" || ret=1
+test "$ret" -eq 0 || echo_i "failed"
+status=$((status+ret))
+
+n=$((n+1))
+echo_i "check that 'dnssec-ksr' creates only one key for zsk with unlimited lifetime ($n)"
+ret=0
+ksr unlimited -e +2y keygen unlimited.test > ksr.out.$n 2>&1 || ret=1
+num=$(cat ksr.out.$n | wc -l)
+[ $num -eq 1 ] || ret=1
+key=$(cat ksr.out.$n)
+grep "; Created:" "${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
+test "$ret" -eq 0 || echo_i "failed"
+status=$((status+ret))
+
+n=$((n+1))
+echo_i "check that 'dnssec-ksr' creates no keys for policy with csk ($n)"
+ret=0
+ksr csk -e +2y keygen csk.test > ksr.out.$n 2>&1 && ret=1
+grep "dnssec-ksr: fatal: policy 'csk' has no zsks" ksr.out.$n > /dev/null || ret=1
+test "$ret" -eq 0 || echo_i "failed"
+status=$((status+ret))
+
+n=$((n+1))
+echo_i "check that 'dnssec-ksr' creates keys for different algorithms ($n)"
+ret=0
+ksr two-tone -e +1y keygen two-tone.test > ksr.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.out.$n | wc -l)
+[ $num -eq 4 ] || ret=1
+set_zsk $DEFAULT_ALGORITHM_NUMBER $DEFAULT_BITS 8035200
+check_keys two-tone.test "." || ret=1
+# 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
+# extra key for the remainder of the bundle.
+alg=$(printf "%03d" "$ALTERNATIVE_ALGORITHM_NUMBER")
+num=$(grep "Ktwo-tone.test.+$alg+" ksr.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
+test "$ret" -eq 0 || echo_i "failed"
+status=$((status+ret))
+
+echo_i "exit status: $status"
+[ $status -eq 0 ] || exit 1
diff --git a/bin/tests/system/ksr/tests_sh_ksr.py b/bin/tests/system/ksr/tests_sh_ksr.py
new file mode 100644 (file)
index 0000000..56f07ce
--- /dev/null
@@ -0,0 +1,14 @@
+# 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.
+
+
+def test_ksr(run_tests_sh):
+    run_tests_sh()