summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorjsing <>2014-06-05 15:46:24 +0000
committerjsing <>2014-06-05 15:46:24 +0000
commita1aa52709d3c53d1664e282da9d9833869ffcf47 (patch)
tree645cbc9565ca3ee2061f628e95849ce560cf786f /src/lib
parentd874ba6e9641314de878a6d18eaefe826cbe532b (diff)
downloadopenbsd-a1aa52709d3c53d1664e282da9d9833869ffcf47.tar.gz
openbsd-a1aa52709d3c53d1664e282da9d9833869ffcf47.tar.bz2
openbsd-a1aa52709d3c53d1664e282da9d9833869ffcf47.zip
Be selective as to when ChangeCipherSpec messages will be accepted.
Without this an early ChangeCipherSpec message would result in session keys being generated, along with the Finished hash for the handshake, using an empty master secret. For a detailed analysis see: https://www.imperialviolet.org/2014/06/05/earlyccs.html This is a fix for CVE-2014-0224, from OpenSSL. This issue was reported to OpenSSL by KIKUCHI Masashi. Unfortunately the recent OpenSSL commit was the first we were made aware of the issue. ok deraadt@ sthen@
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/libssl/s3_clnt.c3
-rw-r--r--src/lib/libssl/s3_pkt.c8
-rw-r--r--src/lib/libssl/s3_srvr.c7
-rw-r--r--src/lib/libssl/src/ssl/s3_clnt.c3
-rw-r--r--src/lib/libssl/src/ssl/s3_pkt.c8
-rw-r--r--src/lib/libssl/src/ssl/s3_srvr.c7
-rw-r--r--src/lib/libssl/src/ssl/ssl3.h1
-rw-r--r--src/lib/libssl/ssl3.h1
8 files changed, 32 insertions, 6 deletions
diff --git a/src/lib/libssl/s3_clnt.c b/src/lib/libssl/s3_clnt.c
index 66fb26345e..60a17ce11b 100644
--- a/src/lib/libssl/s3_clnt.c
+++ b/src/lib/libssl/s3_clnt.c
@@ -556,7 +556,7 @@ ssl3_connect(SSL *s)
556 556
557 case SSL3_ST_CR_FINISHED_A: 557 case SSL3_ST_CR_FINISHED_A:
558 case SSL3_ST_CR_FINISHED_B: 558 case SSL3_ST_CR_FINISHED_B:
559 559 s->s3->flags |= SSL3_FLAGS_CCS_OK;
560 ret = ssl3_get_finished(s, SSL3_ST_CR_FINISHED_A, 560 ret = ssl3_get_finished(s, SSL3_ST_CR_FINISHED_A,
561 SSL3_ST_CR_FINISHED_B); 561 SSL3_ST_CR_FINISHED_B);
562 if (ret <= 0) 562 if (ret <= 0)
@@ -895,6 +895,7 @@ ssl3_get_server_hello(SSL *s)
895 SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT); 895 SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT);
896 goto f_err; 896 goto f_err;
897 } 897 }
898 s->s3->flags |= SSL3_FLAGS_CCS_OK;
898 s->hit = 1; 899 s->hit = 1;
899 } else { 900 } else {
900 /* a miss or crap from the other end */ 901 /* a miss or crap from the other end */
diff --git a/src/lib/libssl/s3_pkt.c b/src/lib/libssl/s3_pkt.c
index f8f31f2a4a..58d8221fe4 100644
--- a/src/lib/libssl/s3_pkt.c
+++ b/src/lib/libssl/s3_pkt.c
@@ -1209,6 +1209,14 @@ start:
1209 goto f_err; 1209 goto f_err;
1210 } 1210 }
1211 1211
1212 /* Check that we should be receiving a Change Cipher Spec. */
1213 if (!(s->s3->flags & SSL3_FLAGS_CCS_OK)) {
1214 al = SSL_AD_UNEXPECTED_MESSAGE;
1215 SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_CCS_RECEIVED_EARLY);
1216 goto f_err;
1217 }
1218 s->s3->flags &= ~SSL3_FLAGS_CCS_OK;
1219
1212 rr->length = 0; 1220 rr->length = 0;
1213 1221
1214 if (s->msg_callback) { 1222 if (s->msg_callback) {
diff --git a/src/lib/libssl/s3_srvr.c b/src/lib/libssl/s3_srvr.c
index 948569a156..552f8290b5 100644
--- a/src/lib/libssl/s3_srvr.c
+++ b/src/lib/libssl/s3_srvr.c
@@ -635,6 +635,7 @@ ssl3_accept(SSL *s)
635 635
636 case SSL3_ST_SR_CERT_VRFY_A: 636 case SSL3_ST_SR_CERT_VRFY_A:
637 case SSL3_ST_SR_CERT_VRFY_B: 637 case SSL3_ST_SR_CERT_VRFY_B:
638 s->s3->flags |= SSL3_FLAGS_CCS_OK;
638 639
639 /* we should decide if we expected this one */ 640 /* we should decide if we expected this one */
640 ret = ssl3_get_cert_verify(s); 641 ret = ssl3_get_cert_verify(s);
@@ -665,6 +666,7 @@ ssl3_accept(SSL *s)
665 666
666 case SSL3_ST_SR_FINISHED_A: 667 case SSL3_ST_SR_FINISHED_A:
667 case SSL3_ST_SR_FINISHED_B: 668 case SSL3_ST_SR_FINISHED_B:
669 s->s3->flags |= SSL3_FLAGS_CCS_OK;
668 ret = ssl3_get_finished(s, SSL3_ST_SR_FINISHED_A, 670 ret = ssl3_get_finished(s, SSL3_ST_SR_FINISHED_A,
669 SSL3_ST_SR_FINISHED_B); 671 SSL3_ST_SR_FINISHED_B);
670 if (ret <= 0) 672 if (ret <= 0)
@@ -735,10 +737,11 @@ ssl3_accept(SSL *s)
735#ifdef OPENSSL_NO_NEXTPROTONEG 737#ifdef OPENSSL_NO_NEXTPROTONEG
736 s->s3->tmp.next_state = SSL3_ST_SR_FINISHED_A; 738 s->s3->tmp.next_state = SSL3_ST_SR_FINISHED_A;
737#else 739#else
738 if (s->s3->next_proto_neg_seen) 740 if (s->s3->next_proto_neg_seen) {
741 s->s3->flags |= SSL3_FLAGS_CCS_OK;
739 s->s3->tmp.next_state = 742 s->s3->tmp.next_state =
740 SSL3_ST_SR_NEXT_PROTO_A; 743 SSL3_ST_SR_NEXT_PROTO_A;
741 else 744 } else
742 s->s3->tmp.next_state = 745 s->s3->tmp.next_state =
743 SSL3_ST_SR_FINISHED_A; 746 SSL3_ST_SR_FINISHED_A;
744#endif 747#endif
diff --git a/src/lib/libssl/src/ssl/s3_clnt.c b/src/lib/libssl/src/ssl/s3_clnt.c
index 66fb26345e..60a17ce11b 100644
--- a/src/lib/libssl/src/ssl/s3_clnt.c
+++ b/src/lib/libssl/src/ssl/s3_clnt.c
@@ -556,7 +556,7 @@ ssl3_connect(SSL *s)
556 556
557 case SSL3_ST_CR_FINISHED_A: 557 case SSL3_ST_CR_FINISHED_A:
558 case SSL3_ST_CR_FINISHED_B: 558 case SSL3_ST_CR_FINISHED_B:
559 559 s->s3->flags |= SSL3_FLAGS_CCS_OK;
560 ret = ssl3_get_finished(s, SSL3_ST_CR_FINISHED_A, 560 ret = ssl3_get_finished(s, SSL3_ST_CR_FINISHED_A,
561 SSL3_ST_CR_FINISHED_B); 561 SSL3_ST_CR_FINISHED_B);
562 if (ret <= 0) 562 if (ret <= 0)
@@ -895,6 +895,7 @@ ssl3_get_server_hello(SSL *s)
895 SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT); 895 SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT);
896 goto f_err; 896 goto f_err;
897 } 897 }
898 s->s3->flags |= SSL3_FLAGS_CCS_OK;
898 s->hit = 1; 899 s->hit = 1;
899 } else { 900 } else {
900 /* a miss or crap from the other end */ 901 /* a miss or crap from the other end */
diff --git a/src/lib/libssl/src/ssl/s3_pkt.c b/src/lib/libssl/src/ssl/s3_pkt.c
index f8f31f2a4a..58d8221fe4 100644
--- a/src/lib/libssl/src/ssl/s3_pkt.c
+++ b/src/lib/libssl/src/ssl/s3_pkt.c
@@ -1209,6 +1209,14 @@ start:
1209 goto f_err; 1209 goto f_err;
1210 } 1210 }
1211 1211
1212 /* Check that we should be receiving a Change Cipher Spec. */
1213 if (!(s->s3->flags & SSL3_FLAGS_CCS_OK)) {
1214 al = SSL_AD_UNEXPECTED_MESSAGE;
1215 SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_CCS_RECEIVED_EARLY);
1216 goto f_err;
1217 }
1218 s->s3->flags &= ~SSL3_FLAGS_CCS_OK;
1219
1212 rr->length = 0; 1220 rr->length = 0;
1213 1221
1214 if (s->msg_callback) { 1222 if (s->msg_callback) {
diff --git a/src/lib/libssl/src/ssl/s3_srvr.c b/src/lib/libssl/src/ssl/s3_srvr.c
index 948569a156..552f8290b5 100644
--- a/src/lib/libssl/src/ssl/s3_srvr.c
+++ b/src/lib/libssl/src/ssl/s3_srvr.c
@@ -635,6 +635,7 @@ ssl3_accept(SSL *s)
635 635
636 case SSL3_ST_SR_CERT_VRFY_A: 636 case SSL3_ST_SR_CERT_VRFY_A:
637 case SSL3_ST_SR_CERT_VRFY_B: 637 case SSL3_ST_SR_CERT_VRFY_B:
638 s->s3->flags |= SSL3_FLAGS_CCS_OK;
638 639
639 /* we should decide if we expected this one */ 640 /* we should decide if we expected this one */
640 ret = ssl3_get_cert_verify(s); 641 ret = ssl3_get_cert_verify(s);
@@ -665,6 +666,7 @@ ssl3_accept(SSL *s)
665 666
666 case SSL3_ST_SR_FINISHED_A: 667 case SSL3_ST_SR_FINISHED_A:
667 case SSL3_ST_SR_FINISHED_B: 668 case SSL3_ST_SR_FINISHED_B:
669 s->s3->flags |= SSL3_FLAGS_CCS_OK;
668 ret = ssl3_get_finished(s, SSL3_ST_SR_FINISHED_A, 670 ret = ssl3_get_finished(s, SSL3_ST_SR_FINISHED_A,
669 SSL3_ST_SR_FINISHED_B); 671 SSL3_ST_SR_FINISHED_B);
670 if (ret <= 0) 672 if (ret <= 0)
@@ -735,10 +737,11 @@ ssl3_accept(SSL *s)
735#ifdef OPENSSL_NO_NEXTPROTONEG 737#ifdef OPENSSL_NO_NEXTPROTONEG
736 s->s3->tmp.next_state = SSL3_ST_SR_FINISHED_A; 738 s->s3->tmp.next_state = SSL3_ST_SR_FINISHED_A;
737#else 739#else
738 if (s->s3->next_proto_neg_seen) 740 if (s->s3->next_proto_neg_seen) {
741 s->s3->flags |= SSL3_FLAGS_CCS_OK;
739 s->s3->tmp.next_state = 742 s->s3->tmp.next_state =
740 SSL3_ST_SR_NEXT_PROTO_A; 743 SSL3_ST_SR_NEXT_PROTO_A;
741 else 744 } else
742 s->s3->tmp.next_state = 745 s->s3->tmp.next_state =
743 SSL3_ST_SR_FINISHED_A; 746 SSL3_ST_SR_FINISHED_A;
744#endif 747#endif
diff --git a/src/lib/libssl/src/ssl/ssl3.h b/src/lib/libssl/src/ssl/ssl3.h
index 1d2bc2f5c0..8444ccb57d 100644
--- a/src/lib/libssl/src/ssl/ssl3.h
+++ b/src/lib/libssl/src/ssl/ssl3.h
@@ -370,6 +370,7 @@ typedef struct ssl3_buffer_st {
370#define TLS1_FLAGS_TLS_PADDING_BUG 0x0008 370#define TLS1_FLAGS_TLS_PADDING_BUG 0x0008
371#define TLS1_FLAGS_SKIP_CERT_VERIFY 0x0010 371#define TLS1_FLAGS_SKIP_CERT_VERIFY 0x0010
372#define TLS1_FLAGS_KEEP_HANDSHAKE 0x0020 372#define TLS1_FLAGS_KEEP_HANDSHAKE 0x0020
373#define SSL3_FLAGS_CCS_OK 0x0080
373 374
374/* SSL3_FLAGS_SGC_RESTART_DONE is set when we 375/* SSL3_FLAGS_SGC_RESTART_DONE is set when we
375 * restart a handshake because of MS SGC and so prevents us 376 * restart a handshake because of MS SGC and so prevents us
diff --git a/src/lib/libssl/ssl3.h b/src/lib/libssl/ssl3.h
index 1d2bc2f5c0..8444ccb57d 100644
--- a/src/lib/libssl/ssl3.h
+++ b/src/lib/libssl/ssl3.h
@@ -370,6 +370,7 @@ typedef struct ssl3_buffer_st {
370#define TLS1_FLAGS_TLS_PADDING_BUG 0x0008 370#define TLS1_FLAGS_TLS_PADDING_BUG 0x0008
371#define TLS1_FLAGS_SKIP_CERT_VERIFY 0x0010 371#define TLS1_FLAGS_SKIP_CERT_VERIFY 0x0010
372#define TLS1_FLAGS_KEEP_HANDSHAKE 0x0020 372#define TLS1_FLAGS_KEEP_HANDSHAKE 0x0020
373#define SSL3_FLAGS_CCS_OK 0x0080
373 374
374/* SSL3_FLAGS_SGC_RESTART_DONE is set when we 375/* SSL3_FLAGS_SGC_RESTART_DONE is set when we
375 * restart a handshake because of MS SGC and so prevents us 376 * restart a handshake because of MS SGC and so prevents us