]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
mod_ssl: when compiled against OpenSSL 1.0.1 or later, allow explicit
authorWilliam A. Rowe Jr <wrowe@apache.org>
Mon, 20 Aug 2012 15:53:11 +0000 (15:53 +0000)
committerWilliam A. Rowe Jr <wrowe@apache.org>
Mon, 20 Aug 2012 15:53:11 +0000 (15:53 +0000)
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: 1222921122293012254761225792
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

CHANGES
STATUS
docs/manual/mod/mod_ssl.html.en
docs/manual/mod/mod_ssl.xml
modules/ssl/mod_ssl.c
modules/ssl/ssl_engine_config.c
modules/ssl/ssl_engine_init.c
modules/ssl/ssl_engine_kernel.c
modules/ssl/ssl_private.h

diff --git a/CHANGES b/CHANGES
index 992c6964f4b771fcb3ad71b45763043fedbfb411..853be7125d73cc383c86d4349caa72ec3179816c 100644 (file)
--- 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 <heinenn google.com>]
 
+  *) 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 5b2f1db1f4c63e52f54b9cd3d540b6fdbeeed279..1a1d6b21ef22e8c764175cc00b46ae6e4f09e4c4 100644 (file)
--- 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 <openssl/opensslconf.h> 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 ]
index 650e6293812813beb0558e238df52a3ed98afc94..786ae9aa112402eb61a37f423efecd5383dbdfc6 100644 (file)
@@ -114,7 +114,7 @@ compatibility variables.</p>
  <th>Description:</th>
 </tr>
 <tr><td><code>HTTPS</code></td>                         <td>flag</td>      <td>HTTPS is being used.</td></tr>
-<tr><td><code>SSL_PROTOCOL</code></td>                  <td>string</td>    <td>The SSL protocol version (SSLv2, SSLv3, TLSv1)</td></tr>
+<tr><td><code>SSL_PROTOCOL</code></td>                  <td>string</td>    <td>The SSL protocol version (SSLv2, SSLv3, TLSv1, TLSv1.1, TLSv1.2)</td></tr>
 <tr><td><code>SSL_SESSION_ID</code></td>                <td>string</td>    <td>The hex-encoded SSL session id</td></tr>
 <tr><td><code>SSL_CIPHER</code></td>                    <td>string</td>    <td>The cipher specification name</td></tr>
 <tr><td><code>SSL_CIPHER_EXPORT</code></td>             <td>string</td>    <td><code>true</code> if cipher is an export cipher</td></tr>
@@ -1012,20 +1012,29 @@ The available (case-insensitive) <em>protocol</em>s are:</p>
 
 <li><code>TLSv1</code>
     <p>
-    This is the Transport Layer Security (TLS) protocol, version 1.0. It is the
-    successor to SSLv3 and is defined in <a href="http://www.ietf.org/rfc/rfc2246.txt">RFC2246</a>. 
-    Which has been obsoleted by <a href="http://www.ietf.org/rfc/rfc4346.txt">RFC4346</a>.</p></li>
+    This is the Transport Layer Security (TLS) protocol, version 1.0.
+    It is the successor to SSLv3 and is defined in
+    <a href="http://www.ietf.org/rfc/rfc2246.txt">RFC 2246</a>.</p></li>
+
+<li><code>TLSv1.1</code> (when using OpenSSL 1.0.1 and later)
+    <p>
+    A revision of the TLS 1.0 protocol, as defined in
+    <a href="http://www.ietf.org/rfc/rfc4346.txt">RFC 4346</a>.</p></li>
+
+<li><code>TLSv1.2</code> (when using OpenSSL 1.0.1 and later)
+    <p>
+    A revision of the TLS 1.1 protocol, as defined in
+    <a href="http://www.ietf.org/rfc/rfc5246.txt">RFC 5246</a>.</p></li>
 
 <li><code>All</code>
     <p>
-    This is a shortcut for ``<code>+SSLv2 +SSLv3 +TLSv1</code>'' 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.</p></li>
+    This is a shortcut for ``<code>+SSLv2 +SSLv3 +TLSv1</code>'' or
+    - when using OpenSSL 1.0.1 and later -
+    ``<code>+SSLv2 +SSLv3 +TLSv1 +TLSv1.1 +TLSv1.2</code>'', respectively.</p></li>
 </ul>
 <div class="example"><h3>Example</h3><p><code>
