From ecf675884027e8d2d643d1006301bef092221aed Mon Sep 17 00:00:00 2001
From: Kaspar Brand
Date: Wed, 30 Sep 2015 11:50:30 +0000
Subject: [PATCH] merge r1703952 from trunk
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.
Proposed by: kbrand
Reviewed by: ylavic, jorton
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1706008 13f79535-47bb-0310-9956-ffa450edef68
---
CHANGES | 4 ++++
docs/manual/mod/mod_ssl.xml | 11 +++++++----
modules/ssl/mod_ssl.c | 11 ++++++++---
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, 61 insertions(+), 13 deletions(-)
diff --git a/CHANGES b/CHANGES
index 205113e03e..b31b1af66f 100644
--- a/CHANGES
+++ b/CHANGES
@@ -2,6 +2,10 @@
Changes with Apache 2.4.17
+ *) 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_ssl: append :!aNULL:!eNULL:!EXP to the cipher string settings,
instead of prepending !aNULL:!eNULL:!EXP: (as was the case in 2.4.7
and later). Enables support for configuring the SUITEB* cipher
diff --git a/docs/manual/mod/mod_ssl.xml b/docs/manual/mod/mod_ssl.xml
index 152aace24f..b5e1305e0b 100644
--- a/docs/manual/mod/mod_ssl.xml
+++ b/docs/manual/mod/mod_ssl.xml
@@ -586,7 +586,7 @@ by the applicable Security Policy.
SSLProtocol
Configure usable SSL/TLS protocol versions
SSLProtocol [+|-]protocol ...
-SSLProtocol all
+SSLProtocol all -SSLv3 (up to 2.4.16: all)
server config
virtual host
@@ -601,7 +601,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
@@ -624,7 +625,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
@@ -1943,7 +1946,7 @@ proxy SSL/TLS requests.
SSLProxyProtocol
Configure usable SSL protocol flavors for proxy usage
SSLProxyProtocol [+|-]protocol ...
-SSLProxyProtocol all
+SSLProxyProtocol all -SSLv3 (up to 2.4.16: all)
server config
virtual host
Options
diff --git a/modules/ssl/mod_ssl.c b/modules/ssl/mod_ssl.c
index 567daf0a09..41d7f9f705 100644
--- a/modules/ssl/mod_ssl.c
+++ b/modules/ssl/mod_ssl.c
@@ -125,10 +125,15 @@ static const command_rec ssl_config_cmds[] = {
SSL_CMD_SRV(SessionCacheTimeout, TAKE1,
"SSL Session Cache object lifetime "
"('N' - number of seconds)")
-#ifdef HAVE_TLSV1_X
-#define SSL_PROTOCOLS "SSLv3|TLSv1|TLSv1.1|TLSv1.2"
+#ifdef OPENSSL_NO_SSL3
+#define SSLv3_PROTO_PREFIX ""
#else
-#define SSL_PROTOCOLS "SSLv3|TLSv1"
+#define SSLv3_PROTO_PREFIX "SSLv3|"
+#endif
+#ifdef HAVE_TLSV1_X
+#define SSL_PROTOCOLS SSLv3_PROTO_PREFIX "TLSv1|TLSv1.1|TLSv1.2"
+#else
+#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 43be5db720..e5c70f39fc 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;
@@ -1343,7 +1343,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 05479625cc..8b26c353da 100644
--- a/modules/ssl/ssl_engine_init.c
+++ b/modules/ssl/ssl_engine_init.c
@@ -471,7 +471,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, " : ""),
@@ -483,12 +485,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 */
@@ -519,9 +524,11 @@ 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
if (!(protocol & SSL_PROTOCOL_SSLV3)) {
SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3);
}
+#endif
if (!(protocol & SSL_PROTOCOL_TLSV1)) {
SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1);
diff --git a/modules/ssl/ssl_engine_io.c b/modules/ssl/ssl_engine_io.c
index b2f97e9762..1e6c61846d 100644
--- a/modules/ssl/ssl_engine_io.c
+++ b/modules/ssl/ssl_engine_io.c
@@ -1081,7 +1081,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 1c91ffdf8d..dc4e61a6b3 100644
--- a/modules/ssl/ssl_private.h
+++ b/modules/ssl/ssl_private.h
@@ -297,16 +297,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 05f18b0703..02db919008 100644
--- a/support/ab.c
+++ b/support/ab.c
@@ -1961,6 +1961,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
@@ -1969,7 +1975,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);
}
@@ -2314,8 +2320,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();