Index: net/third_party/nss/patches/renegoclientversion.patch |
=================================================================== |
--- net/third_party/nss/patches/renegoclientversion.patch (revision 0) |
+++ net/third_party/nss/patches/renegoclientversion.patch (revision 0) |
@@ -0,0 +1,114 @@ |
+Index: mozilla/security/nss/lib/ssl/ssl3con.c |
+=================================================================== |
+RCS file: /cvsroot/mozilla/security/nss/lib/ssl/ssl3con.c,v |
+retrieving revision 1.186 |
+diff -u -p -r1.186 ssl3con.c |
+--- mozilla/security/nss/lib/ssl/ssl3con.c 30 Jul 2012 00:47:36 -0000 1.186 |
++++ mozilla/security/nss/lib/ssl/ssl3con.c 17 Aug 2012 02:23:29 -0000 |
+@@ -4028,6 +4028,23 @@ ssl3_SendClientHello(sslSocket *ss, PRBo |
+ return rv; |
+ } |
+ |
++ /* |
++ * During a renegotiation, ss->clientHelloVersion will be used again to |
++ * work around a Windows SChannel bug. Ensure that it is still enabled. |
++ */ |
++ if (ss->firstHsDone) { |
++ if (SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) { |
++ PORT_SetError(SSL_ERROR_SSL_DISABLED); |
++ return SECFailure; |
++ } |
++ |
++ if (ss->clientHelloVersion < ss->vrange.min || |
++ ss->clientHelloVersion > ss->vrange.max) { |
++ PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP); |
++ return SECFailure; |
++ } |
++ } |
++ |
+ /* We ignore ss->sec.ci.sid here, and use ssl_Lookup because Lookup |
+ * handles expired entries and other details. |
+ * XXX If we've been called from ssl2_BeginClientHandshake, then |
+@@ -4075,9 +4092,41 @@ ssl3_SendClientHello(sslSocket *ss, PRBo |
+ sidOK = PR_FALSE; |
+ } |
+ |
+- if (sidOK && ssl3_NegotiateVersion(ss, sid->version, |
+- PR_FALSE) != SECSuccess) { |
+- sidOK = PR_FALSE; |
++ /* TLS 1.0 (RFC 2246) Appendix E says: |
++ * Whenever a client already knows the highest protocol known to |
++ * a server (for example, when resuming a session), it should |
++ * initiate the connection in that native protocol. |
++ * So we pass sid->version to ssl3_NegotiateVersion() here, except |
++ * when renegotiating. |
++ * |
++ * Windows SChannel compares the client_version inside the RSA |
++ * EncryptedPreMasterSecret of a renegotiation with the |
++ * client_version of the initial ClientHello rather than the |
++ * ClientHello in the renegotiation. To work around this bug, we |
++ * continue to use the client_version used in the initial |
++ * ClientHello when renegotiating. |
++ */ |
++ if (sidOK) { |
++ if (ss->firstHsDone) { |
++ /* |
++ * The client_version of the initial ClientHello is still |
++ * available in ss->clientHelloVersion. Ensure that |
++ * sid->version is bounded within |
++ * [ss->vrange.min, ss->clientHelloVersion], otherwise we |
++ * can't use sid. |
++ */ |
++ if (sid->version >= ss->vrange.min && |
++ sid->version <= ss->clientHelloVersion) { |
++ ss->version = ss->clientHelloVersion; |
++ } else { |
++ sidOK = PR_FALSE; |
++ } |
++ } else { |
++ if (ssl3_NegotiateVersion(ss, sid->version, |
++ PR_FALSE) != SECSuccess) { |
++ sidOK = PR_FALSE; |
++ } |
++ } |
+ } |
+ |
+ if (!sidOK) { |
+@@ -4104,10 +4153,22 @@ ssl3_SendClientHello(sslSocket *ss, PRBo |
+ } else { |
+ SSL_AtomicIncrementLong(& ssl3stats.sch_sid_cache_misses ); |
+ |
+- rv = ssl3_NegotiateVersion(ss, SSL_LIBRARY_VERSION_MAX_SUPPORTED, |
+- PR_TRUE); |
+- if (rv != SECSuccess) |
+- return rv; /* error code was set */ |
++ /* |
++ * Windows SChannel compares the client_version inside the RSA |
++ * EncryptedPreMasterSecret of a renegotiation with the |
++ * client_version of the initial ClientHello rather than the |
++ * ClientHello in the renegotiation. To work around this bug, we |
++ * continue to use the client_version used in the initial |
++ * ClientHello when renegotiating. |
++ */ |
++ if (ss->firstHsDone) { |
++ ss->version = ss->clientHelloVersion; |
++ } else { |
++ rv = ssl3_NegotiateVersion(ss, SSL_LIBRARY_VERSION_MAX_SUPPORTED, |
++ PR_TRUE); |
++ if (rv != SECSuccess) |
++ return rv; /* error code was set */ |
++ } |
+ |
+ sid = ssl3_NewSessionID(ss, PR_FALSE); |
+ if (!sid) { |
+@@ -4207,6 +4268,10 @@ ssl3_SendClientHello(sslSocket *ss, PRBo |
+ return rv; /* err set by ssl3_AppendHandshake* */ |
+ } |
+ |
++ if (ss->firstHsDone) { |
++ /* Work around the Windows SChannel bug described above. */ |
++ PORT_Assert(ss->version == ss->clientHelloVersion); |
++ } |
+ ss->clientHelloVersion = ss->version; |
+ if (IS_DTLS(ss)) { |
+ PRUint16 version; |