dh-param quoted_string; // experimental
hostname quoted_string;
key-file quoted_string;
- protocols sslprotos; // experimental
+ protocols { string; ... };
};
TRUST-ANCHORS
#ifdef HAVE_LIBNGHTTP2
static isc_result_t
-listenelt_http(const cfg_obj_t *http, bool tls, const char *key,
- const char *cert, in_port_t port, isc_mem_t *mctx,
- ns_listenelt_t **target);
+listenelt_http(const cfg_obj_t *http, bool tls,
+ const ns_listen_tls_params_t *tls_params, in_port_t port,
+ isc_mem_t *mctx, ns_listenelt_t **target);
#endif
static isc_result_t
const char *key = NULL, *cert = NULL;
bool do_tls = false, no_tls = false, http = false;
ns_listenelt_t *delt = NULL;
+ uint32_t tls_protos = 0;
+ ns_listen_tls_params_t tls_params = { 0 };
REQUIRE(target != NULL && *target == NULL);
} else {
const cfg_obj_t *keyobj = NULL, *certobj = NULL;
const cfg_obj_t *tlsmap = NULL;
+ const cfg_obj_t *tls_proto_list = NULL;
do_tls = true;
CHECK(cfg_map_get(tlsmap, "cert-file", &certobj));
cert = cfg_obj_asstring(certobj);
+
+ if (cfg_map_get(tlsmap, "protocols", &tls_proto_list) ==
+ ISC_R_SUCCESS) {
+ const cfg_listelt_t *proto = NULL;
+ INSIST(tls_proto_list != NULL);
+ for (proto = cfg_list_first(tls_proto_list);
+ proto != 0; proto = cfg_list_next(proto))
+ {
+ const cfg_obj_t *tls_proto_obj =
+ cfg_listelt_value(proto);
+ const char *tls_sver =
+ cfg_obj_asstring(tls_proto_obj);
+ const isc_tls_protocol_version_t ver =
+ isc_tls_protocol_name_to_version(
+ tls_sver);
+
+ INSIST(ver !=
+ ISC_TLS_PROTO_VER_UNDEFINED);
+ INSIST(isc_tls_protocol_supported(ver));
+ tls_protos |= ver;
+ }
+ }
}
}
+ tls_params = (ns_listen_tls_params_t){ .key = key,
+ .cert = cert,
+ .protocols = tls_protos };
+
httpobj = cfg_tuple_get(ltup, "http");
if (httpobj != NULL && cfg_obj_isstring(httpobj)) {
const char *httpname = cfg_obj_asstring(httpobj);
#ifdef HAVE_LIBNGHTTP2
if (http) {
- CHECK(listenelt_http(http_server, do_tls, key, cert, port, mctx,
- &delt));
+ CHECK(listenelt_http(http_server, do_tls, &tls_params, port,
+ mctx, &delt));
}
#endif /* HAVE_LIBNGHTTP2 */
if (!http) {
- CHECK(ns_listenelt_create(mctx, port, dscp, NULL, do_tls, key,
- cert, &delt));
+ CHECK(ns_listenelt_create(mctx, port, dscp, NULL, do_tls,
+ &tls_params, &delt));
}
result = cfg_acl_fromconfig2(cfg_tuple_get(listener, "acl"), config,
#ifdef HAVE_LIBNGHTTP2
static isc_result_t
-listenelt_http(const cfg_obj_t *http, bool tls, const char *key,
- const char *cert, in_port_t port, isc_mem_t *mctx,
- ns_listenelt_t **target) {
+listenelt_http(const cfg_obj_t *http, bool tls,
+ const ns_listen_tls_params_t *tls_params, in_port_t port,
+ isc_mem_t *mctx, ns_listenelt_t **target) {
isc_result_t result = ISC_R_SUCCESS;
ns_listenelt_t *delt = NULL;
char **endpoints = NULL;
isc_quota_t *quota = NULL;
REQUIRE(target != NULL && *target == NULL);
- REQUIRE((key == NULL) == (cert == NULL));
+
+ if (tls) {
+ INSIST(tls_params != NULL);
+ INSIST((tls_params->key == NULL) == (tls_params->cert == NULL));
+ }
if (port == 0) {
port = tls ? named_g_httpsport : named_g_httpport;
isc_quota_init(quota, max_clients);
}
result = ns_listenelt_create_http(mctx, port, named_g_dscp, NULL, tls,
- key, cert, endpoints, len, quota,
+ tls_params, endpoints, len, quota,
max_streams, &delt);
if (result != ISC_R_SUCCESS) {
goto error;
--- /dev/null
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+tls local-tls {
+ key-file "key.pem";
+ cert-file "cert.pem";
+ protocols { unknown; TLSv1.2; }; # bad TLS protocol version name
+};
+
+options {
+ listen-on port 853 tls local-tls { 10.53.0.1; };
+};
--- /dev/null
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+tls local-tls {
+ key-file "key.pem";
+ cert-file "cert.pem";
+};
+
+tls local-tls {
+ key-file "key.pem";
+ cert-file "cert.pem";
+};
+
+options {
+ listen-on port 853 tls local-tls { 10.53.0.1; };
+};
--- /dev/null
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+# ephemeral is reserved for internal use
+tls ephemeral {
+ key-file "key.pem";
+ cert-file "cert.pem";
+};
+
+options {
+ listen-on port 853 tls ephemeral { 10.53.0.1; };
+};
--- /dev/null
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+tls local-tls {
+ key-file "key.pem";
+};
+
+http local-http-server {
+ endpoints { "/dns-query"; };
+ listener-clients 100;
+ streams-per-connection 100;
+};
+
+options {
+ listen-on { 10.53.0.1; };
+ http-port 80;
+ https-port 443;
+ http-listener-clients 100;
+ http-streams-per-connection 100;
+ listen-on port 443 tls local-tls http local-http-server { 10.53.0.1; };
+ listen-on port 8080 tls none http local-http-server { 10.53.0.1; };
+};
--- /dev/null
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+tls local-tls {
+ cert-file "cert.pem";
+};
+
+http local-http-server {
+ endpoints { "/dns-query"; };
+ listener-clients 100;
+ streams-per-connection 100;
+};
+
+options {
+ listen-on { 10.53.0.1; };
+ http-port 80;
+ https-port 443;
+ http-listener-clients 100;
+ http-streams-per-connection 100;
+ listen-on port 443 tls local-tls http local-http-server { 10.53.0.1; };
+ listen-on port 8080 tls none http local-http-server { 10.53.0.1; };
+};
--- /dev/null
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+# none is reserved for internal use
+tls none {
+ key-file "key.pem";
+ cert-file "cert.pem";
+};
+
+options {
+ listen-on port 853 tls none { 10.53.0.1; };
+};
--- /dev/null
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+tls local-tls {
+ protocols { TLSv1.2; };
+ key-file "key.pem";
+ cert-file "cert.pem";
+};
+
+http local-http-server {
+ endpoints { "/dns-query"; };
+ listener-clients 100;
+ streams-per-connection 100;
+};
+
+options {
+ listen-on { 10.53.0.1; };
+ http-port 80;
+ https-port 443;
+ http-listener-clients 100;
+ http-streams-per-connection 100;
+ listen-on port 443 tls local-tls http local-http-server { 10.53.0.1; };
+ listen-on port 8080 tls none http local-http-server { 10.53.0.1; };
+};
--- /dev/null
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+tls local-tls {
+ protocols { TLSv1.2; };
+ key-file "key.pem";
+ cert-file "cert.pem";
+};
+
+options {
+ listen-on port 853 tls local-tls { 10.53.0.1; };
+};
Declares communication channels to get access to ``named`` statistics.
``tls``
- Specifies configuration information for a TLS connection, including a ``key-file``, ``cert-file``, ``ca-file`` and ``hostname``.
+ Specifies configuration information for a TLS connection, including a ``key-file``, ``cert-file``, ``ca-file``, ``hostname``, and ``protocols``.
``http``
Specifies configuration information for an HTTP connection, including ``endponts``, ``listener-clients`` and ``streams-per-connection``.
``hostname``
The hostname associated with the certificate.
+ ``protocols``
+ Allowed versions of the TLS protocol. TLS version 1.2 and higher are
+ supported, depending on the cryptographic library in use. Multiple
+ versions might be specified (e.g.
+ ``protocols { TLSv1.2; TLSv1.3; };``).
+
There are two built-in TLS connection configurations: ``ephemeral``,
uses a temporary key and certificate created for the current ``named``
session only, and ``none``, which can be used when setting up an HTTP
dh\-param quoted_string; // experimental
hostname quoted_string;
key\-file quoted_string;
- protocols sslprotos; // experimental
+ protocols { string; ... };
};
.ft P
.fi
dh-param <quoted_string>; // experimental
hostname <quoted_string>;
key-file <quoted_string>;
- protocols <sslprotos>; // experimental
+ protocols { <string>; ... };
}; // may occur multiple times
trust-anchors { <string> ( static-key |
dh-param <quoted_string>; // experimental
hostname <quoted_string>;
key-file <quoted_string>;
- protocols <sslprotos>; // experimental
+ protocols { <string>; ... };
}; // may occur multiple times
trust-anchors { <string> ( static-key |
dh-param <quoted_string>; // experimental
hostname <quoted_string>;
key-file <quoted_string>;
- protocols <sslprotos>; // experimental
+ protocols { <string>; ... };
};
#include <stdbool.h>
#include <stdlib.h>
+#include <openssl/opensslv.h>
+
#ifdef HAVE_DNSTAP
#include <fstrm.h>
#endif
}
#endif /* HAVE_LIBNGHTTP2 */
+static isc_result_t
+bind9_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;
+ uint32_t tls_protos = 0;
+ isc_symvalue_t symvalue;
+
+ if (strcasecmp(name, "ephemeral") == 0 || strcasecmp(name, "none") == 0)
+ {
+ cfg_obj_log(tlsobj, logctx, ISC_LOG_ERROR,
+ "tls clause name '%s' is reserved for internal use",
+ name);
+ result = ISC_R_FAILURE;
+ } else {
+ /* Check for duplicates */
+ symvalue.as_cpointer = tlsobj;
+ result = isc_symtab_define(symtab, name, 1, symvalue,
+ isc_symexists_reject);
+ if (result == ISC_R_EXISTS) {
+ const char *file = NULL;
+ unsigned int line;
+
+ tresult = isc_symtab_lookup(symtab, name, 1, &symvalue);
+ RUNTIME_CHECK(tresult == ISC_R_SUCCESS);
+
+ line = cfg_obj_line(symvalue.as_cpointer);
+ file = cfg_obj_file(symvalue.as_cpointer);
+ if (file == NULL) {
+ file = "<unknown file>";
+ }
+
+ cfg_obj_log(tlsobj, logctx, ISC_LOG_ERROR,
+ "tls clause '%s' is duplicated: "
+ "also defined at %s:%u",
+ name, file, line);
+ }
+ }
+
+ if (cfg_map_get(tlsobj, "key-file", &tls_key) != ISC_R_SUCCESS) {
+ cfg_obj_log(tlsobj, logctx, ISC_LOG_ERROR,
+ "'key-file' is required in tls clause '%s'", name);
+ result = ISC_R_FAILURE;
+ }
+
+ if (cfg_map_get(tlsobj, "cert-file", &tls_cert) != ISC_R_SUCCESS) {
+ cfg_obj_log(tlsobj, logctx, ISC_LOG_ERROR,
+ "'cert-file' is required in tls clause '%s'", name);
+ result = ISC_R_FAILURE;
+ }
+
+ /* Check protocols are valid */
+ tresult = cfg_map_get(tlsobj, "protocols", &tls_proto_list);
+ if (tresult == ISC_R_SUCCESS) {
+ const cfg_listelt_t *proto = NULL;
+ INSIST(tls_proto_list != NULL);
+ for (proto = cfg_list_first(tls_proto_list); proto != 0;
+ proto = cfg_list_next(proto))
+ {
+ const cfg_obj_t *tls_proto_obj =
+ cfg_listelt_value(proto);
+ const char *tls_sver = cfg_obj_asstring(tls_proto_obj);
+ const isc_tls_protocol_version_t ver =
+ isc_tls_protocol_name_to_version(tls_sver);
+
+ if (ver == ISC_TLS_PROTO_VER_UNDEFINED) {
+ cfg_obj_log(tls_proto_obj, logctx,
+ ISC_LOG_ERROR,
+ "'%s' is not a valid "
+ "TLS protocol version",
+ tls_sver);
+ result = ISC_R_FAILURE;
+ continue;
+ } else if (!isc_tls_protocol_supported(ver)) {
+ cfg_obj_log(tls_proto_obj, logctx,
+ ISC_LOG_ERROR,
+ "'%s' is not "
+ "supported by the "
+ "cryptographic library version in "
+ "use (%s)",
+ tls_sver, OPENSSL_VERSION_TEXT);
+ result = ISC_R_FAILURE;
+ }
+
+ if ((tls_protos & ver) != 0) {
+ cfg_obj_log(tls_proto_obj, logctx,
+ ISC_LOG_WARNING,
+ "'%s' is specified more than once "
+ "in '%s'",
+ tls_sver, name);
+ result = ISC_R_FAILURE;
+ }
+
+ tls_protos |= ver;
+ }
+
+ if (tls_protos == 0) {
+ cfg_obj_log(tlsobj, logctx, ISC_LOG_ERROR,
+ "tls '%s' does not contain any valid "
+ "TLS protocol versions definitions",
+ name);
+ result = ISC_R_FAILURE;
+ }
+ }
+
+ return (result);
+}
+
+static isc_result_t
+bind9_check_tls_definitions(const cfg_obj_t *config, isc_log_t *logctx,
+ isc_mem_t *mctx) {
+ isc_result_t result, tresult;
+ const cfg_obj_t *obj = NULL;
+ const cfg_listelt_t *elt = NULL;
+ isc_symtab_t *symtab = NULL;
+
+ result = cfg_map_get(config, "tls", &obj);
+ if (result != ISC_R_SUCCESS) {
+ result = ISC_R_SUCCESS;
+ return (result);
+ }
+
+ result = isc_symtab_create(mctx, 100, NULL, NULL, false, &symtab);
+ if (result != ISC_R_SUCCESS) {
+ return (result);
+ }
+
+ for (elt = cfg_list_first(obj); elt != NULL; elt = cfg_list_next(elt)) {
+ const char *name;
+ obj = cfg_listelt_value(elt);
+ name = cfg_obj_asstring(cfg_map_getname(obj));
+ tresult = bind9_check_tls_defintion(obj, name, logctx, symtab);
+ if (result == ISC_R_SUCCESS) {
+ result = tresult;
+ }
+ }
+
+ isc_symtab_destroy(&symtab);
+
+ return (result);
+}
+
static isc_result_t
get_remotes(const cfg_obj_t *cctx, const char *list, const char *name,
const cfg_obj_t **ret) {
}
#endif /* HAVE_LIBNGHTTP2 */
+ if (bind9_check_tls_definitions(config, logctx, mctx) != ISC_R_SUCCESS)
+ {
+ result = ISC_R_FAILURE;
+ }
+
(void)cfg_map_get(config, "view", &views);
if (views != NULL && options != NULL) {
*\li 'ctxp' != NULL and '*ctxp' == NULL.
*/
+typedef enum isc_tls_protocol_version {
+ /* these must be the powers of two */
+ ISC_TLS_PROTO_VER_1_2 = 1 << 0,
+ ISC_TLS_PROTO_VER_1_3 = 1 << 1,
+ ISC_TLS_PROTO_VER_UNDEFINED,
+} isc_tls_protocol_version_t;
+
+void
+isc_tlsctx_set_protocols(isc_tlsctx_t *ctx, const uint32_t tls_versions);
+/*%<
+ * Sets the supported TLS protocol versions via the 'tls_versions' bit
+ * set argument (see `isc_tls_protocol_version_t` enum for the
+ * expected values).
+ *
+ * Requires:
+ *\li 'ctx' != NULL;
+ *\li 'tls_versions' != 0.
+ */
+
+bool
+isc_tls_protocol_supported(const isc_tls_protocol_version_t tls_ver);
+/*%<
+ * Check in runtime that the specified TLS protocol versions is supported.
+ */
+
+isc_tls_protocol_version_t
+isc_tls_protocol_name_to_version(const char *name);
+/*%<
+ * Convert the protocol version string into the version of
+ * 'isc_tls_protocol_version_t' type.
+ * Requires:
+ *\li 'name' != NULL.
+ */
+
isc_tls_t *
isc_tls_create(isc_tlsctx_t *ctx);
/*%<
*/
#include <inttypes.h>
+#include <string.h>
#if HAVE_LIBNGHTTP2
#include <nghttp2/nghttp2.h>
#endif /* HAVE_LIBNGHTTP2 */
return (ISC_R_TLSERROR);
}
+static long
+get_tls_version_disable_bit(const isc_tls_protocol_version_t tls_ver) {
+ long bit = 0;
+
+ switch (tls_ver) {
+ case ISC_TLS_PROTO_VER_1_2:
+#ifdef SSL_OP_NO_TLSv1_2
+ bit = SSL_OP_NO_TLSv1_2;
+#else
+ bit = 0;
+#endif
+ break;
+ case ISC_TLS_PROTO_VER_1_3:
+#ifdef SSL_OP_NO_TLSv1_3
+ bit = SSL_OP_NO_TLSv1_3;
+#else
+ bit = 0;
+#endif
+ break;
+ default:
+ INSIST(0);
+ ISC_UNREACHABLE();
+ break;
+ };
+
+ return (bit);
+}
+
+bool
+isc_tls_protocol_supported(const isc_tls_protocol_version_t tls_ver) {
+ return (get_tls_version_disable_bit(tls_ver) != 0);
+}
+
+isc_tls_protocol_version_t
+isc_tls_protocol_name_to_version(const char *name) {
+ REQUIRE(name != NULL);
+
+ if (strcasecmp(name, "TLSv1.2") == 0) {
+ return (ISC_TLS_PROTO_VER_1_2);
+ } else if (strcasecmp(name, "TLSv1.3") == 0) {
+ return (ISC_TLS_PROTO_VER_1_3);
+ }
+
+ return (ISC_TLS_PROTO_VER_UNDEFINED);
+}
+
+void
+isc_tlsctx_set_protocols(isc_tlsctx_t *ctx, const uint32_t tls_versions) {
+ REQUIRE(ctx != NULL);
+ REQUIRE(tls_versions != 0);
+ long set_options = 0;
+ long clear_options = 0;
+ uint32_t versions = tls_versions;
+
+ /*
+ * The code below might be initially hard to follow because of the
+ * double negation that OpenSSL enforces.
+ *
+ * Taking into account that OpenSSL provides bits to *disable*
+ * specific protocol versions, like SSL_OP_NO_TLSv1_2,
+ * SSL_OP_NO_TLSv1_3, etc., the code has the following logic:
+ *
+ * If a protocol version is not specified in the bitmask, get the
+ * bit that disables it and add it to the set of TLS options to
+ * set ('set_options'). Otherwise, if a protocol version is set,
+ * add the bit to the set of options to clear ('clear_options').
+ */
+
+ /* TLS protocol versions are defined as powers of two. */
+ for (uint32_t tls_ver = ISC_TLS_PROTO_VER_1_2;
+ tls_ver < ISC_TLS_PROTO_VER_UNDEFINED; tls_ver <<= 1)
+ {
+ /* Only supported versions should ever be passed to the
+ * function. The configuration file was not verified
+ * properly, if we are trying to enable an unsupported
+ * TLS version */
+ INSIST(isc_tls_protocol_supported(tls_ver));
+ if ((tls_versions & tls_ver) == 0) {
+ set_options |= get_tls_version_disable_bit(tls_ver);
+ } else {
+ clear_options |= get_tls_version_disable_bit(tls_ver);
+ }
+ versions &= ~(tls_ver);
+ }
+
+ /* All versions should be processed at this point, thus the value
+ * must equal zero. If it is not, then some garbage has been
+ * passed to the function; this situation is worth
+ * investigation. */
+ INSIST(versions == 0);
+
+ (void)SSL_CTX_set_options(ctx, set_options);
+ (void)SSL_CTX_clear_options(ctx, clear_options);
+}
+
isc_tls_t *
isc_tls_create(isc_tlsctx_t *ctx) {
isc_tls_t *newctx = NULL;
/*%
* "tls" and related statement syntax.
*/
-static cfg_type_t cfg_type_sslprotos = {
- "sslprotos", cfg_parse_spacelist, cfg_print_spacelist,
- cfg_doc_terminal, &cfg_rep_list, &cfg_type_astring
-};
+static cfg_type_t cfg_type_tlsprotos = { "tls_protocols",
+ cfg_parse_bracketed_list,
+ cfg_print_bracketed_list,
+ cfg_doc_bracketed_list,
+ &cfg_rep_list,
+ &cfg_type_astring };
static cfg_clausedef_t tls_clauses[] = {
{ "key-file", &cfg_type_qstring, 0 },
{ "ca-file", &cfg_type_qstring, 0 },
{ "hostname", &cfg_type_qstring, 0 },
{ "dh-param", &cfg_type_qstring, CFG_CLAUSEFLAG_EXPERIMENTAL },
- { "protocols", &cfg_type_sslprotos, CFG_CLAUSEFLAG_EXPERIMENTAL },
+ { "protocols", &cfg_type_tlsprotos, 0 },
{ "ciphers", &cfg_type_astring, CFG_CLAUSEFLAG_EXPERIMENTAL },
{ NULL, NULL, 0 }
};
ISC_LIST(ns_listenelt_t) elts;
};
+typedef struct ns_listen_tls_params {
+ const char *key;
+ const char *cert;
+ uint32_t protocols;
+} ns_listen_tls_params_t;
+
/***
*** Functions
***/
isc_result_t
ns_listenelt_create(isc_mem_t *mctx, in_port_t port, isc_dscp_t dscp,
- dns_acl_t *acl, bool tls, const char *key, const char *cert,
- ns_listenelt_t **target);
+ dns_acl_t *acl, bool tls,
+ const ns_listen_tls_params_t *tls_params,
+ ns_listenelt_t ** target);
/*%<
* Create a listen-on list element.
+ *
+ * Requires:
+ * \li 'targetp' is a valid pointer to a pointer containing 'NULL';
+ * \li 'tls_params' is a valid, non-'NULL' pointer if 'tls' equals 'true'.
*/
isc_result_t
ns_listenelt_create_http(isc_mem_t *mctx, in_port_t http_port, isc_dscp_t dscp,
- dns_acl_t *acl, bool tls, const char *key,
- const char *cert, char **endpoints, size_t nendpoints,
+ dns_acl_t *acl, bool tls,
+ const ns_listen_tls_params_t *tls_params,
+ char **endpoints, size_t nendpoints,
isc_quota_t *quota, const uint32_t max_streams,
ns_listenelt_t **target);
/*%<
isc_result_t
ns_listenelt_create(isc_mem_t *mctx, in_port_t port, isc_dscp_t dscp,
- dns_acl_t *acl, bool tls, const char *key, const char *cert,
+ dns_acl_t *acl, bool tls,
+ const ns_listen_tls_params_t *tls_params,
ns_listenelt_t **target) {
ns_listenelt_t *elt = NULL;
isc_result_t result = ISC_R_SUCCESS;
isc_tlsctx_t *sslctx = NULL;
REQUIRE(target != NULL && *target == NULL);
+ REQUIRE(!tls || tls_params != NULL);
if (tls) {
- result = isc_tlsctx_createserver(key, cert, &sslctx);
+ result = isc_tlsctx_createserver(tls_params->key,
+ tls_params->cert, &sslctx);
if (result != ISC_R_SUCCESS) {
return (result);
}
+
+ if (tls_params->protocols != 0) {
+ isc_tlsctx_set_protocols(sslctx, tls_params->protocols);
+ }
}
elt = isc_mem_get(mctx, sizeof(*elt));
isc_result_t
ns_listenelt_create_http(isc_mem_t *mctx, in_port_t http_port, isc_dscp_t dscp,
- dns_acl_t *acl, bool tls, const char *key,
- const char *cert, char **endpoints, size_t nendpoints,
+ dns_acl_t *acl, bool tls,
+ const ns_listen_tls_params_t *tls_params,
+ char **endpoints, size_t nendpoints,
isc_quota_t *quota, const uint32_t max_streams,
ns_listenelt_t **target) {
isc_result_t result;
REQUIRE(endpoints != NULL && *endpoints != NULL);
REQUIRE(nendpoints > 0);
- result = ns_listenelt_create(mctx, http_port, dscp, acl, tls, key, cert,
- target);
+ result = ns_listenelt_create(mctx, http_port, dscp, acl, tls,
+ tls_params, target);
if (result == ISC_R_SUCCESS) {
(*target)->is_http = true;
(*target)->http_endpoints = endpoints;
goto cleanup;
}
- result = ns_listenelt_create(mctx, port, dscp, acl, false, NULL, NULL,
- &elt);
+ result = ns_listenelt_create(mctx, port, dscp, acl, false, NULL, &elt);
if (result != ISC_R_SUCCESS) {
goto cleanup_acl;
}