diff --git a/CHANGES b/CHANGES index c428ab1b5b..10358f8a9f 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,8 @@ +6321. [func] The 'tls' block was extended with a new + 'cipher-suites' option that allows setting + allowed cipher suites for TLSv1.3. + [GL #3504] + 6320. [bug] Fix a possible crash in 'dig +nssearch +nofail' and 'host -C' commands when one of the name servers returns SERVFAIL. [GL #4508] diff --git a/bin/named/server.c b/bin/named/server.c index 80c5b5f1bb..062f021c57 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -10784,7 +10784,7 @@ listenelt_fromconfig(const cfg_obj_t *listener, const cfg_obj_t *config, const cfg_obj_t *proxyobj = NULL; in_port_t port = 0; const char *key = NULL, *cert = NULL, *ca_file = NULL, - *dhparam_file = NULL, *ciphers = NULL; + *dhparam_file = NULL, *ciphers = NULL, *cipher_suites = NULL; bool tls_prefer_server_ciphers = false, tls_prefer_server_ciphers_set = false; bool tls_session_tickets = false, tls_session_tickets_set = false; @@ -10814,6 +10814,7 @@ listenelt_fromconfig(const cfg_obj_t *listener, const cfg_obj_t *config, const cfg_obj_t *tlsmap = NULL; const cfg_obj_t *tls_proto_list = NULL; const cfg_obj_t *ciphers_obj = NULL; + const cfg_obj_t *cipher_suites_obj = NULL; const cfg_obj_t *prefer_server_ciphers_obj = NULL; const cfg_obj_t *session_tickets_obj = NULL; @@ -10874,6 +10875,13 @@ listenelt_fromconfig(const cfg_obj_t *listener, const cfg_obj_t *config, ciphers = cfg_obj_asstring(ciphers_obj); } + if (cfg_map_get(tlsmap, "cipher-suites", + &cipher_suites_obj) == ISC_R_SUCCESS) + { + cipher_suites = + cfg_obj_asstring(cipher_suites_obj); + } + if (cfg_map_get(tlsmap, "prefer-server-ciphers", &prefer_server_ciphers_obj) == ISC_R_SUCCESS) @@ -10901,6 +10909,7 @@ listenelt_fromconfig(const cfg_obj_t *listener, const cfg_obj_t *config, .protocols = tls_protos, .dhparam_file = dhparam_file, .ciphers = ciphers, + .cipher_suites = cipher_suites, .prefer_server_ciphers = tls_prefer_server_ciphers, .prefer_server_ciphers_set = tls_prefer_server_ciphers_set, .session_tickets = tls_session_tickets, diff --git a/bin/named/transportconf.c b/bin/named/transportconf.c index f24aab11dd..d1736d0726 100644 --- a/bin/named/transportconf.c +++ b/bin/named/transportconf.c @@ -120,11 +120,13 @@ add_doh_transports(const cfg_obj_t *transportlist, dns_transport_list_t *list) { dns_transport_set_tls_versions); parse_transport_option(doh, transport, "ciphers", dns_transport_set_ciphers); + parse_transport_option(doh, transport, "cipher-suites", + dns_transport_set_cipher_suites); parse_transport_bool_option( doh, transport, "prefer-server-ciphers", - dns_transport_set_prefer_server_ciphers) - parse_transport_option(doh, transport, "ca-file", - dns_transport_set_cafile); + dns_transport_set_prefer_server_ciphers); + parse_transport_option(doh, transport, "ca-file", + dns_transport_set_cafile); parse_transport_option(doh, transport, "remote-hostname", dns_transport_set_remote_hostname); } @@ -172,11 +174,13 @@ add_tls_transports(const cfg_obj_t *transportlist, dns_transport_list_t *list) { dns_transport_set_tls_versions); parse_transport_option(tls, transport, "ciphers", dns_transport_set_ciphers); + parse_transport_option(tls, transport, "cipher-suites", + dns_transport_set_cipher_suites); parse_transport_bool_option( tls, transport, "prefer-server-ciphers", - dns_transport_set_prefer_server_ciphers) - parse_transport_option(tls, transport, "ca-file", - dns_transport_set_cafile); + dns_transport_set_prefer_server_ciphers); + parse_transport_option(tls, transport, "ca-file", + dns_transport_set_cafile); parse_transport_option(tls, transport, "remote-hostname", dns_transport_set_remote_hostname); } diff --git a/bin/tests/system/checkconf/bad-tls-cipher-suites-ciphers-string.conf b/bin/tests/system/checkconf/bad-tls-cipher-suites-ciphers-string.conf new file mode 100644 index 0000000000..524239cc34 --- /dev/null +++ b/bin/tests/system/checkconf/bad-tls-cipher-suites-ciphers-string.conf @@ -0,0 +1,26 @@ +/* + * 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. + */ + +tls local-tls { + protocols { TLSv1.3; }; + key-file "key.pem"; + cert-file "cert.pem"; + dhparam-file "dhparam.pem"; + cipher-suites "HIGH:!aNULL:!MD5:!RC4"; + prefer-server-ciphers yes; + session-tickets no; +}; + +options { + listen-on port 853 tls local-tls { 10.53.0.1; }; +}; diff --git a/bin/tests/system/checkconf/bad-tls-cipher-suites-empty-string.conf b/bin/tests/system/checkconf/bad-tls-cipher-suites-empty-string.conf new file mode 100644 index 0000000000..7e0ebcf902 --- /dev/null +++ b/bin/tests/system/checkconf/bad-tls-cipher-suites-empty-string.conf @@ -0,0 +1,26 @@ +/* + * 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. + */ + +tls local-tls { + protocols { TLSv1.3; }; + key-file "key.pem"; + cert-file "cert.pem"; + dhparam-file "dhparam.pem"; + cipher-suites ""; + prefer-server-ciphers yes; + session-tickets no; +}; + +options { + listen-on port 853 tls local-tls { 10.53.0.1; }; +}; diff --git a/bin/tests/system/checkconf/bad-tls-cipher-suites-wrong-string.conf b/bin/tests/system/checkconf/bad-tls-cipher-suites-wrong-string.conf new file mode 100644 index 0000000000..44f74fe9a7 --- /dev/null +++ b/bin/tests/system/checkconf/bad-tls-cipher-suites-wrong-string.conf @@ -0,0 +1,26 @@ +/* + * 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. + */ + +tls local-tls { + protocols { TLSv1.3; }; + key-file "key.pem"; + cert-file "cert.pem"; + dhparam-file "dhparam.pem"; + cipher-suites "lalalalalgggg"; + prefer-server-ciphers yes; + session-tickets no; +}; + +options { + listen-on port 853 tls local-tls { 10.53.0.1; }; +}; diff --git a/bin/tests/system/checkconf/good-tls-cipher-suites-multiple-cipher-suites.conf b/bin/tests/system/checkconf/good-tls-cipher-suites-multiple-cipher-suites.conf new file mode 100644 index 0000000000..6ef3df6f2c --- /dev/null +++ b/bin/tests/system/checkconf/good-tls-cipher-suites-multiple-cipher-suites.conf @@ -0,0 +1,26 @@ +/* + * 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. + */ + +tls local-tls { + protocols { TLSv1.3; }; + key-file "key.pem"; + cert-file "cert.pem"; + dhparam-file "dhparam.pem"; + cipher-suites "TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256"; + prefer-server-ciphers yes; + session-tickets no; +}; + +options { + listen-on port 853 tls local-tls { 10.53.0.1; }; +}; diff --git a/bin/tests/system/checkconf/good-tls-cipher-suites-one-cipher-suite.conf b/bin/tests/system/checkconf/good-tls-cipher-suites-one-cipher-suite.conf new file mode 100644 index 0000000000..da52e6685d --- /dev/null +++ b/bin/tests/system/checkconf/good-tls-cipher-suites-one-cipher-suite.conf @@ -0,0 +1,26 @@ +/* + * 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. + */ + +tls local-tls { + protocols { TLSv1.3; }; + key-file "key.pem"; + cert-file "cert.pem"; + dhparam-file "dhparam.pem"; + cipher-suites "TLS_CHACHA20_POLY1305_SHA256"; + prefer-server-ciphers yes; + session-tickets no; +}; + +options { + listen-on port 853 tls local-tls { 10.53.0.1; }; +}; diff --git a/bin/tests/system/checkconf/tests.sh b/bin/tests/system/checkconf/tests.sh index 7eced17663..d3289015d2 100644 --- a/bin/tests/system/checkconf/tests.sh +++ b/bin/tests/system/checkconf/tests.sh @@ -89,6 +89,10 @@ for good in good-*.conf; do good-proxy-*doh*.conf) continue ;; bad-proxy-*doh*.conf) continue ;; esac + elif ! $FEATURETEST --have-openssl-cipher-suites; then + case $good in + good-tls-cipher-suites-*.conf) continue ;; + esac fi { $CHECKCONF $good >checkconf.out$n 2>&1 diff --git a/bin/tests/system/cipher-suites/clean.sh b/bin/tests/system/cipher-suites/clean.sh new file mode 100644 index 0000000000..c81c6a1bdc --- /dev/null +++ b/bin/tests/system/cipher-suites/clean.sh @@ -0,0 +1,26 @@ +#!/bin/sh + +# Copyright (C) Internet Systems Consortium, Inc. ("ISC") +# +# SPDX-License-Identifier: MPL-2.0 +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, you can obtain one at https://mozilla.org/MPL/2.0/. +# +# See the COPYRIGHT file distributed with this work for additional +# information regarding copyright ownership. + +# +# Clean up after zone transfer tests. +# + +rm -f ./*/named.conf +rm -f ./*/named.memstats +rm -f ./*/named.run +rm -f ./*/named.run.prev +rm -f ./dig.out.* +rm -f ./gnutls-cli.* +rm -f ./sslyze.log.* +rm -f ./*/example*.db +rm -rf ./headers.* diff --git a/bin/tests/system/cipher-suites/ns1/named.conf.in b/bin/tests/system/cipher-suites/ns1/named.conf.in new file mode 100644 index 0000000000..77186a6e63 --- /dev/null +++ b/bin/tests/system/cipher-suites/ns1/named.conf.in @@ -0,0 +1,100 @@ +/* + * 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. + */ + +include "../../_common/rndc.key"; + +controls { + inet 10.53.0.1 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; +}; + +tls tls-perfect-forward-secrecy { + protocols { TLSv1.3; }; + cipher-suites "TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256"; + key-file "../self-signed-key.pem"; + cert-file "../self-signed-cert.pem"; + session-tickets no; +}; + +tls tls-pfs-aes256 { + protocols { TLSv1.3; }; + cipher-suites "TLS_AES_256_GCM_SHA384"; + key-file "../self-signed-key.pem"; + cert-file "../self-signed-cert.pem"; + session-tickets no; +}; + +tls tls-pfs-aes128 { + protocols { TLSv1.3; }; + cipher-suites "TLS_AES_128_GCM_SHA256"; + key-file "../self-signed-key.pem"; + cert-file "../self-signed-cert.pem"; + session-tickets no; +}; + +tls tls-pfs-chacha20 { + protocols { TLSv1.3; }; + cipher-suites "TLS_CHACHA20_POLY1305_SHA256"; + key-file "../self-signed-key.pem"; + cert-file "../self-signed-cert.pem"; + session-tickets no; +}; + +options { + port @PORT@; + tls-port @TLSPORT@; + pid-file "named.pid"; + listen-on-v6 { none; }; + listen-on { 10.53.0.1; }; + listen-on tls tls-perfect-forward-secrecy { 10.53.0.1; }; + listen-on port @EXTRAPORT1@ tls tls-pfs-aes128 { 10.53.0.1; }; + listen-on port @EXTRAPORT2@ tls tls-pfs-aes256 { 10.53.0.1; }; + listen-on port @EXTRAPORT3@ tls tls-pfs-chacha20 { 10.53.0.1; }; + recursion no; + notify explicit; + also-notify { 10.53.0.2 port @PORT@; }; + statistics-file "named.stats"; + dnssec-validation yes; + tcp-initial-timeout 1200; + transfers-in 100; + transfers-out 100; +}; + +zone "." { + type primary; + file "root.db"; + allow-transfer port @TLSPORT@ transport tls { any; }; +}; + +zone "example" { + type primary; + file "example.db"; + allow-transfer port @TLSPORT@ transport tls { any; }; +}; + +zone "example-aes-128" { + type primary; + file "example.db"; + allow-transfer port @EXTRAPORT1@ transport tls { any; }; +}; + +zone "example-aes-256" { + type primary; + file "example.db"; + allow-transfer port @EXTRAPORT2@ transport tls { any; }; +}; + +zone "example-chacha-20" { + type primary; + file "example.db"; + allow-transfer port @EXTRAPORT3@ transport tls { any; }; +}; diff --git a/bin/tests/system/cipher-suites/ns2/named.conf.in b/bin/tests/system/cipher-suites/ns2/named.conf.in new file mode 100644 index 0000000000..58189524b8 --- /dev/null +++ b/bin/tests/system/cipher-suites/ns2/named.conf.in @@ -0,0 +1,85 @@ +/* + * 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. + */ + +include "../../_common/rndc.key"; + +controls { + inet 10.53.0.2 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; +}; + +tls local { + key-file "../self-signed-key.pem"; + cert-file "../self-signed-cert.pem"; +}; + +options { + query-source address 10.53.0.2; + notify-source 10.53.0.2; + transfer-source 10.53.0.2; + port @PORT@; + tls-port @TLSPORT@; + pid-file "named.pid"; + listen-on { 10.53.0.2; }; + listen-on tls local { 10.53.0.2; }; // DoT + listen-on-v6 { none; }; + recursion no; + notify no; + ixfr-from-differences yes; + check-integrity no; + dnssec-validation yes; +}; + +zone "." { + type hint; + file "../../_common/root.hint"; +}; + +tls tls-v1.3 { + protocols { TLSv1.3; }; + cipher-suites "TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256"; + prefer-server-ciphers no; +}; + +zone "example" { + type secondary; + primaries { 10.53.0.1 tls tls-v1.3; }; + file "example.db"; + allow-transfer { any; }; +}; + +tls tls-v1.3-aes-128 { + protocols { TLSv1.3; }; + cipher-suites "TLS_AES_128_GCM_SHA256"; + prefer-server-ciphers no; +}; + +zone "example-aes-128" { + type secondary; + primaries port @EXTRAPORT1@ { 10.53.0.1 tls tls-v1.3-aes-128; }; + file "example-aes-128.db"; + allow-transfer { any; }; +}; + +zone "example-aes-256" { + type secondary; + primaries port @EXTRAPORT2@ { 10.53.0.1 tls tls-v1.3-aes-128; }; + file "example-aes-256.db"; + allow-transfer { any; }; +}; + +zone "example-chacha-20" { + type secondary; + primaries port @EXTRAPORT3@ { 10.53.0.1 tls tls-v1.3-aes-128; }; + file "example-chacha-20.db"; + allow-transfer { any; }; +}; diff --git a/bin/tests/system/cipher-suites/ns3/named.conf.in b/bin/tests/system/cipher-suites/ns3/named.conf.in new file mode 100644 index 0000000000..9a78903d98 --- /dev/null +++ b/bin/tests/system/cipher-suites/ns3/named.conf.in @@ -0,0 +1,85 @@ +/* + * 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. + */ + +include "../../_common/rndc.key"; + +controls { + inet 10.53.0.3 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; +}; + +tls local { + key-file "../self-signed-key.pem"; + cert-file "../self-signed-cert.pem"; +}; + +options { + query-source address 10.53.0.3; + notify-source 10.53.0.3; + transfer-source 10.53.0.3; + port @PORT@; + tls-port @TLSPORT@; + pid-file "named.pid"; + listen-on { 10.53.0.3; }; + listen-on tls local { 10.53.0.3; }; // DoT + listen-on-v6 { none; }; + recursion no; + notify no; + ixfr-from-differences yes; + check-integrity no; + dnssec-validation yes; +}; + +zone "." { + type hint; + file "../../_common/root.hint"; +}; + +tls tls-v1.3 { + protocols { TLSv1.3; }; + cipher-suites "TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256"; + prefer-server-ciphers no; +}; + +zone "example" { + type secondary; + primaries { 10.53.0.1 tls tls-v1.3; }; + file "example.db"; + allow-transfer { any; }; +}; + +tls tls-v1.3-aes-256 { + protocols { TLSv1.3; }; + cipher-suites "TLS_AES_256_GCM_SHA384"; + prefer-server-ciphers no; +}; + +zone "example-aes-128" { + type secondary; + primaries port @EXTRAPORT1@ { 10.53.0.1 tls tls-v1.3-aes-256; }; + file "example-aes-128.db"; + allow-transfer { any; }; +}; + +zone "example-aes-256" { + type secondary; + primaries port @EXTRAPORT2@ { 10.53.0.1 tls tls-v1.3-aes-256; }; + file "example-aes-256.db"; + allow-transfer { any; }; +}; + +zone "example-chacha-20" { + type secondary; + primaries port @EXTRAPORT3@ { 10.53.0.1 tls tls-v1.3-aes-256; }; + file "example-chacha-20.db"; + allow-transfer { any; }; +}; diff --git a/bin/tests/system/cipher-suites/ns4/named.conf.in b/bin/tests/system/cipher-suites/ns4/named.conf.in new file mode 100644 index 0000000000..cf52f98b0d --- /dev/null +++ b/bin/tests/system/cipher-suites/ns4/named.conf.in @@ -0,0 +1,85 @@ +/* + * 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. + */ + +include "../../_common/rndc.key"; + +controls { + inet 10.53.0.4 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; +}; + +tls local { + key-file "../self-signed-key.pem"; + cert-file "../self-signed-cert.pem"; +}; + +options { + query-source address 10.53.0.4; + notify-source 10.53.0.4; + transfer-source 10.53.0.4; + port @PORT@; + tls-port @TLSPORT@; + pid-file "named.pid"; + listen-on { 10.53.0.4; }; + listen-on tls local { 10.53.0.4; }; // DoT + listen-on-v6 { none; }; + recursion no; + notify no; + ixfr-from-differences yes; + check-integrity no; + dnssec-validation yes; +}; + +zone "." { + type hint; + file "../../_common/root.hint"; +}; + +tls tls-v1.3 { + protocols { TLSv1.3; }; + cipher-suites "TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256"; + prefer-server-ciphers no; +}; + +zone "example" { + type secondary; + primaries { 10.53.0.1 tls tls-v1.3; }; + file "example.db"; + allow-transfer { any; }; +}; + +tls tls-v1.3-chacha20 { + protocols { TLSv1.3; }; + cipher-suites "TLS_CHACHA20_POLY1305_SHA256"; + prefer-server-ciphers no; +}; + +zone "example-aes-128" { + type secondary; + primaries port @EXTRAPORT1@ { 10.53.0.1 tls tls-v1.3-chacha20; }; + file "example-aes-128.db"; + allow-transfer { any; }; +}; + +zone "example-aes-256" { + type secondary; + primaries port @EXTRAPORT2@ { 10.53.0.1 tls tls-v1.3-chacha20; }; + file "example-aes-256.db"; + allow-transfer { any; }; +}; + +zone "example-chacha-20" { + type secondary; + primaries port @EXTRAPORT3@ { 10.53.0.1 tls tls-v1.3-chacha20; }; + file "example-chacha-20.db"; + allow-transfer { any; }; +}; diff --git a/bin/tests/system/cipher-suites/ns5/named.conf.in b/bin/tests/system/cipher-suites/ns5/named.conf.in new file mode 100644 index 0000000000..9187d0e94a --- /dev/null +++ b/bin/tests/system/cipher-suites/ns5/named.conf.in @@ -0,0 +1,78 @@ +/* + * 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. + */ + +include "../../_common/rndc.key"; + +controls { + inet 10.53.0.5 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; +}; + +tls local { + key-file "../self-signed-key.pem"; + cert-file "../self-signed-cert.pem"; +}; + +options { + query-source address 10.53.0.5; + notify-source 10.53.0.5; + transfer-source 10.53.0.5; + port @PORT@; + tls-port @TLSPORT@; + pid-file "named.pid"; + listen-on { 10.53.0.5; }; + listen-on tls local { 10.53.0.5; }; // DoT + listen-on-v6 { none; }; + recursion no; + notify no; + ixfr-from-differences yes; + check-integrity no; + dnssec-validation yes; +}; + +zone "." { + type hint; + file "../../_common/root.hint"; +}; + +tls tls-v1.2 { + protocols { TLSv1.2; }; + prefer-server-ciphers no; +}; + +zone "example" { + type secondary; + primaries { 10.53.0.1 tls tls-v1.2; }; + file "example.db"; + allow-transfer { any; }; +}; + +zone "example-aes-128" { + type secondary; + primaries port @EXTRAPORT1@ { 10.53.0.1 tls tls-v1.2; }; + file "example-aes-128.db"; + allow-transfer { any; }; +}; + +zone "example-aes-256" { + type secondary; + primaries port @EXTRAPORT2@ { 10.53.0.1 tls tls-v1.2; }; + file "example-aes-256.db"; + allow-transfer { any; }; +}; + +zone "example-chacha-20" { + type secondary; + primaries port @EXTRAPORT3@ { 10.53.0.1 tls tls-v1.2; }; + file "example-chacha-20.db"; + allow-transfer { any; }; +}; diff --git a/bin/tests/system/cipher-suites/prereq.sh b/bin/tests/system/cipher-suites/prereq.sh new file mode 100644 index 0000000000..910359535c --- /dev/null +++ b/bin/tests/system/cipher-suites/prereq.sh @@ -0,0 +1,21 @@ +#!/bin/sh + +# Copyright (C) Internet Systems Consortium, Inc. ("ISC") +# +# SPDX-License-Identifier: MPL-2.0 +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, you can obtain one at https://mozilla.org/MPL/2.0/. +# +# See the COPYRIGHT file distributed with this work for additional +# information regarding copyright ownership. + +. ../conf.sh + +$FEATURETEST --have-openssl-cipher-suites || { + echo_i "SSL_CTX_set_ciphersuites() is required for the test." + exit 255 +} + +exit 0 diff --git a/bin/tests/system/cipher-suites/self-signed-cert.pem b/bin/tests/system/cipher-suites/self-signed-cert.pem new file mode 100644 index 0000000000..8fd6db35b9 --- /dev/null +++ b/bin/tests/system/cipher-suites/self-signed-cert.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICpDCCAkmgAwIBAgIUCgppsffsoMFrEULJBNaABqUJGl8wCgYIKoZIzj0EAwIw +gaYxCzAJBgNVBAYTAlVBMRwwGgYDVQQIDBNLaGFya2l2cydrYSBvYmxhc3QnMRAw +DgYDVQQHDAdLaGFya2l2MSQwIgYDVQQKDBtJbnRlcm5ldCBTeXN0ZW1zIENvbnNv +cnRpdW0xHzAdBgNVBAsMFkJJTkQ5IERldmVsb3BtZW50IFRlYW0xIDAeBgNVBAMM +F3NlbGYtc2lnbmVkLmV4YW1wbGUuY29tMB4XDTIzMTIwMTE1NTU0OVoXDTQzMTEz +MDE1NTU0OVowgaYxCzAJBgNVBAYTAlVBMRwwGgYDVQQIDBNLaGFya2l2cydrYSBv +Ymxhc3QnMRAwDgYDVQQHDAdLaGFya2l2MSQwIgYDVQQKDBtJbnRlcm5ldCBTeXN0 +ZW1zIENvbnNvcnRpdW0xHzAdBgNVBAsMFkJJTkQ5IERldmVsb3BtZW50IFRlYW0x +IDAeBgNVBAMMF3NlbGYtc2lnbmVkLmV4YW1wbGUuY29tMFkwEwYHKoZIzj0CAQYI +KoZIzj0DAQcDQgAEAvOwTFQkxZ5buinXL2II3F2Bkq7BfycqugoRJohm6avxEqKF +pByu6gWQxgWFFelXAz2FRhT4SK+E1o/b9X2EGKNTMFEwHQYDVR0OBBYEFPcvo8eC +k8kDoF2Lmpua+qMJdV5eMB8GA1UdIwQYMBaAFPcvo8eCk8kDoF2Lmpua+qMJdV5e +MA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDSQAwRgIhAJh6QFBC8JnHTEjD +GLevzFzjbxSNjMj0xgrX4eK+9JjCAiEAqFkj9wGs7U1cZrZI0Mnje9itHgQrMl1u +olvLJ/W2LBc= +-----END CERTIFICATE----- diff --git a/bin/tests/system/cipher-suites/self-signed-key.pem b/bin/tests/system/cipher-suites/self-signed-key.pem new file mode 100644 index 0000000000..075b4d9ca0 --- /dev/null +++ b/bin/tests/system/cipher-suites/self-signed-key.pem @@ -0,0 +1,8 @@ +-----BEGIN EC PARAMETERS----- +BggqhkjOPQMBBw== +-----END EC PARAMETERS----- +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEIME55eKuHtLyCHYCvJcIU1o8FdATceC7rQWwEyIhnzINoAoGCCqGSM49 +AwEHoUQDQgAEAvOwTFQkxZ5buinXL2II3F2Bkq7BfycqugoRJohm6avxEqKFpByu +6gWQxgWFFelXAz2FRhT4SK+E1o/b9X2EGA== +-----END EC PRIVATE KEY----- diff --git a/bin/tests/system/cipher-suites/setup.sh b/bin/tests/system/cipher-suites/setup.sh new file mode 100644 index 0000000000..9d7d0a928e --- /dev/null +++ b/bin/tests/system/cipher-suites/setup.sh @@ -0,0 +1,22 @@ +#!/bin/sh + +# Copyright (C) Internet Systems Consortium, Inc. ("ISC") +# +# SPDX-License-Identifier: MPL-2.0 +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, you can obtain one at https://mozilla.org/MPL/2.0/. +# +# See the COPYRIGHT file distributed with this work for additional +# information regarding copyright ownership. + +. ../conf.sh + +$SHELL "${TOP_SRCDIR}/bin/tests/system/genzone.sh" 2 >ns1/example.db + +copy_setports ns1/named.conf.in ns1/named.conf +copy_setports ns2/named.conf.in ns2/named.conf +copy_setports ns3/named.conf.in ns3/named.conf +copy_setports ns4/named.conf.in ns4/named.conf +copy_setports ns5/named.conf.in ns5/named.conf diff --git a/bin/tests/system/cipher-suites/tests.sh b/bin/tests/system/cipher-suites/tests.sh new file mode 100644 index 0000000000..2c8076717c --- /dev/null +++ b/bin/tests/system/cipher-suites/tests.sh @@ -0,0 +1,88 @@ +#!/bin/sh + +# Copyright (C) Internet Systems Consortium, Inc. ("ISC") +# +# SPDX-License-Identifier: MPL-2.0 +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, you can obtain one at https://mozilla.org/MPL/2.0/. +# +# See the COPYRIGHT file distributed with this work for additional +# information regarding copyright ownership. + +set -e + +# shellcheck disable=SC1091 +. ../conf.sh + +testing="testing zone transfer over TLS (XoT): " + +common_dig_options="+noadd +nosea +nostat +noquest +nocmd" + +status=0 +n=0 + +dig_with_tls_opts() { + # shellcheck disable=SC2086 + "$DIG" +tls $common_dig_options -p "${TLSPORT}" "$@" +} + +wait_for_tls_xfer() ( + srv_number="$1" + shift + zone_name="$1" + shift + # Let's bind to .10 to make it possible to easily distinguish dig from NSs in packet traces + dig_with_tls_opts -b 10.53.0.10 "@10.53.0.$srv_number" "${zone_name}." AXFR >"dig.out.ns$srv_number.${zone_name}.test$n" || return 1 + grep "^;" "dig.out.ns$srv_number.${zone_name}.test$n" >/dev/null && return 1 + return 0 +) + +tls_xfer_expect_success() { + test_message="$1" + shift + n=$((n + 1)) + echo_i "$test_message - zone \"$2\" at \"ns$1\" ($n)" + ret=0 + retry_quiet 10 wait_for_tls_xfer "$@" || ret=1 + if [ $ret != 0 ]; then echo_i "failed"; fi + status=$((status + ret)) +} + +tls_xfer_expect_failure() { + test_message="$1" + shift + n=$((n + 1)) + echo_i "$test_message - zone \"$2\" at \"ns$1\", failure expected ($n)" + ret=0 + retry_quiet 10 wait_for_tls_xfer "$@" && ret=1 + if [ $ret != 0 ]; then echo_i "failed"; fi + status=$((status + ret)) +} + +tls_xfer_expect_success "$testing" 2 example +tls_xfer_expect_success "$testing" 3 example +tls_xfer_expect_success "$testing" 4 example + +tls_xfer_expect_success "$testing" 2 example-aes-128 +tls_xfer_expect_success "$testing" 3 example-aes-256 +tls_xfer_expect_success "$testing" 4 example-chacha-20 + +tls_xfer_expect_failure "$testing" 2 example-aes-256 +tls_xfer_expect_failure "$testing" 2 example-chacha-20 + +tls_xfer_expect_failure "$testing" 3 example-aes-128 +tls_xfer_expect_failure "$testing" 3 example-chacha-20 + +tls_xfer_expect_failure "$testing" 4 example-aes-128 +tls_xfer_expect_failure "$testing" 4 example-aes-256 + +# NS5 tries to download the zone over TLSv1.2 +tls_xfer_expect_failure "$testing" 5 example +tls_xfer_expect_failure "$testing" 5 example-aes-128 +tls_xfer_expect_failure "$testing" 5 example-aes-256 +tls_xfer_expect_failure "$testing" 5 example-chacha-20 + +echo_i "exit status: $status" +[ $status -eq 0 ] || exit 1 diff --git a/bin/tests/system/cipher-suites/tests_sh_cipher_suites.py b/bin/tests/system/cipher-suites/tests_sh_cipher_suites.py new file mode 100644 index 0000000000..78095ba719 --- /dev/null +++ b/bin/tests/system/cipher-suites/tests_sh_cipher_suites.py @@ -0,0 +1,14 @@ +# Copyright (C) Internet Systems Consortium, Inc. ("ISC") +# +# SPDX-License-Identifier: MPL-2.0 +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, you can obtain one at https://mozilla.org/MPL/2.0/. +# +# See the COPYRIGHT file distributed with this work for additional +# information regarding copyright ownership. + + +def test_cipher_suites(run_tests_sh): + run_tests_sh() diff --git a/bin/tests/system/feature-test.c b/bin/tests/system/feature-test.c index 5b3c504d62..66731c513d 100644 --- a/bin/tests/system/feature-test.c +++ b/bin/tests/system/feature-test.c @@ -49,6 +49,7 @@ usage(void) { fprintf(stderr, "\t--have-geoip2\n"); fprintf(stderr, "\t--have-json-c\n"); fprintf(stderr, "\t--have-libxml2\n"); + fprintf(stderr, "\t--have-openssl-cipher-suites\n"); fprintf(stderr, "\t--ipv6only=no\n"); fprintf(stderr, "\t--md5\n"); fprintf(stderr, "\t--rsasha1\n"); @@ -184,6 +185,14 @@ main(int argc, char **argv) { #endif /* ifdef HAVE_LIBXML2 */ } + if (strcmp(argv[1], "--have-openssl-cipher-suites") == 0) { +#ifdef HAVE_SSL_CTX_SET_CIPHERSUITES + return (0); +#else /* ifdef HAVE_SSL_CTX_SET_CIPHERSUITES */ + return (1); +#endif /* ifdef HAVE_SSL_CTX_SET_CIPHERSUITES */ + } + if (strcmp(argv[1], "--tsan") == 0) { #if defined(__has_feature) #if __has_feature(thread_sanitizer) diff --git a/configure.ac b/configure.ac index 75b9b40c11..60a0ad86f7 100644 --- a/configure.ac +++ b/configure.ac @@ -714,6 +714,7 @@ AC_CHECK_FUNCS([SSL_read_ex SSL_peek_ex SSL_write_ex]) AC_CHECK_FUNCS([SSL_CTX_set1_cert_store X509_STORE_up_ref]) AC_CHECK_FUNCS([SSL_CTX_up_ref]) AC_CHECK_FUNCS([SSL_SESSION_is_resumable]) +AC_CHECK_FUNCS([SSL_CTX_set_ciphersuites]) # # Check for algorithm support in OpenSSL diff --git a/doc/arm/reference.rst b/doc/arm/reference.rst index 8468a785ea..0f6d82e176 100644 --- a/doc/arm/reference.rst +++ b/doc/arm/reference.rst @@ -5823,9 +5823,20 @@ The following options can be specified in a :any:`tls` statement: versions might be specified (e.g. ``protocols { TLSv1.2; TLSv1.3; };``). +.. namedconf:statement:: cipher-suites + :tags: security + :short: Specifies a list of allowed cipher suites in the order of preference for TLSv1.3 only. + + Cipher suites list which defines allowed cipher suites, such as + ``TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256``. + The string must be formed according to the rules specified in the + OpenSSL documentation (see + https://www.openssl.org/docs/man1.1.1/man1/ciphers.html, section + "TLS v1.3 cipher suites" for details). + .. namedconf:statement:: ciphers :tags: security - :short: Specifies a list of allowed ciphers. + :short: Specifies a list of allowed ciphers in the order of preference for TLSv1.2 only. Cipher list which defines allowed ciphers, such as ``HIGH:!aNULL:!MD5:!SHA1:!SHA256:!SHA384``. The string must be diff --git a/doc/misc/options b/doc/misc/options index ac5dd66794..edf6fb04af 100644 --- a/doc/misc/options +++ b/doc/misc/options @@ -350,6 +350,7 @@ statistics-channels { tls { ca-file ; cert-file ; + cipher-suites ; ciphers ; dhparam-file ; key-file ; diff --git a/doc/notes/notes-current.rst b/doc/notes/notes-current.rst index 52774b07aa..d76a0a7ed4 100644 --- a/doc/notes/notes-current.rst +++ b/doc/notes/notes-current.rst @@ -20,7 +20,10 @@ Security Fixes New Features ~~~~~~~~~~~~ -- None. +- The ``tls`` block was extended with a new ``cipher-suites`` option + that allows setting allowed cipher suites for TLSv1.3. Please + consult the documentation for additional details. + :gl:`#3504` Removed Features ~~~~~~~~~~~~~~~~ diff --git a/lib/dns/include/dns/transport.h b/lib/dns/include/dns/transport.h index 705b1f4f76..b8845208e3 100644 --- a/lib/dns/include/dns/transport.h +++ b/lib/dns/include/dns/transport.h @@ -56,6 +56,8 @@ dns_transport_get_mode(const dns_transport_t *transport); char * dns_transport_get_ciphers(const dns_transport_t *transport); char * +dns_transport_get_cipher_suites(const dns_transport_t *transport); +char * dns_transport_get_tlsname(const dns_transport_t *transport); uint32_t dns_transport_get_tls_versions(const dns_transport_t *transport); @@ -66,8 +68,8 @@ 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, HTTP mode (GET or POST), ciphers, TLS name, - * TLS version, server ciphers preference mode, and always enabling + * hostname, HTTP endpoint, HTTP mode (GET or POST), ciphers, cipher suites, + * 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 @@ -116,6 +118,9 @@ dns_transport_set_mode(dns_transport_t *transport, dns_http_mode_t mode); void dns_transport_set_ciphers(dns_transport_t *transport, const char *ciphers); void +dns_transport_set_cipher_suites(dns_transport_t *transport, + const char *cipher_suites); +void dns_transport_set_tlsname(dns_transport_t *transport, const char *tlsname); void @@ -129,8 +134,8 @@ 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, HTTP mode (GET or POST), ciphers, TLS name, - * TLS version, server ciphers preference mode, and always enabling + * hostname, HTTP endpoint, HTTP mode (GET or POST), ciphers, cipher suites, TLS + *name, TLS version, server ciphers preference mode, and always enabling * authentication mode for 'transport'. * * Requires: diff --git a/lib/dns/transport.c b/lib/dns/transport.c index fb0c4ffb3d..b2328d144c 100644 --- a/lib/dns/transport.c +++ b/lib/dns/transport.c @@ -57,6 +57,7 @@ struct dns_transport { char *cafile; char *remote_hostname; char *ciphers; + char *cipher_suites; uint32_t protocol_versions; ternary_t prefer_server_ciphers; bool always_verify_remote; @@ -300,6 +301,30 @@ dns_transport_get_ciphers(const dns_transport_t *transport) { return (transport->tls.ciphers); } +void +dns_transport_set_cipher_suites(dns_transport_t *transport, + const char *cipher_suites) { + REQUIRE(VALID_TRANSPORT(transport)); + REQUIRE(transport->type == DNS_TRANSPORT_TLS || + transport->type == DNS_TRANSPORT_HTTP); + + if (transport->tls.cipher_suites != NULL) { + isc_mem_free(transport->mctx, transport->tls.cipher_suites); + } + + if (cipher_suites != NULL) { + transport->tls.cipher_suites = isc_mem_strdup(transport->mctx, + cipher_suites); + } +} + +char * +dns_transport_get_cipher_suites(const dns_transport_t *transport) { + REQUIRE(VALID_TRANSPORT(transport)); + + return (transport->tls.cipher_suites); +} + char * dns_transport_get_tlsname(const dns_transport_t *transport) { REQUIRE(VALID_TRANSPORT(transport)); @@ -367,6 +392,7 @@ dns_transport_get_tlsctx(dns_transport_t *transport, const isc_sockaddr_t *peer, isc_tlsctx_client_session_cache_t *found_sess_cache = NULL; uint32_t tls_versions; const char *ciphers = NULL; + const char *cipher_suites = NULL; bool prefer_server_ciphers; uint16_t family; const char *tlsname = NULL; @@ -422,6 +448,10 @@ dns_transport_get_tlsctx(dns_transport_t *transport, const isc_sockaddr_t *peer, if (ciphers != NULL) { isc_tlsctx_set_cipherlist(tlsctx, ciphers); } + cipher_suites = dns_transport_get_cipher_suites(transport); + if (cipher_suites != NULL) { + isc_tlsctx_set_cipher_suites(tlsctx, cipher_suites); + } if (dns_transport_get_prefer_server_ciphers( transport, &prefer_server_ciphers)) @@ -609,6 +639,9 @@ transport_destroy(dns_transport_t *transport) { if (transport->tls.ciphers != NULL) { isc_mem_free(transport->mctx, transport->tls.ciphers); } + if (transport->tls.cipher_suites != NULL) { + isc_mem_free(transport->mctx, transport->tls.cipher_suites); + } if (transport->tls.tlsname != NULL) { isc_mem_free(transport->mctx, transport->tls.tlsname); diff --git a/lib/isc/include/isc/tls.h b/lib/isc/include/isc/tls.h index 634ba65c4e..109a7f7eab 100644 --- a/lib/isc/include/isc/tls.h +++ b/lib/isc/include/isc/tls.h @@ -133,13 +133,34 @@ isc_tls_cipherlist_valid(const char *cipherlist); void isc_tlsctx_set_cipherlist(isc_tlsctx_t *ctx, const char *cipherlist); /*%< - * Set cipher list string for on the given TLS context 'ctx'. + * Set cipher list string for on the given TLS context 'ctx'. This affects only + * TLSv1.2 (and older). * * Requires: * \li 'ctx' != NULL; * \li 'cipherlist' a valid pointer to a non empty string. */ +bool +isc_tls_cipher_suites_valid(const char *cipher_suites); +/*%< + * Check if cipher suites string is valid. + * + * Requires: + * \li 'cipher_suites' a valid pointer to a non empty string. + */ + +void +isc_tlsctx_set_cipher_suites(isc_tlsctx_t *ctx, const char *cipher_suites); +/*%< + * Set cipher suites string for on the given TLS context 'ctx'. This affects + * only TLSv1.3. + * + * Requires: + * \li 'ctx' != NULL; + * \li 'cipher_suites' a valid pointer to a non empty string. + */ + void isc_tlsctx_prefer_server_ciphers(isc_tlsctx_t *ctx, const bool prefer); /*%< diff --git a/lib/isc/tls.c b/lib/isc/tls.c index e92f5af91a..b2fca8b459 100644 --- a/lib/isc/tls.c +++ b/lib/isc/tls.c @@ -788,6 +788,55 @@ isc_tlsctx_set_cipherlist(isc_tlsctx_t *ctx, const char *cipherlist) { RUNTIME_CHECK(SSL_CTX_set_cipher_list(ctx, cipherlist) == 1); } +bool +isc_tls_cipher_suites_valid(const char *cipher_suites) { +#ifdef HAVE_SSL_CTX_SET_CIPHERSUITES + isc_tlsctx_t *tmp_ctx = NULL; + const SSL_METHOD *method = NULL; + bool result; + REQUIRE(cipher_suites != NULL); + + if (*cipher_suites == '\0') { + return (false); + } + + method = TLS_server_method(); + if (method == NULL) { + return (false); + } + tmp_ctx = SSL_CTX_new(method); + if (tmp_ctx == NULL) { + return (false); + } + + result = SSL_CTX_set_ciphersuites(tmp_ctx, cipher_suites) == 1; + + isc_tlsctx_free(&tmp_ctx); + + return (result); +#else + UNUSED(cipher_suites); + + UNREACHABLE(); +#endif +} + +void +isc_tlsctx_set_cipher_suites(isc_tlsctx_t *ctx, const char *cipher_suites) { +#ifdef HAVE_SSL_CTX_SET_CIPHERSUITES + REQUIRE(ctx != NULL); + REQUIRE(cipher_suites != NULL); + REQUIRE(*cipher_suites != '\0'); + + RUNTIME_CHECK(SSL_CTX_set_ciphersuites(ctx, cipher_suites) == 1); +#else + UNUSED(ctx); + UNUSED(cipher_suites); + + UNREACHABLE(); +#endif +} + void isc_tlsctx_prefer_server_ciphers(isc_tlsctx_t *ctx, const bool prefer) { REQUIRE(ctx != NULL); diff --git a/lib/isccfg/check.c b/lib/isccfg/check.c index 8c8f7b6df7..c4e09f1c88 100644 --- a/lib/isccfg/check.c +++ b/lib/isccfg/check.c @@ -2131,7 +2131,8 @@ check_tls_defintion(const cfg_obj_t *tlsobj, const char *name, isc_log_t *logctx, isc_symtab_t *symtab) { isc_result_t result, tresult; const cfg_obj_t *tls_proto_list = NULL, *tls_key = NULL, - *tls_cert = NULL, *tls_ciphers = NULL; + *tls_cert = NULL, *tls_ciphers = NULL, + *tls_cipher_suites = NULL; uint32_t tls_protos = 0; isc_symvalue_t symvalue; @@ -2246,6 +2247,20 @@ check_tls_defintion(const cfg_obj_t *tlsobj, const char *name, } } + /* Check if the cipher suites string is valid */ + tresult = cfg_map_get(tlsobj, "cipher-suites", &tls_cipher_suites); + if (tresult == ISC_R_SUCCESS) { + const char *cipher_suites = cfg_obj_asstring(tls_cipher_suites); + if (!isc_tls_cipher_suites_valid(cipher_suites)) { + cfg_obj_log( + tls_cipher_suites, logctx, ISC_LOG_ERROR, + "'cipher-suites' in the 'tls' clause '%s' is " + "not a valid cipher suites string", + name); + result = ISC_R_FAILURE; + } + } + return (result); } diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c index 10aa92ee22..625edc7f4f 100644 --- a/lib/isccfg/namedconf.c +++ b/lib/isccfg/namedconf.c @@ -3971,6 +3971,11 @@ static cfg_clausedef_t tls_clauses[] = { { "dhparam-file", &cfg_type_qstring, 0 }, { "protocols", &cfg_type_tlsprotos, 0 }, { "ciphers", &cfg_type_astring, 0 }, +#ifdef HAVE_SSL_CTX_SET_CIPHERSUITES + { "cipher-suites", &cfg_type_astring, 0 }, +#else + { "cipher-suites", &cfg_type_astring, CFG_CLAUSEFLAG_NOTCONFIGURED }, +#endif { "prefer-server-ciphers", &cfg_type_boolean, 0 }, { "session-tickets", &cfg_type_boolean, 0 }, { NULL, NULL, 0 } diff --git a/lib/ns/include/ns/listenlist.h b/lib/ns/include/ns/listenlist.h index 0f06347058..275be49a51 100644 --- a/lib/ns/include/ns/listenlist.h +++ b/lib/ns/include/ns/listenlist.h @@ -70,6 +70,7 @@ typedef struct ns_listen_tls_params { uint32_t protocols; const char *dhparam_file; const char *ciphers; + const char *cipher_suites; bool prefer_server_ciphers; bool prefer_server_ciphers_set; bool session_tickets; diff --git a/lib/ns/listenlist.c b/lib/ns/listenlist.c index d267ebe1ea..cfac466540 100644 --- a/lib/ns/listenlist.c +++ b/lib/ns/listenlist.c @@ -135,6 +135,11 @@ listenelt_create(isc_mem_t *mctx, in_port_t port, dns_acl_t *acl, tls_params->ciphers); } + if (tls_params->cipher_suites != NULL) { + isc_tlsctx_set_cipher_suites( + sslctx, tls_params->cipher_suites); + } + if (tls_params->prefer_server_ciphers_set) { isc_tlsctx_prefer_server_ciphers( sslctx,