From 4c9b3c3b35b83c5ad182c73a25b097d4be933e4e Mon Sep 17 00:00:00 2001 From: Kaspar Brand Date: Sat, 19 Sep 2015 08:40:56 +0000 Subject: [PATCH] Support compilation against libssl built with OPENSSL_NO_SSL3, and change the compiled-in default for SSL[Proxy]Protocol to "all -SSLv3", in accordance with RFC 7568. PR 58349, PR 57120. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1703952 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES | 4 ++++ docs/manual/mod/mod_ssl.xml | 11 +++++++---- modules/ssl/mod_ssl.c | 9 +++++++-- modules/ssl/ssl_engine_config.c | 10 +++++++++- modules/ssl/ssl_engine_init.c | 9 ++++++++- modules/ssl/ssl_engine_io.c | 2 ++ modules/ssl/ssl_private.h | 17 ++++++++++++++--- support/ab.c | 10 +++++++++- 8 files changed, 60 insertions(+), 12 deletions(-) diff --git a/CHANGES b/CHANGES index df056b1c0c..3a77f52d26 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,10 @@ -*- coding: utf-8 -*- Changes with Apache 2.5.0 + *) mod_ssl: Support compilation against libssl built with OPENSSL_NO_SSL3, + and change the compiled-in default for SSL[Proxy]Protocol to "all -SSLv3", + in accordance with RFC 7568. PR 58349, PR 57120. [Kaspar Brand] + *) mod_proxy: Fix ProxySourceAddress binding failure with AH00938. PR 56687. [Arne de Bruijn diff --git a/docs/manual/mod/mod_ssl.xml b/docs/manual/mod/mod_ssl.xml index 5ca0eea368..34022c7de3 100644 --- a/docs/manual/mod/mod_ssl.xml +++ b/docs/manual/mod/mod_ssl.xml @@ -581,7 +581,7 @@ by the applicable Security Policy. SSLProtocol Configure usable SSL/TLS protocol versions SSLProtocol [+|-]protocol ... -SSLProtocol all +SSLProtocol all -SSLv3 server config virtual host @@ -596,7 +596,8 @@ The available (case-insensitive) protocols are:

This is the Secure Sockets Layer (SSL) protocol, version 3.0, from the Netscape Corporation. - It is the successor to SSLv2 and the predecessor to TLSv1.

+ It is the successor to SSLv2 and the predecessor to TLSv1, but is + deprecated in RFC 7568.

  • TLSv1

    @@ -619,7 +620,9 @@ The available (case-insensitive) protocols are:

    This is a shortcut for ``+SSLv3 +TLSv1'' or - when using OpenSSL 1.0.1 and later - - ``+SSLv3 +TLSv1 +TLSv1.1 +TLSv1.2, respectively.

  • + ``+SSLv3 +TLSv1 +TLSv1.1 +TLSv1.2'', respectively + (except for OpenSSL versions compiled with the ``no-ssl3'' configuration + option, where all does not include +SSLv3).

    Example @@ -1940,7 +1943,7 @@ proxy SSL/TLS requests.

    SSLProxyProtocol Configure usable SSL protocol flavors for proxy usage SSLProxyProtocol [+|-]protocol ... -SSLProxyProtocol all +SSLProxyProtocol all -SSLv3 server config virtual host Options diff --git a/modules/ssl/mod_ssl.c b/modules/ssl/mod_ssl.c index 56e6182ec4..4b7d1818b7 100644 --- a/modules/ssl/mod_ssl.c +++ b/modules/ssl/mod_ssl.c @@ -135,10 +135,15 @@ static const command_rec ssl_config_cmds[] = { SSL_CMD_SRV(SessionCacheTimeout, TAKE1, "SSL Session Cache object lifetime " "('N' - number of seconds)") +#ifdef OPENSSL_NO_SSL3 +#define SSLv3_PROTO_PREFIX "" +#else +#define SSLv3_PROTO_PREFIX "SSLv3|" +#endif #ifdef HAVE_TLSV1_X -#define SSL_PROTOCOLS "SSLv3|TLSv1|TLSv1.1|TLSv1.2" +#define SSL_PROTOCOLS SSLv3_PROTO_PREFIX "TLSv1|TLSv1.1|TLSv1.2" #else -#define SSL_PROTOCOLS "SSLv3|TLSv1" +#define SSL_PROTOCOLS SSLv3_PROTO_PREFIX "TLSv1" #endif SSL_CMD_SRV(Protocol, RAW_ARGS, "Enable or disable various SSL protocols " diff --git a/modules/ssl/ssl_engine_config.c b/modules/ssl/ssl_engine_config.c index c9012beb55..28f79ea684 100644 --- a/modules/ssl/ssl_engine_config.c +++ b/modules/ssl/ssl_engine_config.c @@ -111,7 +111,7 @@ static void modssl_ctx_init(modssl_ctx_t *mctx, apr_pool_t *p) mctx->ticket_key = NULL; #endif - mctx->protocol = SSL_PROTOCOL_ALL; + mctx->protocol = SSL_PROTOCOL_DEFAULT; mctx->protocol_set = 0; mctx->pphrase_dialog_type = SSL_PPTYPE_UNSET; @@ -1316,7 +1316,15 @@ static const char *ssl_cmd_protocol_parse(cmd_parms *parms, } } else if (strcEQ(w, "SSLv3")) { +#ifdef OPENSSL_NO_SSL3 + if (action != '-') { + return "SSLv3 not supported by this version of OpenSSL"; + } + /* Nothing to do, the flag is not present to be toggled */ + continue; +#else thisopt = SSL_PROTOCOL_SSLV3; +#endif } else if (strcEQ(w, "TLSv1")) { thisopt = SSL_PROTOCOL_TLSV1; diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c index 04ca2e603c..fcda4fbdf7 100644 --- a/modules/ssl/ssl_engine_init.c +++ b/modules/ssl/ssl_engine_init.c @@ -514,7 +514,9 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s, } cp = apr_pstrcat(p, +#ifndef OPENSSL_NO_SSL3 (protocol & SSL_PROTOCOL_SSLV3 ? "SSLv3, " : ""), +#endif (protocol & SSL_PROTOCOL_TLSV1 ? "TLSv1, " : ""), #ifdef HAVE_TLSV1_X (protocol & SSL_PROTOCOL_TLSV1_1 ? "TLSv1.1, " : ""), @@ -526,12 +528,15 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s, ap_log_error(APLOG_MARK, APLOG_TRACE3, 0, s, "Creating new SSL context (protocols: %s)", cp); +#ifndef OPENSSL_NO_SSL3 if (protocol == SSL_PROTOCOL_SSLV3) { method = mctx->pkp ? SSLv3_client_method() : /* proxy */ SSLv3_server_method(); /* server */ } - else if (protocol == SSL_PROTOCOL_TLSV1) { + else +#endif + if (protocol == SSL_PROTOCOL_TLSV1) { method = mctx->pkp ? TLSv1_client_method() : /* proxy */ TLSv1_server_method(); /* server */ @@ -562,8 +567,10 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s, /* always disable SSLv2, as per RFC 6176 */ SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2); +#ifndef OPENSSL_NO_SSL3 ssl_set_ctx_protocol_option(s, ctx, SSL_OP_NO_SSLv3, protocol & SSL_PROTOCOL_SSLV3, "SSLv3"); +#endif ssl_set_ctx_protocol_option(s, ctx, SSL_OP_NO_TLSv1, protocol & SSL_PROTOCOL_TLSV1, "TLSv1"); diff --git a/modules/ssl/ssl_engine_io.c b/modules/ssl/ssl_engine_io.c index 0cc013dcb5..bea0718e5e 100644 --- a/modules/ssl/ssl_engine_io.c +++ b/modules/ssl/ssl_engine_io.c @@ -1139,7 +1139,9 @@ static apr_status_t ssl_io_filter_handshake(ssl_filter_ctx_t *filter_ctx) * IPv4 and IPv6 addresses are not permitted".) */ if (hostname_note && +#ifndef OPENSSL_NO_SSL3 sc->proxy->protocol != SSL_PROTOCOL_SSLV3 && +#endif apr_ipsubnet_create(&ip, hostname_note, NULL, c->pool) != APR_SUCCESS) { if (SSL_set_tlsext_host_name(filter_ctx->pssl, hostname_note)) { diff --git a/modules/ssl/ssl_private.h b/modules/ssl/ssl_private.h index 6b89fcf24c..bc822235cf 100644 --- a/modules/ssl/ssl_private.h +++ b/modules/ssl/ssl_private.h @@ -287,16 +287,27 @@ typedef int ssl_opt_t; * Define the SSL Protocol options */ #define SSL_PROTOCOL_NONE (0) -#define SSL_PROTOCOL_SSLV2 (1<<0) +#ifndef OPENSSL_NO_SSL3 #define SSL_PROTOCOL_SSLV3 (1<<1) +#endif #define SSL_PROTOCOL_TLSV1 (1<<2) +#ifndef OPENSSL_NO_SSL3 +#define SSL_PROTOCOL_BASIC (SSL_PROTOCOL_SSLV3|SSL_PROTOCOL_TLSV1) +#else +#define SSL_PROTOCOL_BASIC (SSL_PROTOCOL_TLSV1) +#endif #ifdef HAVE_TLSV1_X #define SSL_PROTOCOL_TLSV1_1 (1<<3) #define SSL_PROTOCOL_TLSV1_2 (1<<4) -#define SSL_PROTOCOL_ALL (SSL_PROTOCOL_SSLV3|SSL_PROTOCOL_TLSV1| \ +#define SSL_PROTOCOL_ALL (SSL_PROTOCOL_BASIC| \ SSL_PROTOCOL_TLSV1_1|SSL_PROTOCOL_TLSV1_2) #else -#define SSL_PROTOCOL_ALL (SSL_PROTOCOL_SSLV3|SSL_PROTOCOL_TLSV1) +#define SSL_PROTOCOL_ALL (SSL_PROTOCOL_BASIC) +#endif +#ifndef OPENSSL_NO_SSL3 +#define SSL_PROTOCOL_DEFAULT (SSL_PROTOCOL_ALL & ~SSL_PROTOCOL_SSLV3) +#else +#define SSL_PROTOCOL_DEFAULT (SSL_PROTOCOL_ALL) #endif typedef int ssl_proto_t; diff --git a/support/ab.c b/support/ab.c index 096be0759e..44e55040b9 100644 --- a/support/ab.c +++ b/support/ab.c @@ -1997,6 +1997,12 @@ static void usage(const char *progname) #define SSL2_HELP_MSG "" #endif +#ifndef OPENSSL_NO_SSL3 +#define SSL3_HELP_MSG "SSL3, " +#else +#define SSL3_HELP_MSG "" +#endif + #ifdef HAVE_TLSV1_X #define TLS1_X_HELP_MSG ", TLS1.1, TLS1.2" #else @@ -2005,7 +2011,7 @@ static void usage(const char *progname) fprintf(stderr, " -Z ciphersuite Specify SSL/TLS cipher suite (See openssl ciphers)\n"); fprintf(stderr, " -f protocol Specify SSL/TLS protocol\n"); - fprintf(stderr, " (" SSL2_HELP_MSG "SSL3, TLS1" TLS1_X_HELP_MSG " or ALL)\n"); + fprintf(stderr, " (" SSL2_HELP_MSG SSL3_HELP_MSG "TLS1" TLS1_X_HELP_MSG " or ALL)\n"); #endif exit(EINVAL); } @@ -2350,8 +2356,10 @@ int main(int argc, const char * const argv[]) } else if (strncasecmp(opt_arg, "SSL2", 4) == 0) { meth = SSLv2_client_method(); #endif +#ifndef OPENSSL_NO_SSL3 } else if (strncasecmp(opt_arg, "SSL3", 4) == 0) { meth = SSLv3_client_method(); +#endif #ifdef HAVE_TLSV1_X } else if (strncasecmp(opt_arg, "TLS1.1", 6) == 0) { meth = TLSv1_1_client_method(); -- 2.40.0