summaryrefslogtreecommitdiffstats
path: root/net/third_party
diff options
context:
space:
mode:
authoragl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-11-18 22:00:04 +0000
committeragl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-11-18 22:00:04 +0000
commit2b0dbd272de36d95c7cd0890a5b3f391f7a13970 (patch)
tree6abd8f6620444bbe7654ec8ee0990f24d5d0000f /net/third_party
parentc19b6a6365a680222f73edfd57b1fd40cba97409 (diff)
downloadchromium_src-2b0dbd272de36d95c7cd0890a5b3f391f7a13970.zip
chromium_src-2b0dbd272de36d95c7cd0890a5b3f391f7a13970.tar.gz
chromium_src-2b0dbd272de36d95c7cd0890a5b3f391f7a13970.tar.bz2
Support new ChannelID extension.
This change switches over to use the new-style ChannelID extension. BUG=305951 Review URL: https://codereview.chromium.org/27589002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@235826 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/third_party')
-rw-r--r--net/third_party/nss/README.chromium1
-rwxr-xr-xnet/third_party/nss/patches/applypatches.sh2
-rw-r--r--net/third_party/nss/patches/channelid2.patch156
-rw-r--r--net/third_party/nss/ssl/ssl3con.c58
-rw-r--r--net/third_party/nss/ssl/ssl3ext.c10
-rw-r--r--net/third_party/nss/ssl/sslimpl.h8
-rw-r--r--net/third_party/nss/ssl/sslnonce.c3
-rw-r--r--net/third_party/nss/ssl/sslt.h2
8 files changed, 233 insertions, 7 deletions
diff --git a/net/third_party/nss/README.chromium b/net/third_party/nss/README.chromium
index ab2d0b03..088252a 100644
--- a/net/third_party/nss/README.chromium
+++ b/net/third_party/nss/README.chromium
@@ -57,6 +57,7 @@ Patches:
* Add support for TLS Channel IDs
patches/channelid.patch
+ patches/channelid2.patch
* Add support for extracting the tls-unique channel binding value
patches/tlsunique.patch
diff --git a/net/third_party/nss/patches/applypatches.sh b/net/third_party/nss/patches/applypatches.sh
index 5bdc670..ca05c92 100755
--- a/net/third_party/nss/patches/applypatches.sh
+++ b/net/third_party/nss/patches/applypatches.sh
@@ -69,3 +69,5 @@ patch -p4 < $patches_dir/nullcipher_934016.patch
patch -p4 < $patches_dir/paddingextension.patch
patch -p4 < $patches_dir/paddingextensionall.patch
+
+patch -p4 < $patches_dir/channelid2.patch
diff --git a/net/third_party/nss/patches/channelid2.patch b/net/third_party/nss/patches/channelid2.patch
new file mode 100644
index 0000000..011db87
--- /dev/null
+++ b/net/third_party/nss/patches/channelid2.patch
@@ -0,0 +1,156 @@
+diff --git a/nss/lib/ssl/ssl3con.c b/nss/lib/ssl/ssl3con.c
+index 882e356..396c408 100644
+--- a/nss/lib/ssl/ssl3con.c
++++ b/nss/lib/ssl/ssl3con.c
+@@ -7594,6 +7594,33 @@ ssl3_SendClientSecondRound(sslSocket *ss)
+
+ ssl_ReleaseXmitBufLock(ss); /*******************************/
+
++ if (!ss->ssl3.hs.isResuming &&
++ ssl3_ExtensionNegotiated(ss, ssl_channel_id_xtn)) {
++ /* If we are negotiating ChannelID on a full handshake then we record
++ * the handshake hashes in |sid| at this point. They will be needed in
++ * the event that we resume this session and use ChannelID on the
++ * resumption handshake. */
++ SSL3Hashes hashes;
++ SECItem *originalHandshakeHash =
++ &ss->sec.ci.sid->u.ssl3.originalHandshakeHash;
++ PORT_Assert(ss->sec.ci.sid->cached == never_cached);
++
++ ssl_GetSpecReadLock(ss);
++ PORT_Assert(ss->version > SSL_LIBRARY_VERSION_3_0);
++ rv = ssl3_ComputeHandshakeHashes(ss, ss->ssl3.cwSpec, &hashes, 0);
++ ssl_ReleaseSpecReadLock(ss);
++ if (rv != SECSuccess) {
++ return rv;
++ }
++
++ PORT_Assert(originalHandshakeHash->len == 0);
++ originalHandshakeHash->data = PORT_Alloc(hashes.len);
++ if (!originalHandshakeHash->data)
++ return SECFailure;
++ originalHandshakeHash->len = hashes.len;
++ memcpy(originalHandshakeHash->data, hashes.u.raw, hashes.len);
++ }
++
+ if (ssl3_ExtensionNegotiated(ss, ssl_session_ticket_xtn))
+ ss->ssl3.hs.ws = wait_new_session_ticket;
+ else
+@@ -10590,6 +10617,7 @@ static SECStatus
+ ssl3_SendEncryptedExtensions(sslSocket *ss)
+ {
+ static const char CHANNEL_ID_MAGIC[] = "TLS Channel ID signature";
++ static const char CHANNEL_ID_RESUMPTION_MAGIC[] = "Resumption";
+ /* This is the ASN.1 prefix for a P-256 public key. Specifically it's:
+ * SEQUENCE
+ * SEQUENCE
+@@ -10615,7 +10643,10 @@ ssl3_SendEncryptedExtensions(sslSocket *ss)
+ SECItem *spki = NULL;
+ SSL3Hashes hashes;
+ const unsigned char *pub_bytes;
+- unsigned char signed_data[sizeof(CHANNEL_ID_MAGIC) + sizeof(SSL3Hashes)];
++ unsigned char signed_data[sizeof(CHANNEL_ID_MAGIC) +
++ sizeof(CHANNEL_ID_RESUMPTION_MAGIC) +
++ sizeof(SSL3Hashes)*2];
++ size_t signed_data_len;
+ unsigned char digest[SHA256_LENGTH];
+ SECItem digest_item;
+ unsigned char signature[64];
+@@ -10665,11 +10696,26 @@ ssl3_SendEncryptedExtensions(sslSocket *ss)
+
+ pub_bytes = spki->data + sizeof(P256_SPKI_PREFIX);
+
+- memcpy(signed_data, CHANNEL_ID_MAGIC, sizeof(CHANNEL_ID_MAGIC));
+- memcpy(signed_data + sizeof(CHANNEL_ID_MAGIC), hashes.u.raw, hashes.len);
++ signed_data_len = 0;
++ memcpy(signed_data + signed_data_len, CHANNEL_ID_MAGIC,
++ sizeof(CHANNEL_ID_MAGIC));
++ signed_data_len += sizeof(CHANNEL_ID_MAGIC);
++ if (ss->ssl3.hs.isResuming) {
++ SECItem *originalHandshakeHash =
++ &ss->sec.ci.sid->u.ssl3.originalHandshakeHash;
++ PORT_Assert(originalHandshakeHash->len > 0);
+
+- rv = PK11_HashBuf(SEC_OID_SHA256, digest, signed_data,
+- sizeof(CHANNEL_ID_MAGIC) + hashes.len);
++ memcpy(signed_data + signed_data_len, CHANNEL_ID_RESUMPTION_MAGIC,
++ sizeof(CHANNEL_ID_RESUMPTION_MAGIC));
++ signed_data_len += sizeof(CHANNEL_ID_RESUMPTION_MAGIC);
++ memcpy(signed_data + signed_data_len, originalHandshakeHash->data,
++ originalHandshakeHash->len);
++ signed_data_len += originalHandshakeHash->len;
++ }
++ memcpy(signed_data + signed_data_len, hashes.u.raw, hashes.len);
++ signed_data_len += hashes.len;
++
++ rv = PK11_HashBuf(SEC_OID_SHA256, digest, signed_data, signed_data_len);
+ if (rv != SECSuccess)
+ goto loser;
+
+diff --git a/nss/lib/ssl/ssl3ext.c b/nss/lib/ssl/ssl3ext.c
+index 03cf05c..166022c 100644
+--- a/nss/lib/ssl/ssl3ext.c
++++ b/nss/lib/ssl/ssl3ext.c
+@@ -812,6 +812,16 @@ ssl3_ClientSendChannelIDXtn(sslSocket * ss, PRBool append,
+ return 0;
+ }
+
++ if (ss->ssl3.hs.isResuming &&
++ ss->sec.ci.sid->u.ssl3.originalHandshakeHash.len == 0) {
++ /* We can't do ChannelID on a connection if we're resuming and didn't
++ * do ChannelID on the original connection: without ChannelID on the
++ * original connection we didn't record the handshake hashes needed for
++ * the signature. */
++ PORT_Assert(0);
++ return 0;
++ }
++
+ if (append) {
+ SECStatus rv;
+ rv = ssl3_AppendHandshakeNumber(ss, ssl_channel_id_xtn, 2);
+diff --git a/nss/lib/ssl/sslimpl.h b/nss/lib/ssl/sslimpl.h
+index 9c789bf..ca68727 100644
+--- a/nss/lib/ssl/sslimpl.h
++++ b/nss/lib/ssl/sslimpl.h
+@@ -705,6 +705,14 @@ struct sslSessionIDStr {
+ */
+ NewSessionTicket sessionTicket;
+ SECItem srvName;
++
++ /* originalHandshakeHash contains the hash of the original, full
++ * handshake prior to the server's final flow. This is either a
++ * SHA-1/MD5 combination (for TLS < 1.2) or the TLS PRF hash (for
++ * TLS 1.2). This is recorded and used only when ChannelID is
++ * negotiated as it's used to bind the ChannelID signature on the
++ * resumption handshake to the original handshake. */
++ SECItem originalHandshakeHash;
+ } ssl3;
+ } u;
+ };
+diff --git a/nss/lib/ssl/sslnonce.c b/nss/lib/ssl/sslnonce.c
+index a6f7349..eb5004c 100644
+--- a/nss/lib/ssl/sslnonce.c
++++ b/nss/lib/ssl/sslnonce.c
+@@ -148,6 +148,9 @@ ssl_DestroySID(sslSessionID *sid)
+ if (sid->u.ssl3.srvName.data) {
+ SECITEM_FreeItem(&sid->u.ssl3.srvName, PR_FALSE);
+ }
++ if (sid->u.ssl3.originalHandshakeHash.data) {
++ SECITEM_FreeItem(&sid->u.ssl3.originalHandshakeHash, PR_FALSE);
++ }
+
+ PORT_ZFree(sid, sizeof(sslSessionID));
+ }
+diff --git a/nss/lib/ssl/sslt.h b/nss/lib/ssl/sslt.h
+index e4d188f..b813c04 100644
+--- a/nss/lib/ssl/sslt.h
++++ b/nss/lib/ssl/sslt.h
+@@ -204,7 +204,7 @@ typedef enum {
+ ssl_app_layer_protocol_xtn = 16,
+ ssl_session_ticket_xtn = 35,
+ ssl_next_proto_nego_xtn = 13172,
+- ssl_channel_id_xtn = 30031,
++ ssl_channel_id_xtn = 30032,
+ ssl_padding_xtn = 35655,
+ ssl_renegotiation_info_xtn = 0xff01 /* experimental number */
+ } SSLExtensionType;
diff --git a/net/third_party/nss/ssl/ssl3con.c b/net/third_party/nss/ssl/ssl3con.c
index 882e356..396c408 100644
--- a/net/third_party/nss/ssl/ssl3con.c
+++ b/net/third_party/nss/ssl/ssl3con.c
@@ -7594,6 +7594,33 @@ ssl3_SendClientSecondRound(sslSocket *ss)
ssl_ReleaseXmitBufLock(ss); /*******************************/
+ if (!ss->ssl3.hs.isResuming &&
+ ssl3_ExtensionNegotiated(ss, ssl_channel_id_xtn)) {
+ /* If we are negotiating ChannelID on a full handshake then we record
+ * the handshake hashes in |sid| at this point. They will be needed in
+ * the event that we resume this session and use ChannelID on the
+ * resumption handshake. */
+ SSL3Hashes hashes;
+ SECItem *originalHandshakeHash =
+ &ss->sec.ci.sid->u.ssl3.originalHandshakeHash;
+ PORT_Assert(ss->sec.ci.sid->cached == never_cached);
+
+ ssl_GetSpecReadLock(ss);
+ PORT_Assert(ss->version > SSL_LIBRARY_VERSION_3_0);
+ rv = ssl3_ComputeHandshakeHashes(ss, ss->ssl3.cwSpec, &hashes, 0);
+ ssl_ReleaseSpecReadLock(ss);
+ if (rv != SECSuccess) {
+ return rv;
+ }
+
+ PORT_Assert(originalHandshakeHash->len == 0);
+ originalHandshakeHash->data = PORT_Alloc(hashes.len);
+ if (!originalHandshakeHash->data)
+ return SECFailure;
+ originalHandshakeHash->len = hashes.len;
+ memcpy(originalHandshakeHash->data, hashes.u.raw, hashes.len);
+ }
+
if (ssl3_ExtensionNegotiated(ss, ssl_session_ticket_xtn))
ss->ssl3.hs.ws = wait_new_session_ticket;
else
@@ -10590,6 +10617,7 @@ static SECStatus
ssl3_SendEncryptedExtensions(sslSocket *ss)
{
static const char CHANNEL_ID_MAGIC[] = "TLS Channel ID signature";
+ static const char CHANNEL_ID_RESUMPTION_MAGIC[] = "Resumption";
/* This is the ASN.1 prefix for a P-256 public key. Specifically it's:
* SEQUENCE
* SEQUENCE
@@ -10615,7 +10643,10 @@ ssl3_SendEncryptedExtensions(sslSocket *ss)
SECItem *spki = NULL;
SSL3Hashes hashes;
const unsigned char *pub_bytes;
- unsigned char signed_data[sizeof(CHANNEL_ID_MAGIC) + sizeof(SSL3Hashes)];
+ unsigned char signed_data[sizeof(CHANNEL_ID_MAGIC) +
+ sizeof(CHANNEL_ID_RESUMPTION_MAGIC) +
+ sizeof(SSL3Hashes)*2];
+ size_t signed_data_len;
unsigned char digest[SHA256_LENGTH];
SECItem digest_item;
unsigned char signature[64];
@@ -10665,11 +10696,26 @@ ssl3_SendEncryptedExtensions(sslSocket *ss)
pub_bytes = spki->data + sizeof(P256_SPKI_PREFIX);
- memcpy(signed_data, CHANNEL_ID_MAGIC, sizeof(CHANNEL_ID_MAGIC));
- memcpy(signed_data + sizeof(CHANNEL_ID_MAGIC), hashes.u.raw, hashes.len);
-
- rv = PK11_HashBuf(SEC_OID_SHA256, digest, signed_data,
- sizeof(CHANNEL_ID_MAGIC) + hashes.len);
+ signed_data_len = 0;
+ memcpy(signed_data + signed_data_len, CHANNEL_ID_MAGIC,
+ sizeof(CHANNEL_ID_MAGIC));
+ signed_data_len += sizeof(CHANNEL_ID_MAGIC);
+ if (ss->ssl3.hs.isResuming) {
+ SECItem *originalHandshakeHash =
+ &ss->sec.ci.sid->u.ssl3.originalHandshakeHash;
+ PORT_Assert(originalHandshakeHash->len > 0);
+
+ memcpy(signed_data + signed_data_len, CHANNEL_ID_RESUMPTION_MAGIC,
+ sizeof(CHANNEL_ID_RESUMPTION_MAGIC));
+ signed_data_len += sizeof(CHANNEL_ID_RESUMPTION_MAGIC);
+ memcpy(signed_data + signed_data_len, originalHandshakeHash->data,
+ originalHandshakeHash->len);
+ signed_data_len += originalHandshakeHash->len;
+ }
+ memcpy(signed_data + signed_data_len, hashes.u.raw, hashes.len);
+ signed_data_len += hashes.len;
+
+ rv = PK11_HashBuf(SEC_OID_SHA256, digest, signed_data, signed_data_len);
if (rv != SECSuccess)
goto loser;
diff --git a/net/third_party/nss/ssl/ssl3ext.c b/net/third_party/nss/ssl/ssl3ext.c
index 03cf05c..adb81ed 100644
--- a/net/third_party/nss/ssl/ssl3ext.c
+++ b/net/third_party/nss/ssl/ssl3ext.c
@@ -812,6 +812,16 @@ ssl3_ClientSendChannelIDXtn(sslSocket * ss, PRBool append,
return 0;
}
+ if (ss->ssl3.hs.isResuming &&
+ ss->sec.ci.sid->u.ssl3.originalHandshakeHash.len == 0) {
+ /* We can't do ChannelID on a connection if we're resuming and didn't
+ * do ChannelID on the original connection: without ChannelID on the
+ * original connection we didn't record the handshake hashes needed for
+ * the signature. */
+ PORT_Assert(0);
+ return 0;
+ }
+
if (append) {
SECStatus rv;
rv = ssl3_AppendHandshakeNumber(ss, ssl_channel_id_xtn, 2);
diff --git a/net/third_party/nss/ssl/sslimpl.h b/net/third_party/nss/ssl/sslimpl.h
index 9c789bf..ca68727 100644
--- a/net/third_party/nss/ssl/sslimpl.h
+++ b/net/third_party/nss/ssl/sslimpl.h
@@ -705,6 +705,14 @@ struct sslSessionIDStr {
*/
NewSessionTicket sessionTicket;
SECItem srvName;
+
+ /* originalHandshakeHash contains the hash of the original, full
+ * handshake prior to the server's final flow. This is either a
+ * SHA-1/MD5 combination (for TLS < 1.2) or the TLS PRF hash (for
+ * TLS 1.2). This is recorded and used only when ChannelID is
+ * negotiated as it's used to bind the ChannelID signature on the
+ * resumption handshake to the original handshake. */
+ SECItem originalHandshakeHash;
} ssl3;
} u;
};
diff --git a/net/third_party/nss/ssl/sslnonce.c b/net/third_party/nss/ssl/sslnonce.c
index a6f7349..eb5004c 100644
--- a/net/third_party/nss/ssl/sslnonce.c
+++ b/net/third_party/nss/ssl/sslnonce.c
@@ -148,6 +148,9 @@ ssl_DestroySID(sslSessionID *sid)
if (sid->u.ssl3.srvName.data) {
SECITEM_FreeItem(&sid->u.ssl3.srvName, PR_FALSE);
}
+ if (sid->u.ssl3.originalHandshakeHash.data) {
+ SECITEM_FreeItem(&sid->u.ssl3.originalHandshakeHash, PR_FALSE);
+ }
PORT_ZFree(sid, sizeof(sslSessionID));
}
diff --git a/net/third_party/nss/ssl/sslt.h b/net/third_party/nss/ssl/sslt.h
index e4d188f..b813c04 100644
--- a/net/third_party/nss/ssl/sslt.h
+++ b/net/third_party/nss/ssl/sslt.h
@@ -204,7 +204,7 @@ typedef enum {
ssl_app_layer_protocol_xtn = 16,
ssl_session_ticket_xtn = 35,
ssl_next_proto_nego_xtn = 13172,
- ssl_channel_id_xtn = 30031,
+ ssl_channel_id_xtn = 30032,
ssl_padding_xtn = 35655,
ssl_renegotiation_info_xtn = 0xff01 /* experimental number */
} SSLExtensionType;