summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>2014-05-16 12:49:48 +0100
committerDr. Stephen Henson <steve@openssl.org>2014-06-03 16:30:23 +0100
commit410a49a4fa1d2a1a9775ee29f9e40cbbda79c149 (patch)
tree778046d20f87601d63cd20f69e600e4a97f74a93
parent82ba68c42d6a9cf245afa489471005b2a0377c10 (diff)
Fix for CVE-2014-0224
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.
-rw-r--r--ssl/s3_clnt.c2
-rw-r--r--ssl/s3_pkt.c9
-rw-r--r--ssl/s3_srvr.c2
-rw-r--r--ssl/ssl3.h1
4 files changed, 14 insertions, 0 deletions
diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c
index 7caabf38a4..af2960027c 100644
--- a/ssl/s3_clnt.c
+++ b/ssl/s3_clnt.c
@@ -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 */
diff --git a/ssl/s3_pkt.c b/ssl/s3_pkt.c
index 169f235c61..6caa3bb522 100644
--- a/ssl/s3_pkt.c
+++ b/ssl/s3_pkt.c
@@ -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)
diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c
index 06c7b008e5..fcc97f374f 100644
--- a/ssl/s3_srvr.c
+++ b/ssl/s3_srvr.c
@@ -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;
diff --git a/ssl/ssl3.h b/ssl/ssl3.h
index 3aab0800c1..de5e559a59 100644
--- a/ssl/ssl3.h
+++ b/ssl/ssl3.h
@@ -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