Updating Channel ID to allow computing the key when the server supports it.

The previous API of openssl for channel ID forces the client to set the
private key before knowing if the server supports channel ID. This
updates the API so that the client can set the private key after the
handshake started and the server confirmed it supports the protocol.

R=agl@chromium.org, digit@chromium.org

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

git-svn-id: http://src.chromium.org/svn/trunk/deps/third_party/openssl@230132 4ff67af0-8c30-449e-8e8b-ad334ec8d88c
diff --git a/README.chromium b/README.chromium
index 6e49163..552df66 100644
--- a/README.chromium
+++ b/README.chromium
@@ -180,6 +180,10 @@
     Advertise support of only the NIST curves P-521, P-384, and P-256,
     as well as only uncompressed points, to keep ClientHello small.
 
+  channelid.patch
+    Add API so that channel ID private key can be set only after verifying the
+    remote server supports channel IDs.
+
 **************************************************************************
 Adding new Chromium patches:
 
diff --git a/import_from_android.sh b/import_from_android.sh
index fe40e3e..e7b5f55 100755
--- a/import_from_android.sh
+++ b/import_from_android.sh
@@ -339,7 +339,7 @@
 #
 dump "Saving .svn subdirectories"
 SAVED_SVN_TARBALL=$BUILD_DIR/saved-svn-subdirs.tar.gz
-run tar czf $SAVED_SVN_TARBALL $(find . -type d -name ".svn")
+#run tar czf $SAVED_SVN_TARBALL $(find . -type d -name ".svn")
 
 # Re-run the import_openssl.sh script.
 dump "Re-running the 'import_openssl.sh' script to reconfigure all sources."
@@ -360,7 +360,7 @@
 run rm -rf "$PROGDIR/openssl.old"
 
 dump "Restoring .svn subdirectores"
-run tar xzf $SAVED_SVN_TARBALL
+# run tar xzf $SAVED_SVN_TARBALL
 
 # Extract list of source files or compiler defines from openssl.config
 # variable definition. This assumes that the lists are in variables that
diff --git a/openssl/crypto/bio/bio.h b/openssl/crypto/bio/bio.h
index 05699ab..d05fa22 100644
--- a/openssl/crypto/bio/bio.h
+++ b/openssl/crypto/bio/bio.h
@@ -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 --git a/openssl/include/openssl/bio.h b/openssl/include/openssl/bio.h
index 05699ab..d05fa22 100644
--- a/openssl/include/openssl/bio.h
+++ b/openssl/include/openssl/bio.h
@@ -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 --git a/openssl/include/openssl/ssl.h b/openssl/include/openssl/ssl.h
index 61b110f..4d893a1 100644
--- a/openssl/include/openssl/ssl.h
+++ b/openssl/include/openssl/ssl.h
@@ -1104,12 +1104,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 +1537,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 +1675,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 --git a/openssl/ssl/bio_ssl.c b/openssl/ssl/bio_ssl.c
index e9552ca..06a13de 100644
--- a/openssl/ssl/bio_ssl.c
+++ b/openssl/ssl/bio_ssl.c
@@ -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 --git a/openssl/ssl/s3_clnt.c b/openssl/ssl/s3_clnt.c
index 1d40a2e..edbf6d0 100644
--- a/openssl/ssl/s3_clnt.c
+++ b/openssl/ssl/s3_clnt.c
@@ -3414,6 +3414,13 @@
 	if (s->state != SSL3_ST_CW_CHANNEL_ID_A)
 		return ssl3_do_write(s, SSL3_RT_HANDSHAKE);
 
+        if (s->tlsext_channel_id_private == NULL)
+            {
+                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 --git a/openssl/ssl/s3_lib.c b/openssl/ssl/s3_lib.c
index 0be87e8..a71d05a 100644
--- a/openssl/ssl/s3_lib.c
+++ b/openssl/ssl/s3_lib.c
@@ -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 --git a/openssl/ssl/ssl.h b/openssl/ssl/ssl.h
index 61b110f..4d893a1 100644
--- a/openssl/ssl/ssl.h
+++ b/openssl/ssl/ssl.h
@@ -1104,12 +1104,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 +1537,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 +1675,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 --git a/openssl/ssl/ssl_lib.c b/openssl/ssl/ssl_lib.c
index 65b2ef8..92e2cf3 100644
--- a/openssl/ssl/ssl_lib.c
+++ b/openssl/ssl/ssl_lib.c
@@ -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 --git a/patches.chromium/channelid.patch b/patches.chromium/channelid.patch
new file mode 100644
index 0000000..0c761c6
--- /dev/null
+++ b/patches.chromium/channelid.patch
@@ -0,0 +1,196 @@
+diff -burN android-openssl.orig/crypto/bio/bio.h android-openssl/crypto/bio/bio.h
+--- android-openssl.orig/crypto/bio/bio.h	2013-10-18 16:41:41.052291400 +0200
++++ android-openssl/crypto/bio/bio.h	2013-10-18 16:42:58.772982447 +0200
+@@ -266,6 +266,8 @@
+ #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-18 16:41:41.162292378 +0200
++++ android-openssl/include/openssl/bio.h	2013-10-18 16:42:58.772982447 +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-18 16:41:41.252293178 +0200
++++ android-openssl/include/openssl/ssl.h	2013-10-18 16:42:58.772982447 +0200
+@@ -1104,12 +1104,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 +1537,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 +1675,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-10-18 16:41:41.172292466 +0200
++++ android-openssl/ssl/bio_ssl.c	2013-10-18 16:42:58.772982447 +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-18 16:41:41.262293266 +0200
++++ android-openssl/ssl/s3_clnt.c	2013-10-18 16:42:58.772982447 +0200
+@@ -3414,6 +3414,13 @@
+ 	if (s->state != SSL3_ST_CW_CHANNEL_ID_A)
+ 		return ssl3_do_write(s, SSL3_RT_HANDSHAKE);
+ 
++        if (s->tlsext_channel_id_private == NULL)
++            {
++                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-18 16:41:41.262293266 +0200
++++ android-openssl/ssl/s3_lib.c	2013-10-18 16:42:58.772982447 +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-18 16:41:41.262293266 +0200
++++ android-openssl/ssl/ssl.h	2013-10-18 16:42:58.772982447 +0200
+@@ -1104,12 +1104,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 +1537,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 +1675,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-18 16:41:41.262293266 +0200
++++ android-openssl/ssl/ssl_lib.c	2013-10-18 16:42:58.772982447 +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)
+ 		{