diff -urN android-openssl.orig/openssl.config android-openssl/openssl.config
--- android-openssl.orig/openssl.config	2013-10-28 13:39:11.618121779 -0400
+++ android-openssl/openssl.config	2013-10-28 14:40:32.642178484 -0400
@@ -992,6 +992,7 @@
 handshake_cutthrough.patch \
 jsse.patch \
 channelid.patch \
+channelidchromium.patch \
 eng_dyn_dirs.patch \
 fix_clang_build.patch \
 x509_hash_name_algorithm_change.patch \
diff -urN android-openssl.orig/patches/channelidchromium.patch android-openssl/patches/channelidchromium.patch
--- android-openssl.orig/patches/channelidchromium.patch	1969-12-31 19:00:00.000000000 -0500
+++ android-openssl/patches/channelidchromium.patch	2013-10-28 14:34:42.945588394 -0400
@@ -0,0 +1,264 @@
+diff -burN android-openssl.orig/crypto/bio/bio.h android-openssl/crypto/bio/bio.h
+--- android-openssl.orig/crypto/bio/bio.h	2013-02-11 16:26:04.000000000 +0100
++++ android-openssl/crypto/bio/bio.h	2013-10-22 18:22:42.080337200 +0200
+@@ -266,6 +266,9 @@
+ #define BIO_RR_CONNECT			0x02
+ /* Returned from the accept BIO when an accept would have blocked */
+ #define BIO_RR_ACCEPT			0x03
++/* Returned from the SSL bio when the channel id retrieval code cannot find the
++ * private key. */
++#define BIO_RR_SSL_CHANNEL_ID_LOOKUP	0x04
+ 
+ /* These are passed by the BIO callback */
+ #define BIO_CB_FREE	0x01
+diff -burN android-openssl.orig/include/openssl/bio.h android-openssl/include/openssl/bio.h
+--- android-openssl.orig/include/openssl/bio.h	2013-10-22 18:20:42.249270230 +0200
++++ android-openssl/include/openssl/bio.h	2013-10-22 18:22:42.080337200 +0200
+@@ -266,6 +266,9 @@
+ #define BIO_RR_CONNECT			0x02
+ /* Returned from the accept BIO when an accept would have blocked */
+ #define BIO_RR_ACCEPT			0x03
++/* Returned from the SSL bio when the channel id retrieval code cannot find the
++ * private key. */
++#define BIO_RR_SSL_CHANNEL_ID_LOOKUP	0x04
+ 
+ /* These are passed by the BIO callback */
+ #define BIO_CB_FREE	0x01
+diff -burN android-openssl.orig/include/openssl/ssl.h android-openssl/include/openssl/ssl.h
+--- android-openssl.orig/include/openssl/ssl.h	2013-10-22 18:20:42.259270320 +0200
++++ android-openssl/include/openssl/ssl.h	2013-10-22 18:24:14.771162612 +0200
+@@ -848,6 +848,9 @@
+ 	/* get client cert callback */
+ 	int (*client_cert_cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey);
+ 
++	/* get channel id callback */
++	void (*channel_id_cb)(SSL *ssl, EVP_PKEY **pkey);
++
+     /* cookie generate callback */
+     int (*app_gen_cookie_cb)(SSL *ssl, unsigned char *cookie, 
+         unsigned int *cookie_len);
+@@ -1043,6 +1046,8 @@
+ void (*SSL_CTX_get_info_callback(SSL_CTX *ctx))(const SSL *ssl,int type,int val);
+ void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx, int (*client_cert_cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey));
+ int (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx))(SSL *ssl, X509 **x509, EVP_PKEY **pkey);
++void SSL_CTX_set_channel_id_cb(SSL_CTX *ctx, void (*channel_id_cb)(SSL *ssl, EVP_PKEY **pkey));
++void (*SSL_CTX_get_channel_id_cb(SSL_CTX *ctx))(SSL *ssl, EVP_PKEY **pkey);
+ #ifndef OPENSSL_NO_ENGINE
+ int SSL_CTX_set_client_cert_engine(SSL_CTX *ctx, ENGINE *e);
+ #endif
+@@ -1104,12 +1109,14 @@
+ #define SSL_WRITING	2
+ #define SSL_READING	3
+ #define SSL_X509_LOOKUP	4
++#define SSL_CHANNEL_ID_LOOKUP	5
+ 
+ /* These will only be used when doing non-blocking IO */
+ #define SSL_want_nothing(s)	(SSL_want(s) == SSL_NOTHING)
+ #define SSL_want_read(s)	(SSL_want(s) == SSL_READING)
+ #define SSL_want_write(s)	(SSL_want(s) == SSL_WRITING)
+ #define SSL_want_x509_lookup(s)	(SSL_want(s) == SSL_X509_LOOKUP)
++#define SSL_want_channel_id_lookup(s)	(SSL_want(s) == SSL_CHANNEL_ID_LOOKUP)
+ 
+ #define SSL_MAC_FLAG_READ_MAC_STREAM 1
+ #define SSL_MAC_FLAG_WRITE_MAC_STREAM 2
+@@ -1535,6 +1542,7 @@
+ #define SSL_ERROR_ZERO_RETURN		6
+ #define SSL_ERROR_WANT_CONNECT		7
+ #define SSL_ERROR_WANT_ACCEPT		8
++#define SSL_ERROR_WANT_CHANNEL_ID_LOOKUP	9
+ 
+ #define SSL_CTRL_NEED_TMP_RSA			1
+ #define SSL_CTRL_SET_TMP_RSA			2
+@@ -1672,10 +1680,11 @@
+ #define SSL_set_tmp_ecdh(ssl,ecdh) \
+ 	SSL_ctrl(ssl,SSL_CTRL_SET_TMP_ECDH,0,(char *)ecdh)
+ 
+-/* SSL_enable_tls_channel_id configures a TLS server to accept TLS client
+- * IDs from clients. Returns 1 on success. */
+-#define SSL_enable_tls_channel_id(ctx) \
+-	SSL_ctrl(ctx,SSL_CTRL_CHANNEL_ID,0,NULL)
++/* SSL_enable_tls_channel_id either configures a TLS server to accept TLS client
++ * IDs from clients, or configure a client to send TLS client IDs to server.
++ * Returns 1 on success. */
++#define SSL_enable_tls_channel_id(s) \
++	SSL_ctrl(s,SSL_CTRL_CHANNEL_ID,0,NULL)
+ /* SSL_set1_tls_channel_id configures a TLS client to send a TLS Channel ID to
+  * compatible servers. private_key must be a P-256 EVP_PKEY*. Returns 1 on
+  * success. */
+diff -burN android-openssl.orig/ssl/bio_ssl.c android-openssl/ssl/bio_ssl.c
+--- android-openssl.orig/ssl/bio_ssl.c	2013-02-11 16:26:04.000000000 +0100
++++ android-openssl/ssl/bio_ssl.c	2013-10-22 18:22:42.090337290 +0200
+@@ -206,6 +206,10 @@
+ 		BIO_set_retry_special(b);
+ 		retry_reason=BIO_RR_SSL_X509_LOOKUP;
+ 		break;
++	case SSL_ERROR_WANT_CHANNEL_ID_LOOKUP:
++		BIO_set_retry_special(b);
++		retry_reason=BIO_RR_SSL_CHANNEL_ID_LOOKUP;
++		break;
+ 	case SSL_ERROR_WANT_ACCEPT:
+ 		BIO_set_retry_special(b);
+ 		retry_reason=BIO_RR_ACCEPT;
+@@ -280,6 +284,10 @@
+ 		BIO_set_retry_special(b);
+ 		retry_reason=BIO_RR_SSL_X509_LOOKUP;
+ 		break;
++	case SSL_ERROR_WANT_CHANNEL_ID_LOOKUP:
++		BIO_set_retry_special(b);
++		retry_reason=BIO_RR_SSL_CHANNEL_ID_LOOKUP;
++		break;
+ 	case SSL_ERROR_WANT_CONNECT:
+ 		BIO_set_retry_special(b);
+ 		retry_reason=BIO_RR_CONNECT;
+diff -burN android-openssl.orig/ssl/s3_clnt.c android-openssl/ssl/s3_clnt.c
+--- android-openssl.orig/ssl/s3_clnt.c	2013-10-22 18:20:40.289252781 +0200
++++ android-openssl/ssl/s3_clnt.c	2013-10-22 18:22:42.090337290 +0200
+@@ -3414,6 +3414,22 @@
+ 	if (s->state != SSL3_ST_CW_CHANNEL_ID_A)
+ 		return ssl3_do_write(s, SSL3_RT_HANDSHAKE);
+ 
++	if (!s->tlsext_channel_id_private && s->ctx->channel_id_cb)
++		{
++		EVP_PKEY *key = NULL;
++		s->ctx->channel_id_cb(s, &key);
++		if (key != NULL)
++			{
++			s->tlsext_channel_id_private = key;
++			}
++		}
++	if (!s->tlsext_channel_id_private)
++		{
++		s->rwstate=SSL_CHANNEL_ID_LOOKUP;
++		return (-1);
++		}
++	s->rwstate=SSL_NOTHING;
++
+ 	d = (unsigned char *)s->init_buf->data;
+ 	*(d++)=SSL3_MT_ENCRYPTED_EXTENSIONS;
+ 	l2n3(2 + 2 + TLSEXT_CHANNEL_ID_SIZE, d);
+diff -burN android-openssl.orig/ssl/s3_lib.c android-openssl/ssl/s3_lib.c
+--- android-openssl.orig/ssl/s3_lib.c	2013-10-22 18:20:40.289252781 +0200
++++ android-openssl/ssl/s3_lib.c	2013-10-22 18:22:42.090337290 +0200
+@@ -3358,8 +3358,6 @@
+ 		break;
+ #endif
+ 	case SSL_CTRL_CHANNEL_ID:
+-		if (!s->server)
+-			break;
+ 		s->tlsext_channel_id_enabled = 1;
+ 		ret = 1;
+ 		break;
+@@ -3375,7 +3373,7 @@
+ 			}
+ 		if (s->tlsext_channel_id_private)
+ 			EVP_PKEY_free(s->tlsext_channel_id_private);
+-		s->tlsext_channel_id_private = (EVP_PKEY*) parg;
++		s->tlsext_channel_id_private = EVP_PKEY_dup((EVP_PKEY*) parg);
+ 		ret = 1;
+ 		break;
+ 
+@@ -3690,7 +3688,7 @@
+ 			}
+ 		if (ctx->tlsext_channel_id_private)
+ 			EVP_PKEY_free(ctx->tlsext_channel_id_private);
+-		ctx->tlsext_channel_id_private = (EVP_PKEY*) parg;
++		ctx->tlsext_channel_id_private = EVP_PKEY_dup((EVP_PKEY*) parg);
+ 		break;
+ 
+ 	default:
+diff -burN android-openssl.orig/ssl/ssl.h android-openssl/ssl/ssl.h
+--- android-openssl.orig/ssl/ssl.h	2013-10-22 18:20:40.299252871 +0200
++++ android-openssl/ssl/ssl.h	2013-10-22 18:24:24.121245879 +0200
+@@ -848,6 +848,9 @@
+ 	/* get client cert callback */
+ 	int (*client_cert_cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey);
+ 
++	/* get channel id callback */
++	void (*channel_id_cb)(SSL *ssl, EVP_PKEY **pkey);
++
+     /* cookie generate callback */
+     int (*app_gen_cookie_cb)(SSL *ssl, unsigned char *cookie, 
+         unsigned int *cookie_len);
+@@ -1043,6 +1046,8 @@
+ void (*SSL_CTX_get_info_callback(SSL_CTX *ctx))(const SSL *ssl,int type,int val);
+ void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx, int (*client_cert_cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey));
+ int (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx))(SSL *ssl, X509 **x509, EVP_PKEY **pkey);
++void SSL_CTX_set_channel_id_cb(SSL_CTX *ctx, void (*channel_id_cb)(SSL *ssl, EVP_PKEY **pkey));
++void (*SSL_CTX_get_channel_id_cb(SSL_CTX *ctx))(SSL *ssl, EVP_PKEY **pkey);
+ #ifndef OPENSSL_NO_ENGINE
+ int SSL_CTX_set_client_cert_engine(SSL_CTX *ctx, ENGINE *e);
+ #endif
+@@ -1104,12 +1109,14 @@
+ #define SSL_WRITING	2
+ #define SSL_READING	3
+ #define SSL_X509_LOOKUP	4
++#define SSL_CHANNEL_ID_LOOKUP	5
+ 
+ /* These will only be used when doing non-blocking IO */
+ #define SSL_want_nothing(s)	(SSL_want(s) == SSL_NOTHING)
+ #define SSL_want_read(s)	(SSL_want(s) == SSL_READING)
+ #define SSL_want_write(s)	(SSL_want(s) == SSL_WRITING)
+ #define SSL_want_x509_lookup(s)	(SSL_want(s) == SSL_X509_LOOKUP)
++#define SSL_want_channel_id_lookup(s)	(SSL_want(s) == SSL_CHANNEL_ID_LOOKUP)
+ 
+ #define SSL_MAC_FLAG_READ_MAC_STREAM 1
+ #define SSL_MAC_FLAG_WRITE_MAC_STREAM 2
+@@ -1535,6 +1542,7 @@
+ #define SSL_ERROR_ZERO_RETURN		6
+ #define SSL_ERROR_WANT_CONNECT		7
+ #define SSL_ERROR_WANT_ACCEPT		8
++#define SSL_ERROR_WANT_CHANNEL_ID_LOOKUP	9
+ 
+ #define SSL_CTRL_NEED_TMP_RSA			1
+ #define SSL_CTRL_SET_TMP_RSA			2
+@@ -1672,10 +1680,11 @@
+ #define SSL_set_tmp_ecdh(ssl,ecdh) \
+ 	SSL_ctrl(ssl,SSL_CTRL_SET_TMP_ECDH,0,(char *)ecdh)
+ 
+-/* SSL_enable_tls_channel_id configures a TLS server to accept TLS client
+- * IDs from clients. Returns 1 on success. */
+-#define SSL_enable_tls_channel_id(ctx) \
+-	SSL_ctrl(ctx,SSL_CTRL_CHANNEL_ID,0,NULL)
++/* SSL_enable_tls_channel_id either configures a TLS server to accept TLS client
++ * IDs from clients, or configure a client to send TLS client IDs to server.
++ * Returns 1 on success. */
++#define SSL_enable_tls_channel_id(s) \
++	SSL_ctrl(s,SSL_CTRL_CHANNEL_ID,0,NULL)
+ /* SSL_set1_tls_channel_id configures a TLS client to send a TLS Channel ID to
+  * compatible servers. private_key must be a P-256 EVP_PKEY*. Returns 1 on
+  * success. */
+diff -burN android-openssl.orig/ssl/ssl_lib.c android-openssl/ssl/ssl_lib.c
+--- android-openssl.orig/ssl/ssl_lib.c	2013-10-22 18:20:40.299252871 +0200
++++ android-openssl/ssl/ssl_lib.c	2013-10-22 18:22:42.090337290 +0200
+@@ -2561,6 +2561,10 @@
+ 		{
+ 		return(SSL_ERROR_WANT_X509_LOOKUP);
+ 		}
++	if ((i < 0) && SSL_want_channel_id_lookup(s))
++		{
++		return(SSL_ERROR_WANT_CHANNEL_ID_LOOKUP);
++		}
+ 
+ 	if (i == 0)
+ 		{
+diff -burN android-openssl.orig/ssl/ssl_sess.c android-openssl/ssl/ssl_sess.c
+--- android-openssl.orig/ssl/ssl_sess.c	2013-10-22 18:20:40.289252781 +0200
++++ android-openssl/ssl/ssl_sess.c	2013-10-22 18:22:42.090337290 +0200
+@@ -1132,6 +1132,17 @@
+ 	return ctx->client_cert_cb;
+ 	}
+ 
++void SSL_CTX_set_channel_id_cb(SSL_CTX *ctx,
++	void (*cb)(SSL *ssl, EVP_PKEY **pkey))
++	{
++	ctx->channel_id_cb=cb;
++	}
++
++void (*SSL_CTX_get_channel_id_cb(SSL_CTX *ctx))(SSL * ssl, EVP_PKEY **pkey)
++	{
++	return ctx->channel_id_cb;
++	}
++
+ #ifndef OPENSSL_NO_ENGINE
+ int SSL_CTX_set_client_cert_engine(SSL_CTX *ctx, ENGINE *e)
+ 	{