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

diff --git a/CHANGES b/CHANGES
index a6672ed6fe73544050d33b93b580a6e0e7cbfe2d..5e6fcbd6b320b826e41c3d7a95ef09bac4fb514a 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -3,6 +3,9 @@
  _______________
 
  Changes between 0.9.8r and 0.9.8s [xx XXX xxxx]
+
+  *) Only allow one SGC handshake restart for SSL/TLS. (CVE-2011-4619)
+     [Adam Langley (Google)]
  
   *) Prevent malformed RFC3779 data triggering an assertion failure.
      Thanks to Andrew Chi, BBN Technologies, for discovering the flaw
index 4850a9a9570c20234e7e07484b2d26246d89f245..f6102123d43a7bf28b0ea6da102ff7739f4cb0dc 100644 (file)
@@ -235,6 +235,7 @@ int ssl3_accept(SSL *s)
                                }
 
                        s->init_num=0;
+                       s->s3->flags &= ~SSL3_FLAGS_SGC_RESTART_DONE;
 
                        if (s->state != SSL_ST_RENEGOTIATE)
                                {
@@ -697,6 +698,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,
@@ -725,6 +734,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 7d4e46e9163a683b86e483466c8c762209ae6b61..590a369fa305f4471b9b672478ec848fc6250946 100644 (file)
--- a/ssl/ssl.h
+++ b/ssl/ssl.h
@@ -1739,6 +1739,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                   292
 #define SSL_F_SSL3_CLIENT_HELLO                                 131
 #define SSL_F_SSL3_CONNECT                              132
 #define SSL_F_SSL3_CTRL                                         213
@@ -1974,6 +1975,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                     325
 #define SSL_R_NON_SSLV2_INITIAL_PACKET                  175
 #define SSL_R_NO_CERTIFICATES_RETURNED                  176
 #define SSL_R_NO_CERTIFICATE_ASSIGNED                   177
index 2f579c253bc8a2b18a4f3527ab51121b68ed6028..b9a85effa0058b1ad7b84e7ae7193057a8c4e372 100644 (file)
@@ -333,6 +333,17 @@ typedef struct ssl3_buffer_st
 #define SSL3_FLAGS_DELAY_CLIENT_FINISHED       0x0002
 #define SSL3_FLAGS_POP_BUFFER                  0x0004
 #define TLS1_FLAGS_TLS_PADDING_BUG             0x0008
+/* 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
 
 typedef struct ssl3_state_st
        {
index 7eb52026e78a135ee028b90422be226cca767c3e..bd52c98a0d0fe045384ebb475c3322f25c847f0d 100644 (file)
@@ -1,6 +1,6 @@
 /* ssl/ssl_err.c */
 /* ====================================================================
- * Copyright (c) 1999-2008 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1999-2011 The OpenSSL Project.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -137,6 +137,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"},
@@ -375,6 +376,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"},