From: William A. Rowe Jr
Date: Mon, 20 Aug 2012 15:53:11 +0000 (+0000)
Subject: mod_ssl: when compiled against OpenSSL 1.0.1 or later, allow explicit
X-Git-Tag: 2.2.23~15
X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=dab83f78c3d4bc7010e13c8e49706a4d3008df4e;p=thirdparty%2Fapache%2Fhttpd.git
mod_ssl: when compiled against OpenSSL 1.0.1 or later, allow explicit
control of TLSv1.1 and TLSv1.2 through the SSLProtocol directive,
adding TLSv1.1 and TLSv1.2 support by default given 'SSLProtocol All'.
Picked up comment edit, trusting openssl compilation state and current
method which openssl uses to include opensslconf.h - if this should be
refined, it needs to be refined for other openssl operations as well.
Any #define OPENSSL_* for httpd alone would be invalid, these are all
namespace protected by openssl.org project.
Submitted by: kbrand, wrowe
Backports: 1222921, 1222930, 1225476, 1225792
Reviewed by: sf, kbrand, rjung
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.2.x@1375076 13f79535-47bb-0310-9956-ffa450edef68
---
diff --git a/CHANGES b/CHANGES
index 992c6964f4b..853be7125d7 100644
--- a/CHANGES
+++ b/CHANGES
@@ -10,6 +10,11 @@ Changes with Apache 2.2.23
possible XSS for a site where untrusted users can upload files to
a location with MultiViews enabled. [Niels Heinen ]
+ *) mod_ssl: when compiled against OpenSSL 1.0.1 or later, allow explicit
+ control of TLSv1.1 and TLSv1.2 through the SSLProtocol directive,
+ adding TLSv1.1 and TLSv1.2 support by default given 'SSLProtocol All'.
+ [Kaspar Brand, William Rowe]
+
*) mod_log_config: Fix %{abc}C truncating cookie values at first "=".
PR 53104. [Greg Ames]
diff --git a/STATUS b/STATUS
index 5b2f1db1f4c..1a1d6b21ef2 100644
--- a/STATUS
+++ b/STATUS
@@ -93,31 +93,6 @@ RELEASE SHOWSTOPPERS:
PATCHES ACCEPTED TO BACKPORT FROM TRUNK:
[ start all new proposals below, under PATCHES PROPOSED. ]
- * mod_ssl: when compiled against OpenSSL 1.0.1 or later, allow explicit
- control of TLSv1.1 and TLSv1.2 through the SSLProtocol directive,
- adding TLSv1.1 and TLSv1.2 support by default given 'SSLProtocol All'.
- [Kaspar Brand, William Rowe]
- http://svn.apache.org/viewvc?view=revision&revision=1222921
- http://svn.apache.org/viewvc?view=revision&revision=1222930
- http://svn.apache.org/viewvc?view=revision&revision=1225476
- http://svn.apache.org/viewvc?view=revision&revision=1225792
- Backport version for 2.2.x of the patches above:
- http://people.apache.org/~wrowe/tls11-12-patch-2.2-kbrand-wrowe.2.patch
- +1: wrowe, sf, kbrand, rjung
- kbrand: explicitly including in ssl_toolkit_compat.h
- would make sense, since we're relying on OPENSSL_NO_SSL2 being
- properly reported by OpenSSL (currently opensslconf.h is only
- indirectly included, which seems somewhat brittle)
- sf: I would also have taken the approach suggested by kbrand,
- but I am OK with the approach from patch .2, too.
- Minor (CTR) issues:
- - The "/* only SSLv2 is left */" comment is now obsolete.
- - Needs CHANGES entry.
- rjung: Voted on the basis, that OPENSSL_NO_SSL2 is not meant
- to be set for the web server compile only but instead
- would only be retrieved from OpenSSL. Otherwise
- setting OPENSSL_NO_SSL2 only for the web server compile
- does *not* disable SSLv2 (see r1374734).
PATCHES PROPOSED TO BACKPORT FROM TRUNK:
[ New proposals should be added at the end of the list ]
diff --git a/docs/manual/mod/mod_ssl.html.en b/docs/manual/mod/mod_ssl.html.en
index 650e6293812..786ae9aa112 100644
--- a/docs/manual/mod/mod_ssl.html.en
+++ b/docs/manual/mod/mod_ssl.html.en
@@ -114,7 +114,7 @@ compatibility variables.
Description: |
HTTPS | flag | HTTPS is being used. |
-SSL_PROTOCOL | string | The SSL protocol version (SSLv2, SSLv3, TLSv1) |
+SSL_PROTOCOL | string | The SSL protocol version (SSLv2, SSLv3, TLSv1, TLSv1.1, TLSv1.2) |
SSL_SESSION_ID | string | The hex-encoded SSL session id |
SSL_CIPHER | string | The cipher specification name |
SSL_CIPHER_EXPORT | string | true if cipher is an export cipher |
@@ -1012,20 +1012,29 @@ The available (case-insensitive) protocols are:
TLSv1
- This is the Transport Layer Security (TLS) protocol, version 1.0. It is the
- successor to SSLv3 and is defined in RFC2246.
- Which has been obsoleted by RFC4346.
+ This is the Transport Layer Security (TLS) protocol, version 1.0.
+ It is the successor to SSLv3 and is defined in
+ RFC 2246.
+
+TLSv1.1
(when using OpenSSL 1.0.1 and later)
+
+ A revision of the TLS 1.0 protocol, as defined in
+ RFC 4346.
+
+TLSv1.2
(when using OpenSSL 1.0.1 and later)
+
+ A revision of the TLS 1.1 protocol, as defined in
+ RFC 5246.
All
- This is a shortcut for ``+SSLv2 +SSLv3 +TLSv1
'' and a
- convenient way for enabling all protocols except one when used in
- combination with the minus sign on a protocol as the example above
- shows.
+ This is a shortcut for ``+SSLv2 +SSLv3 +TLSv1
'' or
+ - when using OpenSSL 1.0.1 and later -
+ ``+SSLv2 +SSLv3 +TLSv1 +TLSv1.1 +TLSv1.2
'', respectively.
Example
-# enable SSLv3 and TLSv1, but not SSLv2
-SSLProtocol all -SSLv2
+# enable SSLv3 and all available TLSv1 flavors, but not SSLv2
+SSLProtocol All -SSLv2
diff --git a/docs/manual/mod/mod_ssl.xml b/docs/manual/mod/mod_ssl.xml
index 2a368c5ecc0..3c9c9cba4cb 100644
--- a/docs/manual/mod/mod_ssl.xml
+++ b/docs/manual/mod/mod_ssl.xml
@@ -61,7 +61,7 @@ compatibility variables.
Description: |
HTTPS | flag | HTTPS is being used. |
-SSL_PROTOCOL | string | The SSL protocol version (SSLv2, SSLv3, TLSv1) |
+SSL_PROTOCOL | string | The SSL protocol version (SSLv2, SSLv3, TLSv1, TLSv1.1, TLSv1.2) |
SSL_SESSION_ID | string | The hex-encoded SSL session id |
SSL_CIPHER | string | The cipher specification name |
SSL_CIPHER_EXPORT | string | true if cipher is an export cipher |
@@ -562,20 +562,29 @@ The available (case-insensitive) protocols are:
TLSv1
- This is the Transport Layer Security (TLS) protocol, version 1.0. It is the
- successor to SSLv3 and is defined in RFC2246.
- Which has been obsoleted by RFC4346.
+ This is the Transport Layer Security (TLS) protocol, version 1.0.
+ It is the successor to SSLv3 and is defined in
+ RFC 2246.
+
+TLSv1.1
(when using OpenSSL 1.0.1 and later)
+
+ A revision of the TLS 1.0 protocol, as defined in
+ RFC 4346.
+
+TLSv1.2
(when using OpenSSL 1.0.1 and later)
+
+ A revision of the TLS 1.1 protocol, as defined in
+ RFC 5246.
All
- This is a shortcut for ``+SSLv2 +SSLv3 +TLSv1
'' and a
- convenient way for enabling all protocols except one when used in
- combination with the minus sign on a protocol as the example above
- shows.
+ This is a shortcut for ``+SSLv2 +SSLv3 +TLSv1
'' or
+ - when using OpenSSL 1.0.1 and later -
+ ``+SSLv2 +SSLv3 +TLSv1 +TLSv1.1 +TLSv1.2
'', respectively.
Example
-# enable SSLv3 and TLSv1, but not SSLv2
-SSLProtocol all -SSLv2
+# enable SSLv3 and all available TLSv1 flavors, but not SSLv2
+SSLProtocol All -SSLv2
diff --git a/modules/ssl/mod_ssl.c b/modules/ssl/mod_ssl.c
index a5fe388b3ba..3e2e21bb40f 100644
--- a/modules/ssl/mod_ssl.c
+++ b/modules/ssl/mod_ssl.c
@@ -141,9 +141,19 @@ static const command_rec ssl_config_cmds[] = {
SSL_CMD_SRV(SessionCacheTimeout, TAKE1,
"SSL Session Cache object lifetime "
"(`N' - number of seconds)")
+#ifdef OPENSSL_NO_SSL2
+#define SSLv2_PROTO_PREFIX ""
+#else
+#define SSLv2_PROTO_PREFIX "SSLv2|"
+#endif
+#ifdef HAVE_TLSV1_X
+#define SSL_PROTOCOLS SSLv2_PROTO_PREFIX "SSLv3|TLSv1|TLSv1.1|TLSv1.2"
+#else
+#define SSL_PROTOCOLS SSLv2_PROTO_PREFIX "SSLv3|TLSv1"
+#endif
SSL_CMD_SRV(Protocol, RAW_ARGS,
- "Enable or disable various SSL protocols"
- "(`[+-][SSLv2|SSLv3|TLSv1] ...' - see manual)")
+ "Enable or disable various SSL protocols "
+ "('[+-][" SSL_PROTOCOLS "] ...' - see manual)")
SSL_CMD_SRV(HonorCipherOrder, FLAG,
"Use the server's cipher ordering preference")
SSL_CMD_SRV(InsecureRenegotiation, FLAG,
@@ -160,8 +170,8 @@ static const command_rec ssl_config_cmds[] = {
"SSL switch for the proxy protocol engine "
"(`on', `off')")
SSL_CMD_SRV(ProxyProtocol, RAW_ARGS,
- "SSL Proxy: enable or disable SSL protocol flavors "
- "(`[+-][SSLv2|SSLv3|TLSv1] ...' - see manual)")
+ "SSL Proxy: enable or disable SSL protocol flavors "
+ "('[+-][" SSL_PROTOCOLS "] ...' - see manual)")
SSL_CMD_SRV(ProxyCipherSuite, TAKE1,
"SSL Proxy: colon-delimited list of permitted SSL ciphers "
"(`XXX:...:XXX' - see manual)")
diff --git a/modules/ssl/ssl_engine_config.c b/modules/ssl/ssl_engine_config.c
index ee1243e47c1..7a14bd53717 100644
--- a/modules/ssl/ssl_engine_config.c
+++ b/modules/ssl/ssl_engine_config.c
@@ -1280,8 +1280,11 @@ static const char *ssl_cmd_protocol_parse(cmd_parms *parms,
if (action != '-') {
return "SSLv2 not supported by this version of OpenSSL";
}
-#endif
+ /* Nothing to do, the flag is not present to be toggled */
+ continue;
+#else
thisopt = SSL_PROTOCOL_SSLV2;
+#endif
}
else if (strcEQ(w, "SSLv3")) {
thisopt = SSL_PROTOCOL_SSLV3;
@@ -1289,6 +1292,14 @@ static const char *ssl_cmd_protocol_parse(cmd_parms *parms,
else if (strcEQ(w, "TLSv1")) {
thisopt = SSL_PROTOCOL_TLSV1;
}
+#ifdef HAVE_TLSV1_X
+ else if (strcEQ(w, "TLSv1.1")) {
+ thisopt = SSL_PROTOCOL_TLSV1_1;
+ }
+ else if (strcEQ(w, "TLSv1.2")) {
+ thisopt = SSL_PROTOCOL_TLSV1_2;
+ }
+#endif
else if (strcEQ(w, "all")) {
thisopt = SSL_PROTOCOL_ALL;
}
diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c
index 2f0094ad84e..f5ccd12a4fd 100644
--- a/modules/ssl/ssl_engine_init.c
+++ b/modules/ssl/ssl_engine_init.c
@@ -456,9 +456,15 @@ static void ssl_init_ctx_protocol(server_rec *s,
}
cp = apr_pstrcat(p,
+#ifndef OPENSSL_NO_SSL2
(protocol & SSL_PROTOCOL_SSLV2 ? "SSLv2, " : ""),
+#endif
(protocol & SSL_PROTOCOL_SSLV3 ? "SSLv3, " : ""),
(protocol & SSL_PROTOCOL_TLSV1 ? "TLSv1, " : ""),
+#ifdef HAVE_TLSV1_X
+ (protocol & SSL_PROTOCOL_TLSV1_1 ? "TLSv1.1, " : ""),
+ (protocol & SSL_PROTOCOL_TLSV1_2 ? "TLSv1.2, " : ""),
+#endif
NULL);
cp[strlen(cp)-2] = NUL;
@@ -470,7 +476,19 @@ static void ssl_init_ctx_protocol(server_rec *s,
method = mctx->pkp ?
SSLv2_client_method() : /* proxy */
SSLv2_server_method(); /* server */
- ctx = SSL_CTX_new(method); /* only SSLv2 is left */
+ }
+ else
+#endif
+#ifdef HAVE_TLSV1_X
+ if (protocol == SSL_PROTOCOL_TLSV1_1) {
+ method = mctx->pkp ?
+ TLSv1_1_client_method() : /* proxy */
+ TLSv1_1_server_method(); /* server */
+ }
+ else if (protocol == SSL_PROTOCOL_TLSV1_2) {
+ method = mctx->pkp ?
+ TLSv1_2_client_method() : /* proxy */
+ TLSv1_2_server_method(); /* server */
}
else
#endif
@@ -478,16 +496,18 @@ static void ssl_init_ctx_protocol(server_rec *s,
method = mctx->pkp ?
SSLv23_client_method() : /* proxy */
SSLv23_server_method(); /* server */
- ctx = SSL_CTX_new(method); /* be more flexible */
}
+ ctx = SSL_CTX_new(method);
mctx->ssl_ctx = ctx;
SSL_CTX_set_options(ctx, SSL_OP_ALL);
+#ifndef OPENSSL_NO_SSL2
if (!(protocol & SSL_PROTOCOL_SSLV2)) {
SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2);
}
+#endif
if (!(protocol & SSL_PROTOCOL_SSLV3)) {
SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3);
@@ -497,6 +517,16 @@ static void ssl_init_ctx_protocol(server_rec *s,
SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1);
}
+#ifdef HAVE_TLSV1_X
+ if (!(protocol & SSL_PROTOCOL_TLSV1_1)) {
+ SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_1);
+ }
+
+ if (!(protocol & SSL_PROTOCOL_TLSV1_2)) {
+ SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_2);
+ }
+#endif
+
#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
if (sc->cipher_server_pref == TRUE) {
SSL_CTX_set_options(ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
@@ -1198,21 +1228,17 @@ void ssl_init_CheckServers(server_rec *base_server, apr_pool_t *p)
klen = strlen(key);
if ((ps = (server_rec *)apr_hash_get(table, key, klen))) {
- ap_log_error(APLOG_MARK,
#ifdef OPENSSL_NO_TLSEXT
- APLOG_WARNING,
+ int level = APLOG_WARNING;
+ const char *problem = "conflict";
#else
- APLOG_DEBUG,
-#endif
- 0,
- base_server,
-#ifdef OPENSSL_NO_TLSEXT
- "Init: SSL server IP/port conflict: "
-#else
- "Init: SSL server IP/port overlap: "
+ int level = APLOG_DEBUG;
+ const char *problem = "overlap";
#endif
+ ap_log_error(APLOG_MARK, level, 0, base_server,
+ "Init: SSL server IP/port %s: "
"%s (%s:%d) vs. %s (%s:%d)",
- ssl_util_vhostid(p, s),
+ problem, ssl_util_vhostid(p, s),
(s->defn_name ? s->defn_name : "unknown"),
s->defn_line_number,
ssl_util_vhostid(p, ps),
diff --git a/modules/ssl/ssl_engine_kernel.c b/modules/ssl/ssl_engine_kernel.c
index 5ea88575237..315ccafc149 100644
--- a/modules/ssl/ssl_engine_kernel.c
+++ b/modules/ssl/ssl_engine_kernel.c
@@ -741,6 +741,7 @@ int ssl_hook_Access(request_rec *r)
}
}
else {
+ const char *reneg_support;
request_rec *id = r->main ? r->main : r;
/* Additional mitigation for CVE-2009-3555: At this point,
@@ -760,17 +761,17 @@ int ssl_hook_Access(request_rec *r)
r->connection->keepalive = AP_CONN_CLOSE;
}
+#if defined(SSL_get_secure_renegotiation_support)
+ reneg_support = SSL_get_secure_renegotiation_support(ssl) ?
+ "client does" : "client does not";
+#else
+ reneg_support = "server does not";
+#endif
/* Perform a full renegotiation. */
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
"Performing full renegotiation: complete handshake "
"protocol (%s support secure renegotiation)",
-#if defined(SSL_get_secure_renegotiation_support)
- SSL_get_secure_renegotiation_support(ssl) ?
- "client does" : "client does not"
-#else
- "server does not"
-#endif
- );
+ reneg_support);
SSL_set_session_id_context(ssl,
(unsigned char *)&id,
diff --git a/modules/ssl/ssl_private.h b/modules/ssl/ssl_private.h
index 6aaaae9cfed..381aba45d82 100644
--- a/modules/ssl/ssl_private.h
+++ b/modules/ssl/ssl_private.h
@@ -59,6 +59,11 @@
/** mod_ssl headers */
#include "ssl_toolkit_compat.h"
#include "ssl_expr.h"
+
+#ifdef SSL_OP_NO_TLSv1_2
+#define HAVE_TLSV1_X
+#endif
+
#include "ssl_util_ssl.h"
/** The #ifdef macros are only defined AFTER including the above
@@ -215,13 +220,22 @@ typedef int ssl_opt_t;
* Define the SSL Protocol options
*/
#define SSL_PROTOCOL_NONE (0)
+#ifndef OPENSSL_NO_SSL2
#define SSL_PROTOCOL_SSLV2 (1<<0)
+#endif
#define SSL_PROTOCOL_SSLV3 (1<<1)
#define SSL_PROTOCOL_TLSV1 (1<<2)
-#ifndef OPENSSL_NO_SSL2
-#define SSL_PROTOCOL_ALL (SSL_PROTOCOL_SSLV2|SSL_PROTOCOL_SSLV3|SSL_PROTOCOL_TLSV1)
+#ifdef OPENSSL_NO_SSL2
+#define SSL_MOST_ALL SSL_PROTOCOL_SSLV3|SSL_PROTOCOL_TLSV1
+#else
+#define SSL_MOST_ALL SSL_PROTOCOL_SSLV2|SSL_PROTOCOL_SSLV3|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_MOST_ALL|SSL_PROTOCOL_TLSV1_1|SSL_PROTOCOL_TLSV1_2)
#else
-#define SSL_PROTOCOL_ALL (SSL_PROTOCOL_SSLV3|SSL_PROTOCOL_TLSV1)
+#define SSL_PROTOCOL_ALL (SSL_MOST_ALL)
#endif
typedef int ssl_proto_t;