--- /dev/null
+/*
+ * 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 "alternative-kz" {
+ keys {
+ ksk key-directory lifetime unlimited algorithm RSASHA256;
+ zsk key-directory lifetime unlimited algorithm RSASHA256;
+ };
+};
+
+zone "bad-algorithm.kz.example" {
+ type primary;
+ file "bad-algorithm.kz.example.db";
+ dnssec-policy "alternative-kz";
+};
--- /dev/null
+/*
+ * 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.
+ */
+
+key-store "ksk" {
+ directory "ksk";
+};
+
+key-store "zsk" {
+ directory "zsk";
+};
+
+dnssec-policy "keystores-kz" {
+ keys {
+ ksk key-store "ksk" lifetime unlimited algorithm ECDSAP256SHA256;
+ zsk key-store "zsk" lifetime unlimited algorithm ECDSAP256SHA256;
+ };
+};
+
+zone "bad-keystores.kz.example" {
+ type primary;
+ file "bad-keystores.kz.example.db";
+ dnssec-policy "keystores-kz";
+};
--- /dev/null
+/*
+ * 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 "alternative-csk" {
+ keys {
+ csk key-directory lifetime unlimited algorithm RSASHA256 2048;
+ };
+};
+
+zone "bad-length.csk.example" {
+ type primary;
+ file "bad-length.csk.example.db";
+ dnssec-policy "alternative-csk";
+};
--- /dev/null
+/*
+ * 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 "default-kz" {
+ keys {
+ ksk key-directory lifetime unlimited algorithm ECDSAP256SHA256;
+ zsk key-directory lifetime unlimited algorithm ECDSAP256SHA256;
+ };
+};
+
+zone "missing-keyfile.kz.example" {
+ type primary;
+ file "missing-keyfile.kz.example.db";
+ dnssec-policy "default-kz";
+};
--- /dev/null
+/*
+ * 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 "default-kz" {
+ keys {
+ ksk key-directory lifetime unlimited algorithm ECDSAP256SHA256;
+ zsk key-directory lifetime unlimited algorithm ECDSAP256SHA256;
+ };
+};
+
+zone "bad-role.kz.example" {
+ type primary;
+ file "bad-role.kz.example.db";
+ dnssec-policy "default-kz";
+};
--- /dev/null
+/*
+ * 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 "default-kz" {
+ keys {
+ ksk key-directory lifetime unlimited algorithm ECDSAP256SHA256;
+ zsk key-directory lifetime unlimited algorithm ECDSAP256SHA256;
+ };
+};
+
+zone "superfluous-keyfile.kz.example" {
+ type primary;
+ file "superfluous-keyfile.kz.example.db";
+ dnssec-policy "default-kz";
+};
--- /dev/null
+/*
+ * 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 "tagrange-csk" {
+ keys {
+ csk key-directory lifetime unlimited algorithm ECDSAP256SHA256 tag-range 0 32767;
+ };
+};
+
+zone "bad-tagrange.csk.example" {
+ type primary;
+ file "bad-tagrange.csk.example.db";
+ dnssec-policy "tagrange-csk";
+};
--- /dev/null
+/*
+ * 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.
+ */
+
+key-store "ksk" {
+ directory "ksk";
+};
+
+key-store "zsk" {
+ directory "zsk";
+};
+
+dnssec-policy "alternative-kz" {
+ keys {
+ ksk key-directory lifetime unlimited algorithm RSASHA256 2048;
+ zsk key-directory lifetime unlimited algorithm RSASHA256 2048;
+ };
+};
+
+dnssec-policy "alternative-csk" {
+ keys {
+ csk key-directory lifetime unlimited algorithm RSASHA256 2048;
+ };
+};
+
+dnssec-policy "default-kz" {
+ keys {
+ ksk key-directory lifetime unlimited algorithm ECDSAP256SHA256;
+ zsk key-directory lifetime unlimited algorithm ECDSAP256SHA256;
+ };
+};
+
+dnssec-policy "default-csk" {
+ keys {
+ csk key-directory lifetime unlimited algorithm ECDSAP256SHA256;
+ };
+};
+
+
+dnssec-policy "keystores-kz" {
+ keys {
+ ksk key-store "ksk" lifetime unlimited algorithm ECDSAP256SHA256;
+ zsk key-store "zsk" lifetime unlimited algorithm ECDSAP256SHA256;
+ };
+};
+
+zone "alternative.kz.example" {
+ type primary;
+ file "alternative.kz.example.db";
+ dnssec-policy "alternative-kz";
+};
+
+zone "alternative.csk.example" {
+ type primary;
+ file "alternative.csk.example.db";
+ dnssec-policy "alternative-csk";
+};
+
+zone "default.kz.example" {
+ type primary;
+ file "default.kz.example.db";
+ dnssec-policy "default-kz";
+};
+
+zone "default.csk.example" {
+ type primary;
+ file "default.csk.example.db";
+ dnssec-policy "default-csk";
+};
+
+zone "keystores.kz.example" {
+ type primary;
+ file "keystores.kz.example.db";
+ dnssec-policy "keystores-kz";
+};
--- /dev/null
+#!/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
+
+mkdir ksk
+mkdir zsk
+
+zone="alternative.kz.example"
+cp template.db.in "${zone}.db"
+$KEYGEN -a RSASHA256 -b 2048 $zone 2>keygen.out.$zone.1
+$KEYGEN -a RSASHA256 -b 2048 -fK $zone 2>keygen.out.$zone.2
+
+zone="alternative.csk.example"
+cp template.db.in "${zone}.db"
+$KEYGEN -a RSASHA256 -b 2048 -fK $zone 2>keygen.out.$zone.2
+
+zone="default.kz.example"
+cp template.db.in "${zone}.db"
+$KEYGEN -a 13 $zone 2>keygen.out.$zone.1
+$KEYGEN -a 13 -fK $zone 2>keygen.out.$zone.2
+
+zone="default.csk.example"
+cp template.db.in "${zone}.db"
+$KEYGEN -a 13 -fK $zone 2>keygen.out.$zone.2
+
+zone="keystores.kz.example"
+cp template.db.in "${zone}.db"
+$KEYGEN -a 13 -fK -K ksk $zone 2>keygen.out.$zone.2
+$KEYGEN -a 13 -K zsk $zone 2>keygen.out.$zone.2
+
+zone="superfluous-keyfile.kz.example"
+cp template.db.in "${zone}.db"
+$KEYGEN -a 13 $zone 2>keygen.out.$zone.1
+$KEYGEN -a 13 -fK $zone 2>keygen.out.$zone.2
+$KEYGEN -a 13 $zone 2>keygen.out.$zone.3 # superfluous
+
+zone="missing-keyfile.kz.example"
+cp template.db.in "${zone}.db"
+$KEYGEN -a 13 $zone 2>keygen.out.$zone.1
+# no ksk
+
+zone="bad-algorithm.kz.example"
+cp template.db.in "${zone}.db"
+$KEYGEN -a 13 $zone 2>keygen.out.$zone.1
+$KEYGEN -a 13 -fK $zone 2>keygen.out.$zone.2
+
+zone="bad-length.csk.example"
+cp template.db.in "${zone}.db"
+$KEYGEN -a 8 -b 4096 -fK $zone 2>keygen.out.$zone.2
+
+zone="bad-tagrange.csk.example"
+cp template.db.in "${zone}.db"
+$KEYGEN -a 13 -M 32768:65535 -fK $zone 2>keygen.out.$zone.2
+
+zone="bad-role.kz.example"
+cp template.db.in "${zone}.db"
+$KEYGEN -a 13 -fK $zone 2>keygen.out.$zone.1
+$KEYGEN -a 13 -fK $zone 2>keygen.out.$zone.2
--- /dev/null
+; 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 ns3
+ns3 A 10.53.0.3
+
+a A 10.0.0.1
+b A 10.0.0.2
+c A 10.0.0.3
+
--- /dev/null
+# 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.
+
+import os
+
+import pytest
+
+import isctest
+
+pytestmark = pytest.mark.extra_artifacts(
+ [
+ "bad-*.conf",
+ "K*.key",
+ "K*.private",
+ "K*.state",
+ "keygen.out.*",
+ "named.conf",
+ "*.db",
+ "ksk/",
+ "zsk/",
+ ]
+)
+
+CHECKCONF = os.environ["CHECKCONF"]
+
+
+def test_dnssecpolicy_keystore():
+ # Good configuration.
+ isctest.run.cmd([CHECKCONF, "-k", "named.conf"])
+
+ # Superfluous key file.
+ zone = "superfluous-keyfile.kz.example"
+ out = isctest.run.cmd(
+ [CHECKCONF, "-k", "bad-superfluous-keyfile.conf"], raise_on_exception=False
+ )
+ err = out.stdout.decode("utf-8")
+ assert f"zone '{zone}': wrong number of key files (3, expected 2)" in err
+
+ # Missing key file.
+ zone = "missing-keyfile.kz.example"
+ out = isctest.run.cmd(
+ [CHECKCONF, "-k", "bad-missing-keyfile.conf"], raise_on_exception=False
+ )
+ err = out.stdout.decode("utf-8")
+ assert f"zone '{zone}': wrong number of key files (1, expected 2)" in err
+
+ # Mismatch algorithm.
+ zone = "bad-algorithm.kz.example"
+ out = isctest.run.cmd(
+ [CHECKCONF, "-k", "bad-algorithm.conf"], raise_on_exception=False
+ )
+ err = out.stdout.decode("utf-8")
+ keys = isctest.kasp.keydir_to_keylist(zone)
+ assert len(keys) == 2
+ assert (
+ f"zone '{zone}': key file '{zone}/ECDSAP256SHA256/{keys[0].tag}' does not match dnssec-policy alternative-kz"
+ in err
+ )
+ assert (
+ f"zone '{zone}': key file '{zone}/ECDSAP256SHA256/{keys[1].tag}' does not match dnssec-policy alternative-kz"
+ in err
+ )
+ assert (
+ f"zone '{zone}': no key file found matching dnssec-policy alternative-kz key:'ksk algorithm:RSASHA256 length:2048 tag-range:0-65535'"
+ in err
+ )
+ assert (
+ f"zone '{zone}': no key file found matching dnssec-policy alternative-kz key:'zsk algorithm:RSASHA256 length:2048 tag-range:0-65535'"
+ in err
+ )
+
+ # Mismatch length
+ zone = "bad-length.csk.example"
+ out = isctest.run.cmd(
+ [CHECKCONF, "-k", "bad-length.conf"], raise_on_exception=False
+ )
+ err = out.stdout.decode("utf-8")
+ keys = isctest.kasp.keydir_to_keylist(zone)
+ assert len(keys) == 1
+ assert (
+ f"zone '{zone}': key file '{zone}/RSASHA256/{keys[0].tag}' does not match dnssec-policy alternative-csk"
+ in err
+ )
+ assert (
+ f"zone '{zone}': no key file found matching dnssec-policy alternative-csk key:'csk algorithm:RSASHA256 length:2048 tag-range:0-65535'"
+ in err
+ )
+
+ # Mismatch tag range
+ zone = "bad-tagrange.csk.example"
+ out = isctest.run.cmd(
+ [CHECKCONF, "-k", "bad-tagrange.conf"], raise_on_exception=False
+ )
+ err = out.stdout.decode("utf-8")
+ keys = isctest.kasp.keydir_to_keylist(zone)
+ assert len(keys) == 1
+ assert (
+ f"zone '{zone}': key file '{zone}/ECDSAP256SHA256/{keys[0].tag}' does not match dnssec-policy tagrange-csk"
+ in err
+ )
+ assert (
+ f"zone '{zone}': no key file found matching dnssec-policy tagrange-csk key:'csk algorithm:ECDSAP256SHA256 length:256 tag-range:0-32767'"
+ in err
+ )
+
+ # Mismatch role
+ zone = "bad-role.kz.example"
+ out = isctest.run.cmd([CHECKCONF, "-k", "bad-role.conf"], raise_on_exception=False)
+ err = out.stdout.decode("utf-8")
+ keys = isctest.kasp.keydir_to_keylist(zone)
+ assert len(keys) == 2
+ assert (
+ f"zone '{zone}': no key file found matching dnssec-policy default-kz key:'zsk algorithm:ECDSAP256SHA256 length:256 tag-range:0-65535'"
+ in err
+ )