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

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: Remove unrelated bug fix, add comments, don't move ss->ssl3.hs.ws assignment 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 | « no previous file | 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
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
4080 } 4081 }
4081 } 4082 }
4082 /* If we previously did client-auth, make sure that the token that 4083 /* 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 4084 ** holds the private key still exists, is logged in, hasn't been
4084 ** removed, etc. 4085 ** removed, etc.
4085 */ 4086 */
4086 if (sidOK && !ssl3_ClientAuthTokenPresent(sid)) { 4087 if (sidOK && !ssl3_ClientAuthTokenPresent(sid)) {
4087 sidOK = PR_FALSE; 4088 sidOK = PR_FALSE;
4088 } 4089 }
4089 4090
4090 » if (sidOK && ssl3_NegotiateVersion(ss, sid->version, 4091 » /* TLS 1.0 (RFC 2246) Appendix E says:
4091 » » » » » PR_FALSE) != SECSuccess) { 4092 » * Whenever a client already knows the highest protocol known to
4092 » sidOK = PR_FALSE; 4093 » * a server (for example, when resuming a session), it should
4094 » * initiate the connection in that native protocol.
4095 » * So we pass sid->version to ssl3_NegotiateVersion() here, except
4096 » * when renegotiating.
4097 » *
4098 » * Windows SChannel compares the client_version inside the RSA
4099 » * EncryptedPreMasterSecret of a renegotiation with the
4100 » * client_version of the initial ClientHello rather than the
4101 » * ClientHello in the renegotiation. To work around this bug, we
4102 » * continue to use the client_version used in the initial
4103 » * ClientHello when renegotiating.
4104 » */
4105 » if (sidOK) {
4106 » if (ss->firstHsDone) {
4107 » » /*
4108 » » * The client_version of the initial ClientHello is still
4109 » » * available in ss->clientHelloVersion. Ensure that
4110 » » * sid->version is bounded within
4111 » » * [ss->vrange.min, ss->clientHelloVersion], otherwise we
4112 » » * can't use sid.
4113 » » */
4114 » » if (sid->version >= ss->vrange.min &&
4115 » » sid->version <= ss->clientHelloVersion) {
Ryan Sleevi 2012/08/16 00:33:25 I'm still having trouble parsing this, in part bec
wtc 2012/08/16 01:40:06 This is an important question. Here is the reason
4116 » » ss->version = ss->clientHelloVersion;
4117 » » } else {
4118 » » sidOK = PR_FALSE;
4119 » » }
4120 » } else {
4121 » » if (ssl3_NegotiateVersion(ss, sid->version,
4122 » » » » » PR_FALSE) != SECSuccess) {
4123 » » sidOK = PR_FALSE;
4124 » » }
4125 » }
4093 } 4126 }
4094 4127
4095 if (!sidOK) { 4128 if (!sidOK) {
4096 SSL_AtomicIncrementLong(& ssl3stats.sch_sid_cache_not_ok ); 4129 SSL_AtomicIncrementLong(& ssl3stats.sch_sid_cache_not_ok );
4097 (*ss->sec.uncache)(sid); 4130 (*ss->sec.uncache)(sid);
4098 ssl_FreeSID(sid); 4131 ssl_FreeSID(sid);
4099 sid = NULL; 4132 sid = NULL;
4100 } 4133 }
4101 } 4134 }
4102 4135
4103 if (sid) { 4136 if (sid) {
4104 » serverVersionKnown = PR_TRUE; 4137 » requestingResume = PR_TRUE;
4105 SSL_AtomicIncrementLong(& ssl3stats.sch_sid_cache_hits ); 4138 SSL_AtomicIncrementLong(& ssl3stats.sch_sid_cache_hits );
4106 4139
4107 /* Are we attempting a stateless session resume? */ 4140 /* Are we attempting a stateless session resume? */
4108 if (sid->version > SSL_LIBRARY_VERSION_3_0 && 4141 if (sid->version > SSL_LIBRARY_VERSION_3_0 &&
4109 sid->u.ssl3.sessionTicket.ticket.data) 4142 sid->u.ssl3.sessionTicket.ticket.data)
4110 SSL_AtomicIncrementLong(& ssl3stats.sch_sid_stateless_resumes ); 4143 SSL_AtomicIncrementLong(& ssl3stats.sch_sid_stateless_resumes );
4111 4144
4112 PRINT_BUF(4, (ss, "client, found session-id:", sid->u.ssl3.sessionID, 4145 PRINT_BUF(4, (ss, "client, found session-id:", sid->u.ssl3.sessionID,
4113 sid->u.ssl3.sessionIDLength)); 4146 sid->u.ssl3.sessionIDLength));
4114 4147
4115 ss->ssl3.policy = sid->u.ssl3.policy; 4148 ss->ssl3.policy = sid->u.ssl3.policy;
4116 } else { 4149 } else {
4117 SSL_AtomicIncrementLong(& ssl3stats.sch_sid_cache_misses ); 4150 SSL_AtomicIncrementLong(& ssl3stats.sch_sid_cache_misses );
4118 4151
4119 » rv = ssl3_NegotiateVersion(ss, SSL_LIBRARY_VERSION_MAX_SUPPORTED, 4152 » /*
4120 » » » » PR_TRUE); 4153 » * Windows SChannel compares the client_version inside the RSA
4121 » if (rv != SECSuccess) 4154 » * EncryptedPreMasterSecret of a renegotiation with the
4122 » return rv;» /* error code was set */ 4155 » * client_version of the initial ClientHello rather than the
4156 » * ClientHello in the renegotiation. To work around this bug, we
4157 » * continue to use the client_version used in the initial
4158 » * ClientHello when renegotiating.
4159 » */
4160 » if (ss->firstHsDone) {
4161 » ss->version = ss->clientHelloVersion;
Ryan Sleevi 2012/08/16 00:33:25 Is it possible for the socket to be re-configured
wtc 2012/08/16 01:40:06 An application can do that, but a lot of NSS code
4162 » } else {
4163 » rv = ssl3_NegotiateVersion(ss, SSL_LIBRARY_VERSION_MAX_SUPPORTED,
4164 » » » » PR_TRUE);
4165 » if (rv != SECSuccess)
4166 » » return rv;» /* error code was set */
4167 » }
4123 4168
4124 sid = ssl3_NewSessionID(ss, PR_FALSE); 4169 sid = ssl3_NewSessionID(ss, PR_FALSE);
wtc 2012/08/16 01:40:06 I considered handling the SChannel bug only once,
4125 if (!sid) { 4170 if (!sid) {
4126 return SECFailure; /* memory error is set */ 4171 return SECFailure; /* memory error is set */
4127 } 4172 }
4128 } 4173 }
4129 4174
4130 isTLS = (ss->version > SSL_LIBRARY_VERSION_3_0); 4175 isTLS = (ss->version > SSL_LIBRARY_VERSION_3_0);
4131 ssl_GetSpecWriteLock(ss); 4176 ssl_GetSpecWriteLock(ss);
4132 cwSpec = ss->ssl3.cwSpec; 4177 cwSpec = ss->ssl3.cwSpec;
4133 if (cwSpec->mac_def->mac == mac_null) { 4178 if (cwSpec->mac_def->mac == mac_null) {
4134 /* SSL records are not being MACed. */ 4179 /* SSL records are not being MACed. */
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
4212 1 + numCompressionMethods + total_exten_len; 4257 1 + numCompressionMethods + total_exten_len;
4213 if (IS_DTLS(ss)) { 4258 if (IS_DTLS(ss)) {
4214 length += 1 + ss->ssl3.hs.cookieLen; 4259 length += 1 + ss->ssl3.hs.cookieLen;
4215 } 4260 }
4216 4261
4217 rv = ssl3_AppendHandshakeHeader(ss, client_hello, length); 4262 rv = ssl3_AppendHandshakeHeader(ss, client_hello, length);
4218 if (rv != SECSuccess) { 4263 if (rv != SECSuccess) {
4219 return rv; /* err set by ssl3_AppendHandshake* */ 4264 return rv; /* err set by ssl3_AppendHandshake* */
4220 } 4265 }
4221 4266
4267 if (ss->firstHsDone) {
4268 /* Work around the Windows SChannel bug described above. */
4269 PORT_Assert(ss->version == ss->clientHelloVersion);
4270 }
4222 ss->clientHelloVersion = ss->version; 4271 ss->clientHelloVersion = ss->version;
4223 if (IS_DTLS(ss)) { 4272 if (IS_DTLS(ss)) {
4224 PRUint16 version; 4273 PRUint16 version;
4225 4274
4226 version = dtls_TLSVersionToDTLSVersion(ss->clientHelloVersion); 4275 version = dtls_TLSVersionToDTLSVersion(ss->clientHelloVersion);
4227 rv = ssl3_AppendHandshakeNumber(ss, version, 2); 4276 rv = ssl3_AppendHandshakeNumber(ss, version, 2);
4228 } else { 4277 } else {
4229 rv = ssl3_AppendHandshakeNumber(ss, ss->clientHelloVersion, 2); 4278 rv = ssl3_AppendHandshakeNumber(ss, ss->clientHelloVersion, 2);
4230 } 4279 }
4231 if (rv != SECSuccess) { 4280 if (rv != SECSuccess) {
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
4331 PORT_Assert(!maxBytes); 4380 PORT_Assert(!maxBytes);
4332 } 4381 }
4333 if (ss->ssl3.hs.sendingSCSV) { 4382 if (ss->ssl3.hs.sendingSCSV) {
4334 /* Since we sent the SCSV, pretend we sent empty RI extension. */ 4383 /* Since we sent the SCSV, pretend we sent empty RI extension. */
4335 TLSExtensionData *xtnData = &ss->xtnData; 4384 TLSExtensionData *xtnData = &ss->xtnData;
4336 xtnData->advertised[xtnData->numAdvertised++] = 4385 xtnData->advertised[xtnData->numAdvertised++] =
4337 ssl_renegotiation_info_xtn; 4386 ssl_renegotiation_info_xtn;
4338 } 4387 }
4339 4388
4340 flags = 0; 4389 flags = 0;
4341 if (!serverVersionKnown && !IS_DTLS(ss)) { 4390 if (!ss->firstHsDone && !requestingResume && !IS_DTLS(ss)) {
4342 flags |= ssl_SEND_FLAG_CAP_RECORD_VERSION; 4391 flags |= ssl_SEND_FLAG_CAP_RECORD_VERSION;
4343 } 4392 }
4344 rv = ssl3_FlushHandshake(ss, flags); 4393 rv = ssl3_FlushHandshake(ss, flags);
4345 if (rv != SECSuccess) { 4394 if (rv != SECSuccess) {
4346 return rv; /* error code set by ssl3_FlushHandshake */ 4395 return rv; /* error code set by ssl3_FlushHandshake */
4347 } 4396 }
4348 4397
4349 ss->ssl3.hs.ws = wait_server_hello; 4398 ss->ssl3.hs.ws = wait_server_hello;
4350 return rv; 4399 return rv;
4351 } 4400 }
(...skipping 6440 matching lines...) Expand 10 before | Expand all | Expand 10 after
10792 PORT_Free(ss->ssl3.hs.recvdFragments.buf); 10841 PORT_Free(ss->ssl3.hs.recvdFragments.buf);
10793 } 10842 }
10794 } 10843 }
10795 10844
10796 ss->ssl3.initialized = PR_FALSE; 10845 ss->ssl3.initialized = PR_FALSE;
10797 10846
10798 SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE); 10847 SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE);
10799 } 10848 }
10800 10849
10801 /* End of ssl3con.c */ 10850 /* End of ssl3con.c */
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698