diff options
author | jca <> | 2014-02-27 21:04:57 +0000 |
---|---|---|
committer | jca <> | 2014-02-27 21:04:57 +0000 |
commit | 3b6d92e82b1421b811bcdec7f7fdfb31eeef18de (patch) | |
tree | 40e788c732b30794928787a09a2b41e34c4772bb /src | |
parent | 76214748f84ef8bbc3833462e40ef29a1e84a02c (diff) | |
download | openbsd-3b6d92e82b1421b811bcdec7f7fdfb31eeef18de.tar.gz openbsd-3b6d92e82b1421b811bcdec7f7fdfb31eeef18de.tar.bz2 openbsd-3b6d92e82b1421b811bcdec7f7fdfb31eeef18de.zip |
SECURITY fixes backported from openssl-1.0.1f. ok mikeb@
CVE-2013-4353 NULL pointer dereference with crafted Next Protocol
Negotiation record in TLS handshake.
Upstream: 197e0ea
CVE-2013-6449 Fix crash with crafted traffic from a TLS 1.2 client.
Upstream: ca98926, 0294b2b
CVE-2013-6450 Fix DTLS retransmission from previous session.
Upstream: 3462896
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/libssl/d1_both.c | 7 | ||||
-rw-r--r-- | src/lib/libssl/s3_both.c | 7 | ||||
-rw-r--r-- | src/lib/libssl/s3_lib.c | 2 | ||||
-rw-r--r-- | src/lib/libssl/s3_pkt.c | 8 | ||||
-rw-r--r-- | src/lib/libssl/src/ssl/d1_both.c | 7 | ||||
-rw-r--r-- | src/lib/libssl/src/ssl/s3_both.c | 7 | ||||
-rw-r--r-- | src/lib/libssl/src/ssl/s3_lib.c | 2 | ||||
-rw-r--r-- | src/lib/libssl/src/ssl/s3_pkt.c | 8 | ||||
-rw-r--r-- | src/lib/libssl/src/ssl/ssl_locl.h | 2 | ||||
-rw-r--r-- | src/lib/libssl/src/ssl/t1_enc.c | 28 | ||||
-rw-r--r-- | src/lib/libssl/ssl_locl.h | 2 | ||||
-rw-r--r-- | src/lib/libssl/t1_enc.c | 28 |
12 files changed, 82 insertions, 26 deletions
diff --git a/src/lib/libssl/d1_both.c b/src/lib/libssl/d1_both.c index de8bab873f..72b3b20ae4 100644 --- a/src/lib/libssl/d1_both.c +++ b/src/lib/libssl/d1_both.c | |||
@@ -214,6 +214,13 @@ dtls1_hm_fragment_new(unsigned long frag_len, int reassembly) | |||
214 | static void | 214 | static void |
215 | dtls1_hm_fragment_free(hm_fragment *frag) | 215 | dtls1_hm_fragment_free(hm_fragment *frag) |
216 | { | 216 | { |
217 | |||
218 | if (frag->msg_header.is_ccs) | ||
219 | { | ||
220 | EVP_CIPHER_CTX_free(frag->msg_header.saved_retransmit_state.enc_write_ctx); | ||
221 | EVP_MD_CTX_destroy(frag->msg_header.saved_retransmit_state.write_hash); | ||
222 | } | ||
223 | |||
217 | if (frag->fragment) OPENSSL_free(frag->fragment); | 224 | if (frag->fragment) OPENSSL_free(frag->fragment); |
218 | if (frag->reassembly) OPENSSL_free(frag->reassembly); | 225 | if (frag->reassembly) OPENSSL_free(frag->reassembly); |
219 | OPENSSL_free(frag); | 226 | OPENSSL_free(frag); |
diff --git a/src/lib/libssl/s3_both.c b/src/lib/libssl/s3_both.c index 6981852b5b..ed0fcfc532 100644 --- a/src/lib/libssl/s3_both.c +++ b/src/lib/libssl/s3_both.c | |||
@@ -161,6 +161,8 @@ int ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen) | |||
161 | 161 | ||
162 | i=s->method->ssl3_enc->final_finish_mac(s, | 162 | i=s->method->ssl3_enc->final_finish_mac(s, |
163 | sender,slen,s->s3->tmp.finish_md); | 163 | sender,slen,s->s3->tmp.finish_md); |
164 | if (i == 0) | ||
165 | return 0; | ||
164 | s->s3->tmp.finish_md_len = i; | 166 | s->s3->tmp.finish_md_len = i; |
165 | memcpy(p, s->s3->tmp.finish_md, i); | 167 | memcpy(p, s->s3->tmp.finish_md, i); |
166 | p+=i; | 168 | p+=i; |
@@ -208,6 +210,11 @@ static void ssl3_take_mac(SSL *s) { | |||
208 | const char *sender; | 210 | const char *sender; |
209 | int slen; | 211 | int slen; |
210 | 212 | ||
213 | /* If no new cipher setup return immediately: other functions will | ||
214 | * set the appropriate error. | ||
215 | */ | ||
216 | if (s->s3->tmp.new_cipher == NULL) | ||
217 | return; | ||
211 | if (s->state & SSL_ST_CONNECT) | 218 | if (s->state & SSL_ST_CONNECT) |
212 | { | 219 | { |
213 | sender=s->method->ssl3_enc->server_finished_label; | 220 | sender=s->method->ssl3_enc->server_finished_label; |
diff --git a/src/lib/libssl/s3_lib.c b/src/lib/libssl/s3_lib.c index fb60cde8ee..b73b5ac87f 100644 --- a/src/lib/libssl/s3_lib.c +++ b/src/lib/libssl/s3_lib.c | |||
@@ -4274,7 +4274,7 @@ need to go to SSL_ST_ACCEPT. | |||
4274 | long ssl_get_algorithm2(SSL *s) | 4274 | long ssl_get_algorithm2(SSL *s) |
4275 | { | 4275 | { |
4276 | long alg2 = s->s3->tmp.new_cipher->algorithm2; | 4276 | long alg2 = s->s3->tmp.new_cipher->algorithm2; |
4277 | if (TLS1_get_version(s) >= TLS1_2_VERSION && | 4277 | if (s->method->version == TLS1_2_VERSION && |
4278 | alg2 == (SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF)) | 4278 | alg2 == (SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF)) |
4279 | return SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256; | 4279 | return SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256; |
4280 | return alg2; | 4280 | return alg2; |
diff --git a/src/lib/libssl/s3_pkt.c b/src/lib/libssl/s3_pkt.c index a7d2defbea..c499c29cb5 100644 --- a/src/lib/libssl/s3_pkt.c +++ b/src/lib/libssl/s3_pkt.c | |||
@@ -1458,8 +1458,14 @@ int ssl3_do_change_cipher_spec(SSL *s) | |||
1458 | slen=s->method->ssl3_enc->client_finished_label_len; | 1458 | slen=s->method->ssl3_enc->client_finished_label_len; |
1459 | } | 1459 | } |
1460 | 1460 | ||
1461 | s->s3->tmp.peer_finish_md_len = s->method->ssl3_enc->final_finish_mac(s, | 1461 | i = s->method->ssl3_enc->final_finish_mac(s, |
1462 | sender,slen,s->s3->tmp.peer_finish_md); | 1462 | sender,slen,s->s3->tmp.peer_finish_md); |
1463 | if (i == 0) | ||
1464 | { | ||
1465 | SSLerr(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC, ERR_R_INTERNAL_ERROR); | ||
1466 | return 0; | ||
1467 | } | ||
1468 | s->s3->tmp.peer_finish_md_len = i; | ||
1463 | 1469 | ||
1464 | return(1); | 1470 | return(1); |
1465 | } | 1471 | } |
diff --git a/src/lib/libssl/src/ssl/d1_both.c b/src/lib/libssl/src/ssl/d1_both.c index de8bab873f..72b3b20ae4 100644 --- a/src/lib/libssl/src/ssl/d1_both.c +++ b/src/lib/libssl/src/ssl/d1_both.c | |||
@@ -214,6 +214,13 @@ dtls1_hm_fragment_new(unsigned long frag_len, int reassembly) | |||
214 | static void | 214 | static void |
215 | dtls1_hm_fragment_free(hm_fragment *frag) | 215 | dtls1_hm_fragment_free(hm_fragment *frag) |
216 | { | 216 | { |
217 | |||
218 | if (frag->msg_header.is_ccs) | ||
219 | { | ||
220 | EVP_CIPHER_CTX_free(frag->msg_header.saved_retransmit_state.enc_write_ctx); | ||
221 | EVP_MD_CTX_destroy(frag->msg_header.saved_retransmit_state.write_hash); | ||
222 | } | ||
223 | |||
217 | if (frag->fragment) OPENSSL_free(frag->fragment); | 224 | if (frag->fragment) OPENSSL_free(frag->fragment); |
218 | if (frag->reassembly) OPENSSL_free(frag->reassembly); | 225 | if (frag->reassembly) OPENSSL_free(frag->reassembly); |
219 | OPENSSL_free(frag); | 226 | OPENSSL_free(frag); |
diff --git a/src/lib/libssl/src/ssl/s3_both.c b/src/lib/libssl/src/ssl/s3_both.c index 6981852b5b..ed0fcfc532 100644 --- a/src/lib/libssl/src/ssl/s3_both.c +++ b/src/lib/libssl/src/ssl/s3_both.c | |||
@@ -161,6 +161,8 @@ int ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen) | |||
161 | 161 | ||
162 | i=s->method->ssl3_enc->final_finish_mac(s, | 162 | i=s->method->ssl3_enc->final_finish_mac(s, |
163 | sender,slen,s->s3->tmp.finish_md); | 163 | sender,slen,s->s3->tmp.finish_md); |
164 | if (i == 0) | ||
165 | return 0; | ||
164 | s->s3->tmp.finish_md_len = i; | 166 | s->s3->tmp.finish_md_len = i; |
165 | memcpy(p, s->s3->tmp.finish_md, i); | 167 | memcpy(p, s->s3->tmp.finish_md, i); |
166 | p+=i; | 168 | p+=i; |
@@ -208,6 +210,11 @@ static void ssl3_take_mac(SSL *s) { | |||
208 | const char *sender; | 210 | const char *sender; |
209 | int slen; | 211 | int slen; |
210 | 212 | ||
213 | /* If no new cipher setup return immediately: other functions will | ||
214 | * set the appropriate error. | ||
215 | */ | ||
216 | if (s->s3->tmp.new_cipher == NULL) | ||
217 | return; | ||
211 | if (s->state & SSL_ST_CONNECT) | 218 | if (s->state & SSL_ST_CONNECT) |
212 | { | 219 | { |
213 | sender=s->method->ssl3_enc->server_finished_label; | 220 | sender=s->method->ssl3_enc->server_finished_label; |
diff --git a/src/lib/libssl/src/ssl/s3_lib.c b/src/lib/libssl/src/ssl/s3_lib.c index fb60cde8ee..b73b5ac87f 100644 --- a/src/lib/libssl/src/ssl/s3_lib.c +++ b/src/lib/libssl/src/ssl/s3_lib.c | |||
@@ -4274,7 +4274,7 @@ need to go to SSL_ST_ACCEPT. | |||
4274 | long ssl_get_algorithm2(SSL *s) | 4274 | long ssl_get_algorithm2(SSL *s) |
4275 | { | 4275 | { |
4276 | long alg2 = s->s3->tmp.new_cipher->algorithm2; | 4276 | long alg2 = s->s3->tmp.new_cipher->algorithm2; |
4277 | if (TLS1_get_version(s) >= TLS1_2_VERSION && | 4277 | if (s->method->version == TLS1_2_VERSION && |
4278 | alg2 == (SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF)) | 4278 | alg2 == (SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF)) |
4279 | return SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256; | 4279 | return SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256; |
4280 | return alg2; | 4280 | return alg2; |
diff --git a/src/lib/libssl/src/ssl/s3_pkt.c b/src/lib/libssl/src/ssl/s3_pkt.c index a7d2defbea..c499c29cb5 100644 --- a/src/lib/libssl/src/ssl/s3_pkt.c +++ b/src/lib/libssl/src/ssl/s3_pkt.c | |||
@@ -1458,8 +1458,14 @@ int ssl3_do_change_cipher_spec(SSL *s) | |||
1458 | slen=s->method->ssl3_enc->client_finished_label_len; | 1458 | slen=s->method->ssl3_enc->client_finished_label_len; |
1459 | } | 1459 | } |
1460 | 1460 | ||
1461 | s->s3->tmp.peer_finish_md_len = s->method->ssl3_enc->final_finish_mac(s, | 1461 | i = s->method->ssl3_enc->final_finish_mac(s, |
1462 | sender,slen,s->s3->tmp.peer_finish_md); | 1462 | sender,slen,s->s3->tmp.peer_finish_md); |
1463 | if (i == 0) | ||
1464 | { | ||
1465 | SSLerr(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC, ERR_R_INTERNAL_ERROR); | ||
1466 | return 0; | ||
1467 | } | ||
1468 | s->s3->tmp.peer_finish_md_len = i; | ||
1463 | 1469 | ||
1464 | return(1); | 1470 | return(1); |
1465 | } | 1471 | } |
diff --git a/src/lib/libssl/src/ssl/ssl_locl.h b/src/lib/libssl/src/ssl/ssl_locl.h index 7fc110df64..c3c4c21d38 100644 --- a/src/lib/libssl/src/ssl/ssl_locl.h +++ b/src/lib/libssl/src/ssl/ssl_locl.h | |||
@@ -621,6 +621,8 @@ extern SSL3_ENC_METHOD TLSv1_enc_data; | |||
621 | extern SSL3_ENC_METHOD SSLv3_enc_data; | 621 | extern SSL3_ENC_METHOD SSLv3_enc_data; |
622 | extern SSL3_ENC_METHOD DTLSv1_enc_data; | 622 | extern SSL3_ENC_METHOD DTLSv1_enc_data; |
623 | 623 | ||
624 | #define SSL_IS_DTLS(s) (s->method->version == DTLS1_VERSION) | ||
625 | |||
624 | #define IMPLEMENT_tls_meth_func(version, func_name, s_accept, s_connect, \ | 626 | #define IMPLEMENT_tls_meth_func(version, func_name, s_accept, s_connect, \ |
625 | s_get_meth) \ | 627 | s_get_meth) \ |
626 | const SSL_METHOD *func_name(void) \ | 628 | const SSL_METHOD *func_name(void) \ |
diff --git a/src/lib/libssl/src/ssl/t1_enc.c b/src/lib/libssl/src/ssl/t1_enc.c index 448eef274f..638405ec39 100644 --- a/src/lib/libssl/src/ssl/t1_enc.c +++ b/src/lib/libssl/src/ssl/t1_enc.c | |||
@@ -414,15 +414,20 @@ int tls1_change_cipher_state(SSL *s, int which) | |||
414 | s->mac_flags |= SSL_MAC_FLAG_WRITE_MAC_STREAM; | 414 | s->mac_flags |= SSL_MAC_FLAG_WRITE_MAC_STREAM; |
415 | else | 415 | else |
416 | s->mac_flags &= ~SSL_MAC_FLAG_WRITE_MAC_STREAM; | 416 | s->mac_flags &= ~SSL_MAC_FLAG_WRITE_MAC_STREAM; |
417 | if (s->enc_write_ctx != NULL) | 417 | if (s->enc_write_ctx != NULL && !SSL_IS_DTLS(s)) |
418 | reuse_dd = 1; | 418 | reuse_dd = 1; |
419 | else if ((s->enc_write_ctx=OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL) | 419 | else if ((s->enc_write_ctx=EVP_CIPHER_CTX_new()) == NULL) |
420 | goto err; | 420 | goto err; |
421 | else | ||
422 | /* make sure it's intialized in case we exit later with an error */ | ||
423 | EVP_CIPHER_CTX_init(s->enc_write_ctx); | ||
424 | dd= s->enc_write_ctx; | 421 | dd= s->enc_write_ctx; |
425 | mac_ctx = ssl_replace_hash(&s->write_hash,NULL); | 422 | if (SSL_IS_DTLS(s)) |
423 | { | ||
424 | mac_ctx = EVP_MD_CTX_create(); | ||
425 | if (!mac_ctx) | ||
426 | goto err; | ||
427 | s->write_hash = mac_ctx; | ||
428 | } | ||
429 | else | ||
430 | mac_ctx = ssl_replace_hash(&s->write_hash,NULL); | ||
426 | #ifndef OPENSSL_NO_COMP | 431 | #ifndef OPENSSL_NO_COMP |
427 | if (s->compress != NULL) | 432 | if (s->compress != NULL) |
428 | { | 433 | { |
@@ -915,18 +920,19 @@ int tls1_final_finish_mac(SSL *s, | |||
915 | if (mask & ssl_get_algorithm2(s)) | 920 | if (mask & ssl_get_algorithm2(s)) |
916 | { | 921 | { |
917 | int hashsize = EVP_MD_size(md); | 922 | int hashsize = EVP_MD_size(md); |
918 | if (hashsize < 0 || hashsize > (int)(sizeof buf - (size_t)(q-buf))) | 923 | EVP_MD_CTX *hdgst = s->s3->handshake_dgst[idx]; |
924 | if (!hdgst || hashsize < 0 || hashsize > (int)(sizeof buf - (size_t)(q-buf))) | ||
919 | { | 925 | { |
920 | /* internal error: 'buf' is too small for this cipersuite! */ | 926 | /* internal error: 'buf' is too small for this cipersuite! */ |
921 | err = 1; | 927 | err = 1; |
922 | } | 928 | } |
923 | else | 929 | else |
924 | { | 930 | { |
925 | EVP_MD_CTX_copy_ex(&ctx,s->s3->handshake_dgst[idx]); | 931 | if (!EVP_MD_CTX_copy_ex(&ctx, hdgst) || |
926 | EVP_DigestFinal_ex(&ctx,q,&i); | 932 | !EVP_DigestFinal_ex(&ctx,q,&i) || |
927 | if (i != (unsigned int)hashsize) /* can't really happen */ | 933 | (i != (unsigned int)hashsize)) |
928 | err = 1; | 934 | err = 1; |
929 | q+=i; | 935 | q+=hashsize; |
930 | } | 936 | } |
931 | } | 937 | } |
932 | } | 938 | } |
diff --git a/src/lib/libssl/ssl_locl.h b/src/lib/libssl/ssl_locl.h index 7fc110df64..c3c4c21d38 100644 --- a/src/lib/libssl/ssl_locl.h +++ b/src/lib/libssl/ssl_locl.h | |||
@@ -621,6 +621,8 @@ extern SSL3_ENC_METHOD TLSv1_enc_data; | |||
621 | extern SSL3_ENC_METHOD SSLv3_enc_data; | 621 | extern SSL3_ENC_METHOD SSLv3_enc_data; |
622 | extern SSL3_ENC_METHOD DTLSv1_enc_data; | 622 | extern SSL3_ENC_METHOD DTLSv1_enc_data; |
623 | 623 | ||
624 | #define SSL_IS_DTLS(s) (s->method->version == DTLS1_VERSION) | ||
625 | |||
624 | #define IMPLEMENT_tls_meth_func(version, func_name, s_accept, s_connect, \ | 626 | #define IMPLEMENT_tls_meth_func(version, func_name, s_accept, s_connect, \ |
625 | s_get_meth) \ | 627 | s_get_meth) \ |
626 | const SSL_METHOD *func_name(void) \ | 628 | const SSL_METHOD *func_name(void) \ |
diff --git a/src/lib/libssl/t1_enc.c b/src/lib/libssl/t1_enc.c index 448eef274f..638405ec39 100644 --- a/src/lib/libssl/t1_enc.c +++ b/src/lib/libssl/t1_enc.c | |||
@@ -414,15 +414,20 @@ int tls1_change_cipher_state(SSL *s, int which) | |||
414 | s->mac_flags |= SSL_MAC_FLAG_WRITE_MAC_STREAM; | 414 | s->mac_flags |= SSL_MAC_FLAG_WRITE_MAC_STREAM; |
415 | else | 415 | else |
416 | s->mac_flags &= ~SSL_MAC_FLAG_WRITE_MAC_STREAM; | 416 | s->mac_flags &= ~SSL_MAC_FLAG_WRITE_MAC_STREAM; |
417 | if (s->enc_write_ctx != NULL) | 417 | if (s->enc_write_ctx != NULL && !SSL_IS_DTLS(s)) |
418 | reuse_dd = 1; | 418 | reuse_dd = 1; |
419 | else if ((s->enc_write_ctx=OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL) | 419 | else if ((s->enc_write_ctx=EVP_CIPHER_CTX_new()) == NULL) |
420 | goto err; | 420 | goto err; |
421 | else | ||
422 | /* make sure it's intialized in case we exit later with an error */ | ||
423 | EVP_CIPHER_CTX_init(s->enc_write_ctx); | ||
424 | dd= s->enc_write_ctx; | 421 | dd= s->enc_write_ctx; |
425 | mac_ctx = ssl_replace_hash(&s->write_hash,NULL); | 422 | if (SSL_IS_DTLS(s)) |
423 | { | ||
424 | mac_ctx = EVP_MD_CTX_create(); | ||
425 | if (!mac_ctx) | ||
426 | goto err; | ||
427 | s->write_hash = mac_ctx; | ||
428 | } | ||
429 | else | ||
430 | mac_ctx = ssl_replace_hash(&s->write_hash,NULL); | ||
426 | #ifndef OPENSSL_NO_COMP | 431 | #ifndef OPENSSL_NO_COMP |
427 | if (s->compress != NULL) | 432 | if (s->compress != NULL) |
428 | { | 433 | { |
@@ -915,18 +920,19 @@ int tls1_final_finish_mac(SSL *s, | |||
915 | if (mask & ssl_get_algorithm2(s)) | 920 | if (mask & ssl_get_algorithm2(s)) |
916 | { | 921 | { |
917 | int hashsize = EVP_MD_size(md); | 922 | int hashsize = EVP_MD_size(md); |
918 | if (hashsize < 0 || hashsize > (int)(sizeof buf - (size_t)(q-buf))) | 923 | EVP_MD_CTX *hdgst = s->s3->handshake_dgst[idx]; |
924 | if (!hdgst || hashsize < 0 || hashsize > (int)(sizeof buf - (size_t)(q-buf))) | ||
919 | { | 925 | { |
920 | /* internal error: 'buf' is too small for this cipersuite! */ | 926 | /* internal error: 'buf' is too small for this cipersuite! */ |
921 | err = 1; | 927 | err = 1; |
922 | } | 928 | } |
923 | else | 929 | else |
924 | { | 930 | { |
925 | EVP_MD_CTX_copy_ex(&ctx,s->s3->handshake_dgst[idx]); | 931 | if (!EVP_MD_CTX_copy_ex(&ctx, hdgst) || |
926 | EVP_DigestFinal_ex(&ctx,q,&i); | 932 | !EVP_DigestFinal_ex(&ctx,q,&i) || |
927 | if (i != (unsigned int)hashsize) /* can't really happen */ | 933 | (i != (unsigned int)hashsize)) |
928 | err = 1; | 934 | err = 1; |
929 | q+=i; | 935 | q+=hashsize; |
930 | } | 936 | } |
931 | } | 937 | } |
932 | } | 938 | } |