File Fix-stateless-session-resumption-so-it-can-coexist-with-SNI.patch of Package compat-openssl098.703

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.