File Fix-stateless-session-resumption-so-it-can-coexist-with-SNI.patch of Package compat-openssl098.29129
From 2a8834cf898e991be09923577740e78e73ddcbe5 Mon Sep 17 00:00:00 2001
From: "Dr. Stephen Henson" <steve@openssl.org>
Date: Fri, 30 Oct 2009 13:28:07 +0000
Subject: [PATCH] Fix stateless session resumption so it can coexist with SNI
Signed-off-by: Petr Uzel <petr.uzel@suse.cz>
---
CHANGES | 8 ++++++++
ssl/s3_srvr.c | 11 ++++++-----
ssl/ssl_asn1.c | 19 +++++++++++++------
ssl/t1_lib.c | 11 ++++++-----
4 files changed, 33 insertions(+), 16 deletions(-)
Index: openssl-0.9.8j/CHANGES
===================================================================
--- openssl-0.9.8j.orig/CHANGES
+++ openssl-0.9.8j/CHANGES
@@ -7025,6 +7025,14 @@ des-cbc 3624.96k 5258.21k
*) New configuration variants "bsdi-elf-gcc" (BSD/OS 4.x).
[Bodo Moeller]
+ *) Fixes to stateless session resumption handling. Use initial_ctx when
+ issuing and attempting to decrypt tickets in case it has changed during
+ servername handling. Use a non-zero length session ID when attempting
+ stateless session resumption: this makes it possible to determine if
+ a resumption has occurred immediately after receiving server hello
+ (several places in OpenSSL subtly assume this) instead of later in
+ the handshake.
+ [Steve Henson]
Changes between 0.9.3 and 0.9.3a [29 May 1999]
Index: openssl-0.9.8j/ssl/s3_srvr.c
===================================================================
--- openssl-0.9.8j.orig/ssl/s3_srvr.c
+++ openssl-0.9.8j/ssl/s3_srvr.c
@@ -2750,6 +2750,7 @@ int ssl3_send_newsession_ticket(SSL *s)
unsigned int hlen;
EVP_CIPHER_CTX ctx;
HMAC_CTX hctx;
+ SSL_CTX *tctx = s->initial_ctx;
unsigned char iv[EVP_MAX_IV_LENGTH];
unsigned char key_name[16];
@@ -2788,9 +2789,9 @@ int ssl3_send_newsession_ticket(SSL *s)
* it does all the work otherwise use generated values
* from parent ctx.
*/
- if (s->ctx->tlsext_ticket_key_cb)
+ if (tctx->tlsext_ticket_key_cb)
{
- if (s->ctx->tlsext_ticket_key_cb(s, key_name, iv, &ctx,
+ if (tctx->tlsext_ticket_key_cb(s, key_name, iv, &ctx,
&hctx, 1) < 0)
{
OPENSSL_free(senc);
@@ -2801,10 +2802,10 @@ int ssl3_send_newsession_ticket(SSL *s)
{
RAND_pseudo_bytes(iv, 16);
EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL,
- s->ctx->tlsext_tick_aes_key, iv);
- HMAC_Init_ex(&hctx, s->ctx->tlsext_tick_hmac_key, 16,
+ tctx->tlsext_tick_aes_key, iv);
+ HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16,
tlsext_tick_md(), NULL);
- memcpy(key_name, s->ctx->tlsext_tick_key_name, 16);
+ memcpy(key_name, tctx->tlsext_tick_key_name, 16);
}
l2n(s->session->tlsext_tick_lifetime_hint, p);
/* Skip ticket length for now */
Index: openssl-0.9.8j/ssl/ssl_asn1.c
===================================================================
--- openssl-0.9.8j.orig/ssl/ssl_asn1.c
+++ openssl-0.9.8j/ssl/ssl_asn1.c
@@ -478,19 +478,26 @@ SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION
ret->tlsext_ticklen = os.length;
os.data = NULL;
os.length = 0;
-#if 0
/* There are two ways to detect a resumed ticket sesion.
* One is to set a random session ID and then the server
* must return a match in ServerHello. This allows the normal
- * client session ID matching to work.
+ * client session ID matching to work and we know much
+ * earlier that the ticket has been accepted.
+ *
+ * The other way is to set zero length session ID when the
+ * ticket is presented and rely on the handshake to determine
+ * session resumption.
*/
if (ret->session_id_length == 0)
{
- ret->session_id_length=SSL3_MAX_SSL_SESSION_ID_LENGTH;
- RAND_pseudo_bytes(ret->session_id,
- ret->session_id_length);
- }
+ EVP_Digest(ret->tlsext_tick, ret->tlsext_ticklen,
+ ret->session_id, &ret->session_id_length,
+#ifndef OPENSSL_NO_SHA256
+ EVP_sha256(), NULL);
+#else
+ EVP_sha1(), NULL);
#endif
+ }
}
else
ret->tlsext_tick=NULL;
Index: openssl-0.9.8j/ssl/t1_lib.c
===================================================================
--- openssl-0.9.8j.orig/ssl/t1_lib.c
+++ openssl-0.9.8j/ssl/t1_lib.c
@@ -919,16 +919,17 @@ static int tls_decrypt_ticket(SSL *s, co
unsigned char tick_hmac[EVP_MAX_MD_SIZE];
HMAC_CTX hctx;
EVP_CIPHER_CTX ctx;
+ SSL_CTX *tctx = s->initial_ctx;
/* Need at least keyname + iv + some encrypted data */
if (eticklen < 48)
goto tickerr;
/* Initialize session ticket encryption and HMAC contexts */
HMAC_CTX_init(&hctx);
EVP_CIPHER_CTX_init(&ctx);
- if (s->ctx->tlsext_ticket_key_cb)
+ if (tctx->tlsext_ticket_key_cb)
{
unsigned char *nctick = (unsigned char *)etick;
- int rv = s->ctx->tlsext_ticket_key_cb(s, nctick, nctick + 16,
+ int rv = tctx->tlsext_ticket_key_cb(s, nctick, nctick + 16,
&ctx, &hctx, 0);
if (rv < 0)
return -1;
@@ -940,12 +941,12 @@ static int tls_decrypt_ticket(SSL *s, co
else
{
/* Check key name matches */
- if (memcmp(etick, s->ctx->tlsext_tick_key_name, 16))
+ if (memcmp(etick, tctx->tlsext_tick_key_name, 16))
goto tickerr;
- HMAC_Init_ex(&hctx, s->ctx->tlsext_tick_hmac_key, 16,
+ HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16,
tlsext_tick_md(), NULL);
EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL,
- s->ctx->tlsext_tick_aes_key, etick + 16);
+ tctx->tlsext_tick_aes_key, etick + 16);
}
/* Attempt to process session ticket, first conduct sanity and
* integrity checks on ticket.