Blame SOURCES/openssl-1.0.1e-cve-2015-1791.patch

5c1a6c
diff -up openssl-1.0.1e/ssl/ssl_err.c.ticket-race openssl-1.0.1e/ssl/ssl_err.c
5c1a6c
--- openssl-1.0.1e/ssl/ssl_err.c.ticket-race	2015-06-09 15:40:41.000000000 +0200
5c1a6c
+++ openssl-1.0.1e/ssl/ssl_err.c	2015-06-09 15:45:06.879198463 +0200
5c1a6c
@@ -245,6 +245,7 @@ static ERR_STRING_DATA SSL_str_functs[]=
5c1a6c
 {ERR_FUNC(SSL_F_SSL_READ),	"SSL_read"},
5c1a6c
 {ERR_FUNC(SSL_F_SSL_RSA_PRIVATE_DECRYPT),	"SSL_RSA_PRIVATE_DECRYPT"},
5c1a6c
 {ERR_FUNC(SSL_F_SSL_RSA_PUBLIC_ENCRYPT),	"SSL_RSA_PUBLIC_ENCRYPT"},
5c1a6c
+{ERR_FUNC(SSL_F_SSL_SESSION_DUP),	"ssl_session_dup"},
5c1a6c
 {ERR_FUNC(SSL_F_SSL_SESSION_NEW),	"SSL_SESSION_new"},
5c1a6c
 {ERR_FUNC(SSL_F_SSL_SESSION_PRINT_FP),	"SSL_SESSION_print_fp"},
5c1a6c
 {ERR_FUNC(SSL_F_SSL_SESSION_SET1_ID_CONTEXT),	"SSL_SESSION_set1_id_context"},
5c1a6c
diff -up openssl-1.0.1e/ssl/ssl.h.ticket-race openssl-1.0.1e/ssl/ssl.h
5c1a6c
--- openssl-1.0.1e/ssl/ssl.h.ticket-race	2015-06-09 15:40:41.000000000 +0200
5c1a6c
+++ openssl-1.0.1e/ssl/ssl.h	2015-06-09 15:44:22.696191291 +0200
5c1a6c
@@ -2176,6 +2176,7 @@ void ERR_load_SSL_strings(void);
5c1a6c
 #define SSL_F_SSL_READ					 223
5c1a6c
 #define SSL_F_SSL_RSA_PRIVATE_DECRYPT			 187
5c1a6c
 #define SSL_F_SSL_RSA_PUBLIC_ENCRYPT			 188
5c1a6c
+#define SSL_F_SSL_SESSION_DUP				 348
5c1a6c
 #define SSL_F_SSL_SESSION_NEW				 189
5c1a6c
 #define SSL_F_SSL_SESSION_PRINT_FP			 190
5c1a6c
 #define SSL_F_SSL_SESSION_SET1_ID_CONTEXT		 312
5c1a6c
diff -up openssl-1.0.1e/ssl/ssl_locl.h.ticket-race openssl-1.0.1e/ssl/ssl_locl.h
5c1a6c
--- openssl-1.0.1e/ssl/ssl_locl.h.ticket-race	2015-06-09 15:40:41.000000000 +0200
5c1a6c
+++ openssl-1.0.1e/ssl/ssl_locl.h	2015-06-09 16:02:41.105243796 +0200
5c1a6c
@@ -822,6 +822,7 @@ void ssl_sess_cert_free(SESS_CERT *sc);
5c1a6c
 int ssl_set_peer_cert_type(SESS_CERT *c, int type);
5c1a6c
 int ssl_get_new_session(SSL *s, int session);
5c1a6c
 int ssl_get_prev_session(SSL *s, unsigned char *session,int len, const unsigned char *limit);
5c1a6c
+SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket);
5c1a6c
 int ssl_cipher_id_cmp(const SSL_CIPHER *a,const SSL_CIPHER *b);
5c1a6c
 DECLARE_OBJ_BSEARCH_GLOBAL_CMP_FN(SSL_CIPHER, SSL_CIPHER,
5c1a6c
 				  ssl_cipher_id);
