]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Test dnssec-policy/hsm with multiple views
authorMatthijs Mekking <matthijs@isc.org>
Thu, 16 Nov 2023 14:37:34 +0000 (15:37 +0100)
committerMatthijs Mekking <matthijs@isc.org>
Thu, 25 Jan 2024 14:37:40 +0000 (15:37 +0100)
Add test cases for zones in different views that are using PKCS#11
tokens to store its keys.

If it is using the same DNSSEC policy, only one PKCS#11 token should be
created and the same key should be used for the zone in both views.

If it is using a different DNSSEC policy, multiple PKCS#11 token should
be created and each view should use their respective key.

bin/tests/system/enginepkcs11/clean.sh
bin/tests/system/enginepkcs11/ns2/named.args.in [new file with mode: 0644]
bin/tests/system/enginepkcs11/ns2/named.conf.in [new file with mode: 0644]
bin/tests/system/enginepkcs11/ns2/template.db.in [new file with mode: 0644]
bin/tests/system/enginepkcs11/setup.sh
bin/tests/system/enginepkcs11/tests.sh

index c8b3c79d0db4efbc387a7c8194f2845bc33f2e7d..5a24ebd3dae704aba1c4c344fb17e94abfc03dcf 100644 (file)
@@ -21,19 +21,21 @@ rm -f dsset-*
 rm -f keyfromlabel.err.* keyfromlabel.out.*
 rm -f pkcs11-tool.err.* pkcs11-tool.out.*
 rm -f signer.out.*
+rm -f ns*/*.kskid1 ns*/*.kskid2 ns*/*.zskid1 ns/*.zskid2
+rm -f ns*/dig.out.*
+rm -f ns*/K*
+rm -f ns*/keygen.out.*
+rm -f ns*/named.conf ns1/named.args ns1/named.run ns1/named.memstats
+rm -f ns*/pin
+rm -f ns*/update.cmd.*
+rm -f ns*/update.log.*
+rm -f ns*/verify.out.*
+rm -f ns*/zone.*.jnl ns1/zone.*.jbk
 rm -f ns1/*.example.db ns1/*.example.db.signed
 rm -f ns1/*.kasp.db ns1/*.kasp.db.signed
 rm -f ns1/*.split.db ns1/*.split.db.signed
-rm -f ns1/*.kskid1 ns1/*.kskid2 ns1/*.zskid1 ns1/*.zskid2
-rm -f ns1/dig.out.*
-rm -f ns1/K*
-rm -f ns1/keygen.out.*
-rm -f ns1/named.conf ns1/named.args ns1/named.run ns1/named.memstats
-rm -f ns1/pin
-rm -f ns1/update.cmd.*
-rm -f ns1/update.log.*
-rm -f ns1/verify.out.*
-rm -f ns1/zone.*.jnl ns1/zone.*.jbk
+rm -f ns2/*.views.db ns1/*.views.db.signed
 rm -rf ./ns1/keys/
+rm -rf ./ns2/keys/
 
 OPENSSL_CONF= softhsm2-util --delete-token --token "softhsm2-enginepkcs11" >/dev/null 2>&1 || echo_i "softhsm2-enginepkcs11 token not found for cleaning"
diff --git a/bin/tests/system/enginepkcs11/ns2/named.args.in b/bin/tests/system/enginepkcs11/ns2/named.args.in
new file mode 100644 (file)
index 0000000..1d6beb9
--- /dev/null
@@ -0,0 +1 @@
+@ENGINE_ARGS@ -D enginepkcs11-ns2 -m record -c named.conf -d 99 -U 4 -T maxcachesize=2097152
diff --git a/bin/tests/system/enginepkcs11/ns2/named.conf.in b/bin/tests/system/enginepkcs11/ns2/named.conf.in
new file mode 100644 (file)
index 0000000..262419e
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+
+controls { /* empty */ };
+
+options {
+       query-source address 10.53.0.2;
+       notify-source 10.53.0.2;
+       transfer-source 10.53.0.2;
+       port @PORT@;
+       pid-file "named.pid";
+       listen-on { 10.53.0.2; };
+       listen-on-v6 { none; };
+       recursion no;
+       dnssec-validation no;
+       notify no;
+};
+
+key "keyforview1" {
+        algorithm @DEFAULT_HMAC@;
+        secret "YPfMoAk6h+3iN8MDRQC004iSNHY=";
+};
+
+key "keyforview2" {
+        algorithm @DEFAULT_HMAC@;
+        secret "4xILSZQnuO1UKubXHkYUsvBRPu8=";
+};
+
+key-store "hsm" {
+       directory ".";
+       uri "pkcs11:token=softhsm2-enginepkcs11;pin-value=1234";
+};
+
+key-store "hsm2" {
+       directory "keys";
+       uri "pkcs11:token=softhsm2-enginepkcs11;pin-value=1234";
+};
+
+key-store "pin" {
+       directory ".";
+       uri "pkcs11:token=softhsm2-enginepkcs11;pin-source=pin";
+};
+
+key-store "disk" {
+       directory "keys";
+};
+
diff --git a/bin/tests/system/enginepkcs11/ns2/template.db.in b/bin/tests/system/enginepkcs11/ns2/template.db.in
new file mode 100644 (file)
index 0000000..a140bff
--- /dev/null
@@ -0,0 +1,23 @@
+; 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 http://mozilla.org/MPL/2.0/.
+;
+; See the COPYRIGHT file distributed with this work for additional
+; information regarding copyright ownership.
+
+$TTL 300       ; 5 minutes
+@                      IN SOA  ns root (
+                               2000082401 ; serial
+                               1800       ; refresh (30 minutes)
+                               1800       ; retry (30 minutes)
+                               1814400    ; expire (3 weeks)
+                               3600       ; minimum (1 hour)
+                               )
+                       NS      ns
+ns                     A       10.53.0.2
+
+txt                    TXT     "test"
index 84d4d7edb088f079d211546426db1f971aa60443..59a2361e6895b17eca6afae99bae471995e670f0 100644 (file)
@@ -24,11 +24,6 @@ parse_openssl_config
 printf '%s' "${HSMPIN:-1234}" >ns1/pin
 PWD=$(pwd)
 
