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 |