Description: Support TLSv1.1 and TLSv1.2 in SSLProtocol directive
Forwarded: not-needed
Author: Stefan Fritsch
Last-Update: 2012-07-30
Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=682897
#
# This patch encompases backports from 2.4 branch;
#
#   http://svn.apache.org/viewvc?view=revision&revision=1222921
#   http://svn.apache.org/viewvc?view=revision&revision=1222930
#
# However, it also accounts for the fact that SSLv2 support
# remains present in httpd-2.2 branch and makes no changes
# which changes the existing configuration behavior, with
# the exception of adding TLS1.1 and TLS1.2 by default.)
#
Index: apache2/modules/ssl/ssl_private.h
===================================================================
--- apache2.orig/modules/ssl/ssl_private.h
+++ apache2/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
@@ -218,10 +223,14 @@
 #define SSL_PROTOCOL_SSLV2 (1<<0)
 #define SSL_PROTOCOL_SSLV3 (1<<1)
 #define SSL_PROTOCOL_TLSV1 (1<<2)
+#define SSL_PROTOCOL_TLSV1_1 (1<<3)
+#define SSL_PROTOCOL_TLSV1_2 (1<<4)
 #ifndef OPENSSL_NO_SSL2
-#define SSL_PROTOCOL_ALL   (SSL_PROTOCOL_SSLV2|SSL_PROTOCOL_SSLV3|SSL_PROTOCOL_TLSV1)
+#define SSL_PROTOCOL_ALL (SSL_PROTOCOL_SSLV2|SSL_PROTOCOL_SSLV3|SSL_PROTOCOL_TLSV1|\
+                          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_SSLV3|SSL_PROTOCOL_TLSV1|\
+                          SSL_PROTOCOL_TLSV1_1|SSL_PROTOCOL_TLSV1_2)
 #endif
 typedef int ssl_proto_t;
 
Index: apache2/modules/ssl/ssl_engine_init.c
===================================================================
--- apache2.orig/modules/ssl/ssl_engine_init.c
+++ apache2/modules/ssl/ssl_engine_init.c
@@ -459,6 +459,10 @@
                      (protocol & SSL_PROTOCOL_SSLV2 ? "SSLv2, " : ""),
                      (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;
 
@@ -474,6 +478,21 @@
     }
     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 */
+        ctx = SSL_CTX_new(method);
+    }
+    else if (protocol == SSL_PROTOCOL_TLSV1_2) {
+        method = mctx->pkp ?
+            TLSv1_2_client_method() : /* proxy */
+            TLSv1_2_server_method();  /* server */
+        ctx = SSL_CTX_new(method);
+    }
+    else
+#endif
     {
         method = mctx->pkp ?
             SSLv23_client_method() : /* proxy */
@@ -497,6 +516,16 @@
         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);
Index: apache2/modules/ssl/ssl_engine_config.c
===================================================================
--- apache2.orig/modules/ssl/ssl_engine_config.c
+++ apache2/modules/ssl/ssl_engine_config.c
@@ -1286,6 +1286,14 @@
         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: apache2/modules/ssl/mod_ssl.c
===================================================================
--- apache2.orig/modules/ssl/mod_ssl.c
+++ apache2/modules/ssl/mod_ssl.c
@@ -142,8 +142,8 @@
                 "SSL Session Cache object lifetime "
                 "(`N' - number of seconds)")
     SSL_CMD_SRV(Protocol, RAW_ARGS,
-                "Enable or disable various SSL protocols"
-                "(`[+-][SSLv2|SSLv3|TLSv1] ...' - see manual)")
+                "Enable or disable various SSL protocols "
+                "('[+-][SSLv3|TLSv1|TLSv1.1|TLSv1.2] ...' - see manual)")
     SSL_CMD_SRV(HonorCipherOrder, FLAG,
                 "Use the server's cipher ordering preference")
     SSL_CMD_SRV(InsecureRenegotiation, FLAG,
@@ -160,8 +160,8 @@
                 "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 "
+                "('[+-][SSLv3|TLSv1|TLSv1.1|TLSv1.2] ...' - see manual)")
     SSL_CMD_SRV(ProxyCipherSuite, TAKE1,
                "SSL Proxy: colon-delimited list of permitted SSL ciphers "
                "(`XXX:...:XXX' - see manual)")
