summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Sing <jsing@cvs.openbsd.org>2014-05-29 11:28:19 +0000
committerJoel Sing <jsing@cvs.openbsd.org>2014-05-29 11:28:19 +0000
commitcc11d58cfe9c2712c5abce46b8dab7224c31fccb (patch)
treec0a6cf5ac47977631d274c976b8a9556d38d51a9
parentdfacbcfdcd577e1992b00725964d56eec02af3cb (diff)
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@
-rw-r--r--lib/libssl/t1_enc.c26
1 files changed, 18 insertions, 8 deletions
diff --git a/lib/libssl/t1_enc.c b/lib/libssl/t1_enc.c
index 894b521e718..87860feda98 100644
--- a/lib/libssl/t1_enc.c
+++ b/lib/libssl/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)