From 97689c3c739d48ee649fbb40f550346b592a97e5 Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Sun, 2 Apr 2017 14:54:39 +0100 Subject: [PATCH] Openssl: disable session-tickets by default and session-cache always (cherry picked from commit 7006ee24ecfd9d8f405f70d38cc36bdd91f8de87) --- doc/doc-docbook/spec.xfpt | 2 +- doc/doc-txt/ChangeLog | 9 +++++++++ src/src/readconf.c | 4 ++-- src/src/tls-openssl.c | 36 ++++++++++++++++++++---------------- 4 files changed, 32 insertions(+), 19 deletions(-) diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt index afd690ab8..5900b9c9e 100644 --- a/doc/doc-docbook/spec.xfpt +++ b/doc/doc-docbook/spec.xfpt @@ -15676,7 +15676,7 @@ harm. This option overrides the &%pipe_as_creator%& option of the &(pipe)& transport driver. -.option openssl_options main "string list" "+no_sslv2 +single_dh_use" +.option openssl_options main "string list" "+no_sslv2 +single_dh_use +no_ticket" .cindex "OpenSSL "compatibility options" This option allows an administrator to adjust the SSL options applied by OpenSSL to connections. It is given as a space-separated list of items, diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog index 74414039f..8035ec4a5 100644 --- a/doc/doc-txt/ChangeLog +++ b/doc/doc-txt/ChangeLog @@ -12,6 +12,15 @@ Cherry-Picked from the master development branch HS/01 Cleanup, prevent repeated use of -p/-oMr (CVE-2017-1000369) +JH/06 Default openssl_options to include +no_ticket, to reduce load on peers. + Disable the session-cache too, which might reduce our load. Since we + currrectly use a new context for every connection, both as server and + client, there is no benefit for these. + GnuTLS appears to not support tickets server-side by default (we don't + call gnutls_session_ticket_enable_server()) but client side is enabled + by default on recent versions (3.1.3 +) unless the PFS priority string + is used (3.2.4 +). + Exim version 4.89 ----------------- diff --git a/src/src/readconf.c b/src/src/readconf.c index 790f07317..6a59dda71 100644 --- a/src/src/readconf.c +++ b/src/src/readconf.c @@ -3787,14 +3787,14 @@ if (tls_dh_max_bits < 1024) "tls_dh_max_bits is too small, must be at least 1024 for interop"); /* If openssl_options is set, validate it */ -if (openssl_options != NULL) +if (openssl_options) { # ifdef USE_GNUTLS log_write(0, LOG_PANIC_DIE|LOG_CONFIG, "openssl_options is set but we're using GnuTLS"); # else long dummy; - if (!(tls_openssl_options_parse(openssl_options, &dummy))) + if (!tls_openssl_options_parse(openssl_options, &dummy)) log_write(0, LOG_PANIC_DIE|LOG_CONFIG, "openssl_options parse error: %s", openssl_options); # endif diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c index 392d59dd5..60c07402b 100644 --- a/src/src/tls-openssl.c +++ b/src/src/tls-openssl.c @@ -1426,9 +1426,9 @@ tls_init(SSL_CTX **ctxp, host_item *host, uschar *dhparam, uschar *certificate, #endif address_item *addr, tls_ext_ctx_cb ** cbp) { +SSL_CTX * ctx; long init_options; int rc; -BOOL okay; tls_ext_ctx_cb * cbinfo; cbinfo = store_malloc(sizeof(tls_ext_ctx_cb)); @@ -1499,10 +1499,10 @@ if (!RAND_status()) /* Set up the information callback, which outputs if debugging is at a suitable level. */ -DEBUG(D_tls) SSL_CTX_set_info_callback(*ctxp, (void (*)())info_callback); +DEBUG(D_tls) SSL_CTX_set_info_callback(ctx, (void (*)())info_callback); /* Automatically re-try reads/writes after renegotiation. */ -(void) SSL_CTX_set_mode(*ctxp, SSL_MODE_AUTO_RETRY); +(void) SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY); /* Apply administrator-supplied work-arounds. Historically we applied just one requested option, @@ -1513,20 +1513,23 @@ grandfathered in the first one as the default value for "openssl_options". No OpenSSL version number checks: the options we accept depend upon the availability of the option value macros from OpenSSL. */ -okay = tls_openssl_options_parse(openssl_options, &init_options); -if (!okay) +if (!tls_openssl_options_parse(openssl_options, &init_options)) return tls_error(US"openssl_options parsing failed", host, NULL); if (init_options) { DEBUG(D_tls) debug_printf("setting SSL CTX options: %#lx\n", init_options); - if (!(SSL_CTX_set_options(*ctxp, init_options))) + if (!(SSL_CTX_set_options(ctx, init_options))) return tls_error(string_sprintf( "SSL_CTX_set_option(%#lx)", init_options), host, NULL); } else DEBUG(D_tls) debug_printf("no SSL CTX options to set\n"); +/* Disable session cache unconditionally */ + +(void) SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF); + /* Initialize with DH parameters if supplied */ /* Initialize ECDH temp key parameter selection */ @@ -1560,14 +1563,14 @@ if (host == NULL) /* server */ callback is invoked. */ if (cbinfo->u_ocsp.server.file) { - SSL_CTX_set_tlsext_status_cb(server_ctx, tls_server_stapling_cb); - SSL_CTX_set_tlsext_status_arg(server_ctx, cbinfo); + SSL_CTX_set_tlsext_status_cb(ctx, tls_server_stapling_cb); + SSL_CTX_set_tlsext_status_arg(ctx, cbinfo); } # endif /* We always do this, so that $tls_sni is available even if not used in tls_certificate */ - SSL_CTX_set_tlsext_servername_callback(*ctxp, tls_servername_cb); - SSL_CTX_set_tlsext_servername_arg(*ctxp, cbinfo); + SSL_CTX_set_tlsext_servername_callback(ctx, tls_servername_cb); + SSL_CTX_set_tlsext_servername_arg(ctx, cbinfo); } # ifndef DISABLE_OCSP else /* client */ @@ -1578,8 +1581,8 @@ else /* client */ DEBUG(D_tls) debug_printf("failed to create store for stapling verify\n"); return FAIL; } - SSL_CTX_set_tlsext_status_cb(*ctxp, tls_client_stapling_cb); - SSL_CTX_set_tlsext_status_arg(*ctxp, cbinfo); + SSL_CTX_set_tlsext_status_cb(ctx, tls_client_stapling_cb); + SSL_CTX_set_tlsext_status_arg(ctx, cbinfo); } # endif #endif @@ -1588,15 +1591,16 @@ cbinfo->verify_cert_hostnames = NULL; #ifdef EXIM_HAVE_EPHEM_RSA_KEX /* Set up the RSA callback */ -SSL_CTX_set_tmp_rsa_callback(*ctxp, rsa_callback); +SSL_CTX_set_tmp_rsa_callback(ctx, rsa_callback); #endif /* Finally, set the timeout, and we are done */ -SSL_CTX_set_timeout(*ctxp, ssl_session_timeout); +SSL_CTX_set_timeout(ctx, ssl_session_timeout); DEBUG(D_tls) debug_printf("Initialized TLS\n"); *cbp = cbinfo; +*ctxp = ctx; return OK; } @@ -2955,7 +2959,7 @@ uschar *s, *end; uschar keep_c; BOOL adding, item_parsed; -result = 0L; +result = SSL_OP_NO_TICKET; /* Prior to 4.80 we or'd in SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS; removed * from default because it increases BEAST susceptibility. */ #ifdef SSL_OP_NO_SSLv2 @@ -2965,7 +2969,7 @@ result |= SSL_OP_NO_SSLv2; result |= SSL_OP_SINGLE_DH_USE; #endif -if (option_spec == NULL) +if (!option_spec) { *results = result; return TRUE; -- 2.30.2