New tls channel id version for OpenSSL

New tls channel id version extracted from patch 0015-channelid.patch attached to http://crbug.com/366961.

BUG=366961

Review URL: https://codereview.chromium.org/259963009

git-svn-id: http://src.chromium.org/svn/trunk/deps/third_party/openssl@268457 4ff67af0-8c30-449e-8e8b-ad334ec8d88c
diff --git a/openssl/include/openssl/ssl.h b/openssl/include/openssl/ssl.h
index a3944f1..fe92ccf 100644
--- a/openssl/include/openssl/ssl.h
+++ b/openssl/include/openssl/ssl.h
@@ -547,6 +547,13 @@
 #ifndef OPENSSL_NO_SRP
 	char *srp_username;
 #endif
+
+	/* original_handshake_hash contains the handshake hash (either
+	 * SHA-1+MD5 or SHA-2, depending on TLS version) for the original, full
+	 * handshake that created a session. This is used by Channel IDs during
+	 * resumption. */
+	unsigned char original_handshake_hash[EVP_MAX_MD_SIZE];
+	unsigned int original_handshake_hash_len;
 	};
 
 #endif
diff --git a/openssl/include/openssl/tls1.h b/openssl/include/openssl/tls1.h
index c4f69aa..5559486 100644
--- a/openssl/include/openssl/tls1.h
+++ b/openssl/include/openssl/tls1.h
@@ -255,7 +255,7 @@
 #endif
 
 /* This is not an IANA defined extension number */
-#define TLSEXT_TYPE_channel_id			30031
+#define TLSEXT_TYPE_channel_id			30032
 
 /* NameType value from RFC 3546 */
 #define TLSEXT_NAMETYPE_host_name 0