-#   enable SSLv3 and TLSv1, but not SSLv2<br />
-SSLProtocol all -SSLv2
+# enable SSLv3 and all available TLSv1 flavors, but not SSLv2<br />
+SSLProtocol All -SSLv2
 </code></p></div>
 
 </div>
index 2a368c5ecc0fabf307d9200aae99a4483e15916b..3c9c9cba4cbd2b0797d77e8ac753516c0e74d22e 100644 (file)
@@ -61,7 +61,7 @@ compatibility variables.</p>
  <th>Description:</th>
 </tr>
 <tr><td><code>HTTPS</code></td>                         <td>flag</td>      <td>HTTPS is being used.</td></tr>
-<tr><td><code>SSL_PROTOCOL</code></td>                  <td>string</td>    <td>The SSL protocol version (SSLv2, SSLv3, TLSv1)</td></tr>
+<tr><td><code>SSL_PROTOCOL</code></td>                  <td>string</td>    <td>The SSL protocol version (SSLv2, SSLv3, TLSv1, TLSv1.1, TLSv1.2)</td></tr>
 <tr><td><code>SSL_SESSION_ID</code></td>                <td>string</td>    <td>The hex-encoded SSL session id</td></tr>
 <tr><td><code>SSL_CIPHER</code></td>                    <td>string</td>    <td>The cipher specification name</td></tr>
 <tr><td><code>SSL_CIPHER_EXPORT</code></td>             <td>string</td>    <td><code>true</code> if cipher is an export cipher</td></tr>
@@ -562,20 +562,29 @@ The available (case-insensitive) <em>protocol</em>s are:</p>
 
 <li><code>TLSv1</code>
     <p>
-    This is the Transport Layer Security (TLS) protocol, version 1.0. It is the
-    successor to SSLv3 and is defined in <a href="http://www.ietf.org/rfc/rfc2246.txt">RFC2246</a>. 
-    Which has been obsoleted by <a href="http://www.ietf.org/rfc/rfc4346.txt">RFC4346</a>.</p></li>
+    This is the Transport Layer Security (TLS) protocol, version 1.0.
+    It is the successor to SSLv3 and is defined in
+    <a href="http://www.ietf.org/rfc/rfc2246.txt">RFC 2246</a>.</p></li>
+
+<li><code>TLSv1.1</code> (when using OpenSSL 1.0.1 and later)
+    <p>
+    A revision of the TLS 1.0 protocol, as defined in
+    <a href="http://www.ietf.org/rfc/rfc4346.txt">RFC 4346</a>.</p></li>
+
+<li><code>TLSv1.2</code> (when using OpenSSL 1.0.1 and later)
+    <p>
+    A revision of the TLS 1.1 protocol, as defined in
+    <a href="http://www.ietf.org/rfc/rfc5246.txt">RFC 5246</a>.</p></li>
 
 <li><code>All</code>
     <p>
-    This is a shortcut for ``<code>+SSLv2 +SSLv3 +TLSv1</code>'' 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.</p></li>
+    This is a shortcut for ``<code>+SSLv2 +SSLv3 +TLSv1</code>'' or
+    - when using OpenSSL 1.0.1 and later -
+    ``<code>+SSLv2 +SSLv3 +TLSv1 +TLSv1.1 +TLSv1.2</code>'', respectively.</p></li>
 </ul>
 <example><title>Example</title>
-#   enable SSLv3 and TLSv1, but not SSLv2<br />
-SSLProtocol all -SSLv2
+# enable SSLv3 and all available TLSv1 flavors, but not SSLv2<br />
+SSLProtocol All -SSLv2
 </example>
 </usage>
 </directivesynopsis>
index a5fe388b3ba6764a2d90a42c07fff476758ba9cb..3e2e21bb40fba49cd939d8a3ddce96dbc46a646f 100644 (file)
@@ -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)")
index ee1243e47c1c84216bcf27d3e1fcd84afd1ca068..7a14bd53717f4b70e42b7adcccff57095cef2964 100644 (file)
@@ -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;
         }
index 2f0094ad84e3516547bc402b52ae2485d563ef5e..f5ccd12a4fda47dd7f35ce4f3b3c68de6f143559 100644 (file)
@@ -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),
index 5ea885752379bf53e332737576bb7d3f4cf83e5e..315ccafc1496eb92fd99e82a15e83b05c982cea7 100644 (file)
@@ -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,
index 6aaaae9cfed2d3adc75398c6f1fc727d7e9b0c0d..381aba45d82d102d88ff8bce2dbd3fe279e5dd7e 100644 (file)
 /** 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;