Fix for CVE-2014-0224
[openssl.git] / ssl / s3_srvr.c
index f6102123d43a7bf28b0ea6da102ff7739f4cb0dc..fcc97f374f56b5fa550439e92a50b6c54a45bee5 100644 (file)
@@ -523,6 +523,7 @@ int ssl3_accept(SSL *s)
                case SSL3_ST_SR_CERT_VRFY_A:
                case SSL3_ST_SR_CERT_VRFY_B:
 
                case SSL3_ST_SR_CERT_VRFY_A:
                case SSL3_ST_SR_CERT_VRFY_B:
 
+                       s->s3->flags |= SSL3_FLAGS_CCS_OK;
                        /* we should decide if we expected this one */
                        ret=ssl3_get_cert_verify(s);
                        if (ret <= 0) goto end;
                        /* we should decide if we expected this one */
                        ret=ssl3_get_cert_verify(s);
                        if (ret <= 0) goto end;
@@ -533,6 +534,7 @@ int ssl3_accept(SSL *s)
 
                case SSL3_ST_SR_FINISHED_A:
                case SSL3_ST_SR_FINISHED_B:
 
                case SSL3_ST_SR_FINISHED_A:
                case SSL3_ST_SR_FINISHED_B:
+                       s->s3->flags |= SSL3_FLAGS_CCS_OK;
                        ret=ssl3_get_finished(s,SSL3_ST_SR_FINISHED_A,
                                SSL3_ST_SR_FINISHED_B);
                        if (ret <= 0) goto end;
                        ret=ssl3_get_finished(s,SSL3_ST_SR_FINISHED_A,
                                SSL3_ST_SR_FINISHED_B);
                        if (ret <= 0) goto end;
@@ -698,14 +700,6 @@ 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,
@@ -718,6 +712,13 @@ int ssl3_check_client_hello(SSL *s)
        s->s3->tmp.reuse_message = 1;
        if (s->s3->tmp.message_type == SSL3_MT_CLIENT_HELLO)
                {
        s->s3->tmp.reuse_message = 1;
        if (s->s3->tmp.message_type == SSL3_MT_CLIENT_HELLO)
                {
+               /* 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;
+                       }
                /* Throw away what we have done so far in the current handshake,
                 * which will now be aborted. (A full SSL_clear would be too much.) */
 #ifndef OPENSSL_NO_DH
                /* Throw away what we have done so far in the current handshake,
                 * which will now be aborted. (A full SSL_clear would be too much.) */
 #ifndef OPENSSL_NO_DH
@@ -1006,7 +1007,7 @@ int ssl3_get_client_hello(SSL *s)
                        goto f_err;
                        }
                }
                        goto f_err;
                        }
                }
-               if (ssl_check_clienthello_tlsext(s) <= 0) {
+               if (ssl_check_clienthello_tlsext_early(s) <= 0) {
                        SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT);
                        goto err;
                }
                        SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT);
                        goto err;
                }
@@ -1132,6 +1133,18 @@ int ssl3_get_client_hello(SSL *s)
         * s->tmp.new_cipher    - the new cipher to use.
         */
 
         * s->tmp.new_cipher    - the new cipher to use.
         */
 
+#ifndef OPENSSL_NO_TLSEXT
+       /* Handles TLS extensions that we couldn't check earlier */
+       if (s->version >= SSL3_VERSION)
+               {
+               if (ssl_check_clienthello_tlsext_late(s) <= 0)
+                       {
+                       SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT);
+                       goto err;
+                       }
+               }
+#endif
+
        if (ret < 0) ret=1;
        if (0)
                {
        if (ret < 0) ret=1;
        if (0)
                {
@@ -1751,6 +1764,11 @@ int ssl3_send_certificate_request(SSL *s)
                s->init_num=n+4;
                s->init_off=0;
 #ifdef NETSCAPE_HANG_BUG
                s->init_num=n+4;
                s->init_off=0;
 #ifdef NETSCAPE_HANG_BUG
+               if (!BUF_MEM_grow_clean(buf, s->init_num + 4))
+                       {
+                       SSLerr(SSL_F_SSL3_SEND_CERTIFICATE_REQUEST,ERR_R_BUF_LIB);
+                       goto err;
+                       }
                p=(unsigned char *)s->init_buf->data + s->init_num;
 
                /* do the header */
                p=(unsigned char *)s->init_buf->data + s->init_num;
 
                /* do the header */