Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(240)

Unified Diff: net/third_party/nss/patches/channelid2.patch

Issue 27589002: Support new ChannelID extension. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Add patch file Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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;
+

Powered by Google App Engine
This is Rietveld 408576698