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:37 +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 f1f9c219ed295753c11f6466576b6b8cf1303800..450d5592856c089832c4676b5046f6f1520d45cd 100644 (file)
@@ -516,6 +516,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;
@@ -829,6 +830,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 988bfe57041a961b5473887f55bab4e02e216eee..8950e902a64e2b450b2b6c3443fbc4487318a4d3 100644 (file)
@@ -1258,6 +1258,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 b4ec010115f78ae87e02c219b9a211b4e3e5337f..9c29cdfe01c72896808da468e890eb6d2deaeb34 100644 (file)
@@ -578,6 +578,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;
@@ -588,6 +589,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 7686472a0fff77a1478f886ade3008d31abc18c3..9664a8b14536f9c205ef4d723f26be87fc97f283 100644 (file)
@@ -379,6 +379,7 @@ typedef struct ssl3_buffer_st
 #define SSL3_FLAGS_POP_BUFFER                  0x0004
 #define TLS1_FLAGS_TLS_PADDING_BUG             0x0008
 #define TLS1_FLAGS_SKIP_CERT_VERIFY            0x0010
+#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