Fix for CVE-2014-0224
authorDr. Stephen Henson <steve@openssl.org>
Fri, 16 May 2014 11:49:48 +0000 (12:49 +0100)
committerDr. Stephen Henson <steve@openssl.org>
Tue, 3 Jun 2014 15:30:23 +0000 (16:30 +0100)
Only accept change cipher spec when it is expected instead of at any
time. This prevents premature setting of session keys before the master
secret is determined which an attacker could use as a MITM attack.

Thanks to KIKUCHI Masashi (Lepidum Co. Ltd.) for reporting this issue
and providing the initial fix this patch is based on.

ssl/s3_clnt.c
ssl/s3_pkt.c
ssl/s3_srvr.c
ssl/ssl3.h

index 7caabf38a4bea221c96a0cb94185fc3b48eb8bb7..af2960027c36d6a891bd4002dd308d110a3c5219 100644 (file)
@@ -491,6 +491,7 @@ int ssl3_connect(SSL *s)
                case SSL3_ST_CR_FINISHED_A:
                case SSL3_ST_CR_FINISHED_B:
 
+                       s->s3->flags |= SSL3_FLAGS_CCS_OK;
                        ret=ssl3_get_finished(s,SSL3_ST_CR_FINISHED_A,
                                SSL3_ST_CR_FINISHED_B);
                        if (ret <= 0) goto end;
@@ -777,6 +778,7 @@ int ssl3_get_server_hello(SSL *s)
                SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT);
                goto f_err;
                }
+           s->s3->flags |= SSL3_FLAGS_CCS_OK;
            s->hit=1;
            }
        else    /* a miss or crap from the other end */
index 169f235c61eafe68ef72d88f7989183dfb4f8800..6caa3bb522e24c00331d688eef0bffc9e4252369 100644 (file)
@@ -1166,6 +1166,15 @@ start:
                        goto f_err;
                        }
 
+               if (!(s->s3->flags & SSL3_FLAGS_CCS_OK))
+                       {
+                       al=SSL_AD_UNEXPECTED_MESSAGE;
+                       SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_CCS_RECEIVED_EARLY);
+                       goto f_err;
+                       }
+
+               s->s3->flags &= ~SSL3_FLAGS_CCS_OK;
+
                rr->length=0;
 
                if (s->msg_callback)
index 06c7b008e51cf91b4f5e637ab36f4f4f65a1ade4..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:
 
+                       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;
@@ -533,6 +534,7 @@ int ssl3_accept(SSL *s)
 
                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;
index 3aab0800c111c15875e4bd557b8c035e04035c55..de5e559a59df3204bcf0140526996a4f95aa319c 100644 (file)
@@ -333,6 +333,7 @@ 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
+#define SSL3_FLAGS_CCS_OK                      0x0080
  
 /* SSL3_FLAGS_SGC_RESTART_DONE is set when we
  * restart a handshake because of MS SGC and so prevents us