forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
When renegotiating, continue to use the client_version used in the
initial ClientHello to work around a Windows SChannel bug. Cap the record layer version number to TLS 1.0 only for the initial ClientHello. The record layer version number of the ClientHello in a renegotiation should use the currently negotiated version number. R=agl@chromium.org,rsleevi@chromium.org BUG=141629 TEST=Visit https://solutionscenter.naradana.net/, an IIS server that requests (but doesn't require) client certificates over renegotiation. The page should be laid out correctly. Review URL: https://chromiumcodereview.appspot.com/10828269 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@152116 0039d316-1c4b-4281-b951-d872f2087c98
- Loading branch information
wtc@chromium.org
committed
Aug 17, 2012
1 parent
c0495e8
commit 9808588
Showing
5 changed files
with
242 additions
and
45 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; |
Oops, something went wrong.