Only allow one SGC handshake restart for SSL/TLS. (CVE-2011-4619)
authorDr. Stephen Henson <steve@openssl.org>
Wed, 4 Jan 2012 23:07:54 +0000 (23:07 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Wed, 4 Jan 2012 23:07:54 +0000 (23:07 +0000)
CHANGES
ssl/s3_srvr.c
ssl/ssl.h
ssl/ssl3.h
ssl/ssl_err.c

diff --git a/CHANGES b/CHANGES
index 338e49d95ccddca1ae48252014ef76302a275d69..c6df38ac9ace19dfebbb0b350c4928f9dec984d7 100644 (file)
--- a/CHANGES
+++ b/CHANGES
   *) Add support for SCTP.
      [Robin Seggelmann <seggelmann@fh-muenster.de>]
 
+  *) Only allow one SGC handshake restart for SSL/TLS. (CVE-2011-4619)
+     [Adam Langley (Google)]
+
+  *) Only allow one SGC handshake restart for SSL/TLS. (CVE-2011-4619)
+     [Adam Langley (Google)]
+
   *) Check parameters are not NULL in GOST ENGINE. (CVE-2012-0027)
      [Andrey Kulikov <amdeich@gmail.com>]
 
index eee8de1ab51dbf47d2b0eb1076dea73511d93fc4..45c36aed4fe3878f8ed8fb1a58732149503d168a 100644 (file)
@@ -295,6 +295,7 @@ int ssl3_accept(SSL *s)
                                }
 
                        s->init_num=0;
+                       s->s3->flags &= ~SSL3_FLAGS_SGC_RESTART_DONE;
 
                        if (s->state != SSL_ST_RENEGOTIATE)
                                {
@@ -869,6 +870,14 @@ int ssl3_check_client_hello(SSL *s)
        int ok;
        long n;
 
+       /* We only allow the client to restart the handshake once per
+        * negotiation. */
+       if (s->s3->flags & SSL3_FLAGS_SGC_RESTART_DONE)
+               {
+               SSLerr(SSL_F_SSL3_CHECK_CLIENT_HELLO, SSL_R_MULTIPLE_SGC_RESTARTS);
+               return -1;
+               }
+
        /* this function is called when we really expect a Certificate message,
         * so permit appropriate message length */
        n=s->method->ssl_get_message(s,
@@ -897,6 +906,7 @@ int ssl3_check_client_hello(SSL *s)
                        s->s3->tmp.ecdh = NULL;
                        }
 #endif
+               s->s3->flags |= SSL3_FLAGS_SGC_RESTART_DONE;
                return 2;
                }
        return 1;
index 40eb489e1aa664d385c9618790ecbaa9b654c9ab..5cb835a183dcac68ddc6763af16b50d55eb74a99 100644 (file)
--- a/ssl/ssl.h
+++ b/ssl/ssl.h
@@ -2118,6 +2118,7 @@ void ERR_load_SSL_strings(void);
 #define SSL_F_SSL3_CALLBACK_CTRL                        233
 #define SSL_F_SSL3_CHANGE_CIPHER_STATE                  129
 #define SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM             130
+#define SSL_F_SSL3_CHECK_CLIENT_HELLO                   315
 #define SSL_F_SSL3_CLIENT_HELLO                                 131
 #define SSL_F_SSL3_CONNECT                              132
 #define SSL_F_SSL3_CTRL                                         213
@@ -2397,6 +2398,7 @@ void ERR_load_SSL_strings(void);
 #define SSL_R_MISSING_TMP_RSA_KEY                       172
 #define SSL_R_MISSING_TMP_RSA_PKEY                      173
 #define SSL_R_MISSING_VERIFY_MESSAGE                    174
+#define SSL_R_MULTIPLE_SGC_RESTARTS                     370
 #define SSL_R_NON_SSLV2_INITIAL_PACKET                  175
 #define SSL_R_NO_CERTIFICATES_RETURNED                  176
 #define SSL_R_NO_CERTIFICATE_ASSIGNED                   177
index 05a59e6ce0cd120d4e272da405bc929d14bc68f8..badf89d3d9b3aaf481ff6301c955c6a220bb2d8a 100644 (file)
@@ -388,6 +388,17 @@ typedef struct ssl3_buffer_st
 #define TLS1_FLAGS_TLS_PADDING_BUG             0x0008
 #define TLS1_FLAGS_SKIP_CERT_VERIFY            0x0010
 #define TLS1_FLAGS_KEEP_HANDSHAKE              0x0020
+/* SSL3_FLAGS_SGC_RESTART_DONE is set when we
+ * restart a handshake because of MS SGC and so prevents us
+ * from restarting the handshake in a loop. It's reset on a
+ * renegotiation, so effectively limits the client to one restart
+ * per negotiation. This limits the possibility of a DDoS
+ * attack where the client handshakes in a loop using SGC to
+ * restart. Servers which permit renegotiation can still be
+ * effected, but we can't prevent that.
+ */
+#define SSL3_FLAGS_SGC_RESTART_DONE            0x0040
 
 #ifndef OPENSSL_NO_SSL_INTERN
 
index 0c3838a55d5b020dd7d031e67debf7e04d942b92..4eb2e44f5d09019f2d3ac0b9c8f5103fcf71995e 100644 (file)
@@ -138,6 +138,7 @@ static ERR_STRING_DATA SSL_str_functs[]=
 {ERR_FUNC(SSL_F_SSL3_CALLBACK_CTRL),   "SSL3_CALLBACK_CTRL"},
 {ERR_FUNC(SSL_F_SSL3_CHANGE_CIPHER_STATE),     "SSL3_CHANGE_CIPHER_STATE"},
 {ERR_FUNC(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM),        "SSL3_CHECK_CERT_AND_ALGORITHM"},
+{ERR_FUNC(SSL_F_SSL3_CHECK_CLIENT_HELLO),      "SSL3_CHECK_CLIENT_HELLO"},
 {ERR_FUNC(SSL_F_SSL3_CLIENT_HELLO),    "SSL3_CLIENT_HELLO"},
 {ERR_FUNC(SSL_F_SSL3_CONNECT), "SSL3_CONNECT"},
 {ERR_FUNC(SSL_F_SSL3_CTRL),    "SSL3_CTRL"},
@@ -420,6 +421,7 @@ static ERR_STRING_DATA SSL_str_reasons[]=
 {ERR_REASON(SSL_R_MISSING_TMP_RSA_KEY)   ,"missing tmp rsa key"},
 {ERR_REASON(SSL_R_MISSING_TMP_RSA_PKEY)  ,"missing tmp rsa pkey"},
 {ERR_REASON(SSL_R_MISSING_VERIFY_MESSAGE),"missing verify message"},
+{ERR_REASON(SSL_R_MULTIPLE_SGC_RESTARTS) ,"multiple sgc restarts"},
 {ERR_REASON(SSL_R_NON_SSLV2_INITIAL_PACKET),"non sslv2 initial packet"},
 {ERR_REASON(SSL_R_NO_CERTIFICATES_RETURNED),"no certificates returned"},
 {ERR_REASON(SSL_R_NO_CERTIFICATE_ASSIGNED),"no certificate assigned"},