summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>2014-05-16 12:49:48 +0100
committerDan Pasanen <dan.pasanen@gmail.com>2014-06-06 09:18:27 -0500
commitf672e21e2d09c00413fb76f48d4cd21170ed95ec (patch)
treeb117164eccb38305a3cf7088309309ae5276972f
parentf12d924262aa1445f0441459db92791c43f9927a (diff)
downloadreplicant_openssl-f672e21e2d09c00413fb76f48d4cd21170ed95ec.zip
replicant_openssl-f672e21e2d09c00413fb76f48d4cd21170ed95ec.tar.gz
replicant_openssl-f672e21e2d09c00413fb76f48d4cd21170ed95ec.tar.bz2
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. (cherry picked from commit bc8923b1ec9c467755cd86f7848c50ee8812e441) Conflicts: ssl/s3_srvr.c Change-Id: I259216c5859b8c3a21bf9cf345d465a7ec905ce7
-rw-r--r--include/openssl/ssl3.h1
-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
5 files changed, 15 insertions, 0 deletions
diff --git a/include/openssl/ssl3.h b/include/openssl/ssl3.h
index 4729868..d63663b 100644
--- a/include/openssl/ssl3.h
+++ b/include/openssl/ssl3.h
@@ -388,6 +388,7 @@ 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 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
diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c
index bb4805e..1c4f4db 100644
--- a/ssl/s3_clnt.c
+++ b/ssl/s3_clnt.c
@@ -607,6 +607,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;
@@ -988,6 +989,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 6bc9395..31ce0e3 100644
--- a/ssl/s3_pkt.c
+++ b/ssl/s3_pkt.c
@@ -1297,6 +1297,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 5c3343a..f76b49c 100644
--- a/ssl/s3_srvr.c
+++ b/ssl/s3_srvr.c
@@ -669,6 +669,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;
@@ -721,6 +722,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 4729868..d63663b 100644
--- a/ssl/ssl3.h
+++ b/ssl/ssl3.h
@@ -388,6 +388,7 @@ 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 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