diff options
author | jsing <> | 2018-09-05 16:48:11 +0000 |
---|---|---|
committer | jsing <> | 2018-09-05 16:48:11 +0000 |
commit | 3dd336e6ff4073ca34d5f248d90afd65c6e3f27f (patch) | |
tree | 7285548c994d450785c9af93c1936fef8e5ee489 /src/lib | |
parent | 500c35c4f020d87efbd1b5f638d51d78cce1b5ea (diff) | |
download | openbsd-3dd336e6ff4073ca34d5f248d90afd65c6e3f27f.tar.gz openbsd-3dd336e6ff4073ca34d5f248d90afd65c6e3f27f.tar.bz2 openbsd-3dd336e6ff4073ca34d5f248d90afd65c6e3f27f.zip |
Correctly clear the current cipher state, when changing cipher state.
When a renegotiation results in a change of cipher suite, the renegotation
would fail if it switched from AEAD to non-AEAD or vice versa. This is due
to the fact that the previous EVP_AEAD or EVP_CIPHER state remained,
resulting in incorrect logic that caused MAC failures.
Rename ssl_clear_cipher_ctx() to ssl_clear_cipher_state() and split it
into separate read/write components, then call these functions from the
appropriate places when a ChangeCipherSpec message is being processed.
Also, remove the separate ssl_clear_hash_ctx() calls and fold these into
the ssl_clear_cipher_{read,write}_state() functions.
Issue reported by Bernard Spil, who also tested this diff.
ok tb@
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/libssl/ssl_lib.c | 52 | ||||
-rw-r--r-- | src/lib/libssl/ssl_locl.h | 7 | ||||
-rw-r--r-- | src/lib/libssl/t1_enc.c | 19 |
3 files changed, 37 insertions, 41 deletions
diff --git a/src/lib/libssl/ssl_lib.c b/src/lib/libssl/ssl_lib.c index 938139e18e..44d11d4b16 100644 --- a/src/lib/libssl/ssl_lib.c +++ b/src/lib/libssl/ssl_lib.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssl_lib.c,v 1.187 2018/08/30 16:56:16 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_lib.c,v 1.188 2018/09/05 16:48:11 jsing Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -191,9 +191,7 @@ SSL_clear(SSL *s) | |||
191 | BUF_MEM_free(s->internal->init_buf); | 191 | BUF_MEM_free(s->internal->init_buf); |
192 | s->internal->init_buf = NULL; | 192 | s->internal->init_buf = NULL; |
193 | 193 | ||
194 | ssl_clear_cipher_ctx(s); | 194 | ssl_clear_cipher_state(s); |
195 | ssl_clear_hash_ctx(&s->read_hash); | ||
196 | ssl_clear_hash_ctx(&s->internal->write_hash); | ||
197 | 195 | ||
198 | s->internal->first_packet = 0; | 196 | s->internal->first_packet = 0; |
199 | 197 | ||
@@ -534,9 +532,7 @@ SSL_free(SSL *s) | |||
534 | SSL_SESSION_free(s->session); | 532 | SSL_SESSION_free(s->session); |
535 | } | 533 | } |
536 | 534 | ||
537 | ssl_clear_cipher_ctx(s); | 535 | ssl_clear_cipher_state(s); |
538 | ssl_clear_hash_ctx(&s->read_hash); | ||
539 | ssl_clear_hash_ctx(&s->internal->write_hash); | ||
540 | 536 | ||
541 | ssl_cert_free(s->cert); | 537 | ssl_cert_free(s->cert); |
542 | 538 | ||
@@ -2431,10 +2427,7 @@ SSL_set_accept_state(SSL *s) | |||
2431 | s->internal->shutdown = 0; | 2427 | s->internal->shutdown = 0; |
2432 | S3I(s)->hs.state = SSL_ST_ACCEPT|SSL_ST_BEFORE; | 2428 | S3I(s)->hs.state = SSL_ST_ACCEPT|SSL_ST_BEFORE; |
2433 | s->internal->handshake_func = s->method->internal->ssl_accept; | 2429 | s->internal->handshake_func = s->method->internal->ssl_accept; |
2434 | /* clear the current cipher */ | 2430 | ssl_clear_cipher_state(s); |
2435 | ssl_clear_cipher_ctx(s); | ||
2436 | ssl_clear_hash_ctx(&s->read_hash); | ||
2437 | ssl_clear_hash_ctx(&s->internal->write_hash); | ||
2438 | } | 2431 | } |
2439 | 2432 | ||
2440 | void | 2433 | void |
@@ -2444,10 +2437,7 @@ SSL_set_connect_state(SSL *s) | |||
2444 | s->internal->shutdown = 0; | 2437 | s->internal->shutdown = 0; |
2445 | S3I(s)->hs.state = SSL_ST_CONNECT|SSL_ST_BEFORE; | 2438 | S3I(s)->hs.state = SSL_ST_CONNECT|SSL_ST_BEFORE; |
2446 | s->internal->handshake_func = s->method->internal->ssl_connect; | 2439 | s->internal->handshake_func = s->method->internal->ssl_connect; |
2447 | /* clear the current cipher */ | 2440 | ssl_clear_cipher_state(s); |
2448 | ssl_clear_cipher_ctx(s); | ||
2449 | ssl_clear_hash_ctx(&s->read_hash); | ||
2450 | ssl_clear_hash_ctx(&s->internal->write_hash); | ||
2451 | } | 2441 | } |
2452 | 2442 | ||
2453 | int | 2443 | int |
@@ -2623,24 +2613,40 @@ SSL_dup(SSL *s) | |||
2623 | } | 2613 | } |
2624 | 2614 | ||
2625 | void | 2615 | void |
2626 | ssl_clear_cipher_ctx(SSL *s) | 2616 | ssl_clear_cipher_state(SSL *s) |
2617 | { | ||
2618 | ssl_clear_cipher_read_state(s); | ||
2619 | ssl_clear_cipher_write_state(s); | ||
2620 | } | ||
2621 | |||
2622 | void | ||
2623 | ssl_clear_cipher_read_state(SSL *s) | ||
2627 | { | 2624 | { |
2628 | EVP_CIPHER_CTX_free(s->enc_read_ctx); | 2625 | EVP_CIPHER_CTX_free(s->enc_read_ctx); |
2629 | s->enc_read_ctx = NULL; | 2626 | s->enc_read_ctx = NULL; |
2630 | EVP_CIPHER_CTX_free(s->internal->enc_write_ctx); | 2627 | EVP_MD_CTX_destroy(s->read_hash); |
2631 | s->internal->enc_write_ctx = NULL; | 2628 | s->read_hash = NULL; |
2632 | 2629 | ||
2633 | if (s->internal->aead_read_ctx != NULL) { | 2630 | if (s->internal->aead_read_ctx != NULL) { |
2634 | EVP_AEAD_CTX_cleanup(&s->internal->aead_read_ctx->ctx); | 2631 | EVP_AEAD_CTX_cleanup(&s->internal->aead_read_ctx->ctx); |
2635 | free(s->internal->aead_read_ctx); | 2632 | free(s->internal->aead_read_ctx); |
2636 | s->internal->aead_read_ctx = NULL; | 2633 | s->internal->aead_read_ctx = NULL; |
2637 | } | 2634 | } |
2635 | } | ||
2636 | |||
2637 | void | ||
2638 | ssl_clear_cipher_write_state(SSL *s) | ||
2639 | { | ||
2640 | EVP_CIPHER_CTX_free(s->internal->enc_write_ctx); | ||
2641 | s->internal->enc_write_ctx = NULL; | ||
2642 | EVP_MD_CTX_destroy(s->internal->write_hash); | ||
2643 | s->internal->write_hash = NULL; | ||
2644 | |||
2638 | if (s->internal->aead_write_ctx != NULL) { | 2645 | if (s->internal->aead_write_ctx != NULL) { |
2639 | EVP_AEAD_CTX_cleanup(&s->internal->aead_write_ctx->ctx); | 2646 | EVP_AEAD_CTX_cleanup(&s->internal->aead_write_ctx->ctx); |
2640 | free(s->internal->aead_write_ctx); | 2647 | free(s->internal->aead_write_ctx); |
2641 | s->internal->aead_write_ctx = NULL; | 2648 | s->internal->aead_write_ctx = NULL; |
2642 | } | 2649 | } |
2643 | |||
2644 | } | 2650 | } |
2645 | 2651 | ||
2646 | /* Fix this function so that it takes an optional type parameter */ | 2652 | /* Fix this function so that it takes an optional type parameter */ |
@@ -3021,14 +3027,6 @@ SSL_set_msg_callback(SSL *ssl, void (*cb)(int write_p, int version, | |||
3021 | } | 3027 | } |
3022 | 3028 | ||
3023 | void | 3029 | void |
3024 | ssl_clear_hash_ctx(EVP_MD_CTX **hash) | ||
3025 | { | ||
3026 | if (*hash) | ||
3027 | EVP_MD_CTX_destroy(*hash); | ||
3028 | *hash = NULL; | ||
3029 | } | ||
3030 | |||
3031 | void | ||
3032 | SSL_set_debug(SSL *s, int debug) | 3030 | SSL_set_debug(SSL *s, int debug) |
3033 | { | 3031 | { |
3034 | s->internal->debug = debug; | 3032 | s->internal->debug = debug; |
diff --git a/src/lib/libssl/ssl_locl.h b/src/lib/libssl/ssl_locl.h index b6d71492fd..a4e831577d 100644 --- a/src/lib/libssl/ssl_locl.h +++ b/src/lib/libssl/ssl_locl.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssl_locl.h,v 1.212 2018/08/30 16:56:16 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_locl.h,v 1.213 2018/09/05 16:48:11 jsing Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -1039,7 +1039,9 @@ extern SSL3_ENC_METHOD TLSv1_enc_data; | |||
1039 | extern SSL3_ENC_METHOD TLSv1_1_enc_data; | 1039 | extern SSL3_ENC_METHOD TLSv1_1_enc_data; |
1040 | extern SSL3_ENC_METHOD TLSv1_2_enc_data; | 1040 | extern SSL3_ENC_METHOD TLSv1_2_enc_data; |
1041 | 1041 | ||
1042 | void ssl_clear_cipher_ctx(SSL *s); | 1042 | void ssl_clear_cipher_state(SSL *s); |
1043 | void ssl_clear_cipher_read_state(SSL *s); | ||
1044 | void ssl_clear_cipher_write_state(SSL *s); | ||
1043 | int ssl_clear_bad_session(SSL *s); | 1045 | int ssl_clear_bad_session(SSL *s); |
1044 | CERT *ssl_cert_new(void); | 1046 | CERT *ssl_cert_new(void); |
1045 | CERT *ssl_cert_dup(CERT *cert); | 1047 | CERT *ssl_cert_dup(CERT *cert); |
@@ -1279,7 +1281,6 @@ int tls12_get_sigid(const EVP_PKEY *pk); | |||
1279 | int tls12_get_hashandsig(CBB *cbb, const EVP_PKEY *pk, const EVP_MD *md); | 1281 | int tls12_get_hashandsig(CBB *cbb, const EVP_PKEY *pk, const EVP_MD *md); |
1280 | const EVP_MD *tls12_get_hash(unsigned char hash_alg); | 1282 | const EVP_MD *tls12_get_hash(unsigned char hash_alg); |
1281 | 1283 | ||
1282 | void ssl_clear_hash_ctx(EVP_MD_CTX **hash); | ||
1283 | long ssl_get_algorithm2(SSL *s); | 1284 | long ssl_get_algorithm2(SSL *s); |
1284 | int tls1_process_sigalgs(SSL *s, CBS *cbs); | 1285 | int tls1_process_sigalgs(SSL *s, CBS *cbs); |
1285 | void tls12_get_req_sig_algs(SSL *s, unsigned char **sigalgs, | 1286 | void tls12_get_req_sig_algs(SSL *s, unsigned char **sigalgs, |
diff --git a/src/lib/libssl/t1_enc.c b/src/lib/libssl/t1_enc.c index 24fc8ede68..39f542215b 100644 --- a/src/lib/libssl/t1_enc.c +++ b/src/lib/libssl/t1_enc.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: t1_enc.c,v 1.110 2018/08/31 18:31:34 jsing Exp $ */ | 1 | /* $OpenBSD: t1_enc.c,v 1.111 2018/09/05 16:48:11 jsing Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -397,10 +397,13 @@ tls1_change_cipher_state_aead(SSL *s, char is_read, const unsigned char *key, | |||
397 | SSL_AEAD_CTX *aead_ctx; | 397 | SSL_AEAD_CTX *aead_ctx; |
398 | 398 | ||
399 | if (is_read) { | 399 | if (is_read) { |
400 | ssl_clear_cipher_read_state(s); | ||
400 | if (!tls1_aead_ctx_init(&s->internal->aead_read_ctx)) | 401 | if (!tls1_aead_ctx_init(&s->internal->aead_read_ctx)) |
401 | return 0; | 402 | return 0; |
402 | aead_ctx = s->internal->aead_read_ctx; | 403 | aead_ctx = s->internal->aead_read_ctx; |
403 | } else { | 404 | } else { |
405 | /* XXX - Need to correctly handle DTLS. */ | ||
406 | ssl_clear_cipher_write_state(s); | ||
404 | if (!tls1_aead_ctx_init(&s->internal->aead_write_ctx)) | 407 | if (!tls1_aead_ctx_init(&s->internal->aead_write_ctx)) |
405 | return 0; | 408 | return 0; |
406 | aead_ctx = s->internal->aead_write_ctx; | 409 | aead_ctx = s->internal->aead_write_ctx; |
@@ -468,10 +471,7 @@ tls1_change_cipher_state_cipher(SSL *s, char is_read, | |||
468 | else | 471 | else |
469 | s->internal->mac_flags &= ~SSL_MAC_FLAG_READ_MAC_STREAM; | 472 | s->internal->mac_flags &= ~SSL_MAC_FLAG_READ_MAC_STREAM; |
470 | 473 | ||
471 | EVP_CIPHER_CTX_free(s->enc_read_ctx); | 474 | ssl_clear_cipher_read_state(s); |
472 | s->enc_read_ctx = NULL; | ||
473 | EVP_MD_CTX_destroy(s->read_hash); | ||
474 | s->read_hash = NULL; | ||
475 | 475 | ||
476 | if ((cipher_ctx = EVP_CIPHER_CTX_new()) == NULL) | 476 | if ((cipher_ctx = EVP_CIPHER_CTX_new()) == NULL) |
477 | goto err; | 477 | goto err; |
@@ -492,12 +492,9 @@ tls1_change_cipher_state_cipher(SSL *s, char is_read, | |||
492 | * contexts that are used for DTLS - these are instead freed | 492 | * contexts that are used for DTLS - these are instead freed |
493 | * by DTLS when its frees a ChangeCipherSpec fragment. | 493 | * by DTLS when its frees a ChangeCipherSpec fragment. |
494 | */ | 494 | */ |
495 | if (!SSL_IS_DTLS(s)) { | 495 | if (!SSL_IS_DTLS(s)) |
496 | EVP_CIPHER_CTX_free(s->internal->enc_write_ctx); | 496 | ssl_clear_cipher_write_state(s); |
497 | s->internal->enc_write_ctx = NULL; | 497 | |
498 | EVP_MD_CTX_destroy(s->internal->write_hash); | ||
499 | s->internal->write_hash = NULL; | ||
500 | } | ||
501 | if ((cipher_ctx = EVP_CIPHER_CTX_new()) == NULL) | 498 | if ((cipher_ctx = EVP_CIPHER_CTX_new()) == NULL) |
502 | goto err; | 499 | goto err; |
503 | s->internal->enc_write_ctx = cipher_ctx; | 500 | s->internal->enc_write_ctx = cipher_ctx; |