]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
Introduce new 'tls-protocols' configuration option (#1406)
authorYorgos Thessalonikefs <yorgos@nlnetlabs.nl>
Thu, 16 Apr 2026 08:38:24 +0000 (10:38 +0200)
committerGitHub <noreply@github.com>
Thu, 16 Apr 2026 08:38:24 +0000 (10:38 +0200)
- Introduce new 'tls-protocols' configuration option that specifies
  which of the supported TLS protocols will be used.
  This change invalidates some previous changes:
- TLSv1.2 is again enabled by default, but can be selectively turned off if
  desired (related to #1303).
- The biefly introduced (not yet released) 'tls-use-system-versions'
  configuration option, that addressed #1346, is reverted in favor of
  'tls-protocols'.
- The briefly introduced (not yet released) '--enable-system-tls'
  configure option, related to #1401, is no longer needed with the new
  option and the current default.

- Review comment for checking out of memory condition

Co-authored-by: Wouter Wijngaards <wcawijngaards@users.noreply.github.com>
14 files changed:
configure.ac
daemon/daemon.c
daemon/remote.c
dnstap/unbound-dnstap-socket.c
doc/example.conf.in
doc/unbound.conf.5.in
doc/unbound.conf.rst
util/config_file.c
util/config_file.h
util/configlexer.lex
util/configparser.y
util/net_help.c
util/net_help.h
winrc/win_svc.c

index bc1274c087358ec000722c25c651570df5e4f44a..8b56b09e1024d5076ed891d3e1fc7fc11bb7cdaa 100644 (file)
@@ -2081,19 +2081,6 @@ case "$enable_ipsecmod" in
                ;;
 esac
 
-# check for system TLS preference if requested
-AC_ARG_ENABLE(system-tls, AS_HELP_STRING([--enable-system-tls],[Enable preference of system configured TLS socket options]))
-case "$enable_system_tls" in
-       yes)
-               AC_DEFINE([USE_SYSTEM_TLS], [1], [Define to 1 to prefer TLS crypto settings from the system.])
-               SYSTEM_TLS_DEFAULT="yes"
-               ;;
-       no|*)
-               SYSTEM_TLS_DEFAULT="no"
-               ;;
-esac
-AC_SUBST([SYSTEM_TLS_DEFAULT])
-
 # check for ipset if requested
 AC_ARG_ENABLE(ipset, AS_HELP_STRING([--enable-ipset],[enable ipset module]))
 case "$enable_ipset" in
index 23e9493a0551eca73ae367e7a58364d8dd22c446..1c744538f2585dfc1cdeee228e7f336c2bb8df72 100644 (file)
@@ -215,7 +215,7 @@ setup_listen_sslctx(void** ctx, int is_dot, int is_doh,
                cfg->tls_ciphers, cfg->tls_ciphersuites,
                (cfg->tls_session_ticket_keys.first &&
                cfg->tls_session_ticket_keys.first->str[0] != 0),
-               is_dot, is_doh, cfg->tls_use_system_policy_versions))) {
+               is_dot, is_doh, cfg->tls_protocols))) {
                fatal_exit("could not set up listen SSL_CTX");
        }
 }
index 6a5b1ad12e12218880f1b03d73a45006c36e1f07..0aa3b49f0a354465b6941937c72ee5e296695ae9 100644 (file)
@@ -153,7 +153,7 @@ remote_setup_ctx(struct daemon_remote* rc, struct config_file* cfg)
                log_crypto_err("could not SSL_CTX_new");
                return 0;
        }
