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

Side by Side Diff: net/third_party/nss/ssl/ssl3con.c

Issue 10828269: When renegotiating, continue to use the client_version used in the initial ClientHello (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Add the patch file Created 8 years, 4 months 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/third_party/nss/patches/renegoclientversion.patch ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* 2 /*
3 * SSL3 Protocol 3 * SSL3 Protocol
4 * 4 *
5 * ***** BEGIN LICENSE BLOCK ***** 5 * ***** BEGIN LICENSE BLOCK *****
6 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 6 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
7 * 7 *
8 * The contents of this file are subject to the Mozilla Public License Version 8 * The contents of this file are subject to the Mozilla Public License Version
9 * 1.1 (the "License"); you may not use this file except in compliance with 9 * 1.1 (the "License"); you may not use this file except in compliance with
10 * the License. You may obtain a copy of the License at 10 * the License. You may obtain a copy of the License at
(...skipping 2267 matching lines...) Expand 10 before | Expand all | Expand 10 after
2278 SSL_TRC(3, ("%d: SSL3[%d] SendRecord type: %s nIn=%d", 2278 SSL_TRC(3, ("%d: SSL3[%d] SendRecord type: %s nIn=%d",
2279 SSL_GETPID(), ss->fd, ssl3_DecodeContentType(type), 2279 SSL_GETPID(), ss->fd, ssl3_DecodeContentType(type),
2280 nIn)); 2280 nIn));
2281 PRINT_BUF(3, (ss, "Send record (plain text)", pIn, nIn)); 2281 PRINT_BUF(3, (ss, "Send record (plain text)", pIn, nIn));
2282 2282
2283 PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) ); 2283 PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
2284 2284
2285 capRecordVersion = ((flags & ssl_SEND_FLAG_CAP_RECORD_VERSION) != 0); 2285 capRecordVersion = ((flags & ssl_SEND_FLAG_CAP_RECORD_VERSION) != 0);
2286 2286
2287 if (capRecordVersion) { 2287 if (capRecordVersion) {
2288 » /* ssl_SEND_FLAG_CAP_RECORD_VERSION can only be used with 2288 » /* ssl_SEND_FLAG_CAP_RECORD_VERSION can only be used with the
2289 » * TLS ClientHello. */ 2289 » * TLS initial ClientHello. */
2290 PORT_Assert(!IS_DTLS(ss)); 2290 PORT_Assert(!IS_DTLS(ss));
2291 PORT_Assert(!ss->firstHsDone);
2291 PORT_Assert(type == content_handshake); 2292 PORT_Assert(type == content_handshake);
2292 PORT_Assert(ss->ssl3.hs.ws == wait_server_hello); 2293 PORT_Assert(ss->ssl3.hs.ws == wait_server_hello);
2293 } 2294 }
2294 2295
2295 if (ss->ssl3.initialized == PR_FALSE) { 2296 if (ss->ssl3.initialized == PR_FALSE) {
2296 /* This can happen on a server if the very first incoming record 2297 /* This can happen on a server if the very first incoming record
2297 ** looks like a defective ssl3 record (e.g. too long), and we're 2298 ** looks like a defective ssl3 record (e.g. too long), and we're
2298 ** trying to send an alert. 2299 ** trying to send an alert.
2299 */ 2300 */
2300 PR_ASSERT(type == content_alert); 2301 PR_ASSERT(type == content_alert);
(...skipping 1702 matching lines...) Expand 10 before | Expand all | Expand 10 after
4003 ssl3_SendClientHello(sslSocket *ss, PRBool resending) 4004 ssl3_SendClientHello(sslSocket *ss, PRBool resending)
4004 { 4005 {
4005 sslSessionID * sid; 4006 sslSessionID * sid;
4006 ssl3CipherSpec * cwSpec; 4007 ssl3CipherSpec * cwSpec;
4007 SECStatus rv; 4008 SECStatus rv;
4008 int i; 4009 int i;
4009 int length; 4010 int length;
4010 int num_suites; 4011 int num_suites;
4011 int actual_count = 0; 4012 int actual_count = 0;
4012 PRBool isTLS = PR_FALSE; 4013 PRBool isTLS = PR_FALSE;
4013 PRBool serverVersionKnown = PR_FALSE; 4014 PRBool requestingResume = PR_FALSE;
4014 PRInt32 total_exten_len = 0; 4015 PRInt32 total_exten_len = 0;
4015 unsigned numCompressionMethods; 4016 unsigned numCompressionMethods;
4016 PRInt32 flags; 4017 PRInt32 flags;
4017 4018
4018 SSL_TRC(3, ("%d: SSL3[%d]: send client_hello handshake", SSL_GETPID(), 4019 SSL_TRC(3, ("%d: SSL3[%d]: send client_hello handshake", SSL_GETPID(),
4019 ss->fd)); 4020 ss->fd));
4020 4021
4021 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); 4022 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
4022 PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) ); 4023 PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
4023 4024
4024 rv = ssl3_InitState(ss); 4025 rv = ssl3_InitState(ss);
4025 if (rv != SECSuccess) { 4026 if (rv != SECSuccess) {
4026 return rv; /* ssl3_InitState has set the error code. */ 4027 return rv; /* ssl3_InitState has set the error code. */
4027 } 4028 }
4028 ss->ssl3.hs.sendingSCSV = PR_FALSE; /* Must be reset every handshake */ 4029 ss->ssl3.hs.sendingSCSV = PR_FALSE; /* Must be reset every handshake */
4029 PORT_Assert(IS_DTLS(ss) || !resending); 4030 PORT_Assert(IS_DTLS(ss) || !resending);
4030 4031
4031 /* We might be starting a session renegotiation in which case we should 4032 /* We might be starting a session renegotiation in which case we should
4032 * clear previous state. 4033 * clear previous state.
4033 */ 4034 */
4034 PORT_Memset(&ss->xtnData, 0, sizeof(TLSExtensionData)); 4035 PORT_Memset(&ss->xtnData, 0, sizeof(TLSExtensionData));
4035 4036
4036 SSL_TRC(30,("%d: SSL3[%d]: reset handshake hashes", 4037 SSL_TRC(30,("%d: SSL3[%d]: reset handshake hashes",
4037 SSL_GETPID(), ss->fd )); 4038 SSL_GETPID(), ss->fd ));
4038 rv = ssl3_RestartHandshakeHashes(ss); 4039 rv = ssl3_RestartHandshakeHashes(ss);
4039 if (rv != SECSuccess) { 4040 if (rv != SECSuccess) {
4040 return rv; 4041 return rv;
4041 } 4042 }
4042 4043
4044 /*
4045 * During a renegotiation, ss->clientHelloVersion will be used again to
4046 * work around a Windows SChannel bug. Ensure that it is still enabled.
4047 */
4048 if (ss->firstHsDone) {
4049 if (SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) {
4050 PORT_SetError(SSL_ERROR_SSL_DISABLED);
4051 return SECFailure;
4052 }
4053
4054 if (ss->clientHelloVersion < ss->vrange.min ||
4055 ss->clientHelloVersion > ss->vrange.max) {
4056 PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
4057 return SECFailure;
4058 }
4059 }
4060
4043 /* We ignore ss->sec.ci.sid here, and use ssl_Lookup because Lookup 4061 /* We ignore ss->sec.ci.sid here, and use ssl_Lookup because Lookup
4044 * handles expired entries and other details. 4062 * handles expired entries and other details.
4045 * XXX If we've been called from ssl2_BeginClientHandshake, then 4063 * XXX If we've been called from ssl2_BeginClientHandshake, then
4046 * this lookup is duplicative and wasteful. 4064 * this lookup is duplicative and wasteful.
4047 */ 4065 */
4048 sid = (ss->opt.noCache) ? NULL 4066 sid = (ss->opt.noCache) ? NULL
4049 : ssl_LookupSID(&ss->sec.ci.peer, ss->sec.ci.port, ss->peerID, ss->u rl); 4067 : ssl_LookupSID(&ss->sec.ci.peer, ss->sec.ci.port, ss->peerID, ss->u rl);
4050 4068
4051 /* We can't resume based on a different token. If the sid exists, 4069 /* We can't resume based on a different token. If the sid exists,
4052 * make sure the token that holds the master secret still exists ... 4070 * make sure the token that holds the master secret still exists ...
(...skipping 27 matching lines...) Expand all
4080 } 4098 }
4081 } 4099 }
4082 /* If we previously did client-auth, make sure that the token that 4100 /* If we previously did client-auth, make sure that the token that
4083 ** holds the private key still exists, is logged in, hasn't been 4101 ** holds the private key still exists, is logged in, hasn't been
4084 ** removed, etc. 4102 ** removed, etc.
4085 */ 4103 */
4086 if (sidOK && !ssl3_ClientAuthTokenPresent(sid)) { 4104 if (sidOK && !ssl3_ClientAuthTokenPresent(sid)) {
4087 sidOK = PR_FALSE; 4105 sidOK = PR_FALSE;
4088 } 4106 }
4089 4107
4090 » if (sidOK && ssl3_NegotiateVersion(ss, sid->version, 4108 » /* TLS 1.0 (RFC 2246) Appendix E says:
4091 » » » » » PR_FALSE) != SECSuccess) { 4109 » * Whenever a client already knows the highest protocol known to
4092 » sidOK = PR_FALSE; 4110 » * a server (for example, when resuming a session), it should
4111 » * initiate the connection in that native protocol.
4112 » * So we pass sid->version to ssl3_NegotiateVersion() here, except
4113 » * when renegotiating.
4114 » *
4115 » * Windows SChannel compares the client_version inside the RSA
4116 » * EncryptedPreMasterSecret of a renegotiation with the
4117 » * client_version of the initial ClientHello rather than the
4118 » * ClientHello in the renegotiation. To work around this bug, we
4119 » * continue to use the client_version used in the initial
4120 » * ClientHello when renegotiating.
4121 » */
4122 » if (sidOK) {
4123 » if (ss->firstHsDone) {
4124 » » /*
4125 » » * The client_version of the initial ClientHello is still
4126 » » * available in ss->clientHelloVersion. Ensure that
4127 » » * sid->version is bounded within
4128 » » * [ss->vrange.min, ss->clientHelloVersion], otherwise we
4129 » » * can't use sid.
4130 » » */
4131 » » if (sid->version >= ss->vrange.min &&
4132 » » sid->version <= ss->clientHelloVersion) {
4133 » » ss->version = ss->clientHelloVersion;
4134 » » } else {
4135 » » sidOK = PR_FALSE;
4136 » » }
4137 » } else {
4138 » » if (ssl3_NegotiateVersion(ss, sid->version,
4139 » » » » » PR_FALSE) != SECSuccess) {
4140 » » sidOK = PR_FALSE;
4141 » » }
4142 » }
4093 } 4143 }
4094 4144
4095 if (!sidOK) { 4145 if (!sidOK) {
4096 SSL_AtomicIncrementLong(& ssl3stats.sch_sid_cache_not_ok ); 4146 SSL_AtomicIncrementLong(& ssl3stats.sch_sid_cache_not_ok );
4097 (*ss->sec.uncache)(sid); 4147 (*ss->sec.uncache)(sid);
4098 ssl_FreeSID(sid); 4148 ssl_FreeSID(sid);
4099 sid = NULL; 4149 sid = NULL;
4100 } 4150 }
4101 } 4151 }
4102 4152
4103 if (sid) { 4153 if (sid) {
4104 » serverVersionKnown = PR_TRUE; 4154 » requestingResume = PR_TRUE;
4105 SSL_AtomicIncrementLong(& ssl3stats.sch_sid_cache_hits ); 4155 SSL_AtomicIncrementLong(& ssl3stats.sch_sid_cache_hits );
4106 4156
4107 /* Are we attempting a stateless session resume? */ 4157 /* Are we attempting a stateless session resume? */
4108 if (sid->version > SSL_LIBRARY_VERSION_3_0 && 4158 if (sid->version > SSL_LIBRARY_VERSION_3_0 &&
4109 sid->u.ssl3.sessionTicket.ticket.data) 4159 sid->u.ssl3.sessionTicket.ticket.data)
4110 SSL_AtomicIncrementLong(& ssl3stats.sch_sid_stateless_resumes ); 4160 SSL_AtomicIncrementLong(& ssl3stats.sch_sid_stateless_resumes );
4111 4161
4112 PRINT_BUF(4, (ss, "client, found session-id:", sid->u.ssl3.sessionID, 4162 PRINT_BUF(4, (ss, "client, found session-id:", sid->u.ssl3.sessionID,
4113 sid->u.ssl3.sessionIDLength)); 4163 sid->u.ssl3.sessionIDLength));
4114 4164
4115 ss->ssl3.policy = sid->u.ssl3.policy; 4165 ss->ssl3.policy = sid->u.ssl3.policy;
4116 } else { 4166 } else {
4117 SSL_AtomicIncrementLong(& ssl3stats.sch_sid_cache_misses ); 4167 SSL_AtomicIncrementLong(& ssl3stats.sch_sid_cache_misses );
4118 4168
4119 » rv = ssl3_NegotiateVersion(ss, SSL_LIBRARY_VERSION_MAX_SUPPORTED, 4169 » /*
4120 » » » » PR_TRUE); 4170 » * Windows SChannel compares the client_version inside the RSA
4121 » if (rv != SECSuccess) 4171 » * EncryptedPreMasterSecret of a renegotiation with the
4122 » return rv;» /* error code was set */ 4172 » * client_version of the initial ClientHello rather than the
4173 » * ClientHello in the renegotiation. To work around this bug, we
4174 » * continue to use the client_version used in the initial
4175 » * ClientHello when renegotiating.
4176 » */
4177 » if (ss->firstHsDone) {
4178 » ss->version = ss->clientHelloVersion;
4179 » } else {
4180 » rv = ssl3_NegotiateVersion(ss, SSL_LIBRARY_VERSION_MAX_SUPPORTED,
4181 » » » » PR_TRUE);
4182 » if (rv != SECSuccess)
4183 » » return rv;» /* error code was set */
4184 » }
4123 4185
4124 sid = ssl3_NewSessionID(ss, PR_FALSE); 4186 sid = ssl3_NewSessionID(ss, PR_FALSE);
4125 if (!sid) { 4187 if (!sid) {
4126 return SECFailure; /* memory error is set */ 4188 return SECFailure; /* memory error is set */
4127 } 4189 }
4128 } 4190 }
4129 4191
4130 isTLS = (ss->version > SSL_LIBRARY_VERSION_3_0); 4192 isTLS = (ss->version > SSL_LIBRARY_VERSION_3_0);
4131 ssl_GetSpecWriteLock(ss); 4193 ssl_GetSpecWriteLock(ss);
4132 cwSpec = ss->ssl3.cwSpec; 4194 cwSpec = ss->ssl3.cwSpec;
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
4212 1 + numCompressionMethods + total_exten_len; 4274 1 + numCompressionMethods + total_exten_len;
4213 if (IS_DTLS(ss)) { 4275 if (IS_DTLS(ss)) {
4214 length += 1 + ss->ssl3.hs.cookieLen; 4276 length += 1 + ss->ssl3.hs.cookieLen;
4215 } 4277 }
4216 4278
4217 rv = ssl3_AppendHandshakeHeader(ss, client_hello, length); 4279 rv = ssl3_AppendHandshakeHeader(ss, client_hello, length);
4218 if (rv != SECSuccess) { 4280 if (rv != SECSuccess) {
4219 return rv; /* err set by ssl3_AppendHandshake* */ 4281 return rv; /* err set by ssl3_AppendHandshake* */
4220 } 4282 }
4221 4283
4284 if (ss->firstHsDone) {
4285 /* Work around the Windows SChannel bug described above. */
4286 PORT_Assert(ss->version == ss->clientHelloVersion);
4287 }
4222 ss->clientHelloVersion = ss->version; 4288 ss->clientHelloVersion = ss->version;
4223 if (IS_DTLS(ss)) { 4289 if (IS_DTLS(ss)) {
4224 PRUint16 version; 4290 PRUint16 version;
4225 4291
4226 version = dtls_TLSVersionToDTLSVersion(ss->clientHelloVersion); 4292 version = dtls_TLSVersionToDTLSVersion(ss->clientHelloVersion);
4227 rv = ssl3_AppendHandshakeNumber(ss, version, 2); 4293 rv = ssl3_AppendHandshakeNumber(ss, version, 2);
4228 } else { 4294 } else {
4229 rv = ssl3_AppendHandshakeNumber(ss, ss->clientHelloVersion, 2); 4295 rv = ssl3_AppendHandshakeNumber(ss, ss->clientHelloVersion, 2);
4230 } 4296 }
4231 if (rv != SECSuccess) { 4297 if (rv != SECSuccess) {
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
4331 PORT_Assert(!maxBytes); 4397 PORT_Assert(!maxBytes);
4332 } 4398 }
4333 if (ss->ssl3.hs.sendingSCSV) { 4399 if (ss->ssl3.hs.sendingSCSV) {
4334 /* Since we sent the SCSV, pretend we sent empty RI extension. */ 4400 /* Since we sent the SCSV, pretend we sent empty RI extension. */
4335 TLSExtensionData *xtnData = &ss->xtnData; 4401 TLSExtensionData *xtnData = &ss->xtnData;
4336 xtnData->advertised[xtnData->numAdvertised++] = 4402 xtnData->advertised[xtnData->numAdvertised++] =
4337 ssl_renegotiation_info_xtn; 4403 ssl_renegotiation_info_xtn;
4338 } 4404 }
4339 4405
4340 flags = 0; 4406 flags = 0;
4341 if (!serverVersionKnown && !IS_DTLS(ss)) { 4407 if (!ss->firstHsDone && !requestingResume && !IS_DTLS(ss)) {
4342 flags |= ssl_SEND_FLAG_CAP_RECORD_VERSION; 4408 flags |= ssl_SEND_FLAG_CAP_RECORD_VERSION;
4343 } 4409 }
4344 rv = ssl3_FlushHandshake(ss, flags); 4410 rv = ssl3_FlushHandshake(ss, flags);
4345 if (rv != SECSuccess) { 4411 if (rv != SECSuccess) {
4346 return rv; /* error code set by ssl3_FlushHandshake */ 4412 return rv; /* error code set by ssl3_FlushHandshake */
4347 } 4413 }
4348 4414
4349 ss->ssl3.hs.ws = wait_server_hello; 4415 ss->ssl3.hs.ws = wait_server_hello;
4350 return rv; 4416 return rv;
4351 } 4417 }
(...skipping 6440 matching lines...) Expand 10 before | Expand all | Expand 10 after
10792 PORT_Free(ss->ssl3.hs.recvdFragments.buf); 10858 PORT_Free(ss->ssl3.hs.recvdFragments.buf);
10793 } 10859 }
10794 } 10860 }
10795 10861
10796 ss->ssl3.initialized = PR_FALSE; 10862 ss->ssl3.initialized = PR_FALSE;
10797 10863
10798 SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE); 10864 SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE);
10799 } 10865 }
10800 10866
10801 /* End of ssl3con.c */ 10867 /* End of ssl3con.c */
OLDNEW
« no previous file with comments | « net/third_party/nss/patches/renegoclientversion.patch ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698