| OLD | NEW |
| (Empty) |
| 1 Index: mozilla/security/nss/lib/ssl/ssl3con.c | |
| 2 =================================================================== | |
| 3 RCS file: /cvsroot/mozilla/security/nss/lib/ssl/ssl3con.c,v | |
| 4 retrieving revision 1.186 | |
| 5 diff -u -p -r1.186 ssl3con.c | |
| 6 --- mozilla/security/nss/lib/ssl/ssl3con.c 30 Jul 2012 00:47:36 -0000
1.186 | |
| 7 +++ mozilla/security/nss/lib/ssl/ssl3con.c 17 Aug 2012 02:23:29 -0000 | |
| 8 @@ -4028,6 +4028,23 @@ ssl3_SendClientHello(sslSocket *ss, PRBo | |
| 9 return rv; | |
| 10 } | |
| 11 | |
| 12 + /* | |
| 13 + * During a renegotiation, ss->clientHelloVersion will be used again to | |
| 14 + * work around a Windows SChannel bug. Ensure that it is still enabled. | |
| 15 + */ | |
| 16 + if (ss->firstHsDone) { | |
| 17 + if (SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) { | |
| 18 + PORT_SetError(SSL_ERROR_SSL_DISABLED); | |
| 19 + return SECFailure; | |
| 20 + } | |
| 21 + | |
| 22 + if (ss->clientHelloVersion < ss->vrange.min || | |
| 23 + ss->clientHelloVersion > ss->vrange.max) { | |
| 24 + PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP); | |
| 25 + return SECFailure; | |
| 26 + } | |
| 27 + } | |
| 28 + | |
| 29 /* We ignore ss->sec.ci.sid here, and use ssl_Lookup because Lookup | |
| 30 * handles expired entries and other details. | |
| 31 * XXX If we've been called from ssl2_BeginClientHandshake, then | |
| 32 @@ -4075,9 +4092,41 @@ ssl3_SendClientHello(sslSocket *ss, PRBo | |
| 33 sidOK = PR_FALSE; | |
| 34 } | |
| 35 | |
| 36 - if (sidOK && ssl3_NegotiateVersion(ss, sid->version, | |
| 37 - PR_FALSE) != SECSuccess) { | |
| 38 - sidOK = PR_FALSE; | |
| 39 + /* TLS 1.0 (RFC 2246) Appendix E says: | |
| 40 + * Whenever a client already knows the highest protocol known to | |
| 41 + * a server (for example, when resuming a session), it should | |
| 42 + * initiate the connection in that native protocol. | |
| 43 + * So we pass sid->version to ssl3_NegotiateVersion() here, except | |
| 44 + * when renegotiating. | |
| 45 + * | |
| 46 + * Windows SChannel compares the client_version inside the RSA | |
| 47 + * EncryptedPreMasterSecret of a renegotiation with the | |
| 48 + * client_version of the initial ClientHello rather than the | |
| 49 + * ClientHello in the renegotiation. To work around this bug, we | |
| 50 + * continue to use the client_version used in the initial | |
| 51 + * ClientHello when renegotiating. | |
| 52 + */ | |
| 53 + if (sidOK) { | |
| 54 + if (ss->firstHsDone) { | |
| 55 + /* | |
| 56 + * The client_version of the initial ClientHello is still | |
| 57 + * available in ss->clientHelloVersion. Ensure that | |
| 58 + * sid->version is bounded within | |
| 59 + * [ss->vrange.min, ss->clientHelloVersion], otherwise we | |
| 60 + * can't use sid. | |
| 61 + */ | |
| 62 + if (sid->version >= ss->vrange.min && | |
| 63 + sid->version <= ss->clientHelloVersion) { | |
| 64 + ss->version = ss->clientHelloVersion; | |
| 65 + } else { | |
| 66 + sidOK = PR_FALSE; | |
| 67 + } | |
| 68 + } else { | |
| 69 + if (ssl3_NegotiateVersion(ss, sid->version, | |
| 70 + PR_FALSE) != SECSuccess) { | |
| 71 + sidOK = PR_FALSE; | |
| 72 + } | |
| 73 + } | |
| 74 } | |
| 75 | |
| 76 if (!sidOK) { | |
| 77 @@ -4104,10 +4153,22 @@ ssl3_SendClientHello(sslSocket *ss, PRBo | |
| 78 } else { | |
| 79 SSL_AtomicIncrementLong(& ssl3stats.sch_sid_cache_misses ); | |
| 80 | |
| 81 - rv = ssl3_NegotiateVersion(ss, SSL_LIBRARY_VERSION_MAX_SUPPORTED, | |
| 82 - PR_TRUE); | |
| 83 - if (rv != SECSuccess) | |
| 84 - return rv; /* error code was set */ | |
| 85 + /* | |
| 86 + * Windows SChannel compares the client_version inside the RSA | |
| 87 + * EncryptedPreMasterSecret of a renegotiation with the | |
| 88 + * client_version of the initial ClientHello rather than the | |
| 89 + * ClientHello in the renegotiation. To work around this bug, we | |
| 90 + * continue to use the client_version used in the initial | |
| 91 + * ClientHello when renegotiating. | |
| 92 + */ | |
| 93 + if (ss->firstHsDone) { | |
| 94 + ss->version = ss->clientHelloVersion; | |
| 95 + } else { | |
| 96 + rv = ssl3_NegotiateVersion(ss, SSL_LIBRARY_VERSION_MAX_SUPPORTED, | |
| 97 + PR_TRUE); | |
| 98 + if (rv != SECSuccess) | |
| 99 + return rv; /* error code was set */ | |
| 100 + } | |
| 101 | |
| 102 sid = ssl3_NewSessionID(ss, PR_FALSE); | |
| 103 if (!sid) { | |
| 104 @@ -4207,6 +4268,10 @@ ssl3_SendClientHello(sslSocket *ss, PRBo | |
| 105 return rv; /* err set by ssl3_AppendHandshake* */ | |
| 106 } | |
| 107 | |
| 108 + if (ss->firstHsDone) { | |
| 109 + /* Work around the Windows SChannel bug described above. */ | |
| 110 + PORT_Assert(ss->version == ss->clientHelloVersion); | |
| 111 + } | |
| 112 ss->clientHelloVersion = ss->version; | |
| 113 if (IS_DTLS(ss)) { | |
| 114 PRUint16 version; | |
| OLD | NEW |