Patch for CVE-2010-3864

OpenSSL Security Advisory [16 November 2010]
TLS extension parsing race condition. (UPDATED)
CVE-2010-3864
http://www.openssl.org/news/secadv_20101116-2.txt

Bug: 3201137
Change-Id: Ie3e38b9e02ac35eb8c782e0bcd19ce29ac457f29
diff --git a/openssl.config b/openssl.config
index 8f56273..1eb1d40 100644
--- a/openssl.config
+++ b/openssl.config
@@ -165,6 +165,7 @@
 small_records.patch \
 handshake_cutthrough.patch \
 jsse.patch \
+secadv_20101116-2.patch \
 "
 
 OPENSSL_PATCHES_progs_SOURCES="\
@@ -209,3 +210,7 @@
 ssl/ssl_rsa.c \
 ssl/ssl_sess.c \
 "
+
+OPENSSL_PATCHES_secadv_20101116_2_SOURCES="\
+ssl/t1_lib.c \
+"
diff --git a/patches/README b/patches/README
index 4b182dd..bc98ee1 100644
--- a/patches/README
+++ b/patches/README
@@ -27,3 +27,11 @@
 Support for JSSE implementation based on OpenSSL.
 
 
+secadv_20101116-2.patch
+
+OpenSSL Security Advisory [16 November 2010]
+TLS extension parsing race condition. (UPDATED)
+CVE-2010-3864
+http://www.openssl.org/news/secadv_20101116-2.txt
+
+
diff --git a/patches/secadv_20101116-2.patch b/patches/secadv_20101116-2.patch
new file mode 100644
index 0000000..cd13136
--- /dev/null
+++ b/patches/secadv_20101116-2.patch
@@ -0,0 +1,99 @@
+--- openssl-1.0.0.orig/ssl/t1_lib.c	15 Jun 2010 17:25:15 -0000	1.64.2.14
++++ openssl-1.0.0/ssl/t1_lib.c	15 Nov 2010 15:26:19 -0000
+@@ -714,14 +714,23 @@
+ 				switch (servname_type)
+ 					{
+ 				case TLSEXT_NAMETYPE_host_name:
+-					if (s->session->tlsext_hostname == NULL)
++					if (!s->hit)
+ 						{
+-						if (len > TLSEXT_MAXLEN_host_name || 
+-							((s->session->tlsext_hostname = OPENSSL_malloc(len+1)) == NULL))
++						if(s->session->tlsext_hostname)
++							{
++							*al = SSL_AD_DECODE_ERROR;
++							return 0;
++							}
++						if (len > TLSEXT_MAXLEN_host_name)
+ 							{
+ 							*al = TLS1_AD_UNRECOGNIZED_NAME;
+ 							return 0;
+ 							}
++						if ((s->session->tlsext_hostname = OPENSSL_malloc(len+1)) == NULL)
++							{
++							*al = TLS1_AD_INTERNAL_ERROR;
++							return 0;
++							}
+ 						memcpy(s->session->tlsext_hostname, sdata, len);
+ 						s->session->tlsext_hostname[len]='\0';
+ 						if (strlen(s->session->tlsext_hostname) != len) {
+@@ -734,7 +743,8 @@
+ 
+ 						}
+ 					else 
+-						s->servername_done = strlen(s->session->tlsext_hostname) == len 
++						s->servername_done = s->session->tlsext_hostname
++							&& strlen(s->session->tlsext_hostname) == len 
+ 							&& strncmp(s->session->tlsext_hostname, (char *)sdata, len) == 0;
+ 					
+ 					break;
+@@ -765,15 +775,22 @@
+ 				*al = TLS1_AD_DECODE_ERROR;
+ 				return 0;
+ 				}
+-			s->session->tlsext_ecpointformatlist_length = 0;
+-			if (s->session->tlsext_ecpointformatlist != NULL) OPENSSL_free(s->session->tlsext_ecpointformatlist);
+-			if ((s->session->tlsext_ecpointformatlist = OPENSSL_malloc(ecpointformatlist_length)) == NULL)
++			if (!s->hit)
+ 				{
+-				*al = TLS1_AD_INTERNAL_ERROR;
+-				return 0;
++				if(s->session->tlsext_ecpointformatlist)
++					{
++					*al = TLS1_AD_DECODE_ERROR;
++					return 0;
++					}
++				s->session->tlsext_ecpointformatlist_length = 0;
++				if ((s->session->tlsext_ecpointformatlist = OPENSSL_malloc(ecpointformatlist_length)) == NULL)
++					{
++					*al = TLS1_AD_INTERNAL_ERROR;
++					return 0;
++					}
++				s->session->tlsext_ecpointformatlist_length = ecpointformatlist_length;
++				memcpy(s->session->tlsext_ecpointformatlist, sdata, ecpointformatlist_length);
+ 				}
+-			s->session->tlsext_ecpointformatlist_length = ecpointformatlist_length;
+-			memcpy(s->session->tlsext_ecpointformatlist, sdata, ecpointformatlist_length);
+ #if 0
+ 			fprintf(stderr,"ssl_parse_clienthello_tlsext s->session->tlsext_ecpointformatlist (length=%i) ", s->session->tlsext_ecpointformatlist_length);
+ 			sdata = s->session->tlsext_ecpointformatlist;
+@@ -794,15 +811,22 @@
+ 				*al = TLS1_AD_DECODE_ERROR;
+ 				return 0;
+ 				}
+-			s->session->tlsext_ellipticcurvelist_length = 0;
+-			if (s->session->tlsext_ellipticcurvelist != NULL) OPENSSL_free(s->session->tlsext_ellipticcurvelist);
+-			if ((s->session->tlsext_ellipticcurvelist = OPENSSL_malloc(ellipticcurvelist_length)) == NULL)
++			if (!s->hit)
+ 				{
+-				*al = TLS1_AD_INTERNAL_ERROR;
+-				return 0;
++				if(s->session->tlsext_ellipticcurvelist)
++					{
++					*al = TLS1_AD_DECODE_ERROR;
++					return 0;
++					}
++				s->session->tlsext_ellipticcurvelist_length = 0;
++				if ((s->session->tlsext_ellipticcurvelist = OPENSSL_malloc(ellipticcurvelist_length)) == NULL)
++					{
++					*al = TLS1_AD_INTERNAL_ERROR;
++					return 0;
++					}
++				s->session->tlsext_ellipticcurvelist_length = ellipticcurvelist_length;
++				memcpy(s->session->tlsext_ellipticcurvelist, sdata, ellipticcurvelist_length);
+ 				}
+-			s->session->tlsext_ellipticcurvelist_length = ellipticcurvelist_length;
+-			memcpy(s->session->tlsext_ellipticcurvelist, sdata, ellipticcurvelist_length);
+ #if 0
+ 			fprintf(stderr,"ssl_parse_clienthello_tlsext s->session->tlsext_ellipticcurvelist (length=%i) ", s->session->tlsext_ellipticcurvelist_length);
+ 			sdata = s->session->tlsext_ellipticcurvelist;
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
index e8bc34c..eac2deb 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -714,14 +714,23 @@
 				switch (servname_type)
 					{
 				case TLSEXT_NAMETYPE_host_name:
-					if (s->session->tlsext_hostname == NULL)
+					if (!s->hit)
 						{
-						if (len > TLSEXT_MAXLEN_host_name || 
-							((s->session->tlsext_hostname = OPENSSL_malloc(len+1)) == NULL))
+						if(s->session->tlsext_hostname)
+							{
+							*al = SSL_AD_DECODE_ERROR;
+							return 0;
+							}
+						if (len > TLSEXT_MAXLEN_host_name)
 							{
 							*al = TLS1_AD_UNRECOGNIZED_NAME;
 							return 0;
 							}
+						if ((s->session->tlsext_hostname = OPENSSL_malloc(len+1)) == NULL)
+							{
+							*al = TLS1_AD_INTERNAL_ERROR;
+							return 0;
+							}
 						memcpy(s->session->tlsext_hostname, sdata, len);
 						s->session->tlsext_hostname[len]='\0';
 						if (strlen(s->session->tlsext_hostname) != len) {
@@ -734,7 +743,8 @@
 
 						}
 					else 
-						s->servername_done = strlen(s->session->tlsext_hostname) == len 
+						s->servername_done = s->session->tlsext_hostname
+							&& strlen(s->session->tlsext_hostname) == len 
 							&& strncmp(s->session->tlsext_hostname, (char *)sdata, len) == 0;
 					
 					break;
@@ -765,15 +775,22 @@
 				*al = TLS1_AD_DECODE_ERROR;
 				return 0;
 				}
-			s->session->tlsext_ecpointformatlist_length = 0;
-			if (s->session->tlsext_ecpointformatlist != NULL) OPENSSL_free(s->session->tlsext_ecpointformatlist);
-			if ((s->session->tlsext_ecpointformatlist = OPENSSL_malloc(ecpointformatlist_length)) == NULL)
+			if (!s->hit)
 				{
-				*al = TLS1_AD_INTERNAL_ERROR;
-				return 0;
+				if(s->session->tlsext_ecpointformatlist)
+					{
+					*al = TLS1_AD_DECODE_ERROR;
+					return 0;
+					}
+				s->session->tlsext_ecpointformatlist_length = 0;
+				if ((s->session->tlsext_ecpointformatlist = OPENSSL_malloc(ecpointformatlist_length)) == NULL)
+					{
+					*al = TLS1_AD_INTERNAL_ERROR;
+					return 0;
+					}
+				s->session->tlsext_ecpointformatlist_length = ecpointformatlist_length;
+				memcpy(s->session->tlsext_ecpointformatlist, sdata, ecpointformatlist_length);
 				}
-			s->session->tlsext_ecpointformatlist_length = ecpointformatlist_length;
-			memcpy(s->session->tlsext_ecpointformatlist, sdata, ecpointformatlist_length);
 #if 0
 			fprintf(stderr,"ssl_parse_clienthello_tlsext s->session->tlsext_ecpointformatlist (length=%i) ", s->session->tlsext_ecpointformatlist_length);
 			sdata = s->session->tlsext_ecpointformatlist;
@@ -794,15 +811,22 @@
 				*al = TLS1_AD_DECODE_ERROR;
 				return 0;
 				}
