diff options
author | guenther <> | 2016-09-22 06:57:40 +0000 |
---|---|---|
committer | guenther <> | 2016-09-22 06:57:40 +0000 |
commit | b8e79b960794be13c34694d468ef9fb44e70a355 (patch) | |
tree | 66163f3ec4e56ffd8d9b01ef9d200a0369282188 | |
parent | 24803e8b1a8ceacaf15f228058401a4add0be4e1 (diff) | |
download | openbsd-b8e79b960794be13c34694d468ef9fb44e70a355.tar.gz openbsd-b8e79b960794be13c34694d468ef9fb44e70a355.tar.bz2 openbsd-b8e79b960794be13c34694d468ef9fb44e70a355.zip |
Improve ticket validity checking when tlsext_ticket_key_cb() callback
chooses a different HMAC algorithm.
Avert memory leaks if the callback preps the HMAC in some way.
Based on openssl commit 1bbe48ab149893a78bf99c8eb8895c928900a16f
but retaining a pre-callback length check to guarantee the callback
is provided the buffer that the API claims.
ok bcook@ jsing@
-rw-r--r-- | src/lib/libssl/t1_lib.c | 29 |
1 files changed, 25 insertions, 4 deletions
diff --git a/src/lib/libssl/t1_lib.c b/src/lib/libssl/t1_lib.c index 3022469ea9..6853bc210e 100644 --- a/src/lib/libssl/t1_lib.c +++ b/src/lib/libssl/t1_lib.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: t1_lib.c,v 1.88 2016/08/27 15:58:06 jsing Exp $ */ | 1 | /* $OpenBSD: t1_lib.c,v 1.89 2016/09/22 06:57:40 guenther 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 | * |
@@ -2163,9 +2163,16 @@ tls_decrypt_ticket(SSL *s, const unsigned char *etick, int eticklen, | |||
2163 | HMAC_CTX hctx; | 2163 | HMAC_CTX hctx; |
2164 | EVP_CIPHER_CTX ctx; | 2164 | EVP_CIPHER_CTX ctx; |
2165 | SSL_CTX *tctx = s->initial_ctx; | 2165 | SSL_CTX *tctx = s->initial_ctx; |
2166 | /* Need at least keyname + iv + some encrypted data */ | 2166 | |
2167 | if (eticklen < 48) | 2167 | /* |
2168 | * The API guarantees EVP_MAX_IV_LENGTH bytes of space for | ||
2169 | * the iv to tlsext_ticket_key_cb(). Since the total space | ||
2170 | * required for a session cookie is never less than this, | ||
2171 | * this check isn't too strict. The exact check comes later. | ||
2172 | */ | ||
2173 | if (eticklen < 16 + EVP_MAX_IV_LENGTH) | ||
2168 | return 2; | 2174 | return 2; |
2175 | |||
2169 | /* Initialize session ticket encryption and HMAC contexts */ | 2176 | /* Initialize session ticket encryption and HMAC contexts */ |
2170 | HMAC_CTX_init(&hctx); | 2177 | HMAC_CTX_init(&hctx); |
2171 | EVP_CIPHER_CTX_init(&ctx); | 2178 | EVP_CIPHER_CTX_init(&ctx); |
@@ -2174,10 +2181,12 @@ tls_decrypt_ticket(SSL *s, const unsigned char *etick, int eticklen, | |||
2174 | int rv = tctx->tlsext_ticket_key_cb(s, nctick, nctick + 16, | 2181 | int rv = tctx->tlsext_ticket_key_cb(s, nctick, nctick + 16, |
2175 | &ctx, &hctx, 0); | 2182 | &ctx, &hctx, 0); |
2176 | if (rv < 0) { | 2183 | if (rv < 0) { |
2184 | HMAC_CTX_cleanup(&hctx); | ||
2177 | EVP_CIPHER_CTX_cleanup(&ctx); | 2185 | EVP_CIPHER_CTX_cleanup(&ctx); |
2178 | return -1; | 2186 | return -1; |
2179 | } | 2187 | } |
2180 | if (rv == 0) { | 2188 | if (rv == 0) { |
2189 | HMAC_CTX_cleanup(&hctx); | ||
2181 | EVP_CIPHER_CTX_cleanup(&ctx); | 2190 | EVP_CIPHER_CTX_cleanup(&ctx); |
2182 | return 2; | 2191 | return 2; |
2183 | } | 2192 | } |
@@ -2192,15 +2201,26 @@ tls_decrypt_ticket(SSL *s, const unsigned char *etick, int eticklen, | |||
2192 | EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, | 2201 | EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, |
2193 | tctx->tlsext_tick_aes_key, etick + 16); | 2202 | tctx->tlsext_tick_aes_key, etick + 16); |
2194 | } | 2203 | } |
2195 | /* Attempt to process session ticket, first conduct sanity and | 2204 | |
2205 | /* | ||
2206 | * Attempt to process session ticket, first conduct sanity and | ||
2196 | * integrity checks on ticket. | 2207 | * integrity checks on ticket. |
2197 | */ | 2208 | */ |
2198 | mlen = HMAC_size(&hctx); | 2209 | mlen = HMAC_size(&hctx); |
2199 | if (mlen < 0) { | 2210 | if (mlen < 0) { |
2211 | HMAC_CTX_cleanup(&hctx); | ||
2200 | EVP_CIPHER_CTX_cleanup(&ctx); | 2212 | EVP_CIPHER_CTX_cleanup(&ctx); |
2201 | return -1; | 2213 | return -1; |
2202 | } | 2214 | } |
2215 | |||
2216 | /* Sanity check ticket length: must exceed keyname + IV + HMAC */ | ||
2217 | if (eticklen < 16 + EVP_CIPHER_CTX_iv_length(&ctx) + mlen) { | ||
2218 | HMAC_CTX_cleanup(&hctx); | ||
2219 | EVP_CIPHER_CTX_cleanup(&ctx); | ||
2220 | return 2; | ||
2221 | } | ||
2203 | eticklen -= mlen; | 2222 | eticklen -= mlen; |
2223 | |||
2204 | /* Check HMAC of encrypted ticket */ | 2224 | /* Check HMAC of encrypted ticket */ |
2205 | HMAC_Update(&hctx, etick, eticklen); | 2225 | HMAC_Update(&hctx, etick, eticklen); |
2206 | HMAC_Final(&hctx, tick_hmac, NULL); | 2226 | HMAC_Final(&hctx, tick_hmac, NULL); |
@@ -2209,6 +2229,7 @@ tls_decrypt_ticket(SSL *s, const unsigned char *etick, int eticklen, | |||
2209 | EVP_CIPHER_CTX_cleanup(&ctx); | 2229 | EVP_CIPHER_CTX_cleanup(&ctx); |
2210 | return 2; | 2230 | return 2; |
2211 | } | 2231 | } |
2232 | |||
2212 | /* Attempt to decrypt session data */ | 2233 | /* Attempt to decrypt session data */ |
2213 | /* Move p after IV to start of encrypted ticket, update length */ | 2234 | /* Move p after IV to start of encrypted ticket, update length */ |
2214 | p = etick + 16 + EVP_CIPHER_CTX_iv_length(&ctx); | 2235 | p = etick + 16 + EVP_CIPHER_CTX_iv_length(&ctx); |