5c1a6c
diff -up openssl-1.0.1e/ssl/ssl_sess.c.ticket-race openssl-1.0.1e/ssl/ssl_sess.c
5c1a6c
--- openssl-1.0.1e/ssl/ssl_sess.c.ticket-race	2013-02-11 16:26:04.000000000 +0100
5c1a6c
+++ openssl-1.0.1e/ssl/ssl_sess.c	2015-06-11 13:48:26.724348868 +0200
5c1a6c
@@ -224,6 +224,146 @@ SSL_SESSION *SSL_SESSION_new(void)
5c1a6c
 	return(ss);
5c1a6c
 	}
5c1a6c
 
5c1a6c
+/*
5c1a6c
+ * Create a new SSL_SESSION and duplicate the contents of |src| into it. If
5c1a6c
+ * ticket == 0 then no ticket information is duplicated, otherwise it is.
5c1a6c
+ */
5c1a6c
+SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket)
5c1a6c
+{
5c1a6c
+	SSL_SESSION *dest;
5c1a6c
+
5c1a6c
+	dest = OPENSSL_malloc(sizeof(*src));
5c1a6c
+	if (dest == NULL)
5c1a6c
+		{
5c1a6c
+		goto err;
5c1a6c
+		}
5c1a6c
+	memcpy(dest, src, sizeof(*dest));
5c1a6c
+
5c1a6c
+	/*
5c1a6c
+	 * Set the various pointers to NULL so that we can call SSL_SESSION_free in
5c1a6c
+	 * the case of an error whilst halfway through constructing dest
5c1a6c
+	 */
5c1a6c
+#ifndef OPENSSL_NO_PSK
5c1a6c
+	dest->psk_identity_hint = NULL;
5c1a6c
+	dest->psk_identity = NULL;
5c1a6c
+#endif
5c1a6c
+	dest->ciphers = NULL;
5c1a6c
+#ifndef OPENSSL_NO_TLSEXT
5c1a6c
+	dest->tlsext_hostname = NULL;
5c1a6c
+# ifndef OPENSSL_NO_EC
5c1a6c
+	dest->tlsext_ecpointformatlist = NULL;
5c1a6c
+	dest->tlsext_ellipticcurvelist = NULL;
5c1a6c
+# endif
5c1a6c
+#endif
5c1a6c
+	dest->tlsext_tick = NULL;
5c1a6c
+#ifndef OPENSSL_NO_SRP
5c1a6c
+	dest->srp_username = NULL;
5c1a6c
+#endif
5c1a6c
+	memset(&dest->ex_data, 0, sizeof(dest->ex_data));
5c1a6c
+
5c1a6c
+	/* We deliberately don't copy the prev and next pointers */
5c1a6c
+	dest->prev = NULL;
5c1a6c
+	dest->next = NULL;
5c1a6c
+
5c1a6c
+	dest->references = 1;
5c1a6c
+
5c1a6c
+	if (src->sess_cert != NULL)
5c1a6c
+		CRYPTO_add(&src->sess_cert->references, 1, CRYPTO_LOCK_SSL_SESS_CERT);
5c1a6c
+
5c1a6c
+	if (src->peer != NULL)
5c1a6c
+		CRYPTO_add(&src->peer->references, 1, CRYPTO_LOCK_X509);
5c1a6c
+
5c1a6c
+#ifndef OPENSSL_NO_PSK
5c1a6c
+	if (src->psk_identity_hint)
5c1a6c
+		{
5c1a6c
+		dest->psk_identity_hint = BUF_strdup(src->psk_identity_hint);
5c1a6c
+		if (dest->psk_identity_hint == NULL)
5c1a6c
+			{
5c1a6c
+			goto err;
5c1a6c
+			}
5c1a6c
+		}
5c1a6c
+	if (src->psk_identity)
5c1a6c
+		{
5c1a6c
+		dest->psk_identity = BUF_strdup(src->psk_identity);
5c1a6c
+		if (dest->psk_identity == NULL)
5c1a6c
+			{
5c1a6c
+			goto err;
5c1a6c
+			}
5c1a6c
+		}
5c1a6c
+#endif
5c1a6c
+
5c1a6c
+	if(src->ciphers != NULL)
5c1a6c
+		{
5c1a6c
+		dest->ciphers = sk_SSL_CIPHER_dup(src->ciphers);
5c1a6c
+		if (dest->ciphers == NULL)
5c1a6c
+			goto err;
5c1a6c
+		}
5c1a6c
+
5c1a6c
+	if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_SSL_SESSION,
5c1a6c
+				&dest->ex_data, &src->ex_data))
5c1a6c
+		{
5c1a6c
+		goto err;
5c1a6c
+		}
5c1a6c
+
5c1a6c
+#ifndef OPENSSL_NO_TLSEXT
5c1a6c
+	if (src->tlsext_hostname)
5c1a6c
+		{
5c1a6c
+		dest->tlsext_hostname = BUF_strdup(src->tlsext_hostname);
5c1a6c
+		if (dest->tlsext_hostname == NULL)
5c1a6c
+			{
5c1a6c
+			goto err;
5c1a6c
+			}
5c1a6c
+		}
5c1a6c
+# ifndef OPENSSL_NO_EC
5c1a6c
+	if (src->tlsext_ecpointformatlist)
5c1a6c
+		{
5c1a6c
+		dest->tlsext_ecpointformatlist =
5c1a6c
+			BUF_memdup(src->tlsext_ecpointformatlist,
5c1a6c
+				src->tlsext_ecpointformatlist_length);
5c1a6c
+		if (dest->tlsext_ecpointformatlist == NULL)
5c1a6c
+			goto err;
5c1a6c
+		}
5c1a6c
+	if (src->tlsext_ellipticcurvelist)
5c1a6c
+		{
5c1a6c
+		dest->tlsext_ellipticcurvelist =
5c1a6c
+			BUF_memdup(src->tlsext_ellipticcurvelist,
5c1a6c
+				src->tlsext_ellipticcurvelist_length);
5c1a6c
+		if (dest->tlsext_ellipticcurvelist == NULL)
5c1a6c
+			goto err;
5c1a6c
+		}
5c1a6c
+# endif
5c1a6c
+#endif
5c1a6c
+
5c1a6c
+	if (ticket != 0)
5c1a6c
+		{
5c1a6c
+		dest->tlsext_tick = BUF_memdup(src->tlsext_tick, src->tlsext_ticklen);
5c1a6c
+        	if(dest->tlsext_tick == NULL)
5c1a6c
+			goto err;
5c1a6c
+		}
5c1a6c
+	else
5c1a6c
+		{
5c1a6c
+		dest->tlsext_tick_lifetime_hint = 0;
5c1a6c
+		dest->tlsext_ticklen = 0;
5c1a6c
+		}
5c1a6c
+
5c1a6c
+#ifndef OPENSSL_NO_SRP
5c1a6c
+	if (src->srp_username)
5c1a6c
+		{
5c1a6c
+		dest->srp_username = BUF_strdup(src->srp_username);
5c1a6c
+		if (dest->srp_username == NULL)
5c1a6c
+			{
5c1a6c
+			goto err;
5c1a6c
+			}
5c1a6c
+		}
5c1a6c
+#endif
5c1a6c
+
5c1a6c
+	return dest;
5c1a6c
+err:
5c1a6c
+	SSLerr(SSL_F_SSL_SESSION_DUP, ERR_R_MALLOC_FAILURE);
5c1a6c
+	SSL_SESSION_free(dest);
5c1a6c
+	return NULL;
5c1a6c
+}
5c1a6c
+
5c1a6c
 const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s, unsigned int *len)
