| Index: net/third_party/nss/patches/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 0000000000000000000000000000000000000000..b2144418a055e0b46c3b7f6d84fede8081828274
|
| --- /dev/null
|
| +++ b/net/third_party/nss/patches/channelid2.patch
|
| @@ -0,0 +1,150 @@
|
| +diff --git a/nss/lib/ssl/ssl3con.c b/nss/lib/ssl/ssl3con.c
|
| +index 8b8b758..1c55bc4 100644
|
| +--- a/nss/lib/ssl/ssl3con.c
|
| ++++ b/nss/lib/ssl/ssl3con.c
|
| +@@ -7570,6 +7570,30 @@ ssl3_SendClientSecondRound(sslSocket *ss)
|
| + goto loser; /* err code was set. */
|
| + }
|
| +
|
| ++ 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 *lastHandshakeHash = &ss->sec.ci.sid->u.ssl3.lastHandshakeHash;
|
| ++
|
| ++ ssl_GetSpecReadLock(ss);
|
| ++ /* the cwSpec and zero arguments are only used for SSLv3, but we know
|
| ++ * that this connection is not SSLv3 because we negotiated ChannelID. */
|
| ++ PORT_Assert(ss->version > SSL_LIBRARY_VERSION_3_0);
|
| ++ ssl3_ComputeHandshakeHashes(ss, ss->ssl3.cwSpec, &hashes, 0);
|
| ++ ssl_ReleaseSpecReadLock(ss);
|
| ++
|
| ++ PORT_Assert(lastHandshakeHash->len == 0);
|
| ++ lastHandshakeHash->data = PORT_Alloc(hashes.len);
|
| ++ if (!lastHandshakeHash->data)
|
| ++ goto loser;
|
| ++ lastHandshakeHash->len = hashes.len;
|
| ++ memcpy(lastHandshakeHash->data, hashes.u.raw, hashes.len);
|
| ++ }
|
| ++
|
| + ssl_ReleaseXmitBufLock(ss); /*******************************/
|
| +
|
| + if (ssl3_ExtensionNegotiated(ss, ssl_session_ticket_xtn))
|
| +@@ -10568,6 +10592,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
|
| +@@ -10593,7 +10618,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 j;
|
| + unsigned char digest[SHA256_LENGTH];
|
| + SECItem digest_item;
|
| + unsigned char signature[64];
|
| +@@ -10643,11 +10671,24 @@ 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);
|
| ++ j = 0;
|
| ++ memcpy(signed_data + j, CHANNEL_ID_MAGIC, sizeof(CHANNEL_ID_MAGIC));
|
| ++ j += sizeof(CHANNEL_ID_MAGIC);
|
| ++ if (ss->ssl3.hs.isResuming) {
|
| ++ SECItem *lastHandshakeHash = &ss->sec.ci.sid->u.ssl3.lastHandshakeHash;
|
| ++ PORT_Assert(lastHandshakeHash->len > 0);
|
| +
|
| +- rv = PK11_HashBuf(SEC_OID_SHA256, digest, signed_data,
|
| +- sizeof(CHANNEL_ID_MAGIC) + hashes.len);
|
| ++ memcpy(signed_data + j, CHANNEL_ID_RESUMPTION_MAGIC,
|
| ++ sizeof(CHANNEL_ID_RESUMPTION_MAGIC));
|
| ++ j += sizeof(CHANNEL_ID_RESUMPTION_MAGIC);
|
| ++ memcpy(signed_data + j, lastHandshakeHash->data,
|
| ++ lastHandshakeHash->len);
|
| ++ j += lastHandshakeHash->len;
|
| ++ }
|
| ++ memcpy(signed_data + j, hashes.u.raw, hashes.len);
|
| ++ j += hashes.len;
|
| ++
|
| ++ rv = PK11_HashBuf(SEC_OID_SHA256, digest, signed_data, j);
|
| + if (rv != SECSuccess)
|
| + goto loser;
|
| +
|
| +diff --git a/nss/lib/ssl/ssl3ext.c b/nss/lib/ssl/ssl3ext.c
|
| +index 0415770..8142c3a 100644
|
| +--- a/nss/lib/ssl/ssl3ext.c
|
| ++++ b/nss/lib/ssl/ssl3ext.c
|
| +@@ -812,6 +812,15 @@ ssl3_ClientSendChannelIDXtn(sslSocket * ss, PRBool append,
|
| + return 0;
|
| + }
|
| +
|
| ++ if (ss->ssl3.hs.isResuming &&
|
| ++ ss->sec.ci.sid->u.ssl3.lastHandshakeHash.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. */
|
| ++ 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 614eed1..bc0e85c 100644
|
| +--- a/nss/lib/ssl/sslimpl.h
|
| ++++ b/nss/lib/ssl/sslimpl.h
|
| +@@ -698,6 +698,14 @@ struct sslSessionIDStr {
|
| + */
|
| + NewSessionTicket sessionTicket;
|
| + SECItem srvName;
|
| ++
|
| ++ /* lastHandshakeHash contains the hash of the original, full
|
| ++ * handshake. This is either a SHA-1/MD5 combination (for TLS <
|
| ++ * 1.2) or a SHA-2 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 lastHandshakeHash;
|
| + } ssl3;
|
| + } u;
|
| + };
|
| +diff --git a/nss/lib/ssl/sslnonce.c b/nss/lib/ssl/sslnonce.c
|
| +index a6f7349..a18c4e3 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.lastHandshakeHash.data) {
|
| ++ SECITEM_FreeItem(&sid->u.ssl3.lastHandshakeHash, PR_FALSE);
|
| ++ }
|
| +
|
| + PORT_ZFree(sid, sizeof(sslSessionID));
|
| + }
|
| +diff --git a/nss/lib/ssl/sslt.h b/nss/lib/ssl/sslt.h
|
| +index a8007d8..77ab4b1 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_renegotiation_info_xtn = 0xff01 /* experimental number */
|
| + } SSLExtensionType;
|
| +
|
|
|