OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 */ |
OLD | NEW |