diff --git a/openssl/patches/new_channelid.patch b/openssl/patches/new_channelid.patch
new file mode 100644
index 0000000..22a8fdd
--- /dev/null
+++ b/openssl/patches/new_channelid.patch
@@ -0,0 +1,273 @@
+diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
+index a3944f1..fe92ccf 100644
+--- a/include/openssl/ssl.h
++++ b/include/openssl/ssl.h
+@@ -547,6 +547,13 @@ struct ssl_session_st
+ #ifndef OPENSSL_NO_SRP
+ 	char *srp_username;
+ #endif
++
++	/* original_handshake_hash contains the handshake hash (either
++	 * SHA-1+MD5 or SHA-2, depending on TLS version) for the original, full
++	 * handshake that created a session. This is used by Channel IDs during
++	 * resumption. */
++	unsigned char original_handshake_hash[EVP_MAX_MD_SIZE];
++	unsigned int original_handshake_hash_len;
+ 	};
+ 
+ #endif
+diff --git a/include/openssl/tls1.h b/include/openssl/tls1.h
+index c4f69aa..5559486 100644
+--- a/include/openssl/tls1.h
++++ b/include/openssl/tls1.h
+@@ -255,7 +255,7 @@ extern "C" {
+ #endif
+ 
+ /* This is not an IANA defined extension number */
+-#define TLSEXT_TYPE_channel_id			30031
++#define TLSEXT_TYPE_channel_id			30032
+ 
+ /* NameType value from RFC 3546 */
+ #define TLSEXT_NAMETYPE_host_name 0
+diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c
+index 640df80..d6154c5 100644
+--- a/ssl/s3_clnt.c
++++ b/ssl/s3_clnt.c
+@@ -583,6 +583,18 @@ int ssl3_connect(SSL *s)
+ #endif
+ 						s->s3->tmp.next_state=SSL3_ST_CR_FINISHED_A;
+ 					}
++					if (s->s3->tlsext_channel_id_valid)
++					{
++					/* This is a non-resumption handshake. If it
++					 * involves ChannelID, then record the
++					 * handshake hashes at this point in the
++					 * session so that any resumption of this
++					 * session with ChannelID can sign those
++					 * hashes. */
++					ret = tls1_record_handshake_hashes_for_channel_id(s);
++					if (ret <= 0)
++						goto end;
++					}
+ 				}
+ 			s->init_num=0;
+ 			break;
+diff --git a/ssl/ssl.h b/ssl/ssl.h
+index a3944f1..fe92ccf 100644
+--- a/ssl/ssl.h
++++ b/ssl/ssl.h
+@@ -547,6 +547,13 @@ struct ssl_session_st
+ #ifndef OPENSSL_NO_SRP
+ 	char *srp_username;
+ #endif
++
++	/* original_handshake_hash contains the handshake hash (either
++	 * SHA-1+MD5 or SHA-2, depending on TLS version) for the original, full
++	 * handshake that created a session. This is used by Channel IDs during
++	 * resumption. */
++	unsigned char original_handshake_hash[EVP_MAX_MD_SIZE];
++	unsigned int original_handshake_hash_len;
+ 	};
+ 
+ #endif
+diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h
+index 531a291..c975d31 100644
+--- a/ssl/ssl_locl.h
++++ b/ssl/ssl_locl.h
+@@ -1102,6 +1102,7 @@ void ssl_free_wbio_buffer(SSL *s);
+ int tls1_change_cipher_state(SSL *s, int which);
+ int tls1_setup_key_block(SSL *s);
+ int tls1_enc(SSL *s, int snd);
++int tls1_handshake_digest(SSL *s, unsigned char *out, size_t out_len);
+ int tls1_final_finish_mac(SSL *s,
+ 	const char *str, int slen, unsigned char *p);
+ int tls1_cert_verify_mac(SSL *s, int md_nid, unsigned char *p);
+@@ -1158,6 +1159,7 @@ int tls12_get_sigid(const EVP_PKEY *pk);
+ const EVP_MD *tls12_get_hash(unsigned char hash_alg);
+ 
+ int tls1_channel_id_hash(EVP_MD_CTX *ctx, SSL *s);
++int tls1_record_handshake_hashes_for_channel_id(SSL *s);
+ #endif
+ 
+ int ssl3_can_cutthrough(const SSL *s);
+diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c
+index 87b7021..d30ce61 100644
+--- a/ssl/t1_enc.c
++++ b/ssl/t1_enc.c
+@@ -1147,53 +1147,79 @@ int tls1_cert_verify_mac(SSL *s, int md_nid, unsigned char *out)
+ 	return((int)ret);
+ 	}
+ 
++/* tls1_handshake_digest calculates the current handshake hash and writes it to
++ * |out|, which has space for |out_len| bytes. It returns the number of bytes
++ * written or -1 in the event of an error. This function works on a copy of the
++ * underlying digests so can be called multiple times and prior to the final
++ * update etc. */
++int tls1_handshake_digest(SSL *s, unsigned char *out, size_t out_len)
++	{
++	const EVP_MD *md;
++	EVP_MD_CTX ctx;
++	int i, err = 0, len = 0;
++	long mask;
++
++	EVP_MD_CTX_init(&ctx);
++
++	for (i = 0; ssl_get_handshake_digest(i, &mask, &md); i++)
++		{
++		int hash_size;
++		unsigned int digest_len;
++		EVP_MD_CTX *hdgst = s->s3->handshake_dgst[i];
++
++		if ((mask & ssl_get_algorithm2(s)) == 0)
++			continue;
++
++		hash_size = EVP_MD_size(md);
++		if (!hdgst || hash_size < 0 || (size_t)hash_size > out_len)
++			{
++			err = 1;
++			break;
++			}
++
++		if (!EVP_MD_CTX_copy_ex(&ctx, hdgst) ||
++		    !EVP_DigestFinal_ex(&ctx, out, &digest_len) ||
++		    digest_len != (unsigned int)hash_size) /* internal error */
++			{
++			err = 1;
++			break;
++			}
++		out += digest_len;
++		out_len -= digest_len;
++		len += digest_len;
++		}
++
++	EVP_MD_CTX_cleanup(&ctx);
++
++	if (err != 0)
++		return -1;
++	return len;
++	}
++
+ int tls1_final_finish_mac(SSL *s,
+ 	     const char *str, int slen, unsigned char *out)
+ 	{
+-	unsigned int i;
+-	EVP_MD_CTX ctx;
+ 	unsigned char buf[2*EVP_MAX_MD_SIZE];
+-	unsigned char *q,buf2[12];
+-	int idx;
+-	long mask;
++	unsigned char buf2[12];
+ 	int err=0;
+-	const EVP_MD *md; 
++	int digests_len;
+ 
+-	q=buf;
+-
+-	if (s->s3->handshake_buffer) 
++	if (s->s3->handshake_buffer)
+ 		if (!ssl3_digest_cached_records(s))
+ 			return 0;
+ 
+-	EVP_MD_CTX_init(&ctx);
+-
+-	for (idx=0;ssl_get_handshake_digest(idx,&mask,&md);idx++)
++	digests_len = tls1_handshake_digest(s, buf, sizeof(buf));
++	if (digests_len < 0)
+ 		{
+-		if (mask & ssl_get_algorithm2(s))
+-			{
+-			int hashsize = EVP_MD_size(md);
+-			if (hashsize < 0 || hashsize > (int)(sizeof buf - (size_t)(q-buf)))
+-				{
+-				/* internal error: 'buf' is too small for this cipersuite! */
+-				err = 1;
+-				}
+-			else
+-				{
+-				EVP_MD_CTX_copy_ex(&ctx,s->s3->handshake_dgst[idx]);
+-				EVP_DigestFinal_ex(&ctx,q,&i);
+-				if (i != (unsigned int)hashsize) /* can't really happen */
+-					err = 1;
+-				q+=i;
+-				}
+-			}
++		err = 1;
++		digests_len = 0;
+ 		}
+-		
++
+ 	if (!tls1_PRF(ssl_get_algorithm2(s),
+-			str,slen, buf,(int)(q-buf), NULL,0, NULL,0, NULL,0,
++			str,slen, buf, digests_len, NULL,0, NULL,0, NULL,0,
+ 			s->session->master_key,s->session->master_key_length,
+ 			out,buf2,sizeof buf2))
+ 		err = 1;
+-	EVP_MD_CTX_cleanup(&ctx);
+ 
+ 	if (err)
+ 		return 0;
+diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
+index ea7fefa..d7ea9a5 100644
+--- a/ssl/t1_lib.c
++++ b/ssl/t1_lib.c
+@@ -2684,6 +2684,17 @@ tls1_channel_id_hash(EVP_MD_CTX *md, SSL *s)
+ 
+ 	EVP_DigestUpdate(md, kClientIDMagic, sizeof(kClientIDMagic));
+ 
++	if (s->hit)
++		{
++		static const char kResumptionMagic[] = "Resumption";
++		EVP_DigestUpdate(md, kResumptionMagic,
++				 sizeof(kResumptionMagic));
++		if (s->session->original_handshake_hash_len == 0)
++			return 0;
++		EVP_DigestUpdate(md, s->session->original_handshake_hash,
++				 s->session->original_handshake_hash_len);
++		}
++
+ 	EVP_MD_CTX_init(&ctx);
+ 	for (i = 0; i < SSL_MAX_DIGEST; i++)
+ 		{
+@@ -2698,3 +2709,29 @@ tls1_channel_id_hash(EVP_MD_CTX *md, SSL *s)
+ 	return 1;
+ 	}
+ #endif
++
++/* tls1_record_handshake_hashes_for_channel_id records the current handshake
++ * hashes in |s->session| so that Channel ID resumptions can sign that data. */
++int tls1_record_handshake_hashes_for_channel_id(SSL *s)
++	{
++	int digest_len;
++	/* This function should never be called for a resumed session because
++	 * the handshake hashes that we wish to record are for the original,
++	 * full handshake. */
++	if (s->hit)
++		return -1;
++	/* It only makes sense to call this function if Channel IDs have been
++	 * negotiated. */
++	if (!s->s3->tlsext_channel_id_valid)
++		return -1;
++
++	digest_len = tls1_handshake_digest(
++		s, s->session->original_handshake_hash,
++		sizeof(s->session->original_handshake_hash));
++	if (digest_len < 0)
++		return -1;
++
++	s->session->original_handshake_hash_len = digest_len;
++
++	return 1;
++	}
+diff --git a/ssl/tls1.h b/ssl/tls1.h
+index c4f69aa..5559486 100644
+--- a/ssl/tls1.h
++++ b/ssl/tls1.h
+@@ -255,7 +255,7 @@ extern "C" {
+ #endif
+ 
+ /* This is not an IANA defined extension number */
+-#define TLSEXT_TYPE_channel_id			30031
++#define TLSEXT_TYPE_channel_id			30032
+ 
+ /* NameType value from RFC 3546 */
+ #define TLSEXT_NAMETYPE_host_name 0
diff --git a/openssl/ssl/s3_clnt.c b/openssl/ssl/s3_clnt.c
index 640df80..d6154c5 100644
--- a/openssl/ssl/s3_clnt.c
+++ b/openssl/ssl/s3_clnt.c
@@ -583,6 +583,18 @@
 #endif
 						s->s3->tmp.next_state=SSL3_ST_CR_FINISHED_A;
 					}
+					if (s->s3->tlsext_channel_id_valid)
+					{
+					/* This is a non-resumption handshake. If it
+					 * involves ChannelID, then record the
+					 * handshake hashes at this point in the
+					 * session so that any resumption of this
+					 * session with ChannelID can sign those
+					 * hashes. */
+					ret = tls1_record_handshake_hashes_for_channel_id(s);
+					if (ret <= 0)
+						goto end;
+					}
 				}
 			s->init_num=0;
 			break;
