diff --git a/.bind9.18.metadata b/.bind9.18.metadata new file mode 100644 index 0000000..1dcdb67 --- /dev/null +++ b/.bind9.18.metadata @@ -0,0 +1 @@ +33ff5a86e56d65859358749654ea848809bd4532 SOURCES/bind-9.18.29.tar.xz diff --git a/.fmf/version b/.fmf/version deleted file mode 100644 index d00491f..0000000 --- a/.fmf/version +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/.gitignore b/.gitignore index eb3cc4f..cda6a17 100644 --- a/.gitignore +++ b/.gitignore @@ -1,232 +1 @@ -bind-9.7.1-P2.tar.gz -config-8.tar.bz2 -bind-9.7.2b1.tar.gz -/config-8.tar.bz2 -/bind-9.7.2rc1.tar.gz -/bind-9.7.2.tar.gz -/bind-9.7.2-P2.tar.gz -/bind-9.7.2-P3.tar.gz -/bind-9.7.3b1.tar.gz -/bind-9.7.3rc1.tar.gz -/bind-9.7.3.tar.gz -/bind-9.8.0rc1.tar.gz -/bind-9.8.0.tar.gz -/bind-9.8.0-P1.tar.gz -/bind-9.8.0-P2.tar.gz -/bind-9.8.0-P4.tar.gz -/bind-9.8.1rc1.tar.gz -/bind-9.8.1.tar.gz -/bind-9.9.0b1.tar.gz -/bind-9.9.0b2.tar.gz -/bind-9.9.0rc1.tar.gz -/bind-9.9.0rc2.tar.gz -/bind-9.9.0.tar.gz -/bind-9.9.1.tar.gz -/bind-9.9.1-P1.tar.gz -/bind-9.9.1-P2.tar.gz -/bind-9.9.1-P3.tar.gz -/bind-9.9.2.tar.gz -/bind-9.9.2-P1.tar.gz -/config-9.tar.bz2 -/config-10.tar.bz2 -/bind-9.9.2-P2.tar.gz -/bind-9.9.3rc1.tar.gz -/config-11.tar.bz2 -/bind-9.9.3rc2.tar.gz -/bind-9.9.3.tar.gz -/bind-9.9.3-P1.tar.gz -/bind-9.9.4b1.tar.gz -/bind-9.9.4rc1.tar.gz -/bind-9.9.4rc2.tar.gz -/bind-9.9.4.tar.gz -/config-12.tar.bz2 -/bind-9.9.5b1.tar.gz -/bind-9.9.5rc2.tar.gz -/bind-9.9.5.tar.gz -/bind-9.9.5-P1.tar.gz -/bind-9.9.6.tar.gz -/bind-9.9.6-P1.tar.gz -/bind-9.10.1b2.tar.gz -/bind-9.10.1.tar.gz -/bind-9.10.1-P1.tar.gz -/bind-9.10.2rc1.tar.gz -/bind-9.10.2rc2.tar.gz -/bind-9.10.2.tar.gz -/config-13.tar.bz2 -/config-14.tar.bz2 -/bind-9.10.2-P1.tar.gz -/bind-9.10.2-P2.tar.gz -/bind-9.10.2-P3.tar.gz -/bind-9.10.3rc1.tar.gz -/bind-9.10.3.tar.gz -/bind-9.10.3-P2.tar.gz -/config-15.tar.bz2 -/bind-9.10.3-P3.tar.gz -/bind-9.10.3-P4.tar.gz -/bind-9.10.4-P1.tar.gz -/bind-9.10.4-P2.tar.gz -/bind-9.10.4-P3.tar.gz -/bind-9.10.4-P4.tar.gz -/bind-9.11.0-P1.tar.gz -/bind-9.11.0-P2.tar.gz -/bind-9.11.0-P3.tar.gz -/bind-9.11.0-P5.tar.gz -/config-16.tar.bz2 -/bind-9.11.1-P1.tar.gz -/bind-9.11.1-P2.tar.gz -/bind-9.11.1-P3.tar.gz -/bind-9.11.2b1.tar.gz -/bind-9.11.2.tar.gz -/config-17.tar.bz2 -/bind-9.11.2-P1.tar.gz -/bind-9.11.3b1.tar.gz -/bind-9.11.3.tar.gz -/config-18.tar.bz2 -/bind-9.11.4rc1.tar.gz -/bind-9.11.4.tar.gz -/bind-9.11.4-P1.tar.gz -/bind-9.11.4-P2.tar.gz -/bind-9.11.5.tar.gz -/bind-9.11.5-P1.tar.gz -/config-19.tar.bz2 -/bind-9.11.5-P4.tar.gz -/bind-9.11.6.tar.gz -/bind-9.11.6-P1.tar.gz -/bind-9.11.7.tar.gz -/bind-9.11.8.tar.gz -/bind-9.11.9.tar.gz -/bind-9.11.10.tar.gz -/bind-9.11.11.tar.gz -/bind-9.11.12.tar.gz -/bind-9.11.13.tar.gz -/bind-9.11.13.tar.gz.asc -/bind-9.11.14.tar.gz -/bind-9.11.14.tar.gz.asc -/bind-9.11.17.tar.gz -/bind-9.11.17.tar.gz.asc -/bind-9.11.18.tar.gz -/bind-9.11.18.tar.gz.asc -/bind-9.11.19.tar.gz -/bind-9.11.19.tar.gz.asc -/bind-9.11.20.tar.gz -/bind-9.11.20.tar.gz.asc -/bind-9.11.21.tar.gz -/bind-9.11.21.tar.gz.asc -/bind-9.11.22.tar.gz -/bind-9.11.22.tar.gz.asc -/bind-9.11.23.tar.gz -/bind-9.11.23.tar.gz.asc -/bind-9.11.24.tar.gz -/bind-9.11.24.tar.gz.asc -/bind-9.11.25.tar.gz -/bind-9.11.25.tar.gz.asc -/bind-9.11.26.tar.gz -/bind-9.11.26.tar.gz.asc -/bind-9.16.1.tar.xz -/bind-9.16.1.tar.xz.asc -/bind-9.16.2.tar.xz -/bind-9.16.2.tar.xz.asc -/bind-9.16.4.tar.xz -/bind-9.16.4.tar.xz.asc -/bind-9.16.5.tar.xz -/bind-9.16.5.tar.xz.asc -/bind-9.16.6.tar.xz -/bind-9.16.6.tar.xz.asc -/bind-9.16.7.tar.xz -/bind-9.16.7.tar.xz.asc -/bind-9.16.8.tar.xz -/bind-9.16.8.tar.xz.asc -/bind-9.16.9.tar.xz -/bind-9.16.9.tar.xz.asc -/bind-9.16.10.tar.xz -/bind-9.16.10.tar.xz.asc -/bind-9.16.11.tar.xz -/bind-9.16.11.tar.xz.asc -/bind-9.16.13.tar.xz -/bind-9.16.13.tar.xz.asc -/bind-9.16.15.tar.xz -/bind-9.16.15.tar.xz.asc -/bind-9.16.16.tar.xz -/bind-9.16.16.tar.xz.asc -/bind-9.16.17.tar.xz -/bind-9.16.17.tar.xz.asc -/bind-9.16.18.tar.xz -/bind-9.16.18.tar.xz.asc -/bind-9.16.19.tar.xz -/bind-9.16.19.tar.xz.asc -/bind-9.16.20.tar.xz -/bind-9.16.20.tar.xz.asc -/bind-9.16.21.tar.xz -/bind-9.16.21.tar.xz.asc -/bind-9.16.22.tar.xz -/bind-9.16.22.tar.xz.asc -/bind-9.16.23.tar.xz -/bind-9.16.23.tar.xz.asc -/bind-9.16.24.tar.xz -/bind-9.16.24.tar.xz.asc -/bind-9.16.25.tar.xz -/bind-9.16.25.tar.xz.asc -/bind-9.16.26.tar.xz -/bind-9.16.26.tar.xz.asc -/bind-9.16.27.tar.xz -/bind-9.16.27.tar.xz.asc -/bind-9.16.28.tar.xz -/bind-9.16.28.tar.xz.asc -/bind-9.16.29.tar.xz -/bind-9.16.29.tar.xz.asc -/bind-9.16.30.tar.xz -/bind-9.16.30.tar.xz.asc -/bind-9.18.0.tar.xz -/bind-9.18.0.tar.xz.asc -/bind-9.18.1.tar.xz -/bind-9.18.1.tar.xz.asc -/bind-9.18.2.tar.xz -/bind-9.18.2.tar.xz.asc -/bind-9.18.3.tar.xz -/bind-9.18.3.tar.xz.asc -/bind-9.18.4.tar.xz -/bind-9.18.4.tar.xz.asc -/bind-9.18.5.tar.xz -/bind-9.18.5.tar.xz.asc -/bind-9.18.6.tar.xz -/bind-9.18.6.tar.xz.asc -/bind-9.18.7.tar.xz -/bind-9.18.7.tar.xz.asc -/bind-9.18.8.tar.xz -/bind-9.18.8.tar.xz.asc -/bind-9.18.9.tar.xz -/bind-9.18.9.tar.xz.asc -/bind-9.18.10.tar.xz -/bind-9.18.10.tar.xz.asc -/bind-9.18.11.tar.xz -/bind-9.18.11.tar.xz.asc -/bind-9.18.12.tar.xz -/bind-9.18.12.tar.xz.asc -/bind-9.18.13.tar.xz -/bind-9.18.13.tar.xz.asc -/bind-9.18.14.tar.xz -/bind-9.18.14.tar.xz.asc -/bind-9.18.15.tar.xz -/bind-9.18.15.tar.xz.asc -/bind-9.18.16.tar.xz -/bind-9.18.16.tar.xz.asc -/bind-9.18.17.tar.xz -/bind-9.18.17.tar.xz.asc -/bind-9.18.18.tar.xz -/bind-9.18.18.tar.xz.asc -/bind-9.18.19.tar.xz -/bind-9.18.19.tar.xz.asc -/bind-9.18.20.tar.xz -/bind-9.18.20.tar.xz.asc -/bind-9.18.21.tar.xz -/bind-9.18.21.tar.xz.asc -/bind-9.18.24.tar.xz -/bind-9.18.24.tar.xz.asc -/bind-9.18.26.tar.xz -/bind-9.18.26.tar.xz.asc -/bind-9.18.27.tar.xz -/bind-9.18.27.tar.xz.asc -/bind-9.18.28.tar.xz -/bind-9.18.28.tar.xz.asc -/bind-9.18.29.tar.xz -/bind-9.18.29.tar.xz.asc +SOURCES/bind-9.18.29.tar.xz diff --git a/Changes.md b/Changes.md deleted file mode 100644 index 6661034..0000000 --- a/Changes.md +++ /dev/null @@ -1,43 +0,0 @@ -# Significant Changes in BIND9 package - -## BIND 9.16 - -### New features - -- *libuv* is used for network subsystem as a mandatory dependency -- *dnssec-policy* support in named.conf is introduced, providing a a key and signing policy - ([KASP](https://gitlab.isc.org/isc-projects/bind9/-/wikis/DNSSEC-Key-and-Signing-Policy-(KASP))) -- *trusted-keys* and *managed-keys* are deprecated, replaced by *trust-anchors* -- *trust-anchors* support also anchor in a *DS* format, in addition to *DNSKEY* format -- **dig, mdig** and **delv** support **+yaml** parameter to print detailed machine parseable output - -### Feature changes - -- Static trust anchor and *dnssec-validation auto;* are incompatible and cause fatal error, when used together. -- *DS* and *CDS* now generates only SHA-256 digest, SHA-1 is no longer generated by default -- SipHash 2-4 DNS Cookie ([RFC 7873](https://www.rfc-editor.org/rfc/rfc7873.html) is now default). - Only AES alternative algorithm is kept, HMAC-SHA cookie support were removed. -- **dnssec-signzone** and **dnssec-verify** commands print output to stdout, *-q* parameter can silence them - -### Features removed - -- *dnssec-enable* option is obsolete, DNSSEC support is always enabled -- *dnssec-lookaside* option is deprecated and support for it removed from all tools -- *cleaning-interval* option is removed - -### Upstream release notes - -- [9.16.10 notes](https://downloads.isc.org/isc/bind9/9.16.10/doc/arm/html/notes.html#notes-for-bind-9-16-10) -- [9.16.0 notes](https://downloads.isc.org/isc/bind9/9.16.0/doc/arm/html/notes.html#notes-for-bind-9-16-0) - -## BIND 9.14 - -- single thread support removed. Cannot provide *bind-export-libs* for DHCP -- *lwres* support completely removed. Both daemon and library -- common parts of daemon moved into *libns* shared library -- introduced plugin for filtering aaaa responses -- some SDB utilities no longer supported - -### Upstream release notes - -- [9.14.7 notes](https://downloads.isc.org/isc/bind9/9.14.7/RELEASE-NOTES-bind-9.14.7.html) diff --git a/README.md b/README.md deleted file mode 100644 index 42aad62..0000000 --- a/README.md +++ /dev/null @@ -1,33 +0,0 @@ -# BIND 9 - -[BIND (Berkeley Internet Name Domain)](https://www.isc.org/downloads/bind/doc/) is a complete, highly portable -implementation of the DNS (Domain Name System) protocol. - -Internet Systems Consortium -([https://www.isc.org](https://www.isc.org)), a 501(c)(3) public benefit -corporation dedicated to providing software and services in support of the -Internet infrastructure, developed BIND 9 and is responsible for its -ongoing maintenance and improvement. - -More details about upstream project can be found on their -[gitlab](https://gitlab.isc.org/isc-projects/bind9). This repository contains -only upstream sources and packaging instructions for -[Fedora Project](https://fedoraproject.org). - -## Subpackages - -The package contains several subpackages, some of them can be disabled on rebuild. - -* **bind** -- *named* daemon providing DNS server -* **bind-utils** -- set of tools to analyse DNS responses or update entries (dig, host) -* **bind-doc** -- documentation for current bind, *BIND 9 Administrator Reference Manual*. -* **bind-license** -- Shared license for all packages but bind-export-libs. -* **bind-libs** -- Shared libraries used by some others programs -* **bind-devel** -- Development headers for libs. Can be disabled by `--without DEVEL` - - -## Optional features - -* *GSSTSIG* -- Support for Kerberos authentication in BIND. -* *LMDB* -- Support for dynamic database for managing runtime added zones. Provides faster removal of added zone with much less overhead. But requires lmdb linked to base libs. -* *DLZ* -- Support for dynamic loaded modules providing support for features *bind-sdb* provides, but only small module is required. diff --git a/bind-9.16-redhat_doc.patch b/SOURCES/bind-9.16-redhat_doc.patch similarity index 100% rename from bind-9.16-redhat_doc.patch rename to SOURCES/bind-9.16-redhat_doc.patch diff --git a/SOURCES/bind-9.18-CVE-2024-11187-pre-test.patch b/SOURCES/bind-9.18-CVE-2024-11187-pre-test.patch new file mode 100644 index 0000000..9b0cca8 --- /dev/null +++ b/SOURCES/bind-9.18-CVE-2024-11187-pre-test.patch @@ -0,0 +1,68 @@ +From cd48dcb0f87f8bed8138cbc4635a6a46f3148620 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= +Date: Tue, 7 Jan 2025 15:22:40 +0100 +Subject: [PATCH] Isolate using the -T noaa flag only for part of the resolver + test + +Instead of running the whole resolver/ns4 server with -T noaa flag, +use it only for the part where it is actually needed. The -T noaa +could interfere with other parts of the test because the answers don't +have the authoritative-answer bit set, and we could have false +positives (or false negatives) in the test because the authoritative +server doesn't follow the DNS protocol for all the tests in the resolver +system test. + +(cherry picked from commit e51d4d3b88af00d6667f2055087ebfc47fb3107c) +--- + bin/tests/system/resolver/ns4/named.noaa | 12 ------------ + bin/tests/system/resolver/tests.sh | 8 ++++++++ + 2 files changed, 8 insertions(+), 12 deletions(-) + delete mode 100644 bin/tests/system/resolver/ns4/named.noaa + +diff --git a/bin/tests/system/resolver/ns4/named.noaa b/bin/tests/system/resolver/ns4/named.noaa +deleted file mode 100644 +index be78cc2c949..00000000000 +--- a/bin/tests/system/resolver/ns4/named.noaa ++++ /dev/null +@@ -1,12 +0,0 @@ +-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. +- +-Add -T noaa. +diff --git a/bin/tests/system/resolver/tests.sh b/bin/tests/system/resolver/tests.sh +index 982ff9761be..23b42f728cd 100755 +--- a/bin/tests/system/resolver/tests.sh ++++ b/bin/tests/system/resolver/tests.sh +@@ -322,6 +322,10 @@ done + if [ $ret != 0 ]; then echo_i "failed"; fi + status=$((status + ret)) + ++stop_server ns4 ++touch ns4/named.noaa ++start_server --noclean --restart --port ${PORT} ns4 || ret=1 ++ + n=$((n + 1)) + echo_i "RT21594 regression test check setup ($n)" + ret=0 +@@ -358,6 +362,10 @@ grep "status: NXDOMAIN" dig.ns5.out.${n} >/dev/null || ret=1 + if [ $ret != 0 ]; then echo_i "failed"; fi + status=$((status + ret)) + ++stop_server ns4 ++rm ns4/named.noaa ++start_server --noclean --restart --port ${PORT} ns4 || ret=1 ++ + n=$((n + 1)) + echo_i "check that replacement of additional data by a negative cache no data entry clears the additional RRSIGs ($n)" + ret=0 +-- +2.48.1 + diff --git a/SOURCES/bind-9.18-CVE-2024-11187.patch b/SOURCES/bind-9.18-CVE-2024-11187.patch new file mode 100644 index 0000000..68682e6 --- /dev/null +++ b/SOURCES/bind-9.18-CVE-2024-11187.patch @@ -0,0 +1,226 @@ +From 7ded6b358ced23bb6214c7309cff0850b7d1b77d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= +Date: Thu, 14 Nov 2024 10:37:29 +0100 +Subject: [PATCH] Limit the additional processing for large RDATA sets + +When answering queries, don't add data to the additional section if +the answer has more than 13 names in the RDATA. This limits the +number of lookups into the database(s) during a single client query, +reducing query processing load. + +Also, don't append any additional data to type=ANY queries. The +answer to ANY is already big enough. + +(cherry picked from commit a1982cf1bb95c818aa7b58988b5611dec80f2408) +--- + bin/tests/system/additional/tests.sh | 2 +- + lib/dns/include/dns/rdataset.h | 10 +++++++++- + lib/dns/rbtdb.c | 2 +- + lib/dns/rdataset.c | 7 ++++++- + lib/dns/resolver.c | 19 ++++++++++++------- + lib/ns/query.c | 12 ++++++++---- + 6 files changed, 37 insertions(+), 15 deletions(-) + +diff --git a/bin/tests/system/additional/tests.sh b/bin/tests/system/additional/tests.sh +index 193c9f9..e1b0cfb 100644 +--- a/bin/tests/system/additional/tests.sh ++++ b/bin/tests/system/additional/tests.sh +@@ -279,7 +279,7 @@ n=$((n + 1)) + echo_i "testing with 'minimal-any no;' ($n)" + ret=0 + $DIG $DIGOPTS -t ANY www.rt.example @10.53.0.1 >dig.out.$n || ret=1 +-grep "ANSWER: 3, AUTHORITY: 2, ADDITIONAL: 2" dig.out.$n >/dev/null || ret=1 ++grep "ANSWER: 3, AUTHORITY: 2, ADDITIONAL: 1" dig.out.$n >/dev/null || ret=1 + if [ $ret -eq 1 ]; then + echo_i "failed" + status=$((status + 1)) +diff --git a/lib/dns/include/dns/rdataset.h b/lib/dns/include/dns/rdataset.h +index f63591c..b28686a 100644 +--- a/lib/dns/include/dns/rdataset.h ++++ b/lib/dns/include/dns/rdataset.h +@@ -54,6 +54,8 @@ + #include + #include + ++#define DNS_RDATASET_MAXADDITIONAL 13 ++ + ISC_LANG_BEGINDECLS + + typedef enum { +@@ -453,7 +455,8 @@ dns_rdataset_towirepartial(dns_rdataset_t *rdataset, + isc_result_t + dns_rdataset_additionaldata(dns_rdataset_t *rdataset, + const dns_name_t *owner_name, +- dns_additionaldatafunc_t add, void *arg); ++ dns_additionaldatafunc_t add, void *arg, ++ size_t limit); + /*%< + * For each rdata in rdataset, call 'add' for each name and type in the + * rdata which is subject to additional section processing. +@@ -472,10 +475,15 @@ dns_rdataset_additionaldata(dns_rdataset_t *rdataset, + *\li If a call to dns_rdata_additionaldata() is not successful, the + * result returned will be the result of dns_rdataset_additionaldata(). + * ++ *\li If 'limit' is non-zero and the number of the rdatasets is larger ++ * than 'limit', no additional data will be processed. ++ * + * Returns: + * + *\li #ISC_R_SUCCESS + * ++ *\li #DNS_R_TOOMANYRECORDS in case rdataset count is larger than 'limit' ++ * + *\li Any error that dns_rdata_additionaldata() can return. + */ + +diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c +index 5c2f0b2..c4db047 100644 +--- a/lib/dns/rbtdb.c ++++ b/lib/dns/rbtdb.c +@@ -10317,7 +10317,7 @@ no_glue: + idx = hash_32(hash, rbtversion->glue_table_bits); + + (void)dns_rdataset_additionaldata(rdataset, dns_rootname, +- glue_nsdname_cb, &ctx); ++ glue_nsdname_cb, &ctx, 0); + + cur = isc_mem_get(rbtdb->common.mctx, sizeof(*cur)); + +diff --git a/lib/dns/rdataset.c b/lib/dns/rdataset.c +index 4d48203..0b450a9 100644 +--- a/lib/dns/rdataset.c ++++ b/lib/dns/rdataset.c +@@ -577,7 +577,8 @@ dns_rdataset_towire(dns_rdataset_t *rdataset, const dns_name_t *owner_name, + isc_result_t + dns_rdataset_additionaldata(dns_rdataset_t *rdataset, + const dns_name_t *owner_name, +- dns_additionaldatafunc_t add, void *arg) { ++ dns_additionaldatafunc_t add, void *arg, ++ size_t limit) { + dns_rdata_t rdata = DNS_RDATA_INIT; + isc_result_t result; + +@@ -589,6 +590,10 @@ dns_rdataset_additionaldata(dns_rdataset_t *rdataset, + REQUIRE(DNS_RDATASET_VALID(rdataset)); + REQUIRE((rdataset->attributes & DNS_RDATASETATTR_QUESTION) == 0); + ++ if (limit != 0 && dns_rdataset_count(rdataset) > limit) { ++ return DNS_R_TOOMANYRECORDS; ++ } ++ + result = dns_rdataset_first(rdataset); + if (result != ISC_R_SUCCESS) { + return (result); +diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c +index f8f53d2..bb0bfa1 100644 +--- a/lib/dns/resolver.c ++++ b/lib/dns/resolver.c +@@ -8904,7 +8904,7 @@ rctx_answer_any(respctx_t *rctx) { + rdataset->trust = rctx->trust; + + (void)dns_rdataset_additionaldata(rdataset, rctx->aname, +- check_related, rctx); ++ check_related, rctx, 0); + } + + return (ISC_R_SUCCESS); +@@ -8952,7 +8952,7 @@ rctx_answer_match(respctx_t *rctx) { + rctx->ardataset->attributes |= DNS_RDATASETATTR_CACHE; + rctx->ardataset->trust = rctx->trust; + (void)dns_rdataset_additionaldata(rctx->ardataset, rctx->aname, +- check_related, rctx); ++ check_related, rctx, 0); + + for (sigrdataset = ISC_LIST_HEAD(rctx->aname->list); + sigrdataset != NULL; +@@ -9159,7 +9159,7 @@ rctx_authority_positive(respctx_t *rctx) { + */ + (void)dns_rdataset_additionaldata( + rdataset, name, check_related, +- rctx); ++ rctx, 0); + done = true; + } + } +@@ -9666,8 +9666,12 @@ rctx_referral(respctx_t *rctx) { + */ + INSIST(rctx->ns_rdataset != NULL); + FCTX_ATTR_SET(fctx, FCTX_ATTR_GLUING); ++ ++ /* ++ * Mark the glue records in the additional section to be cached. ++ */ + (void)dns_rdataset_additionaldata(rctx->ns_rdataset, rctx->ns_name, +- check_related, rctx); ++ check_related, rctx, 0); + #if CHECK_FOR_GLUE_IN_ANSWER + /* + * Look in the answer section for "glue" that is incorrectly +@@ -9679,8 +9683,9 @@ rctx_referral(respctx_t *rctx) { + if (rctx->glue_in_answer && + (fctx->type == dns_rdatatype_aaaa || fctx->type == dns_rdatatype_a)) + { +- (void)dns_rdataset_additionaldata( +- rctx->ns_rdataset, rctx->ns_name, check_answer, fctx); ++ (void)dns_rdataset_additionaldata(rctx->ns_rdataset, ++ rctx->ns_name, check_answer, ++ fctx, 0); + } + #endif /* if CHECK_FOR_GLUE_IN_ANSWER */ + FCTX_ATTR_CLR(fctx, FCTX_ATTR_GLUING); +@@ -9782,7 +9787,7 @@ again: + if (CHASE(rdataset)) { + rdataset->attributes &= ~DNS_RDATASETATTR_CHASE; + (void)dns_rdataset_additionaldata( +- rdataset, name, check_related, rctx); ++ rdataset, name, check_related, rctx, 0); + rescan = true; + } + } +diff --git a/lib/ns/query.c b/lib/ns/query.c +index 5549e20..ded1eae 100644 +--- a/lib/ns/query.c ++++ b/lib/ns/query.c +@@ -2094,7 +2094,8 @@ addname: + if (trdataset != NULL && dns_rdatatype_followadditional(type)) { + if (client->additionaldepth++ < client->view->max_restarts) { + eresult = dns_rdataset_additionaldata( +- trdataset, fname, query_additional_cb, qctx); ++ trdataset, fname, query_additional_cb, qctx, ++ DNS_RDATASET_MAXADDITIONAL); + } + client->additionaldepth--; + } +@@ -2194,7 +2195,7 @@ regular: + * We don't care if dns_rdataset_additionaldata() fails. + */ + (void)dns_rdataset_additionaldata(rdataset, name, query_additional_cb, +- qctx); ++ qctx, DNS_RDATASET_MAXADDITIONAL); + CTRACE(ISC_LOG_DEBUG(3), "query_additional: done"); + } + +@@ -2220,7 +2221,8 @@ query_addrrset(query_ctx_t *qctx, dns_name_t **namep, + * To the current response for 'client', add the answer RRset + * '*rdatasetp' and an optional signature set '*sigrdatasetp', with + * owner name '*namep', to section 'section', unless they are +- * already there. Also add any pertinent additional data. ++ * already there. Also add any pertinent additional data, unless ++ * the query was for type ANY. + * + * If 'dbuf' is not NULL, then '*namep' is the name whose data is + * stored in 'dbuf'. In this case, query_addrrset() guarantees that +@@ -2275,7 +2277,9 @@ query_addrrset(query_ctx_t *qctx, dns_name_t **namep, + */ + query_addtoname(mname, rdataset); + query_setorder(qctx, mname, rdataset); +- query_additional(qctx, mname, rdataset); ++ if (qctx->qtype != dns_rdatatype_any) { ++ query_additional(qctx, mname, rdataset); ++ } + + /* + * Note: we only add SIGs if we've added the type they cover, so +-- +2.48.1 + diff --git a/SOURCES/bind-9.18-CVE-2024-12705.patch b/SOURCES/bind-9.18-CVE-2024-12705.patch new file mode 100644 index 0000000..39db165 --- /dev/null +++ b/SOURCES/bind-9.18-CVE-2024-12705.patch @@ -0,0 +1,1418 @@ +From 05f63912f7a9246ccf1c59ee0b93782b5a576dbf Mon Sep 17 00:00:00 2001 +From: Artem Boldariev +Date: Wed, 4 Sep 2024 18:53:35 +0300 +Subject: [PATCH] Implement TCP manual read timer control functionality + +This commit adds a manual TCP read timer control mode which is +supposed to override automatic resetting of the timer when any data is +received. That can be accomplished by +`isc__nmhandle_set_manual_timer()`. + +This functionality is supposed to be used by multilevel networking +transports which require finer grained control over the read +timer (TLS Stream, DoH). + +The commit is essentially an implementation of the functionality from +newer versions of BIND. + +(cherry picked from commit a67b3255426160c55faa9d1d3aa6e7579439b2b4) + +Implement TLS manual read timer control functionality + +This commit adds a manual TLS read timer control mode which is +supposed to override automatic resetting of the timer when any data is +received. + +It both depends and complements similar functionality in TCP. + +(cherry picked from commit 13d521fa5fe7102733db15079fd49c7ccf5b0648) + +Add isc__nm_async_run() + +This commit adds isc__nm_async_run() which is very similar to +isc_async_run() in newer versions of BIND: it allows calling a +callback asynchronously. + +Potentially, it can be used to replace some other async operations in +other networking code, in particular the delayed I/O calls in TLS a +TCP DNS transports to name a few and remove quiet a lot of code, but +it we are unlikely to do that for the strictly maintenance only +branch, so it is protected with DoH-related #ifdefs. + +It is implemented in a "universal" way mainly because doing it in the +specific code requires the same amount of code and is not simpler. + +(cherry picked from commit 125bfd71d3c8d0ad23477867f1e41a2392e03138) + +DoH: process data chunk by chunk instead of all at once + +Initially, our DNS-over-HTTP(S) implementation would try to process as +much incoming data from the network as possible. However, that might +be undesirable as we might create too many streams (each effectively +backed by a ns_client_t object). That is too forgiving as it might +overwhelm the server and trash its memory allocator, causing high CPU +and memory usage. + +Instead of doing that, we resort to processing incoming data using a +chunk-by-chunk processing strategy. That is, we split data into small +chunks (currently 256 bytes) and process each of them +asynchronously. However, we can process more than one chunk at +once (up to 4 currently), given that the number of HTTP/2 streams has +not increased while processing a chunk. + +That alone is not enough, though. In addition to the above, we should +limit the number of active streams: these streams for which we have +received a request and started processing it (the ones for which a +read callback was called), as it is perfectly fine to have more opened +streams than active ones. In the case we have reached or surpassed the +limit of active streams, we stop reading AND processing the data from +the remote peer. The number of active streams is effectively decreased +only when responses associated with the active streams are sent to the +remote peer. + +Overall, this strategy is very similar to the one used for other +stream-based DNS transports like TCP and TLS. + +(cherry picked from commit 9846f395ad79bb50a5fa5ca6ab97ef904b3be35a) +(cherry picked from commit 11a2956dce6f983d2bfcb532f5719791845b06ab) + +DoH: floodding clients detection + +This commit adds logic to make code better protected against clients +that send valid HTTP/2 data that is useless from a DNS server +perspective. + +Firstly, it adds logic that protects against clients who send too +little useful (=DNS) data. We achieve that by adding a check that +eventually detects such clients with a nonfavorable useful to +processed data ratio after the initial grace period. The grace period +is limited to processing 128 KiB of data, which should be enough for +sending the largest possible DNS message in a GET request and then +some. This is the main safety belt that would detect even flooding +clients that initially behave well in order to fool the checks server. + +Secondly, in addition to the above, we introduce additional checks to +detect outright misbehaving clients earlier: + +The code will treat clients that open too many streams (50) without +sending any data for processing as flooding ones; The clients that +managed to send 1.5 KiB of data without opening a single stream or +submitting at least some DNS data will be treated as flooding ones. +Of course, the behaviour described above is nothing else but +heuristical checks, so they can never be perfect. At the same time, +they should be reasonable enough not to drop any valid clients, +realatively easy to implement, and have negligible computational +overhead. + +(cherry picked from commit 3425e4b1d04746520931e93ac7ef5979fd6b54fd) +(cherry picked from commit ee42514be2cc56f5d31fdb9d0c6a838e0d372654) + +DoH: introduce manual read timer control + +This commit introduces manual read timer control as used by StreamDNS +and its underlying transports. Before that, DoH code would rely on the +timer control provided by TCP, which would reset the timer any time +some data arrived. Now, the timer is restarted only when a full DNS +message is processed in line with other DNS transports. + +That change is required because we should not stop the timer when +reading from the network is paused due to throttling. We need a way to +drop timed-out clients, particularly those who refuse to read the data +we send. + +(cherry picked from commit 609a41517b1631c320876a41c43c68c9a0ee0f9f) +(cherry picked from commit 796708775d178adc5256ce03956d134c9fd38a33) + +DoH: reduce excessive bad request logging + +We started using isc_nm_bad_request() more actively throughout +codebase. In the case of HTTP/2 it can lead to a large count of +useless "Bad Request" messages in the BIND log, as often we attempt to +send such request over effectively finished HTTP/2 sessions. + +This commit fixes that. + +(cherry picked from commit 937b5f8349a6a5e15af254a53a659e39c7c1d179) +(cherry picked from commit 550b692343e398e0debe18ddb5908b4ccb183b91) +--- + lib/isc/netmgr/http.c | 448 +++++++++++++++++++++++++++++++++--- + lib/isc/netmgr/netmgr-int.h | 81 ++++++- + lib/isc/netmgr/netmgr.c | 80 ++++++- + lib/isc/netmgr/tcp.c | 26 ++- + lib/isc/netmgr/tlsstream.c | 137 +++++++++-- + 5 files changed, 721 insertions(+), 51 deletions(-) + +diff --git a/lib/isc/netmgr/http.c b/lib/isc/netmgr/http.c +index 1d4b82fd0ec..2002848c519 100644 +--- a/lib/isc/netmgr/http.c ++++ b/lib/isc/netmgr/http.c +@@ -85,6 +85,37 @@ + + #define INITIAL_DNS_MESSAGE_BUFFER_SIZE (512) + ++/* ++ * The value should be small enough to not allow a server to open too ++ * many streams at once. It should not be too small either because ++ * the incoming data will be split into too many chunks with each of ++ * them processed asynchronously. ++ */ ++#define INCOMING_DATA_CHUNK_SIZE (256) ++ ++/* ++ * Often processing a chunk does not change the number of streams. In ++ * that case we can process more than once, but we still should have a ++ * hard limit on that. ++ */ ++#define INCOMING_DATA_MAX_CHUNKS_AT_ONCE (4) ++ ++/* ++ * These constants define the grace period to help detect flooding clients. ++ * ++ * The first one defines how much data can be processed before opening ++ * a first stream and received at least some useful (=DNS) data. ++ * ++ * The second one defines how much data from a client we read before ++ * trying to drop a clients who sends not enough useful data. ++ * ++ * The third constant defines how many streams we agree to process ++ * before checking if there was at least one DNS request received. ++ */ ++#define INCOMING_DATA_INITIAL_STREAM_SIZE (1536) ++#define INCOMING_DATA_GRACE_SIZE (MAX_ALLOWED_DATA_IN_HEADERS) ++#define MAX_STREAMS_BEFORE_FIRST_REQUEST (50) ++ + typedef struct isc_nm_http_response_status { + size_t code; + size_t content_length; +@@ -143,6 +174,7 @@ struct isc_nm_http_session { + ISC_LIST(http_cstream_t) cstreams; + ISC_LIST(isc_nmsocket_h2_t) sstreams; + size_t nsstreams; ++ uint64_t total_opened_sstreams; + + isc_nmhandle_t *handle; + isc_nmhandle_t *client_httphandle; +@@ -155,6 +187,18 @@ struct isc_nm_http_session { + + isc__nm_http_pending_callbacks_t pending_write_callbacks; + isc_buffer_t *pending_write_data; ++ ++ /* ++ * The statistical values below are for usage on server-side ++ * only. They are meant to detect clients that are taking too many ++ * resources from the server. ++ */ ++ uint64_t received; /* How many requests have been received. */ ++ uint64_t submitted; /* How many responses were submitted to send */ ++ uint64_t processed; /* How many responses were processed. */ ++ ++ uint64_t processed_incoming_data; ++ uint64_t processed_useful_data; /* DNS data */ + }; + + typedef enum isc_http_error_responses { +@@ -177,6 +221,7 @@ typedef struct isc_http_send_req { + void *cbarg; + isc_buffer_t *pending_write_data; + isc__nm_http_pending_callbacks_t pending_write_callbacks; ++ uint64_t submitted; + } isc_http_send_req_t; + + #define HTTP_ENDPOINTS_MAGIC ISC_MAGIC('H', 'T', 'E', 'P') +@@ -189,10 +234,26 @@ static bool + http_send_outgoing(isc_nm_http_session_t *session, isc_nmhandle_t *httphandle, + isc_nm_cb_t cb, void *cbarg); + ++static void ++http_log_flooding_peer(isc_nm_http_session_t *session); ++ ++static bool ++http_is_flooding_peer(isc_nm_http_session_t *session); ++ ++static ssize_t ++http_process_input_data(isc_nm_http_session_t *session, ++ isc_buffer_t *input_data); ++ ++static inline bool ++http_too_many_active_streams(isc_nm_http_session_t *session); ++ + static void + http_do_bio(isc_nm_http_session_t *session, isc_nmhandle_t *send_httphandle, + isc_nm_cb_t send_cb, void *send_cbarg); + ++static void ++http_do_bio_async(isc_nm_http_session_t *session); ++ + static void + failed_httpstream_read_cb(isc_nmsocket_t *sock, isc_result_t result, + isc_nm_http_session_t *session); +@@ -494,6 +555,16 @@ finish_http_session(isc_nm_http_session_t *session) { + if (!session->closed) { + session->closed = true; + isc_nm_cancelread(session->handle); ++ isc__nmsocket_timer_stop(session->handle->sock); ++ } ++ ++ /* ++ * Free any unprocessed incoming data in order to not process ++ * it during indirect calls to http_do_bio() that might happen ++ * when calling the failed callbacks. ++ */ ++ if (session->buf != NULL) { ++ isc_buffer_free(&session->buf); + } + + if (session->client) { +@@ -567,6 +638,7 @@ on_server_data_chunk_recv_callback(int32_t stream_id, const uint8_t *data, + if (new_bufsize <= MAX_DNS_MESSAGE_SIZE && + new_bufsize <= h2->content_length) + { ++ session->processed_useful_data += len; + isc_buffer_putmem(&h2->rbuf, data, len); + break; + } +@@ -615,6 +687,9 @@ call_unlink_cstream_readcb(http_cstream_t *cstream, + isc_buffer_usedregion(cstream->rbuf, &read_data); + cstream->read_cb(session->client_httphandle, result, &read_data, + cstream->read_cbarg); ++ if (result == ISC_R_SUCCESS) { ++ isc__nmsocket_timer_restart(session->handle->sock); ++ } + put_http_cstream(session->mctx, cstream); + } + +@@ -656,6 +731,9 @@ on_server_stream_close_callback(int32_t stream_id, + + ISC_LIST_UNLINK(session->sstreams, &sock->h2, link); + session->nsstreams--; ++ if (sock->h2.request_received) { ++ session->submitted++; ++ } + + /* + * By making a call to isc__nmsocket_prep_destroy(), we ensure that +@@ -967,6 +1045,182 @@ client_submit_request(isc_nm_http_session_t *session, http_cstream_t *stream) { + return (ISC_R_SUCCESS); + } + ++static ssize_t ++http_process_input_data(isc_nm_http_session_t *session, ++ isc_buffer_t *input_data) { ++ ssize_t readlen = 0; ++ ssize_t processed = 0; ++ isc_region_t chunk = { 0 }; ++ size_t before, after; ++ size_t i; ++ ++ REQUIRE(VALID_HTTP2_SESSION(session)); ++ REQUIRE(input_data != NULL); ++ ++ if (!http_session_active(session)) { ++ return 0; ++ } ++ ++ /* ++ * For clients that initiate request themselves just process ++ * everything. ++ */ ++ if (session->client) { ++ isc_buffer_remainingregion(input_data, &chunk); ++ if (chunk.length == 0) { ++ return 0; ++ } ++ ++ readlen = nghttp2_session_mem_recv(session->ngsession, ++ chunk.base, chunk.length); ++ ++ if (readlen >= 0) { ++ isc_buffer_forward(input_data, readlen); ++ session->processed_incoming_data += readlen; ++ } ++ ++ return readlen; ++ } ++ ++ /* ++ * If no streams are created during processing, we might process ++ * more than one chunk at a time. Still we should not overdo that ++ * to avoid processing too much data at once as such behaviour is ++ * known for trashing the memory allocator at times. ++ */ ++ for (before = after = session->nsstreams, i = 0; ++ after <= before && i < INCOMING_DATA_MAX_CHUNKS_AT_ONCE; ++ after = session->nsstreams, i++) ++ { ++ const uint64_t active_streams = ++ (session->received - session->processed); ++ ++ /* ++ * If there are non completed send requests in flight -let's ++ * not process any incoming data, as it could lead to piling ++ * up too much send data in send buffers. With many clients ++ * connected it can lead to excessive memory consumption on ++ * the server instance. ++ */ ++ if (session->sending > 0) { ++ break; ++ } ++ ++ /* ++ * If we have reached the maximum number of streams used, we ++ * might stop processing for now, as nghttp2 will happily ++ * consume as much data as possible. ++ */ ++ if (session->nsstreams >= session->max_concurrent_streams && ++ active_streams > 0) ++ { ++ break; ++ } ++ ++ if (http_too_many_active_streams(session)) { ++ break; ++ } ++ ++ isc_buffer_remainingregion(input_data, &chunk); ++ if (chunk.length == 0) { ++ break; ++ } ++ ++ chunk.length = ISC_MIN(chunk.length, INCOMING_DATA_CHUNK_SIZE); ++ ++ readlen = nghttp2_session_mem_recv(session->ngsession, ++ chunk.base, chunk.length); ++ ++ if (readlen >= 0) { ++ isc_buffer_forward(input_data, readlen); ++ session->processed_incoming_data += readlen; ++ processed += readlen; ++ } else { ++ isc_buffer_clear(input_data); ++ return readlen; ++ } ++ } ++ ++ return processed; ++} ++ ++static void ++http_log_flooding_peer(isc_nm_http_session_t *session) { ++ const int log_level = ISC_LOG_DEBUG(1); ++ if (session->handle != NULL && isc_log_wouldlog(isc_lctx, log_level)) { ++ char client_sabuf[ISC_SOCKADDR_FORMATSIZE]; ++ char local_sabuf[ISC_SOCKADDR_FORMATSIZE]; ++ ++ isc_sockaddr_format(&session->handle->sock->peer, client_sabuf, ++ sizeof(client_sabuf)); ++ isc_sockaddr_format(&session->handle->sock->iface, local_sabuf, ++ sizeof(local_sabuf)); ++ isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, ++ ISC_LOGMODULE_NETMGR, log_level, ++ "Dropping a flooding HTTP/2 peer " ++ "%s (on %s) - processed: %" PRIu64 ++ " bytes, of them useful: %" PRIu64 "", ++ client_sabuf, local_sabuf, ++ session->processed_incoming_data, ++ session->processed_useful_data); ++ } ++} ++ ++static bool ++http_is_flooding_peer(isc_nm_http_session_t *session) { ++ if (session->client) { ++ return false; ++ } ++ ++ /* ++ * A flooding client can try to open a lot of streams before ++ * submitting a request. Let's drop such clients. ++ */ ++ if (session->received == 0 && ++ session->total_opened_sstreams > MAX_STREAMS_BEFORE_FIRST_REQUEST) ++ { ++ return true; ++ } ++ ++ /* ++ * We have processed enough data to open at least one stream and ++ * get some useful data. ++ */ ++ if (session->processed_incoming_data > ++ INCOMING_DATA_INITIAL_STREAM_SIZE && ++ (session->total_opened_sstreams == 0 || ++ session->processed_useful_data == 0)) ++ { ++ return true; ++ } ++ ++ if (session->processed_incoming_data < INCOMING_DATA_GRACE_SIZE) { ++ return false; ++ } ++ ++ /* ++ * The overhead of DoH per DNS message can be minimum 160-180 ++ * bytes. We should allow more for extra information that can be ++ * included in headers, so let's use 256 bytes. Minimum DNS ++ * message size is 12 bytes. So, (256+12)/12=22. Even that can be ++ * too restricting for some edge cases, but should be good enough ++ * for any practical purposes. Not to mention that HTTP/2 may ++ * include legitimate data that is completely useless for DNS ++ * purposes... ++ * ++ * Anyway, at that point we should have processed enough requests ++ * for such clients (if any). ++ */ ++ if (session->processed_useful_data == 0 || ++ (session->processed_incoming_data / ++ session->processed_useful_data) > 22) ++ { ++ return true; ++ } ++ ++ return false; ++} ++ + /* + * Read callback from TLS socket. + */ +@@ -976,6 +1230,7 @@ http_readcb(isc_nmhandle_t *handle, isc_result_t result, isc_region_t *region, + isc_nm_http_session_t *session = (isc_nm_http_session_t *)data; + isc_nm_http_session_t *tmpsess = NULL; + ssize_t readlen; ++ isc_buffer_t input; + + REQUIRE(VALID_HTTP2_SESSION(session)); + +@@ -994,11 +1249,17 @@ http_readcb(isc_nmhandle_t *handle, isc_result_t result, isc_region_t *region, + goto done; + } + +- readlen = nghttp2_session_mem_recv(session->ngsession, region->base, +- region->length); ++ isc_buffer_init(&input, region->base, region->length); ++ isc_buffer_add(&input, region->length); ++ ++ readlen = http_process_input_data(session, &input); + if (readlen < 0) { + failed_read_cb(ISC_R_UNEXPECTED, session); + goto done; ++ } else if (http_is_flooding_peer(session)) { ++ http_log_flooding_peer(session); ++ failed_read_cb(ISC_R_RANGE, session); ++ goto done; + } + + if ((size_t)readlen < region->length) { +@@ -1011,11 +1272,12 @@ http_readcb(isc_nmhandle_t *handle, isc_result_t result, isc_region_t *region, + isc_buffer_putmem(session->buf, region->base + readlen, + unread_size); + isc_nm_pauseread(session->handle); ++ http_do_bio_async(session); ++ } else { ++ /* We might have something to receive or send, do IO */ ++ http_do_bio(session, NULL, NULL, NULL); + } + +- /* We might have something to receive or send, do IO */ +- http_do_bio(session, NULL, NULL, NULL); +- + done: + isc__nm_httpsession_detach(&tmpsess); + } +@@ -1053,14 +1315,18 @@ http_writecb(isc_nmhandle_t *handle, isc_result_t result, void *arg) { + } + + isc_buffer_free(&req->pending_write_data); ++ session->processed += req->submitted; + isc_mem_put(session->mctx, req, sizeof(*req)); + + session->sending--; +- http_do_bio(session, NULL, NULL, NULL); +- isc_nmhandle_detach(&transphandle); +- if (result != ISC_R_SUCCESS && session->sending == 0) { ++ ++ if (result == ISC_R_SUCCESS) { ++ http_do_bio(session, NULL, NULL, NULL); ++ } else { + finish_http_session(session); + } ++ isc_nmhandle_detach(&transphandle); ++ + isc__nm_httpsession_detach(&session); + } + +@@ -1206,7 +1472,9 @@ http_send_outgoing(isc_nm_http_session_t *session, isc_nmhandle_t *httphandle, + *send = (isc_http_send_req_t){ .pending_write_data = + session->pending_write_data, + .cb = cb, +- .cbarg = cbarg }; ++ .cbarg = cbarg, ++ .submitted = session->submitted }; ++ session->submitted = 0; + session->pending_write_data = NULL; + move_pending_send_callbacks(session, send); + +@@ -1227,6 +1495,27 @@ nothing_to_send: + return (false); + } + ++static inline bool ++http_too_many_active_streams(isc_nm_http_session_t *session) { ++ const uint64_t active_streams = session->received - session->processed; ++ const uint64_t max_active_streams = ISC_MIN( ++ STREAM_CLIENTS_PER_CONN, session->max_concurrent_streams); ++ ++ if (session->client) { ++ return false; ++ } ++ ++ /* ++ * Do not process incoming data if there are too many active DNS ++ * clients (streams) per connection. ++ */ ++ if (active_streams >= max_active_streams) { ++ return true; ++ } ++ ++ return false; ++} ++ + static void + http_do_bio(isc_nm_http_session_t *session, isc_nmhandle_t *send_httphandle, + isc_nm_cb_t send_cb, void *send_cbarg) { +@@ -1242,59 +1531,140 @@ http_do_bio(isc_nm_http_session_t *session, isc_nmhandle_t *send_httphandle, + finish_http_session(session); + } + return; +- } else if (nghttp2_session_want_read(session->ngsession) == 0 && +- nghttp2_session_want_write(session->ngsession) == 0 && +- session->pending_write_data == NULL) +- { +- session->closing = true; ++ } ++ ++ if (send_cb != NULL) { ++ INSIST(VALID_NMHANDLE(send_httphandle)); ++ (void)http_send_outgoing(session, send_httphandle, send_cb, ++ send_cbarg); ++ return; ++ } ++ ++ INSIST(send_httphandle == NULL); ++ INSIST(send_cb == NULL); ++ INSIST(send_cbarg == NULL); ++ ++ if (session->pending_write_data != NULL && session->sending == 0) { ++ (void)http_send_outgoing(session, NULL, NULL, NULL); + return; + } + + if (nghttp2_session_want_read(session->ngsession) != 0) { + if (!session->reading) { + /* We have not yet started reading from this handle */ ++ isc__nmsocket_timer_start(session->handle->sock); + isc_nm_read(session->handle, http_readcb, session); + session->reading = true; + } else if (session->buf != NULL) { + size_t remaining = + isc_buffer_remaininglength(session->buf); + /* Leftover data in the buffer, use it */ +- size_t readlen = nghttp2_session_mem_recv( +- session->ngsession, +- isc_buffer_current(session->buf), remaining); ++ size_t remaining_after = 0; ++ ssize_t readlen = 0; ++ isc_nm_http_session_t *tmpsess = NULL; + +- if (readlen == remaining) { ++ /* ++ * Let's ensure that HTTP/2 session and its associated ++ * data will not go "out of scope" too early. ++ */ ++ isc__nm_httpsession_attach(session, &tmpsess); ++ ++ readlen = http_process_input_data(session, ++ session->buf); ++ ++ remaining_after = ++ isc_buffer_remaininglength(session->buf); ++ ++ if (readlen < 0) { ++ failed_read_cb(ISC_R_UNEXPECTED, session); ++ } else if (http_is_flooding_peer(session)) { ++ http_log_flooding_peer(session); ++ failed_read_cb(ISC_R_RANGE, session); ++ } else if ((size_t)readlen == remaining) { + isc_buffer_free(&session->buf); ++ http_do_bio(session, NULL, NULL, NULL); ++ } else if (remaining_after > 0 && ++ remaining_after < remaining) ++ { ++ /* ++ * We have processed a part of the data, now ++ * let's delay processing of whatever is left ++ * here. We want it to be an async operation so ++ * that we will: ++ * ++ * a) let other things run; ++ * b) have finer grained control over how much ++ * data is processed at once, because nghttp2 ++ * would happily consume as much data we pass to ++ * it and that could overwhelm the server. ++ */ ++ http_do_bio_async(session); + } else { +- isc_buffer_forward(session->buf, readlen); ++ (void)http_send_outgoing(session, NULL, NULL, ++ NULL); + } + +- http_do_bio(session, send_httphandle, send_cb, +- send_cbarg); ++ isc__nm_httpsession_detach(&tmpsess); + return; + } else { + /* Resume reading, it's idempotent, wait for more */ + isc_nm_resumeread(session->handle); ++ isc__nmsocket_timer_start(session->handle->sock); + } + } else { + /* We don't want more data, stop reading for now */ + isc_nm_pauseread(session->handle); + } + +- if (send_cb != NULL) { +- INSIST(VALID_NMHANDLE(send_httphandle)); +- (void)http_send_outgoing(session, send_httphandle, send_cb, +- send_cbarg); +- } else { +- INSIST(send_httphandle == NULL); +- INSIST(send_cb == NULL); +- INSIST(send_cbarg == NULL); +- (void)http_send_outgoing(session, NULL, NULL, NULL); ++ /* we might have some data to send after processing */ ++ (void)http_send_outgoing(session, NULL, NULL, NULL); ++ ++ if (nghttp2_session_want_read(session->ngsession) == 0 && ++ nghttp2_session_want_write(session->ngsession) == 0 && ++ session->pending_write_data == NULL) ++ { ++ session->closing = true; ++ isc_nm_pauseread(session->handle); ++ if (session->sending == 0) { ++ finish_http_session(session); ++ } + } + + return; + } + ++static void ++http_do_bio_async_cb(void *arg) { ++ isc_nm_http_session_t *session = arg; ++ ++ REQUIRE(VALID_HTTP2_SESSION(session)); ++ ++ if (session->handle != NULL && ++ !isc__nmsocket_closing(session->handle->sock)) ++ { ++ http_do_bio(session, NULL, NULL, NULL); ++ } ++ ++ isc__nm_httpsession_detach(&session); ++} ++ ++static void ++http_do_bio_async(isc_nm_http_session_t *session) { ++ isc_nm_http_session_t *tmpsess = NULL; ++ ++ REQUIRE(VALID_HTTP2_SESSION(session)); ++ ++ if (session->handle == NULL || ++ isc__nmsocket_closing(session->handle->sock)) ++ { ++ return; ++ } ++ isc__nm_httpsession_attach(session, &tmpsess); ++ isc__nm_async_run( ++ &session->handle->sock->mgr->workers[session->handle->sock->tid], ++ http_do_bio_async_cb, tmpsess); ++} ++ + static isc_result_t + get_http_cstream(isc_nmsocket_t *sock, http_cstream_t **streamp) { + http_cstream_t *cstream = sock->h2.connect.cstream; +@@ -1424,6 +1794,7 @@ transport_connect_cb(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) { + } + + http_transpost_tcp_nodelay(handle); ++ isc__nmhandle_set_manual_timer(session->handle, true); + + http_call_connect_cb(http_sock, session, result); + +@@ -1670,6 +2041,7 @@ server_on_begin_headers_callback(nghttp2_session *ngsession, + socket->tid = session->handle->sock->tid; + ISC_LINK_INIT(&socket->h2, link); + ISC_LIST_APPEND(session->sstreams, &socket->h2, link); ++ session->total_opened_sstreams++; + + nghttp2_session_set_stream_user_data(ngsession, frame->hd.stream_id, + socket); +@@ -1730,6 +2102,8 @@ server_handle_path_header(isc_nmsocket_t *socket, const uint8_t *value, + socket->mgr->mctx, dns_value, + dns_value_len, + &socket->h2.query_data_len); ++ socket->h2.session->processed_useful_data += ++ dns_value_len; + } else { + socket->h2.query_too_large = true; + return (ISC_HTTP_ERROR_PAYLOAD_TOO_LARGE); +@@ -2038,6 +2412,12 @@ server_call_cb(isc_nmsocket_t *socket, const isc_result_t result, + handle = isc__nmhandle_get(socket, NULL, NULL); + if (result != ISC_R_SUCCESS) { + data = NULL; ++ } else if (socket->h2.session->handle != NULL) { ++ isc__nmsocket_timer_restart(socket->h2.session->handle->sock); ++ } ++ if (result == ISC_R_SUCCESS) { ++ socket->h2.request_received = true; ++ socket->h2.session->received++; + } + socket->h2.cb(handle, result, data, socket->h2.cbarg); + isc_nmhandle_detach(&handle); +@@ -2054,6 +2434,12 @@ isc__nm_http_bad_request(isc_nmhandle_t *handle) { + REQUIRE(!atomic_load(&sock->client)); + REQUIRE(VALID_HTTP2_SESSION(sock->h2.session)); + ++ if (sock->h2.response_submitted || ++ !http_session_active(sock->h2.session)) ++ { ++ return; ++ } ++ + (void)server_send_error_response(ISC_HTTP_ERROR_BAD_REQUEST, + sock->h2.session->ngsession, sock); + } +@@ -2475,6 +2861,8 @@ httplisten_acceptcb(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) { + isc__nmsocket_attach(httplistensock, &session->serversocket); + server_send_connection_header(session); + ++ isc__nmhandle_set_manual_timer(session->handle, true); ++ + /* TODO H2 */ + http_do_bio(session, NULL, NULL, NULL); + return (ISC_R_SUCCESS); +diff --git a/lib/isc/netmgr/netmgr-int.h b/lib/isc/netmgr/netmgr-int.h +index cc635e3f5f9..79e970a2f6d 100644 +--- a/lib/isc/netmgr/netmgr-int.h ++++ b/lib/isc/netmgr/netmgr-int.h +@@ -337,6 +337,7 @@ typedef enum isc__netievent_type { + netievent_privilegedtask, + + netievent_settlsctx, ++ netievent_asyncrun, + + /* + * event type values higher than this will be treated +@@ -708,6 +709,42 @@ typedef struct isc__netievent__tlsctx { + } + + #ifdef HAVE_LIBNGHTTP2 ++typedef void (*isc__nm_asyncrun_cb_t)(void *); ++ ++typedef struct isc__netievent__asyncrun { ++ isc__netievent_type type; ++ ISC_LINK(isc__netievent_t) link; ++ isc__nm_asyncrun_cb_t cb; ++ void *cbarg; ++} isc__netievent__asyncrun_t; ++ ++#define NETIEVENT_ASYNCRUN_TYPE(type) \ ++ typedef isc__netievent__asyncrun_t isc__netievent_##type##_t; ++ ++#define NETIEVENT_ASYNCRUN_DECL(type) \ ++ isc__netievent_##type##_t *isc__nm_get_netievent_##type( \ ++ isc_nm_t *nm, isc__nm_asyncrun_cb_t cb, void *cbarg); \ ++ void isc__nm_put_netievent_##type(isc_nm_t *nm, \ ++ isc__netievent_##type##_t *ievent); ++ ++#define NETIEVENT_ASYNCRUN_DEF(type) \ ++ isc__netievent_##type##_t *isc__nm_get_netievent_##type( \ ++ isc_nm_t *nm, isc__nm_asyncrun_cb_t cb, void *cbarg) { \ ++ isc__netievent_##type##_t *ievent = \ ++ isc__nm_get_netievent(nm, netievent_##type); \ ++ ievent->cb = cb; \ ++ ievent->cbarg = cbarg; \ ++ \ ++ return (ievent); \ ++ } \ ++ \ ++ void isc__nm_put_netievent_##type(isc_nm_t *nm, \ ++ isc__netievent_##type##_t *ievent) { \ ++ ievent->cb = NULL; \ ++ ievent->cbarg = NULL; \ ++ isc__nm_put_netievent(nm, ievent); \ ++ } ++ + typedef struct isc__netievent__http_eps { + NETIEVENT__SOCKET; + isc_nm_http_endpoints_t *endpoints; +@@ -752,6 +789,7 @@ typedef union { + isc__netievent_tlsconnect_t nitc; + isc__netievent__tlsctx_t nitls; + #ifdef HAVE_LIBNGHTTP2 ++ isc__netievent__asyncrun_t niasync; + isc__netievent__http_eps_t nihttpeps; + #endif /* HAVE_LIBNGHTTP2 */ + } isc__netievent_storage_t; +@@ -944,6 +982,7 @@ typedef struct isc_nmsocket_h2 { + + isc_nm_http_endpoints_t *peer_endpoints; + ++ bool request_received; + bool response_submitted; + struct { + char *uri; +@@ -1228,6 +1267,7 @@ struct isc_nmsocket { + + isc_barrier_t barrier; + bool barrier_initialised; ++ atomic_bool manual_read_timer; + #ifdef NETMGR_TRACE + void *backtrace[TRACE_SIZE]; + int backtrace_size; +@@ -1546,6 +1586,9 @@ isc__nm_tcp_settimeout(isc_nmhandle_t *handle, uint32_t timeout); + * Set the read timeout for the TCP socket associated with 'handle'. + */ + ++void ++isc__nmhandle_tcp_set_manual_timer(isc_nmhandle_t *handle, const bool manual); ++ + void + isc__nm_async_tcpconnect(isc__networker_t *worker, isc__netievent_t *ev0); + void +@@ -1788,6 +1831,9 @@ isc__nm_tls_cleartimeout(isc_nmhandle_t *handle); + * around. + */ + ++void ++isc__nmhandle_tls_set_manual_timer(isc_nmhandle_t *handle, const bool manual); ++ + const char * + isc__nm_tls_verify_tls_peer_result_string(const isc_nmhandle_t *handle); + +@@ -1805,6 +1851,15 @@ void + isc__nmhandle_tls_setwritetimeout(isc_nmhandle_t *handle, + uint64_t write_timeout); + ++bool ++isc__nmsocket_tls_timer_running(isc_nmsocket_t *sock); ++ ++void ++isc__nmsocket_tls_timer_restart(isc_nmsocket_t *sock); ++ ++void ++isc__nmsocket_tls_timer_stop(isc_nmsocket_t *sock); ++ + void + isc__nm_http_stoplistening(isc_nmsocket_t *sock); + +@@ -1897,7 +1952,10 @@ void + isc__nm_http_set_max_streams(isc_nmsocket_t *listener, + const uint32_t max_concurrent_streams); + +-#endif ++void ++isc__nm_async_asyncrun(isc__networker_t *worker, isc__netievent_t *ev0); ++ ++#endif /* HAVE_LIBNGHTTP2 */ + + void + isc__nm_async_settlsctx(isc__networker_t *worker, isc__netievent_t *ev0); +@@ -2093,6 +2151,8 @@ NETIEVENT_SOCKET_TYPE(tlsdnscycle); + NETIEVENT_SOCKET_REQ_TYPE(httpsend); + NETIEVENT_SOCKET_TYPE(httpclose); + NETIEVENT_SOCKET_HTTP_EPS_TYPE(httpendpoints); ++ ++NETIEVENT_ASYNCRUN_TYPE(asyncrun); + #endif /* HAVE_LIBNGHTTP2 */ + + NETIEVENT_SOCKET_REQ_TYPE(tcpconnect); +@@ -2167,6 +2227,8 @@ NETIEVENT_SOCKET_DECL(tlsdnscycle); + NETIEVENT_SOCKET_REQ_DECL(httpsend); + NETIEVENT_SOCKET_DECL(httpclose); + NETIEVENT_SOCKET_HTTP_EPS_DECL(httpendpoints); ++ ++NETIEVENT_ASYNCRUN_DECL(asyncrun); + #endif /* HAVE_LIBNGHTTP2 */ + + NETIEVENT_SOCKET_REQ_DECL(tcpconnect); +@@ -2283,3 +2345,20 @@ isc__nmsocket_writetimeout_cb(void *data, isc_result_t eresult); + + void + isc__nmsocket_log_tls_session_reuse(isc_nmsocket_t *sock, isc_tls_t *tls); ++ ++void ++isc__nmhandle_set_manual_timer(isc_nmhandle_t *handle, const bool manual); ++/* ++ * Set manual read timer control mode - so that it will not get reset ++ * automatically on read nor get started when read is initiated. ++ */ ++ ++#if HAVE_LIBNGHTTP2 ++void ++isc__nm_async_run(isc__networker_t *worker, isc__nm_asyncrun_cb_t cb, ++ void *cbarg); ++/* ++ * Call the given callback asynchronously by the give network manager ++ * worker, pass the given argument to it. ++ */ ++#endif /* HAVE_LIBNGHTTP2 */ +diff --git a/lib/isc/netmgr/netmgr.c b/lib/isc/netmgr/netmgr.c +index a42ca90e8d2..8df6dc07408 100644 +--- a/lib/isc/netmgr/netmgr.c ++++ b/lib/isc/netmgr/netmgr.c +@@ -998,6 +998,8 @@ process_netievent(isc__networker_t *worker, isc__netievent_t *ievent) { + NETIEVENT_CASE(httpsend); + NETIEVENT_CASE(httpclose); + NETIEVENT_CASE(httpendpoints); ++ ++ NETIEVENT_CASE(asyncrun); + #endif + NETIEVENT_CASE(settlsctx); + NETIEVENT_CASE(sockstop); +@@ -1116,6 +1118,8 @@ NETIEVENT_SOCKET_DEF(tlsdnsshutdown); + NETIEVENT_SOCKET_REQ_DEF(httpsend); + NETIEVENT_SOCKET_DEF(httpclose); + NETIEVENT_SOCKET_HTTP_EPS_DEF(httpendpoints); ++ ++NETIEVENT_ASYNCRUN_DEF(asyncrun); + #endif /* HAVE_LIBNGHTTP2 */ + + NETIEVENT_SOCKET_REQ_DEF(tcpconnect); +@@ -1627,6 +1631,7 @@ isc___nmsocket_init(isc_nmsocket_t *sock, isc_nm_t *mgr, isc_nmsocket_type type, + atomic_init(&sock->keepalive, false); + atomic_init(&sock->connected, false); + atomic_init(&sock->timedout, false); ++ atomic_init(&sock->manual_read_timer, false); + + atomic_init(&sock->active_child_connections, 0); + +@@ -2136,6 +2141,15 @@ void + isc__nmsocket_timer_restart(isc_nmsocket_t *sock) { + REQUIRE(VALID_NMSOCK(sock)); + ++ switch (sock->type) { ++#if HAVE_LIBNGHTTP2 ++ case isc_nm_tlssocket: ++ return isc__nmsocket_tls_timer_restart(sock); ++#endif /* HAVE_LIBNGHTTP2 */ ++ default: ++ break; ++ } ++ + if (uv_is_closing((uv_handle_t *)&sock->read_timer)) { + return; + } +@@ -2170,7 +2184,16 @@ bool + isc__nmsocket_timer_running(isc_nmsocket_t *sock) { + REQUIRE(VALID_NMSOCK(sock)); + +- return (uv_is_active((uv_handle_t *)&sock->read_timer)); ++ switch (sock->type) { ++#if HAVE_LIBNGHTTP2 ++ case isc_nm_tlssocket: ++ return isc__nmsocket_tls_timer_running(sock); ++#endif /* HAVE_LIBNGHTTP2 */ ++ default: ++ break; ++ } ++ ++ return uv_is_active((uv_handle_t *)&sock->read_timer); + } + + void +@@ -2190,6 +2213,15 @@ isc__nmsocket_timer_stop(isc_nmsocket_t *sock) { + + REQUIRE(VALID_NMSOCK(sock)); + ++ switch (sock->type) { ++#if HAVE_LIBNGHTTP2 ++ case isc_nm_tlssocket: ++ return isc__nmsocket_tls_timer_stop(sock); ++#endif /* HAVE_LIBNGHTTP2 */ ++ default: ++ break; ++ } ++ + /* uv_timer_stop() is idempotent, no need to check if running */ + + r = uv_timer_stop(&sock->read_timer); +@@ -3946,6 +3978,52 @@ isc__nmsocket_log_tls_session_reuse(isc_nmsocket_t *sock, isc_tls_t *tls) { + client_sabuf, local_sabuf); + } + ++void ++isc__nmhandle_set_manual_timer(isc_nmhandle_t *handle, const bool manual) { ++ REQUIRE(VALID_NMHANDLE(handle)); ++ REQUIRE(VALID_NMSOCK(handle->sock)); ++ ++ isc_nmsocket_t *sock = handle->sock; ++ ++ switch (sock->type) { ++ case isc_nm_tcpsocket: ++ isc__nmhandle_tcp_set_manual_timer(handle, manual); ++ return; ++#if HAVE_LIBNGHTTP2 ++ case isc_nm_tlssocket: ++ isc__nmhandle_tls_set_manual_timer(handle, manual); ++ return; ++#endif /* HAVE_LIBNGHTTP2 */ ++ default: ++ break; ++ }; ++ ++ UNREACHABLE(); ++} ++ ++#if HAVE_LIBNGHTTP2 ++void ++isc__nm_async_run(isc__networker_t *worker, isc__nm_asyncrun_cb_t cb, ++ void *cbarg) { ++ isc__netievent__asyncrun_t *ievent = NULL; ++ REQUIRE(worker != NULL); ++ REQUIRE(cb != NULL); ++ ++ ievent = isc__nm_get_netievent_asyncrun(worker->mgr, cb, cbarg); ++ isc__nm_enqueue_ievent(worker, (isc__netievent_t *)ievent); ++} ++ ++void ++isc__nm_async_asyncrun(isc__networker_t *worker, isc__netievent_t *ev0) { ++ isc__netievent_asyncrun_t *ievent = (isc__netievent_asyncrun_t *)ev0; ++ ++ UNUSED(worker); ++ ++ ievent->cb(ievent->cbarg); ++} ++ ++#endif /* HAVE_LIBNGHTTP2 */ ++ + #ifdef NETMGR_TRACE + /* + * Dump all active sockets in netmgr. We output to stderr +diff --git a/lib/isc/netmgr/tcp.c b/lib/isc/netmgr/tcp.c +index 37d44bd9c84..925bc85e028 100644 +--- a/lib/isc/netmgr/tcp.c ++++ b/lib/isc/netmgr/tcp.c +@@ -784,7 +784,9 @@ isc__nm_async_tcpstartread(isc__networker_t *worker, isc__netievent_t *ev0) { + return; + } + +- isc__nmsocket_timer_start(sock); ++ if (!atomic_load(&sock->manual_read_timer)) { ++ isc__nmsocket_timer_start(sock); ++ } + } + + void +@@ -822,7 +824,9 @@ isc__nm_async_tcppauseread(isc__networker_t *worker, isc__netievent_t *ev0) { + REQUIRE(sock->tid == isc_nm_tid()); + UNUSED(worker); + +- isc__nmsocket_timer_stop(sock); ++ if (!atomic_load(&sock->manual_read_timer)) { ++ isc__nmsocket_timer_stop(sock); ++ } + isc__nm_stop_reading(sock); + } + +@@ -931,8 +935,10 @@ isc__nm_tcp_read_cb(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) { + } + } + +- /* The timer will be updated */ +- isc__nmsocket_timer_restart(sock); ++ if (!atomic_load(&sock->manual_read_timer)) { ++ /* The timer will be updated */ ++ isc__nmsocket_timer_restart(sock); ++ } + } + + free: +@@ -1521,3 +1527,15 @@ isc__nm_tcp_listener_nactive(isc_nmsocket_t *listener) { + INSIST(nactive >= 0); + return (nactive); + } ++ ++void ++isc__nmhandle_tcp_set_manual_timer(isc_nmhandle_t *handle, const bool manual) { ++ isc_nmsocket_t *sock; ++ ++ REQUIRE(VALID_NMHANDLE(handle)); ++ sock = handle->sock; ++ REQUIRE(VALID_NMSOCK(sock)); ++ REQUIRE(sock->type == isc_nm_tcpsocket); ++ ++ atomic_store(&sock->manual_read_timer, manual); ++} +diff --git a/lib/isc/netmgr/tlsstream.c b/lib/isc/netmgr/tlsstream.c +index 4fef5985b25..3d78df6a4d1 100644 +--- a/lib/isc/netmgr/tlsstream.c ++++ b/lib/isc/netmgr/tlsstream.c +@@ -60,6 +60,12 @@ tls_error_to_result(const int tls_err, const int tls_state, isc_tls_t *tls) { + } + } + ++static void ++tls_read_start(isc_nmsocket_t *sock); ++ ++static void ++tls_read_stop(isc_nmsocket_t *sock); ++ + static void + tls_failed_read_cb(isc_nmsocket_t *sock, const isc_result_t result); + +@@ -203,8 +209,13 @@ tls_failed_read_cb(isc_nmsocket_t *sock, const isc_result_t result) { + tls_call_connect_cb(sock, handle, result); + isc__nmsocket_clearcb(sock); + isc_nmhandle_detach(&handle); +- } else if (sock->recv_cb != NULL && sock->statichandle != NULL && +- (sock->recv_read || result == ISC_R_TIMEDOUT)) ++ goto do_destroy; ++ } ++ ++ isc__nmsocket_timer_stop(sock); ++ ++ if (sock->recv_cb != NULL && sock->statichandle != NULL && ++ (sock->recv_read || result == ISC_R_TIMEDOUT)) + { + isc__nm_uvreq_t *req = NULL; + INSIST(VALID_NMHANDLE(sock->statichandle)); +@@ -218,13 +229,13 @@ tls_failed_read_cb(isc_nmsocket_t *sock, const isc_result_t result) { + } + isc__nm_readcb(sock, req, result); + if (result == ISC_R_TIMEDOUT && +- (sock->outerhandle == NULL || +- isc__nmsocket_timer_running(sock->outerhandle->sock))) ++ isc__nmsocket_timer_running(sock)) + { + destroy = false; + } + } + ++do_destroy: + if (destroy) { + isc__nmsocket_prep_destroy(sock); + } +@@ -344,6 +355,8 @@ tls_try_handshake(isc_nmsocket_t *sock, isc_result_t *presult) { + INSIST(sock->statichandle == NULL); + isc__nmsocket_log_tls_session_reuse(sock, sock->tlsstream.tls); + tlshandle = isc__nmhandle_get(sock, &sock->peer, &sock->iface); ++ isc__nmsocket_timer_stop(sock); ++ tls_read_stop(sock); + + if (isc__nm_closing(sock)) { + result = ISC_R_SHUTTINGDOWN; +@@ -437,6 +450,7 @@ tls_do_bio(isc_nmsocket_t *sock, isc_region_t *received_data, + sock->tlsstream.state = TLS_HANDSHAKE; + rv = tls_try_handshake(sock, NULL); + INSIST(SSL_is_init_finished(sock->tlsstream.tls) == 0); ++ isc__nmsocket_timer_restart(sock); + } else if (sock->tlsstream.state == TLS_CLOSED) { + return; + } else { /* initialised and doing I/O */ +@@ -502,6 +516,7 @@ tls_do_bio(isc_nmsocket_t *sock, isc_region_t *received_data, + !atomic_load(&sock->readpaused) && + sock->statichandle != NULL && !finish) + { ++ bool was_new_data = false; + uint8_t recv_buf[TLS_BUF_SIZE]; + INSIST(sock->tlsstream.state > TLS_HANDSHAKE); + while ((rv = SSL_read_ex(sock->tlsstream.tls, recv_buf, +@@ -510,7 +525,7 @@ tls_do_bio(isc_nmsocket_t *sock, isc_region_t *received_data, + isc_region_t region; + region = (isc_region_t){ .base = &recv_buf[0], + .length = len }; +- ++ was_new_data = true; + INSIST(VALID_NMHANDLE(sock->statichandle)); + sock->recv_cb(sock->statichandle, ISC_R_SUCCESS, + ®ion, sock->recv_cbarg); +@@ -547,8 +562,29 @@ tls_do_bio(isc_nmsocket_t *sock, isc_region_t *received_data, + break; + } + } ++ ++ if (was_new_data && !sock->manual_read_timer) { ++ /* ++ * Some data has been decrypted, it is the right ++ * time to stop the read timer as it will be ++ * restarted on the next read attempt. ++ */ ++ isc__nmsocket_timer_stop(sock); ++ } + } + } ++ ++ /* ++ * Setting 'finish' to 'true' means that we are about to close the ++ * TLS stream (we intend to send TLS shutdown message to the ++ * remote side). After that no new data can be received, so we ++ * should stop the timer regardless of the ++ * 'sock->manual_read_timer' value. ++ */ ++ if (finish) { ++ isc__nmsocket_timer_stop(sock); ++ } ++ + errno = 0; + tls_status = SSL_get_error(sock->tlsstream.tls, rv); + saved_errno = errno; +@@ -601,14 +637,7 @@ tls_do_bio(isc_nmsocket_t *sock, isc_region_t *received_data, + return; + } + +- INSIST(VALID_NMHANDLE(sock->outerhandle)); +- +- if (sock->tlsstream.reading) { +- isc_nm_resumeread(sock->outerhandle); +- } else if (sock->tlsstream.state == TLS_HANDSHAKE) { +- sock->tlsstream.reading = true; +- isc_nm_read(sock->outerhandle, tls_readcb, sock); +- } ++ tls_read_start(sock); + return; + default: + result = tls_error_to_result(tls_status, sock->tlsstream.state, +@@ -743,6 +772,7 @@ tlslisten_acceptcb(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) { + RUNTIME_CHECK(result == ISC_R_SUCCESS); + /* TODO: catch failure code, detach tlssock, and log the error */ + ++ isc__nmhandle_set_manual_timer(tlssock->outerhandle, true); + tls_do_bio(tlssock, NULL, NULL, false); + return (result); + } +@@ -898,6 +928,29 @@ isc__nm_tls_read(isc_nmhandle_t *handle, isc_nm_recv_cb_t cb, void *cbarg) { + (isc__netievent_t *)ievent); + } + ++static void ++tls_read_start(isc_nmsocket_t *sock) { ++ INSIST(VALID_NMHANDLE(sock->outerhandle)); ++ ++ if (sock->tlsstream.reading) { ++ isc_nm_resumeread(sock->outerhandle); ++ } else if (sock->tlsstream.state == TLS_HANDSHAKE) { ++ sock->tlsstream.reading = true; ++ isc_nm_read(sock->outerhandle, tls_readcb, sock); ++ } ++ ++ if (!sock->manual_read_timer) { ++ isc__nmsocket_timer_start(sock); ++ } ++} ++ ++static void ++tls_read_stop(isc_nmsocket_t *sock) { ++ if (sock->outerhandle != NULL) { ++ isc_nm_pauseread(sock->outerhandle); ++ } ++} ++ + void + isc__nm_tls_pauseread(isc_nmhandle_t *handle) { + REQUIRE(VALID_NMHANDLE(handle)); +@@ -906,9 +959,11 @@ isc__nm_tls_pauseread(isc_nmhandle_t *handle) { + if (atomic_compare_exchange_strong(&handle->sock->readpaused, + &(bool){ false }, true)) + { +- if (handle->sock->outerhandle != NULL) { +- isc_nm_pauseread(handle->sock->outerhandle); ++ if (!atomic_load(&handle->sock->manual_read_timer)) { ++ isc__nmsocket_timer_stop(handle->sock); + } ++ ++ tls_read_stop(handle->sock); + } + } + +@@ -937,6 +992,7 @@ tls_close_direct(isc_nmsocket_t *sock) { + * external references, we can close everything. + */ + if (sock->outerhandle != NULL) { ++ isc__nmsocket_timer_stop(sock); + isc_nm_pauseread(sock->outerhandle); + isc__nmsocket_clearcb(sock->outerhandle->sock); + isc_nmhandle_detach(&sock->outerhandle); +@@ -1085,6 +1141,7 @@ tcp_connected(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) { + */ + handle->sock->tlsstream.tlssocket = tlssock; + ++ isc__nmhandle_set_manual_timer(tlssock->outerhandle, true); + tls_do_bio(tlssock, NULL, NULL, false); + return; + error: +@@ -1251,6 +1308,44 @@ isc__nmhandle_tls_setwritetimeout(isc_nmhandle_t *handle, + } + } + ++bool ++isc__nmsocket_tls_timer_running(isc_nmsocket_t *sock) { ++ REQUIRE(VALID_NMSOCK(sock)); ++ REQUIRE(sock->type == isc_nm_tlssocket); ++ ++ if (sock->outerhandle != NULL) { ++ INSIST(VALID_NMHANDLE(sock->outerhandle)); ++ REQUIRE(VALID_NMSOCK(sock->outerhandle->sock)); ++ return isc__nmsocket_timer_running(sock->outerhandle->sock); ++ } ++ ++ return false; ++} ++ ++void ++isc__nmsocket_tls_timer_restart(isc_nmsocket_t *sock) { ++ REQUIRE(VALID_NMSOCK(sock)); ++ REQUIRE(sock->type == isc_nm_tlssocket); ++ ++ if (sock->outerhandle != NULL) { ++ INSIST(VALID_NMHANDLE(sock->outerhandle)); ++ REQUIRE(VALID_NMSOCK(sock->outerhandle->sock)); ++ isc__nmsocket_timer_restart(sock->outerhandle->sock); ++ } ++} ++ ++void ++isc__nmsocket_tls_timer_stop(isc_nmsocket_t *sock) { ++ REQUIRE(VALID_NMSOCK(sock)); ++ REQUIRE(sock->type == isc_nm_tlssocket); ++ ++ if (sock->outerhandle != NULL) { ++ INSIST(VALID_NMHANDLE(sock->outerhandle)); ++ REQUIRE(VALID_NMSOCK(sock->outerhandle->sock)); ++ isc__nmsocket_timer_stop(sock->outerhandle->sock); ++ } ++} ++ + const char * + isc__nm_tls_verify_tls_peer_result_string(const isc_nmhandle_t *handle) { + isc_nmsocket_t *sock = NULL; +@@ -1351,3 +1446,15 @@ tls_try_shutdown(isc_tls_t *tls, const bool force) { + (void)SSL_shutdown(tls); + } + } ++ ++void ++isc__nmhandle_tls_set_manual_timer(isc_nmhandle_t *handle, const bool manual) { ++ isc_nmsocket_t *sock; ++ ++ REQUIRE(VALID_NMHANDLE(handle)); ++ sock = handle->sock; ++ REQUIRE(VALID_NMSOCK(sock)); ++ REQUIRE(sock->type == isc_nm_tlssocket); ++ ++ atomic_store(&sock->manual_read_timer, manual); ++} +-- +2.48.1 + diff --git a/SOURCES/bind-9.18-nsupdate-TLS-doc.patch b/SOURCES/bind-9.18-nsupdate-TLS-doc.patch new file mode 100644 index 0000000..bb7021a --- /dev/null +++ b/SOURCES/bind-9.18-nsupdate-TLS-doc.patch @@ -0,0 +1,114 @@ +From 146811cdc40459129b20df9b3bb31bd152570b72 Mon Sep 17 00:00:00 2001 +From: Aram Sargsyan +Date: Wed, 21 Sep 2022 15:05:11 +0000 +Subject: [PATCH 2/3] Document nsupdate options related to DoT + +Add documentation for the newly implemented DoT feature of the +nsupdate program. + +(cherry picked from commit bd8299d7b501234263a6aee98049f879b1c700b7) +--- + bin/nsupdate/nsupdate.rst | 48 ++++++++++++++++++++++++++++++++++++++- + 1 file changed, 47 insertions(+), 1 deletion(-) + +diff --git a/bin/nsupdate/nsupdate.rst b/bin/nsupdate/nsupdate.rst +index 81bb4815cf4..f1ab5c76fa7 100644 +--- a/bin/nsupdate/nsupdate.rst ++++ b/bin/nsupdate/nsupdate.rst +@@ -19,7 +19,7 @@ nsupdate - dynamic DNS update utility + Synopsis + ~~~~~~~~ + +-:program:`nsupdate` [**-d**] [**-D**] [**-i**] [**-L** level] [ [**-g**] | [**-o**] | [**-l**] | [**-y** [hmac:]keyname:secret] | [**-k** keyfile] ] [**-t** timeout] [**-u** udptimeout] [**-r** udpretries] [**-v**] [**-T**] [**-P**] [**-V**] [ [**-4**] | [**-6**] ] [filename] ++:program:`nsupdate` [**-d**] [**-D**] [**-i**] [**-L** level] [ [**-g**] | [**-o**] | [**-l**] | [**-y** [hmac:]keyname:secret] | [**-k** keyfile] ] [ [**-S**] [**-K** tlskeyfile] [**-E** tlscertfile] [**-A** tlscafile] [**-H** tlshostname] [-O] ] [**-t** timeout] [**-u** udptimeout] [**-r** udpretries] [**-v**] [**-T**] [**-P**] [**-V**] [ [**-4**] | [**-6**] ] [filename] + + Description + ~~~~~~~~~~~ +@@ -71,6 +71,15 @@ Options + + This option sets use of IPv6 only. + ++.. option:: -A tlscafile ++ ++ This option specifies the file of the certificate authorities (CA) certificates ++ (in PEM format) in order to verify the remote server TLS certificate when ++ using DNS-over-TLS (DoT), to achieve Strict or Mutual TLS. When used, it will ++ override the certificates from the global certificates store, which are ++ otherwise used by default when :option:`-S` is enabled. This option can not ++ be used in conjuction with :option:`-O`, and it implies :option:`-S`. ++ + .. option:: -C + + Overrides the default `resolv.conf` file. This is only intended for testing. +@@ -84,10 +93,23 @@ Options + + This option sets extra debug mode. + ++.. option:: -E tlscertfile ++ ++ This option sets the certificate(s) file for authentication for the ++ DNS-over-TLS (DoT) transport to the remote server. The certificate ++ chain file is expected to be in PEM format. This option implies :option:`-S`, ++ and can only be used with :option:`-K`. ++ + .. option:: -g + + This option enables standard GSS-TSIG mode. + ++.. option:: -H tlshostname ++ ++ This option makes :program:`nsupdate` use the provided hostname during remote ++ server TLS certificate verification. Otherwise, the DNS server name ++ is used. This option implies :option:`-S`. ++ + .. option:: -i + + This option forces interactive mode, even when standard input is not a terminal. +@@ -104,6 +126,13 @@ Options + key used to authenticate Dynamic DNS update requests. In this case, + the key specified is not an HMAC-MD5 key. + ++.. option:: -K tlskeyfile ++ ++ This option sets the key file for authenticated encryption for the ++ DNS-over-TLS (DoT) transport with the remote server. The private key file is ++ expected to be in PEM format. This option implies :option:`-S`, and can only ++ be used with :option:`-E`. ++ + .. option:: -l + + This option sets local-host only mode, which sets the server address to localhost +@@ -123,6 +152,14 @@ Options + This option enables a non-standards-compliant variant of GSS-TSIG + used by Windows 2000. + ++.. option:: -O ++ ++ This option enables Opportunistic TLS. When used, the remote peer's TLS ++ certificate will not be verified. This option should be used for debugging ++ purposes only, and it is not recommended to use it in production. This ++ option can not be used in conjuction with :option:`-A`, and it implies ++ :option:`-S`. ++ + .. option:: -p port + + This option sets the port to use for connections to a name server. The default is +@@ -138,6 +175,15 @@ Options + This option sets the number of UDP retries. The default is 3. If zero, only one update + request is made. + ++.. option:: -S ++ ++ This option indicates whether to use DNS-over-TLS (DoT) when querying ++ name servers specified by ``server servername port`` syntax in the input ++ file, and the primary server discovered through a SOA request. When the ++ :option:`-K` and :option:`-E` options are used, then the specified TLS ++ client certificate and private key pair are used for authentication ++ (Mutual TLS). This option implies :option:`-v`. ++ + .. option:: -t timeout + + This option sets the maximum time an update request can take before it is aborted. The +-- +2.48.1 + diff --git a/SOURCES/bind-9.18-nsupdate-TLS-tests.patch b/SOURCES/bind-9.18-nsupdate-TLS-tests.patch new file mode 100644 index 0000000..e726db4 --- /dev/null +++ b/SOURCES/bind-9.18-nsupdate-TLS-tests.patch @@ -0,0 +1,1630 @@ +From 8444573a5bd65c44bb3ec6f4d7cf6fe85ca3f3d4 Mon Sep 17 00:00:00 2001 +From: Aram Sargsyan +Date: Wed, 21 Sep 2022 13:15:50 +0000 +Subject: [PATCH 3/3] Extend the nsupdate system test with DoT-related checks + +Add a simple test PKI based on the existing one in the doth test. + +Check ephemeral, forward-secrecy, and forward-secrecy-mutual-tls +TLS configurations with different scenarios. + +(cherry picked from commit f2bb80d6ae172f6fd7943bf913d1b0566b5df352) +--- + bin/tests/system/nsupdate/.gitignore | 5 + + bin/tests/system/nsupdate/CA/CA-other.pem | 26 +++ + bin/tests/system/nsupdate/CA/CA.cfg | 77 +++++++ + bin/tests/system/nsupdate/CA/CA.pem | 29 +++ + bin/tests/system/nsupdate/CA/README | 2 + + .../CA/certs/srv01.client01.example.nil.key | 40 ++++ + .../CA/certs/srv01.client01.example.nil.pem | 93 +++++++++ + .../srv01.client02-expired.example.nil.key | 40 ++++ + .../srv01.client02-expired.example.nil.pem | 93 +++++++++ + .../CA/certs/srv01.crt01.example.nil.key | 40 ++++ + .../CA/certs/srv01.crt01.example.nil.pem | 93 +++++++++ + .../certs/srv01.crt02-expired.example.nil.key | 40 ++++ + .../certs/srv01.crt02-expired.example.nil.pem | 93 +++++++++ + bin/tests/system/nsupdate/CA/index.txt | 4 + + bin/tests/system/nsupdate/CA/index.txt.attr | 1 + + .../nsupdate/CA/newcerts/70B9F4EB2FA19598.pem | 93 +++++++++ + .../nsupdate/CA/newcerts/70B9F4EB2FA19599.pem | 93 +++++++++ + .../nsupdate/CA/newcerts/70B9F4EB2FA1959A.pem | 93 +++++++++ + .../nsupdate/CA/newcerts/70B9F4EB2FA1959B.pem | 93 +++++++++ + .../system/nsupdate/CA/private/CA-other.key | 39 ++++ + bin/tests/system/nsupdate/CA/private/CA.key | 39 ++++ + bin/tests/system/nsupdate/CA/serial | 1 + + bin/tests/system/nsupdate/dhparam3072.pem | 11 + + bin/tests/system/nsupdate/ns1/named.conf.in | 34 +++ + bin/tests/system/nsupdate/ns10/named.conf.in | 2 + + bin/tests/system/nsupdate/tests.sh | 193 ++++++++++++++++++ + 26 files changed, 1367 insertions(+) + create mode 100644 bin/tests/system/nsupdate/.gitignore + create mode 100644 bin/tests/system/nsupdate/CA/CA-other.pem + create mode 100644 bin/tests/system/nsupdate/CA/CA.cfg + create mode 100644 bin/tests/system/nsupdate/CA/CA.pem + create mode 100644 bin/tests/system/nsupdate/CA/README + create mode 100644 bin/tests/system/nsupdate/CA/certs/srv01.client01.example.nil.key + create mode 100644 bin/tests/system/nsupdate/CA/certs/srv01.client01.example.nil.pem + create mode 100644 bin/tests/system/nsupdate/CA/certs/srv01.client02-expired.example.nil.key + create mode 100644 bin/tests/system/nsupdate/CA/certs/srv01.client02-expired.example.nil.pem + create mode 100644 bin/tests/system/nsupdate/CA/certs/srv01.crt01.example.nil.key + create mode 100644 bin/tests/system/nsupdate/CA/certs/srv01.crt01.example.nil.pem + create mode 100644 bin/tests/system/nsupdate/CA/certs/srv01.crt02-expired.example.nil.key + create mode 100644 bin/tests/system/nsupdate/CA/certs/srv01.crt02-expired.example.nil.pem + create mode 100644 bin/tests/system/nsupdate/CA/index.txt + create mode 100644 bin/tests/system/nsupdate/CA/index.txt.attr + create mode 100644 bin/tests/system/nsupdate/CA/newcerts/70B9F4EB2FA19598.pem + create mode 100644 bin/tests/system/nsupdate/CA/newcerts/70B9F4EB2FA19599.pem + create mode 100644 bin/tests/system/nsupdate/CA/newcerts/70B9F4EB2FA1959A.pem + create mode 100644 bin/tests/system/nsupdate/CA/newcerts/70B9F4EB2FA1959B.pem + create mode 100644 bin/tests/system/nsupdate/CA/private/CA-other.key + create mode 100644 bin/tests/system/nsupdate/CA/private/CA.key + create mode 100644 bin/tests/system/nsupdate/CA/serial + create mode 100644 bin/tests/system/nsupdate/dhparam3072.pem + +diff --git a/bin/tests/system/nsupdate/.gitignore b/bin/tests/system/nsupdate/.gitignore +new file mode 100644 +index 00000000000..df5fe68d5d7 +--- /dev/null ++++ b/bin/tests/system/nsupdate/.gitignore +@@ -0,0 +1,5 @@ ++# temporary files generated by "openssl ca" ++/CA/*.old ++# there is little point in keeping the certificate requests ++# for the issued certificates ++/CA/certs/*.csr +diff --git a/bin/tests/system/nsupdate/CA/CA-other.pem b/bin/tests/system/nsupdate/CA/CA-other.pem +new file mode 100644 +index 00000000000..6bdbedacbf4 +--- /dev/null ++++ b/bin/tests/system/nsupdate/CA/CA-other.pem +@@ -0,0 +1,26 @@ ++-----BEGIN CERTIFICATE----- ++MIIEZTCCAs0CFDYlin3oeYDu16bFItl9tGZz1Ra4MA0GCSqGSIb3DQEBCwUAMG4x ++CzAJBgNVBAYTAlVBMRcwFQYDVQQIDA5LaGFya2l2IE9ibGFzdDEQMA4GA1UEBwwH ++S2hhcmtpdjEMMAoGA1UECgwDSVNDMSYwJAYDVQQLDB1Tb2Z0d2FyZSBFbmdlbmVl ++cmluZyAoQklORCA5KTAgFw0yMjA5MDcyMTIzNTBaGA8yMDUyMDgzMDIxMjM1MFow ++bjELMAkGA1UEBhMCVUExFzAVBgNVBAgMDktoYXJraXYgT2JsYXN0MRAwDgYDVQQH ++DAdLaGFya2l2MQwwCgYDVQQKDANJU0MxJjAkBgNVBAsMHVNvZnR3YXJlIEVuZ2Vu ++ZWVyaW5nIChCSU5EIDkpMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEA ++10Xj8dH8/XCfUvhdL/S3E10TnrYY8IIDBmU0lkUR5IHwgP9IYVyR/0Mibg79FAs+ ++rvuEDifUK+6wvkpj+BXNVZCspo9/u3cl7dqrLH+1SeUs50OeQnbbTrBl0PuNwvzE ++kbk7xwLlVDOyRmmvY/EEu7WkitQZgXSAYgttrk62CuJUQUmwUTX5Jxndsjydk/zW ++/DiulTsX+zv8kG5NiwpXCfL6QxBoMZNI4fUmDL3bX1XfHaFA+45GT2lHu07xc+cV ++eZIRCo0Nk+fIO53lDol8mmR8/5vna27gRnqEUSU7MZAMG6QBXkotnq3rHnrI/ku6 ++dCJW4tbWV/ANQ+TG17g2tygzC/smqTuLqavyP9V5cRrdU9awEqwvy8uVbGkTmUZd ++tjkGWCcmBSWJvkH3MRJmijS7rDcb8m/g9+xKe79V1c8durGWvcfMRZZhWaoHyhnH ++g9+JLUCC3EUCp/1206w5vTXEQNpqi9Z3AZfgboPzJyji4OeYfcQ5eaIZ3OuIpyQz ++AgMBAAEwDQYJKoZIhvcNAQELBQADggGBAKdQkmmyUqcE1by7AeHoxkqFgqUeSAlh ++flXi5DD+j5+Op2GAUrx84LGy4+heKEwAkV5Cw2c9IMHmDDMnGe/g4FjBS+dTZsTs ++JRXXDR7t20eWiBpvO/3IMqVpPq9CAQY1L9PYAVuVM5cwdzsJXdH82z2BZ3Ttg3GX ++NPnybxzD/auC051vqEp28Jzbswd4c3VvTmRnYY7rYNNKnLD7812BIp7lnE6s5X2D ++y0PPSYdhscTqfJV0+GDF5hUduOFX1xTcPlXaXfyKLLelqtrw40p3ynww9v/J4mwt ++FBV+a8gguM7tCZMoV/VJZghObglV/wpokAQchL/pnxL7+U8JklRqaU4DlxyGZ+K4 ++QlR5mJe19ZlkgHePk1MbwNZaTXjaOFirYmZzs4YynOp3iBHrW3CYY3kVlrUpKP08 ++o101hce32VxkyST6i5W24MU02O/wuPdyQpN+rJjYv32Axsrh/ePkI5qKew9eZ63i ++WzNb7BW1LrHrQ/lXoJ3ekRQd10UX3xhk/w== ++-----END CERTIFICATE----- +diff --git a/bin/tests/system/nsupdate/CA/CA.cfg b/bin/tests/system/nsupdate/CA/CA.cfg +new file mode 100644 +index 00000000000..1a3ed65f676 +--- /dev/null ++++ b/bin/tests/system/nsupdate/CA/CA.cfg +@@ -0,0 +1,77 @@ ++# See ../../doth/CA/ca.cfg for more information ++ ++# certificate authority configuration ++[ca] ++default_ca = CA_default # The default ca section ++ ++[CA_default] ++dir = . ++new_certs_dir = $dir/newcerts # new certs dir (must be created) ++certificate = $dir/CA.pem # The CA cert ++private_key = $dir/private/CA.key # CA private key ++ ++serial = $dir/serial # serial number file for the next certificate ++ # Update before issuing it: ++ # xxd -l 8 -u -ps /dev/urandom > ./serial ++database = $dir/index.txt # (must be created manually: touch ./index.txt) ++ ++default_days = 1 # how long to certify for ++ ++#default_crl_days = 30 # the number of days before the ++default_crl_days = 10950 # next CRL is due. That is the ++ # days from now to place in the ++ # CRL nextUpdate field. If CRL ++ # is expired, certificate ++ # verifications will fail even ++ # for otherwise valid ++ # certificates. Clients might ++ # cache the CRL, so the expiry ++ # period should normally be ++ # relatively short (default: ++ # 30) for production CAs. ++ ++default_md = sha256 # digest to use ++ ++policy = policy_default # default policy ++email_in_dn = no # Don't add the email into cert DN ++ ++name_opt = ca_default # Subject name display option ++cert_opt = ca_default # Certificate display option ++ ++# We need the following in order to copy Subject Alt Name(s) from a ++# request to the certificate. ++copy_extensions = copy # copy extensions from request ++ ++[policy_default] ++countryName = optional ++stateOrProvinceName = optional ++organizationalUnitName = optional ++commonName = supplied ++emailAddress = optional ++ ++# default certificate requests settings ++[req] ++# Options for the `req` tool (`man req`). ++default_bits = 3072 # for RSA only ++distinguished_name = req_default ++string_mask = utf8only ++# SHA-1 is deprecated, so use SHA-256 instead. ++default_md = sha256 ++# do not encrypt the private key file ++encrypt_key = no ++ ++[req_default] ++# See . ++countryName = Country Name (2 letter code) ++stateOrProvinceName = State or Province Name (full name) ++localityName = Locality Name (e.g., city) ++0.organizationName = Organization Name (e.g., company) ++organizationalUnitName = Organizational Unit Name (e.g. department) ++commonName = Common Name (e.g. server FQDN or YOUR name) ++emailAddress = Email Address ++# defaults ++countryName_default = UA ++stateOrProvinceName_default = Kharkiv Oblast ++localityName_default = Kharkiv ++0.organizationName_default = ISC ++organizationalUnitName_default = Software Engeneering (BIND 9) +diff --git a/bin/tests/system/nsupdate/CA/CA.pem b/bin/tests/system/nsupdate/CA/CA.pem +new file mode 100644 +index 00000000000..1f725dbb8ab +--- /dev/null ++++ b/bin/tests/system/nsupdate/CA/CA.pem +@@ -0,0 +1,29 @@ ++-----BEGIN CERTIFICATE----- ++MIIE3TCCA0WgAwIBAgIUeZPKrvbGEBZaRc2jNczlIsJXyPYwDQYJKoZIhvcNAQEL ++BQAwfTELMAkGA1UEBhMCVUExGDAWBgNVBAgMD0toYXJraXYgT2JsYXN0JzEQMA4G ++A1UEBwwHS2hhcmtpdjEkMCIGA1UECgwbSW50ZXJuZXQgU3lzdGVtcyBDb25zb3J0 ++aXVtMRwwGgYDVQQDDBNjYS50ZXN0LmV4YW1wbGUuY29tMCAXDTIyMDEyNDEyNDA1 ++NFoYDzIwNTIwMTE3MTI0MDU0WjB9MQswCQYDVQQGEwJVQTEYMBYGA1UECAwPS2hh ++cmtpdiBPYmxhc3QnMRAwDgYDVQQHDAdLaGFya2l2MSQwIgYDVQQKDBtJbnRlcm5l ++dCBTeXN0ZW1zIENvbnNvcnRpdW0xHDAaBgNVBAMME2NhLnRlc3QuZXhhbXBsZS5j ++b20wggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQCi6hEegBzpUKbE1NTo ++Z7uz7EMUY7TBckkiw/7ydTLKNa8YI4JpBguFvWQsDY0dGFJIoVwyHyNx3seW/LoI ++B5zWPZ2xbOvLLceA+t2NZpbc98E7jUOVS123yED+nqlfZjCq9Zt0r/ezwnQtjnFF ++ko1mcU4H9Jvg8aIgnU2AxE78zciU9CY8799pFFNThIjbooI8oVbfjbzbpmLzxjA5 ++3rDmZBTh+ySTlMa2U2oT4WPjRltZWnJVegRRLpG95GnTbQ1fkJAbj1Iu10XTkCee ++wBOqaA1UJem0a6pby5odE414Y7c0ETKcmaJtYENQyO0IJwZWDKtVe5OTIAklakia ++eyFTCAw1h5tHCYLaJW/Yu2wlLl5RNQcRZ9+cWXnldTY+TI1iBjfmADjLdKJYUlhX ++z7kWJtTi63Sdv6WYcEXxaWpxT+R3e2kaR/R7GOo4gdkWpX1siGlRteHHH2/36CSQ ++ZD2etcTUpGW+KDHFR4grnEfL1rt9UgvCjpa4KcssmZtWSSUCAwEAAaNTMFEwHQYD ++VR0OBBYEFHyJ6Fzr5R9ySATFj/uSCJz1YCY5MB8GA1UdIwQYMBaAFHyJ6Fzr5R9y ++SATFj/uSCJz1YCY5MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggGB ++AF3y0hvzyZWtmuG1JwIcOcc1aPl1KdRy8bao/5iHYGYYrsdDgcO5/e+y9S/izalc ++TdW7SKB5iBOCiE8fBNtToCvGP+fxNxHijpAmTr37G5sWuSo1T1VYFizHWL+df/Ig ++TcSvDrEjSnAwaEdNJUWtjoIC4VzNKTLtZf16QIATTzTZa3bfgSetpWS7LhLQbHod ++CSGI2QB1LRbqGC+a1Y85QxHv81jWzPWPzXYvnOLrDdQyBMOBcxDzrN4b6zg+5Itz ++qGYt+IS71jAH0IhxAyD/U5n1jGJv02BnSq0ynLEOD6gsnZjqAwPbt/PM9pGbtbXO ++70Q9rxr+vQc1IISKAEiH3txaEPi10wU98d6LbInJvQrmgHo/ntet8skWNYuxlEzS ++wvynuE9KvvQtOTodWt5AePtKrhHdxu527a4CHVp59nYUjKSdMKjvmhMRXM1cNjFE ++rA/pyyhozR47w3RzHMJVHw2GJ2B/HeqmxpXr1CmJjoRP38QCR7N+mqiZy85Fq2j2 ++8Q== ++-----END CERTIFICATE----- +diff --git a/bin/tests/system/nsupdate/CA/README b/bin/tests/system/nsupdate/CA/README +new file mode 100644 +index 00000000000..13069ca2f83 +--- /dev/null ++++ b/bin/tests/system/nsupdate/CA/README +@@ -0,0 +1,2 @@ ++Please take a look at the contents of the CA.cfg file for further ++instructions and configurations options. +diff --git a/bin/tests/system/nsupdate/CA/certs/srv01.client01.example.nil.key b/bin/tests/system/nsupdate/CA/certs/srv01.client01.example.nil.key +new file mode 100644 +index 00000000000..5e3420eda2c +--- /dev/null ++++ b/bin/tests/system/nsupdate/CA/certs/srv01.client01.example.nil.key +@@ -0,0 +1,40 @@ ++-----BEGIN PRIVATE KEY----- ++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 ++smxv7aRpgoWBRa5vinKvOv2T ++-----END PRIVATE KEY----- +diff --git a/bin/tests/system/nsupdate/CA/certs/srv01.client01.example.nil.pem b/bin/tests/system/nsupdate/CA/certs/srv01.client01.example.nil.pem +new file mode 100644 +index 00000000000..f546d35e7d6 +--- /dev/null ++++ b/bin/tests/system/nsupdate/CA/certs/srv01.client01.example.nil.pem +@@ -0,0 +1,93 @@ ++Certificate: ++ Data: ++ Version: 3 (0x2) ++ Serial Number: 8122792693893010842 (0x70b9f4eb2fa1959a) ++ Signature Algorithm: sha256WithRSAEncryption ++ Issuer: C=UA, ST=Kharkiv Oblast', L=Kharkiv, O=Internet Systems Consortium, CN=ca.test.example.com ++ Validity ++ Not Before: Sep 8 08:20:17 2022 GMT ++ Not After : Aug 31 08:20:17 2052 GMT ++ Subject: CN=srv01.client01.example.nil ++ Subject Public Key Info: ++ Public Key Algorithm: rsaEncryption ++ RSA Public-Key: (3072 bit) ++ Modulus: ++ 00:ab:60:2e:9c:61:e3:89:c6:52:2b:bc:e9:e1:05: ++ fd:18:65:42:20:f6:56:16:40:33:d2:cb:9f:f7:ef: ++ 22:54:a7:c9:55:70:ca:52:f0:e2:a2:58:38:7f:10: ++ ad:2b:05:e0:11:b6:69:21:7f:2d:38:56:dd:d5:e4: ++ f3:de:a7:32:35:f7:33:2a:52:80:ae:b7:d6:7c:35: ++ 74:c3:0c:8a:c3:3a:18:61:68:73:62:58:56:ff:78: ++ 25:57:1c:7b:be:98:88:21:dd:1c:8a:13:a5:9a:52: ++ 48:98:d9:3d:c4:28:a6:7e:9b:11:56:7e:ce:09:bb: ++ 51:89:8a:a8:1b:00:b5:73:2b:41:93:b1:62:40:30: ++ 29:ea:f6:a3:e7:bc:f0:e9:9e:07:2b:ae:a9:a0:1d: ++ 4d:d9:f8:18:4d:83:47:4e:68:ee:57:c8:55:15:86: ++ 3c:6d:1e:f5:31:f1:de:cf:c2:7e:6b:8e:22:5a:c5: ++ 76:af:d0:01:de:ab:7a:03:b2:96:33:cc:a0:26:ae: ++ de:c4:bd:76:85:96:c7:88:e4:46:bc:3f:c6:54:c9: ++ 95:83:87:9c:49:0d:31:dd:c4:17:52:99:e4:65:49: ++ 9b:9d:f3:ad:ce:66:08:57:f4:83:be:5e:87:da:42: ++ 5a:01:2a:6d:68:d1:8d:38:d9:18:ae:5e:2e:54:72: ++ 8b:01:45:96:af:f5:a3:d0:29:5d:22:8b:b4:d4:30: ++ af:02:36:c5:2d:e9:29:eb:2c:ea:6a:7e:27:b3:70: ++ fc:87:1f:2b:c4:b1:3a:a6:c2:e9:b7:c2:6f:46:63: ++ b7:96:2e:53:d8:b7:cd:c3:f4:b5:6d:b2:fc:57:49: ++ ac:9f:98:c9:fe:b4:f5:7c:93:48:2e:93:dc:e9:18: ++ 54:63:5f:18:a3:e7:12:aa:fe:38:f0:73:e5:17:1e: ++ fe:40:65:81:a8:8f:60:46:c2:16:f2:a8:9d:b1:1b: ++ bc:ce:05:de:37:b2:a8:86:47:bd:8d:92:de:e0:e5: ++ 42:89:b8:e3:f8:b1:24:08:7e:99 ++ Exponent: 65537 (0x10001) ++ X509v3 extensions: ++ X509v3 Subject Alternative Name: ++ DNS:srv01.client01.example.nil, IP Address:10.53.0.1 ++ Signature Algorithm: sha256WithRSAEncryption ++ 07:97:69:51:12:50:6a:e1:02:a0:b0:dc:93:75:16:c4:38:0f: ++ 5c:b3:47:da:bf:fa:9c:b6:de:c0:ef:38:f7:cc:d9:8d:71:ba: ++ 51:89:e5:48:36:dd:e1:f8:73:9d:92:80:1c:42:30:69:4f:8c: ++ 19:5d:f7:1d:03:e4:f2:76:e0:58:7b:c2:76:c4:0a:7e:20:69: ++ 26:6c:3e:cb:31:45:93:1d:07:5f:45:44:8e:5a:fb:87:17:7b: ++ 4d:5c:bf:37:bd:5e:ba:5c:22:84:bf:26:21:4a:c4:e9:f9:cb: ++ 73:de:fc:62:04:96:ad:aa:fd:89:09:5c:74:d6:bd:5f:07:17: ++ ef:9c:3d:ee:b7:dc:08:11:7f:12:66:ab:c4:ff:43:6d:7f:1e: ++ 01:b6:d1:19:73:53:18:e4:02:b0:7c:9e:99:63:d8:57:dd:07: ++ 79:fb:83:39:09:de:76:6e:68:b7:87:81:13:b8:26:e5:1c:c9: ++ a0:23:e5:97:39:ff:93:c7:8d:08:d8:ce:97:34:fc:ad:22:14: ++ 89:c0:ae:83:7d:0a:3f:cf:a0:9b:b4:6a:5c:b3:6d:5d:3b:88: ++ ca:1e:9b:99:54:64:57:58:3c:4c:bd:26:ee:11:c3:13:0b:1d: ++ f5:fd:d9:37:b0:31:72:6f:1d:e8:ba:43:37:46:f7:71:fe:6d: ++ 4a:30:33:29:c5:7b:37:8b:7e:06:22:89:a4:46:36:f0:fe:c6: ++ f5:f0:53:04:c0:35:52:78:6e:10:24:3a:d8:bf:7b:13:2f:98: ++ bc:69:31:41:68:02:5a:c4:f9:11:a2:6b:3f:c8:e0:d4:b3:80: ++ af:d2:be:fe:28:70:61:18:ed:8a:de:c4:cb:da:c9:60:94:91: ++ 76:63:69:8c:6e:96:f5:ba:e7:be:1e:1c:c3:84:b1:8d:e8:31: ++ f7:66:8c:0d:da:a8:78:57:19:fd:a0:8d:fa:9a:7e:51:1c:d1: ++ d0:84:07:a2:45:40:2d:c4:6b:e9:9f:86:4a:08:20:8f:9c:79: ++ 97:e3:7f:2a:14:73 ++-----BEGIN CERTIFICATE----- ++MIIEVTCCAr2gAwIBAgIIcLn06y+hlZowDQYJKoZIhvcNAQELBQAwfTELMAkGA1UE ++BhMCVUExGDAWBgNVBAgMD0toYXJraXYgT2JsYXN0JzEQMA4GA1UEBwwHS2hhcmtp ++djEkMCIGA1UECgwbSW50ZXJuZXQgU3lzdGVtcyBDb25zb3J0aXVtMRwwGgYDVQQD ++DBNjYS50ZXN0LmV4YW1wbGUuY29tMCAXDTIyMDkwODA4MjAxN1oYDzIwNTIwODMx ++MDgyMDE3WjAlMSMwIQYDVQQDDBpzcnYwMS5jbGllbnQwMS5leGFtcGxlLm5pbDCC ++AaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBAKtgLpxh44nGUiu86eEF/Rhl ++QiD2VhZAM9LLn/fvIlSnyVVwylLw4qJYOH8QrSsF4BG2aSF/LThW3dXk896nMjX3 ++MypSgK631nw1dMMMisM6GGFoc2JYVv94JVcce76YiCHdHIoTpZpSSJjZPcQopn6b ++EVZ+zgm7UYmKqBsAtXMrQZOxYkAwKer2o+e88OmeByuuqaAdTdn4GE2DR05o7lfI ++VRWGPG0e9THx3s/CfmuOIlrFdq/QAd6regOyljPMoCau3sS9doWWx4jkRrw/xlTJ ++lYOHnEkNMd3EF1KZ5GVJm53zrc5mCFf0g75eh9pCWgEqbWjRjTjZGK5eLlRyiwFF ++lq/1o9ApXSKLtNQwrwI2xS3pKess6mp+J7Nw/IcfK8SxOqbC6bfCb0Zjt5YuU9i3 ++zcP0tW2y/FdJrJ+Yyf609XyTSC6T3OkYVGNfGKPnEqr+OPBz5Rce/kBlgaiPYEbC ++FvKonbEbvM4F3jeyqIZHvY2S3uDlQom44/ixJAh+mQIDAQABoy8wLTArBgNVHREE ++JDAighpzcnYwMS5jbGllbnQwMS5leGFtcGxlLm5pbIcECjUAATANBgkqhkiG9w0B ++AQsFAAOCAYEAB5dpURJQauECoLDck3UWxDgPXLNH2r/6nLbewO8498zZjXG6UYnl ++SDbd4fhznZKAHEIwaU+MGV33HQPk8nbgWHvCdsQKfiBpJmw+yzFFkx0HX0VEjlr7 ++hxd7TVy/N71eulwihL8mIUrE6fnLc978YgSWrar9iQlcdNa9XwcX75w97rfcCBF/ ++EmarxP9DbX8eAbbRGXNTGOQCsHyemWPYV90HefuDOQnedm5ot4eBE7gm5RzJoCPl ++lzn/k8eNCNjOlzT8rSIUicCug30KP8+gm7RqXLNtXTuIyh6bmVRkV1g8TL0m7hHD ++Ewsd9f3ZN7Axcm8d6LpDN0b3cf5tSjAzKcV7N4t+BiKJpEY28P7G9fBTBMA1Unhu ++ECQ62L97Ey+YvGkxQWgCWsT5EaJrP8jg1LOAr9K+/ihwYRjtit7Ey9rJYJSRdmNp ++jG6W9brnvh4cw4Sxjegx92aMDdqoeFcZ/aCN+pp+URzR0IQHokVALcRr6Z+GSggg ++j5x5l+N/KhRz ++-----END CERTIFICATE----- +diff --git a/bin/tests/system/nsupdate/CA/certs/srv01.client02-expired.example.nil.key b/bin/tests/system/nsupdate/CA/certs/srv01.client02-expired.example.nil.key +new file mode 100644 +index 00000000000..d8f68ac3eb7 +--- /dev/null ++++ b/bin/tests/system/nsupdate/CA/certs/srv01.client02-expired.example.nil.key +@@ -0,0 +1,40 @@ ++-----BEGIN PRIVATE KEY----- ++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 ++c+Ctg5Ig6vwr2weVc7s/4jz9Kg== ++-----END PRIVATE KEY----- +diff --git a/bin/tests/system/nsupdate/CA/certs/srv01.client02-expired.example.nil.pem b/bin/tests/system/nsupdate/CA/certs/srv01.client02-expired.example.nil.pem +new file mode 100644 +index 00000000000..365b493f7e3 +--- /dev/null ++++ b/bin/tests/system/nsupdate/CA/certs/srv01.client02-expired.example.nil.pem +@@ -0,0 +1,93 @@ ++Certificate: ++ Data: ++ Version: 3 (0x2) ++ Serial Number: 8122792693893010843 (0x70b9f4eb2fa1959b) ++ Signature Algorithm: sha256WithRSAEncryption ++ Issuer: C=UA, ST=Kharkiv Oblast', L=Kharkiv, O=Internet Systems Consortium, CN=ca.test.example.com ++ Validity ++ Not Before: Sep 7 08:14:18 2022 GMT ++ Not After : Sep 8 08:14:18 2022 GMT ++ Subject: CN=srv01.client02-expired.example.nil ++ Subject Public Key Info: ++ Public Key Algorithm: rsaEncryption ++ RSA Public-Key: (3072 bit) ++ Modulus: ++ 00:c0:11:27:17:25:3a:ad:85:a0:3b:59:0b:22:64: ++ 63:7d:bb:05:32:35:4f:68:d5:19:2b:cd:46:bd:e2: ++ b6:42:8c:08:cf:09:0d:a8:cd:58:d9:1b:77:db:17: ++ 8a:fc:f0:55:f2:e1:50:f4:fd:90:aa:49:15:5d:ea: ++ 9b:5a:47:c4:2f:82:07:46:87:f6:05:ef:15:02:a4: ++ 3c:a1:da:fc:5b:75:36:12:f7:12:50:55:f8:be:0c: ++ 7d:21:91:e2:92:d8:41:3f:71:fe:b2:17:c0:68:1d: ++ 09:be:fc:c4:24:ec:ef:d2:5c:52:a9:4f:d6:5d:30: ++ b8:ab:68:2e:39:e9:8b:5b:c6:f0:64:42:f7:b8:bd: ++ b2:90:32:22:68:bc:38:70:2f:14:ae:c8:7c:63:04: ++ d5:11:b2:0a:f1:8e:13:10:b2:3b:69:f4:fe:3a:e2: ++ f1:58:56:28:93:c1:28:aa:a7:19:c9:91:12:43:f8: ++ f5:1d:34:58:3d:32:9f:11:67:d1:1f:53:d4:e0:d5: ++ 0c:78:2c:6f:38:3f:e1:89:69:b5:09:3c:12:f4:a9: ++ ee:e5:2f:c5:47:65:a6:82:fa:ea:78:48:31:89:11: ++ b6:23:8a:27:ed:7c:1d:6d:e8:ab:a0:29:de:40:f4: ++ f2:9b:61:22:da:9c:22:32:f7:3d:f8:4c:e1:38:a7: ++ e2:c3:af:a4:67:7f:94:a4:fd:52:25:89:4d:f4:9a: ++ d6:35:ba:98:20:f1:4b:c9:a5:cf:ac:72:58:2a:cd: ++ 3b:4a:3e:e9:04:31:e2:9a:74:32:d5:52:60:34:ad: ++ 0c:85:02:65:58:41:74:2a:57:91:34:55:36:a9:14: ++ 5b:45:cc:28:27:d7:6d:ba:55:a3:dd:9f:00:04:a4: ++ 43:c2:af:5c:af:86:53:a6:d5:a7:49:aa:31:d6:5e: ++ 92:7d:26:dd:8d:f4:87:8a:9b:48:e8:25:f4:c7:34: ++ ca:cf:e3:f7:84:19:3b:43:c7:6a:b8:da:6e:6f:85: ++ af:8d:0c:fb:7c:ea:c7:73:9c:9b ++ Exponent: 65537 (0x10001) ++ X509v3 extensions: ++ X509v3 Subject Alternative Name: ++ DNS:srv01.client02-expired.example.nil, IP Address:10.53.0.1 ++ Signature Algorithm: sha256WithRSAEncryption ++ 18:f1:7c:24:5b:d2:03:b0:60:0e:60:e6:32:f9:a7:47:d1:e4: ++ bd:3f:a3:21:53:90:84:9a:c6:2c:87:b2:16:28:95:07:a3:2a: ++ c3:33:8f:60:70:3f:26:58:be:ec:a2:6c:44:89:d3:4e:ef:bb: ++ ce:af:9b:5f:15:06:03:21:74:e3:6f:2a:dc:5c:19:4e:d3:cb: ++ ba:c3:5f:d8:76:89:59:50:82:69:5f:a1:ac:9f:be:79:e1:22: ++ 12:37:f9:d3:2e:00:35:03:03:9d:08:24:45:65:7a:e9:72:31: ++ e1:67:44:32:17:25:dd:b9:72:eb:c6:40:d7:5d:8d:5f:00:48: ++ 07:09:0d:3c:4c:a1:f1:05:4b:05:9b:2b:5a:21:09:46:f4:17: ++ 7a:cf:34:87:ad:bf:ef:bd:56:74:d7:1a:8f:07:ce:70:b1:aa: ++ 4d:82:4f:08:dc:56:27:f9:21:20:b8:06:c7:29:b4:8e:36:82: ++ b8:43:85:1c:2d:9f:be:2d:b9:9d:40:de:52:55:6a:2e:0b:28: ++ 33:fc:f8:1b:70:e9:c5:46:50:f3:05:be:8d:ed:99:ec:f1:8c: ++ 51:8a:1c:4b:95:f4:c4:dd:cd:42:74:bc:6f:66:64:54:b8:c1: ++ 6e:c8:3d:e9:fe:10:02:61:50:77:38:b9:b0:b8:13:37:8f:0e: ++ 5b:49:92:3a:9d:9a:60:51:68:99:8a:d5:7e:92:71:7e:fa:db: ++ 52:37:4d:f9:0d:6c:3b:79:a3:b9:16:b7:95:00:ea:eb:17:54: ++ e2:50:d7:a5:08:54:58:2c:79:66:01:4b:95:65:ed:b8:81:f7: ++ 4c:fa:f8:89:37:ad:d9:dc:c9:75:9d:02:3e:e5:92:b3:03:ab: ++ 70:69:83:f5:6c:a6:27:7e:2e:fc:9d:b2:59:0a:43:ad:3f:55: ++ 2f:5d:ec:ef:52:f0:3e:be:b5:d6:e2:c3:91:9d:dd:5d:e1:9e: ++ e6:18:90:0b:6a:85:f8:e3:83:2a:7c:91:c3:52:1c:6d:aa:2b: ++ 44:b8:6f:2b:af:6e ++-----BEGIN CERTIFICATE----- ++MIIEYzCCAsugAwIBAgIIcLn06y+hlZswDQYJKoZIhvcNAQELBQAwfTELMAkGA1UE ++BhMCVUExGDAWBgNVBAgMD0toYXJraXYgT2JsYXN0JzEQMA4GA1UEBwwHS2hhcmtp ++djEkMCIGA1UECgwbSW50ZXJuZXQgU3lzdGVtcyBDb25zb3J0aXVtMRwwGgYDVQQD ++DBNjYS50ZXN0LmV4YW1wbGUuY29tMB4XDTIyMDkwNzA4MTQxOFoXDTIyMDkwODA4 ++MTQxOFowLTErMCkGA1UEAwwic3J2MDEuY2xpZW50MDItZXhwaXJlZC5leGFtcGxl ++Lm5pbDCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBAMARJxclOq2FoDtZ ++CyJkY327BTI1T2jVGSvNRr3itkKMCM8JDajNWNkbd9sXivzwVfLhUPT9kKpJFV3q ++m1pHxC+CB0aH9gXvFQKkPKHa/Ft1NhL3ElBV+L4MfSGR4pLYQT9x/rIXwGgdCb78 ++xCTs79JcUqlP1l0wuKtoLjnpi1vG8GRC97i9spAyImi8OHAvFK7IfGME1RGyCvGO ++ExCyO2n0/jri8VhWKJPBKKqnGcmREkP49R00WD0ynxFn0R9T1ODVDHgsbzg/4Ylp ++tQk8EvSp7uUvxUdlpoL66nhIMYkRtiOKJ+18HW3oq6Ap3kD08pthItqcIjL3PfhM ++4Tin4sOvpGd/lKT9UiWJTfSa1jW6mCDxS8mlz6xyWCrNO0o+6QQx4pp0MtVSYDSt ++DIUCZVhBdCpXkTRVNqkUW0XMKCfXbbpVo92fAASkQ8KvXK+GU6bVp0mqMdZekn0m ++3Y30h4qbSOgl9Mc0ys/j94QZO0PHarjabm+Fr40M+3zqx3OcmwIDAQABozcwNTAz ++BgNVHREELDAqgiJzcnYwMS5jbGllbnQwMi1leHBpcmVkLmV4YW1wbGUubmlshwQK ++NQABMA0GCSqGSIb3DQEBCwUAA4IBgQAY8XwkW9IDsGAOYOYy+adH0eS9P6MhU5CE ++msYsh7IWKJUHoyrDM49gcD8mWL7somxEidNO77vOr5tfFQYDIXTjbyrcXBlO08u6 ++w1/YdolZUIJpX6Gsn7554SISN/nTLgA1AwOdCCRFZXrpcjHhZ0QyFyXduXLrxkDX ++XY1fAEgHCQ08TKHxBUsFmytaIQlG9Bd6zzSHrb/vvVZ01xqPB85wsapNgk8I3FYn +++SEguAbHKbSONoK4Q4UcLZ++LbmdQN5SVWouCygz/PgbcOnFRlDzBb6N7Zns8YxR ++ihxLlfTE3c1CdLxvZmRUuMFuyD3p/hACYVB3OLmwuBM3jw5bSZI6nZpgUWiZitV+ ++knF++ttSN035DWw7eaO5FreVAOrrF1TiUNelCFRYLHlmAUuVZe24gfdM+viJN63Z ++3Ml1nQI+5ZKzA6twaYP1bKYnfi78nbJZCkOtP1UvXezvUvA+vrXW4sORnd1d4Z7m ++GJALaoX444MqfJHDUhxtqitEuG8rr24= ++-----END CERTIFICATE----- +diff --git a/bin/tests/system/nsupdate/CA/certs/srv01.crt01.example.nil.key b/bin/tests/system/nsupdate/CA/certs/srv01.crt01.example.nil.key +new file mode 100644 +index 00000000000..8a1f5dce5ef +--- /dev/null ++++ b/bin/tests/system/nsupdate/CA/certs/srv01.crt01.example.nil.key +@@ -0,0 +1,40 @@ ++-----BEGIN PRIVATE KEY----- ++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 ++v3Tmy/b2gUdEwuKFCxx97g== ++-----END PRIVATE KEY----- +diff --git a/bin/tests/system/nsupdate/CA/certs/srv01.crt01.example.nil.pem b/bin/tests/system/nsupdate/CA/certs/srv01.crt01.example.nil.pem +new file mode 100644 +index 00000000000..4a4556c2b04 +--- /dev/null ++++ b/bin/tests/system/nsupdate/CA/certs/srv01.crt01.example.nil.pem +@@ -0,0 +1,93 @@ ++Certificate: ++ Data: ++ Version: 3 (0x2) ++ Serial Number: 8122792693893010840 (0x70b9f4eb2fa19598) ++ Signature Algorithm: sha256WithRSAEncryption ++ Issuer: C=UA, ST=Kharkiv Oblast', L=Kharkiv, O=Internet Systems Consortium, CN=ca.test.example.com ++ Validity ++ Not Before: Sep 7 20:28:03 2022 GMT ++ Not After : Aug 30 20:28:03 2052 GMT ++ Subject: CN=srv01.crt01.example.nil ++ Subject Public Key Info: ++ Public Key Algorithm: rsaEncryption ++ RSA Public-Key: (3072 bit) ++ Modulus: ++ 00:b4:9a:63:98:04:ad:bd:ab:29:bf:22:70:54:30: ++ df:c7:6b:77:5d:b8:5e:0b:cd:0e:a0:6c:74:37:e7: ++ 4b:78:d1:96:da:ca:99:7d:92:b1:e4:1a:0a:1e:b4: ++ 1c:be:ee:cc:95:8c:52:03:93:85:e1:40:43:68:86: ++ 86:bc:6a:62:6d:d6:0a:ca:ee:4f:93:2d:ee:6b:df: ++ 7a:f6:dc:fa:44:a6:39:80:2c:38:7c:89:cd:d9:a3: ++ 99:ec:e8:2b:48:6d:84:41:3d:0e:1a:1f:68:5e:17: ++ 88:8f:a5:da:4d:1c:36:26:ae:b4:7e:d2:fe:a2:59: ++ d5:67:3a:56:c2:21:65:0d:dd:97:6f:f0:e5:b4:1e: ++ 87:ae:97:35:0d:f4:9b:ae:dc:8a:3e:28:aa:b8:a2: ++ ab:ee:9d:b2:c5:91:f6:71:99:a5:86:cb:31:9c:05: ++ d6:9b:94:13:46:a9:9a:c9:a5:55:5f:6c:cc:d0:84: ++ 27:e2:b1:b5:73:39:08:7f:80:2f:04:26:96:0c:8d: ++ 29:9b:be:5e:cc:39:af:a2:db:82:82:57:07:e6:b2: ++ 4a:d9:3d:c8:79:6e:67:61:f3:48:37:a8:4f:9f:b3: ++ cf:84:b6:50:08:3d:e9:85:e9:a9:76:50:80:e7:2c: ++ 6f:65:95:cb:e2:23:41:58:39:70:e7:78:29:3d:c2: ++ d6:20:7c:2b:87:30:bd:98:87:63:ed:4a:ad:b9:ed: ++ 7a:4b:13:a1:3d:62:5e:b6:74:64:ef:25:a3:dd:93: ++ 47:aa:d3:25:7e:2a:d7:09:1b:5c:59:50:f1:d4:c6: ++ 9c:f2:64:8a:7c:cb:cc:52:37:50:88:4b:84:35:40: ++ 51:0e:a1:06:a2:60:b6:b0:e3:8f:f9:d8:8e:45:77: ++ 7d:0e:7d:11:92:22:15:0f:a3:37:84:c4:25:dc:14: ++ b4:20:7a:b7:16:96:72:d4:bf:4d:5d:d2:ab:71:43: ++ 44:be:87:44:d2:b8:74:f7:86:3f:d2:5d:dd:5e:e6: ++ 74:ab:fb:cc:a3:5d:a6:84:80:0b ++ Exponent: 65537 (0x10001) ++ X509v3 extensions: ++ X509v3 Subject Alternative Name: ++ DNS:srv01.crt01.example.nil, IP Address:10.53.0.1 ++ Signature Algorithm: sha256WithRSAEncryption ++ 94:15:c0:4a:f1:aa:15:30:f7:cb:fe:f9:fa:ba:5f:f0:18:1f: ++ 7e:44:9a:b1:d4:9c:f9:78:d3:a7:c7:65:f2:d1:48:62:f4:cb: ++ 2f:20:ea:7c:af:08:cf:db:e2:0f:ab:c0:22:38:16:c5:0c:e5: ++ c7:6e:34:b1:ed:f6:02:1a:69:c0:09:d1:43:b3:30:77:fc:00: ++ 07:1b:da:88:97:5b:28:4e:e6:92:ca:00:cc:86:66:a9:a9:0a: ++ 75:be:74:88:7d:09:52:e7:a9:82:8f:a9:62:5e:b3:19:64:14: ++ e5:54:9e:6d:9c:98:39:8b:1f:92:92:59:f9:a2:46:75:96:11: ++ 71:8a:c8:71:05:10:2a:b8:f3:a4:19:db:eb:05:17:0a:dd:98: ++ 2c:58:54:3a:7f:8c:c2:26:9e:62:ca:04:dd:3c:99:1f:a0:64: ++ 69:fb:d6:04:c1:0b:8c:62:f6:2d:ea:bc:6c:a9:39:7b:f1:20: ++ b8:b7:04:3c:a7:65:fa:1f:db:22:e2:5b:8b:91:75:60:be:e1: ++ 1e:50:13:23:d5:4b:93:87:20:ec:46:6f:5f:94:dc:b1:60:d1: ++ 79:4b:5e:76:c9:6d:0d:be:a6:9a:6b:67:8b:a7:48:7e:51:b5: ++ 9b:9d:ec:a6:0c:c1:b3:d9:0b:26:8b:f2:7c:cf:61:d0:a2:a0: ++ 90:90:18:6b:b4:ca:56:b8:5e:5a:8b:78:71:c4:d1:fc:15:30: ++ 0a:03:26:74:85:3d:6c:ed:d3:e1:c9:c1:b0:d4:0c:b9:f3:04: ++ 93:0d:e3:a6:2c:a7:ee:e0:24:0d:dd:37:fc:6b:09:d5:b5:55: ++ 33:12:82:cf:f2:ba:0f:b0:e2:ce:f7:c0:ac:2c:7f:ab:f9:dd: ++ 87:b1:9b:95:f2:d7:32:98:dd:4c:b3:28:b7:0d:2b:2f:62:65: ++ ce:59:fb:95:d4:5f:9d:fd:83:5a:01:3b:5f:48:5f:3c:fa:4b: ++ 52:91:66:e1:49:8e:cd:09:78:f5:ce:f8:cd:5c:85:3e:ad:bd: ++ 1c:4e:e0:3f:0a:8b ++-----BEGIN CERTIFICATE----- ++MIIETzCCAregAwIBAgIIcLn06y+hlZgwDQYJKoZIhvcNAQELBQAwfTELMAkGA1UE ++BhMCVUExGDAWBgNVBAgMD0toYXJraXYgT2JsYXN0JzEQMA4GA1UEBwwHS2hhcmtp ++djEkMCIGA1UECgwbSW50ZXJuZXQgU3lzdGVtcyBDb25zb3J0aXVtMRwwGgYDVQQD ++DBNjYS50ZXN0LmV4YW1wbGUuY29tMCAXDTIyMDkwNzIwMjgwM1oYDzIwNTIwODMw ++MjAyODAzWjAiMSAwHgYDVQQDDBdzcnYwMS5jcnQwMS5leGFtcGxlLm5pbDCCAaIw ++DQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBALSaY5gErb2rKb8icFQw38drd124 ++XgvNDqBsdDfnS3jRltrKmX2SseQaCh60HL7uzJWMUgOTheFAQ2iGhrxqYm3WCsru ++T5Mt7mvfevbc+kSmOYAsOHyJzdmjmezoK0hthEE9DhofaF4XiI+l2k0cNiautH7S ++/qJZ1Wc6VsIhZQ3dl2/w5bQeh66XNQ30m67cij4oqriiq+6dssWR9nGZpYbLMZwF ++1puUE0apmsmlVV9szNCEJ+KxtXM5CH+ALwQmlgyNKZu+Xsw5r6LbgoJXB+ayStk9 ++yHluZ2HzSDeoT5+zz4S2UAg96YXpqXZQgOcsb2WVy+IjQVg5cOd4KT3C1iB8K4cw ++vZiHY+1KrbnteksToT1iXrZ0ZO8lo92TR6rTJX4q1wkbXFlQ8dTGnPJkinzLzFI3 ++UIhLhDVAUQ6hBqJgtrDjj/nYjkV3fQ59EZIiFQ+jN4TEJdwUtCB6txaWctS/TV3S ++q3FDRL6HRNK4dPeGP9Jd3V7mdKv7zKNdpoSACwIDAQABoywwKjAoBgNVHREEITAf ++ghdzcnYwMS5jcnQwMS5leGFtcGxlLm5pbIcECjUAATANBgkqhkiG9w0BAQsFAAOC ++AYEAlBXASvGqFTD3y/75+rpf8BgffkSasdSc+XjTp8dl8tFIYvTLLyDqfK8Iz9vi ++D6vAIjgWxQzlx240se32AhppwAnRQ7Mwd/wABxvaiJdbKE7mksoAzIZmqakKdb50 ++iH0JUuepgo+pYl6zGWQU5VSebZyYOYsfkpJZ+aJGdZYRcYrIcQUQKrjzpBnb6wUX ++Ct2YLFhUOn+MwiaeYsoE3TyZH6BkafvWBMELjGL2Leq8bKk5e/EguLcEPKdl+h/b ++IuJbi5F1YL7hHlATI9VLk4cg7EZvX5TcsWDReUtedsltDb6mmmtni6dIflG1m53s ++pgzBs9kLJovyfM9h0KKgkJAYa7TKVrheWot4ccTR/BUwCgMmdIU9bO3T4cnBsNQM ++ufMEkw3jpiyn7uAkDd03/GsJ1bVVMxKCz/K6D7DizvfArCx/q/ndh7GblfLXMpjd ++TLMotw0rL2Jlzln7ldRfnf2DWgE7X0hfPPpLUpFm4UmOzQl49c74zVyFPq29HE7g ++PwqL ++-----END CERTIFICATE----- +diff --git a/bin/tests/system/nsupdate/CA/certs/srv01.crt02-expired.example.nil.key b/bin/tests/system/nsupdate/CA/certs/srv01.crt02-expired.example.nil.key +new file mode 100644 +index 00000000000..307d26df74f +--- /dev/null ++++ b/bin/tests/system/nsupdate/CA/certs/srv01.crt02-expired.example.nil.key +@@ -0,0 +1,40 @@ ++-----BEGIN PRIVATE KEY----- ++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 ++bKvcUjDKJOb0BURXpKzS8Rf9 ++-----END PRIVATE KEY----- +diff --git a/bin/tests/system/nsupdate/CA/certs/srv01.crt02-expired.example.nil.pem b/bin/tests/system/nsupdate/CA/certs/srv01.crt02-expired.example.nil.pem +new file mode 100644 +index 00000000000..3fa0b9ae881 +--- /dev/null ++++ b/bin/tests/system/nsupdate/CA/certs/srv01.crt02-expired.example.nil.pem +@@ -0,0 +1,93 @@ ++Certificate: ++ Data: ++ Version: 3 (0x2) ++ Serial Number: 8122792693893010841 (0x70b9f4eb2fa19599) ++ Signature Algorithm: sha256WithRSAEncryption ++ Issuer: C=UA, ST=Kharkiv Oblast', L=Kharkiv, O=Internet Systems Consortium, CN=ca.test.example.com ++ Validity ++ Not Before: Sep 6 20:34:09 2022 GMT ++ Not After : Sep 7 20:34:09 2022 GMT ++ Subject: CN=srv01.crt02-expired.example.nil ++ Subject Public Key Info: ++ Public Key Algorithm: rsaEncryption ++ RSA Public-Key: (3072 bit) ++ Modulus: ++ 00:ec:2c:88:01:b5:8b:3a:74:56:0d:57:b3:75:fd: ++ 05:58:05:ed:8a:ab:e8:29:0e:f1:52:34:2e:22:62: ++ 6e:41:74:ff:78:33:b4:ff:15:73:fa:ce:90:10:a4: ++ fe:d2:66:14:7b:0b:79:7b:d6:20:88:f9:41:31:14: ++ 9a:49:36:8c:38:74:4b:f3:e2:51:e7:e5:6f:bd:65: ++ 38:e6:9c:30:80:3f:24:56:f6:68:9e:09:76:81:5b: ++ 59:81:44:56:9f:1c:3f:48:f0:95:bf:60:40:29:df: ++ ac:42:3d:c3:6f:85:2d:c3:0e:08:b6:f7:12:2a:51: ++ 00:bf:cf:fe:6c:ae:d7:7d:de:c1:72:f8:32:03:5f: ++ c9:3f:4a:de:e5:fa:24:90:46:f0:4a:5f:09:d8:93: ++ 4c:bf:1c:61:4c:d2:dc:db:6c:f8:af:73:5b:b7:3b: ++ 7a:e8:6d:1c:bb:26:23:47:87:fd:50:06:0f:f1:b5: ++ 88:8a:a8:25:69:57:e3:46:3b:d2:6b:52:fb:5a:01: ++ f6:96:e9:2a:cf:13:e7:16:4c:fd:5a:f6:1f:0b:8d: ++ f7:25:a3:68:d7:15:fc:5c:48:49:05:e2:85:24:70: ++ 57:b1:d8:05:24:ae:26:3a:00:9b:72:a8:47:05:c5: ++ f3:7c:2d:f2:58:72:37:fb:c1:8b:4f:42:8f:dd:9a: ++ ac:5b:ae:6f:21:62:ad:29:81:b9:8b:4b:6c:ff:61: ++ 99:0f:7c:09:d3:6d:00:20:2d:b1:0c:00:6c:99:4c: ++ 92:dc:0e:11:2d:e7:ba:7b:c7:c8:b1:a3:1a:61:f8: ++ cc:2c:af:17:b6:db:cc:36:02:fe:fb:66:15:77:84: ++ 70:cd:42:25:b7:16:64:28:ae:9d:8c:81:85:a0:e0: ++ 50:82:aa:e8:e9:ac:51:fc:2b:63:44:b1:08:b8:90: ++ d7:8c:1c:23:b2:1b:08:59:85:d5:dd:39:44:f7:47: ++ 5e:48:08:34:eb:2c:df:75:47:08:b6:b6:e6:32:ed: ++ 76:74:77:ce:3d:4d:fe:02:b1:33 ++ Exponent: 65537 (0x10001) ++ X509v3 extensions: ++ X509v3 Subject Alternative Name: ++ DNS:srv01.crt02-expired.example.nil, IP Address:10.53.0.1 ++ Signature Algorithm: sha256WithRSAEncryption ++ 2a:52:c4:cb:a9:2f:f7:2b:ed:04:b5:03:d5:06:59:ed:5c:7c: ++ b7:00:9e:c4:33:90:fe:d0:b0:18:f3:f2:06:30:54:18:fe:34: ++ cb:ea:61:4f:9c:23:67:3c:ae:ed:20:df:82:52:ec:59:88:45: ++ ad:3c:6c:a7:34:24:1c:4d:66:ab:71:3d:59:8c:ef:cd:a0:e2: ++ 7b:59:2d:43:94:cd:f5:0a:3c:4e:81:24:e8:fd:c6:d0:fd:ad: ++ 6f:cc:29:5b:67:0b:b7:ee:43:38:a4:91:c2:d9:3b:f8:d6:97: ++ bc:92:dd:ec:a1:ab:85:35:44:f4:0a:df:ad:8d:8c:52:c3:49: ++ 7e:39:10:a1:13:43:78:71:e2:92:aa:31:3d:d9:94:15:7f:86: ++ c8:aa:b4:a1:6d:bf:eb:55:b1:d7:41:6f:c3:7d:88:5e:9c:b7: ++ b1:4b:0d:a7:17:4f:3e:4a:46:3f:6f:48:27:8c:d0:e5:51:fc: ++ 42:ba:c5:b9:4f:63:6f:2e:f2:fd:0c:c0:6e:23:b4:59:93:68: ++ a4:2d:16:ce:f4:7b:3a:45:1d:a0:6e:98:0b:f7:6a:e6:75:0c: ++ db:56:19:6b:88:f0:7f:6b:08:f8:fc:bb:d1:3f:25:25:1a:6c: ++ 8e:34:cb:91:18:54:d5:2d:ce:9c:d0:b7:c3:bc:b5:0a:e0:b9: ++ 73:6f:4d:ad:6b:3c:b6:49:ef:c0:10:13:c7:0a:78:4d:98:7d: ++ cb:84:a1:29:40:8c:dd:31:7d:ae:c4:f5:25:5d:b9:74:b2:f5: ++ e2:2b:e0:43:c8:50:61:a3:a8:26:1a:03:ab:1a:24:3b:13:56: ++ da:0d:ee:ff:2f:bd:d5:77:82:72:63:b8:aa:e1:18:f7:3b:c1: ++ a1:f8:51:b1:70:b9:25:39:df:a3:41:79:d7:2b:ec:32:f6:cb: ++ 30:28:d2:1e:f1:b4:e1:80:03:9f:c2:0f:36:85:82:5e:39:ba: ++ 9e:eb:67:76:42:93:bf:e0:df:64:b2:b5:5f:98:a1:45:3f:4a: ++ 1f:5c:c5:04:10:f6 ++-----BEGIN CERTIFICATE----- ++MIIEXTCCAsWgAwIBAgIIcLn06y+hlZkwDQYJKoZIhvcNAQELBQAwfTELMAkGA1UE ++BhMCVUExGDAWBgNVBAgMD0toYXJraXYgT2JsYXN0JzEQMA4GA1UEBwwHS2hhcmtp ++djEkMCIGA1UECgwbSW50ZXJuZXQgU3lzdGVtcyBDb25zb3J0aXVtMRwwGgYDVQQD ++DBNjYS50ZXN0LmV4YW1wbGUuY29tMB4XDTIyMDkwNjIwMzQwOVoXDTIyMDkwNzIw ++MzQwOVowKjEoMCYGA1UEAwwfc3J2MDEuY3J0MDItZXhwaXJlZC5leGFtcGxlLm5p ++bDCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBAOwsiAG1izp0Vg1Xs3X9 ++BVgF7Yqr6CkO8VI0LiJibkF0/3gztP8Vc/rOkBCk/tJmFHsLeXvWIIj5QTEUmkk2 ++jDh0S/PiUeflb71lOOacMIA/JFb2aJ4JdoFbWYFEVp8cP0jwlb9gQCnfrEI9w2+F ++LcMOCLb3EipRAL/P/myu133ewXL4MgNfyT9K3uX6JJBG8EpfCdiTTL8cYUzS3Nts +++K9zW7c7euhtHLsmI0eH/VAGD/G1iIqoJWlX40Y70mtS+1oB9pbpKs8T5xZM/Vr2 ++HwuN9yWjaNcV/FxISQXihSRwV7HYBSSuJjoAm3KoRwXF83wt8lhyN/vBi09Cj92a ++rFuubyFirSmBuYtLbP9hmQ98CdNtACAtsQwAbJlMktwOES3nunvHyLGjGmH4zCyv ++F7bbzDYC/vtmFXeEcM1CJbcWZCiunYyBhaDgUIKq6OmsUfwrY0SxCLiQ14wcI7Ib ++CFmF1d05RPdHXkgINOss33VHCLa25jLtdnR3zj1N/gKxMwIDAQABozQwMjAwBgNV ++HREEKTAngh9zcnYwMS5jcnQwMi1leHBpcmVkLmV4YW1wbGUubmlshwQKNQABMA0G ++CSqGSIb3DQEBCwUAA4IBgQAqUsTLqS/3K+0EtQPVBlntXHy3AJ7EM5D+0LAY8/IG ++MFQY/jTL6mFPnCNnPK7tIN+CUuxZiEWtPGynNCQcTWarcT1ZjO/NoOJ7WS1DlM31 ++CjxOgSTo/cbQ/a1vzClbZwu37kM4pJHC2Tv41pe8kt3soauFNUT0Ct+tjYxSw0l+ ++ORChE0N4ceKSqjE92ZQVf4bIqrShbb/rVbHXQW/DfYhenLexSw2nF08+SkY/b0gn ++jNDlUfxCusW5T2NvLvL9DMBuI7RZk2ikLRbO9Hs6RR2gbpgL92rmdQzbVhlriPB/ ++awj4/LvRPyUlGmyONMuRGFTVLc6c0LfDvLUK4Llzb02tazy2Se/AEBPHCnhNmH3L ++hKEpQIzdMX2uxPUlXbl0svXiK+BDyFBho6gmGgOrGiQ7E1baDe7/L73Vd4JyY7iq ++4Rj3O8Gh+FGxcLklOd+jQXnXK+wy9sswKNIe8bThgAOfwg82hYJeObqe62d2QpO/ ++4N9ksrVfmKFFP0ofXMUEEPY= ++-----END CERTIFICATE----- +diff --git a/bin/tests/system/nsupdate/CA/index.txt b/bin/tests/system/nsupdate/CA/index.txt +new file mode 100644 +index 00000000000..020155fb376 +--- /dev/null ++++ b/bin/tests/system/nsupdate/CA/index.txt +@@ -0,0 +1,4 @@ ++V 20520830202803Z 70B9F4EB2FA19598 unknown /CN=srv01.crt01.example.nil ++V 220907203409Z 70B9F4EB2FA19599 unknown /CN=srv01.crt02-expired.example.nil ++V 20520831082017Z 70B9F4EB2FA1959A unknown /CN=srv01.client01.example.nil ++V 220908081418Z 70B9F4EB2FA1959B unknown /CN=srv01.client02-expired.example.nil +diff --git a/bin/tests/system/nsupdate/CA/index.txt.attr b/bin/tests/system/nsupdate/CA/index.txt.attr +new file mode 100644 +index 00000000000..8f7e63a3475 +--- /dev/null ++++ b/bin/tests/system/nsupdate/CA/index.txt.attr +@@ -0,0 +1 @@ ++unique_subject = yes +diff --git a/bin/tests/system/nsupdate/CA/newcerts/70B9F4EB2FA19598.pem b/bin/tests/system/nsupdate/CA/newcerts/70B9F4EB2FA19598.pem +new file mode 100644 +index 00000000000..4a4556c2b04 +--- /dev/null ++++ b/bin/tests/system/nsupdate/CA/newcerts/70B9F4EB2FA19598.pem +@@ -0,0 +1,93 @@ ++Certificate: ++ Data: ++ Version: 3 (0x2) ++ Serial Number: 8122792693893010840 (0x70b9f4eb2fa19598) ++ Signature Algorithm: sha256WithRSAEncryption ++ Issuer: C=UA, ST=Kharkiv Oblast', L=Kharkiv, O=Internet Systems Consortium, CN=ca.test.example.com ++ Validity ++ Not Before: Sep 7 20:28:03 2022 GMT ++ Not After : Aug 30 20:28:03 2052 GMT ++ Subject: CN=srv01.crt01.example.nil ++ Subject Public Key Info: ++ Public Key Algorithm: rsaEncryption ++ RSA Public-Key: (3072 bit) ++ Modulus: ++ 00:b4:9a:63:98:04:ad:bd:ab:29:bf:22:70:54:30: ++ df:c7:6b:77:5d:b8:5e:0b:cd:0e:a0:6c:74:37:e7: ++ 4b:78:d1:96:da:ca:99:7d:92:b1:e4:1a:0a:1e:b4: ++ 1c:be:ee:cc:95:8c:52:03:93:85:e1:40:43:68:86: ++ 86:bc:6a:62:6d:d6:0a:ca:ee:4f:93:2d:ee:6b:df: ++ 7a:f6:dc:fa:44:a6:39:80:2c:38:7c:89:cd:d9:a3: ++ 99:ec:e8:2b:48:6d:84:41:3d:0e:1a:1f:68:5e:17: ++ 88:8f:a5:da:4d:1c:36:26:ae:b4:7e:d2:fe:a2:59: ++ d5:67:3a:56:c2:21:65:0d:dd:97:6f:f0:e5:b4:1e: ++ 87:ae:97:35:0d:f4:9b:ae:dc:8a:3e:28:aa:b8:a2: ++ ab:ee:9d:b2:c5:91:f6:71:99:a5:86:cb:31:9c:05: ++ d6:9b:94:13:46:a9:9a:c9:a5:55:5f:6c:cc:d0:84: ++ 27:e2:b1:b5:73:39:08:7f:80:2f:04:26:96:0c:8d: ++ 29:9b:be:5e:cc:39:af:a2:db:82:82:57:07:e6:b2: ++ 4a:d9:3d:c8:79:6e:67:61:f3:48:37:a8:4f:9f:b3: ++ cf:84:b6:50:08:3d:e9:85:e9:a9:76:50:80:e7:2c: ++ 6f:65:95:cb:e2:23:41:58:39:70:e7:78:29:3d:c2: ++ d6:20:7c:2b:87:30:bd:98:87:63:ed:4a:ad:b9:ed: ++ 7a:4b:13:a1:3d:62:5e:b6:74:64:ef:25:a3:dd:93: ++ 47:aa:d3:25:7e:2a:d7:09:1b:5c:59:50:f1:d4:c6: ++ 9c:f2:64:8a:7c:cb:cc:52:37:50:88:4b:84:35:40: ++ 51:0e:a1:06:a2:60:b6:b0:e3:8f:f9:d8:8e:45:77: ++ 7d:0e:7d:11:92:22:15:0f:a3:37:84:c4:25:dc:14: ++ b4:20:7a:b7:16:96:72:d4:bf:4d:5d:d2:ab:71:43: ++ 44:be:87:44:d2:b8:74:f7:86:3f:d2:5d:dd:5e:e6: ++ 74:ab:fb:cc:a3:5d:a6:84:80:0b ++ Exponent: 65537 (0x10001) ++ X509v3 extensions: ++ X509v3 Subject Alternative Name: ++ DNS:srv01.crt01.example.nil, IP Address:10.53.0.1 ++ Signature Algorithm: sha256WithRSAEncryption ++ 94:15:c0:4a:f1:aa:15:30:f7:cb:fe:f9:fa:ba:5f:f0:18:1f: ++ 7e:44:9a:b1:d4:9c:f9:78:d3:a7:c7:65:f2:d1:48:62:f4:cb: ++ 2f:20:ea:7c:af:08:cf:db:e2:0f:ab:c0:22:38:16:c5:0c:e5: ++ c7:6e:34:b1:ed:f6:02:1a:69:c0:09:d1:43:b3:30:77:fc:00: ++ 07:1b:da:88:97:5b:28:4e:e6:92:ca:00:cc:86:66:a9:a9:0a: ++ 75:be:74:88:7d:09:52:e7:a9:82:8f:a9:62:5e:b3:19:64:14: ++ e5:54:9e:6d:9c:98:39:8b:1f:92:92:59:f9:a2:46:75:96:11: ++ 71:8a:c8:71:05:10:2a:b8:f3:a4:19:db:eb:05:17:0a:dd:98: ++ 2c:58:54:3a:7f:8c:c2:26:9e:62:ca:04:dd:3c:99:1f:a0:64: ++ 69:fb:d6:04:c1:0b:8c:62:f6:2d:ea:bc:6c:a9:39:7b:f1:20: ++ b8:b7:04:3c:a7:65:fa:1f:db:22:e2:5b:8b:91:75:60:be:e1: ++ 1e:50:13:23:d5:4b:93:87:20:ec:46:6f:5f:94:dc:b1:60:d1: ++ 79:4b:5e:76:c9:6d:0d:be:a6:9a:6b:67:8b:a7:48:7e:51:b5: ++ 9b:9d:ec:a6:0c:c1:b3:d9:0b:26:8b:f2:7c:cf:61:d0:a2:a0: ++ 90:90:18:6b:b4:ca:56:b8:5e:5a:8b:78:71:c4:d1:fc:15:30: ++ 0a:03:26:74:85:3d:6c:ed:d3:e1:c9:c1:b0:d4:0c:b9:f3:04: ++ 93:0d:e3:a6:2c:a7:ee:e0:24:0d:dd:37:fc:6b:09:d5:b5:55: ++ 33:12:82:cf:f2:ba:0f:b0:e2:ce:f7:c0:ac:2c:7f:ab:f9:dd: ++ 87:b1:9b:95:f2:d7:32:98:dd:4c:b3:28:b7:0d:2b:2f:62:65: ++ ce:59:fb:95:d4:5f:9d:fd:83:5a:01:3b:5f:48:5f:3c:fa:4b: ++ 52:91:66:e1:49:8e:cd:09:78:f5:ce:f8:cd:5c:85:3e:ad:bd: ++ 1c:4e:e0:3f:0a:8b ++-----BEGIN CERTIFICATE----- ++MIIETzCCAregAwIBAgIIcLn06y+hlZgwDQYJKoZIhvcNAQELBQAwfTELMAkGA1UE ++BhMCVUExGDAWBgNVBAgMD0toYXJraXYgT2JsYXN0JzEQMA4GA1UEBwwHS2hhcmtp ++djEkMCIGA1UECgwbSW50ZXJuZXQgU3lzdGVtcyBDb25zb3J0aXVtMRwwGgYDVQQD ++DBNjYS50ZXN0LmV4YW1wbGUuY29tMCAXDTIyMDkwNzIwMjgwM1oYDzIwNTIwODMw ++MjAyODAzWjAiMSAwHgYDVQQDDBdzcnYwMS5jcnQwMS5leGFtcGxlLm5pbDCCAaIw ++DQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBALSaY5gErb2rKb8icFQw38drd124 ++XgvNDqBsdDfnS3jRltrKmX2SseQaCh60HL7uzJWMUgOTheFAQ2iGhrxqYm3WCsru ++T5Mt7mvfevbc+kSmOYAsOHyJzdmjmezoK0hthEE9DhofaF4XiI+l2k0cNiautH7S ++/qJZ1Wc6VsIhZQ3dl2/w5bQeh66XNQ30m67cij4oqriiq+6dssWR9nGZpYbLMZwF ++1puUE0apmsmlVV9szNCEJ+KxtXM5CH+ALwQmlgyNKZu+Xsw5r6LbgoJXB+ayStk9 ++yHluZ2HzSDeoT5+zz4S2UAg96YXpqXZQgOcsb2WVy+IjQVg5cOd4KT3C1iB8K4cw ++vZiHY+1KrbnteksToT1iXrZ0ZO8lo92TR6rTJX4q1wkbXFlQ8dTGnPJkinzLzFI3 ++UIhLhDVAUQ6hBqJgtrDjj/nYjkV3fQ59EZIiFQ+jN4TEJdwUtCB6txaWctS/TV3S ++q3FDRL6HRNK4dPeGP9Jd3V7mdKv7zKNdpoSACwIDAQABoywwKjAoBgNVHREEITAf ++ghdzcnYwMS5jcnQwMS5leGFtcGxlLm5pbIcECjUAATANBgkqhkiG9w0BAQsFAAOC ++AYEAlBXASvGqFTD3y/75+rpf8BgffkSasdSc+XjTp8dl8tFIYvTLLyDqfK8Iz9vi ++D6vAIjgWxQzlx240se32AhppwAnRQ7Mwd/wABxvaiJdbKE7mksoAzIZmqakKdb50 ++iH0JUuepgo+pYl6zGWQU5VSebZyYOYsfkpJZ+aJGdZYRcYrIcQUQKrjzpBnb6wUX ++Ct2YLFhUOn+MwiaeYsoE3TyZH6BkafvWBMELjGL2Leq8bKk5e/EguLcEPKdl+h/b ++IuJbi5F1YL7hHlATI9VLk4cg7EZvX5TcsWDReUtedsltDb6mmmtni6dIflG1m53s ++pgzBs9kLJovyfM9h0KKgkJAYa7TKVrheWot4ccTR/BUwCgMmdIU9bO3T4cnBsNQM ++ufMEkw3jpiyn7uAkDd03/GsJ1bVVMxKCz/K6D7DizvfArCx/q/ndh7GblfLXMpjd ++TLMotw0rL2Jlzln7ldRfnf2DWgE7X0hfPPpLUpFm4UmOzQl49c74zVyFPq29HE7g ++PwqL ++-----END CERTIFICATE----- +diff --git a/bin/tests/system/nsupdate/CA/newcerts/70B9F4EB2FA19599.pem b/bin/tests/system/nsupdate/CA/newcerts/70B9F4EB2FA19599.pem +new file mode 100644 +index 00000000000..3fa0b9ae881 +--- /dev/null ++++ b/bin/tests/system/nsupdate/CA/newcerts/70B9F4EB2FA19599.pem +@@ -0,0 +1,93 @@ ++Certificate: ++ Data: ++ Version: 3 (0x2) ++ Serial Number: 8122792693893010841 (0x70b9f4eb2fa19599) ++ Signature Algorithm: sha256WithRSAEncryption ++ Issuer: C=UA, ST=Kharkiv Oblast', L=Kharkiv, O=Internet Systems Consortium, CN=ca.test.example.com ++ Validity ++ Not Before: Sep 6 20:34:09 2022 GMT ++ Not After : Sep 7 20:34:09 2022 GMT ++ Subject: CN=srv01.crt02-expired.example.nil ++ Subject Public Key Info: ++ Public Key Algorithm: rsaEncryption ++ RSA Public-Key: (3072 bit) ++ Modulus: ++ 00:ec:2c:88:01:b5:8b:3a:74:56:0d:57:b3:75:fd: ++ 05:58:05:ed:8a:ab:e8:29:0e:f1:52:34:2e:22:62: ++ 6e:41:74:ff:78:33:b4:ff:15:73:fa:ce:90:10:a4: ++ fe:d2:66:14:7b:0b:79:7b:d6:20:88:f9:41:31:14: ++ 9a:49:36:8c:38:74:4b:f3:e2:51:e7:e5:6f:bd:65: ++ 38:e6:9c:30:80:3f:24:56:f6:68:9e:09:76:81:5b: ++ 59:81:44:56:9f:1c:3f:48:f0:95:bf:60:40:29:df: ++ ac:42:3d:c3:6f:85:2d:c3:0e:08:b6:f7:12:2a:51: ++ 00:bf:cf:fe:6c:ae:d7:7d:de:c1:72:f8:32:03:5f: ++ c9:3f:4a:de:e5:fa:24:90:46:f0:4a:5f:09:d8:93: ++ 4c:bf:1c:61:4c:d2:dc:db:6c:f8:af:73:5b:b7:3b: ++ 7a:e8:6d:1c:bb:26:23:47:87:fd:50:06:0f:f1:b5: ++ 88:8a:a8:25:69:57:e3:46:3b:d2:6b:52:fb:5a:01: ++ f6:96:e9:2a:cf:13:e7:16:4c:fd:5a:f6:1f:0b:8d: ++ f7:25:a3:68:d7:15:fc:5c:48:49:05:e2:85:24:70: ++ 57:b1:d8:05:24:ae:26:3a:00:9b:72:a8:47:05:c5: ++ f3:7c:2d:f2:58:72:37:fb:c1:8b:4f:42:8f:dd:9a: ++ ac:5b:ae:6f:21:62:ad:29:81:b9:8b:4b:6c:ff:61: ++ 99:0f:7c:09:d3:6d:00:20:2d:b1:0c:00:6c:99:4c: ++ 92:dc:0e:11:2d:e7:ba:7b:c7:c8:b1:a3:1a:61:f8: ++ cc:2c:af:17:b6:db:cc:36:02:fe:fb:66:15:77:84: ++ 70:cd:42:25:b7:16:64:28:ae:9d:8c:81:85:a0:e0: ++ 50:82:aa:e8:e9:ac:51:fc:2b:63:44:b1:08:b8:90: ++ d7:8c:1c:23:b2:1b:08:59:85:d5:dd:39:44:f7:47: ++ 5e:48:08:34:eb:2c:df:75:47:08:b6:b6:e6:32:ed: ++ 76:74:77:ce:3d:4d:fe:02:b1:33 ++ Exponent: 65537 (0x10001) ++ X509v3 extensions: ++ X509v3 Subject Alternative Name: ++ DNS:srv01.crt02-expired.example.nil, IP Address:10.53.0.1 ++ Signature Algorithm: sha256WithRSAEncryption ++ 2a:52:c4:cb:a9:2f:f7:2b:ed:04:b5:03:d5:06:59:ed:5c:7c: ++ b7:00:9e:c4:33:90:fe:d0:b0:18:f3:f2:06:30:54:18:fe:34: ++ cb:ea:61:4f:9c:23:67:3c:ae:ed:20:df:82:52:ec:59:88:45: ++ ad:3c:6c:a7:34:24:1c:4d:66:ab:71:3d:59:8c:ef:cd:a0:e2: ++ 7b:59:2d:43:94:cd:f5:0a:3c:4e:81:24:e8:fd:c6:d0:fd:ad: ++ 6f:cc:29:5b:67:0b:b7:ee:43:38:a4:91:c2:d9:3b:f8:d6:97: ++ bc:92:dd:ec:a1:ab:85:35:44:f4:0a:df:ad:8d:8c:52:c3:49: ++ 7e:39:10:a1:13:43:78:71:e2:92:aa:31:3d:d9:94:15:7f:86: ++ c8:aa:b4:a1:6d:bf:eb:55:b1:d7:41:6f:c3:7d:88:5e:9c:b7: ++ b1:4b:0d:a7:17:4f:3e:4a:46:3f:6f:48:27:8c:d0:e5:51:fc: ++ 42:ba:c5:b9:4f:63:6f:2e:f2:fd:0c:c0:6e:23:b4:59:93:68: ++ a4:2d:16:ce:f4:7b:3a:45:1d:a0:6e:98:0b:f7:6a:e6:75:0c: ++ db:56:19:6b:88:f0:7f:6b:08:f8:fc:bb:d1:3f:25:25:1a:6c: ++ 8e:34:cb:91:18:54:d5:2d:ce:9c:d0:b7:c3:bc:b5:0a:e0:b9: ++ 73:6f:4d:ad:6b:3c:b6:49:ef:c0:10:13:c7:0a:78:4d:98:7d: ++ cb:84:a1:29:40:8c:dd:31:7d:ae:c4:f5:25:5d:b9:74:b2:f5: ++ e2:2b:e0:43:c8:50:61:a3:a8:26:1a:03:ab:1a:24:3b:13:56: ++ da:0d:ee:ff:2f:bd:d5:77:82:72:63:b8:aa:e1:18:f7:3b:c1: ++ a1:f8:51:b1:70:b9:25:39:df:a3:41:79:d7:2b:ec:32:f6:cb: ++ 30:28:d2:1e:f1:b4:e1:80:03:9f:c2:0f:36:85:82:5e:39:ba: ++ 9e:eb:67:76:42:93:bf:e0:df:64:b2:b5:5f:98:a1:45:3f:4a: ++ 1f:5c:c5:04:10:f6 ++-----BEGIN CERTIFICATE----- ++MIIEXTCCAsWgAwIBAgIIcLn06y+hlZkwDQYJKoZIhvcNAQELBQAwfTELMAkGA1UE ++BhMCVUExGDAWBgNVBAgMD0toYXJraXYgT2JsYXN0JzEQMA4GA1UEBwwHS2hhcmtp ++djEkMCIGA1UECgwbSW50ZXJuZXQgU3lzdGVtcyBDb25zb3J0aXVtMRwwGgYDVQQD ++DBNjYS50ZXN0LmV4YW1wbGUuY29tMB4XDTIyMDkwNjIwMzQwOVoXDTIyMDkwNzIw ++MzQwOVowKjEoMCYGA1UEAwwfc3J2MDEuY3J0MDItZXhwaXJlZC5leGFtcGxlLm5p ++bDCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBAOwsiAG1izp0Vg1Xs3X9 ++BVgF7Yqr6CkO8VI0LiJibkF0/3gztP8Vc/rOkBCk/tJmFHsLeXvWIIj5QTEUmkk2 ++jDh0S/PiUeflb71lOOacMIA/JFb2aJ4JdoFbWYFEVp8cP0jwlb9gQCnfrEI9w2+F ++LcMOCLb3EipRAL/P/myu133ewXL4MgNfyT9K3uX6JJBG8EpfCdiTTL8cYUzS3Nts +++K9zW7c7euhtHLsmI0eH/VAGD/G1iIqoJWlX40Y70mtS+1oB9pbpKs8T5xZM/Vr2 ++HwuN9yWjaNcV/FxISQXihSRwV7HYBSSuJjoAm3KoRwXF83wt8lhyN/vBi09Cj92a ++rFuubyFirSmBuYtLbP9hmQ98CdNtACAtsQwAbJlMktwOES3nunvHyLGjGmH4zCyv ++F7bbzDYC/vtmFXeEcM1CJbcWZCiunYyBhaDgUIKq6OmsUfwrY0SxCLiQ14wcI7Ib ++CFmF1d05RPdHXkgINOss33VHCLa25jLtdnR3zj1N/gKxMwIDAQABozQwMjAwBgNV ++HREEKTAngh9zcnYwMS5jcnQwMi1leHBpcmVkLmV4YW1wbGUubmlshwQKNQABMA0G ++CSqGSIb3DQEBCwUAA4IBgQAqUsTLqS/3K+0EtQPVBlntXHy3AJ7EM5D+0LAY8/IG ++MFQY/jTL6mFPnCNnPK7tIN+CUuxZiEWtPGynNCQcTWarcT1ZjO/NoOJ7WS1DlM31 ++CjxOgSTo/cbQ/a1vzClbZwu37kM4pJHC2Tv41pe8kt3soauFNUT0Ct+tjYxSw0l+ ++ORChE0N4ceKSqjE92ZQVf4bIqrShbb/rVbHXQW/DfYhenLexSw2nF08+SkY/b0gn ++jNDlUfxCusW5T2NvLvL9DMBuI7RZk2ikLRbO9Hs6RR2gbpgL92rmdQzbVhlriPB/ ++awj4/LvRPyUlGmyONMuRGFTVLc6c0LfDvLUK4Llzb02tazy2Se/AEBPHCnhNmH3L ++hKEpQIzdMX2uxPUlXbl0svXiK+BDyFBho6gmGgOrGiQ7E1baDe7/L73Vd4JyY7iq ++4Rj3O8Gh+FGxcLklOd+jQXnXK+wy9sswKNIe8bThgAOfwg82hYJeObqe62d2QpO/ ++4N9ksrVfmKFFP0ofXMUEEPY= ++-----END CERTIFICATE----- +diff --git a/bin/tests/system/nsupdate/CA/newcerts/70B9F4EB2FA1959A.pem b/bin/tests/system/nsupdate/CA/newcerts/70B9F4EB2FA1959A.pem +new file mode 100644 +index 00000000000..f546d35e7d6 +--- /dev/null ++++ b/bin/tests/system/nsupdate/CA/newcerts/70B9F4EB2FA1959A.pem +@@ -0,0 +1,93 @@ ++Certificate: ++ Data: ++ Version: 3 (0x2) ++ Serial Number: 8122792693893010842 (0x70b9f4eb2fa1959a) ++ Signature Algorithm: sha256WithRSAEncryption ++ Issuer: C=UA, ST=Kharkiv Oblast', L=Kharkiv, O=Internet Systems Consortium, CN=ca.test.example.com ++ Validity ++ Not Before: Sep 8 08:20:17 2022 GMT ++ Not After : Aug 31 08:20:17 2052 GMT ++ Subject: CN=srv01.client01.example.nil ++ Subject Public Key Info: ++ Public Key Algorithm: rsaEncryption ++ RSA Public-Key: (3072 bit) ++ Modulus: ++ 00:ab:60:2e:9c:61:e3:89:c6:52:2b:bc:e9:e1:05: ++ fd:18:65:42:20:f6:56:16:40:33:d2:cb:9f:f7:ef: ++ 22:54:a7:c9:55:70:ca:52:f0:e2:a2:58:38:7f:10: ++ ad:2b:05:e0:11:b6:69:21:7f:2d:38:56:dd:d5:e4: ++ f3:de:a7:32:35:f7:33:2a:52:80:ae:b7:d6:7c:35: ++ 74:c3:0c:8a:c3:3a:18:61:68:73:62:58:56:ff:78: ++ 25:57:1c:7b:be:98:88:21:dd:1c:8a:13:a5:9a:52: ++ 48:98:d9:3d:c4:28:a6:7e:9b:11:56:7e:ce:09:bb: ++ 51:89:8a:a8:1b:00:b5:73:2b:41:93:b1:62:40:30: ++ 29:ea:f6:a3:e7:bc:f0:e9:9e:07:2b:ae:a9:a0:1d: ++ 4d:d9:f8:18:4d:83:47:4e:68:ee:57:c8:55:15:86: ++ 3c:6d:1e:f5:31:f1:de:cf:c2:7e:6b:8e:22:5a:c5: ++ 76:af:d0:01:de:ab:7a:03:b2:96:33:cc:a0:26:ae: ++ de:c4:bd:76:85:96:c7:88:e4:46:bc:3f:c6:54:c9: ++ 95:83:87:9c:49:0d:31:dd:c4:17:52:99:e4:65:49: ++ 9b:9d:f3:ad:ce:66:08:57:f4:83:be:5e:87:da:42: ++ 5a:01:2a:6d:68:d1:8d:38:d9:18:ae:5e:2e:54:72: ++ 8b:01:45:96:af:f5:a3:d0:29:5d:22:8b:b4:d4:30: ++ af:02:36:c5:2d:e9:29:eb:2c:ea:6a:7e:27:b3:70: ++ fc:87:1f:2b:c4:b1:3a:a6:c2:e9:b7:c2:6f:46:63: ++ b7:96:2e:53:d8:b7:cd:c3:f4:b5:6d:b2:fc:57:49: ++ ac:9f:98:c9:fe:b4:f5:7c:93:48:2e:93:dc:e9:18: ++ 54:63:5f:18:a3:e7:12:aa:fe:38:f0:73:e5:17:1e: ++ fe:40:65:81:a8:8f:60:46:c2:16:f2:a8:9d:b1:1b: ++ bc:ce:05:de:37:b2:a8:86:47:bd:8d:92:de:e0:e5: ++ 42:89:b8:e3:f8:b1:24:08:7e:99 ++ Exponent: 65537 (0x10001) ++ X509v3 extensions: ++ X509v3 Subject Alternative Name: ++ DNS:srv01.client01.example.nil, IP Address:10.53.0.1 ++ Signature Algorithm: sha256WithRSAEncryption ++ 07:97:69:51:12:50:6a:e1:02:a0:b0:dc:93:75:16:c4:38:0f: ++ 5c:b3:47:da:bf:fa:9c:b6:de:c0:ef:38:f7:cc:d9:8d:71:ba: ++ 51:89:e5:48:36:dd:e1:f8:73:9d:92:80:1c:42:30:69:4f:8c: ++ 19:5d:f7:1d:03:e4:f2:76:e0:58:7b:c2:76:c4:0a:7e:20:69: ++ 26:6c:3e:cb:31:45:93:1d:07:5f:45:44:8e:5a:fb:87:17:7b: ++ 4d:5c:bf:37:bd:5e:ba:5c:22:84:bf:26:21:4a:c4:e9:f9:cb: ++ 73:de:fc:62:04:96:ad:aa:fd:89:09:5c:74:d6:bd:5f:07:17: ++ ef:9c:3d:ee:b7:dc:08:11:7f:12:66:ab:c4:ff:43:6d:7f:1e: ++ 01:b6:d1:19:73:53:18:e4:02:b0:7c:9e:99:63:d8:57:dd:07: ++ 79:fb:83:39:09:de:76:6e:68:b7:87:81:13:b8:26:e5:1c:c9: ++ a0:23:e5:97:39:ff:93:c7:8d:08:d8:ce:97:34:fc:ad:22:14: ++ 89:c0:ae:83:7d:0a:3f:cf:a0:9b:b4:6a:5c:b3:6d:5d:3b:88: ++ ca:1e:9b:99:54:64:57:58:3c:4c:bd:26:ee:11:c3:13:0b:1d: ++ f5:fd:d9:37:b0:31:72:6f:1d:e8:ba:43:37:46:f7:71:fe:6d: ++ 4a:30:33:29:c5:7b:37:8b:7e:06:22:89:a4:46:36:f0:fe:c6: ++ f5:f0:53:04:c0:35:52:78:6e:10:24:3a:d8:bf:7b:13:2f:98: ++ bc:69:31:41:68:02:5a:c4:f9:11:a2:6b:3f:c8:e0:d4:b3:80: ++ af:d2:be:fe:28:70:61:18:ed:8a:de:c4:cb:da:c9:60:94:91: ++ 76:63:69:8c:6e:96:f5:ba:e7:be:1e:1c:c3:84:b1:8d:e8:31: ++ f7:66:8c:0d:da:a8:78:57:19:fd:a0:8d:fa:9a:7e:51:1c:d1: ++ d0:84:07:a2:45:40:2d:c4:6b:e9:9f:86:4a:08:20:8f:9c:79: ++ 97:e3:7f:2a:14:73 ++-----BEGIN CERTIFICATE----- ++MIIEVTCCAr2gAwIBAgIIcLn06y+hlZowDQYJKoZIhvcNAQELBQAwfTELMAkGA1UE ++BhMCVUExGDAWBgNVBAgMD0toYXJraXYgT2JsYXN0JzEQMA4GA1UEBwwHS2hhcmtp ++djEkMCIGA1UECgwbSW50ZXJuZXQgU3lzdGVtcyBDb25zb3J0aXVtMRwwGgYDVQQD ++DBNjYS50ZXN0LmV4YW1wbGUuY29tMCAXDTIyMDkwODA4MjAxN1oYDzIwNTIwODMx ++MDgyMDE3WjAlMSMwIQYDVQQDDBpzcnYwMS5jbGllbnQwMS5leGFtcGxlLm5pbDCC ++AaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBAKtgLpxh44nGUiu86eEF/Rhl ++QiD2VhZAM9LLn/fvIlSnyVVwylLw4qJYOH8QrSsF4BG2aSF/LThW3dXk896nMjX3 ++MypSgK631nw1dMMMisM6GGFoc2JYVv94JVcce76YiCHdHIoTpZpSSJjZPcQopn6b ++EVZ+zgm7UYmKqBsAtXMrQZOxYkAwKer2o+e88OmeByuuqaAdTdn4GE2DR05o7lfI ++VRWGPG0e9THx3s/CfmuOIlrFdq/QAd6regOyljPMoCau3sS9doWWx4jkRrw/xlTJ ++lYOHnEkNMd3EF1KZ5GVJm53zrc5mCFf0g75eh9pCWgEqbWjRjTjZGK5eLlRyiwFF ++lq/1o9ApXSKLtNQwrwI2xS3pKess6mp+J7Nw/IcfK8SxOqbC6bfCb0Zjt5YuU9i3 ++zcP0tW2y/FdJrJ+Yyf609XyTSC6T3OkYVGNfGKPnEqr+OPBz5Rce/kBlgaiPYEbC ++FvKonbEbvM4F3jeyqIZHvY2S3uDlQom44/ixJAh+mQIDAQABoy8wLTArBgNVHREE ++JDAighpzcnYwMS5jbGllbnQwMS5leGFtcGxlLm5pbIcECjUAATANBgkqhkiG9w0B ++AQsFAAOCAYEAB5dpURJQauECoLDck3UWxDgPXLNH2r/6nLbewO8498zZjXG6UYnl ++SDbd4fhznZKAHEIwaU+MGV33HQPk8nbgWHvCdsQKfiBpJmw+yzFFkx0HX0VEjlr7 ++hxd7TVy/N71eulwihL8mIUrE6fnLc978YgSWrar9iQlcdNa9XwcX75w97rfcCBF/ ++EmarxP9DbX8eAbbRGXNTGOQCsHyemWPYV90HefuDOQnedm5ot4eBE7gm5RzJoCPl ++lzn/k8eNCNjOlzT8rSIUicCug30KP8+gm7RqXLNtXTuIyh6bmVRkV1g8TL0m7hHD ++Ewsd9f3ZN7Axcm8d6LpDN0b3cf5tSjAzKcV7N4t+BiKJpEY28P7G9fBTBMA1Unhu ++ECQ62L97Ey+YvGkxQWgCWsT5EaJrP8jg1LOAr9K+/ihwYRjtit7Ey9rJYJSRdmNp ++jG6W9brnvh4cw4Sxjegx92aMDdqoeFcZ/aCN+pp+URzR0IQHokVALcRr6Z+GSggg ++j5x5l+N/KhRz ++-----END CERTIFICATE----- +diff --git a/bin/tests/system/nsupdate/CA/newcerts/70B9F4EB2FA1959B.pem b/bin/tests/system/nsupdate/CA/newcerts/70B9F4EB2FA1959B.pem +new file mode 100644 +index 00000000000..365b493f7e3 +--- /dev/null ++++ b/bin/tests/system/nsupdate/CA/newcerts/70B9F4EB2FA1959B.pem +@@ -0,0 +1,93 @@ ++Certificate: ++ Data: ++ Version: 3 (0x2) ++ Serial Number: 8122792693893010843 (0x70b9f4eb2fa1959b) ++ Signature Algorithm: sha256WithRSAEncryption ++ Issuer: C=UA, ST=Kharkiv Oblast', L=Kharkiv, O=Internet Systems Consortium, CN=ca.test.example.com ++ Validity ++ Not Before: Sep 7 08:14:18 2022 GMT ++ Not After : Sep 8 08:14:18 2022 GMT ++ Subject: CN=srv01.client02-expired.example.nil ++ Subject Public Key Info: ++ Public Key Algorithm: rsaEncryption ++ RSA Public-Key: (3072 bit) ++ Modulus: ++ 00:c0:11:27:17:25:3a:ad:85:a0:3b:59:0b:22:64: ++ 63:7d:bb:05:32:35:4f:68:d5:19:2b:cd:46:bd:e2: ++ b6:42:8c:08:cf:09:0d:a8:cd:58:d9:1b:77:db:17: ++ 8a:fc:f0:55:f2:e1:50:f4:fd:90:aa:49:15:5d:ea: ++ 9b:5a:47:c4:2f:82:07:46:87:f6:05:ef:15:02:a4: ++ 3c:a1:da:fc:5b:75:36:12:f7:12:50:55:f8:be:0c: ++ 7d:21:91:e2:92:d8:41:3f:71:fe:b2:17:c0:68:1d: ++ 09:be:fc:c4:24:ec:ef:d2:5c:52:a9:4f:d6:5d:30: ++ b8:ab:68:2e:39:e9:8b:5b:c6:f0:64:42:f7:b8:bd: ++ b2:90:32:22:68:bc:38:70:2f:14:ae:c8:7c:63:04: ++ d5:11:b2:0a:f1:8e:13:10:b2:3b:69:f4:fe:3a:e2: ++ f1:58:56:28:93:c1:28:aa:a7:19:c9:91:12:43:f8: ++ f5:1d:34:58:3d:32:9f:11:67:d1:1f:53:d4:e0:d5: ++ 0c:78:2c:6f:38:3f:e1:89:69:b5:09:3c:12:f4:a9: ++ ee:e5:2f:c5:47:65:a6:82:fa:ea:78:48:31:89:11: ++ b6:23:8a:27:ed:7c:1d:6d:e8:ab:a0:29:de:40:f4: ++ f2:9b:61:22:da:9c:22:32:f7:3d:f8:4c:e1:38:a7: ++ e2:c3:af:a4:67:7f:94:a4:fd:52:25:89:4d:f4:9a: ++ d6:35:ba:98:20:f1:4b:c9:a5:cf:ac:72:58:2a:cd: ++ 3b:4a:3e:e9:04:31:e2:9a:74:32:d5:52:60:34:ad: ++ 0c:85:02:65:58:41:74:2a:57:91:34:55:36:a9:14: ++ 5b:45:cc:28:27:d7:6d:ba:55:a3:dd:9f:00:04:a4: ++ 43:c2:af:5c:af:86:53:a6:d5:a7:49:aa:31:d6:5e: ++ 92:7d:26:dd:8d:f4:87:8a:9b:48:e8:25:f4:c7:34: ++ ca:cf:e3:f7:84:19:3b:43:c7:6a:b8:da:6e:6f:85: ++ af:8d:0c:fb:7c:ea:c7:73:9c:9b ++ Exponent: 65537 (0x10001) ++ X509v3 extensions: ++ X509v3 Subject Alternative Name: ++ DNS:srv01.client02-expired.example.nil, IP Address:10.53.0.1 ++ Signature Algorithm: sha256WithRSAEncryption ++ 18:f1:7c:24:5b:d2:03:b0:60:0e:60:e6:32:f9:a7:47:d1:e4: ++ bd:3f:a3:21:53:90:84:9a:c6:2c:87:b2:16:28:95:07:a3:2a: ++ c3:33:8f:60:70:3f:26:58:be:ec:a2:6c:44:89:d3:4e:ef:bb: ++ ce:af:9b:5f:15:06:03:21:74:e3:6f:2a:dc:5c:19:4e:d3:cb: ++ ba:c3:5f:d8:76:89:59:50:82:69:5f:a1:ac:9f:be:79:e1:22: ++ 12:37:f9:d3:2e:00:35:03:03:9d:08:24:45:65:7a:e9:72:31: ++ e1:67:44:32:17:25:dd:b9:72:eb:c6:40:d7:5d:8d:5f:00:48: ++ 07:09:0d:3c:4c:a1:f1:05:4b:05:9b:2b:5a:21:09:46:f4:17: ++ 7a:cf:34:87:ad:bf:ef:bd:56:74:d7:1a:8f:07:ce:70:b1:aa: ++ 4d:82:4f:08:dc:56:27:f9:21:20:b8:06:c7:29:b4:8e:36:82: ++ b8:43:85:1c:2d:9f:be:2d:b9:9d:40:de:52:55:6a:2e:0b:28: ++ 33:fc:f8:1b:70:e9:c5:46:50:f3:05:be:8d:ed:99:ec:f1:8c: ++ 51:8a:1c:4b:95:f4:c4:dd:cd:42:74:bc:6f:66:64:54:b8:c1: ++ 6e:c8:3d:e9:fe:10:02:61:50:77:38:b9:b0:b8:13:37:8f:0e: ++ 5b:49:92:3a:9d:9a:60:51:68:99:8a:d5:7e:92:71:7e:fa:db: ++ 52:37:4d:f9:0d:6c:3b:79:a3:b9:16:b7:95:00:ea:eb:17:54: ++ e2:50:d7:a5:08:54:58:2c:79:66:01:4b:95:65:ed:b8:81:f7: ++ 4c:fa:f8:89:37:ad:d9:dc:c9:75:9d:02:3e:e5:92:b3:03:ab: ++ 70:69:83:f5:6c:a6:27:7e:2e:fc:9d:b2:59:0a:43:ad:3f:55: ++ 2f:5d:ec:ef:52:f0:3e:be:b5:d6:e2:c3:91:9d:dd:5d:e1:9e: ++ e6:18:90:0b:6a:85:f8:e3:83:2a:7c:91:c3:52:1c:6d:aa:2b: ++ 44:b8:6f:2b:af:6e ++-----BEGIN CERTIFICATE----- ++MIIEYzCCAsugAwIBAgIIcLn06y+hlZswDQYJKoZIhvcNAQELBQAwfTELMAkGA1UE ++BhMCVUExGDAWBgNVBAgMD0toYXJraXYgT2JsYXN0JzEQMA4GA1UEBwwHS2hhcmtp ++djEkMCIGA1UECgwbSW50ZXJuZXQgU3lzdGVtcyBDb25zb3J0aXVtMRwwGgYDVQQD ++DBNjYS50ZXN0LmV4YW1wbGUuY29tMB4XDTIyMDkwNzA4MTQxOFoXDTIyMDkwODA4 ++MTQxOFowLTErMCkGA1UEAwwic3J2MDEuY2xpZW50MDItZXhwaXJlZC5leGFtcGxl ++Lm5pbDCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBAMARJxclOq2FoDtZ ++CyJkY327BTI1T2jVGSvNRr3itkKMCM8JDajNWNkbd9sXivzwVfLhUPT9kKpJFV3q ++m1pHxC+CB0aH9gXvFQKkPKHa/Ft1NhL3ElBV+L4MfSGR4pLYQT9x/rIXwGgdCb78 ++xCTs79JcUqlP1l0wuKtoLjnpi1vG8GRC97i9spAyImi8OHAvFK7IfGME1RGyCvGO ++ExCyO2n0/jri8VhWKJPBKKqnGcmREkP49R00WD0ynxFn0R9T1ODVDHgsbzg/4Ylp ++tQk8EvSp7uUvxUdlpoL66nhIMYkRtiOKJ+18HW3oq6Ap3kD08pthItqcIjL3PfhM ++4Tin4sOvpGd/lKT9UiWJTfSa1jW6mCDxS8mlz6xyWCrNO0o+6QQx4pp0MtVSYDSt ++DIUCZVhBdCpXkTRVNqkUW0XMKCfXbbpVo92fAASkQ8KvXK+GU6bVp0mqMdZekn0m ++3Y30h4qbSOgl9Mc0ys/j94QZO0PHarjabm+Fr40M+3zqx3OcmwIDAQABozcwNTAz ++BgNVHREELDAqgiJzcnYwMS5jbGllbnQwMi1leHBpcmVkLmV4YW1wbGUubmlshwQK ++NQABMA0GCSqGSIb3DQEBCwUAA4IBgQAY8XwkW9IDsGAOYOYy+adH0eS9P6MhU5CE ++msYsh7IWKJUHoyrDM49gcD8mWL7somxEidNO77vOr5tfFQYDIXTjbyrcXBlO08u6 ++w1/YdolZUIJpX6Gsn7554SISN/nTLgA1AwOdCCRFZXrpcjHhZ0QyFyXduXLrxkDX ++XY1fAEgHCQ08TKHxBUsFmytaIQlG9Bd6zzSHrb/vvVZ01xqPB85wsapNgk8I3FYn +++SEguAbHKbSONoK4Q4UcLZ++LbmdQN5SVWouCygz/PgbcOnFRlDzBb6N7Zns8YxR ++ihxLlfTE3c1CdLxvZmRUuMFuyD3p/hACYVB3OLmwuBM3jw5bSZI6nZpgUWiZitV+ ++knF++ttSN035DWw7eaO5FreVAOrrF1TiUNelCFRYLHlmAUuVZe24gfdM+viJN63Z ++3Ml1nQI+5ZKzA6twaYP1bKYnfi78nbJZCkOtP1UvXezvUvA+vrXW4sORnd1d4Z7m ++GJALaoX444MqfJHDUhxtqitEuG8rr24= ++-----END CERTIFICATE----- +diff --git a/bin/tests/system/nsupdate/CA/private/CA-other.key b/bin/tests/system/nsupdate/CA/private/CA-other.key +new file mode 100644 +index 00000000000..41818aacd8a +--- /dev/null ++++ b/bin/tests/system/nsupdate/CA/private/CA-other.key +@@ -0,0 +1,39 @@ ++-----BEGIN RSA PRIVATE KEY----- ++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 ++-----END RSA PRIVATE KEY----- +diff --git a/bin/tests/system/nsupdate/CA/private/CA.key b/bin/tests/system/nsupdate/CA/private/CA.key +new file mode 100644 +index 00000000000..2d5419d89a3 +--- /dev/null ++++ b/bin/tests/system/nsupdate/CA/private/CA.key +@@ -0,0 +1,39 @@ ++-----BEGIN RSA PRIVATE KEY----- ++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 ++-----END RSA PRIVATE KEY----- +diff --git a/bin/tests/system/nsupdate/CA/serial b/bin/tests/system/nsupdate/CA/serial +new file mode 100644 +index 00000000000..0a263a531a7 +--- /dev/null ++++ b/bin/tests/system/nsupdate/CA/serial +@@ -0,0 +1 @@ ++70B9F4EB2FA1959C +diff --git a/bin/tests/system/nsupdate/dhparam3072.pem b/bin/tests/system/nsupdate/dhparam3072.pem +new file mode 100644 +index 00000000000..9c2e0aa42b8 +--- /dev/null ++++ b/bin/tests/system/nsupdate/dhparam3072.pem +@@ -0,0 +1,11 @@ ++-----BEGIN DH PARAMETERS----- ++MIIBiAKCAYEA5D/Oioe+G+EMf/9RVxmcV4rZAtqZpVTFHcX0ZulvdiQGCQmopm6K ++3+0uoU2J6WVMjhna5nHD2NO9miRDI/jIxX9g9k6PedSB4o3fSTtkAnGtUbB8S+Ab ++EHtWfd7FTES8P1n16HN7BfPXVbP8zTcK+jO63KdQoxueYoETcrw0Myi9Lm8ri8os ++O4oQ+XAH7GzZ60bcYV9jge0XIRUGVnYZDjWMlnwMvZyjLivxKXTC9HPNA6FF1/0H ++0LPhsfjdoLNsVHFzfQz7QELMfHbTd0C8y0UMDQw9FqUp0esHZ5gsTlqnDHp2ZHoR ++JDfNl4yVO5Gv4HiFJ0NSdggefhESU3FRAOhMmUkctOCxk5hyPqGMsvofOajY2MBp ++eCffrKuAU6/dGUeq8inwrZlAMIZ20WyskHmbHnc4DXo2Uo6xSZo3xyEq1ofXXwTZ ++vPw4e12so3RJAT2a8UsHf7DG1tH+9ke7HCAJQWxUizRFRsMi1Nl/7ikS4f3zgIbX ++GKz9+uk5eS6jAgEC ++-----END DH PARAMETERS----- +diff --git a/bin/tests/system/nsupdate/ns1/named.conf.in b/bin/tests/system/nsupdate/ns1/named.conf.in +index 2c1899f17a8..aaf1d9c14ed 100644 +--- a/bin/tests/system/nsupdate/ns1/named.conf.in ++++ b/bin/tests/system/nsupdate/ns1/named.conf.in +@@ -11,14 +11,48 @@ + * information regarding copyright ownership. + */ + ++tls tls-forward-secrecy { ++ protocols { TLSv1.2; }; ++ ciphers "HIGH:!kRSA:!aNULL:!eNULL:!RC4:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS:!SHA1:!SHA256:!SHA384"; ++ prefer-server-ciphers yes; ++ key-file "../CA/certs/srv01.crt01.example.nil.key"; ++ cert-file "../CA/certs/srv01.crt01.example.nil.pem"; ++ dhparam-file "../dhparam3072.pem"; ++}; ++ ++tls tls-forward-secrecy-mutual-tls { ++ protocols { TLSv1.2; }; ++ ciphers "HIGH:!kRSA:!aNULL:!eNULL:!RC4:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS:!SHA1:!SHA256:!SHA384"; ++ prefer-server-ciphers yes; ++ key-file "../CA/certs/srv01.crt01.example.nil.key"; ++ cert-file "../CA/certs/srv01.crt01.example.nil.pem"; ++ dhparam-file "../dhparam3072.pem"; ++ ca-file "../CA/CA.pem"; ++}; ++ ++tls tls-expired { ++ protocols { TLSv1.2; }; ++ ciphers "HIGH:!kRSA:!aNULL:!eNULL:!RC4:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS:!SHA1:!SHA256:!SHA384"; ++ prefer-server-ciphers yes; ++ key-file "../CA/certs/srv01.crt02-expired.example.nil.key"; ++ cert-file "../CA/certs/srv01.crt02-expired.example.nil.pem"; ++ dhparam-file "../dhparam3072.pem"; ++}; ++ ++ + options { + query-source address 10.53.0.1; + notify-source 10.53.0.1; + transfer-source 10.53.0.1; + port @PORT@; ++ tls-port @TLSPORT@; + pid-file "named.pid"; + session-keyfile "session.key"; + listen-on { 10.53.0.1; 127.0.0.1; }; ++ listen-on tls ephemeral { 10.53.0.1; }; ++ listen-on port @EXTRAPORT1@ tls tls-forward-secrecy { 10.53.0.1; }; ++ listen-on port @EXTRAPORT2@ tls tls-forward-secrecy-mutual-tls { 10.53.0.1; }; ++ listen-on port @EXTRAPORT3@ tls tls-expired { 10.53.0.1; }; + listen-on-v6 { none; }; + recursion no; + notify yes; +diff --git a/bin/tests/system/nsupdate/ns10/named.conf.in b/bin/tests/system/nsupdate/ns10/named.conf.in +index 25ba1410f42..51a0b4f5873 100644 +--- a/bin/tests/system/nsupdate/ns10/named.conf.in ++++ b/bin/tests/system/nsupdate/ns10/named.conf.in +@@ -16,9 +16,11 @@ options { + notify-source 10.53.0.10; + transfer-source 10.53.0.10; + port @PORT@; ++ tls-port @TLSPORT@; + pid-file "named.pid"; + session-keyfile "session.key"; + listen-on { 10.53.0.10; }; ++ listen-on tls ephemeral { 10.53.0.10; }; + listen-on-v6 { none; }; + recursion no; + notify yes; +diff --git a/bin/tests/system/nsupdate/tests.sh b/bin/tests/system/nsupdate/tests.sh +index 916f45bc18f..735b659e4d0 100755 +--- a/bin/tests/system/nsupdate/tests.sh ++++ b/bin/tests/system/nsupdate/tests.sh +@@ -1145,7 +1145,182 @@ fi + + n=$((n + 1)) + ret=0 ++echo_i "check DoT (opportunistic-tls) ($n)" ++$NSUPDATE -D -S -O -k ns1/ddns.key <nsupdate.out.test$n 2>&1 || ret=1 ++server 10.53.0.1 ${TLSPORT} ++update add dot-non-auth-client-o.example.nil. 600 A 10.10.10.3 ++send ++END ++sleep 2 ++$DIG $DIGOPTS +short @10.53.0.1 dot-non-auth-client-o.example.nil >dig.out.test$n 2>&1 || ret=1 ++grep -F "10.10.10.3" dig.out.test$n >/dev/null 2>&1 || ret=1 ++if [ $ret -ne 0 ]; then ++ echo_i "failed" ++ status=1 ++fi ++ ++n=$((n + 1)) ++ret=0 ++echo_i "check DoT (strict-tls) with an implicit hostname (by IP address) ($n)" ++$NSUPDATE -D -S -A CA/CA.pem -k ns1/ddns.key <nsupdate.out.test$n 2>&1 || ret=1 ++server 10.53.0.1 ${EXTRAPORT1} ++update add dot-non-auth-client.example.nil. 600 A 10.10.10.3 ++send ++END ++sleep 2 ++$DIG $DIGOPTS +short @10.53.0.1 dot-non-auth-client.example.nil >dig.out.test$n 2>&1 || ret=1 ++grep -F "10.10.10.3" dig.out.test$n >/dev/null 2>&1 || ret=1 ++if [ $ret -ne 0 ]; then ++ echo_i "failed" ++ status=1 ++fi ++ ++n=$((n + 1)) ++ret=0 ++echo_i "check DoT (strict-tls) with an implicit hostname (by IP address) ($n)" ++$NSUPDATE -D -S -A CA/CA.pem -k ns1/ddns.key <nsupdate.out.test$n 2>&1 || ret=1 ++server 10.53.0.1 ${EXTRAPORT1} ++update add dot-fs.example.nil. 600 A 10.10.10.3 ++send ++END ++sleep 2 ++$DIG $DIGOPTS +short @10.53.0.1 dot-fs.example.nil >dig.out.test$n 2>&1 || ret=1 ++grep -F "10.10.10.3" dig.out.test$n >/dev/null 2>&1 || ret=1 ++if [ $ret -ne 0 ]; then ++ echo_i "failed" ++ status=1 ++fi ++ ++n=$((n + 1)) ++ret=0 ++echo_i "check DoT (strict-tls) with a correct hostname ($n)" ++$NSUPDATE -D -S -A CA/CA.pem -H srv01.crt01.example.nil -k ns1/ddns.key <nsupdate.out.test$n 2>&1 || ret=1 ++server 10.53.0.1 ${EXTRAPORT1} ++update add dot-fs-h.example.nil. 600 A 10.10.10.3 ++send ++END ++sleep 2 ++$DIG $DIGOPTS +short @10.53.0.1 dot-fs-h.example.nil >dig.out.test$n 2>&1 || ret=1 ++grep -F "10.10.10.3" dig.out.test$n >/dev/null 2>&1 || ret=1 ++if [ $ret -ne 0 ]; then ++ echo_i "failed" ++ status=1 ++fi ++ ++n=$((n + 1)) ++ret=0 ++echo_i "check DoT (strict-tls) with an incorrect hostname (failure expected) ($n)" ++$NSUPDATE -D -S -A CA/CA.pem -H srv01.crt01.example.bad -k ns1/ddns.key <nsupdate.out.test$n 2>&1 && ret=1 ++server 10.53.0.1 ${EXTRAPORT1} ++update add dot-fs-h-bad.example.nil. 600 A 10.10.10.3 ++send ++END ++sleep 2 ++$DIG $DIGOPTS +short @10.53.0.1 dot-fs-h-bad.example.nil >dig.out.test$n 2>&1 || ret=1 ++grep -F "10.10.10.3" dig.out.test$n >/dev/null 2>&1 && ret=1 ++if [ $ret -ne 0 ]; then ++ echo_i "failed" ++ status=1 ++fi ++ ++n=$((n + 1)) ++ret=0 ++echo_i "check DoT (strict-tls) with a wrong authority (failure expected) ($n)" ++$NSUPDATE -D -S -A CA/CA-other.pem -k ns1/ddns.key <nsupdate.out.test$n 2>&1 && ret=1 ++server 10.53.0.1 ${EXTRAPORT1} ++update add dot-fs-auth-bad.example.nil. 600 A 10.10.10.3 ++send ++END ++sleep 2 ++$DIG $DIGOPTS +short @10.53.0.1 dot-fs-auth-bad.example.nil >dig.out.test$n 2>&1 || ret=1 ++grep -F "10.10.10.3" dig.out.test$n >/dev/null 2>&1 && ret=1 ++if [ $ret -ne 0 ]; then ++ echo_i "failed" ++ status=1 ++fi ++ ++n=$((n + 1)) ++ret=0 ++echo_i "check DoT (mutual-tls) with a valid client certificate ($n)" ++$NSUPDATE -D -S -A CA/CA.pem -K CA/certs/srv01.client01.example.nil.key -E CA/certs/srv01.client01.example.nil.pem -k ns1/ddns.key <nsupdate.out.test$n 2>&1 || ret=1 ++server 10.53.0.1 ${EXTRAPORT2} ++update add dot-fsmt.example.nil. 600 A 10.10.10.3 ++send ++END ++sleep 2 ++$DIG $DIGOPTS +short @10.53.0.1 dot-fsmt.example.nil >dig.out.test$n 2>&1 || ret=1 ++grep -F "10.10.10.3" dig.out.test$n >/dev/null 2>&1 || ret=1 ++if [ $ret -ne 0 ]; then ++ echo_i "failed" ++ status=1 ++fi ++ ++n=$((n + 1)) ++ret=0 ++echo_i "check DoT (mutual-tls) with a valid client certificate but with an incorrect hostname (failure expected) ($n)" ++$NSUPDATE -D -S -A CA/CA.pem -K CA/certs/srv01.client01.example.nil.key -E CA/certs/srv01.client01.example.nil.pem -H srv01.crt01.example.bad -k ns1/ddns.key <nsupdate.out.test$n 2>&1 && ret=1 ++server 10.53.0.1 ${EXTRAPORT2} ++update add dot-fsmt-h-bad.example.nil. 600 A 10.10.10.3 ++send ++END ++sleep 2 ++$DIG $DIGOPTS +short @10.53.0.1 dot-fsmt-h-bad.example.nil >dig.out.test$n 2>&1 || ret=1 ++grep -F "10.10.10.3" dig.out.test$n >/dev/null 2>&1 && ret=1 ++if [ $ret -ne 0 ]; then ++ echo_i "failed" ++ status=1 ++fi + ++n=$((n + 1)) ++ret=0 ++echo_i "check DoT (mutual-tls) with a valid client certificate but with a wrong authority (failure expected) ($n)" ++$NSUPDATE -D -S -A CA/CA-other.pem -K CA/certs/srv01.client01.example.nil.key -E CA/certs/client01.crt01.example.nil.pem -k ns1/ddns.key <nsupdate.out.test$n 2>&1 && ret=1 ++server 10.53.0.1 ${EXTRAPORT2} ++update add dot-fsmt-auth-bad.example.nil. 600 A 10.10.10.3 ++send ++END ++sleep 2 ++$DIG $DIGOPTS +short @10.53.0.1 dot-fsmt-auth-bad.example.nil >dig.out.test$n 2>&1 || ret=1 ++grep -F "10.10.10.3" dig.out.test$n >/dev/null 2>&1 && ret=1 ++if [ $ret -ne 0 ]; then ++ echo_i "failed" ++ status=1 ++fi ++ ++n=$((n + 1)) ++ret=0 ++echo_i "check DoT (mutual-tls) with an expired client certificate (failure expected) ($n)" ++$NSUPDATE -D -S -A CA/CA.pem -K CA/certs/srv01.client02-expired.example.nil.key -E CA/certs/srv01.client02-expired.example.nil.pem -k ns1/ddns.key <nsupdate.out.test$n 2>&1 && ret=1 ++server 10.53.0.1 ${EXTRAPORT2} ++update add dot-fsmt-exp-bad.example.nil. 600 A 10.10.10.3 ++send ++END ++sleep 2 ++$DIG $DIGOPTS +short @10.53.0.1 dot-fsmt-exp-bad.example.nil >dig.out.test$n 2>&1 || ret=1 ++grep -F "10.10.10.3" dig.out.test$n >/dev/null 2>&1 && ret=1 ++if [ $ret -ne 0 ]; then ++ echo_i "failed" ++ status=1 ++fi ++ ++n=$((n + 1)) ++ret=0 ++echo_i "check DoT (mutual-tls) with a valid client certificate and an expired server certificate (failure expected) ($n)" ++$NSUPDATE -D -S -A CA/CA.pem -K CA/certs/srv01.client01.example.nil.key -E CA/certs/srv01.client01.example.nil.pem -k ns1/ddns.key <nsupdate.out.test$n 2>&1 && ret=1 ++server 10.53.0.1 ${EXTRAPORT3} ++update add dot-fsmt-exp-bad.example.nil. 600 A 10.10.10.3 ++send ++END ++sleep 2 ++$DIG $DIGOPTS +short @10.53.0.1 dot-fsmt-exp-bad.example.nil >dig.out.test$n 2>&1 || ret=1 ++grep -F "10.10.10.3" dig.out.test$n >/dev/null 2>&1 && ret=1 ++if [ $ret -ne 0 ]; then ++ echo_i "failed" ++ status=1 ++fi ++ ++n=$((n + 1)) ++ret=0 + echo_i "check TSIG key algorithms (nsupdate -k) ($n)" + if $FEATURETEST --md5; then + ALGS="md5 sha1 sha224 sha256 sha384 sha512" +@@ -1409,6 +1584,7 @@ send + END + t2=$($PERL -e 'print time()') + grep "; Communication with 10.53.0.4#${PORT} failed: timed out" nsupdate.out.test$n >/dev/null 2>&1 || ret=1 ++grep "not implemented" nsupdate.out.test$n > /dev/null 2>&1 && ret=1 + grep "not implemented" nsupdate.out.test$n >/dev/null 2>&1 && ret=1 + elapsed=$((t2 - t1)) + # Check that default timeout value is respected, there should be 4 tries with 3 seconds each. +@@ -2710,6 +2886,23 @@ EOF + status=1 + } + ++ n=$((n + 1)) ++ ret=0 ++ echo_i "check ms-selfsub match using DoT (opportunistic-tls) ($n)" ++ KRB5CCNAME="FILE:$(pwd)/ns10/machine.ccache" ++ export KRB5CCNAME ++ $NSUPDATE -d -S -O << EOF > nsupdate.out.test$n 2>&1 || ret=1 ++ gsstsig ++ realm EXAMPLE.COM ++ server 10.53.0.10 ${TLSPORT} ++ zone example.com ++ update add dot.machine.example.com 3600 IN A 10.53.0.10 ++ send ++EOF ++ $DIG $DIGOPTS +tcp @10.53.0.10 dot.machine.example.com A > dig.out.ns10.test$n ++ grep "status: NOERROR" dig.out.ns10.test$n > /dev/null || ret=1 ++ grep "dot.machine.example.com..*A.*10.53.0.10" dig.out.ns10.test$n > /dev/null || ret=1 ++ [ $ret = 0 ] || { echo_i "failed"; status=1; } + fi + + echo_i "exit status: $status" +-- +2.48.1 + diff --git a/SOURCES/bind-9.18-nsupdate-TLS.patch b/SOURCES/bind-9.18-nsupdate-TLS.patch new file mode 100644 index 0000000..8108b45 --- /dev/null +++ b/SOURCES/bind-9.18-nsupdate-TLS.patch @@ -0,0 +1,1602 @@ +From afc1cacbc9742c46ed0352f3dbf5e0780f529333 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= +Date: Mon, 11 Nov 2024 18:09:07 +0100 +Subject: [PATCH 1/3] Backport nsupdate TLS support into 9.18 + +Attempt to support TLS from nsupdate even in 9.18 release. + +Create few dispatch calls with 2 suffix with tls + +Keep original functions without changes and add new functions with +additional tlsctx and transport pointers passed. + +Convert xfrin.c:get_create_tlsctx() into a library function + +In order to make xfrin.c:get_create_tlsctx() reusable, move the function +into transport.c, and make changes into its prototype to not use the +'dns_xfrin_ctx_t' type, thus making it more universal. + +This change prepares ground for adding transport support into the +dispatch manager. + +Also, move the typedefs for 'dns_transport_t' and 'dns_transport_list_t' +from transport.h into types.h. + +(cherry picked from commit 881747218ba0ad411f6f1bf361c2c09c805d4aa8) + +Update calls inside libdns + +Add remaining transport additions to request and dispatch calls. Add +mctx into dispentry. + +Compilable nsupdate + +Implement DoT support for nsupdate + +Implement DNS-over-TLS support for nsupdate. Use DiG's DoT +implementation as a model for the newly added features. + +(cherry picked from commit 13000c28c2e0ab2754f0f37ab8d6edb8249a1370) + +[pemensik] Adapted to previous 9.18 changes. +Add usage and command line parsing + +Fixup tls initialization from nsupdate + +Detach transport also on dispatch_destroy properly. +--- + bin/nsupdate/nsupdate.c | 192 ++++++++++++++++++++---- + lib/dns/dispatch.c | 128 ++++++++++++++-- + lib/dns/include/dns/dispatch.h | 22 +++ + lib/dns/include/dns/request.h | 23 +++ + lib/dns/include/dns/transport.h | 45 +++++- + lib/dns/include/dns/types.h | 2 + + lib/dns/request.c | 63 ++++++-- + lib/dns/transport.c | 253 ++++++++++++++++++++++++++++++++ + lib/dns/xfrin.c | 232 +---------------------------- + 9 files changed, 668 insertions(+), 292 deletions(-) + +diff --git a/bin/nsupdate/nsupdate.c b/bin/nsupdate/nsupdate.c +index 45ba90fba7b..93c7ea6cb17 100644 +--- a/bin/nsupdate/nsupdate.c ++++ b/bin/nsupdate/nsupdate.c +@@ -45,6 +45,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -67,6 +68,7 @@ + #include + #include + #include ++#include + #include + + #include +@@ -118,6 +120,7 @@ static bool memdebugging = false; + static bool have_ipv4 = false; + static bool have_ipv6 = false; + static bool is_dst_up = false; ++static bool use_tls = false; + static bool usevc = false; + static bool usegsstsig = false; + static bool use_win2k_gsstsig = false; +@@ -145,6 +148,14 @@ static dns_tsigkey_t *tsigkey = NULL; + static dst_key_t *sig0key = NULL; + static isc_sockaddr_t *servers = NULL; + static isc_sockaddr_t *primary_servers = NULL; ++static dns_transport_list_t *transport_list = NULL; ++static dns_transport_t *transport = NULL; ++static isc_tlsctx_cache_t *tls_ctx_cache = NULL; ++static char *tls_hostname = NULL; ++static char *tls_client_key_file = NULL; ++static char *tls_client_cert_file = NULL; ++static char *tls_ca_file = NULL; ++static bool tls_always_verify_remote = true; + static bool default_servers = true; + static int ns_inuse = 0; + static int primary_inuse = 0; +@@ -790,6 +801,19 @@ set_source_ports(dns_dispatchmgr_t *manager) { + isc_portset_destroy(gmctx, &v6portset); + } + ++static isc_result_t ++create_name(const char *str, char *namedata, size_t len, dns_name_t *name) { ++ isc_buffer_t namesrc, namebuf; ++ ++ dns_name_init(name, NULL); ++ isc_buffer_constinit(&namesrc, str, strlen(str)); ++ isc_buffer_add(&namesrc, strlen(str)); ++ isc_buffer_init(&namebuf, namedata, len); ++ ++ return dns_name_fromtext(name, &namesrc, dns_rootname, ++ DNS_NAME_DOWNCASE, &namebuf); ++} ++ + static void + setup_system(void) { + isc_result_t result; +@@ -797,6 +821,8 @@ setup_system(void) { + isc_sockaddrlist_t *nslist; + isc_logconfig_t *logconfig = NULL; + irs_resconf_t *resconf = NULL; ++ dns_name_t tlsname; ++ char namedata[DNS_NAME_FORMATSIZE + 1]; + + ddebug("setup_system()"); + +@@ -942,6 +968,31 @@ setup_system(void) { + check_result(result, "dns_dispatch_createudp (v4)"); + } + ++ transport_list = dns_transport_list_new(gmctx); ++ isc_tlsctx_cache_create(gmctx, &tls_ctx_cache); ++ ++ if (tls_client_key_file == NULL) { ++ result = create_name("tls-non-auth-client", namedata, ++ sizeof(namedata), &tlsname); ++ check_result(result, "create_name (tls-non-auth-client)"); ++ transport = dns_transport_new(&tlsname, DNS_TRANSPORT_TLS, ++ transport_list); ++ dns_transport_set_tlsname(transport, "tls-non-auth-client"); ++ } else { ++ result = create_name("tls-auth-client", namedata, ++ sizeof(namedata), &tlsname); ++ check_result(result, "create_name (tls-auth-client)"); ++ transport = dns_transport_new(&tlsname, DNS_TRANSPORT_TLS, ++ transport_list); ++ dns_transport_set_tlsname(transport, "tls-auth-client"); ++ dns_transport_set_keyfile(transport, tls_client_key_file); ++ dns_transport_set_certfile(transport, tls_client_cert_file); ++ } ++ dns_transport_set_cafile(transport, tls_ca_file); ++ dns_transport_set_remote_hostname(transport, tls_hostname); ++ dns_transport_set_always_verify_remote(transport, ++ tls_always_verify_remote); ++ + result = dns_requestmgr_create(gmctx, taskmgr, dispatchmgr, dispatchv4, + dispatchv6, &requestmgr); + check_result(result, "dns_requestmgr_create"); +@@ -982,7 +1033,7 @@ version(void) { + fprintf(stderr, "nsupdate %s\n", PACKAGE_VERSION); + } + +-#define PARSE_ARGS_FMT "46C:dDghilL:Mok:p:Pr:R:t:Tu:vVy:" ++#define PARSE_ARGS_FMT "46A:C:dDE:ghH:iK:lL:MoOk:p:Pr:R:St:Tu:vVy:" + + static void + pre_parse_args(int argc, char **argv) { +@@ -1025,7 +1076,9 @@ pre_parse_args(int argc, char **argv) { + fprintf(stderr, "usage: nsupdate [-CdDi] [-L level] " + "[-l] [-g | -o | -y keyname:secret " + "| -k keyfile] [-p port] " +- "[-v] [-V] [-P] [-T] [-4 | -6] " ++ "[ -S [-K tlskeyfile] [-E tlscertfile] " ++ "[-A tlscafile] [-H tlshostname] " ++ "[-O] ] [-v] [-V] [-P] [-T] [-4 | -6] " + "[filename]\n"); + exit(EXIT_FAILURE); + +@@ -1097,6 +1150,10 @@ parse_args(int argc, char **argv) { + fatal("can't find IPv6 networking"); + } + break; ++ case 'A': ++ use_tls = true; ++ tls_ca_file = isc_commandline_argument; ++ break; + case 'C': + resolvconf = isc_commandline_argument; + break; +@@ -1107,12 +1164,27 @@ parse_args(int argc, char **argv) { + debugging = true; + ddebugging = true; + break; ++ case 'E': ++ use_tls = true; ++ usevc = true; ++ tls_client_cert_file = isc_commandline_argument; ++ break; ++ case 'H': ++ use_tls = true; ++ usevc = true; ++ tls_hostname = isc_commandline_argument; ++ break; + case 'M': + break; + case 'i': + force_interactive = true; + interactive = true; + break; ++ case 'K': ++ use_tls = true; ++ usevc = true; ++ tls_client_key_file = isc_commandline_argument; ++ break; + case 'l': + local_only = true; + break; +@@ -1145,6 +1217,11 @@ parse_args(int argc, char **argv) { + usegsstsig = true; + use_win2k_gsstsig = true; + break; ++ case 'O': ++ use_tls = true; ++ usevc = true; ++ tls_always_verify_remote = false; ++ break; + case 'p': + result = isc_parse_uint16(&dnsport, + isc_commandline_argument, 10); +@@ -1156,6 +1233,10 @@ parse_args(int argc, char **argv) { + exit(EXIT_FAILURE); + } + break; ++ case 'S': ++ use_tls = true; ++ usevc = true; ++ break; + case 't': + result = isc_parse_uint32(&timeout, + isc_commandline_argument, 10); +@@ -1218,6 +1299,26 @@ parse_args(int argc, char **argv) { + } + #endif /* HAVE_GSSAPI */ + ++ if (use_tls) { ++ usevc = true; ++ if ((tls_client_key_file == NULL) != ++ (tls_client_cert_file == NULL)) ++ { ++ fprintf(stderr, ++ "%s: cannot specify the -K option without" ++ "the -E option, and vice versa.\n", ++ argv[0]); ++ exit(EXIT_FAILURE); ++ } ++ if (tls_ca_file != NULL && tls_always_verify_remote == false) { ++ fprintf(stderr, ++ "%s: cannot specify the -A option in " ++ "conjuction with the -O option.\n", ++ argv[0]); ++ exit(EXIT_FAILURE); ++ } ++ } ++ + if (argv[isc_commandline_index] != NULL) { + if (strcmp(argv[isc_commandline_index], "-") == 0) { + input = stdin; +@@ -2468,8 +2569,10 @@ static void + send_update(dns_name_t *zone, isc_sockaddr_t *primary) { + isc_result_t result; + dns_request_t *request = NULL; +- unsigned int options = DNS_REQUESTOPT_CASE; + isc_sockaddr_t *srcaddr; ++ unsigned int options = DNS_REQUESTOPT_CASE; ++ dns_transport_t *req_transport = NULL; ++ isc_tlsctx_cache_t *req_tls_ctx_cache = NULL; + + ddebug("send_update()"); + +@@ -2477,7 +2580,12 @@ send_update(dns_name_t *zone, isc_sockaddr_t *primary) { + + if (usevc) { + options |= DNS_REQUESTOPT_TCP; ++ if (use_tls) { ++ req_transport = transport; ++ req_tls_ctx_cache = tls_ctx_cache; ++ } + } ++ + if (tsigkey == NULL && sig0key != NULL) { + result = dns_message_setsig0key(updatemsg, sig0key); + check_result(result, "dns_message_setsig0key"); +@@ -2500,11 +2608,11 @@ send_update(dns_name_t *zone, isc_sockaddr_t *primary) { + updatemsg->tsigname->attributes |= DNS_NAMEATTR_NOCOMPRESS; + } + +- result = dns_request_create(requestmgr, updatemsg, srcaddr, primary, +- options, tsigkey, timeout, udp_timeout, +- udp_retries, global_task, update_completed, +- NULL, &request); +- check_result(result, "dns_request_create"); ++ result = dns_request_create2( ++ requestmgr, updatemsg, srcaddr, primary, req_transport, ++ req_tls_ctx_cache, options, tsigkey, timeout, udp_timeout, ++ udp_retries, global_task, update_completed, NULL, &request); ++ check_result(result, "dns_request_create2"); + + if (debugging) { + show_message(stdout, updatemsg, "Outgoing update query:"); +@@ -2594,7 +2702,9 @@ recvsoa(isc_task_t *task, isc_event_t *event) { + result = dns_request_getresponse(request, rcvmsg, + DNS_MESSAGEPARSE_PRESERVEORDER); + if (result == DNS_R_TSIGERRORSET && servers != NULL) { +- unsigned int options = 0; ++ unsigned int options = DNS_REQUESTOPT_CASE; ++ dns_transport_t *req_transport = NULL; ++ isc_tlsctx_cache_t *req_tls_ctx_cache = NULL; + + dns_message_detach(&rcvmsg); + ddebug("Destroying request [%p]", request); +@@ -2605,8 +2715,12 @@ recvsoa(isc_task_t *task, isc_event_t *event) { + dns_message_renderreset(soaquery); + ddebug("retrying soa request without TSIG"); + +- if (!default_servers && usevc) { ++ if (usevc) { + options |= DNS_REQUESTOPT_TCP; ++ if (!default_servers && use_tls) { ++ req_transport = transport; ++ req_tls_ctx_cache = tls_ctx_cache; ++ } + } + + if (isc_sockaddr_pf(addr) == AF_INET6) { +@@ -2615,10 +2729,10 @@ recvsoa(isc_task_t *task, isc_event_t *event) { + srcaddr = localaddr4; + } + +- result = dns_request_create(requestmgr, soaquery, srcaddr, addr, +- options, NULL, timeout, udp_timeout, +- udp_retries, global_task, recvsoa, +- reqinfo, &request); ++ result = dns_request_create2( ++ requestmgr, soaquery, srcaddr, addr, req_transport, ++ req_tls_ctx_cache, options, NULL, timeout, udp_timeout, ++ udp_retries, global_task, recvsoa, reqinfo, &request); + check_result(result, "dns_request_create"); + requests++; + return; +@@ -2831,10 +2945,16 @@ sendrequest(isc_sockaddr_t *destaddr, dns_message_t *msg, + isc_result_t result; + nsu_requestinfo_t *reqinfo; + isc_sockaddr_t *srcaddr; +- unsigned int options = 0; ++ unsigned int options = DNS_REQUESTOPT_CASE; ++ dns_transport_t *req_transport = NULL; ++ isc_tlsctx_cache_t *req_tls_ctx_cache = NULL; + +- if (!default_servers && usevc) { ++ if (usevc) { + options |= DNS_REQUESTOPT_TCP; ++ if (!default_servers && use_tls) { ++ req_transport = transport; ++ req_tls_ctx_cache = tls_ctx_cache; ++ } + } + + reqinfo = isc_mem_get(gmctx, sizeof(nsu_requestinfo_t)); +@@ -2847,11 +2967,12 @@ sendrequest(isc_sockaddr_t *destaddr, dns_message_t *msg, + srcaddr = localaddr4; + } + +- result = dns_request_create(requestmgr, msg, srcaddr, destaddr, options, +- default_servers ? NULL : tsigkey, timeout, +- udp_timeout, udp_retries, global_task, +- recvsoa, reqinfo, request); +- check_result(result, "dns_request_create"); ++ result = dns_request_create2(requestmgr, msg, srcaddr, destaddr, ++ req_transport, req_tls_ctx_cache, options, ++ default_servers ? NULL : tsigkey, timeout, ++ udp_timeout, udp_retries, global_task, ++ recvsoa, reqinfo, request); ++ check_result(result, "dns_request_create2"); + requests++; + } + +@@ -2934,7 +3055,6 @@ start_gssrequest(dns_name_t *primary) { + char namestr[DNS_NAME_FORMATSIZE]; + char mykeystr[DNS_NAME_FORMATSIZE]; + char *err_message = NULL; +- + debug("start_gssrequest"); + usevc = true; + +@@ -3030,8 +3150,15 @@ send_gssrequest(isc_sockaddr_t *destaddr, dns_message_t *msg, + dns_request_t **request, gss_ctx_id_t context) { + isc_result_t result; + nsu_gssinfo_t *reqinfo; +- unsigned int options = 0; + isc_sockaddr_t *srcaddr; ++ unsigned int options = DNS_REQUESTOPT_CASE | DNS_REQUESTOPT_TCP; ++ dns_transport_t *req_transport = NULL; ++ isc_tlsctx_cache_t *req_tls_ctx_cache = NULL; ++ ++ if (!default_servers && use_tls) { ++ req_transport = transport; ++ req_tls_ctx_cache = tls_ctx_cache; ++ } + + debug("send_gssrequest"); + REQUIRE(destaddr != NULL); +@@ -3041,18 +3168,17 @@ send_gssrequest(isc_sockaddr_t *destaddr, dns_message_t *msg, + reqinfo->addr = destaddr; + reqinfo->context = context; + +- options |= DNS_REQUESTOPT_TCP; +- + if (isc_sockaddr_pf(destaddr) == AF_INET6) { + srcaddr = localaddr6; + } else { + srcaddr = localaddr4; + } + +- result = dns_request_create(requestmgr, msg, srcaddr, destaddr, options, +- tsigkey, timeout, udp_timeout, udp_retries, +- global_task, recvgss, reqinfo, request); +- check_result(result, "dns_request_create"); ++ result = dns_request_create2(requestmgr, msg, srcaddr, destaddr, ++ req_transport, req_tls_ctx_cache, options, ++ tsigkey, timeout, udp_timeout, udp_retries, ++ global_task, recvgss, reqinfo, request); ++ check_result(result, "dns_request_create2"); + if (debugging) { + show_message(stdout, msg, "Outgoing update query:"); + } +@@ -3321,6 +3447,14 @@ static void + cleanup(void) { + ddebug("cleanup()"); + ++ if (tls_ctx_cache != NULL) { ++ isc_tlsctx_cache_detach(&tls_ctx_cache); ++ } ++ ++ if (transport_list != NULL) { ++ dns_transport_list_detach(&transport_list); ++ } ++ + LOCK(&answer_lock); + if (answer != NULL) { + dns_message_detach(&answer); +diff --git a/lib/dns/dispatch.c b/lib/dns/dispatch.c +index d737363fea4..90d756f8f0a 100644 +--- a/lib/dns/dispatch.c ++++ b/lib/dns/dispatch.c +@@ -30,6 +30,7 @@ + #include + #include + #include ++#include + #include + + #include +@@ -83,6 +84,10 @@ struct dns_dispentry { + dns_dispatch_t *disp; + isc_nmhandle_t *handle; /*%< netmgr handle for UDP connection */ + dns_dispatchstate_t state; ++ /* TLS support for nsupdate. */ ++ isc_mem_t *mctx; ++ dns_transport_t *transport; ++ isc_tlsctx_cache_t *tlsctx_cache; + unsigned int bucket; + unsigned int retries; + unsigned int timeout; +@@ -107,11 +112,12 @@ struct dns_dispatch { + /* Unlocked. */ + unsigned int magic; /*%< magic */ + int tid; +- dns_dispatchmgr_t *mgr; /*%< dispatch manager */ +- isc_nmhandle_t *handle; /*%< netmgr handle for TCP connection */ +- isc_sockaddr_t local; /*%< local address */ +- in_port_t localport; /*%< local UDP port */ +- isc_sockaddr_t peer; /*%< peer address (TCP) */ ++ dns_dispatchmgr_t *mgr; /*%< dispatch manager */ ++ isc_nmhandle_t *handle; /*%< netmgr handle for TCP connection */ ++ isc_sockaddr_t local; /*%< local address */ ++ in_port_t localport; /*%< local UDP port */ ++ isc_sockaddr_t peer; /*%< peer address (TCP) */ ++ dns_transport_t *transport; /*%< TCP transport parameters */ + + /*% Locked by mgr->lock. */ + ISC_LINK(dns_dispatch_t) link; +@@ -119,6 +125,7 @@ struct dns_dispatch { + /* Locked by "lock". */ + isc_mutex_t lock; /*%< locks all below */ + isc_socktype_t socktype; ++ dns_dispatchopt_t options; + dns_dispatchstate_t state; + isc_refcount_t references; + +@@ -220,13 +227,27 @@ udp_dispatch_getnext(dns_dispentry_t *resp, int32_t timeout); + + static const char * + socktype2str(dns_dispentry_t *resp) { ++ dns_transport_type_t transport_type = DNS_TRANSPORT_UDP; + dns_dispatch_t *disp = resp->disp; + +- switch (disp->socktype) { +- case isc_socktype_udp: ++ if (disp->socktype == isc_socktype_tcp) { ++ if (resp->transport != NULL) { ++ transport_type = ++ dns_transport_get_type(resp->transport); ++ } else { ++ transport_type = DNS_TRANSPORT_TCP; ++ } ++ } ++ ++ switch (transport_type) { ++ case DNS_TRANSPORT_UDP: + return ("UDP"); +- case isc_socktype_tcp: ++ case DNS_TRANSPORT_TCP: + return ("TCP"); ++ case DNS_TRANSPORT_TLS: ++ return "TLS"; ++ case DNS_TRANSPORT_HTTP: ++ return "HTTP"; + default: + return (""); + } +@@ -457,6 +478,14 @@ dispentry_destroy(dns_dispentry_t *resp) { + isc_nmhandle_detach(&resp->handle); + } + ++ if (resp->tlsctx_cache != NULL) { ++ isc_tlsctx_cache_detach(&resp->tlsctx_cache); ++ } ++ ++ if (resp->transport != NULL) { ++ dns_transport_detach(&resp->transport); ++ } ++ + isc_mem_put(disp->mgr->mctx, resp, sizeof(*resp)); + + dns_dispatch_detach(&disp); /* DISPATCH001 */ +@@ -1161,6 +1190,15 @@ dispatch_allocate(dns_dispatchmgr_t *mgr, isc_socktype_t type, + isc_result_t + dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, const isc_sockaddr_t *localaddr, + const isc_sockaddr_t *destaddr, dns_dispatch_t **dispp) { ++ return dns_dispatch_createtcp2(mgr, localaddr, destaddr, NULL, 0, ++ dispp); ++} ++ ++isc_result_t ++dns_dispatch_createtcp2(dns_dispatchmgr_t *mgr, const isc_sockaddr_t *localaddr, ++ const isc_sockaddr_t *destaddr, ++ dns_transport_t *transport, dns_dispatchopt_t options, ++ dns_dispatch_t **dispp) { + dns_dispatch_t *disp = NULL; + + REQUIRE(VALID_DISPATCHMGR(mgr)); +@@ -1170,7 +1208,11 @@ dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, const isc_sockaddr_t *localaddr, + + dispatch_allocate(mgr, isc_socktype_tcp, &disp); + ++ disp->options = options; + disp->peer = *destaddr; ++ if (transport != NULL) { ++ dns_transport_attach(transport, &disp->transport); ++ } + + if (localaddr != NULL) { + disp->local = *localaddr; +@@ -1185,6 +1227,7 @@ dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, const isc_sockaddr_t *localaddr, + * Append it to the dispatcher list. + */ + ++ /* TODO: DNS_DISPATCHOPT_UNSHARED is not backported */ + /* FIXME: There should be a lookup hashtable here */ + ISC_LIST_APPEND(mgr->list, disp, link); + UNLOCK(&mgr->lock); +@@ -1208,6 +1251,13 @@ dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, const isc_sockaddr_t *localaddr, + isc_result_t + dns_dispatch_gettcp(dns_dispatchmgr_t *mgr, const isc_sockaddr_t *destaddr, + const isc_sockaddr_t *localaddr, dns_dispatch_t **dispp) { ++ return dns_dispatch_gettcp2(mgr, destaddr, localaddr, NULL, dispp); ++} ++ ++isc_result_t ++dns_dispatch_gettcp2(dns_dispatchmgr_t *mgr, const isc_sockaddr_t *destaddr, ++ const isc_sockaddr_t *localaddr, ++ dns_transport_t *transport, dns_dispatch_t **dispp) { + dns_dispatch_t *disp_connected = NULL; + dns_dispatch_t *disp_fallback = NULL; + isc_result_t result = ISC_R_NOTFOUND; +@@ -1248,8 +1298,10 @@ dns_dispatch_gettcp(dns_dispatchmgr_t *mgr, const isc_sockaddr_t *destaddr, + if (disp->socktype != isc_socktype_tcp || + !isc_sockaddr_equal(destaddr, &peeraddr) || + (localaddr != NULL && +- !isc_sockaddr_eqaddr(localaddr, &sockname))) ++ !isc_sockaddr_eqaddr(localaddr, &sockname)) || ++ (transport != disp->transport)) + { ++ // dispatch_match alternative + UNLOCK(&disp->lock); + continue; + } +@@ -1403,6 +1455,9 @@ dispatch_destroy(dns_dispatch_t *disp) { + disp->handle, &disp->handle); + isc_nmhandle_detach(&disp->handle); + } ++ if (disp->transport != NULL) { ++ dns_transport_detach(&disp->transport); ++ } + + isc_mutex_destroy(&disp->lock); + +@@ -1426,7 +1481,18 @@ dns_dispatch_add(dns_dispatch_t *disp, unsigned int options, + unsigned int timeout, const isc_sockaddr_t *dest, + dispatch_cb_t connected, dispatch_cb_t sent, + dispatch_cb_t response, void *arg, dns_messageid_t *idp, +- dns_dispentry_t **respp) { ++ dns_dispentry_t **resp) { ++ return dns_dispatch_add2(disp, options, timeout, dest, NULL, NULL, ++ connected, sent, response, arg, idp, resp); ++} ++ ++isc_result_t ++dns_dispatch_add2(dns_dispatch_t *disp, unsigned int options, ++ unsigned int timeout, const isc_sockaddr_t *dest, ++ dns_transport_t *transport, isc_tlsctx_cache_t *tlsctx_cache, ++ dispatch_cb_t connected, dispatch_cb_t sent, ++ dispatch_cb_t response, void *arg, dns_messageid_t *idp, ++ dns_dispentry_t **respp) { + dns_dispentry_t *resp = NULL; + dns_qid_t *qid = NULL; + in_port_t localport; +@@ -1444,6 +1510,7 @@ dns_dispatch_add(dns_dispatch_t *disp, unsigned int options, + REQUIRE(connected != NULL); + REQUIRE(response != NULL); + REQUIRE(sent != NULL); ++ REQUIRE(disp->transport == transport); + + LOCK(&disp->lock); + +@@ -1471,6 +1538,7 @@ dns_dispatch_add(dns_dispatch_t *disp, unsigned int options, + .rlink = ISC_LINK_INITIALIZER, + .magic = RESPONSE_MAGIC, + }; ++ isc_mem_attach(disp->mgr->mctx, &resp->mctx); + + #if DNS_DISPATCH_TRACE + fprintf(stderr, "dns_dispentry__init:%s:%s:%d:%p->references = 1\n", +@@ -1530,6 +1598,14 @@ dns_dispatch_add(dns_dispatch_t *disp, unsigned int options, + return (ISC_R_NOMORE); + } + ++ if (transport != NULL) { ++ dns_transport_attach(transport, &resp->transport); ++ } ++ ++ if (tlsctx_cache != NULL) { ++ isc_tlsctx_cache_attach(tlsctx_cache, &resp->tlsctx_cache); ++ } ++ + dns_dispatch_attach(disp, &resp->disp); /* DISPATCH001 */ + + disp->requests++; +@@ -1779,6 +1855,7 @@ dns_dispatch_done(dns_dispentry_t **respp) { + *respp = NULL; + + dispentry_cancel(resp, ISC_R_CANCELED); ++ isc_mem_detach(&resp->mctx); ///< FIXME: is this ok? + dns_dispentry_detach(&resp); /* DISPENTRY000 */ + } + +@@ -1970,6 +2047,27 @@ udp_dispatch_connect(dns_dispatch_t *disp, dns_dispentry_t *resp) { + + static isc_result_t + tcp_dispatch_connect(dns_dispatch_t *disp, dns_dispentry_t *resp) { ++ dns_transport_type_t transport_type = DNS_TRANSPORT_TCP; ++ isc_tlsctx_t *tlsctx = NULL; ++ isc_tlsctx_client_session_cache_t *sess_cache = NULL; ++ ++ if (resp->transport != NULL) { ++ transport_type = dns_transport_get_type(resp->transport); ++ } ++ ++ if (transport_type == DNS_TRANSPORT_TLS) { ++ isc_result_t result; ++ ++ result = dns_transport_get_tlsctx( ++ resp->transport, &resp->peer, resp->tlsctx_cache, ++ resp->mctx, &tlsctx, &sess_cache); ++ ++ if (result != ISC_R_SUCCESS) { ++ return result; ++ } ++ INSIST(tlsctx != NULL); ++ } ++ + /* Check whether the dispatch is already connecting or connected. */ + LOCK(&disp->lock); + switch (disp->state) { +@@ -1995,8 +2093,14 @@ tcp_dispatch_connect(dns_dispatch_t *disp, dns_dispentry_t *resp) { + "connecting from %s to %s, timeout %u", localbuf, + peerbuf, resp->timeout); + +- isc_nm_tcpdnsconnect(disp->mgr->nm, &disp->local, &disp->peer, +- tcp_connected, disp, resp->timeout, 0); ++ if (tlsctx != NULL) { ++ isc_nm_tlsdnsconnect(disp->mgr->nm, &disp->local, &disp->peer, ++ tcp_connected, disp, resp->timeout, 0, ++ tlsctx, sess_cache); ++ } else { ++ isc_nm_tcpdnsconnect(disp->mgr->nm, &disp->local, &disp->peer, ++ tcp_connected, disp, resp->timeout, 0); ++ } + break; + + case DNS_DISPATCHSTATE_CONNECTING: +diff --git a/lib/dns/include/dns/dispatch.h b/lib/dns/include/dns/dispatch.h +index ad377f078ed..cfdc37481ce 100644 +--- a/lib/dns/include/dns/dispatch.h ++++ b/lib/dns/include/dns/dispatch.h +@@ -56,6 +56,7 @@ + #include + #include + ++#include + #include + + /* Add -DDNS_DISPATCH_TRACE=1 to CFLAGS for detailed reference tracing */ +@@ -74,6 +75,11 @@ struct dns_dispatchset { + isc_mutex_t lock; + }; + ++typedef enum dns_dispatchopt { ++ DNS_DISPATCHOPT_FIXEDID = 1 << 0, ++ DNS_DISPATCHOPT_UNSHARED = 1 << 1, /* Don't share this connection */ ++} dns_dispatchopt_t; ++ + /* + */ + #define DNS_DISPATCHOPT_FIXEDID 0x00000001U +@@ -199,6 +205,11 @@ dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, const isc_sockaddr_t *localaddr, + * + *\li Anything else -- failure. + */ ++isc_result_t ++dns_dispatch_createtcp2(dns_dispatchmgr_t *mgr, const isc_sockaddr_t *localaddr, ++ const isc_sockaddr_t *destaddr, ++ dns_transport_t *transport, dns_dispatchopt_t options, ++ dns_dispatch_t **dispp); + + #if DNS_DISPATCH_TRACE + #define dns_dispatch_ref(ptr) \ +@@ -258,6 +269,10 @@ dns_dispatch_gettcp(dns_dispatchmgr_t *mgr, const isc_sockaddr_t *destaddr, + /* + * Attempt to connect to a existing TCP connection. + */ ++isc_result_t ++dns_dispatch_gettcp2(dns_dispatchmgr_t *mgr, const isc_sockaddr_t *destaddr, ++ const isc_sockaddr_t *localaddr, ++ dns_transport_t *transport, dns_dispatch_t **dispp); + + typedef void (*dispatch_cb_t)(isc_result_t eresult, isc_region_t *region, + void *cbarg); +@@ -268,6 +283,13 @@ dns_dispatch_add(dns_dispatch_t *disp, unsigned int options, + dispatch_cb_t connected, dispatch_cb_t sent, + dispatch_cb_t response, void *arg, dns_messageid_t *idp, + dns_dispentry_t **resp); ++isc_result_t ++dns_dispatch_add2(dns_dispatch_t *disp, unsigned int options, ++ unsigned int timeout, const isc_sockaddr_t *dest, ++ dns_transport_t *transport, isc_tlsctx_cache_t *tlsctx_cache, ++ dispatch_cb_t connected, dispatch_cb_t sent, ++ dispatch_cb_t response, void *arg, dns_messageid_t *idp, ++ dns_dispentry_t **respp); + /*%< + * Add a response entry for this dispatch. + * +diff --git a/lib/dns/include/dns/request.h b/lib/dns/include/dns/request.h +index d00574f9827..17bcbf68c3b 100644 +--- a/lib/dns/include/dns/request.h ++++ b/lib/dns/include/dns/request.h +@@ -44,6 +44,7 @@ + #define DNS_REQUESTOPT_TCP 0x00000001U + #define DNS_REQUESTOPT_CASE 0x00000002U + #define DNS_REQUESTOPT_FIXEDID 0x00000004U ++#define DNS_REQUESTOPT_LARGE 0x00000008U + + typedef struct dns_requestevent { + ISC_EVENT_COMMON(struct dns_requestevent); +@@ -161,6 +162,17 @@ dns_request_create(dns_requestmgr_t *requestmgr, dns_message_t *message, + unsigned int udptimeout, unsigned int udpretries, + isc_task_t *task, isc_taskaction_t action, void *arg, + dns_request_t **requestp); ++isc_result_t ++dns_request_create2(dns_requestmgr_t *requestmgr, dns_message_t *message, ++ const isc_sockaddr_t *srcaddr, ++ const isc_sockaddr_t *destaddr, ++ dns_transport_t *req_transport, ++ isc_tlsctx_cache_t *req_tls_ctx_cache, ++ unsigned int options, ++ dns_tsigkey_t *key, unsigned int timeout, ++ unsigned int udptimeout, unsigned int udpretries, ++ isc_task_t *task, isc_taskaction_t action, void *arg, ++ dns_request_t **requestp); + /*%< + * Create and send a request. + * +@@ -204,6 +216,17 @@ dns_request_createraw(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf, + unsigned int udpretries, isc_task_t *task, + isc_taskaction_t action, void *arg, + dns_request_t **requestp); ++isc_result_t ++dns_request_createraw2(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf, ++ const isc_sockaddr_t *srcaddr, ++ const isc_sockaddr_t *destaddr, ++ dns_transport_t *transport, ++ isc_tlsctx_cache_t *tlsctx_cache, ++ unsigned int options, ++ unsigned int timeout, unsigned int udptimeout, ++ unsigned int udpretries, isc_task_t *task, ++ isc_taskaction_t action, void *arg, ++ dns_request_t **requestp); + /*!< + * \brief Create and send a request. + * +diff --git a/lib/dns/include/dns/transport.h b/lib/dns/include/dns/transport.h +index e74ccd7f970..e6499a97e73 100644 +--- a/lib/dns/include/dns/transport.h ++++ b/lib/dns/include/dns/transport.h +@@ -13,7 +13,9 @@ + + #pragma once + +-#include ++#include ++ ++#include + + typedef enum { + DNS_TRANSPORT_NONE = 0, +@@ -29,9 +31,6 @@ typedef enum { + DNS_HTTP_POST = 1, + } dns_http_mode_t; + +-typedef struct dns_transport dns_transport_t; +-typedef struct dns_transport_list dns_transport_list_t; +- + dns_transport_t * + dns_transport_new(const dns_name_t *name, dns_transport_type_t type, + dns_transport_list_t *list); +@@ -63,15 +62,44 @@ dns_transport_get_tls_versions(const dns_transport_t *transport); + bool + dns_transport_get_prefer_server_ciphers(const dns_transport_t *transport, + bool *preferp); ++bool ++dns_transport_get_always_verify_remote(dns_transport_t *transport); + /*%< + * Getter functions: return the type, cert file, key file, CA file, +- * hostname, HTTP endpoint, or HTTP mode (GET or POST) for 'transport'. ++ * hostname, HTTP endpoint, HTTP mode (GET or POST), ciphers, TLS name, ++ * TLS version, server ciphers preference mode, and always enabling ++ * authentication mode for 'transport'. + * + * dns_transport_get_prefer_server_ciphers() returns 'true' is value + * was set, 'false' otherwise. The actual value is returned via + * 'preferp' pointer. + */ + ++isc_result_t ++dns_transport_get_tlsctx(dns_transport_t *transport, const isc_sockaddr_t *peer, ++ isc_tlsctx_cache_t *tlsctx_cache, isc_mem_t *mctx, ++ isc_tlsctx_t **pctx, ++ isc_tlsctx_client_session_cache_t **psess_cache); ++/*%< ++ * Get the transport's TLS Context and the TLS Client Session Cache associated ++ * with it. ++ * ++ * When neither the TLS hostname, nor the TLS certificates authorities (CA) ++ * file are set for the 'transport', then Opportunistic TLS (no authentication ++ * of the remote peer) will be used, unless the 'always_verify_remote' mode is ++ * enabled on the 'transport', in which case the remote peer will be ++ * authenticated by its IP address using the system's default certificates ++ * authorities store. ++ * ++ * Requires: ++ *\li 'transport' is a valid, 'DNS_TRANSPORT_TLS' type transport. ++ *\li 'peer' is not NULL. ++ *\li 'tlsctx_cache' is not NULL. ++ *\li 'mctx' is not NULL. ++ *\li 'pctx' is not NULL and '*pctx' is NULL. ++ *\li 'psess_cache' is not NULL and '*psess_cache' is NULL. ++ */ ++ + void + dns_transport_set_certfile(dns_transport_t *transport, const char *certfile); + void +@@ -96,9 +124,14 @@ dns_transport_set_tls_versions(dns_transport_t *transport, + void + dns_transport_set_prefer_server_ciphers(dns_transport_t *transport, + const bool prefer); ++void ++dns_transport_set_always_verify_remote(dns_transport_t *transport, ++ const bool always_verify_remote); + /*%< + * Setter functions: set the type, cert file, key file, CA file, +- * hostname, HTTP endpoint, or HTTP mode (GET or POST) for 'transport'. ++ * hostname, HTTP endpoint, HTTP mode (GET or POST), ciphers, TLS name, ++ * TLS version, server ciphers preference mode, and always enabling ++ * authentication mode for 'transport'. + * + * Requires: + *\li 'transport' is valid. +diff --git a/lib/dns/include/dns/types.h b/lib/dns/include/dns/types.h +index 6465962bd41..f0aaa24e936 100644 +--- a/lib/dns/include/dns/types.h ++++ b/lib/dns/include/dns/types.h +@@ -141,6 +141,8 @@ typedef struct dns_ssutable dns_ssutable_t; + typedef struct dns_stats dns_stats_t; + typedef uint32_t dns_rdatastatstype_t; + typedef struct dns_tkeyctx dns_tkeyctx_t; ++typedef struct dns_transport dns_transport_t; ++typedef struct dns_transport_list dns_transport_list_t; + typedef uint16_t dns_trust_t; + typedef struct dns_tsec dns_tsec_t; + typedef struct dns_tsig_keyring dns_tsig_keyring_t; +diff --git a/lib/dns/request.c b/lib/dns/request.c +index fb17ed2262e..463a7ca6d63 100644 +--- a/lib/dns/request.c ++++ b/lib/dns/request.c +@@ -399,12 +399,12 @@ isblackholed(dns_dispatchmgr_t *dispatchmgr, const isc_sockaddr_t *destaddr) { + static isc_result_t + tcp_dispatch(bool newtcp, dns_requestmgr_t *requestmgr, + const isc_sockaddr_t *srcaddr, const isc_sockaddr_t *destaddr, +- dns_dispatch_t **dispatchp) { ++ dns_transport_t *transport, dns_dispatch_t **dispatchp) { + isc_result_t result; + + if (!newtcp) { +- result = dns_dispatch_gettcp(requestmgr->dispatchmgr, destaddr, +- srcaddr, dispatchp); ++ result = dns_dispatch_gettcp2(requestmgr->dispatchmgr, destaddr, ++ srcaddr, transport, dispatchp); + if (result == ISC_R_SUCCESS) { + char peer[ISC_SOCKADDR_FORMATSIZE]; + +@@ -415,8 +415,8 @@ tcp_dispatch(bool newtcp, dns_requestmgr_t *requestmgr, + } + } + +- result = dns_dispatch_createtcp(requestmgr->dispatchmgr, srcaddr, +- destaddr, dispatchp); ++ result = dns_dispatch_createtcp2(requestmgr->dispatchmgr, srcaddr, ++ destaddr, transport, 0, dispatchp); + return (result); + } + +@@ -452,12 +452,12 @@ udp_dispatch(dns_requestmgr_t *requestmgr, const isc_sockaddr_t *srcaddr, + static isc_result_t + get_dispatch(bool tcp, bool newtcp, dns_requestmgr_t *requestmgr, + const isc_sockaddr_t *srcaddr, const isc_sockaddr_t *destaddr, +- dns_dispatch_t **dispatchp) { ++ dns_transport_t *transport, dns_dispatch_t **dispatchp) { + isc_result_t result; + + if (tcp) { + result = tcp_dispatch(newtcp, requestmgr, srcaddr, destaddr, +- dispatchp); ++ transport, dispatchp); + } else { + result = udp_dispatch(requestmgr, srcaddr, destaddr, dispatchp); + } +@@ -472,6 +472,21 @@ dns_request_createraw(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf, + unsigned int udpretries, isc_task_t *task, + isc_taskaction_t action, void *arg, + dns_request_t **requestp) { ++ return dns_request_createraw2(requestmgr, msgbuf, srcaddr, destaddr, ++ NULL, NULL, options, timeout, udptimeout, ++ udpretries, task, action, arg, requestp); ++} ++ ++isc_result_t ++dns_request_createraw2(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf, ++ const isc_sockaddr_t *srcaddr, ++ const isc_sockaddr_t *destaddr, ++ dns_transport_t *transport, ++ isc_tlsctx_cache_t *tlsctx_cache, unsigned int options, ++ unsigned int timeout, unsigned int udptimeout, ++ unsigned int udpretries, isc_task_t *task, ++ isc_taskaction_t action, void *arg, ++ dns_request_t **requestp) { + dns_request_t *request = NULL; + isc_result_t result; + isc_mem_t *mctx = NULL; +@@ -553,7 +568,7 @@ dns_request_createraw(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf, + again: + + result = get_dispatch(tcp, newtcp, requestmgr, srcaddr, destaddr, +- &request->dispatch); ++ transport, &request->dispatch); + if (result != ISC_R_SUCCESS) { + goto detach; + } +@@ -563,10 +578,10 @@ again: + dispopt |= DNS_DISPATCHOPT_FIXEDID; + } + +- result = dns_dispatch_add(request->dispatch, dispopt, request->timeout, +- destaddr, req_connected, req_senddone, +- req_response, request, &id, +- &request->dispentry); ++ result = dns_dispatch_add2(request->dispatch, dispopt, request->timeout, ++ destaddr, transport, tlsctx_cache, ++ req_connected, req_senddone, req_response, ++ request, &id, &request->dispentry); + if (result != ISC_R_SUCCESS) { + if ((options & DNS_REQUESTOPT_FIXEDID) != 0 && !newtcp) { + newtcp = true; +@@ -630,6 +645,21 @@ dns_request_create(dns_requestmgr_t *requestmgr, dns_message_t *message, + unsigned int udptimeout, unsigned int udpretries, + isc_task_t *task, isc_taskaction_t action, void *arg, + dns_request_t **requestp) { ++ return dns_request_create2(requestmgr, message, srcaddr, destaddr, NULL, ++ NULL, options, key, timeout, udptimeout, ++ udpretries, task, action, arg, requestp); ++} ++ ++isc_result_t ++dns_request_create2(dns_requestmgr_t *requestmgr, dns_message_t *message, ++ const isc_sockaddr_t *srcaddr, ++ const isc_sockaddr_t *destaddr, ++ dns_transport_t *req_transport, ++ isc_tlsctx_cache_t *req_tls_ctx_cache, unsigned int options, ++ dns_tsigkey_t *key, unsigned int timeout, ++ unsigned int udptimeout, unsigned int udpretries, ++ isc_task_t *task, isc_taskaction_t action, void *arg, ++ dns_request_t **requestp) { + dns_request_t *request = NULL; + isc_result_t result; + isc_mem_t *mctx = NULL; +@@ -707,14 +737,15 @@ dns_request_create(dns_requestmgr_t *requestmgr, dns_message_t *message, + + again: + result = get_dispatch(tcp, false, requestmgr, srcaddr, destaddr, +- &request->dispatch); ++ req_transport, &request->dispatch); + if (result != ISC_R_SUCCESS) { + goto detach; + } + +- result = dns_dispatch_add( +- request->dispatch, 0, request->timeout, destaddr, req_connected, +- req_senddone, req_response, request, &id, &request->dispentry); ++ result = dns_dispatch_add2(request->dispatch, 0, request->timeout, ++ destaddr, req_transport, req_tls_ctx_cache, ++ req_connected, req_senddone, req_response, ++ request, &id, &request->dispentry); + if (result != ISC_R_SUCCESS) { + goto detach; + } +diff --git a/lib/dns/transport.c b/lib/dns/transport.c +index ae1ab7415b1..59eba1db252 100644 +--- a/lib/dns/transport.c ++++ b/lib/dns/transport.c +@@ -15,9 +15,11 @@ + + #include + #include ++#include + #include + #include + #include ++#include + #include + + #include +@@ -54,6 +56,7 @@ struct dns_transport { + char *ciphers; + uint32_t protocol_versions; + ternary_t prefer_server_ciphers; ++ bool always_verify_remote; + } tls; + struct { + char *endpoint; +@@ -332,6 +335,256 @@ dns_transport_get_prefer_server_ciphers(const dns_transport_t *transport, + return false; + } + ++void ++dns_transport_set_always_verify_remote(dns_transport_t *transport, ++ const bool always_verify_remote) { ++ REQUIRE(VALID_TRANSPORT(transport)); ++ REQUIRE(transport->type == DNS_TRANSPORT_TLS || ++ transport->type == DNS_TRANSPORT_HTTP); ++ ++ transport->tls.always_verify_remote = always_verify_remote; ++} ++ ++bool ++dns_transport_get_always_verify_remote(dns_transport_t *transport) { ++ REQUIRE(VALID_TRANSPORT(transport)); ++ REQUIRE(transport->type == DNS_TRANSPORT_TLS || ++ transport->type == DNS_TRANSPORT_HTTP); ++ ++ return transport->tls.always_verify_remote; ++} ++ ++isc_result_t ++dns_transport_get_tlsctx(dns_transport_t *transport, const isc_sockaddr_t *peer, ++ isc_tlsctx_cache_t *tlsctx_cache, isc_mem_t *mctx, ++ isc_tlsctx_t **pctx, ++ isc_tlsctx_client_session_cache_t **psess_cache) { ++ isc_result_t result = ISC_R_FAILURE; ++ isc_tlsctx_t *tlsctx = NULL, *found = NULL; ++ isc_tls_cert_store_t *store = NULL, *found_store = NULL; ++ isc_tlsctx_client_session_cache_t *sess_cache = NULL; ++ isc_tlsctx_client_session_cache_t *found_sess_cache = NULL; ++ uint32_t tls_versions; ++ const char *ciphers = NULL; ++ bool prefer_server_ciphers; ++ uint16_t family; ++ const char *tlsname = NULL; ++ ++ REQUIRE(VALID_TRANSPORT(transport)); ++ REQUIRE(transport->type == DNS_TRANSPORT_TLS); ++ REQUIRE(peer != NULL); ++ REQUIRE(tlsctx_cache != NULL); ++ REQUIRE(mctx != NULL); ++ REQUIRE(pctx != NULL && *pctx == NULL); ++ REQUIRE(psess_cache != NULL && *psess_cache == NULL); ++ ++ family = (isc_sockaddr_pf(peer) == PF_INET6) ? AF_INET6 : AF_INET; ++ ++ tlsname = dns_transport_get_tlsname(transport); ++ INSIST(tlsname != NULL && *tlsname != '\0'); ++ ++ /* ++ * Let's try to re-use the already created context. This way ++ * we have a chance to resume the TLS session, bypassing the ++ * full TLS handshake procedure, making establishing ++ * subsequent TLS connections faster. ++ */ ++ result = isc_tlsctx_cache_find(tlsctx_cache, tlsname, ++ isc_tlsctx_cache_tls, family, &found, ++ &found_store, &found_sess_cache); ++ if (result != ISC_R_SUCCESS) { ++ const char *hostname = ++ dns_transport_get_remote_hostname(transport); ++ const char *ca_file = dns_transport_get_cafile(transport); ++ const char *cert_file = dns_transport_get_certfile(transport); ++ const char *key_file = dns_transport_get_keyfile(transport); ++ const bool always_verify_remote = ++ dns_transport_get_always_verify_remote(transport); ++ char peer_addr_str[INET6_ADDRSTRLEN] = { 0 }; ++ isc_netaddr_t peer_netaddr = { 0 }; ++ bool hostname_ignore_subject; ++ ++ /* ++ * So, no context exists. Let's create one using the ++ * parameters from the configuration file and try to ++ * store it for further reuse. ++ */ ++ result = isc_tlsctx_createclient(&tlsctx); ++ if (result != ISC_R_SUCCESS) { ++ goto failure; ++ } ++ tls_versions = dns_transport_get_tls_versions(transport); ++ if (tls_versions != 0) { ++ isc_tlsctx_set_protocols(tlsctx, tls_versions); ++ } ++ ciphers = dns_transport_get_ciphers(transport); ++ if (ciphers != NULL) { ++ isc_tlsctx_set_cipherlist(tlsctx, ciphers); ++ } ++ ++ if (dns_transport_get_prefer_server_ciphers( ++ transport, &prefer_server_ciphers)) ++ { ++ isc_tlsctx_prefer_server_ciphers(tlsctx, ++ prefer_server_ciphers); ++ } ++ ++ if (always_verify_remote || hostname != NULL || ca_file != NULL) ++ { ++ /* ++ * The situation when 'found_store != NULL' while ++ * 'found == NULL' may occur as there is a one-to-many ++ * relation between cert stores and per-transport TLS ++ * contexts. That is, there could be one store ++ * shared between multiple contexts. ++ */ ++ if (found_store == NULL) { ++ /* ++ * 'ca_file' can equal 'NULL' here, in ++ * which case the store with system-wide ++ * CA certificates will be created. ++ */ ++ result = isc_tls_cert_store_create(ca_file, ++ &store); ++ ++ if (result != ISC_R_SUCCESS) { ++ goto failure; ++ } ++ } else { ++ store = found_store; ++ } ++ ++ INSIST(store != NULL); ++ if (hostname == NULL) { ++ /* ++ * If hostname is not specified, then use the ++ * peer IP address for validation. ++ */ ++ isc_netaddr_fromsockaddr(&peer_netaddr, peer); ++ isc_netaddr_format(&peer_netaddr, peer_addr_str, ++ sizeof(peer_addr_str)); ++ hostname = peer_addr_str; ++ } ++ ++ /* ++ * According to RFC 8310, Subject field MUST NOT ++ * be inspected when verifying hostname for DoT. ++ * Only SubjectAltName must be checked. ++ */ ++ hostname_ignore_subject = true; ++ result = isc_tlsctx_enable_peer_verification( ++ tlsctx, false, store, hostname, ++ hostname_ignore_subject); ++ if (result != ISC_R_SUCCESS) { ++ goto failure; ++ } ++ ++ /* ++ * Let's load client certificate and enable ++ * Mutual TLS. We do that only in the case when ++ * Strict TLS is enabled, because Mutual TLS is ++ * an extension of it. ++ */ ++ if (cert_file != NULL) { ++ INSIST(key_file != NULL); ++ ++ result = isc_tlsctx_load_certificate( ++ tlsctx, key_file, cert_file); ++ if (result != ISC_R_SUCCESS) { ++ goto failure; ++ } ++ } ++ } ++ ++ isc_tlsctx_enable_dot_client_alpn(tlsctx); ++ ++ isc_tlsctx_client_session_cache_create( ++ mctx, tlsctx, ++ ISC_TLSCTX_CLIENT_SESSION_CACHE_DEFAULT_SIZE, ++ &sess_cache); ++ ++ found_store = NULL; ++ result = isc_tlsctx_cache_add(tlsctx_cache, tlsname, ++ isc_tlsctx_cache_tls, family, ++ tlsctx, store, sess_cache, &found, ++ &found_store, &found_sess_cache); ++ if (result == ISC_R_EXISTS) { ++ /* ++ * It seems the entry has just been created from ++ * within another thread while we were initialising ++ * ours. Although this is unlikely, it could happen ++ * after startup/re-initialisation. In such a case, ++ * discard the new context and associated data and use ++ * the already established one from now on. ++ * ++ * Such situation will not occur after the ++ * initial 'warm-up', so it is not critical ++ * performance-wise. ++ */ ++ INSIST(found != NULL); ++ isc_tlsctx_free(&tlsctx); ++ /* ++ * The 'store' variable can be 'NULL' when remote server ++ * verification is not enabled (that is, when Strict or ++ * Mutual TLS are not used). ++ * ++ * The 'found_store' might be equal to 'store' as there ++ * is one-to-many relation between a store and ++ * per-transport TLS contexts. In that case, the call to ++ * 'isc_tlsctx_cache_find()' above could have returned a ++ * store via the 'found_store' variable, whose value we ++ * can assign to 'store' later. In that case, ++ * 'isc_tlsctx_cache_add()' will return the same value. ++ * When that happens, we should not free the store ++ * object, as it is managed by the TLS context cache. ++ */ ++ if (store != NULL && store != found_store) { ++ isc_tls_cert_store_free(&store); ++ } ++ isc_tlsctx_client_session_cache_detach(&sess_cache); ++ /* Let's return the data from the cache. */ ++ *psess_cache = found_sess_cache; ++ *pctx = found; ++ } else { ++ /* ++ * Adding the fresh values into the cache has been ++ * successful, let's return them ++ */ ++ INSIST(result == ISC_R_SUCCESS); ++ *psess_cache = sess_cache; ++ *pctx = tlsctx; ++ } ++ } else { ++ /* ++ * The cache lookup has been successful, let's return the ++ * results. ++ */ ++ INSIST(result == ISC_R_SUCCESS); ++ *psess_cache = found_sess_cache; ++ *pctx = found; ++ } ++ ++ return ISC_R_SUCCESS; ++ ++failure: ++ if (tlsctx != NULL) { ++ isc_tlsctx_free(&tlsctx); ++ } ++ ++ /* ++ * The 'found_store' is being managed by the TLS context ++ * cache. Thus, we should keep it as it is, as it will get ++ * destroyed alongside the cache. As there is one store per ++ * multiple TLS contexts, we need to handle store deletion in a ++ * special way. ++ */ ++ if (store != NULL && store != found_store) { ++ isc_tls_cert_store_free(&store); ++ } ++ ++ return result; ++} ++ + static void + transport_destroy(dns_transport_t *transport) { + isc_refcount_destroy(&transport->references); +diff --git a/lib/dns/xfrin.c b/lib/dns/xfrin.c +index e5f1e0b536e..c7080765a02 100644 +--- a/lib/dns/xfrin.c ++++ b/lib/dns/xfrin.c +@@ -963,234 +963,6 @@ xfrin_create(isc_mem_t *mctx, dns_zone_t *zone, dns_db_t *db, isc_nm_t *netmgr, + *xfrp = xfr; + } + +-static isc_result_t +-get_create_tlsctx(const dns_xfrin_ctx_t *xfr, isc_tlsctx_t **pctx, +- isc_tlsctx_client_session_cache_t **psess_cache) { +- isc_result_t result = ISC_R_FAILURE; +- isc_tlsctx_t *tlsctx = NULL, *found = NULL; +- isc_tls_cert_store_t *store = NULL, *found_store = NULL; +- isc_tlsctx_client_session_cache_t *sess_cache = NULL, +- *found_sess_cache = NULL; +- uint32_t tls_versions; +- const char *ciphers = NULL; +- bool prefer_server_ciphers; +- const uint16_t family = isc_sockaddr_pf(&xfr->primaryaddr) == PF_INET6 +- ? AF_INET6 +- : AF_INET; +- const char *tlsname = NULL; +- +- REQUIRE(psess_cache != NULL && *psess_cache == NULL); +- REQUIRE(pctx != NULL && *pctx == NULL); +- +- INSIST(xfr->transport != NULL); +- tlsname = dns_transport_get_tlsname(xfr->transport); +- INSIST(tlsname != NULL && *tlsname != '\0'); +- +- /* +- * Let's try to re-use the already created context. This way +- * we have a chance to resume the TLS session, bypassing the +- * full TLS handshake procedure, making establishing +- * subsequent TLS connections for XoT faster. +- */ +- result = isc_tlsctx_cache_find(xfr->tlsctx_cache, tlsname, +- isc_tlsctx_cache_tls, family, &found, +- &found_store, &found_sess_cache); +- if (result != ISC_R_SUCCESS) { +- const char *hostname = +- dns_transport_get_remote_hostname(xfr->transport); +- const char *ca_file = dns_transport_get_cafile(xfr->transport); +- const char *cert_file = +- dns_transport_get_certfile(xfr->transport); +- const char *key_file = +- dns_transport_get_keyfile(xfr->transport); +- char primary_addr_str[INET6_ADDRSTRLEN] = { 0 }; +- isc_netaddr_t primary_netaddr = { 0 }; +- bool hostname_ignore_subject; +- /* +- * So, no context exists. Let's create one using the +- * parameters from the configuration file and try to +- * store it for further reuse. +- */ +- result = isc_tlsctx_createclient(&tlsctx); +- if (result != ISC_R_SUCCESS) { +- goto failure; +- } +- tls_versions = dns_transport_get_tls_versions(xfr->transport); +- if (tls_versions != 0) { +- isc_tlsctx_set_protocols(tlsctx, tls_versions); +- } +- ciphers = dns_transport_get_ciphers(xfr->transport); +- if (ciphers != NULL) { +- isc_tlsctx_set_cipherlist(tlsctx, ciphers); +- } +- +- if (dns_transport_get_prefer_server_ciphers( +- xfr->transport, &prefer_server_ciphers)) +- { +- isc_tlsctx_prefer_server_ciphers(tlsctx, +- prefer_server_ciphers); +- } +- +- if (hostname != NULL || ca_file != NULL) { +- /* +- * The situation when 'found_store != NULL' while 'found +- * == NULL' might appear as there is one to many +- * relation between per transport TLS contexts and cert +- * stores. That is, there could be one store shared +- * between multiple contexts. +- */ +- if (found_store == NULL) { +- /* +- * 'ca_file' can equal 'NULL' here, in +- * that case the store with system-wide +- * CA certificates will be created, just +- * as planned. +- */ +- result = isc_tls_cert_store_create(ca_file, +- &store); +- +- if (result != ISC_R_SUCCESS) { +- goto failure; +- } +- } else { +- store = found_store; +- } +- +- INSIST(store != NULL); +- if (hostname == NULL) { +- /* +- * If CA bundle file is specified, but +- * hostname is not, then use the primary +- * IP address for validation, just like +- * dig does. +- */ +- INSIST(ca_file != NULL); +- isc_netaddr_fromsockaddr(&primary_netaddr, +- &xfr->primaryaddr); +- isc_netaddr_format(&primary_netaddr, +- primary_addr_str, +- sizeof(primary_addr_str)); +- hostname = primary_addr_str; +- } +- /* +- * According to RFC 8310, Subject field MUST NOT +- * be inspected when verifying hostname for DoT. +- * Only SubjectAltName must be checked. +- */ +- hostname_ignore_subject = true; +- result = isc_tlsctx_enable_peer_verification( +- tlsctx, false, store, hostname, +- hostname_ignore_subject); +- if (result != ISC_R_SUCCESS) { +- goto failure; +- } +- +- /* +- * Let's load client certificate and enable +- * Mutual TLS. We do that only in the case when +- * Strict TLS is enabled, because Mutual TLS is +- * an extension of it. +- */ +- if (cert_file != NULL) { +- INSIST(key_file != NULL); +- +- result = isc_tlsctx_load_certificate( +- tlsctx, key_file, cert_file); +- if (result != ISC_R_SUCCESS) { +- goto failure; +- } +- } +- } +- +- isc_tlsctx_enable_dot_client_alpn(tlsctx); +- +- isc_tlsctx_client_session_cache_create( +- xfr->mctx, tlsctx, +- ISC_TLSCTX_CLIENT_SESSION_CACHE_DEFAULT_SIZE, +- &sess_cache); +- +- found_store = NULL; +- result = isc_tlsctx_cache_add(xfr->tlsctx_cache, tlsname, +- isc_tlsctx_cache_tls, family, +- tlsctx, store, sess_cache, &found, +- &found_store, &found_sess_cache); +- if (result == ISC_R_EXISTS) { +- /* +- * It seems the entry has just been created from within +- * another thread while we were initialising +- * ours. Although this is unlikely, it could happen +- * after startup/re-initialisation. In such a case, +- * discard the new context and associated data and use +- * the already established one from now on. +- * +- * Such situation will not occur after the +- * initial 'warm-up', so it is not critical +- * performance-wise. +- */ +- INSIST(found != NULL); +- isc_tlsctx_free(&tlsctx); +- /* +- * The 'store' variable can be 'NULL' when remote server +- * verification is not enabled (that is, when Strict or +- * Mutual TLS are not used). +- * +- * The 'found_store' might be equal to 'store' as there +- * is one-to-many relation between a store and +- * per-transport TLS contexts. In that case, the call to +- * 'isc_tlsctx_cache_find()' above could have returned a +- * store via the 'found_store' variable, whose value we +- * can assign to 'store' later. In that case, +- * 'isc_tlsctx_cache_add()' will return the same value. +- * When that happens, we should not free the store +- * object, as it is managed by the TLS context cache. +- */ +- if (store != NULL && store != found_store) { +- isc_tls_cert_store_free(&store); +- } +- isc_tlsctx_client_session_cache_detach(&sess_cache); +- /* Let's return the data from the cache. */ +- *psess_cache = found_sess_cache; +- *pctx = found; +- } else { +- /* +- * Adding the fresh values into the cache has been +- * successful, let's return them +- */ +- INSIST(result == ISC_R_SUCCESS); +- *psess_cache = sess_cache; +- *pctx = tlsctx; +- } +- } else { +- /* +- * The cache lookup has been successful, let's return the +- * results. +- */ +- INSIST(result == ISC_R_SUCCESS); +- *psess_cache = found_sess_cache; +- *pctx = found; +- } +- +- return (ISC_R_SUCCESS); +- +-failure: +- if (tlsctx != NULL) { +- isc_tlsctx_free(&tlsctx); +- } +- +- /* +- * The 'found_store' is being managed by the TLS context +- * cache. Thus, we should keep it as it is, as it will get +- * destroyed alongside the cache. As there is one store per +- * multiple TLS contexts, we need to handle store deletion in a +- * special way. +- */ +- if (store != NULL && store != found_store) { +- isc_tls_cert_store_free(&store); +- } +- +- return (result); +-} +- + static isc_result_t + xfrin_start(dns_xfrin_ctx_t *xfr) { + isc_result_t result; +@@ -1233,7 +1005,9 @@ xfrin_start(dns_xfrin_ctx_t *xfr) { + connect_xfr, 30000, 0); + break; + case DNS_TRANSPORT_TLS: { +- result = get_create_tlsctx(xfr, &tlsctx, &sess_cache); ++ result = dns_transport_get_tlsctx( ++ xfr->transport, &xfr->primaryaddr, xfr->tlsctx_cache, ++ xfr->mctx, &tlsctx, &sess_cache); + if (result != ISC_R_SUCCESS) { + goto failure; + } +-- +2.48.1 + diff --git a/bind-9.18-unittest-netmgr-unstable.patch b/SOURCES/bind-9.18-unittest-netmgr-unstable.patch similarity index 100% rename from bind-9.18-unittest-netmgr-unstable.patch rename to SOURCES/bind-9.18-unittest-netmgr-unstable.patch diff --git a/SOURCES/bind-9.18.29.tar.xz.asc b/SOURCES/bind-9.18.29.tar.xz.asc new file mode 100644 index 0000000..ecf6dc3 --- /dev/null +++ b/SOURCES/bind-9.18.29.tar.xz.asc @@ -0,0 +1,16 @@ +-----BEGIN PGP SIGNATURE----- + +iQIzBAABCgAdFiEE2ZzOr4eXRwFPA41jGC4jV5Ri76oFAma+DmEACgkQGC4jV5Ri +76q1FQ/8CXrIA21FAdnGuGqC53EVOzFl3QptFMThoVTO0kzp7rQcwv8xE/gphXnT +j4DWMAZ/tDW6ZalDbmCh6t+z/0pXewHB+43CILSkzU9Gi5gnAUHdIdlGQnYH/x2N +eyHBKuB9Wubmi87Yu8zjtF+Xu43qgcYqNKP/QqU9YwsqPQ+7GgcKAETVidFMB9/4 +QZiMT4gMawguft+BwFZ1eYvk0Bemk0OkKhofyWDcVnl5r93pvTIK3SsIHyEHx7xu +dbG9Z5HhoaJ8b48djahrrYSQCQ0Dn9KbEVLu+/BS5tz+k+V1VI1pk4OS15wn7yBZ +8EqAGc5xj4MEKW7PEteOK7QQQE59yKY6SGwt+tQwokUZ/Rq4bAx2bHXY83oRBULo +BIRDdgoxc9X44YQ/a55La+7/xq2eCYwW2s364R4To3K58nPCNlkdEQUziY1V7guR +3zOcHPAZNe5bK7bN3BMDusQgtoerfSUC1x+zj5Nm9Xnb/yAtVUyiP/k/zlIds9W3 +rKSCM5FAuacZdWQKeVpRa1EaXhObm08qLO9a/Dc/Qvll8GKAmrMoll2WwEoUVlZ3 +HwZPRsPIWYSCemtHmp36b7nOZ0vo4NMXjb2nV7xW3a8BqOD3RW0XiTlC814qmqsU +x16eOHowvtDw58abeBzPJ2k1yne1Ic2zBdJzUM9wqdJCoBN5g0A= +=2EW2 +-----END PGP SIGNATURE----- diff --git a/SOURCES/bind-9.5-PIE.patch b/SOURCES/bind-9.5-PIE.patch new file mode 100644 index 0000000..9744f69 --- /dev/null +++ b/SOURCES/bind-9.5-PIE.patch @@ -0,0 +1,28 @@ +From 13348a5fc64387bf53ef450688e181100d0ceddb Mon Sep 17 00:00:00 2001 +From: Petr Mensik +Date: Thu, 12 Dec 2024 15:56:13 +0100 +Subject: [PATCH] Harden named service build flags + +--- + bin/named/Makefile.am | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/bin/named/Makefile.am b/bin/named/Makefile.am +index 57a023b..b832e9c 100644 +--- a/bin/named/Makefile.am ++++ b/bin/named/Makefile.am +@@ -33,7 +33,10 @@ endif HAVE_LIBXML2 + + AM_CPPFLAGS += \ + -DNAMED_LOCALSTATEDIR=\"${localstatedir}\" \ +- -DNAMED_SYSCONFDIR=\"${sysconfdir}\" ++ -DNAMED_SYSCONFDIR=\"${sysconfdir}\" \ ++ -fpie ++ ++AM_LDFLAGS += -pie -Wl,-z,relro,-z,now,-z,nodlopen,-z,noexecstack + + sbin_PROGRAMS = named + +-- +2.47.1 + diff --git a/bind.tmpfiles.d b/SOURCES/bind.tmpfiles.d similarity index 100% rename from bind.tmpfiles.d rename to SOURCES/bind.tmpfiles.d diff --git a/generate-rndc-key.sh b/SOURCES/generate-rndc-key.sh similarity index 100% rename from generate-rndc-key.sh rename to SOURCES/generate-rndc-key.sh diff --git a/isc-keyblock.asc b/SOURCES/isc-keyblock.asc similarity index 100% rename from isc-keyblock.asc rename to SOURCES/isc-keyblock.asc diff --git a/named-chroot-setup.service b/SOURCES/named-chroot-setup.service similarity index 100% rename from named-chroot-setup.service rename to SOURCES/named-chroot-setup.service diff --git a/named-chroot.files b/SOURCES/named-chroot.files similarity index 100% rename from named-chroot.files rename to SOURCES/named-chroot.files diff --git a/named-chroot.service b/SOURCES/named-chroot.service similarity index 100% rename from named-chroot.service rename to SOURCES/named-chroot.service diff --git a/named-setup-rndc.service b/SOURCES/named-setup-rndc.service similarity index 100% rename from named-setup-rndc.service rename to SOURCES/named-setup-rndc.service diff --git a/named.conf b/SOURCES/named.conf similarity index 100% rename from named.conf rename to SOURCES/named.conf diff --git a/named.conf.sample b/SOURCES/named.conf.sample similarity index 100% rename from named.conf.sample rename to SOURCES/named.conf.sample diff --git a/named.empty b/SOURCES/named.empty similarity index 100% rename from named.empty rename to SOURCES/named.empty diff --git a/named.localhost b/SOURCES/named.localhost similarity index 100% rename from named.localhost rename to SOURCES/named.localhost diff --git a/named.logrotate b/SOURCES/named.logrotate similarity index 100% rename from named.logrotate rename to SOURCES/named.logrotate diff --git a/named.loopback b/SOURCES/named.loopback similarity index 100% rename from named.loopback rename to SOURCES/named.loopback diff --git a/named.rfc1912.zones b/SOURCES/named.rfc1912.zones similarity index 100% rename from named.rfc1912.zones rename to SOURCES/named.rfc1912.zones diff --git a/named.root b/SOURCES/named.root similarity index 100% rename from named.root rename to SOURCES/named.root diff --git a/named.root.key b/SOURCES/named.root.key similarity index 100% rename from named.root.key rename to SOURCES/named.root.key diff --git a/named.rwtab b/SOURCES/named.rwtab similarity index 100% rename from named.rwtab rename to SOURCES/named.rwtab diff --git a/named.service b/SOURCES/named.service similarity index 100% rename from named.service rename to SOURCES/named.service diff --git a/named.sysconfig b/SOURCES/named.sysconfig similarity index 100% rename from named.sysconfig rename to SOURCES/named.sysconfig diff --git a/setup-named-chroot.sh b/SOURCES/setup-named-chroot.sh similarity index 100% rename from setup-named-chroot.sh rename to SOURCES/setup-named-chroot.sh diff --git a/setup-named-softhsm.sh b/SOURCES/setup-named-softhsm.sh similarity index 100% rename from setup-named-softhsm.sh rename to SOURCES/setup-named-softhsm.sh diff --git a/trusted-key.key b/SOURCES/trusted-key.key similarity index 100% rename from trusted-key.key rename to SOURCES/trusted-key.key diff --git a/bind9.18.spec b/SPECS/bind9.18.spec similarity index 99% rename from bind9.18.spec rename to SPECS/bind9.18.spec index 385faab..29865f3 100644 --- a/bind9.18.spec +++ b/SPECS/bind9.18.spec @@ -77,7 +77,7 @@ License: MPL-2.0 AND ISC AND MIT AND BSD-3-Clause AND BSD-2-Clause # ./lib/isc/tm.c BSD-2-clause and/or MPL-2.0 # ./lib/isccfg/parser.c BSD-2-clause and/or MPL-2.0 Version: 9.18.29 -Release: 1%{?dist} +Release: 3%{?dist} Epoch: 32 Url: https://www.isc.org/downloads/bind/ # @@ -114,6 +114,16 @@ Patch10: bind-9.5-PIE.patch Patch16: bind-9.16-redhat_doc.patch # https://bugzilla.redhat.com/show_bug.cgi?id=2122010 Patch26: bind-9.18-unittest-netmgr-unstable.patch +# https://issues.redhat.com/browse/FREEIPA-11706 +# https://issues.redhat.com/browse/RHEL-76331 +Patch27: bind-9.18-nsupdate-TLS.patch +Patch28: bind-9.18-nsupdate-TLS-doc.patch +Patch29: bind-9.18-nsupdate-TLS-tests.patch +# https://gitlab.isc.org/isc-projects/bind9/-/commit/c6e6a7af8ac6b575dd3657b0f5cf4248d734c2b0 +Patch30: bind-9.18-CVE-2024-11187-pre-test.patch +Patch31: bind-9.18-CVE-2024-11187.patch +# https://gitlab.isc.org/isc-projects/bind9/-/commit/e733e624147155d6cbee7f0f150c79c7ac6b54bb +Patch32: bind-9.18-CVE-2024-12705.patch %{?systemd_ordering} Requires: coreutils @@ -961,6 +971,15 @@ fi; %endif %changelog +* Mon Feb 03 2025 Petr Menšík - 32:9.18.29-3 +- Limit additional section records CPU processing (CVE-2024-11187) +- Read HTTPS requests in limited chunks and prevent overload (CVE-2024-12705) + +* Mon Jan 27 2025 Petr Menšík - 32:9.18.29-2 +- Backport nsupdate TLS support into 9.18 (RHEL-76331) +- Update nsupdate manual about new TLS options +- Test nsupdate TLS support + * Wed Aug 21 2024 Petr Menšík - 32:9.18.29-1 - Update to 9.18.29 (RHEL-53015) diff --git a/bind-9.11.12.tar.gz.asc b/bind-9.11.12.tar.gz.asc deleted file mode 100644 index 6d7992f..0000000 --- a/bind-9.11.12.tar.gz.asc +++ /dev/null @@ -1,16 +0,0 @@ ------BEGIN PGP SIGNATURE----- - -iQIzBAABAgAdFiEErj+seWcR7Fn8AHqkdLtrmky7PTgFAl2WMooACgkQdLtrmky7 -PThv2RAAnXNLYTzXtH6ls29tRm5Hc+D6UaeqcWDNQ4BpkRVhrFxtukalGCi9mmB6 -NPJzFyXmaOW654pypCIuEgqJNFUpDtLzLzT7SUF+mhm+5plsaRSBnh4mq87l5KSp -twODAPnfCJV+HBk5RmToLEstAbGQ7xEBTyQtZoFkY+V7zEFwENKiCvWsoSWOkYR3 -zXo3sKjc83HV9ShbW/mCtbZf5L0qlbrKOAzqJfAFMhNNJi8kMbmr/Zi2sIfN+Rhv -g8HQo89Epv6r51yAdeED8idIX4rKjjcEtHrZeDmLdCcdHgSEj2sIlH92Joce6vL0 -S59A0rItIXm6fW8sz6WNpcj4tVtWYbIYjXZ4SPFNkaUrHv8cUekq+5vbI+v07Gh3 -2bhtDsDyTY5I1/AsY/EFmwkCAjUS00jZryBnuJpLB3v5JtUog4ek32yLBzPrqRBo -1876j4nlXAia8mG0OgJNWZ0gHyUPe/TgfR8fQDLmHxHHlKrJNTEwY6bLW8jzFTX1 -zk510fI1K7J9tiQgf5wcBQ2h3EBlqzDNIJDovoATzLYIf0HKyVegh/vnQdtdEhUR -1DzJAt3bsBfAP1AFfWPD/ACu5Zdm7SxY1wE/pjkwttDU3sRZqOfuwNBGeolu3cVN -O9/h1zsyVeVS0ui2vu4+V4EvNitmXsVbG2doDq9L5yBiIKGO2Ew= -=GCy6 ------END PGP SIGNATURE----- diff --git a/bind-9.14.7.tar.gz.asc b/bind-9.14.7.tar.gz.asc deleted file mode 100644 index 1134ae1..0000000 --- a/bind-9.14.7.tar.gz.asc +++ /dev/null @@ -1,16 +0,0 @@ ------BEGIN PGP SIGNATURE----- - -iQIzBAABAgAdFiEErj+seWcR7Fn8AHqkdLtrmky7PTgFAl2WMpEACgkQdLtrmky7 -PTh/sg//QbNRAQvADQfwF1PPo+JxB+3WzQ9oJAWeHbOoiubwkUwO9xE+BEnTNd5o -oM1lSLqFxNykOTaoeJlqPftPod1cxo7lSzkwflugGyB/59wliCpqCg053YV4x9mO -QggvA/E50+0FI/Om/7v4GHGADu/JE83FovOueWAB0LgqfDSD6QFcNFF9sUJJ4P7r -FcEXSWj8QbrHMWBKncZUOpD2ECotvtrYmi0DTHl1XfigESDQpWtsnTFuabCCsvkh -ch9wQRplAes2Mf/aS5tl1y0QKKBFuEjtGiTdgrDl6o9GLnx6CueX5saZehu2EVkr -fq2vEYUC2lRQSjuxSMMJ3L0TGUcl7+ixlAIISS2K9L5Xx7MhBXt/EH5KiKPfsEet -3EH+DhxV5uXjDU7MgvREnxT+ssV23e0HWTz4tVVQ9LpvYmWPIgLcSOhHCc57yoQF -c46V0f69dMWbMAlQ93EZSG274ZvpIszpK8+3hGI3/TuDFFgiQJeJJBFVtYJMle69 -3mEEclfzO7fBiXZFec6nVx2309bL64bafN7zszPKXl4XgoefOfD0v0eWqQT4fxfm -dnGC0qMqSZs5F+d0fISV5JUUNYzt9PZjvnzqLLGOeTF6l3/n9G1mmNsXcxJ1OEIF -6qh1oO7JTPjt0MFhKac4QjNQi/Bnp25O3I/PRyWZCbiwXkyvyQU= -=ZT7s ------END PGP SIGNATURE----- diff --git a/bind-9.5-PIE.patch b/bind-9.5-PIE.patch deleted file mode 100644 index 1420cf3..0000000 --- a/bind-9.5-PIE.patch +++ /dev/null @@ -1,17 +0,0 @@ -diff --git a/bin/named/Makefile.am b/bin/named/Makefile.am -index 57a023b..085f2f7 100644 ---- a/bin/named/Makefile.am -+++ b/bin/named/Makefile.am -@@ -32,9 +32,12 @@ AM_CPPFLAGS += \ - endif HAVE_LIBXML2 - - AM_CPPFLAGS += \ -+ -fpie \ - -DNAMED_LOCALSTATEDIR=\"${localstatedir}\" \ - -DNAMED_SYSCONFDIR=\"${sysconfdir}\" - -+AM_LDFLAGS += -pie -Wl,-z,relro,-z,now,-z,nodlopen,-z,noexecstack -+ - sbin_PROGRAMS = named - - nodist_named_SOURCES = xsl.c diff --git a/bind97-exportlib.patch b/bind97-exportlib.patch deleted file mode 100644 index 4468ef5..0000000 --- a/bind97-exportlib.patch +++ /dev/null @@ -1,226 +0,0 @@ -diff -up bind-9.9.3rc2/isc-config.sh.in.exportlib bind-9.9.3rc2/isc-config.sh.in -diff -up bind-9.9.3rc2/lib/export/dns/Makefile.in.exportlib bind-9.9.3rc2/lib/export/dns/Makefile.in ---- bind-9.9.3rc2/lib/export/dns/Makefile.in.exportlib 2013-04-30 08:38:46.000000000 +0200 -+++ bind-9.9.3rc2/lib/export/dns/Makefile.in 2013-05-13 10:45:22.574089729 +0200 -@@ -35,9 +35,9 @@ CDEFINES = -DUSE_MD5 @USE_OPENSSL@ @USE_ - - CWARNINGS = - --ISCLIBS = ../isc/libisc.@A@ -+ISCLIBS = ../isc/libisc-export.@A@ - --ISCDEPLIBS = ../isc/libisc.@A@ -+ISCDEPLIBS = ../isc/libisc-export.@A@ - - LIBS = @LIBS@ - -@@ -116,29 +116,29 @@ version.@O@: ${srcdir}/version.c - -DLIBAGE=${LIBAGE} \ - -c ${srcdir}/version.c - --libdns.@SA@: ${OBJS} -+libdns-export.@SA@: ${OBJS} - ${AR} ${ARFLAGS} $@ ${OBJS} - ${RANLIB} $@ - --libdns.la: ${OBJS} -+libdns-export.la: ${OBJS} - ${LIBTOOL_MODE_LINK} \ -- ${CC} ${ALL_CFLAGS} ${LDFLAGS} -o libdns.la \ -+ ${CC} ${ALL_CFLAGS} ${LDFLAGS} -o libdns-export.la \ - -rpath ${export_libdir} \ - -version-info ${LIBINTERFACE}:${LIBREVISION}:${LIBAGE} \ - ${OBJS} ${ISCLIBS} @DNS_CRYPTO_LIBS@ ${LIBS} - --timestamp: libdns.@A@ -+timestamp: libdns-export.@A@ - touch timestamp - - installdirs: - $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${export_libdir} - - install:: timestamp installdirs -- ${LIBTOOL_MODE_INSTALL} ${INSTALL_DATA} libdns.@A@ \ -+ ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} libdns-export.@A@ \ - ${DESTDIR}${export_libdir}/ - - clean distclean:: -- rm -f libdns.@A@ timestamp -+ rm -f libdns-export.@A@ timestamp - rm -f gen code.h include/dns/enumtype.h include/dns/enumclass.h - rm -f include/dns/rdatastruct.h - -diff -up bind-9.9.3rc2/lib/export/irs/Makefile.in.exportlib bind-9.9.3rc2/lib/export/irs/Makefile.in ---- bind-9.9.3rc2/lib/export/irs/Makefile.in.exportlib 2013-04-30 08:38:46.000000000 +0200 -+++ bind-9.9.3rc2/lib/export/irs/Makefile.in 2013-05-13 10:45:22.575089729 +0200 -@@ -43,9 +43,9 @@ SRCS = context.c \ - gai_sterror.c getaddrinfo.c getnameinfo.c \ - resconf.c - --ISCLIBS = ../isc/libisc.@A@ --DNSLIBS = ../dns/libdns.@A@ --ISCCFGLIBS = ../isccfg/libisccfg.@A@ -+ISCLIBS = ../isc/libisc-export.@A@ -+DNSLIBS = ../dns/libdns-export.@A@ -+ISCCFGLIBS = ../isccfg/libisccfg-export.@A@ - - LIBS = @LIBS@ - -@@ -62,26 +62,26 @@ version.@O@: ${srcdir}/version.c - -DLIBAGE=${LIBAGE} \ - -c ${srcdir}/version.c - --libirs.@SA@: ${OBJS} version.@O@ -+libirs-export.@SA@: ${OBJS} version.@O@ - ${AR} ${ARFLAGS} $@ ${OBJS} version.@O@ - ${RANLIB} $@ - --libirs.la: ${OBJS} version.@O@ -+libirs-export.la: ${OBJS} version.@O@ - ${LIBTOOL_MODE_LINK} \ -- ${CC} ${ALL_CFLAGS} ${LDFLAGS} -o libirs.la \ -+ ${CC} ${ALL_CFLAGS} ${LDFLAGS} -o libirs-export.la \ - -rpath ${export_libdir} \ - -version-info ${LIBINTERFACE}:${LIBREVISION}:${LIBAGE} \ - ${OBJS} version.@O@ ${LIBS} ${ISCCFGLIBS} ${DNSLIBS} ${ISCLIBS} - --timestamp: libirs.@A@ -+timestamp: libirs-export.@A@ - touch timestamp - - installdirs: - $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${export_libdir} - - install:: timestamp installdirs -- ${LIBTOOL_MODE_INSTALL} ${INSTALL_DATA} libirs.@A@ \ -+ ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} libirs-export.@A@ \ - ${DESTDIR}${export_libdir}/ - - clean distclean:: -- rm -f libirs.@A@ libirs.la timestamp -+ rm -f libirs-export.@A@ libirs-export.la timestamp -diff -up bind-9.9.3rc2/lib/export/isccfg/Makefile.in.exportlib bind-9.9.3rc2/lib/export/isccfg/Makefile.in ---- bind-9.9.3rc2/lib/export/isccfg/Makefile.in.exportlib 2013-04-30 08:38:46.000000000 +0200 -+++ bind-9.9.3rc2/lib/export/isccfg/Makefile.in 2013-05-13 10:45:22.576089729 +0200 -@@ -30,11 +30,11 @@ CINCLUDES = -I. ${DNS_INCLUDES} -I${expo - CDEFINES = - CWARNINGS = - --ISCLIBS = ../isc/libisc.@A@ --DNSLIBS = ../dns/libdns.@A@ @DNS_CRYPTO_LIBS@ -+ISCLIBS = ../isc/libisc-export.@A@ -+DNSLIBS = ../dns/libdns-export.@A@ @DNS_CRYPTO_LIBS@ - - ISCDEPLIBS = ../../lib/isc/libisc.@A@ --ISCCFGDEPLIBS = libisccfg.@A@ -+ISCCFGDEPLIBS = libisccfg-export.@A@ - - LIBS = @LIBS@ - -@@ -58,26 +58,26 @@ version.@O@: ${srcdir}/version.c - -DLIBAGE=${LIBAGE} \ - -c ${srcdir}/version.c - --libisccfg.@SA@: ${OBJS} -+libisccfg-export.@SA@: ${OBJS} - ${AR} ${ARFLAGS} $@ ${OBJS} - ${RANLIB} $@ - --libisccfg.la: ${OBJS} -+libisccfg-export.la: ${OBJS} - ${LIBTOOL_MODE_LINK} \ -- ${CC} ${ALL_CFLAGS} ${LDFLAGS} -o libisccfg.la \ -+ ${CC} ${ALL_CFLAGS} ${LDFLAGS} -o libisccfg-export.la \ - -rpath ${export_libdir} \ - -version-info ${LIBINTERFACE}:${LIBREVISION}:${LIBAGE} \ - ${OBJS} ${LIBS} ${DNSLIBS} ${ISCLIBS} - --timestamp: libisccfg.@A@ -+timestamp: libisccfg-export.@A@ - touch timestamp - - installdirs: - $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${export_libdir} - - install:: timestamp installdirs -- ${LIBTOOL_MODE_INSTALL} ${INSTALL_DATA} libisccfg.@A@ \ -+ ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} libisccfg-export.@A@ \ - ${DESTDIR}${export_libdir}/ - - clean distclean:: -- rm -f libisccfg.@A@ timestamp -+ rm -f libisccfg-export.@A@ timestamp -diff -up bind-9.9.3rc2/lib/export/isc/Makefile.in.exportlib bind-9.9.3rc2/lib/export/isc/Makefile.in ---- bind-9.9.3rc2/lib/export/isc/Makefile.in.exportlib 2013-04-30 08:38:46.000000000 +0200 -+++ bind-9.9.3rc2/lib/export/isc/Makefile.in 2013-05-13 10:45:22.576089729 +0200 -@@ -100,6 +100,10 @@ SRCS = @ISC_EXTRA_SRCS@ \ - - LIBS = @LIBS@ - -+# Note: the order of SUBDIRS is important. -+# Attempt to disable parallel processing. -+.NOTPARALLEL: -+.NO_PARALLEL: - SUBDIRS = include unix nls @ISC_THREAD_DIR@ - TARGETS = timestamp - -@@ -113,26 +117,26 @@ version.@O@: ${srcdir}/version.c - -DLIBAGE=${LIBAGE} \ - -c ${srcdir}/version.c - --libisc.@SA@: ${OBJS} -+libisc-export.@SA@: ${OBJS} - ${AR} ${ARFLAGS} $@ ${OBJS} - ${RANLIB} $@ - --libisc.la: ${OBJS} -+libisc-export.la: ${OBJS} - ${LIBTOOL_MODE_LINK} \ -- ${CC} ${ALL_CFLAGS} ${LDFLAGS} -o libisc.la \ -+ ${CC} ${ALL_CFLAGS} ${LDFLAGS} -o libisc-export.la \ - -rpath ${export_libdir} \ - -version-info ${LIBINTERFACE}:${LIBREVISION}:${LIBAGE} \ - ${OBJS} ${LIBS} - --timestamp: libisc.@A@ -+timestamp: libisc-export.@A@ - touch timestamp - - installdirs: - $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${export_libdir} - - install:: timestamp installdirs -- ${LIBTOOL_MODE_INSTALL} ${INSTALL_DATA} libisc.@A@ \ -+ ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} libisc-export.@A@ \ - ${DESTDIR}${export_libdir} - - clean distclean:: -- rm -f libisc.@A@ libisc.la timestamp -+ rm -f libisc-export.@A@ libisc-export.la timestamp -diff -up bind-9.9.3rc2/lib/export/samples/Makefile.in.exportlib bind-9.9.3rc2/lib/export/samples/Makefile.in ---- bind-9.9.3rc2/lib/export/samples/Makefile.in.exportlib 2013-04-30 08:38:46.000000000 +0200 -+++ bind-9.9.3rc2/lib/export/samples/Makefile.in 2013-05-13 10:45:22.577089729 +0200 -@@ -31,15 +31,15 @@ CINCLUDES = -I${srcdir}/include -I../dns - CDEFINES = - CWARNINGS = - --DNSLIBS = ../dns/libdns.@A@ @DNS_CRYPTO_LIBS@ --ISCLIBS = ../isc/libisc.@A@ --ISCCFGLIBS = ../isccfg/libisccfg.@A@ --IRSLIBS = ../irs/libirs.@A@ -+DNSLIBS = ../dns/libdns-export.@A@ @DNS_CRYPTO_LIBS@ -+ISCLIBS = ../isc/libisc-export.@A@ -+ISCCFGLIBS = ../isccfg/libisccfg-export.@A@ -+IRSLIBS = ../irs/libirs-export.@A@ - --DNSDEPLIBS = ../dns/libdns.@A@ --ISCDEPLIBS = ../isc/libisc.@A@ --ISCCFGDEPLIBS = ../isccfg/libisccfg.@A@ --IRSDEPLIBS = ../irs/libirs.@A@ -+DNSDEPLIBS = ../dns/libdns-export.@A@ -+ISCDEPLIBS = ../isc/libisc-export.@A@ -+ISCCFGDEPLIBS = ../isccfg/libisccfg-export.@A@ -+IRSDEPLIBS = ../irs/libirs-export.@A@ - - DEPLIBS = ${DNSDEPLIBS} ${ISCCFGDEPLIBS} ${ISCDEPLIBS} - diff --git a/ci.fmf b/ci.fmf deleted file mode 100644 index c5aa0e0..0000000 --- a/ci.fmf +++ /dev/null @@ -1 +0,0 @@ -resultsdb-testcase: separate diff --git a/codesign2019.txt b/codesign2019.txt deleted file mode 100644 index 1807b58..0000000 --- a/codesign2019.txt +++ /dev/null @@ -1,252 +0,0 @@ ------BEGIN PGP PUBLIC KEY BLOCK----- -Comment: GPGTools - http://gpgtools.org - -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 -=MkGo ------END PGP PUBLIC KEY BLOCK----- diff --git a/gating.yaml b/gating.yaml deleted file mode 100644 index 8085288..0000000 --- a/gating.yaml +++ /dev/null @@ -1,25 +0,0 @@ ---- !Policy -product_versions: - - fedora-* -decision_context: bodhi_update_push_testing -subject_type: koji_build -rules: - - !PassingTestCaseRule {test_case_name: fedora-ci.koji-build./plans/tier1-public.functional} - -#Rawhide ---- !Policy -product_versions: - - fedora-* -decision_context: bodhi_update_push_stable -subject_type: koji_build -rules: - - !PassingTestCaseRule {test_case_name: fedora-ci.koji-build./plans/tier1-public.functional} - -#gating rhel ---- !Policy -product_versions: - - rhel-* -decision_context: osci_compose_gate -rules: - - !PassingTestCaseRule {test_case_name: osci.brew-build./plans/tier1-public.functional} - - !PassingTestCaseRule {test_case_name: osci.brew-build./plans/tier1-internal.functional} diff --git a/ldap2zone.c b/ldap2zone.c deleted file mode 100644 index 80e7919..0000000 --- a/ldap2zone.c +++ /dev/null @@ -1,411 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Stig Venaas - * $Id: ldap2zone.c,v 1.1 2007/07/24 15:18:00 atkac Exp $ - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - */ - -#define LDAP_DEPRECATED 1 - -#include -#include -#include -#include - -#include - -struct string { - void *data; - size_t len; -}; - -struct assstack_entry { - struct string key; - struct string val; - struct assstack_entry *next; -}; - -struct assstack_entry *assstack_find(struct assstack_entry *stack, struct string *key); -void assstack_push(struct assstack_entry **stack, struct assstack_entry *item); -void assstack_insertbottom(struct assstack_entry **stack, struct assstack_entry *item); -void printsoa(struct string *soa); -void printrrs(char *defaultttl, struct assstack_entry *item); -void print_zone(char *defaultttl, struct assstack_entry *stack); -void usage(char *name); -void err(char *name, const char *msg); -int putrr(struct assstack_entry **stack, struct berval *name, char *type, char *ttl, struct berval *val); - -struct assstack_entry *assstack_find(struct assstack_entry *stack, struct string *key) { - for (; stack; stack = stack->next) - if (stack->key.len == key->len && !memcmp(stack->key.data, key->data, key->len)) - return stack; - return NULL; -} - -void assstack_push(struct assstack_entry **stack, struct assstack_entry *item) { - item->next = *stack; - *stack = item; -} - -void assstack_insertbottom(struct assstack_entry **stack, struct assstack_entry *item) { - struct assstack_entry *p; - - item->next = NULL; - if (!*stack) { - *stack = item; - return; - } - /* find end, should keep track of end somewhere */ - /* really a queue, not a stack */ - p = *stack; - while (p->next) - p = p->next; - p->next = item; -} - -void printsoa(struct string *soa) { - char *s; - size_t i; - - s = (char *)soa->data; - i = 0; - while (i < soa->len) { - putchar(s[i]); - if (s[i++] == ' ') - break; - } - while (i < soa->len) { - putchar(s[i]); - if (s[i++] == ' ') - break; - } - printf("(\n\t\t\t\t"); - while (i < soa->len) { - putchar(s[i]); - if (s[i++] == ' ') - break; - } - printf("; Serialnumber\n\t\t\t\t"); - while (i < soa->len) { - if (s[i] == ' ') - break; - putchar(s[i++]); - } - i++; - printf("\t; Refresh\n\t\t\t\t"); - while (i < soa->len) { - if (s[i] == ' ') - break; - putchar(s[i++]); - } - i++; - printf("\t; Retry\n\t\t\t\t"); - while (i < soa->len) { - if (s[i] == ' ') - break; - putchar(s[i++]); - } - i++; - printf("\t; Expire\n\t\t\t\t"); - while (i < soa->len) { - putchar(s[i++]); - } - printf(" )\t; Minimum TTL\n"); -} - -void printrrs(char *defaultttl, struct assstack_entry *item) { - struct assstack_entry *stack; - char *s; - int first; - size_t i; - char *ttl, *type; - int top; - - s = (char *)item->key.data; - - if (item->key.len == 1 && *s == '@') { - top = 1; - printf("@\t"); - } else { - top = 0; - for (i = 0; i < item->key.len; i++) - putchar(s[i]); - if (item->key.len < 8) - putchar('\t'); - putchar('\t'); - } - - first = 1; - for (stack = (struct assstack_entry *) item->val.data; stack; stack = stack->next) { - ttl = (char *)stack->key.data; - s = strchr(ttl, ' '); - *s++ = '\0'; - type = s; - - if (first) - first = 0; - else - printf("\t\t"); - - if (strcmp(defaultttl, ttl)) - printf("%s", ttl); - putchar('\t'); - - if (top) { - top = 0; - printf("IN\t%s\t", type); - /* Should always be SOA here */ - if (!strcmp(type, "SOA")) { - printsoa(&stack->val); - continue; - } - } else - printf("%s\t", type); - - s = (char *)stack->val.data; - for (i = 0; i < stack->val.len; i++) - putchar(s[i]); - putchar('\n'); - } -} - -void print_zone(char *defaultttl, struct assstack_entry *stack) { - printf("$TTL %s\n", defaultttl); - for (; stack; stack = stack->next) - printrrs(defaultttl, stack); -}; - -void usage(char *name) { - fprintf(stderr, "Usage:%s zone-name LDAP-URL default-ttl [serial]\n", name); - exit(1); -}; - -void err(char *name, const char *msg) { - fprintf(stderr, "%s: %s\n", name, msg); - exit(1); -}; - -int putrr(struct assstack_entry **stack, struct berval *name, char *type, char *ttl, struct berval *val) { - struct string key; - struct assstack_entry *rr, *rrdata; - - /* Do nothing if name or value have 0 length */ - if (!name->bv_len || !val->bv_len) - return 0; - - /* see if already have an entry for this name */ - key.len = name->bv_len; - key.data = name->bv_val; - - rr = assstack_find(*stack, &key); - if (!rr) { - /* Not found, create and push new entry */ - rr = (struct assstack_entry *) malloc(sizeof(struct assstack_entry)); - if (!rr) - return -1; - rr->key.len = name->bv_len; - rr->key.data = (void *) malloc(rr->key.len); - if (!rr->key.data) { - free(rr); - return -1; - } - memcpy(rr->key.data, name->bv_val, name->bv_len); - rr->val.len = sizeof(void *); - rr->val.data = NULL; - if (name->bv_len == 1 && *(char *)name->bv_val == '@') - assstack_push(stack, rr); - else - assstack_insertbottom(stack, rr); - } - - rrdata = (struct assstack_entry *) malloc(sizeof(struct assstack_entry)); - if (!rrdata) { - free(rr->key.data); - free(rr); - return -1; - } - rrdata->key.len = strlen(type) + strlen(ttl) + 1; - rrdata->key.data = (void *) malloc(rrdata->key.len); - if (!rrdata->key.data) { - free(rrdata); - free(rr->key.data); - free(rr); - return -1; - } - sprintf((char *)rrdata->key.data, "%s %s", ttl, type); - - rrdata->val.len = val->bv_len; - rrdata->val.data = (void *) malloc(val->bv_len); - if (!rrdata->val.data) { - free(rrdata->key.data); - free(rrdata); - free(rr->key.data); - free(rr); - return -1; - } - memcpy(rrdata->val.data, val->bv_val, val->bv_len); - - if (!strcmp(type, "SOA")) - assstack_push((struct assstack_entry **) &(rr->val.data), rrdata); - else - assstack_insertbottom((struct assstack_entry **) &(rr->val.data), rrdata); - return 0; -} - -int main(int argc, char **argv) { - char *s, *hostporturl, *base = NULL; - char *ttl, *defaultttl; - LDAP *ld; - char *fltr = NULL; - LDAPMessage *res, *e; - char *a, **ttlvals, **soavals, *serial; - struct berval **vals, **names; - char type[64]; - BerElement *ptr; - int i, j, rc, msgid; - struct assstack_entry *zone = NULL; - - if (argc < 4 || argc > 5) - usage(argv[0]); - - hostporturl = argv[2]; - - if (hostporturl != strstr( hostporturl, "ldap")) - err(argv[0], "Not an LDAP URL"); - - s = strchr(hostporturl, ':'); - - if (!s || strlen(s) < 3 || s[1] != '/' || s[2] != '/') - err(argv[0], "Not an LDAP URL"); - - s = strchr(s+3, '/'); - if (s) { - *s++ = '\0'; - base = s; - s = strchr(base, '?'); - if (s) - err(argv[0], "LDAP URL can only contain host, port and base"); - } - - defaultttl = argv[3]; - - rc = ldap_initialize(&ld, hostporturl); - if (rc != LDAP_SUCCESS) - err(argv[0], "ldap_initialize() failed"); - - if (argc == 5) { - /* serial number specified, check if different from one in SOA */ - fltr = (char *)malloc(strlen(argv[1]) + strlen("(&(relativeDomainName=@)(zoneName=))") + 1); - sprintf(fltr, "(&(relativeDomainName=@)(zoneName=%s))", argv[1]); - msgid = ldap_search(ld, base, LDAP_SCOPE_SUBTREE, fltr, NULL, 0); - if (msgid == -1) - err(argv[0], "ldap_search() failed"); - - while ((rc = ldap_result(ld, msgid, 0, NULL, &res)) != LDAP_RES_SEARCH_RESULT ) { - /* not supporting continuation references at present */ - if (rc != LDAP_RES_SEARCH_ENTRY) - err(argv[0], "ldap_result() returned cont.ref? Exiting"); - - /* only one entry per result message */ - e = ldap_first_entry(ld, res); - if (e == NULL) { - ldap_msgfree(res); - err(argv[0], "ldap_first_entry() failed"); - } - - soavals = ldap_get_values(ld, e, "SOARecord"); - if (soavals) - break; - } - - ldap_msgfree(res); - if (!soavals) { - err(argv[0], "No SOA Record found"); - } - - /* We have a SOA, compare serial numbers */ - /* Only checkinf first value, should be only one */ - s = strchr(soavals[0], ' '); - s++; - s = strchr(s, ' '); - s++; - serial = s; - s = strchr(s, ' '); - *s = '\0'; - if (!strcmp(serial, argv[4])) { - ldap_value_free(soavals); - err(argv[0], "serial numbers match"); - } - ldap_value_free(soavals); - } - - if (!fltr) - fltr = (char *)malloc(strlen(argv[1]) + strlen("(zoneName=)") + 1); - if (!fltr) - err(argv[0], "Malloc failed"); - sprintf(fltr, "(zoneName=%s)", argv[1]); - - msgid = ldap_search(ld, base, LDAP_SCOPE_SUBTREE, fltr, NULL, 0); - if (msgid == -1) - err(argv[0], "ldap_search() failed"); - - while ((rc = ldap_result(ld, msgid, 0, NULL, &res)) != LDAP_RES_SEARCH_RESULT ) { - /* not supporting continuation references at present */ - if (rc != LDAP_RES_SEARCH_ENTRY) - err(argv[0], "ldap_result() returned cont.ref? Exiting"); - - /* only one entry per result message */ - e = ldap_first_entry(ld, res); - if (e == NULL) { - ldap_msgfree(res); - err(argv[0], "ldap_first_entry() failed"); - } - - names = ldap_get_values_len(ld, e, "relativeDomainName"); - if (!names) - continue; - - ttlvals = ldap_get_values(ld, e, "dNSTTL"); - ttl = ttlvals ? ttlvals[0] : defaultttl; - - for (a = ldap_first_attribute(ld, e, &ptr); a != NULL; a = ldap_next_attribute(ld, e, ptr)) { - char *s; - - for (s = a; *s; s++) - *s = toupper(*s); - s = strstr(a, "RECORD"); - if ((s == NULL) || (s == a) || (s - a >= (signed int)sizeof(type))) { - ldap_memfree(a); - continue; - } - - strncpy(type, a, s - a); - type[s - a] = '\0'; - vals = ldap_get_values_len(ld, e, a); - if (vals) { - for (i = 0; vals[i]; i++) - for (j = 0; names[j]; j++) - if (putrr(&zone, names[j], type, ttl, vals[i])) - err(argv[0], "malloc failed"); - ldap_value_free_len(vals); - } - ldap_memfree(a); - } - - if (ptr) - ber_free(ptr, 0); - if (ttlvals) - ldap_value_free(ttlvals); - ldap_value_free_len(names); - /* free this result */ - ldap_msgfree(res); - } - - /* free final result */ - ldap_msgfree(res); - - print_zone(defaultttl, zone); - return 0; -} diff --git a/makefile-replace-libs.py b/makefile-replace-libs.py deleted file mode 100755 index 90cb0de..0000000 --- a/makefile-replace-libs.py +++ /dev/null @@ -1,143 +0,0 @@ -#!/usr/bin/python3 -# -# Makefile modificator -# -# Should help in building bin/tests/system tests standalone, -# linked to libraries installed into the system. -# TODO: -# - Fix top_srcdir, because dyndb/driver/Makefile uses $TOPSRC/mkinstalldirs -# - Fix conf.sh to contain paths to system tools -# - Export $TOP/version somewhere, where it would be used -# - system tests needs bin/tests code. Do not include just bin/tests/system -# -# Possible solution: -# -# sed -e 's/$TOP\/s\?bin\/\(delv\|confgen\|named\|nsupdate\|pkcs11\|python\|rndc\|check\|dig\|dnssec\|tools\)\/\([[:alnum:]-]\+\)/`type -p \2`/' conf.sh -# sed -e 's,../../../../\(isc-config.sh\),\1,' builtin/tests.sh -# or use: $NAMED -V | head -1 | cut -d ' ' -f 2 - -import re -import argparse - -""" -Script for replacing Makefile ISC_INCLUDES with runtime flags. - -Should translate part of Makefile to use isc-config.sh instead static linked sources. -ISC_INCLUDES = -I/home/pemensik/rhel/bind/bind-9.11.12/build/lib/isc/include \ - -I${top_srcdir}/lib/isc \ - -I${top_srcdir}/lib/isc/include \ - -I${top_srcdir}/lib/isc/unix/include \ - -I${top_srcdir}/lib/isc/pthreads/include \ - -I${top_srcdir}/lib/isc/x86_32/include - -Should be translated to: -ISC_INCLUDES = $(shell isc-config.sh --cflags isc) -""" - -def isc_config(mode, lib): - if mode: - return '$(shell isc-config.sh {mode} {lib})'.format(mode=mode, lib=lib) - else: - return '' - -def check_match(match, debug=False): - """ - Check this definition is handled by internal library - """ - if not match: - return False - lib = match.group(2).lower() - ok = not lib_filter or lib in lib_filter - if debug: - print('{status} {lib}: {text}'.format(status=ok, lib=lib, text=match.group(1))) - return ok - -def fix_line(match, mode): - lib = match.group(2).lower() - return match.group(1)+isc_config(mode, lib)+"\n" - -def fix_file_lines(path, debug=False): - """ - Opens file and scans fixes selected parameters - - Returns list of lines if something should be changed, - None if no action is required - """ - fixed = [] - changed = False - with open(path, 'r') as fin: - fout = None - - line = next(fin, None) - while line: - appended = False - while line.endswith("\\\n"): - line += next(fin, None) - - inc = re_includes.match(line) - deplibs = re_deplibs.match(line) - libs = re_libs.match(line) - newline = None - if check_match(inc, debug=debug): - newline = fix_line(inc, '--cflags') - elif check_match(deplibs, debug=debug): - newline = fix_line(libs, None) - elif check_match(libs, debug=debug): - newline = fix_line(libs, '--libs') - - if newline and line != newline: - changed = True - line = newline - - fixed.append(line) - line = next(fin, None) - - if not changed: - return None - else: - return fixed - -def write_lines(path, lines): - fout = open(path, 'w') - for line in lines: - fout.write(line) - fout.close() - -def print_lines(lines): - for line in lines: - print(line, end='') - -if __name__ == '__main__': - parser = argparse.ArgumentParser(description='Makefile multiline include replacer') - parser.add_argument('files', nargs='+') - parser.add_argument('--filter', type=str, - default='isc isccc isccfg dns lwres bind9 irs', - help='List of libraries supported by isc-config.sh') - parser.add_argument('--check', action='store_true', - help='Test file only') - parser.add_argument('--print', action='store_true', - help='Print changed file only') - parser.add_argument('--debug', action='store_true', - help='Enable debug outputs') - - args = parser.parse_args() - lib_filter = None - - re_includes = re.compile(r'^\s*((\w+)_INCLUDES\s+=\s*).*') - re_deplibs = re.compile(r'^\s*((\w+)DEPLIBS\s*=).*') - re_libs = re.compile(r'^\s*((\w+)LIBS\s*=).*') - - if args.filter: - lib_filter = set(args.filter.split(' ')) - pass - - for path in args.files: - lines = fix_file_lines(path, debug=args.debug) - if lines: - if args.print: - print_lines(lines) - elif not args.check: - write_lines(path, lines) - print('File {path} was fixed'.format(path=path)) - else: - print('File {path} does not need fixing'.format(path=path)) diff --git a/plans.fmf b/plans.fmf deleted file mode 100644 index a15a672..0000000 --- a/plans.fmf +++ /dev/null @@ -1,39 +0,0 @@ -environment+: - PACKAGE: bind9.18 - -/tier1-internal: - plan: - import: - url: https://src.fedoraproject.org/tests/bind.git - name: /plans/bind9.18/tier1/internal - -/tier1-public: - plan: - import: - url: https://src.fedoraproject.org/tests/bind.git - name: /plans/bind9.18/tier1/public - - -/tier2-tier3-internal: - plan: - import: - url: https://src.fedoraproject.org/tests/bind.git - name: /plans/bind9.18/tier2-tier3/internal - -/tier2-tier3-public: - plan: - import: - url: https://src.fedoraproject.org/tests/bind.git - name: /plans/bind9.18/tier2-tier3/public - -/others-internal: - plan: - import: - url: https://src.fedoraproject.org/tests/bind.git - name: /plans/bind9.18/others/internal - -/others-public: - plan: - import: - url: https://src.fedoraproject.org/tests/bind.git - name: /plans/bind9.18/others/public diff --git a/softhsm2.conf.in b/softhsm2.conf.in deleted file mode 100644 index 1f39320..0000000 --- a/softhsm2.conf.in +++ /dev/null @@ -1,10 +0,0 @@ -# SoftHSM v2 configuration file - -directories.tokendir = @TOKENPATH@ -objectstore.backend = file - -# ERROR, WARNING, INFO, DEBUG -log.level = ERROR - -# If CKF_REMOVABLE_DEVICE flag should be set -slots.removable = false diff --git a/sources b/sources deleted file mode 100644 index f0ecde1..0000000 --- a/sources +++ /dev/null @@ -1,2 +0,0 @@ -SHA512 (bind-9.18.29.tar.xz) = 6c2676e2e2cb90f3bd73afb367813c54d1c961e12df1e12e41b9d0ee5a1d5cdf368d81410469753eaef37e43358b56796f078f3b2f20c3b247c4bef91d56c716 -SHA512 (bind-9.18.29.tar.xz.asc) = 6612c7151c4c1736e0237b8219cefbafbc1dcd4b04ad9b12b99cba703e6debde90d2f9838dd1465a47b9a002a598d9b8f3221dfe1a3bdc41436a92e6d06db472