From 0020e477c64c20939e44e892ad5656aba4b2d5e9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Henrik=20Grubbstr=C3=B6m=20=28Grubba=29?=
 <grubba@grubba.org>
Date: Sun, 22 Dec 2013 16:27:02 +0100
Subject: [PATCH] SSL: Don't attempt AEAD algorithms before TLS 1.2.

TLS 1.1 and earlier does not support AEAD algorithms,
so don't attempt to use them in that case.
---
 lib/modules/SSL.pmod/context.pike | 19 ++++++++++++++-----
 lib/modules/SSL.pmod/testsuite.in |  2 +-
 2 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/lib/modules/SSL.pmod/context.pike b/lib/modules/SSL.pmod/context.pike
index 24454d9194..a6afecfc6c 100644
--- a/lib/modules/SSL.pmod/context.pike
+++ b/lib/modules/SSL.pmod/context.pike
@@ -279,7 +279,7 @@ protected int cipher_suite_sort_key(int suite)
 //!   Note that the effective keylength may differ from
 //!   the actual keylength for old ciphers where there
 //!   are known attacks.
-array(int) get_suites(int sign, int min_keylength)
+array(int) get_suites(int sign, int min_keylength, int|void max_version)
 {
   // Default to the unsigned key exchange methods.
   multiset(int) kes = (< KE_null, KE_dh, KE_dh_anon >);
@@ -310,6 +310,15 @@ array(int) get_suites(int sign, int min_keylength)
 		 }, min_keylength);
   }
 
+  if (!zero_type(max_version) && (max_version < PROTOCOL_TLS_1_2)) {
+    // AEAD protocols are not supported prior to TLS 1.2.
+    res = filter(res,
+		 lambda(int suite) {
+		   return (sizeof(CIPHER_SUITES[suite]) < 4) ||
+		     (CIPHER_SUITES[suite][3] != MODE_gcm);
+		 });
+  }
+
   // Sort.
   sort(map(res, cipher_suite_sort_key), res);
 
@@ -337,10 +346,10 @@ void filter_weak_suites(int min_keylength)
 //!
 //! @seealso
 //!   @[dhe_dss_mode()], @[filter_weak_suites()]
-void rsa_mode(int|void min_keylength)
+void rsa_mode(int|void min_keylength, int|void max_version)
 {
   SSL3_DEBUG_MSG("SSL.context: rsa_mode()\n");
-  preferred_suites = get_suites(SIGNATURE_rsa, min_keylength);
+  preferred_suites = get_suites(SIGNATURE_rsa, min_keylength, max_version);
 }
 
 //! Set @[preferred_suites] to DSS based methods.
@@ -350,10 +359,10 @@ void rsa_mode(int|void min_keylength)
 //!
 //! @seealso
 //!   @[rsa_mode()], @[filter_weak_suites()]
-void dhe_dss_mode(int|void min_keylength)
+void dhe_dss_mode(int|void min_keylength, int|void max_version)
 {
   SSL3_DEBUG_MSG("SSL.context: dhe_dss_mode()\n");
-  preferred_suites = get_suites(SIGNATURE_dsa, min_keylength);
+  preferred_suites = get_suites(SIGNATURE_dsa, min_keylength, max_version);
 }
 
 //! Always ({ COMPRESSION_null })
diff --git a/lib/modules/SSL.pmod/testsuite.in b/lib/modules/SSL.pmod/testsuite.in
index 83bceee21b..f497df29f5 100644
--- a/lib/modules/SSL.pmod/testsuite.in
+++ b/lib/modules/SSL.pmod/testsuite.in
@@ -185,7 +185,7 @@ define(test_ssl, [[
     }
 
     if( `==($1,$2,$3,$4) )
-      suites = server_ctx->get_suites(mode,0) -
+      suites = server_ctx->get_suites(mode, 0, $4) -
   	    (invalid_suites[expected_protocol] || ({}));
 
     foreach(suites, int suite) {
-- 
GitLab