From 5656bbb44139897ce99de23e0b82fbd082b5069c Mon Sep 17 00:00:00 2001 From: Yorgos Thessalonikefs Date: Fri, 13 Feb 2026 17:17:55 +0100 Subject: [PATCH] - 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. --- configure.ac | 13 ------- daemon/remote.c | 6 ++-- daemon/unbound.c | 2 +- dnstap/unbound-dnstap-socket.c | 16 +++++---- doc/example.conf.in | 12 +++---- doc/unbound.conf.5.in | 28 ++++----------- doc/unbound.conf.rst | 23 ++++--------- util/config_file.c | 62 +++++++++++++++++++++++++++++---- util/config_file.h | 19 ++++++++-- util/configlexer.lex | 3 +- util/configparser.y | 17 +++++---- util/net_help.c | 63 ++++++++++++++++++++-------------- util/net_help.h | 10 +++--- winrc/win_svc.c | 4 +-- 14 files changed, 158 insertions(+), 120 deletions(-) diff --git a/configure.ac b/configure.ac index 7317aad60..41eedc2fd 100644 --- a/configure.ac +++ b/configure.ac @@ -2080,19 +2080,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 diff --git a/daemon/remote.c b/daemon/remote.c index 00e7dd21d..e55adee4d 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -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; } @@ -4939,6 +4939,7 @@ fr_check_compat_cfg(struct fast_reload_thread* fr, struct config_file* newcfg) FR_CHECK_CHANGED_CFG_STR("tls-service-key", ssl_service_key, changed_str); FR_CHECK_CHANGED_CFG_STR("tls-service-pem", ssl_service_pem, changed_str); FR_CHECK_CHANGED_CFG_STR("tls-cert-bundle", tls_cert_bundle, 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); @@ -5179,6 +5180,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); @@ -5873,8 +5875,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); diff --git a/daemon/unbound.c b/daemon/unbound.c index 688804743..7914f2cd6 100644 --- a/daemon/unbound.c +++ b/daemon/unbound.c @@ -473,7 +473,7 @@ setup_listen_sslctx(void** ctx, int is_dot, int is_doh, struct config_file* cfg) 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"); } } diff --git a/dnstap/unbound-dnstap-socket.c b/dnstap/unbound-dnstap-socket.c index ac1fcfab4..90b0f6003 100644 --- a/dnstap/unbound-dnstap-socket.c +++ b/dnstap/unbound-dnstap-socket.c @@ -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); diff --git a/doc/example.conf.in b/doc/example.conf.in index d5499b356..bf23a251e 100644 --- a/doc/example.conf.in +++ b/doc/example.conf.in @@ -965,16 +965,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. diff --git a/doc/unbound.conf.5.in b/doc/unbound.conf.5.in index d24872d8e..fa25d07d0 100644 --- a/doc/unbound.conf.5.in +++ b/doc/unbound.conf.5.in @@ -1290,7 +1290,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 @@ -1298,33 +1298,19 @@ Default: yes .UNINDENT .INDENT 0.0 .TP -.B tls\-use\-system\-policy\-versions: \fI\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\(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 diff --git a/doc/unbound.conf.rst b/doc/unbound.conf.rst index 885bd8deb..152014327 100644 --- a/doc/unbound.conf.rst +++ b/doc/unbound.conf.rst @@ -1172,28 +1172,19 @@ These options are part of the ``server:`` section. @@UAHL@unbound.conf@tls-use-sni@@: ** 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@@: ** - 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@@: *""* + 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@@: ** diff --git a/util/config_file.c b/util/config_file.c index 94c9b5edd..0175d562f 100644 --- a/util/config_file.c +++ b/util/config_file.c @@ -71,9 +71,6 @@ #ifdef HAVE_PWD_H #include #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; @@ -132,7 +129,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; + cfg->tls_protocols = strdup("TLSv1.2 TLSv1.3"); cfg->https_port = UNBOUND_DNS_OVER_HTTPS_PORT; if(!(cfg->http_endpoint = strdup("/dns-query"))) goto error_exit; cfg->http_max_streams = 100; @@ -634,7 +631,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) @@ -1188,7 +1189,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) @@ -1759,6 +1760,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(); @@ -2984,3 +2986,51 @@ cfg_has_quic(struct config_file* cfg) return 0; #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++; + } +} diff --git a/util/config_file.h b/util/config_file.h index aff3fd78b..90e5b09db 100644 --- a/util/config_file.h +++ b/util/config_file.h @@ -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; @@ -1493,4 +1493,19 @@ 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); + #endif /* UTIL_CONFIG_FILE_H */ diff --git a/util/configlexer.lex b/util/configlexer.lex index 566de49ab..4780b86f1 100644 --- a/util/configlexer.lex +++ b/util/configlexer.lex @@ -13,7 +13,6 @@ #pragma GCC diagnostic ignored "-Wsign-compare" #endif -#include #include #ifdef HAVE_GLOB_H # include @@ -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) } diff --git a/util/configparser.y b/util/configparser.y index d9a7cd839..b159fa83a 100644 --- a/util/configparser.y +++ b/util/configparser.y @@ -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 @@ -347,8 +347,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 | @@ -1157,13 +1156,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 diff --git a/util/net_help.c b/util/net_help.c index 9ad9a3bb8..79d04a55f 100644 --- a/util/net_help.c +++ b/util/net_help.c @@ -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 } +#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; } diff --git a/util/net_help.h b/util/net_help.h index 1f31a89c3..ec7620c37 100644 --- a/util/net_help.h +++ b/util/net_help.h @@ -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 diff --git a/winrc/win_svc.c b/winrc/win_svc.c index 6fca0c7d5..c08ad97ec 100644 --- a/winrc/win_svc.c +++ b/winrc/win_svc.c @@ -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"); } }