diff --git a/openssl/ssl/ssl.h b/openssl/ssl/ssl.h
index a3944f1..fe92ccf 100644
--- a/openssl/ssl/ssl.h
+++ b/openssl/ssl/ssl.h
@@ -547,6 +547,13 @@
 #ifndef OPENSSL_NO_SRP
 	char *srp_username;
 #endif
+
+	/* original_handshake_hash contains the handshake hash (either
+	 * SHA-1+MD5 or SHA-2, depending on TLS version) for the original, full
+	 * handshake that created a session. This is used by Channel IDs during
+	 * resumption. */
+	unsigned char original_handshake_hash[EVP_MAX_MD_SIZE];
+	unsigned int original_handshake_hash_len;
 	};
 
 #endif
diff --git a/openssl/ssl/ssl_locl.h b/openssl/ssl/ssl_locl.h
index 531a291..c975d31 100644
--- a/openssl/ssl/ssl_locl.h
+++ b/openssl/ssl/ssl_locl.h
@@ -1102,6 +1102,7 @@
 int tls1_change_cipher_state(SSL *s, int which);
 int tls1_setup_key_block(SSL *s);
 int tls1_enc(SSL *s, int snd);
+int tls1_handshake_digest(SSL *s, unsigned char *out, size_t out_len);
 int tls1_final_finish_mac(SSL *s,
 	const char *str, int slen, unsigned char *p);
 int tls1_cert_verify_mac(SSL *s, int md_nid, unsigned char *p);
@@ -1158,6 +1159,7 @@
 const EVP_MD *tls12_get_hash(unsigned char hash_alg);
 
 int tls1_channel_id_hash(EVP_MD_CTX *ctx, SSL *s);
+int tls1_record_handshake_hashes_for_channel_id(SSL *s);
 #endif
 
 int ssl3_can_cutthrough(const SSL *s);
diff --git a/openssl/ssl/t1_enc.c b/openssl/ssl/t1_enc.c
index 87b7021..d30ce61 100644
--- a/openssl/ssl/t1_enc.c
+++ b/openssl/ssl/t1_enc.c
@@ -1147,53 +1147,79 @@
 	return((int)ret);
 	}
 
