diff options
author | 2014-05-29 11:28:18 +0000 | |
---|---|---|
committer | 2014-05-29 11:28:18 +0000 | |
commit | ec0743c214270e4d430795064fc84ce06fcd32f5 (patch) | |
tree | c05764997ef868d89a03526050db1aca4e01d318 /lib/libssl/src/ssl/t1_enc.c | |
parent | no more gcc2. (diff) | |
download | wireguard-openbsd-ec0743c214270e4d430795064fc84ce06fcd32f5.tar.xz wireguard-openbsd-ec0743c214270e4d430795064fc84ce06fcd32f5.zip |
Fix another two cases where the return value of ssl_replace_hash() is
unchecked.
In the case of tls1_change_cipher_state(), it is fairly pointless to use
ssl_replace_hash(), since it does not initialise the hash and there is
special handling required in the DTLS write case. Instead, just inline
the part of ssl_replace_hash() that is needed and only
ssl_clear_hash_ctx() the write hash in the non-DTLS case.
Also add a detailed comment explaining why there needs to be specialised
handling for DTLS write context and where the contexts are actually freed.
ok miod@
Diffstat (limited to 'lib/libssl/src/ssl/t1_enc.c')
-rw-r--r-- | lib/libssl/src/ssl/t1_enc.c | 26 |
1 files changed, 18 insertions, 8 deletions
diff --git a/lib/libssl/src/ssl/t1_enc.c b/lib/libssl/src/ssl/t1_enc.c index 894b521e718..87860feda98 100644 --- a/lib/libssl/src/ssl/t1_enc.c +++ b/lib/libssl/src/ssl/t1_enc.c @@ -386,7 +386,11 @@ tls1_change_cipher_state(SSL *s, int which) EVP_CIPHER_CTX_init(s->enc_read_ctx); } dd = s->enc_read_ctx; - mac_ctx = ssl_replace_hash(&s->read_hash, NULL); + + ssl_clear_hash_ctx(&s->read_hash); + if ((mac_ctx = EVP_MD_CTX_create()) == NULL) + goto err; + s->read_hash = mac_ctx; /* this is done by dtls1_reset_seq_numbers for DTLS1_VERSION */ if (s->version != DTLS1_VERSION) @@ -403,13 +407,19 @@ tls1_change_cipher_state(SSL *s, int which) else if ((s->enc_write_ctx = EVP_CIPHER_CTX_new()) == NULL) goto err; dd = s->enc_write_ctx; - if (SSL_IS_DTLS(s)) { - mac_ctx = EVP_MD_CTX_create(); - if (!mac_ctx) - goto err; - s->write_hash = mac_ctx; - } else - mac_ctx = ssl_replace_hash(&s->write_hash, NULL); + + /* + * DTLS fragments retain a pointer to the compression, cipher + * and hash contexts, so that it can restore state in order + * to perform retransmissions. As such, we cannot free write + * contexts that are used for DTLS - these are instead freed + * by DTLS when its frees a ChangeCipherSpec fragment. + */ + if (!SSL_IS_DTLS(s)) + ssl_clear_hash_ctx(&s->write_hash); + if ((mac_ctx = EVP_MD_CTX_create()) == NULL) + goto err; + s->write_hash = mac_ctx; /* this is done by dtls1_reset_seq_numbers for DTLS1_VERSION */ if (s->version != DTLS1_VERSION) |