From 024d67eca9bbcabc3a9118d28258768e03239022 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicki=20K=C5=99=C3=AD=C5=BEek?= Date: Thu, 11 Sep 2025 14:27:34 +0200 Subject: [PATCH 1/2] Test that DNSSEC validation is aborted on malformed DNSKEY Create a signed zone file that contains malformed ZSKs with colliding key tags. The ZSKs don't represent valid ECDSA keys and will cause a crypto failure when attempting to use them. Sign the zone with KSK, with the exception of one record which is "signed" with the invalid ZSKs. Check that the resolver aborts the DNSSEC verification after encountering the first crypto failure, indicating malformed DNSKEY. (cherry picked from commit 1a2e46d364c8f706c02f3a3681195b03680419e8) --- .../dnssec-malformed-dnskey/ns2/example.db.in | 128 ++++++++++++ .../dnssec-malformed-dnskey/ns2/named.conf.j2 | 37 ++++ .../ns2/trusted.conf.j2 | 16 ++ .../dnssec-malformed-dnskey/ns3/named.conf.j2 | 34 ++++ .../ns3/trusted.conf.j2 | 1 + .../tests_malformed_dnskey.py | 182 ++++++++++++++++++ 6 files changed, 398 insertions(+) create mode 100644 bin/tests/system/dnssec-malformed-dnskey/ns2/example.db.in create mode 100644 bin/tests/system/dnssec-malformed-dnskey/ns2/named.conf.j2 create mode 100644 bin/tests/system/dnssec-malformed-dnskey/ns2/trusted.conf.j2 create mode 100644 bin/tests/system/dnssec-malformed-dnskey/ns3/named.conf.j2 create mode 120000 bin/tests/system/dnssec-malformed-dnskey/ns3/trusted.conf.j2 create mode 100644 bin/tests/system/dnssec-malformed-dnskey/tests_malformed_dnskey.py diff --git a/bin/tests/system/dnssec-malformed-dnskey/ns2/example.db.in b/bin/tests/system/dnssec-malformed-dnskey/ns2/example.db.in new file mode 100644 index 0000000000..b1705d05e4 --- /dev/null +++ b/bin/tests/system/dnssec-malformed-dnskey/ns2/example.db.in @@ -0,0 +1,128 @@ +; 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 + 600 ; refresh + 600 ; retry + 1200 ; expire + 600 ; minimum + ) + +@ NS @ +@ A 10.53.0.2 + +; All of the following DNSKEYs are malformed and have the same key tag - 20071. +; The keys use invalid parameters for the ECDSA curve. + +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cNCeMAGu8qmCKB+KmHS3YPgZjMZtl1Wd/fvtHF/3sU3HoOfwFg5Y9Ytl2+URx5Or0NNksES2iAAwmRfEEnH/hzk+8xF +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cNCeMAGu8qmCKB+KmHS3YPgZjMZtl1Wd/fvtHF/3sU3HoOfjFg5Y9Ytl2+UR1JO/UNNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cNCeMAGu8qmCKB+KmHS3YPgZjMZtl1Wd/fvtHF/3sW2HoOfwFg5Y1ctl2+URx5O/UNNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cNCeMAGu8qmCKB+KmHS3YPgZjMZtl1Wd/fvtHF/3sU3HoOfwFg5ZA8tl2+URx5O/UNNkogS2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rjJ3Mr7XEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cNCeMAGu8qmCKB+KmHS3YPgZjMZtl1Wd/fvtHF/3sU3HoOfwFg5Y9Ytl2+URx5O/UNNksES2iAAwghfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD47F1z4ulhFFbCNxbiu1BvD9cNCeMAGu8qmCKB+KmHS3YPgZjMZtl1Wd/fvtHF/3sU3HoOfwFg5Y9Ytl2+URydO/UNNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cNCeMAGu8qmCKB+KmHS3YPgZjMZtl1Wd/fvtHF/3sU3HoOfwFg5Y9Ytl2+URx5O/UNNkuMS2iAAwmRfEEnH/hzk2cv3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNi7iu1BvD9cNCeMAGu8qmCKB+KmHS3YPgZjMZtl1Wd/fvtHF/3sU3HoOfwFg5Y9Yt0W+URx5O/UNNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cNCeNcGu8qmCKB+KmHS3YPgZjMZtl1Wd/fvtHF/3sU3HoOfwFg5Y9Ytl2+URx5O/UNNksES2iAAwmRfEEnH/hzk+8vg +@ DNSKEY 256 3 14 rdZ2xb7XEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cNCeMAGu8qmCKB+KmHS3YPgZjMZtl1Wd/fvtHF/3sU3HoOfwFg5Y9Ytl2+URx5O/UNNky4S2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cNCeMAGu8qmCKB+FGHS3YPgZjMZtl1Wd/fvtHF/3sU3HoOfwFg5Y9Ytl2+URx5PE0NNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EFvr4ulinFbCNxbiu1BvD9cNCeMAGu8qmCKB+KmHS3YPgZjMZtl1Wd/fvtHF/3sU3HoOfwFg5Y9Ytl2+URx5O/UNNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbkf1BvDhMNCeMAGu8qmCKB+KmHS3YPgZjMZtl1Wd/fvtHF/3sU3HoOfwFg5Y9Ytl2+URx5O/UNNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cNCeMAGu8qmCKB+KmHS3YPgZjMZtjlWd/fvtHF/3sU3HoOfwFg5Y9Ytl2+URx5O/UNNkuUS2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cNCeMAGu8qmCKB+KmHS3YPgZjMZtl1Wd/fvtHF/3sS9HoOfwFg5Y9Ytl2+URx5O/UNNksETVCAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cNCeMAGu8qmCKB+KmHS3YPgZjMZtl1Wd/fvtHF/3sU3HoOfwFg5Y9Ytl2+URx5O/UNNkroS2iAHwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cNCeMAGu8qmCKB+KmHS3YPgZjMZtmpWd/fvtHF/3sU3HoOfwFg5Y9Ytl2+URx5O/UNAksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cNCeMAGQ8qmCKB+KmHS3YPgZjMZtl1W7/fvtHF/3sU3HoOfwFg5Y9Ytl2+URx5O/UNNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cNCeMAGu8qmCKB+KmIe3YPgZjMZthFWd/fvtHF/3sU3HoOfwFg5Y9Ytl2+URx5O/UNNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Nr7XEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cNCeMAGt8qmCKB+KmHS3YPgZjMZtl1Wd/fvtHF/3sU3HoOfwFg5Y9Ytl2+URx5O/UNNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cL1eMAGu8qmCKB+KmHS3YPgZjMZtl1Wd/fvtHGAK8U3HoOfwFg5Y9Ytl2+URx5O/UNNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4uli7FbCNxbiu1BvD9cNCeMAGu8qmCKB+KmHS3YPgZjMZtl1Wd/fvtHF/3sU3HoOfwFg5Y9Ytl2+URqhO/UNNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD6VF1z4ulhFFbCNdLiu1BvD9cNCeMAGu8qmCKB+KmHS3YPgZjMZtl1Wd/fvtHF/3sU3HoOfwFg5Y9Ytl2+URx5O/UNNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulgyFbCNxbiu1BvD9cNCeMAGu8qmCKB+KmHS3YPgZjMZtl1Wd/fvtIR/3sU3HoOfwFg5Y9Ytl2+URx5O/UNNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cNCeMAHOcqmCKB+KmHS3QXgZjMZtl1Wd/fvtHF/3sU3HoOfwFg5Y9Ytl2+URx5O/UNNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cNCeMAGasqmCKB+KmHS3dTgZjMZtl1Wd/fvtHF/3sU3HoOfwFg5Y9Ytl2+URx5O/UNNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cNCeMAGu8qmCKB+KmHS3YPgZjMZtl1Wd/fvtHF/3sU3HoOfeVg5Y9Ytl2+URx5O/UNNksES2iAAwmRfV0nH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cNCeMAGu8qmCKB+KmHS3YPgZjMZtl1Wd/fvtHF/3sU3HoOfwFg5Y9Ytl2+URx5O/UNNksES2iAAwsteqUnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cNCeMAGu8qmCKB+KmHS3YPgZjMZtl1WEvfvtHF/3sU3HoOfwFieY9Ytl2+URx5O/UNNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cNCeMAGu8qmCKB+KmHS3YPgZjMZtl1Wd/fvtHF/3sU3HoOfwFg5Y9YtSW+UR2xO/UNNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cNCeMAGu8qmCKB+KmHS3YPgZjMZtl1WvPfvtHF/3sU3HoOfwFg5Y5Etl2+URx5O/UNNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cNCeMAGu8qmCKB+KmHS3YPg5jMZtl1V9/fvtHF/3sU3HoOfwFg5Y9Ytl2+URx5O/UNNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cNCeMAGu8qmCKB+KmHS3YPgZjMZtl1Wd/fvtHF/3sU3HnqfyVg5Y9Ytl2+URx5O/UNNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD6WF1z4ulhFFbCNxbiu1BvD9cNCeMAGu8qmCKB+KmHS3YPgZjMZtl1Wd/fvtHF/3sTlHoOfwFg5Y9Ytl2+URx5O/UNNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbiu1BfD9cNCeMAGu8qmCKB+KmHS3YPgZjMZtl1Wd/fvtHF/3sU3HoOfwFg5Y9Ytl2+URx5O/UNNksES2iAAwmRfFEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cNCeMAGu8qmCKB+KmHS3YPgcjMZtl1Wd/fvtHF/3sU3HoOfwFg5Y9Ytl2+URx5O/UNNksES2iAAwmRfEEnH/hzk78v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD3HF1z4ulhFFbCNxbiu1BvD9cNCeMAGu8qmCKB+KmHS3YPgZjMZtl1Wd/fvtHF/3sU3HoOfwFg5Y9Ytl2+URx5O/UNNksES2iAAwmRfEEnH/hzleMv3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulinFbCNxbiu07nD9cNCeMAGu8qmCKB+KmHS3YPgZjMZtl1Wd/fvtHF/3sU3HoOfwFg5Y9Ytl2+URx5O/UNNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cNCeJIGu8qmCKB+KmHS3YPgZjMZtl1Wd/fvtHF/3sU3HoOfwFhnY9Ytl2+URx5O/UNNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCOE7iu1BvD9cNCeMAGu8qmCKB+KmGE3YPgZjMZtl1Wd/fvtHF/3sU3HoOfwFg5Y9Ytl2+URx5O/UNNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cNCeMAGu8qmCKB+KmHS3YPgZjMZtl1Wd/fvtGB/3sU3HoOfwFg5Y9Ytl2+URx5O/UNNksES2iAAwmRfEEnH/hzlDMv3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EFwn4uliYFbCNxbiu1BvD9cNCeMAGu8qmCKB+KmHS3YPgZjMZtl1Wd/fvtHF/3sU3HoOfwFg5Y9Ytl2+URx5O/UNNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cLTeMAGu8sVCKB+KmHS3YPgZjMZtl1Wd/fvtHF/3sU3HoOfwFg5Y9Ytl2+URx5O/UNNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cNCeMAGu8qmCKB+KmHS3YPgZjMZtl1WMvfvtHF/3sU3HoOfwFg5Y9Ytl2+URx5O/UNNksES2iBFwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbiu1JHD9cNCeMAGu8qmCKB+KmHS3YPgZjMZtl1Wd/fvtHF/3sU3HoOfSlg5Y9Ytl2+URx5O/UNNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNf7iu1BvD9cNCeMAGu8qmCKB+KmHS3YPgrDMZtl1Wd/fvtHF/3sU3HoOfwFg5Y9Ytl2+URx5O/UNNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFcCNxbiu1BvD9cNCeMAGu8qmCKB+KmHS3YPgZjMZtl1Wd/fftHF/3sU3HoOfwFg5Y9Ytl2+URx5O/UNNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cNCeMAGu8qmCKB+KmHS3YPgZjMZtl1Wd/fGtHF/3sU3HoOfwFg5Y9Ytl2+UR0dO/UNNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cNCeMAGu8qmCKB+KmHS3YPgZjM7tl1Wd/fvtHF/3sU3HoOfnlg5Y9Ytl2+URx5O/UNNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbh71BvD9cN1eMAGu8qmCKB+KmHS3YPgZjMZtl1Wd/fvtHF/3sU3HoOfwFg5Y9Ytl2+URx5O/UNNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cNCeMAGu8qmCKB+KmHS3YPgZjMZtl1Wd/fvtHF/3sU3HoOfwFg5Y9Ytl2+URx5O/UNNksES2iAAwmRfYknH/crk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cNCeMAGu8qmCKB+KmHS3YPgZjMZtl1Wd/hHtHF/3sU3HoOfwFg5Y9Ytl288Rx5O/UNNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF8z4ulhFFbCNxbiu1BvD9cNCeMAGu8qmCKB9umHS3YPgZjMZtl1Wd/fvtHF/3sU3HoOfwFg5Y9Ytl2+URx5O/UNNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cNCeMAHGsqmCKB+KmHS3YPgZjMZtl1Wd/fvtHF/3sU3HoOfwFg5Y3ctl2+URx5O/UNNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4vlhFFbCNxbiu1BvD9cNCeMAGu8qmCKB+KmHS3YPgZjMZtl1Wd/frtHF/3sU3HoOfwFg5Y9Ytl2+URx5O/UNNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cNCeMAGu8qmCKB+KmHS3YPgZjMZtopWd/fvtHF/3sU3HoOfwFgMY9Ytl2+URx5O/UNNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cNCeMAGu8qmCKB+lWHS3RjgZjMZtl1Wd/fvtHF/3sU3HoOfwFg5Y9Ytl2+URx5O/UNNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD4uF1z4ulhFFbCNxbiu1BvD9cNCeMAGu8qmCKB+KmHS3YPgfDMZtl1Wd/fvtHF/3sU3HoOfwFg5Y9Ytl2+URx5O/UNNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cNCeMAGu8qmCKB+KmHS3YPgZjMZtl1Wd/gNtHF/3sU3HoOfwFg5Y9Ytl292Rx5O/UNNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cNCeMAGu8qmCKB+KmHS3YPgZjMZtl1Wd/fvtHF/qMU3HoOfwFg5Y9YtzW+URx5O/UNNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cNCeMAGu8qmCKB+KmHS3YPgZjMZtl1Wd/fvtHF/3sU3HoOfwFg5Y9Ytv2+URx5O/UMlksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr8HEQoEdD5EF1z4ulhFFYCNxbiu1BvD9cNCeMAGu8qmCKB+KmHS3YPgZjMZtl1Wd/fvtHF/3sU3HoOfwFg5Y9Ytl2+URx5O/UNNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cNCeMAGu8qmCKB+KmHS3YPgZjMZtl1Wd/fvtHF/6MU3HoOfwFg5Y9Ytl2+URx5O/UNNksES2iAAwmRfEEm9/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbkT1BvD9cNCeMAGu8qmCKB+KmHS3YPgZjMZtl1Wd/fvtHF/3sU3HoOfwFg5Y9Ytl2+URx5O/UNNksES2iAAwmReq0nH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cNCeMAGu8qmCKB+KmHS3YPgZjMZtl1Wd/fvtCh/3sU3HoOfwFg5Y9Ytl2+URx5O/UNNksES2iAAwmRfEEnH/hzlRMv3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cNCeMAGu8rXCKB+KmHS3YPgZjMZtl1Wd/fvtHF/3sU3HoOfwFg5Y9Ytl2+URx5O/UNNksES2iAAwmRfEEnH/hzkysv3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cNCeMAGu8qmCKB+KmHS3YPg2TMZtl1Wd/fvtHF/3sTEHoOfwFg5Y9Ytl2+URx5O/UNNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cNCeMAGu8qmCKB+KmHS3YPgZjMZtl1Wd/fvtHF/3sU3HoOftVg5Y9Ytl2+URx5O/UNNksES2iAAwm9fEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cN2eMAGu8qmCKB+KmHS3YPgZjMZtl1Wd/fvtHF/3sUDHoOfwFg5Y9Ytl2+URx5O/UNNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr5aEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cNCeMAGu8qmCKB+p2HS3YPgZjMZtl1Wd/fvtHF/3sU3HoOfwFg5Y9Ytl2+URx5O/UNNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF0D4ulhFFbCNxbiu1BvD9cNCeMAGu8qmCKB+KmHS3YPgZjMZtl1Wd/fvtHF/3sU3HoOf3Fg5Y9Ytl2+URx5O/UNNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD6lF1z4ulhFFbCNxbiu1BvD9cNCeMAGu8qmCD9+KmHS3YPgZjMZtl1Wd/fvtHF/3sU3HoOfwFg5Y9Ytl2+URx5O/UNNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4jVhFFbCNxbiu1BvD9cNCeMAGu8qmCKB+KmHS3YPgZjMZtopWd/fvtHF/3sU3HoOfwFg5Y9Ytl2+URx5O/UNNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cNCeMAGu8qmCKB+KmI03YPgZjMZtftWd/fvtHF/3sU3HoOfwFg5Y9Ytl2+URx5O/UNNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cNCeMAGu8qmCKB+KmHS3YPgZjMZtl1Wd/fvtFp/3sU3HoOfwFg5Y9Ytl2+URx5O/UNNktgS2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFZyNxbiu1BvD9cNCeMAGu8qmCKB+KmHS3YPgZjMZtl1Wd/fvtHF/3sU3HoOfwFg5Y9Ytl2+URx5O/UNNksES2iAAwnhfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cNCeMAGu8qmCKB+KmHS3YPgZjMZtl1Wd/gKtHF/w8U3HoOfwFg5Y9Ytl2+URx5O/UNNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cNCeMAGu8qmCKB+KmHS3YPgZjMZtl1Wd/fvtHF/3sU3HoOfwFfXY9Ytl2+URx5O/UNNksETPCAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cNkeMAGu8qmCKB+KmHS3YPgZjMZtl1Wd/fvtHF/vMU3HoOfwFg5Y9Ytl2+URx5O/UNNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCN5Liu1BvD9cNCeMAGu8qmCKB+KmGz3YPgZjMZtl1Wd/fvtHF/3sU3HoOfwFg5Y9Ytl2+URx5O/UNNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD4fF1z4ulhFFbCNxbiu1BvD9cNCeMAGu8qmCKB+KmHS3YPgZjMZtl1Wd/fvtHF/3sU3HoOfwFg5Y9YtvG+URx5O/UNNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoE3z5EF1z4ulhFFbCNxbiu1BvD9cNCeMAGu8qmCKB+KmHS3YPgZjMZtl1Wd/fvtHF/3sU3HoOfwFg5Y9Ytl2+URx5O/UNNksES2iAAwflfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cNCeMAGu8qmCKB+KmHS3YPgZjMZtjNWd/fvtHF/3sU3HoOfwFg5Y9Ytl2+URx5O/UNNksES2iAAwmRfEEnH/hzk+8wh +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1j4ulhFFbCNxbiu1BvD9cNCeMAGu8qmCKB+KmHS3YPgZjMZtl1Wd/fvtHF/3sU3HoOfxFg5Y9Ytl2+URx5O/UNNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ2+L7XEQoEdD5EF1z4ulhFFbCNxbiu1BvEL8NCeMAGu8qmCKB+KmHS3YPgZjMZtl1Wd/fvtHF/3sU3HoOfwFg5Y9Ytl2+URx5O/UNNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cNCeMAGu8qOCKB+KmHS3YPgZjMZtl1Wd/fvtHF/3sU3HoOfwFg5Y9Ytl2+URx5O/UNNksES2iAAwmRfEEnH/hzk+8wP +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbjh1BvD9cNCeMAGu8qmCKB+KmHS3YPgZjLmtl1Wd/fvtHF/3sU3HoOfwFg5Y9Ytl2+URx5O/UNNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cNCeMAGu8qmCKB+KmHS3YPgZjM2tl1Wd/fvtHF/3sU3HoOfwFg5Y9Ytl2+URx5O/UNNksES2h/jwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCN4LiT1BvD9cNCeMAGu8qmCKB+KmHS3YPgZjMZtl1Wd/fvtHF/3sU3HoOfwFg5Y9Ytl2+URx5O/UNNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr9DEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cLWeMAGu8qmCKB+KmHS3YPgZjMZtl1Wd/fvtHF/3sU3HoOfwFg5Y9Ytl2+URx5O/UNNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cNCeMAGu8qmCKB+KmHS3YPgZjMZtl1Wd/fvtHF/3sU3HoOfwFhYY9Ytl2+URx5O/UNNksES2iAAwmRe8UnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cNCeMAGu8qlCKB+KmHS3YPgZjMatl1Wd/fvtHF/3sU3HoOfwFg5Y9Ytl2+URx5O/UNNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1n4ulhFFbCNxbiu1BvD9cNCeMAGu8qmCKB+KmHS3YPgZjMZtl1Wd/fvtHF/3sU3HoOfwFg5Y9Ytl2+URx5O/UNNksES2iAAwmdfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cODeMAGu8qmCKB+KmHS3YPgZjMZtl1Wd/fvtHF/3sU3HoOfwFg5Y9Ytl2+URx5O/UNNksES2iAAwmRez0nH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cNqeMAGu8qmCKB+KmGq3YPgZjMZtl1Wd/fvtHF/3sU3HoOfwFg5Y9Ytl2+URx5O/UNNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhrFbCNxbiu1BvD9cNCeMAGu8qmCKB+KmHS3YPgZjLztl1Wd/fvtHF/3sU3HoOfwFg5Y9Ytl2+URx5O/UNNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF534ulhFFbCNxbiu1BvD9cNCeMAGu8qmCKB+KmHS3YPgZjMZtl1Wd/fvtHF/3sU3HoOfwFg5Y9Ytl2+URx5O/UNNksES2h+/wmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cNCeMAGu8qmCKB+KmHS3QngZjMZtl1Wd/fvtHF/3sU3HoOfwFg5ZFAtl2+URx5O/UNNksES2iAAwmRfEEnH/hzk+8v3 +@ DNSKEY 256 3 14 rdZ3Mr7XEQoEdD5EF1z4ulhFFbCNxbiu1BvD9cNCeMAGu8qmCKB+KmHS3YPgZjMZtl1Wd/fvtHF/3sU3HoOfwFg5Y9Ytl2+URx5O/UNNksES2iAAwmRfEEnH/hzk+8v3 + +malformed-dnskey A 10.53.0.2 +multiple-rrsigs A 10.53.0.2 diff --git a/bin/tests/system/dnssec-malformed-dnskey/ns2/named.conf.j2 b/bin/tests/system/dnssec-malformed-dnskey/ns2/named.conf.j2 new file mode 100644 index 0000000000..6f05c6d5ef --- /dev/null +++ b/bin/tests/system/dnssec-malformed-dnskey/ns2/named.conf.j2 @@ -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. + */ + +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; }; + allow-transfer { any; }; + recursion no; + dnssec-validation yes; + + /* Keep the order of RRSIGs in the response static. */ + rrset-order { + name "example." order none; + }; +}; + +zone example. { + type primary; + file "example.db.signed.malformed"; +}; + +include "trusted.conf"; diff --git a/bin/tests/system/dnssec-malformed-dnskey/ns2/trusted.conf.j2 b/bin/tests/system/dnssec-malformed-dnskey/ns2/trusted.conf.j2 new file mode 100644 index 0000000000..89adc17f29 --- /dev/null +++ b/bin/tests/system/dnssec-malformed-dnskey/ns2/trusted.conf.j2 @@ -0,0 +1,16 @@ +/* + * 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. + */ + +trust-anchors { + example. static-key 257 3 14 "@ksk_public_key@"; +}; diff --git a/bin/tests/system/dnssec-malformed-dnskey/ns3/named.conf.j2 b/bin/tests/system/dnssec-malformed-dnskey/ns3/named.conf.j2 new file mode 100644 index 0000000000..bdd1053cf8 --- /dev/null +++ b/bin/tests/system/dnssec-malformed-dnskey/ns3/named.conf.j2 @@ -0,0 +1,34 @@ +/* + * 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. + */ + +options { + query-source address 10.53.0.3; + notify-source 10.53.0.3; + transfer-source 10.53.0.3; + port @PORT@; + pid-file "named.pid"; + listen-on { 10.53.0.3; }; + listen-on-v6 { none; }; + allow-transfer { any; }; + dnssec-validation yes; + + /* This is the default, but the test relies on it. */ + max-validation-failures-per-fetch 1; +}; + +zone "example." { + type static-stub; + server-addresses { 10.53.0.2; }; +}; + +include "trusted.conf"; diff --git a/bin/tests/system/dnssec-malformed-dnskey/ns3/trusted.conf.j2 b/bin/tests/system/dnssec-malformed-dnskey/ns3/trusted.conf.j2 new file mode 120000 index 0000000000..e14af83a92 --- /dev/null +++ b/bin/tests/system/dnssec-malformed-dnskey/ns3/trusted.conf.j2 @@ -0,0 +1 @@ +../ns2/trusted.conf.j2 \ No newline at end of file diff --git a/bin/tests/system/dnssec-malformed-dnskey/tests_malformed_dnskey.py b/bin/tests/system/dnssec-malformed-dnskey/tests_malformed_dnskey.py new file mode 100644 index 0000000000..8b871de797 --- /dev/null +++ b/bin/tests/system/dnssec-malformed-dnskey/tests_malformed_dnskey.py @@ -0,0 +1,182 @@ +# 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 base64 +from re import compile as Re + +import pytest + +pytest.importorskip("cryptography") +pytest.importorskip( + "dns", minversion="2.7.0" +) # dns.dnssec.sign_zone(deterministic=...) needed + +from cryptography.hazmat.primitives.asymmetric import ec + +import dns +import dns.dnssec +import dns.zone +from dns.rdtypes.dnskeybase import Flag + +import isctest + + +def generate_key(): + algorithm = dns.dnssec.Algorithm.ECDSAP384SHA384 + ksk_private_key = ec.generate_private_key(ec.SECP384R1()) + try: + ksk_dnskey = dns.dnssec.make_dnskey( + public_key=ksk_private_key.public_key(), + algorithm=algorithm, + flags=Flag.ZONE | Flag.SEP, + ) + except ImportError as exc: + # if the cryptography package is too old, the make_dnskey() function + # will raise ImportError at runtime + pytest.skip(f"{exc}") + return ksk_private_key, ksk_dnskey + + +MALFORMED_ZSK_KEY_TAG = 20071 + + +def create_malformed_rr(rr, n=0): + malformed_rr = dns.rdtypes.ANY.RRSIG.RRSIG( + rdclass=rr.rdclass, + rdtype=rr.rdtype, + type_covered=rr.type_covered, + algorithm=rr.algorithm, + labels=rr.labels, + original_ttl=rr.original_ttl - n, # edit TTL so multiple RRSIGs can be added + expiration=rr.expiration, + inception=rr.inception, + key_tag=MALFORMED_ZSK_KEY_TAG, # overwrite with the malformed ZSKs + signer=rr.signer, + signature=rr.signature, + ) + return malformed_rr + + +def bootstrap(): + zone = dns.zone.from_file("ns2/example.db.in", origin="example.") + lifetime = 300 + + # geneate KSK, avoid key tag collision with ZSKs + while True: + ksk_private_key, ksk_dnskey = generate_key() + if dns.dnssec.key_id(ksk_dnskey) != MALFORMED_ZSK_KEY_TAG: + break + keys = [(ksk_private_key, ksk_dnskey)] + + # sign the zone (including the malformed ZSKs) with KSK + with zone.writer() as txn: + dns.dnssec.sign_zone( + zone=zone, + txn=txn, + keys=keys, + lifetime=lifetime, + add_dnskey=True, + deterministic=False, # for OpenSSL<3.2.0 compat + ) + + # force use of the malformed ZSKs for dnssec verification + # malformed-dnskey.example. has only one invalid RRSIG and is only signed + # with malformed ZSKs + malformed_rrset = zone.get_rdataset("malformed-dnskey", "RRSIG", "A") + rr = malformed_rrset.pop() + malformed_rrset.add(create_malformed_rr(rr)) + + # multiple-rrsigs.example. contains a lot of RRSIGS with the same invalid + # signature using malformed RRSIG, and one valid RRSIG + multiple_rrset = zone.get_rdataset("multiple-rrsigs", "RRSIG", "A") + rr = multiple_rrset.pop() + for i in range(99): + multiple_rrset.add(create_malformed_rr(rr, i)) + multiple_rrset.add(rr) + + zone.to_file("ns2/example.db.signed.malformed") + + return { + "ksk_public_key": base64.b64encode(ksk_dnskey.key).decode(), + } + + +def test_malformed_ecdsa(ns3): + log_validation_failed = Re(r"malformed-dnskey\.example/A\): validation failed") + log_openssl_failure = Re("EVP_PKEY_fromdata.*failed") + log_openssl_version = Re("linked to OpenSSL version: OpenSSL ([0-9]+)") + + msg = isctest.query.create("malformed-dnskey.example", "A") + + openssl_vers = ns3.log.grep(log_openssl_version) + if openssl_vers and int(openssl_vers[0].group(1)) >= 3: + # extra check for OpenSSL 3.0.0+ + with ns3.watch_log_from_here() as watcher: + res = isctest.query.tcp(msg, "10.53.0.3") + + # check the OpenSSL-specific log message appears just once + matches = watcher.wait_for_all( + [ + log_openssl_failure, + log_validation_failed, + ] + ) + assert len([m for m in matches if m.re == log_openssl_failure]) == 1 + else: + res = isctest.query.tcp(msg, "10.53.0.3") + + isctest.check.servfail(res) + + +def test_multiple_rrsigs(ns3): + log_validation_failed = Re(r"multiple-rrsigs\.example/A\): validation failed") + log_openssl_failure = Re("EVP_PKEY_fromdata.*failed") + log_openssl_version = Re("linked to OpenSSL version: OpenSSL ([0-9]+)") + + msg = isctest.query.create("multiple-rrsigs.example", "A") + + # Check the order of returned RRSIGs from auth. Due to rrset-order none; + # this should remain constant for the remainder of the test. + # Ensure the first two RRSIGs are malformed, otherwise skip the test. + res = isctest.query.tcp(msg, "10.53.0.2") + rrsigs = res.get_rrset( + res.answer, + dns.name.from_text("multiple-rrsigs.example."), + dns.rdataclass.IN, + dns.rdatatype.RRSIG, + dns.rdatatype.A, + ) + assert len(rrsigs) > 2 + if ( + rrsigs[0].key_tag != MALFORMED_ZSK_KEY_TAG + or rrsigs[1].key_tag != MALFORMED_ZSK_KEY_TAG + ): + pytest.skip("valid RRSIG listed first in response, re-run test") + + openssl_vers = ns3.log.grep(log_openssl_version) + if openssl_vers and int(openssl_vers[0].group(1)) >= 3: + # extra check for OpenSSL 3.0.0+ + with ns3.watch_log_from_here() as watcher: + res = isctest.query.tcp(msg, "10.53.0.3") + + # check the OpenSSL-specific log message appears exactly twice: + # one failure is allowed by setting max-validation-failures-per-fetch 1; + matches = watcher.wait_for_all( + [ + log_openssl_failure, + log_validation_failed, + ] + ) + assert len([m for m in matches if m.re == log_openssl_failure]) == 2 + else: + res = isctest.query.tcp(msg, "10.53.0.3") + + isctest.check.servfail(res) From ccfe50a9b1c6a6ebb63b0bb23c24a7d6a0537763 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicki=20K=C5=99=C3=AD=C5=BEek?= Date: Mon, 13 Oct 2025 18:35:33 +0200 Subject: [PATCH 2/2] Test zone with truncated revoked DNSKEY Ensure that named can handle a situation where the zone is signed with a truncated, self-signed revoked DNSKEY. The signatures are inevitably bogus and a SERVFAIL is expected. However, prior to CVE-2025-8677 fix, this could trigger an assertion failure. (cherry picked from commit 0ddfa108a730f38c8f23430506ac5398a08112ca) --- .../dnssec-malformed-dnskey/ns2/named.conf.j2 | 5 +++ .../ns2/truncated.selfsigned.db.signed | 40 +++++++++++++++++++ .../ns2/trusted.conf.j2 | 11 +++++ .../dnssec-malformed-dnskey/ns3/named.conf.j2 | 5 +++ .../tests_malformed_dnskey.py | 6 +++ 5 files changed, 67 insertions(+) create mode 100644 bin/tests/system/dnssec-malformed-dnskey/ns2/truncated.selfsigned.db.signed diff --git a/bin/tests/system/dnssec-malformed-dnskey/ns2/named.conf.j2 b/bin/tests/system/dnssec-malformed-dnskey/ns2/named.conf.j2 index 6f05c6d5ef..8aa4a3ea02 100644 --- a/bin/tests/system/dnssec-malformed-dnskey/ns2/named.conf.j2 +++ b/bin/tests/system/dnssec-malformed-dnskey/ns2/named.conf.j2 @@ -34,4 +34,9 @@ zone example. { file "example.db.signed.malformed"; }; +zone truncated.selfsigned. { + type primary; + file "truncated.selfsigned.db.signed"; +}; + include "trusted.conf"; diff --git a/bin/tests/system/dnssec-malformed-dnskey/ns2/truncated.selfsigned.db.signed b/bin/tests/system/dnssec-malformed-dnskey/ns2/truncated.selfsigned.db.signed new file mode 100644 index 0000000000..ea49773fe6 --- /dev/null +++ b/bin/tests/system/dnssec-malformed-dnskey/ns2/truncated.selfsigned.db.signed @@ -0,0 +1,40 @@ +; 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 + 600 ; refresh + 600 ; retry + 1200 ; expire + 600 ; minimum + ) + +@ NS @ +@ A 10.53.0.2 + +; The following DNSKEY is revoked and truncated. To trigger the test +; condition, its key tag must be marked as trusted by the resolver. +; Since the key isn't valid, all the RRSIGs in this file are bogus. +@ DNSKEY 385 3 14 fQA= + +@ RRSIG SOA 14 2 86400 20950926153053 20251013153053 33167 @ xxxx5f7U0DiPvKFxpB83mTyqkAO0TfM0 xe4ZMYoJUQEPYdd0GTNkFzI6crsbU0lQ t/V1YOxAt5B+T1ch9n5dhYwt7ZTqluI2 mr6myKMesdPl1zp1hEgkmFpCG3NOXl2Z +@ RRSIG NS 14 2 86400 20950926153053 20251013153053 33167 @ xxxxLBPc05g7v/K5UfGuXsHH8xd29eQb 5qWe+Ei4Qn0GlmH0x/VIJiJMZXuxD5S+ VhP7DiX7uKIxi0QS2DOK1aOMXq/2WiUV 2VBmYAoSUilMlJY84I2XbzqD5iz5y+yp +@ RRSIG A 14 2 86400 20950926153053 20251013153053 33167 @ xxxx6UguMh8jgdVox2UVURjEsAP0D8o2 mFofnFOd6eYf+49QlWD+GX6x60X/hPVi f2XFsajouCvT/ZSmoXKWad3RC1DLHF/H TdOGMKlT4DfvbeJV+N5N0bgu2Wv3QRdM +@ RRSIG DNSKEY 14 2 86400 20950926153053 20251013153053 33167 @ xxxxqayRNsL32Km0c9AjwN0RNktt4iGb 97Dwi0uiHPcM4eVNZR2w68XMUh43+nR1 DA1QE2RqIqt7soEIwi1z4kAczf7W1wrP 7dcbEwjxS9D1CefuNRG1xnj9wGsqKecI +@ NSEC a A NS SOA RRSIG NSEC DNSKEY +@ RRSIG NSEC 14 2 0 20950926153053 20251013153053 33167 @ xxxx4Y6vqeOJHWEeg0T0OY4z7BdDrTkn BY9Yra8zSjFEGZvIX3irPd81+u5xlA0T 9waJO2Y9W42IMrOeKdQt++QXVHsLhOYn 4NAF6RotHSb4cqv1DXI1PSchMaJ5FWwD + +a A 10.53.0.2 +a RRSIG A 14 3 86400 20950926153053 20251013153053 33167 @ xxxxv31CNatB9xzj3AfTMlwiO0OqxbpJ cWrHN8zjj1ScXpqrHITfG/CZpoECDLWF wkXshDB/QMxHrnXkPKEcR2c9o5tcQT5R nHvtr7HT4Ob5PcY5DnItf3OWhE+bocmW +a NSEC @ A RRSIG NSEC +a RRSIG NSEC 14 3 0 20950926153053 20251013153053 33167 @ xxxxwMWbUxb3ScBKEVheQ2wFqujc6cyt 28GVCU0wPrBpK72HSsgdYme7IG8ZXGfa IWSU1Kf/om5+El7Tf2vDs7aI1yI7e7YG D5IxMejQg5v3/wtP7AJZXP5K9ICjq/ph diff --git a/bin/tests/system/dnssec-malformed-dnskey/ns2/trusted.conf.j2 b/bin/tests/system/dnssec-malformed-dnskey/ns2/trusted.conf.j2 index 89adc17f29..b7e95e76f1 100644 --- a/bin/tests/system/dnssec-malformed-dnskey/ns2/trusted.conf.j2 +++ b/bin/tests/system/dnssec-malformed-dnskey/ns2/trusted.conf.j2 @@ -13,4 +13,15 @@ trust-anchors { example. static-key 257 3 14 "@ksk_public_key@"; + + /* + * The key tag in the trust anchor must match that of the revoked + * truncated self-signed key in the truncated.selfsigned. zone. + * + * The DNSKEY contents are intentionally different here, because the + * key doesn't have the revoked bit here and that flag is part of the + * key tag. The following decodes to key tag 33167, which is the same + * as the revoked truncated key in the zone file. + */ + truncated.selfsigned. static-key 257 3 14 "fYA="; }; diff --git a/bin/tests/system/dnssec-malformed-dnskey/ns3/named.conf.j2 b/bin/tests/system/dnssec-malformed-dnskey/ns3/named.conf.j2 index bdd1053cf8..1cff583dca 100644 --- a/bin/tests/system/dnssec-malformed-dnskey/ns3/named.conf.j2 +++ b/bin/tests/system/dnssec-malformed-dnskey/ns3/named.conf.j2 @@ -31,4 +31,9 @@ zone "example." { server-addresses { 10.53.0.2; }; }; +zone "truncated.selfsigned." { + type static-stub; + server-addresses { 10.53.0.2; }; +}; + include "trusted.conf"; diff --git a/bin/tests/system/dnssec-malformed-dnskey/tests_malformed_dnskey.py b/bin/tests/system/dnssec-malformed-dnskey/tests_malformed_dnskey.py index 8b871de797..57d8479dc3 100644 --- a/bin/tests/system/dnssec-malformed-dnskey/tests_malformed_dnskey.py +++ b/bin/tests/system/dnssec-malformed-dnskey/tests_malformed_dnskey.py @@ -180,3 +180,9 @@ def test_multiple_rrsigs(ns3): res = isctest.query.tcp(msg, "10.53.0.3") isctest.check.servfail(res) + + +def test_truncated_dnskey(): + msg = isctest.query.create("a.truncated.selfsigned.", "A") + res = isctest.query.tcp(msg, "10.53.0.3") + isctest.check.servfail(res)