-copy_setports ns1/named.conf.in ns1/named.conf
-sed -e "s/@ENGINE_ARGS@/${ENGINE_ARG}/g" <ns1/named.args.in >ns1/named.args
-
-mkdir ns1/keys
-
 keygen() {
   type="$1"
   bits="$2"
@@ -52,6 +47,11 @@ keyfromlabel() {
 }
 
 # Setup ns1.
+copy_setports ns1/named.conf.in ns1/named.conf
+sed -e "s/@ENGINE_ARGS@/${ENGINE_ARG}/g" <ns1/named.args.in >ns1/named.args
+
+mkdir ns1/keys
+
 dir="ns1"
 infile="${dir}/template.db.in"
 for algtypebits in rsasha256:rsa:2048 rsasha512:rsa:2048 \
@@ -161,3 +161,149 @@ zone "${alg}.split" {
 EOF
   fi
 done
+
+# Setup ns2 (with views).
+copy_setports ns2/named.conf.in ns2/named.conf
+sed -e "s/@ENGINE_ARGS@/${ENGINE_ARG}/g" <ns2/named.args.in >ns2/named.args
+
+mkdir ns2/keys
+
+dir="ns2"
+infile="${dir}/template.db.in"
+algtypebits="ecdsap256sha256:EC:prime256v1"
+alg=$(echo "$algtypebits" | cut -f 1 -d :)
+type=$(echo "$algtypebits" | cut -f 2 -d :)
+bits=$(echo "$algtypebits" | cut -f 3 -d :)
+tld="views"
+
+if $SHELL ../testcrypto.sh $alg; then
+  zone="$alg.$tld"
+  zonefile1="zone.$alg.$tld.view1.db"
+  zonefile2="zone.$alg.$tld.view2.db"
+  ret=0
+
+  echo_i "Generate keys $alg $type:$bits for zone $zone"
+  keygen $type $bits $zone enginepkcs11-zsk || ret=1
+  keygen $type $bits $zone enginepkcs11-ksk || ret=1
+  test "$ret" -eq 0 || exit 1
+
+  echo_i "Get ZSK $alg $zone $type:$bits"
+  zsk1=$(keyfromlabel $alg $zone enginepkcs11-zsk $dir)
+  test -z "$zsk1" && exit 1
+
+  echo_i "Get KSK $alg $zone $type:$bits"
+  ksk1=$(keyfromlabel $alg $zone enginepkcs11-ksk $dir -f KSK)
+  test -z "$ksk1" && exit 1
+
+  (
+    cd $dir
+    zskid1=$(keyfile_to_key_id $zsk1)
+    kskid1=$(keyfile_to_key_id $ksk1)
+    echo "$zskid1" >$zone.zskid1
+    echo "$kskid1" >$zone.kskid1
+  )
+
+  echo_i "Sign zone with $ksk1 $zsk1"
+  cat "$infile" "${dir}/${ksk1}.key" "${dir}/${zsk1}.key" >"${dir}/${zonefile1}"
+  $SIGNER $ENGINE_ARG -K $dir -S -a -g -O full -o "$zone" "${dir}/${zonefile1}" >signer.out.view1.$zone || ret=1
+  test "$ret" -eq 0 || exit 1
+
+  cat "$infile" "${dir}/${ksk1}.key" "${dir}/${zsk1}.key" >"${dir}/${zonefile2}"
+  $SIGNER $ENGINE_ARG -K $dir -S -a -g -O full -o "$zone" "${dir}/${zonefile2}" >signer.out.view2.$zone || ret=1
+  test "$ret" -eq 0 || exit 1
+
+  echo_i "Generate successor keys $alg $type:$bits for zone $zone"
+  keygen $type $bits $zone enginepkcs11-zsk2 || ret=1
+  keygen $type $bits $zone enginepkcs11-ksk2 || ret=1
+  test "$ret" -eq 0 || exit 1
+
+  echo_i "Get ZSK $alg $id-$zone $type:$bits"
+  zsk2=$(keyfromlabel $alg $zone enginepkcs11-zsk2 $dir)
+  test -z "$zsk2" && exit 1
+
+  echo_i "Get KSK $alg $id-$zone $type:$bits"
+  ksk2=$(keyfromlabel $alg $zone enginepkcs11-ksk2 $dir -f KSK)
+  test -z "$ksk2" && exit 1
+
+  (
+    cd $dir
+    zskid2=$(keyfile_to_key_id $zsk2)
+    kskid2=$(keyfile_to_key_id $ksk2)
+    echo "$zskid2" >$zone.zskid2
+    echo "$kskid2" >$zone.kskid2
+    cp "${zsk2}.key" "${zsk2}.zsk2"
+    cp "${ksk2}.key" "${ksk2}.ksk2"
+  )
+
+  echo_i "Add zone $alg.same-policy.$tld to named.conf"
+  cp $infile ${dir}/zone.${alg}.same-policy.view1.db
+  cp $infile ${dir}/zone.${alg}.same-policy.view2.db
+
+  echo_i "Add zone zone-with.different-policy.$tld to named.conf"
+  cp $infile ${dir}/zone.zone-with.different-policy.view1.db
+  cp $infile ${dir}/zone.zone-with.different-policy.view2.db
+
+  echo_i "Add zone $zone to named.conf"
+  cat >>"${dir}/named.conf" <<EOF
+dnssec-policy "$alg" {
+       keys {
+               csk key-store "hsm" lifetime unlimited algorithm ${alg};
+       };
+};
+
+dnssec-policy "rsasha256" {
+       keys {
+               csk key-store "hsm2" lifetime unlimited algorithm rsasha256 2048;
+       };
+};
+
+view "view1" {
+       match-clients { key "keyforview1"; };
+
+       zone "$zone" {
+               type primary;
+               file "${zonefile1}.signed";
+               allow-update { any; };
+       };
+
+       zone "${alg}.same-policy.${tld}" {
+               type primary;
+               file "zone.${alg}.same-policy.view1.db";
+               dnssec-policy "$alg";
+               allow-update { any; };
+       };
+
+       zone "zone-with.different-policy.${tld}" {
+               type primary;
+               file "zone.zone-with.different-policy.view1.db";
+               dnssec-policy "$alg";
+               allow-update { any; };
+       };
+};
+
+view "view2" {
+       match-clients { key "keyforview2"; };
+
+       zone "$zone" {
+               type primary;
+               file "${zonefile2}.signed";
+               allow-update { any; };
+       };
+
+       zone "${alg}.same-policy.${tld}" {
+               type primary;
+               file "zone.${alg}.same-policy.view2.db";
+               dnssec-policy "$alg";
+               allow-update { any; };
+       };
+
+       zone "zone-with.different-policy.${tld}" {
+               type primary;
+               file "zone.zone-with.different-policy.view2.db";
+               dnssec-policy "rsasha256";
+               allow-update { any; };
+       };
+};
+
+EOF
+fi
index d9fe3584758e8d03926df9d62976f03aeb151b43..e30540c658949f1a949b9039f70451aee9ad1b1e 100644 (file)
@@ -243,6 +243,150 @@ done
 # Go back to main test dir.
 cd ..
 
+# Perform tests inside ns2 dir
+cd ns2
+
+algtypebits="ecdsap256sha256:EC:prime256v1"
+alg=$(echo "$algtypebits" | cut -f 1 -d :)
+type=$(echo "$algtypebits" | cut -f 2 -d :)
+bits=$(echo "$algtypebits" | cut -f 3 -d :)
+zone="${alg}.views"
+zonefile1="zone.$alg.views.view1.db.signed"
+zonefile2="zone.$alg.views.view2.db.signed"
+
+skip=0
+if [ ! -f $zonefile1 ]; then
+  echo_i "skipping test for ${alg}:${type}:${bits}, no signed zone file ${zonefile1}"
+  skip=1
+fi
+
+if [ ! -f $zonefile2 ]; then
+  echo_i "skipping test for ${alg}:${type}:${bits}, no signed zone file ${zonefile2}"
+  skip=1
+fi
+
+if [ $skip -eq 0 ]; then
+  # Basic checks if setup was successful.
+  n=$((n + 1))
+  ret=0
+  echo_i "Test key generation was successful for $zone ($n)"
+  check_keys $zone 4 || ret=1
+  status=$((status + ret))
+
+  n=$((n + 1))
+  ret=0
+  echo_i "Test zone signing was successful for $zone in view1 ($n)"
+  $VERIFY -z -o $zone "${zonefile1}" >verify.out.$zone.view1.$n 2>&1 || ret=1
+  test "$ret" -eq 0 || echo_i "failed (dnssec-verify failed)"
+  status=$((status + ret))
+
+  n=$((n + 1))
+  ret=0
+  echo_i "Test zone signing was successful for $zone in view2 ($n)"
+  $VERIFY -z -o $zone "${zonefile2}" >verify.out.$zone.view2.$n 2>&1 || ret=1
+  test "$ret" -eq 0 || echo_i "failed (dnssec-verify failed)"
+  status=$((status + ret))
+
+  # Test dnssec-policy signing with keys stored in engine.
+  zone="${alg}.same-policy.views"
+
+  n=$((n + 1))
+  ret=0
+  echo_i "Test key generation was successful for $zone ($n)"
+  check_keys $zone 1 || ret=1
+  status=$((status + ret))
+
+  _dig_inview() {
+    _qtype="$1"
+    _alg="$2"
+    _tsig="$DEFAULT_HMAC:$3:$4"
+    dig_with_opts "$zone" @10.53.0.2 $_qtype -y "$_tsig" >dig.out.$zone.$n || return 1
+    awk -v cov="$_qtype" '$4 == "RRSIG" && $5 == cov { print $6 }' dig.out.$zone.$n >dig.out.alg.$zone.$n || return 1
+    numsigs=$(cat dig.out.alg.$zone.$n | wc -l)
+    test $numsigs -eq 1 || return 1
+    grep -w "$_alg" dig.out.alg.$zone.$n >/dev/null || return 1
+  }
+
+  n=$((n + 1))
+  ret=0
+  echo_i "Test SOA is signed for $zone in view1 ($n)"
+  VIEW1="YPfMoAk6h+3iN8MDRQC004iSNHY="
+  retry_quiet 4 _dig_inview SOA 13 keyforview1 $VIEW1 || ret=1
+  test "$ret" -eq 0 || echo_i "failed (SOA RRset not signed)"
+  status=$((status + ret))
+
+  n=$((n + 1))
+  ret=0
+  echo_i "Test DNSKEY is signed for $zone in view1 ($n)"
+  retry_quiet 4 _dig_inview DNSKEY 13 keyforview1 $VIEW1 || ret=1
+  test "$ret" -eq 0 || echo_i "failed (DNSKEY RRset not signed)"
+  status=$((status + ret))
+
+  n=$((n + 1))
+  ret=0
+  echo_i "Test SOA is signed for $zone in view2 ($n)"
+  VIEW2="4xILSZQnuO1UKubXHkYUsvBRPu8="
+  retry_quiet 4 _dig_inview SOA 13 keyforview2 $VIEW2 || ret=1
+  test "$ret" -eq 0 || echo_i "failed (SOA RRset not signed)"
+  status=$((status + ret))
+
+  n=$((n + 1))
+  ret=0
+  echo_i "Test DNSKEY is signed for $zone in view2 ($n)"
+  retry_quiet 4 _dig_inview DNSKEY 13 keyforview2 $VIEW2 || ret=1
+  test "$ret" -eq 0 || echo_i "failed (DNSKEY RRset not signed)"
+  status=$((status + ret))
+
+  # Now test zone in different views using a different dnssec-policy.
+  zone="zone-with.different-policy.views"
+
+  n=$((n + 1))
+  ret=0
+  echo_i "Test key generation was successful for $zone in view1 ($n)"
+  # view1
+  check_keys $zone 1 || ret=1
+  status=$((status + ret))
+  # view2
+  echo_i "Test key generation was successful for $zone in view2 ($n)"
+  count=$(ls keys/K*.key | grep "K${zone}" | wc -l)
+  test "$count" -eq 1 || ret=1
+  test "$ret" -eq 0 || echo_i "failed (expected 1 key, got $count)"
+  status=$((status + ret))
+
+  n=$((n + 1))
+  ret=0
+  echo_i "Test SOA is signed for $zone in view1 ($n)"
+  VIEW1="YPfMoAk6h+3iN8MDRQC004iSNHY="
+  retry_quiet 4 _dig_inview SOA 13 keyforview1 $VIEW1 || ret=1
+  test "$ret" -eq 0 || echo_i "failed (SOA RRset not signed)"
+  status=$((status + ret))
+
+  n=$((n + 1))
+  ret=0
+  echo_i "Test DNSKEY is signed for $zone in view1 ($n)"
+  retry_quiet 4 _dig_inview DNSKEY 13 keyforview1 $VIEW1 || ret=1
+  test "$ret" -eq 0 || echo_i "failed (DNSKEY RRset not signed)"
+  status=$((status + ret))
+
+  n=$((n + 1))
+  ret=0
+  echo_i "Test SOA is signed for $zone in view2 ($n)"
+  VIEW2="4xILSZQnuO1UKubXHkYUsvBRPu8="
+  retry_quiet 4 _dig_inview SOA 8 keyforview2 $VIEW2 || ret=1
+  test "$ret" -eq 0 || echo_i "failed (SOA RRset not signed)"
+  status=$((status + ret))
+
+  n=$((n + 1))
+  ret=0
+  echo_i "Test DNSKEY is signed for $zone in view2 ($n)"
+  retry_quiet 4 _dig_inview DNSKEY 8 keyforview2 $VIEW2 || ret=1
+  test "$ret" -eq 0 || echo_i "failed (DNSKEY RRset not signed)"
+  status=$((status + ret))
+fi
+
+# Go back to main test dir.
+cd ..
+
 n=$((n + 1))
 ret=0
 echo_i "Checking for assertion failure in pk11_numbits()"