-			s->session->tlsext_ellipticcurvelist_length = 0;
-			if (s->session->tlsext_ellipticcurvelist != NULL) OPENSSL_free(s->session->tlsext_ellipticcurvelist);
-			if ((s->session->tlsext_ellipticcurvelist = OPENSSL_malloc(ellipticcurvelist_length)) == NULL)
+			if (!s->hit)
 				{
-				*al = TLS1_AD_INTERNAL_ERROR;
-				return 0;
+				if(s->session->tlsext_ellipticcurvelist)
+					{
+					*al = TLS1_AD_DECODE_ERROR;
+					return 0;
+					}
+				s->session->tlsext_ellipticcurvelist_length = 0;
+				if ((s->session->tlsext_ellipticcurvelist = OPENSSL_malloc(ellipticcurvelist_length)) == NULL)
+					{
+					*al = TLS1_AD_INTERNAL_ERROR;
+					return 0;
+					}
+				s->session->tlsext_ellipticcurvelist_length = ellipticcurvelist_length;
+				memcpy(s->session->tlsext_ellipticcurvelist, sdata, ellipticcurvelist_length);
 				}
-			s->session->tlsext_ellipticcurvelist_length = ellipticcurvelist_length;
-			memcpy(s->session->tlsext_ellipticcurvelist, sdata, ellipticcurvelist_length);
 #if 0
 			fprintf(stderr,"ssl_parse_clienthello_tlsext s->session->tlsext_ellipticcurvelist (length=%i) ", s->session->tlsext_ellipticcurvelist_length);
 			sdata = s->session->tlsext_ellipticcurvelist;