diff options
author | jsing <> | 2014-06-05 15:46:24 +0000 |
---|---|---|
committer | jsing <> | 2014-06-05 15:46:24 +0000 |
commit | a1aa52709d3c53d1664e282da9d9833869ffcf47 (patch) | |
tree | 645cbc9565ca3ee2061f628e95849ce560cf786f /src/lib | |
parent | d874ba6e9641314de878a6d18eaefe826cbe532b (diff) | |
download | openbsd-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.c | 3 | ||||
-rw-r--r-- | src/lib/libssl/s3_pkt.c | 8 | ||||
-rw-r--r-- | src/lib/libssl/s3_srvr.c | 7 | ||||
-rw-r--r-- | src/lib/libssl/src/ssl/s3_clnt.c | 3 | ||||
-rw-r--r-- | src/lib/libssl/src/ssl/s3_pkt.c | 8 | ||||
-rw-r--r-- | src/lib/libssl/src/ssl/s3_srvr.c | 7 | ||||
-rw-r--r-- | src/lib/libssl/src/ssl/ssl3.h | 1 | ||||
-rw-r--r-- | src/lib/libssl/ssl3.h | 1 |
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 |