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/libssl/t1_enc.c | |
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/libssl/t1_enc.c')
-rw-r--r-- | src/lib/libssl/t1_enc.c | 19 |
1 files changed, 8 insertions, 11 deletions
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; |