-int tls1_final_finish_mac(SSL *s,
-	     const char *str, int slen, unsigned char *out)
+/* tls1_handshake_digest calculates the current handshake hash and writes it to
+ * |out|, which has space for |out_len| bytes. It returns the number of bytes
+ * written or -1 in the event of an error. This function works on a copy of the
+ * underlying digests so can be called multiple times and prior to the final
+ * update etc. */
+int tls1_handshake_digest(SSL *s, unsigned char *out, size_t out_len)
 	{
-	unsigned int i;
+	const EVP_MD *md;
 	EVP_MD_CTX ctx;
-	unsigned char buf[2*EVP_MAX_MD_SIZE];
-	unsigned char *q,buf2[12];
-	int idx;
+	int i, err = 0, len = 0;
 	long mask;
-	int err=0;
-	const EVP_MD *md; 
-
-	q=buf;
-
-	if (s->s3->handshake_buffer) 
-		if (!ssl3_digest_cached_records(s))
-			return 0;
 
 	EVP_MD_CTX_init(&ctx);
 
-	for (idx=0;ssl_get_handshake_digest(idx,&mask,&md);idx++)
+	for (i = 0; ssl_get_handshake_digest(i, &mask, &md); i++)
 		{
-		if (mask & ssl_get_algorithm2(s))
+		int hash_size;
+		unsigned int digest_len;
+		EVP_MD_CTX *hdgst = s->s3->handshake_dgst[i];
+
+		if ((mask & ssl_get_algorithm2(s)) == 0)
+			continue;
+
+		hash_size = EVP_MD_size(md);
+		if (!hdgst || hash_size < 0 || (size_t)hash_size > out_len)
 			{
-			int hashsize = EVP_MD_size(md);
-			if (hashsize < 0 || hashsize > (int)(sizeof buf - (size_t)(q-buf)))
-				{
-				/* internal error: 'buf' is too small for this cipersuite! */
-				err = 1;
-				}
-			else
-				{
-				EVP_MD_CTX_copy_ex(&ctx,s->s3->handshake_dgst[idx]);
-				EVP_DigestFinal_ex(&ctx,q,&i);
-				if (i != (unsigned int)hashsize) /* can't really happen */
-					err = 1;
-				q+=i;
-				}
+			err = 1;
+			break;
 			}
+
+		if (!EVP_MD_CTX_copy_ex(&ctx, hdgst) ||
+		    !EVP_DigestFinal_ex(&ctx, out, &digest_len) ||
+		    digest_len != (unsigned int)hash_size) /* internal error */
+			{
+			err = 1;
+			break;
+			}
+		out += digest_len;
+		out_len -= digest_len;
+		len += digest_len;
 		}
-		
+
+	EVP_MD_CTX_cleanup(&ctx);
+
+	if (err != 0)
+		return -1;
+	return len;
+	}
+
+int tls1_final_finish_mac(SSL *s,
+	     const char *str, int slen, unsigned char *out)
+	{
+	unsigned char buf[2*EVP_MAX_MD_SIZE];
+	unsigned char buf2[12];
+	int err=0;
+	int digests_len;
+
+	if (s->s3->handshake_buffer)
+		if (!ssl3_digest_cached_records(s))
+			return 0;
+
+	digests_len = tls1_handshake_digest(s, buf, sizeof(buf));
+	if (digests_len < 0)
+		{
+		err = 1;
+		digests_len = 0;
+		}
+
 	if (!tls1_PRF(ssl_get_algorithm2(s),
-			str,slen, buf,(int)(q-buf), NULL,0, NULL,0, NULL,0,
+			str,slen, buf, digests_len, NULL,0, NULL,0, NULL,0,
 			s->session->master_key,s->session->master_key_length,
 			out,buf2,sizeof buf2))
 		err = 1;
-	EVP_MD_CTX_cleanup(&ctx);
 
 	if (err)
 		return 0;
diff --git a/openssl/ssl/t1_lib.c b/openssl/ssl/t1_lib.c
index ea7fefa..d7ea9a5 100644
--- a/openssl/ssl/t1_lib.c
+++ b/openssl/ssl/t1_lib.c
@@ -2684,6 +2684,17 @@
 
 	EVP_DigestUpdate(md, kClientIDMagic, sizeof(kClientIDMagic));
 
+	if (s->hit)
+		{
+		static const char kResumptionMagic[] = "Resumption";
+		EVP_DigestUpdate(md, kResumptionMagic,
+				 sizeof(kResumptionMagic));
+		if (s->session->original_handshake_hash_len == 0)
+			return 0;
+		EVP_DigestUpdate(md, s->session->original_handshake_hash,
+				 s->session->original_handshake_hash_len);
+		}
+
 	EVP_MD_CTX_init(&ctx);
 	for (i = 0; i < SSL_MAX_DIGEST; i++)
 		{
@@ -2698,3 +2709,29 @@
 	return 1;
 	}
 #endif
+
+/* tls1_record_handshake_hashes_for_channel_id records the current handshake
+ * hashes in |s->session| so that Channel ID resumptions can sign that data. */
+int tls1_record_handshake_hashes_for_channel_id(SSL *s)
+	{
+	int digest_len;
+	/* This function should never be called for a resumed session because
+	 * the handshake hashes that we wish to record are for the original,
+	 * full handshake. */
+	if (s->hit)
+		return -1;
+	/* It only makes sense to call this function if Channel IDs have been
+	 * negotiated. */
+	if (!s->s3->tlsext_channel_id_valid)
+		return -1;
+
+	digest_len = tls1_handshake_digest(
+		s, s->session->original_handshake_hash,
+		sizeof(s->session->original_handshake_hash));
+	if (digest_len < 0)
+		return -1;
+
+	s->session->original_handshake_hash_len = digest_len;
+
+	return 1;
+	}
diff --git a/openssl/ssl/tls1.h b/openssl/ssl/tls1.h
index c4f69aa..5559486 100644
--- a/openssl/ssl/tls1.h
+++ b/openssl/ssl/tls1.h
@@ -255,7 +255,7 @@
 #endif
 
 /* This is not an IANA defined extension number */
-#define TLSEXT_TYPE_channel_id			30031
+#define TLSEXT_TYPE_channel_id			30032
 
 /* NameType value from RFC 3546 */
 #define TLSEXT_NAMETYPE_host_name 0
diff --git a/patches.chromium/0014-new_channelid.patch b/patches.chromium/0014-new_channelid.patch
new file mode 100644
index 0000000..7f607d0
--- /dev/null
+++ b/patches.chromium/0014-new_channelid.patch
@@ -0,0 +1,537 @@
+diff -burN android-openssl.orig/include/openssl/ssl.h android-openssl/include/openssl/ssl.h
+--- android-openssl.orig/include/openssl/ssl.h	2014-05-05 16:45:02.685389339 +0200
++++ android-openssl/include/openssl/ssl.h	2014-05-05 16:46:32.513390565 +0200
+@@ -544,6 +544,13 @@
+ #ifndef OPENSSL_NO_SRP
+ 	char *srp_username;
+ #endif
++
++	/* original_handshake_hash contains the handshake hash (either
++	 * SHA-1+MD5 or SHA-2, depending on TLS version) for the original, full
++	 * handshake that created a session. This is used by Channel IDs during
++	 * resumption. */
++	unsigned char original_handshake_hash[EVP_MAX_MD_SIZE];
++	unsigned int original_handshake_hash_len;
+ 	};
+ 
+ #endif
+diff -burN android-openssl.orig/include/openssl/tls1.h android-openssl/include/openssl/tls1.h
+--- android-openssl.orig/include/openssl/tls1.h	2014-05-05 16:45:02.689389339 +0200
++++ android-openssl/include/openssl/tls1.h	2014-05-05 16:46:32.517390565 +0200
+@@ -249,7 +249,7 @@
+ #endif
+ 
+ /* This is not an IANA defined extension number */
+-#define TLSEXT_TYPE_channel_id			30031
++#define TLSEXT_TYPE_channel_id			30032
+ 
+ /* NameType value from RFC 3546 */
+ #define TLSEXT_NAMETYPE_host_name 0
+diff -burN android-openssl.orig/patches/new_channelid.patch android-openssl/patches/new_channelid.patch
+--- android-openssl.orig/patches/new_channelid.patch	1970-01-01 01:00:00.000000000 +0100
++++ android-openssl/patches/new_channelid.patch	2014-05-05 16:48:54.429392502 +0200
+@@ -0,0 +1,273 @@
++diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
++index a3944f1..fe92ccf 100644
++--- a/include/openssl/ssl.h
+++++ b/include/openssl/ssl.h
++@@ -547,6 +547,13 @@ struct ssl_session_st
++ #ifndef OPENSSL_NO_SRP
++ 	char *srp_username;
++ #endif
+++
+++	/* original_handshake_hash contains the handshake hash (either
+++	 * SHA-1+MD5 or SHA-2, depending on TLS version) for the original, full
+++	 * handshake that created a session. This is used by Channel IDs during
+++	 * resumption. */
+++	unsigned char original_handshake_hash[EVP_MAX_MD_SIZE];
+++	unsigned int original_handshake_hash_len;
++ 	};
++ 
++ #endif
++diff --git a/include/openssl/tls1.h b/include/openssl/tls1.h
++index c4f69aa..5559486 100644
++--- a/include/openssl/tls1.h
+++++ b/include/openssl/tls1.h
++@@ -255,7 +255,7 @@ extern "C" {
++ #endif
++ 
++ /* This is not an IANA defined extension number */
++-#define TLSEXT_TYPE_channel_id			30031
+++#define TLSEXT_TYPE_channel_id			30032
++ 
++ /* NameType value from RFC 3546 */
++ #define TLSEXT_NAMETYPE_host_name 0
++diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c
++index 640df80..d6154c5 100644
++--- a/ssl/s3_clnt.c
+++++ b/ssl/s3_clnt.c
++@@ -583,6 +583,18 @@ int ssl3_connect(SSL *s)
++ #endif
++ 						s->s3->tmp.next_state=SSL3_ST_CR_FINISHED_A;
++ 					}
+++					if (s->s3->tlsext_channel_id_valid)
+++					{
+++					/* This is a non-resumption handshake. If it
+++					 * involves ChannelID, then record the
+++					 * handshake hashes at this point in the
+++					 * session so that any resumption of this
+++					 * session with ChannelID can sign those
+++					 * hashes. */
+++					ret = tls1_record_handshake_hashes_for_channel_id(s);
+++					if (ret <= 0)
+++						goto end;
+++					}
++ 				}
++ 			s->init_num=0;
++ 			break;
++diff --git a/ssl/ssl.h b/ssl/ssl.h
++index a3944f1..fe92ccf 100644
++--- a/ssl/ssl.h
+++++ b/ssl/ssl.h
++@@ -547,6 +547,13 @@ struct ssl_session_st
++ #ifndef OPENSSL_NO_SRP
++ 	char *srp_username;
++ #endif
+++
+++	/* original_handshake_hash contains the handshake hash (either
+++	 * SHA-1+MD5 or SHA-2, depending on TLS version) for the original, full
+++	 * handshake that created a session. This is used by Channel IDs during
+++	 * resumption. */
+++	unsigned char original_handshake_hash[EVP_MAX_MD_SIZE];
+++	unsigned int original_handshake_hash_len;
++ 	};
++ 
++ #endif
++diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h
++index 531a291..c975d31 100644
++--- a/ssl/ssl_locl.h
+++++ b/ssl/ssl_locl.h
++@@ -1102,6 +1102,7 @@ void ssl_free_wbio_buffer(SSL *s);
++ int tls1_change_cipher_state(SSL *s, int which);
++ int tls1_setup_key_block(SSL *s);
++ int tls1_enc(SSL *s, int snd);
+++int tls1_handshake_digest(SSL *s, unsigned char *out, size_t out_len);
++ int tls1_final_finish_mac(SSL *s,
++ 	const char *str, int slen, unsigned char *p);
++ int tls1_cert_verify_mac(SSL *s, int md_nid, unsigned char *p);
++@@ -1158,6 +1159,7 @@ int tls12_get_sigid(const EVP_PKEY *pk);
++ const EVP_MD *tls12_get_hash(unsigned char hash_alg);
++ 
++ int tls1_channel_id_hash(EVP_MD_CTX *ctx, SSL *s);
+++int tls1_record_handshake_hashes_for_channel_id(SSL *s);
++ #endif
++ 
++ int ssl3_can_cutthrough(const SSL *s);
++diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c
++index 87b7021..d30ce61 100644
++--- a/ssl/t1_enc.c
+++++ b/ssl/t1_enc.c
++@@ -1147,53 +1147,79 @@ int tls1_cert_verify_mac(SSL *s, int md_nid, unsigned char *out)
++ 	return((int)ret);
++ 	}
++ 
+++/* tls1_handshake_digest calculates the current handshake hash and writes it to
+++ * |out|, which has space for |out_len| bytes. It returns the number of bytes
+++ * written or -1 in the event of an error. This function works on a copy of the
+++ * underlying digests so can be called multiple times and prior to the final
+++ * update etc. */
+++int tls1_handshake_digest(SSL *s, unsigned char *out, size_t out_len)
+++	{
+++	const EVP_MD *md;
+++	EVP_MD_CTX ctx;
+++	int i, err = 0, len = 0;
+++	long mask;
+++
+++	EVP_MD_CTX_init(&ctx);
+++
+++	for (i = 0; ssl_get_handshake_digest(i, &mask, &md); i++)
+++		{
+++		int hash_size;
+++		unsigned int digest_len;
+++		EVP_MD_CTX *hdgst = s->s3->handshake_dgst[i];
+++
+++		if ((mask & ssl_get_algorithm2(s)) == 0)
+++			continue;
+++
+++		hash_size = EVP_MD_size(md);
+++		if (!hdgst || hash_size < 0 || (size_t)hash_size > out_len)
+++			{
+++			err = 1;
+++			break;
+++			}
+++
+++		if (!EVP_MD_CTX_copy_ex(&ctx, hdgst) ||
+++		    !EVP_DigestFinal_ex(&ctx, out, &digest_len) ||
+++		    digest_len != (unsigned int)hash_size) /* internal error */
+++			{
+++			err = 1;
+++			break;
+++			}
+++		out += digest_len;
+++		out_len -= digest_len;
+++		len += digest_len;
+++		}
+++
+++	EVP_MD_CTX_cleanup(&ctx);
+++
+++	if (err != 0)
+++		return -1;
+++	return len;
+++	}
+++
++ int tls1_final_finish_mac(SSL *s,
++ 	     const char *str, int slen, unsigned char *out)
++ 	{
++-	unsigned int i;
++-	EVP_MD_CTX ctx;
++ 	unsigned char buf[2*EVP_MAX_MD_SIZE];
++-	unsigned char *q,buf2[12];
++-	int idx;
++-	long mask;
+++	unsigned char buf2[12];
++ 	int err=0;
++-	const EVP_MD *md; 
+++	int digests_len;
++ 
++-	q=buf;
++-
++-	if (s->s3->handshake_buffer) 
+++	if (s->s3->handshake_buffer)
++ 		if (!ssl3_digest_cached_records(s))
++ 			return 0;
++ 
++-	EVP_MD_CTX_init(&ctx);
++-
++-	for (idx=0;ssl_get_handshake_digest(idx,&mask,&md);idx++)
+++	digests_len = tls1_handshake_digest(s, buf, sizeof(buf));
+++	if (digests_len < 0)
++ 		{
++-		if (mask & ssl_get_algorithm2(s))
++-			{
++-			int hashsize = EVP_MD_size(md);
++-			if (hashsize < 0 || hashsize > (int)(sizeof buf - (size_t)(q-buf)))
++-				{
++-				/* internal error: 'buf' is too small for this cipersuite! */
++-				err = 1;
++-				}
++-			else
++-				{
++-				EVP_MD_CTX_copy_ex(&ctx,s->s3->handshake_dgst[idx]);
++-				EVP_DigestFinal_ex(&ctx,q,&i);
++-				if (i != (unsigned int)hashsize) /* can't really happen */
++-					err = 1;
++-				q+=i;
++-				}
++-			}
+++		err = 1;
+++		digests_len = 0;
++ 		}
++-		
+++
++ 	if (!tls1_PRF(ssl_get_algorithm2(s),
++-			str,slen, buf,(int)(q-buf), NULL,0, NULL,0, NULL,0,
+++			str,slen, buf, digests_len, NULL,0, NULL,0, NULL,0,
++ 			s->session->master_key,s->session->master_key_length,
++ 			out,buf2,sizeof buf2))
++ 		err = 1;
++-	EVP_MD_CTX_cleanup(&ctx);
++ 
++ 	if (err)
++ 		return 0;
++diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
++index ea7fefa..d7ea9a5 100644
++--- a/ssl/t1_lib.c
+++++ b/ssl/t1_lib.c
++@@ -2684,6 +2684,17 @@ tls1_channel_id_hash(EVP_MD_CTX *md, SSL *s)
++ 
++ 	EVP_DigestUpdate(md, kClientIDMagic, sizeof(kClientIDMagic));
++ 
+++	if (s->hit)
+++		{
+++		static const char kResumptionMagic[] = "Resumption";
+++		EVP_DigestUpdate(md, kResumptionMagic,
+++				 sizeof(kResumptionMagic));
+++		if (s->session->original_handshake_hash_len == 0)
+++			return 0;
+++		EVP_DigestUpdate(md, s->session->original_handshake_hash,
+++				 s->session->original_handshake_hash_len);
+++		}
+++
++ 	EVP_MD_CTX_init(&ctx);
++ 	for (i = 0; i < SSL_MAX_DIGEST; i++)
++ 		{
++@@ -2698,3 +2709,29 @@ tls1_channel_id_hash(EVP_MD_CTX *md, SSL *s)
++ 	return 1;
++ 	}
++ #endif
+++
+++/* tls1_record_handshake_hashes_for_channel_id records the current handshake
+++ * hashes in |s->session| so that Channel ID resumptions can sign that data. */
+++int tls1_record_handshake_hashes_for_channel_id(SSL *s)
+++	{
+++	int digest_len;
+++	/* This function should never be called for a resumed session because
+++	 * the handshake hashes that we wish to record are for the original,
+++	 * full handshake. */
+++	if (s->hit)
+++		return -1;
+++	/* It only makes sense to call this function if Channel IDs have been
+++	 * negotiated. */
+++	if (!s->s3->tlsext_channel_id_valid)
+++		return -1;
+++
+++	digest_len = tls1_handshake_digest(
+++		s, s->session->original_handshake_hash,
+++		sizeof(s->session->original_handshake_hash));
+++	if (digest_len < 0)
+++		return -1;
+++
+++	s->session->original_handshake_hash_len = digest_len;
+++
+++	return 1;
+++	}
++diff --git a/ssl/tls1.h b/ssl/tls1.h
++index c4f69aa..5559486 100644
++--- a/ssl/tls1.h
+++++ b/ssl/tls1.h
++@@ -255,7 +255,7 @@ extern "C" {
++ #endif
++ 
++ /* This is not an IANA defined extension number */
++-#define TLSEXT_TYPE_channel_id			30031
+++#define TLSEXT_TYPE_channel_id			30032
++ 
++ /* NameType value from RFC 3546 */
++ #define TLSEXT_NAMETYPE_host_name 0
+diff -burN android-openssl.orig/ssl/s3_clnt.c android-openssl/ssl/s3_clnt.c
+--- android-openssl.orig/ssl/s3_clnt.c	2014-05-05 16:45:02.785389340 +0200
++++ android-openssl/ssl/s3_clnt.c	2014-05-05 16:46:32.525390565 +0200
+@@ -583,6 +583,18 @@
+ #endif
+ 						s->s3->tmp.next_state=SSL3_ST_CR_FINISHED_A;
+ 					}
++					if (s->s3->tlsext_channel_id_valid)
++					{
++					/* This is a non-resumption handshake. If it
++					 * involves ChannelID, then record the
++					 * handshake hashes at this point in the
++					 * session so that any resumption of this
++					 * session with ChannelID can sign those
++					 * hashes. */
++					ret = tls1_record_handshake_hashes_for_channel_id(s);
++					if (ret <= 0)
++						goto end;
++					}
+ 				}
+ 			s->init_num=0;
+ 			break;
+diff -burN android-openssl.orig/ssl/ssl.h android-openssl/ssl/ssl.h
+--- android-openssl.orig/ssl/ssl.h	2014-05-05 16:45:02.693389339 +0200
++++ android-openssl/ssl/ssl.h	2014-05-05 16:46:32.533390565 +0200
+@@ -544,6 +544,13 @@
+ #ifndef OPENSSL_NO_SRP
+ 	char *srp_username;
+ #endif
++
++	/* original_handshake_hash contains the handshake hash (either
++	 * SHA-1+MD5 or SHA-2, depending on TLS version) for the original, full
++	 * handshake that created a session. This is used by Channel IDs during
++	 * resumption. */
++	unsigned char original_handshake_hash[EVP_MAX_MD_SIZE];
++	unsigned int original_handshake_hash_len;
+ 	};
+ 
+ #endif
+diff -burN android-openssl.orig/ssl/ssl_locl.h android-openssl/ssl/ssl_locl.h
+--- android-openssl.orig/ssl/ssl_locl.h	2014-05-05 16:45:02.785389340 +0200
++++ android-openssl/ssl/ssl_locl.h	2014-05-05 16:46:32.541390565 +0200
+@@ -1071,6 +1071,7 @@
+ int tls1_change_cipher_state(SSL *s, int which);
+ int tls1_setup_key_block(SSL *s);
+ int tls1_enc(SSL *s, int snd);
++int tls1_handshake_digest(SSL *s, unsigned char *out, size_t out_len);
+ int tls1_final_finish_mac(SSL *s,
+ 	const char *str, int slen, unsigned char *p);
+ int tls1_cert_verify_mac(SSL *s, int md_nid, unsigned char *p);
+@@ -1127,6 +1128,7 @@
+ const EVP_MD *tls12_get_hash(unsigned char hash_alg);
+ 
+ int tls1_channel_id_hash(EVP_MD_CTX *ctx, SSL *s);
++int tls1_record_handshake_hashes_for_channel_id(SSL *s);
+ #endif
+ 
+ int ssl3_can_cutthrough(const SSL *s);
+diff -burN android-openssl.orig/ssl/t1_enc.c android-openssl/ssl/t1_enc.c
+--- android-openssl.orig/ssl/t1_enc.c	2014-05-05 16:45:02.697389339 +0200
++++ android-openssl/ssl/t1_enc.c	2014-05-05 16:46:32.545390565 +0200
+@@ -890,53 +890,79 @@
+ 	return((int)ret);
+ 	}
+ 
+-int tls1_final_finish_mac(SSL *s,
+-	     const char *str, int slen, unsigned char *out)
++/* tls1_handshake_digest calculates the current handshake hash and writes it to
++ * |out|, which has space for |out_len| bytes. It returns the number of bytes
++ * written or -1 in the event of an error. This function works on a copy of the
++ * underlying digests so can be called multiple times and prior to the final
++ * update etc. */
++int tls1_handshake_digest(SSL *s, unsigned char *out, size_t out_len)
+ 	{
+-	unsigned int i;
++	const EVP_MD *md;
+ 	EVP_MD_CTX ctx;
+-	unsigned char buf[2*EVP_MAX_MD_SIZE];
+-	unsigned char *q,buf2[12];
+-	int idx;
++	int i, err = 0, len = 0;
+ 	long mask;
+-	int err=0;
+-	const EVP_MD *md; 
+-
+-	q=buf;
+-
+-	if (s->s3->handshake_buffer) 
+-		if (!ssl3_digest_cached_records(s))
+-			return 0;
+ 
+ 	EVP_MD_CTX_init(&ctx);
+ 
+-	for (idx=0;ssl_get_handshake_digest(idx,&mask,&md);idx++)
++	for (i = 0; ssl_get_handshake_digest(i, &mask, &md); i++)
+ 		{
+-		if (mask & ssl_get_algorithm2(s))
+-			{
+-			int hashsize = EVP_MD_size(md);
+-			if (hashsize < 0 || hashsize > (int)(sizeof buf - (size_t)(q-buf)))
++		int hash_size;
++		unsigned int digest_len;
++		EVP_MD_CTX *hdgst = s->s3->handshake_dgst[i];
++
++		if ((mask & ssl_get_algorithm2(s)) == 0)
++			continue;
++
++		hash_size = EVP_MD_size(md);
++		if (!hdgst || hash_size < 0 || (size_t)hash_size > out_len)
+ 				{
+-				/* internal error: 'buf' is too small for this cipersuite! */
+ 				err = 1;
++			break;
+ 				}
+-			else
++
++		if (!EVP_MD_CTX_copy_ex(&ctx, hdgst) ||
++		    !EVP_DigestFinal_ex(&ctx, out, &digest_len) ||
++		    digest_len != (unsigned int)hash_size) /* internal error */
+ 				{
+-				EVP_MD_CTX_copy_ex(&ctx,s->s3->handshake_dgst[idx]);
+-				EVP_DigestFinal_ex(&ctx,q,&i);
+-				if (i != (unsigned int)hashsize) /* can't really happen */
+ 					err = 1;
+-				q+=i;
++			break;
+ 				}
++		out += digest_len;
++		out_len -= digest_len;
++		len += digest_len;
+ 			}
++
++	EVP_MD_CTX_cleanup(&ctx);
++
++	if (err != 0)
++		return -1;
++	return len;
++	}
++
++int tls1_final_finish_mac(SSL *s,
++	     const char *str, int slen, unsigned char *out)
++	{
++	unsigned char buf[2*EVP_MAX_MD_SIZE];
++	unsigned char buf2[12];
++	int err=0;
++	int digests_len;
++
++	if (s->s3->handshake_buffer)
++		if (!ssl3_digest_cached_records(s))
++			return 0;
++
++	digests_len = tls1_handshake_digest(s, buf, sizeof(buf));
++	if (digests_len < 0)
++		{
++		err = 1;
++		digests_len = 0;
+ 		}
+ 		
+ 	if (!tls1_PRF(ssl_get_algorithm2(s),
+-			str,slen, buf,(int)(q-buf), NULL,0, NULL,0, NULL,0,
++			str,slen, buf, digests_len, NULL,0, NULL,0, NULL,0,
+ 			s->session->master_key,s->session->master_key_length,
+ 			out,buf2,sizeof buf2))
+ 		err = 1;
+-	EVP_MD_CTX_cleanup(&ctx);
+ 
+ 	if (err)
+ 		return 0;
+diff -burN android-openssl.orig/ssl/t1_lib.c android-openssl/ssl/t1_lib.c
+--- android-openssl.orig/ssl/t1_lib.c	2014-05-05 16:45:02.789389340 +0200
++++ android-openssl/ssl/t1_lib.c	2014-05-05 16:46:32.549390565 +0200
+@@ -2672,6 +2672,17 @@
+ 
+ 	EVP_DigestUpdate(md, kClientIDMagic, sizeof(kClientIDMagic));
+ 
++	if (s->hit)
++		{
++		static const char kResumptionMagic[] = "Resumption";
++		EVP_DigestUpdate(md, kResumptionMagic,
++				 sizeof(kResumptionMagic));
++		if (s->session->original_handshake_hash_len == 0)
++			return 0;
++		EVP_DigestUpdate(md, s->session->original_handshake_hash,
++				 s->session->original_handshake_hash_len);
++		}
++
+ 	EVP_MD_CTX_init(&ctx);
+ 	for (i = 0; i < SSL_MAX_DIGEST; i++)
+ 		{
+@@ -2686,3 +2697,29 @@
+ 	return 1;
+ 	}
+ #endif
++
++/* tls1_record_handshake_hashes_for_channel_id records the current handshake
++ * hashes in |s->session| so that Channel ID resumptions can sign that data. */
++int tls1_record_handshake_hashes_for_channel_id(SSL *s)
++	{
++	int digest_len;
++	/* This function should never be called for a resumed session because
++	 * the handshake hashes that we wish to record are for the original,
++	 * full handshake. */
++	if (s->hit)
++		return -1;
++	/* It only makes sense to call this function if Channel IDs have been
++	 * negotiated. */
++	if (!s->s3->tlsext_channel_id_valid)
++		return -1;
++
++	digest_len = tls1_handshake_digest(
++		s, s->session->original_handshake_hash,
++		sizeof(s->session->original_handshake_hash));
++	if (digest_len < 0)
++		return -1;
++
++	s->session->original_handshake_hash_len = digest_len;
++
++	return 1;
++	}
+diff -burN android-openssl.orig/ssl/tls1.h android-openssl/ssl/tls1.h
+--- android-openssl.orig/ssl/tls1.h	2014-05-05 16:45:02.697389339 +0200
++++ android-openssl/ssl/tls1.h	2014-05-05 16:46:32.553390566 +0200
+@@ -249,7 +249,7 @@
+ #endif
+ 
+ /* This is not an IANA defined extension number */
+-#define TLSEXT_TYPE_channel_id			30031
++#define TLSEXT_TYPE_channel_id			30032
+ 
+ /* NameType value from RFC 3546 */
+ #define TLSEXT_NAMETYPE_host_name 0