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

index c7b9c2c091c1ef3568ad5448857f097443e5e39a..7266b82a1690230f697ab23d7e431afadb6c1f2e 100644 (file)
@@ -297,6 +297,7 @@ int ssl3_accept(SSL *s)
                                }
 
                        s->init_num=0;
                                }
 
                        s->init_num=0;
+                       s->s3->flags &= ~SSL3_FLAGS_SGC_RESTART_DONE;
 
                        if (s->state != SSL_ST_RENEGOTIATE)
                                {
 
                        if (s->state != SSL_ST_RENEGOTIATE)
                                {
@@ -871,6 +872,14 @@ int ssl3_check_client_hello(SSL *s)
        int ok;
        long n;
 
        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,
        /* this function is called when we really expect a Certificate message,
         * so permit appropriate message length */
        n=s->method->ssl_get_message(s,
@@ -899,6 +908,7 @@ int ssl3_check_client_hello(SSL *s)
                        s->s3->tmp.ecdh = NULL;
                        }
 #endif
                        s->s3->tmp.ecdh = NULL;
                        }
 #endif
+               s->s3->flags |= SSL3_FLAGS_SGC_RESTART_DONE;
                return 2;
                }
        return 1;
                return 2;
                }
        return 1;
index 4bf477a2f8bdbc3150c23b219b9df9032464caaa..9ce2684f4eaa6bb543eb525e0f1ee9bfa83d7e7f 100644 (file)
--- a/ssl/ssl.h
+++ b/ssl/ssl.h
@@ -2133,6 +2133,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_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
 #define SSL_F_SSL3_CLIENT_HELLO                                 131
 #define SSL_F_SSL3_CONNECT                              132
 #define SSL_F_SSL3_CTRL                                         213
@@ -2412,6 +2413,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_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
 #define SSL_R_NON_SSLV2_INITIAL_PACKET                  175
 #define SSL_R_NO_CERTIFICATES_RETURNED                  176
 #define SSL_R_NO_CERTIFICATE_ASSIGNED                   177
index 93f9ead3059b807c2d4e78122f551326d9a3bd3f..91089f3e8e44922a015d6612a7965e1fbb78d1da 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
 #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
 
 
 #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_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"},
 {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_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"},
 {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"},