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

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: Comments added. Ready for review 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 | net/third_party/nss/ssl/sslsock.c » ('j') | net/third_party/nss/ssl/sslsock.c » ('J')
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 768 matching lines...) Expand 10 before | Expand all | Expand 10 after
779 return SECFailure; 779 return SECFailure;
780 } 780 }
781 781
782 if (peerVersion < ss->vrange.min || 782 if (peerVersion < ss->vrange.min ||
783 (peerVersion > ss->vrange.max && !allowLargerPeerVersion)) { 783 (peerVersion > ss->vrange.max && !allowLargerPeerVersion)) {
784 PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP); 784 PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
785 return SECFailure; 785 return SECFailure;
786 } 786 }
787 787
788 ss->version = PR_MIN(peerVersion, ss->vrange.max); 788 ss->version = PR_MIN(peerVersion, ss->vrange.max);
789 PORT_Assert(ssl3_VersionIsSupported(ssl_variant_stream, ss->version)); 789 PORT_Assert(ssl3_VersionIsSupported(ss->protocolVariant, ss->version));
Ryan Sleevi 2012/08/15 03:39:07 This is related to your change to ekr's patch, rig
wtc 2012/08/15 16:16:59 Yes, this fixes an unrelated bug that I discovered
790 790
791 return SECSuccess; 791 return SECSuccess;
792 } 792 }
793 793
794 static SECStatus 794 static SECStatus
795 ssl3_GetNewRandom(SSL3Random *random) 795 ssl3_GetNewRandom(SSL3Random *random)
796 { 796 {
797 PRUint32 gmt = ssl_Time(); 797 PRUint32 gmt = ssl_Time();
798 SECStatus rv; 798 SECStatus rv;
799 799
(...skipping 1479 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
2289 » * TLS ClientHello. */ 2289 » * TLS initial ClientHello. */
agl 2012/08/15 04:02:23 (nit: I think there should be a 'the' in this comm
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) {
Ryan Sleevi 2012/08/15 03:39:07 if (sidOK), isn't a guarantee that firstHsDone is
agl 2012/08/15 04:02:23 I'm not quite sure that I understand your question
Ryan Sleevi 2012/08/15 04:09:44 If we have a session to attempt a resumption with,
wtc 2012/08/15 16:16:59 If ss->firstHsDone is true, it means the first han
wtc 2012/08/16 01:40:06 I found that my reply has a typo. It should read (
4107 » » if (sid->version <= ss->clientHelloVersion) {
4108 » » ss->version = ss->clientHelloVersion;
Ryan Sleevi 2012/08/15 03:39:07 It seems implicit in this is the assumption that s
wtc 2012/08/15 16:16:59 In this case, the SChannel bug requires us to set
4109 » » } else {
4110 » » sidOK = PR_FALSE;
agl 2012/08/15 04:02:23 Is this case ok? If we reject sid because it's ver
wtc 2012/08/15 16:16:59 This case will be handled correctly on lines 4152-
4111 » » }
4112 » } else {
4113 » » if (ssl3_NegotiateVersion(ss, sid->version,
4114 » » » » » PR_FALSE) != SECSuccess) {
Ryan Sleevi 2012/08/15 03:39:07 nit: Shouldn't it be two tabs, then 4 spaces (matc
wtc 2012/08/15 16:16:59 The original code also uses the maximum number of
4115 » » sidOK = PR_FALSE;
4116 » » }
4117 » }
4093 } 4118 }
4094 4119
4095 if (!sidOK) { 4120 if (!sidOK) {
4096 SSL_AtomicIncrementLong(& ssl3stats.sch_sid_cache_not_ok ); 4121 SSL_AtomicIncrementLong(& ssl3stats.sch_sid_cache_not_ok );
4097 (*ss->sec.uncache)(sid); 4122 (*ss->sec.uncache)(sid);
4098 ssl_FreeSID(sid); 4123 ssl_FreeSID(sid);
4099 sid = NULL; 4124 sid = NULL;
4100 } 4125 }
4101 } 4126 }
4102 4127
4103 if (sid) { 4128 if (sid) {
4104 » serverVersionKnown = PR_TRUE; 4129 » requestingResume = PR_TRUE;
4105 SSL_AtomicIncrementLong(& ssl3stats.sch_sid_cache_hits ); 4130 SSL_AtomicIncrementLong(& ssl3stats.sch_sid_cache_hits );
4106 4131
4107 /* Are we attempting a stateless session resume? */ 4132 /* Are we attempting a stateless session resume? */
4108 if (sid->version > SSL_LIBRARY_VERSION_3_0 && 4133 if (sid->version > SSL_LIBRARY_VERSION_3_0 &&
4109 sid->u.ssl3.sessionTicket.ticket.data) 4134 sid->u.ssl3.sessionTicket.ticket.data)
4110 SSL_AtomicIncrementLong(& ssl3stats.sch_sid_stateless_resumes ); 4135 SSL_AtomicIncrementLong(& ssl3stats.sch_sid_stateless_resumes );
4111 4136
4112 PRINT_BUF(4, (ss, "client, found session-id:", sid->u.ssl3.sessionID, 4137 PRINT_BUF(4, (ss, "client, found session-id:", sid->u.ssl3.sessionID,
4113 sid->u.ssl3.sessionIDLength)); 4138 sid->u.ssl3.sessionIDLength));
4114 4139
4115 ss->ssl3.policy = sid->u.ssl3.policy; 4140 ss->ssl3.policy = sid->u.ssl3.policy;
4116 } else { 4141 } else {
4117 SSL_AtomicIncrementLong(& ssl3stats.sch_sid_cache_misses ); 4142 SSL_AtomicIncrementLong(& ssl3stats.sch_sid_cache_misses );
4118 4143
4119 » rv = ssl3_NegotiateVersion(ss, SSL_LIBRARY_VERSION_MAX_SUPPORTED, 4144 » /*
4120 » » » » PR_TRUE); 4145 » * Windows SChannel compares the client_version inside the RSA
4121 » if (rv != SECSuccess) 4146 » * EncryptedPreMasterSecret of a renegotiation with the
4122 » return rv;» /* error code was set */ 4147 » * client_version of the initial ClientHello rather than the
4148 » * ClientHello in the renegotiation. To work around this bug, we
4149 » * continue to use the client_version used in the initial
4150 » * ClientHello when renegotiating.
4151 » */
4152 » if (ss->firstHsDone) {
4153 » ss->version = ss->clientHelloVersion;
4154 » } else {
4155 » rv = ssl3_NegotiateVersion(ss, SSL_LIBRARY_VERSION_MAX_SUPPORTED,
4156 » » » » PR_TRUE);
4157 » if (rv != SECSuccess)
4158 » » return rv;» /* error code was set */
4159 » }
4123 4160
4124 sid = ssl3_NewSessionID(ss, PR_FALSE); 4161 sid = ssl3_NewSessionID(ss, PR_FALSE);
4125 if (!sid) { 4162 if (!sid) {
4126 return SECFailure; /* memory error is set */ 4163 return SECFailure; /* memory error is set */
4127 } 4164 }
4128 } 4165 }
4129 4166
4130 isTLS = (ss->version > SSL_LIBRARY_VERSION_3_0); 4167 isTLS = (ss->version > SSL_LIBRARY_VERSION_3_0);
4131 ssl_GetSpecWriteLock(ss); 4168 ssl_GetSpecWriteLock(ss);
4132 cwSpec = ss->ssl3.cwSpec; 4169 cwSpec = ss->ssl3.cwSpec;
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
4212 1 + numCompressionMethods + total_exten_len; 4249 1 + numCompressionMethods + total_exten_len;
4213 if (IS_DTLS(ss)) { 4250 if (IS_DTLS(ss)) {
4214 length += 1 + ss->ssl3.hs.cookieLen; 4251 length += 1 + ss->ssl3.hs.cookieLen;
4215 } 4252 }
4216 4253
4217 rv = ssl3_AppendHandshakeHeader(ss, client_hello, length); 4254 rv = ssl3_AppendHandshakeHeader(ss, client_hello, length);
4218 if (rv != SECSuccess) { 4255 if (rv != SECSuccess) {
4219 return rv; /* err set by ssl3_AppendHandshake* */ 4256 return rv; /* err set by ssl3_AppendHandshake* */
4220 } 4257 }
4221 4258
4259 if (ss->firstHsDone) {
4260 /* Work around the Windows SChannel bug described above. */
4261 PORT_Assert(ss->version == ss->clientHelloVersion);
4262 }
4222 ss->clientHelloVersion = ss->version; 4263 ss->clientHelloVersion = ss->version;
4223 if (IS_DTLS(ss)) { 4264 if (IS_DTLS(ss)) {
4224 PRUint16 version; 4265 PRUint16 version;
4225 4266
4226 version = dtls_TLSVersionToDTLSVersion(ss->clientHelloVersion); 4267 version = dtls_TLSVersionToDTLSVersion(ss->clientHelloVersion);
4227 rv = ssl3_AppendHandshakeNumber(ss, version, 2); 4268 rv = ssl3_AppendHandshakeNumber(ss, version, 2);
4228 } else { 4269 } else {
4229 rv = ssl3_AppendHandshakeNumber(ss, ss->clientHelloVersion, 2); 4270 rv = ssl3_AppendHandshakeNumber(ss, ss->clientHelloVersion, 2);
4230 } 4271 }
4231 if (rv != SECSuccess) { 4272 if (rv != SECSuccess) {
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
4330 maxBytes -= extLen; 4371 maxBytes -= extLen;
4331 PORT_Assert(!maxBytes); 4372 PORT_Assert(!maxBytes);
4332 } 4373 }
4333 if (ss->ssl3.hs.sendingSCSV) { 4374 if (ss->ssl3.hs.sendingSCSV) {
4334 /* Since we sent the SCSV, pretend we sent empty RI extension. */ 4375 /* Since we sent the SCSV, pretend we sent empty RI extension. */
4335 TLSExtensionData *xtnData = &ss->xtnData; 4376 TLSExtensionData *xtnData = &ss->xtnData;
4336 xtnData->advertised[xtnData->numAdvertised++] = 4377 xtnData->advertised[xtnData->numAdvertised++] =
4337 ssl_renegotiation_info_xtn; 4378 ssl_renegotiation_info_xtn;
4338 } 4379 }
4339 4380
4381 ss->ssl3.hs.ws = wait_server_hello;
Ryan Sleevi 2012/08/15 03:39:07 Did you mean to move this? It doesn't seem related
wtc 2012/08/15 16:16:59 Yes, this line needs to be moved here to support t
4340 flags = 0; 4382 flags = 0;
4341 if (!serverVersionKnown && !IS_DTLS(ss)) { 4383 if (!ss->firstHsDone && !requestingResume && !IS_DTLS(ss)) {
4342 flags |= ssl_SEND_FLAG_CAP_RECORD_VERSION; 4384 flags |= ssl_SEND_FLAG_CAP_RECORD_VERSION;
4343 } 4385 }
4344 rv = ssl3_FlushHandshake(ss, flags); 4386 rv = ssl3_FlushHandshake(ss, flags);
4345 if (rv != SECSuccess) { 4387 if (rv != SECSuccess) {
4346 return rv; /* error code set by ssl3_FlushHandshake */ 4388 return rv; /* error code set by ssl3_FlushHandshake */
4347 } 4389 }
4348 4390
4349 ss->ssl3.hs.ws = wait_server_hello;
4350 return rv; 4391 return rv;
4351 } 4392 }
4352 4393
4353 4394
4354 /* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete 4395 /* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
4355 * ssl3 Hello Request. 4396 * ssl3 Hello Request.
4356 * Caller must hold Handshake and RecvBuf locks. 4397 * Caller must hold Handshake and RecvBuf locks.
4357 */ 4398 */
4358 static SECStatus 4399 static SECStatus
4359 ssl3_HandleHelloRequest(sslSocket *ss) 4400 ssl3_HandleHelloRequest(sslSocket *ss)
(...skipping 6432 matching lines...) Expand 10 before | Expand all | Expand 10 after
10792 PORT_Free(ss->ssl3.hs.recvdFragments.buf); 10833 PORT_Free(ss->ssl3.hs.recvdFragments.buf);
10793 } 10834 }
10794 } 10835 }
10795 10836
10796 ss->ssl3.initialized = PR_FALSE; 10837 ss->ssl3.initialized = PR_FALSE;
10797 10838
10798 SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE); 10839 SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE);
10799 } 10840 }
10800 10841
10801 /* End of ssl3con.c */ 10842 /* End of ssl3con.c */
OLDNEW
« no previous file with comments | « no previous file | net/third_party/nss/ssl/sslsock.c » ('j') | net/third_party/nss/ssl/sslsock.c » ('J')

Powered by Google App Engine
This is Rietveld 408576698