-       if(!listen_sslctx_setup(rc->ctx, cfg->tls_use_system_policy_versions)) {
+       if(!listen_sslctx_setup(rc->ctx, cfg->tls_protocols)) {
                return 0;
        }
 
@@ -4976,6 +4976,7 @@ fr_check_compat_cfg(struct fast_reload_thread* fr, struct config_file* newcfg)
        FR_CHECK_CHANGED_CFG("http_notls_downstream", http_notls_downstream, changed_str);
        FR_CHECK_CHANGED_CFG("https-port", https_port, changed_str);
        FR_CHECK_CHANGED_CFG("tls-port", ssl_port, changed_str);
+       FR_CHECK_CHANGED_CFG_STR("tls-protocols", tls_protocols, changed_str);
        FR_CHECK_CHANGED_CFG_STRLIST("proxy-protocol-port", proxy_protocol_port, changed_str);
        FR_CHECK_CHANGED_CFG_STRLIST("tls-additional-port", tls_additional_port, changed_str);
        FR_CHECK_CHANGED_CFG_STR("interface-automatic-ports", if_automatic_ports, changed_str);
@@ -5229,6 +5230,7 @@ config_file_getmem(struct config_file* cfg)
        m += getmem_config_strlist(cfg->tls_session_ticket_keys.first);
        m += getmem_str(cfg->tls_ciphers);
        m += getmem_str(cfg->tls_ciphersuites);
+       m += getmem_str(cfg->tls_protocols);
        m += getmem_str(cfg->http_endpoint);
        m += (cfg->outgoing_avail_ports?65536*sizeof(int):0);
        m += getmem_str(cfg->target_fetch_policy);
@@ -6060,8 +6062,8 @@ fr_atomic_copy_cfg(struct config_file* oldcfg, struct config_file* cfg,
        COPY_VAR_ptr(tls_session_ticket_keys.last);
        COPY_VAR_ptr(tls_ciphers);
        COPY_VAR_ptr(tls_ciphersuites);
+       COPY_VAR_ptr(tls_protocols);
        COPY_VAR_int(tls_use_sni);
-       COPY_VAR_int(tls_use_system_policy_versions);
        COPY_VAR_int(https_port);
        COPY_VAR_ptr(http_endpoint);
        COPY_VAR_uint32_t(http_max_streams);
index ac1fcfab4458442ea50e8fbaeca37566c051420a..90b0f6003ff6416bcbc5406166191d218d454966 100644 (file)
@@ -330,7 +330,7 @@ static struct tap_socket* tap_socket_new_tcpaccept(char* ip,
 /** create new socket (unconnected, not base-added), or NULL malloc fail */
 static struct tap_socket* tap_socket_new_tlsaccept(char* ip,
        void (*ev_cb)(int, short, void*), void* data, char* server_key,
-       char* server_cert, char* verifypem)
+       char* server_cert, char* verifypem, char* tls_protocols)
 {
        struct tap_socket* s = calloc(1, sizeof(*s));
        if(!s) {
@@ -347,7 +347,7 @@ static struct tap_socket* tap_socket_new_tlsaccept(char* ip,
        s->ev_cb = ev_cb;
        s->data = data;
        s->sslctx = listen_sslctx_create(server_key, server_cert, verifypem,
-               NULL, NULL, 0, 0, 0, 0);
+               NULL, NULL, 0, 0, 0, tls_protocols);
        if(!s->sslctx) {
                log_err("could not create ssl context");
                free(s->ip);
@@ -1261,13 +1261,13 @@ static void setup_tcp_list(struct main_tap_data* maindata,
 /** setup tls accept sockets */
 static void setup_tls_list(struct main_tap_data* maindata,
        struct config_strlist_head* tls_list, char* server_key,
-       char* server_cert, char* verifypem)
+       char* server_cert, char* verifypem, char* tls_protocols)
 {
        struct config_strlist* item;
        for(item = tls_list->first; item; item = item->next) {
                struct tap_socket* s;
                s = tap_socket_new_tlsaccept(item->str, &dtio_mainfdcallback,
-                       maindata, server_key, server_cert, verifypem);
+                       maindata, server_key, server_cert, verifypem, tls_protocols);
                if(!s) fatal_exit("out of memory");
                if(!tap_socket_list_insert(&maindata->acceptlist, s))
                        fatal_exit("out of memory");
@@ -1300,7 +1300,7 @@ static void
 setup_and_run(struct config_strlist_head* local_list,
        struct config_strlist_head* tcp_list,
        struct config_strlist_head* tls_list, char* server_key,
-       char* server_cert, char* verifypem)
+       char* server_cert, char* verifypem, char* tls_protocols)
 {
        time_t secs = 0;
        struct timeval now;
@@ -1326,7 +1326,7 @@ setup_and_run(struct config_strlist_head* local_list,
        setup_local_list(maindata, local_list);
        setup_tcp_list(maindata, tcp_list);
        setup_tls_list(maindata, tls_list, server_key, server_cert,
-               verifypem);
+               verifypem, tls_protocols);
        if(!tap_socket_list_addevs(maindata->acceptlist, base))
                fatal_exit("could not setup accept events");
        if(verbosity) log_info("start of service");
@@ -1462,6 +1462,8 @@ int main(int argc, char** argv)
        struct config_strlist_head tcp_list;
        struct config_strlist_head tls_list;
        char* server_key = NULL, *server_cert = NULL, *verifypem = NULL;
+
+       char* tls_protocols = "TLSv1.2 TLSv1.3";
 #ifdef USE_WINSOCK
        WSADATA wsa_data;
        if(WSAStartup(MAKEWORD(2,2), &wsa_data) != 0) {
@@ -1579,7 +1581,7 @@ int main(int argc, char** argv)
 #endif /* HAVE_SSL */
        }
        setup_and_run(&local_list, &tcp_list, &tls_list, server_key,
-               server_cert, verifypem);
+               server_cert, verifypem, tls_protocols);
        config_delstrlist(local_list.first);
        config_delstrlist(tcp_list.first);
        config_delstrlist(tls_list.first);
index 11f0458ce31fbcf1e2371dc2612e998d7abcc03e..2c6d63409dad26cbd6d3fdee0d92220118eb823c 100644 (file)
@@ -968,16 +968,12 @@ server:
        # tls-ciphersuites: "TLS_AES_128_GCM_SHA256:TLS_AES_128_CCM_8_SHA256:TLS_AES_128_CCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256"
 
        # Use the SNI extension for TLS connections.  Default is yes.
-       # Changing the value requires a reload.
+       # Changing the value requires a restart.
        # tls-use-sni: yes
 
-       # Allow general-purpose version-flexible TLS server configuration that
-       # may be further restricted by the system's policy.
-       # Use only if you want to support legacy TLS client connections.
-       # Default is a compilation choice.
-       # With 'no' Unbound will only use the latest available TLS version.
-       # Changing the value requires a reload.
-       # tls-use-system-policy-versions: no
+       # TLS protocols.
+       # Changing the value requires a restart.
+       # tls-protocols: "TLSv1.2 TLSv1.3"
 
        # Add the secret file for TLS Session Ticket.
        # Secret file must be 80 bytes of random data.
index 593a76189f768e0f98d903712db8f0b2946bd28c..f4bc93800aeefe5b46ebbdd8bd8c554eecccbc63 100644 (file)
@@ -1294,7 +1294,7 @@ Enable or disable sending the SNI extension on TLS connections.
 \fBNOTE:\fP
 .INDENT 7.0
 .INDENT 3.5
-Changing the value requires a reload.
+Changing the value requires a restart.
 .UNINDENT
 .UNINDENT
 .sp
@@ -1302,33 +1302,19 @@ Default: yes
 .UNINDENT
 .INDENT 0.0
 .TP
-.B tls\-use\-system\-policy\-versions: \fI<yes or no>\fP 
-Enable or disable general\-purpose version\-flexible TLS server configuration
-when serving TLS.
-This will allow the whole list of available TLS versions provided by the
-crypto library, which may have been further restricted by the system\(aqs
-crypto policy.
-.sp
-If disabled Unbound only uses the latest available TLS version.
-.sp
-The default depends on a compilation choice, it is set
-at @SYSTEM_TLS_DEFAULT@ .
-.sp
-\fBCAUTION:\fP
-.INDENT 7.0
-.INDENT 3.5
-Use only if you want to support legacy TLS client connections.
-.UNINDENT
-.UNINDENT
+.B tls\-protocols: \fI\(dq<list of protocols>\(dq\fP 
+Specify the allowed TLS protocol versions to use, in no particular order.
+Possible values are \fBTLSv1.2\fP and \fBTLSv1.3\fP\&.
+Enclose list of protocols in quotes (\fB\(dq\(dq\fP) and put spaces between them.
 .sp
 \fBNOTE:\fP
 .INDENT 7.0
 .INDENT 3.5
-Changing the value requires a reload.
+Changing the value requires a restart.
 .UNINDENT
 .UNINDENT
 .sp
-Default: @SYSTEM_TLS_DEFAULT@
+Default: \(dqTLSv1.2 TLSv1.3\(dq
 .UNINDENT
 .INDENT 0.0
 .TP
index bb7c9e067257c8c5ed3ba91ee1286149d7de29af..cc01451cd4324d37ab5a36507731b4146f0cd49c 100644 (file)
@@ -1180,28 +1180,19 @@ These options are part of the ``server:`` section.
 @@UAHL@unbound.conf@tls-use-sni@@: *<yes or no>*
     Enable or disable sending the SNI extension on TLS connections.
 
-    .. note:: Changing the value requires a reload.
+    .. note:: Changing the value requires a restart.
 
     Default: yes
 
 
-@@UAHL@unbound.conf@tls-use-system-policy-versions@@: *<yes or no>*
-    Enable or disable general-purpose version-flexible TLS server configuration
-    when serving TLS.
-    This will allow the whole list of available TLS versions provided by the
-    crypto library, which may have been further restricted by the system's
-    crypto policy.
+@@UAHL@unbound.conf@tls-protocols@@: *"<list of protocols>"*
+    Specify the allowed TLS protocol versions to use, in no particular order.
+    Possible values are ``TLSv1.2`` and ``TLSv1.3``.
+    Enclose list of protocols in quotes (``""``) and put spaces between them.
 
-    If disabled Unbound only uses the latest available TLS version.
+    .. note:: Changing the value requires a restart.
 
-    The default depends on a compilation choice, it is set
-    at @SYSTEM_TLS_DEFAULT@ .
-
-    .. caution:: Use only if you want to support legacy TLS client connections.
-
-    .. note:: Changing the value requires a reload.
-
-    Default: @SYSTEM_TLS_DEFAULT@
+    Default: "TLSv1.2 TLSv1.3"
 
 
 @@UAHL@unbound.conf@pad-responses@@: *<yes or no>*
index af8e3c310c3a23a9b4b55217c57c7e959d48f117..adee403b811f5d4a2354841260c6c8641626247f 100644 (file)
@@ -74,9 +74,6 @@
 #ifdef HAVE_PWD_H
 #include <pwd.h>
 #endif
-#ifndef USE_SYSTEM_TLS
-#define USE_SYSTEM_TLS 0
-#endif
 
 /** from cfg username, after daemonize setup performed */
 uid_t cfg_uid = (uid_t)-1;
@@ -135,7 +132,7 @@ config_create(void)
        cfg->tls_cert_bundle = NULL;
        cfg->tls_win_cert = 0;
        cfg->tls_use_sni = 1;
-       cfg->tls_use_system_policy_versions = USE_SYSTEM_TLS;
+       if(!(cfg->tls_protocols = strdup("TLSv1.2 TLSv1.3"))) goto error_exit;
        cfg->https_port = UNBOUND_DNS_OVER_HTTPS_PORT;
        if(!(cfg->http_endpoint = strdup("/dns-query"))) goto error_exit;
        cfg->http_max_streams = 100;
@@ -638,7 +635,11 @@ int config_set_option(struct config_file* cfg, const char* opt,
        else S_STR("tls-ciphers:", tls_ciphers)
        else S_STR("tls-ciphersuites:", tls_ciphersuites)
        else S_YNO("tls-use-sni:", tls_use_sni)
-       else S_YNO("tls-use-system-policy-versions:", tls_use_system_policy_versions)
+       else if(strcmp(opt, "tls-protocols:") == 0) {
+               if(!cfg_tls_protocols_is_valid(val)) return 0;
+               free(cfg->tls_protocols);
+               return (cfg->tls_protocols = strdup(val)) != NULL;
+       }
        else S_NUMBER_NONZERO("https-port:", https_port)
        else S_STR("http-endpoint:", http_endpoint)
        else S_NUMBER_NONZERO("http-max-streams:", http_max_streams)
@@ -1193,7 +1194,7 @@ config_get_option(struct config_file* cfg, const char* opt,
        else O_STR(opt, "tls-ciphers", tls_ciphers)
        else O_STR(opt, "tls-ciphersuites", tls_ciphersuites)
        else O_YNO(opt, "tls-use-sni", tls_use_sni)
-       else O_YNO(opt, "tls-use-system-policy-versions", tls_use_system_policy_versions)
+       else O_STR(opt, "tls-protocols", tls_protocols)
        else O_DEC(opt, "https-port", https_port)
        else O_STR(opt, "http-endpoint", http_endpoint)
        else O_UNS(opt, "http-max-streams", http_max_streams)
@@ -1765,6 +1766,7 @@ config_delete(struct config_file* cfg)
        config_delstrlist(cfg->tls_session_ticket_keys.first);
        free(cfg->tls_ciphers);
        free(cfg->tls_ciphersuites);
+       free(cfg->tls_protocols);
        free(cfg->http_endpoint);
        if(cfg->log_identity) {
                log_ident_revert_to_default();
@@ -2991,6 +2993,54 @@ cfg_has_quic(struct config_file* cfg)
 #endif
 }
 
+int
+cfg_tls_protocols_is_valid(const char* tls_protocols)
+{
+       const char* s = tls_protocols;
+       while(*s && isspace((unsigned char)*s)) s++;
+       while(*s && !isspace((unsigned char)*s)) {
+               if(strncmp(s, "TLSv1.2", 7) == 0 ||
+                       strncmp(s, "TLSv1.3", 7) == 0) {
+                       s += 7;
+                       if(*s && !isspace((unsigned char)*s)) {
+                               /* something is attached; fail */
+                               return 0;
+                       }
+                       while(*s && isspace((unsigned char)*s))
+                               s++;
+                       continue;
+               }
+               return 0;
+       }
+       return 1;
+}
+
+void
+cfg_tls_protocols_allowed(const char* tls_protocols, int* allow12, int* allow13)
+{
+       const char* s = tls_protocols;
+       *allow12 = 0;
+       *allow13 = 0;
+       if(tls_protocols == NULL) return;
+       while(*s && isspace((unsigned char)*s)) s++;
+       while(*s && !isspace((unsigned char)*s)) {
+               if(strncmp(s, "TLSv1.2", 7) == 0) {
+                       *allow12 = 1;
+                       s += 7;
+               } else if(strncmp(s, "TLSv1.3", 7) == 0) {
+                       *allow13 = 1;
+                       s += 7;
+               } else {
+                       /* Unknown word, this should never happen but skip to
+                        * be safe */
+                       while(*s && !isspace((unsigned char)*s))
+                               s++;
+               }
+               while(*s && isspace((unsigned char)*s))
+                       s++;
+       }
+}
+
 int
 file_get_mtime(const char* file, time_t* mtime, long* ns, int* nonexist)
 {
index 23468cb0974bc3eadf55a8558fb3c7ef6f46a8d1..6dadf0b72072d9ab7f8e630593188984da93d37e 100644 (file)
@@ -148,8 +148,8 @@ struct config_file {
        char* tls_ciphersuites;
        /** if SNI is to be used */
        int tls_use_sni;
-       /** if all TLS versions can be used; based on system policy (if any) */
-       int tls_use_system_policy_versions;
+       /** TLS protocols */
+       char* tls_protocols;
 
        /** port on which to provide DNS over HTTPS service */
        int https_port;
@@ -1495,6 +1495,21 @@ size_t getmem_str(char* str);
  */
 int cfg_ports_list_contains(char* ports, int p);
 
+/**
+ * Check if the configured string contains supported TLS protocols.
+ * @param tls_protocols: String with TLS protocols.
+ * @return true if all options are valid, else false.
+ */
+int cfg_tls_protocols_is_valid(const char* tls_protocols);
+
+/**
+ * Based on the configured TLS protocols fill which ones are allowed.
+ * @param tls_protocols: String with TLS protocols.
+ * @param allow12: will be true if TLSv1.2 is configured.
+ * @param allow13: will be true if TLSv1.3 is configured.
+ */
+void cfg_tls_protocols_allowed(const char* tls_protocols, int* allow12, int* allow13);
+
 /** get the file mtime stat (or error, with errno and nonexist) */
 int file_get_mtime(const char* file, time_t* mtime, long* ns, int* nonexist);
 
index 4540913a9e0d724229f941d3a17840f838ae92fb..d6222cdf9a7530d8ec72bc2bd018f58984de6aea 100644 (file)
@@ -13,7 +13,6 @@
 #pragma GCC diagnostic ignored "-Wsign-compare"
 #endif
 
-#include <ctype.h>
 #include <strings.h>
 #ifdef HAVE_GLOB_H
 # include <glob.h>
@@ -262,7 +261,7 @@ tls-session-ticket-keys{COLON}      { YDVAR(1, VAR_TLS_SESSION_TICKET_KEYS) }
 tls-ciphers{COLON}             { YDVAR(1, VAR_TLS_CIPHERS) }
 tls-ciphersuites{COLON}                { YDVAR(1, VAR_TLS_CIPHERSUITES) }
 tls-use-sni{COLON}             { YDVAR(1, VAR_TLS_USE_SNI) }
-tls-use-system-policy-versions{COLON}          { YDVAR(1, VAR_TLS_USE_SYSTEM_POLICY_VERSIONS) }
+tls-protocols{COLON}           { YDVAR(1, VAR_TLS_PROTOCOLS) }
 https-port{COLON}              { YDVAR(1, VAR_HTTPS_PORT) }
 http-endpoint{COLON}           { YDVAR(1, VAR_HTTP_ENDPOINT) }
 http-max-streams{COLON}                { YDVAR(1, VAR_HTTP_MAX_STREAMS) }
index 9b0ef9e72be31d6e1507a319419e8044ef42654d..6ea214ea55876ea754da53dee42b2e1468fa2b1f 100644 (file)
@@ -199,7 +199,7 @@ extern struct config_parser_state* cfg_parser;
 %token VAR_DISCARD_TIMEOUT VAR_WAIT_LIMIT VAR_WAIT_LIMIT_COOKIE
 %token VAR_WAIT_LIMIT_NETBLOCK VAR_WAIT_LIMIT_COOKIE_NETBLOCK
 %token VAR_STREAM_WAIT_SIZE VAR_TLS_CIPHERS VAR_TLS_CIPHERSUITES VAR_TLS_USE_SNI
-%token VAR_TLS_USE_SYSTEM_POLICY_VERSIONS
+%token VAR_TLS_PROTOCOLS
 %token VAR_IPSET VAR_IPSET_NAME_V4 VAR_IPSET_NAME_V6
 %token VAR_TLS_SESSION_TICKET_KEYS VAR_RPZ VAR_TAGS VAR_RPZ_ACTION_OVERRIDE
 %token VAR_RPZ_CNAME_OVERRIDE VAR_RPZ_LOG VAR_RPZ_LOG_NAME
@@ -348,8 +348,7 @@ content_server: server_num_threads | server_verbosity | server_port |
        server_stream_wait_size | server_tls_ciphers |
        server_tls_ciphersuites | server_tls_session_ticket_keys |
        server_answer_cookie | server_cookie_secret | server_ip_ratelimit_cookie |
-       server_tls_use_sni | server_edns_client_string |
-       server_tls_use_system_policy_versions |
+       server_tls_use_sni | server_edns_client_string | server_tls_protocols |
        server_edns_client_string_opcode | server_nsid |
        server_zonemd_permissive_mode | server_max_reuse_tcp_queries |
        server_tcp_reuse_timeout | server_tcp_auth_query_timeout |
@@ -1159,13 +1158,13 @@ server_tls_use_sni: VAR_TLS_USE_SNI STRING_ARG
                free($2);
        }
        ;
-server_tls_use_system_policy_versions: VAR_TLS_USE_SYSTEM_POLICY_VERSIONS STRING_ARG
+server_tls_protocols: VAR_TLS_PROTOCOLS STRING_ARG
        {
-               OUTYY(("P(server_tls_use_system_policy_versions:%s)\n", $2));
-               if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
-                       yyerror("expected yes or no.");
-               else cfg_parser->cfg->tls_use_system_policy_versions = (strcmp($2, "yes")==0);
-               free($2);
+               OUTYY(("P(server_tls_protocols:%s)\n", $2));
+               if(!cfg_tls_protocols_is_valid($2))
+                       yyerror("tls-protocols: valid values are 'TLSv1.2' and 'TLSv1.3'.");
+               free(cfg_parser->cfg->tls_protocols);
+               cfg_parser->cfg->tls_protocols = $2;
        }
        ;
 server_https_port: VAR_HTTPS_PORT STRING_ARG
index 36ed7a05e30559e664df2079a4470f121b252b16..fb38fdff8a843edbd0612b6f4466777600ea12a4 100644 (file)
@@ -1226,10 +1226,13 @@ setup_ticket_keys_cb(void* sslctx)
 #endif /* HAVE_SSL */
 
 int
-listen_sslctx_setup(void* ctxt, int use_system_versions)
+listen_sslctx_setup(void* ctxt, const char* tls_protocols)
 {
 #ifdef HAVE_SSL
+       int allow12, allow13;
        SSL_CTX* ctx = (SSL_CTX*)ctxt;
+       cfg_tls_protocols_allowed(tls_protocols, &allow12, &allow13);
+
        /* no SSLv2, SSLv3 because has defects */
 #if SSL_OP_NO_SSLv2 != 0
        if((SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2) & SSL_OP_NO_SSLv2)
@@ -1238,37 +1241,47 @@ listen_sslctx_setup(void* ctxt, int use_system_versions)
                return 0;
        }
 #endif
-       if(!use_system_versions) {
-               if((SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3) & SSL_OP_NO_SSLv3)
-                       != SSL_OP_NO_SSLv3){
-                       log_crypto_err("could not set SSL_OP_NO_SSLv3");
-                       return 0;
-               }
+       if((SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3) & SSL_OP_NO_SSLv3)
+               != SSL_OP_NO_SSLv3){
+               log_crypto_err("could not set SSL_OP_NO_SSLv3");
+               return 0;
+       }
 #if defined(SSL_OP_NO_TLSv1) && defined(SSL_OP_NO_TLSv1_1)
-               /* if we have tls 1.1 disable 1.0 */
-               if((SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1) & SSL_OP_NO_TLSv1)
-                       != SSL_OP_NO_TLSv1){
-                       log_crypto_err("could not set SSL_OP_NO_TLSv1");
-                       return 0;
-               }
+       /* if we have tls 1.1 disable 1.0 */
+       if((SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1) & SSL_OP_NO_TLSv1)
+               != SSL_OP_NO_TLSv1){
+               log_crypto_err("could not set SSL_OP_NO_TLSv1");
+               return 0;
+       }
 #endif
 #if defined(SSL_OP_NO_TLSv1_1) && defined(SSL_OP_NO_TLSv1_2)
-               /* if we have tls 1.2 disable 1.1 */
-               if((SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_1) & SSL_OP_NO_TLSv1_1)
-                       != SSL_OP_NO_TLSv1_1){
-                       log_crypto_err("could not set SSL_OP_NO_TLSv1_1");
-                       return 0;
-               }
+       /* if we have tls 1.2 disable 1.1 */
+       if((SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_1) & SSL_OP_NO_TLSv1_1)
+               != SSL_OP_NO_TLSv1_1){
+               log_crypto_err("could not set SSL_OP_NO_TLSv1_1");
+               return 0;
+       }
 #endif
-#if defined(SSL_OP_NO_TLSv1_2) && defined(SSL_OP_NO_TLSv1_3)
-               /* if we have tls 1.3 disable 1.2 */
+#if defined(SSL_OP_NO_TLSv1_2)
+       if(!allow12) {
+               /* we are not allowed to use TLS1.2 */
                if((SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_2) & SSL_OP_NO_TLSv1_2)
                        != SSL_OP_NO_TLSv1_2){
                        log_crypto_err("could not set SSL_OP_NO_TLSv1_2");
                        return 0;
                }
+       }
 #endif
+#if defined(SSL_OP_NO_TLSv1_3)
+       if(!allow13) {
+               /* we are not allowed to use TLS1.3 */
+               if((SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_3) & SSL_OP_NO_TLSv1_3)
+                       != SSL_OP_NO_TLSv1_3){
+                       log_crypto_err("could not set SSL_OP_NO_TLSv1_3");
+                       return 0;
+               }
        }
+#endif
 #if defined(SSL_OP_NO_RENEGOTIATION)
        /* disable client renegotiation */
        if((SSL_CTX_set_options(ctx, SSL_OP_NO_RENEGOTIATION) &
@@ -1307,7 +1320,7 @@ listen_sslctx_setup(void* ctxt, int use_system_versions)
        SSL_CTX_set_security_level(ctx, 0);
 #endif
 #else
-       (void)ctxt;
+       (void)ctxt; (void)tls_protocols;
 #endif /* HAVE_SSL */
        return 1;
 }
@@ -1343,7 +1356,7 @@ listen_sslctx_setup_2(void* ctxt)
 void* listen_sslctx_create(const char* key, const char* pem,
        const char* verifypem, const char* tls_ciphers,
        const char* tls_ciphersuites, int set_ticket_keys_cb,
-       int is_dot, int is_doh, int use_system_versions)
+       int is_dot, int is_doh, const char* tls_protocols)
 {
 #ifdef HAVE_SSL
        SSL_CTX* ctx = SSL_CTX_new(SSLv23_server_method());
@@ -1361,7 +1374,7 @@ void* listen_sslctx_create(const char* key, const char* pem,
                SSL_CTX_free(ctx);
                return NULL;
        }
-       if(!listen_sslctx_setup(ctx, use_system_versions)) {
+       if(!listen_sslctx_setup(ctx, tls_protocols)) {
                SSL_CTX_free(ctx);
                return NULL;
        }
index 757aff8556f1e1383627329bb54b1e569cf9a2e7..e9f6f3516ae503aae1a131ddd1605f1eb45246c8 100644 (file)
@@ -478,11 +478,10 @@ void log_cert(unsigned level, const char* str, void* cert);
 /**
  * Set SSL_OP_NOxxx options on SSL context to disable bad crypto
  * @param ctxt: SSL_CTX*
- * @param use_system_versions: rely on the system policy (if any) for allowed
- *     TLS versions
+ * @param tls_protocols: configure string with allowed TLS protocols to use.
  * @return false on failure.
  */
-int listen_sslctx_setup(void* ctxt, int use_system_versions);
+int listen_sslctx_setup(void* ctxt, const char* tls_protocols);
 
 /**
  * Further setup of listening SSL context, after keys loaded.
@@ -501,14 +500,13 @@ void listen_sslctx_setup_2(void* ctxt);
  *     to be set.
  * @param is_dot: if the TLS connection is for DoT to set the appropriate ALPN.
  * @param is_doh: if the TLS connection is for DoH to set the appropriate ALPN.
- * @param use_system_versions: rely on the system policy (if any) for allowed
- *     TLS versions
+ * @param tls_protocols: configure string with allowed TLS protocols to use.
  * return SSL_CTX* or NULL on failure (logged).
  */
 void* listen_sslctx_create(const char* key, const char* pem,
        const char* verifypem, const char* tls_ciphers,
        const char* tls_ciphersuites, int set_ticket_keys_cb,
-       int is_dot, int is_doh, int use_system_versions);
+       int is_dot, int is_doh, const char* tls_protocols);
 
 /**
  * create SSL connect context
index 6fca0c7d52c86085f66ea7211f945a2d8ae8bae4..c08ad97ec71d7b762a69e393e370c9a280ad5305 100644 (file)
@@ -369,7 +369,7 @@ service_init(int r, struct daemon** d, struct config_file** c)
                        cfg->tls_ciphers, cfg->tls_ciphersuites,
                        (cfg->tls_session_ticket_keys.first &&
                        cfg->tls_session_ticket_keys.first->str[0] != 0),
-                       1, 0, cfg->tls_use_system_policy_versions))) {
+                       1, 0, cfg->tls_protocols))) {
                        fatal_exit("could not set up listen SSL_CTX");
                }
 #ifdef HAVE_NGHTTP2_NGHTTP2_H
@@ -379,7 +379,7 @@ service_init(int r, struct daemon** d, struct config_file** c)
                                cfg->tls_ciphers, cfg->tls_ciphersuites,
                                (cfg->tls_session_ticket_keys.first &&
                                cfg->tls_session_ticket_keys.first->str[0] != 0),
-                               0, 1, cfg->tls_use_system_policy_versions))) {
+                               0, 1, cfg->tls_protocols))) {
                                fatal_exit("could not set up listen doh SSL_CTX");
                        }
                }