diff options
author | sthen <> | 2014-06-05 20:37:50 +0000 |
---|---|---|
committer | sthen <> | 2014-06-05 20:37:50 +0000 |
commit | d0f81948182201e2d50b1bf34f37b39db21f3427 (patch) | |
tree | 75a4be322eca1c095fef6d94be90a5c49bca9dca | |
parent | 6b4aaa5fd8098da7212b3f78e87aa3e3ea7841ad (diff) | |
download | openbsd-d0f81948182201e2d50b1bf34f37b39db21f3427.tar.gz openbsd-d0f81948182201e2d50b1bf34f37b39db21f3427.tar.bz2 openbsd-d0f81948182201e2d50b1bf34f37b39db21f3427.zip |
MFC ChangeCipherSpec fixes (CVE-2014-0224 and additional safeguard), ok jsing@
"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." From s3_clnt.c r1.64, s3_pkt.c r1.42,
s3_srvr.c r1.59, ssl3.h r1.19 - note that the ssl3.h change has been
applied to s3_locl.h instead to simplify patching.
"Ensure that we do not process a ChangeCipherSpec with an empty master
secret. This is an additional safeguard against early ChangeCipherSpec
handling." From s3_pkt.c:1.43
-rw-r--r-- | src/lib/libssl/src/ssl/s3_clnt.c | 3 | ||||
-rw-r--r-- | src/lib/libssl/src/ssl/s3_pkt.c | 10 | ||||
-rw-r--r-- | src/lib/libssl/src/ssl/s3_srvr.c | 7 | ||||
-rw-r--r-- | src/lib/libssl/src/ssl/ssl_locl.h | 6 |
4 files changed, 22 insertions, 4 deletions
diff --git a/src/lib/libssl/src/ssl/s3_clnt.c b/src/lib/libssl/src/ssl/s3_clnt.c index b80d052e1f..397e148f11 100644 --- a/src/lib/libssl/src/ssl/s3_clnt.c +++ b/src/lib/libssl/src/ssl/s3_clnt.c | |||
@@ -559,7 +559,7 @@ int ssl3_connect(SSL *s) | |||
559 | 559 | ||
560 | case SSL3_ST_CR_FINISHED_A: | 560 | case SSL3_ST_CR_FINISHED_A: |
561 | case SSL3_ST_CR_FINISHED_B: | 561 | case SSL3_ST_CR_FINISHED_B: |
562 | 562 | s->s3->flags |= SSL3_FLAGS_CCS_OK; | |
563 | ret=ssl3_get_finished(s,SSL3_ST_CR_FINISHED_A, | 563 | ret=ssl3_get_finished(s,SSL3_ST_CR_FINISHED_A, |
564 | SSL3_ST_CR_FINISHED_B); | 564 | SSL3_ST_CR_FINISHED_B); |
565 | if (ret <= 0) goto end; | 565 | if (ret <= 0) goto end; |
@@ -917,6 +917,7 @@ int ssl3_get_server_hello(SSL *s) | |||
917 | SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT); | 917 | SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT); |
918 | goto f_err; | 918 | goto f_err; |
919 | } | 919 | } |
920 | s->s3->flags |= SSL3_FLAGS_CCS_OK; | ||
920 | s->hit=1; | 921 | s->hit=1; |
921 | } | 922 | } |
922 | else /* a miss or crap from the other end */ | 923 | else /* 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 04a47bf2cb..9da0c2ca81 100644 --- a/src/lib/libssl/src/ssl/s3_pkt.c +++ b/src/lib/libssl/src/ssl/s3_pkt.c | |||
@@ -1300,6 +1300,14 @@ start: | |||
1300 | goto f_err; | 1300 | goto f_err; |
1301 | } | 1301 | } |
1302 | 1302 | ||
1303 | /* Check that we should be receiving a Change Cipher Spec. */ | ||
1304 | if (!(s->s3->flags & SSL3_FLAGS_CCS_OK)) { | ||
1305 | al = SSL_AD_UNEXPECTED_MESSAGE; | ||
1306 | SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_CCS_RECEIVED_EARLY); | ||
1307 | goto f_err; | ||
1308 | } | ||
1309 | s->s3->flags &= ~SSL3_FLAGS_CCS_OK; | ||
1310 | |||
1303 | rr->length=0; | 1311 | rr->length=0; |
1304 | 1312 | ||
1305 | if (s->msg_callback) | 1313 | if (s->msg_callback) |
@@ -1434,7 +1442,7 @@ int ssl3_do_change_cipher_spec(SSL *s) | |||
1434 | 1442 | ||
1435 | if (s->s3->tmp.key_block == NULL) | 1443 | if (s->s3->tmp.key_block == NULL) |
1436 | { | 1444 | { |
1437 | if (s->session == NULL) | 1445 | if (s->session == NULL || s->session->master_key_length == 0) |
1438 | { | 1446 | { |
1439 | /* might happen if dtls1_read_bytes() calls this */ | 1447 | /* might happen if dtls1_read_bytes() calls this */ |
1440 | SSLerr(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC,SSL_R_CCS_RECEIVED_EARLY); | 1448 | SSLerr(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC,SSL_R_CCS_RECEIVED_EARLY); |
diff --git a/src/lib/libssl/src/ssl/s3_srvr.c b/src/lib/libssl/src/ssl/s3_srvr.c index 118939fabb..673ced236e 100644 --- a/src/lib/libssl/src/ssl/s3_srvr.c +++ b/src/lib/libssl/src/ssl/s3_srvr.c | |||
@@ -670,6 +670,7 @@ int ssl3_accept(SSL *s) | |||
670 | 670 | ||
671 | case SSL3_ST_SR_CERT_VRFY_A: | 671 | case SSL3_ST_SR_CERT_VRFY_A: |
672 | case SSL3_ST_SR_CERT_VRFY_B: | 672 | case SSL3_ST_SR_CERT_VRFY_B: |
673 | s->s3->flags |= SSL3_FLAGS_CCS_OK; | ||
673 | 674 | ||
674 | /* we should decide if we expected this one */ | 675 | /* we should decide if we expected this one */ |
675 | ret=ssl3_get_cert_verify(s); | 676 | ret=ssl3_get_cert_verify(s); |
@@ -698,6 +699,7 @@ int ssl3_accept(SSL *s) | |||
698 | 699 | ||
699 | case SSL3_ST_SR_FINISHED_A: | 700 | case SSL3_ST_SR_FINISHED_A: |
700 | case SSL3_ST_SR_FINISHED_B: | 701 | case SSL3_ST_SR_FINISHED_B: |
702 | s->s3->flags |= SSL3_FLAGS_CCS_OK; | ||
701 | ret=ssl3_get_finished(s,SSL3_ST_SR_FINISHED_A, | 703 | ret=ssl3_get_finished(s,SSL3_ST_SR_FINISHED_A, |
702 | SSL3_ST_SR_FINISHED_B); | 704 | SSL3_ST_SR_FINISHED_B); |
703 | if (ret <= 0) goto end; | 705 | if (ret <= 0) goto end; |
@@ -767,9 +769,10 @@ int ssl3_accept(SSL *s) | |||
767 | #if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG) | 769 | #if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG) |
768 | s->s3->tmp.next_state=SSL3_ST_SR_FINISHED_A; | 770 | s->s3->tmp.next_state=SSL3_ST_SR_FINISHED_A; |
769 | #else | 771 | #else |
770 | if (s->s3->next_proto_neg_seen) | 772 | if (s->s3->next_proto_neg_seen) { |
773 | s->s3->flags |= SSL3_FLAGS_CCS_OK; | ||
771 | s->s3->tmp.next_state=SSL3_ST_SR_NEXT_PROTO_A; | 774 | s->s3->tmp.next_state=SSL3_ST_SR_NEXT_PROTO_A; |
772 | else | 775 | } else |
773 | s->s3->tmp.next_state=SSL3_ST_SR_FINISHED_A; | 776 | s->s3->tmp.next_state=SSL3_ST_SR_FINISHED_A; |
774 | #endif | 777 | #endif |
775 | } | 778 | } |
diff --git a/src/lib/libssl/src/ssl/ssl_locl.h b/src/lib/libssl/src/ssl/ssl_locl.h index 7fc110df64..33bc1d46d0 100644 --- a/src/lib/libssl/src/ssl/ssl_locl.h +++ b/src/lib/libssl/src/ssl/ssl_locl.h | |||
@@ -165,6 +165,12 @@ | |||
165 | #include <openssl/ssl.h> | 165 | #include <openssl/ssl.h> |
166 | #include <openssl/symhacks.h> | 166 | #include <openssl/symhacks.h> |
167 | 167 | ||
168 | /* | ||
169 | * Macro defined here rather than in ssl.h for -stable, avoiding | ||
170 | * the need to update installed headers before building. | ||
171 | */ | ||
172 | #define SSL3_FLAGS_CCS_OK 0x0080 | ||
173 | |||
168 | #ifdef OPENSSL_BUILD_SHLIBSSL | 174 | #ifdef OPENSSL_BUILD_SHLIBSSL |
169 | # undef OPENSSL_EXTERN | 175 | # undef OPENSSL_EXTERN |
170 | # define OPENSSL_EXTERN OPENSSL_EXPORT | 176 | # define OPENSSL_EXTERN OPENSSL_EXPORT |