5c1a6c
 	{
5c1a6c
 	if(len)
5c1a6c
diff -up openssl-1.0.1e/ssl/s3_clnt.c.ticket-race openssl-1.0.1e/ssl/s3_clnt.c
5c1a6c
--- openssl-1.0.1e/ssl/s3_clnt.c.ticket-race	2015-06-09 15:40:41.000000000 +0200
5c1a6c
+++ openssl-1.0.1e/ssl/s3_clnt.c	2015-06-09 15:39:56.315119013 +0200
5c1a6c
@@ -2065,24 +2065,13 @@ int ssl3_get_new_session_ticket(SSL *s)
5c1a6c
 	n=s->method->ssl_get_message(s,
5c1a6c
 		SSL3_ST_CR_SESSION_TICKET_A,
5c1a6c
 		SSL3_ST_CR_SESSION_TICKET_B,
5c1a6c
-		-1,
5c1a6c
+		SSL3_MT_NEWSESSION_TICKET,
5c1a6c
 		16384,
5c1a6c
 		&ok;;
5c1a6c
 
5c1a6c
 	if (!ok)
5c1a6c
 		return((int)n);
5c1a6c
 
5c1a6c
-	if (s->s3->tmp.message_type == SSL3_MT_FINISHED)
5c1a6c
-		{
5c1a6c
-		s->s3->tmp.reuse_message=1;
5c1a6c
-		return(1);
5c1a6c
-		}
5c1a6c
-	if (s->s3->tmp.message_type != SSL3_MT_NEWSESSION_TICKET)
5c1a6c
-		{
5c1a6c
-		al=SSL_AD_UNEXPECTED_MESSAGE;
5c1a6c
-		SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET,SSL_R_BAD_MESSAGE_TYPE);
5c1a6c
-		goto f_err;
5c1a6c
-		}
5c1a6c
 	if (n < 6)
5c1a6c
 		{
5c1a6c
 		/* need at least ticket_lifetime_hint + ticket length */
5c1a6c
@@ -2092,6 +2081,44 @@ int ssl3_get_new_session_ticket(SSL *s)
5c1a6c
 		}
5c1a6c
 
5c1a6c
 	p=d=(unsigned char *)s->init_msg;
5c1a6c
+
5c1a6c
+	if (s->session->session_id_length > 0)
5c1a6c
+		{
5c1a6c
+		int i = s->session_ctx->session_cache_mode;
5c1a6c
+		SSL_SESSION *new_sess;
5c1a6c
+		/*
5c1a6c
+		 * We reused an existing session, so we need to replace it with a new
5c1a6c
+		 * one
5c1a6c
+		 */
5c1a6c
+		if (i & SSL_SESS_CACHE_CLIENT)
5c1a6c
+			{
5c1a6c
+			/*
5c1a6c
+			 * Remove the old session from the cache
5c1a6c
+			 */
5c1a6c
+			if (i & SSL_SESS_CACHE_NO_INTERNAL_STORE)
5c1a6c
+				{
5c1a6c
+				if (s->session_ctx->remove_session_cb != NULL)
5c1a6c
+					s->session_ctx->remove_session_cb(s->session_ctx,
5c1a6c
+						s->session);
5c1a6c
+				}
5c1a6c
+			else
5c1a6c
+				{
5c1a6c
+				/* We carry on if this fails */
5c1a6c
+				SSL_CTX_remove_session(s->session_ctx, s->session);
5c1a6c
+				}
5c1a6c
+			}
5c1a6c
+
5c1a6c
+		if ((new_sess = ssl_session_dup(s->session, 0)) == 0)
5c1a6c
+			{
5c1a6c
+			al = SSL_AD_INTERNAL_ERROR;
5c1a6c
+			SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET, ERR_R_MALLOC_FAILURE);
5c1a6c
+			goto f_err;
5c1a6c
+			}
5c1a6c
+
5c1a6c
+		SSL_SESSION_free(s->session);
5c1a6c
+		s->session = new_sess;
5c1a6c
+		}
5c1a6c
+
5c1a6c
 	n2l(p, s->session->tlsext_tick_lifetime_hint);
5c1a6c
 	n2s(p, ticklen);
5c1a6c
 	/* ticket_lifetime_hint + ticket_length + ticket */