| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // This file includes code SSLClientSocketNSS::DoVerifyCertComplete() derived | 5 // This file includes code SSLClientSocketNSS::DoVerifyCertComplete() derived |
| 6 // from AuthCertificateCallback() in | 6 // from AuthCertificateCallback() in |
| 7 // mozilla/security/manager/ssl/src/nsNSSCallbacks.cpp. | 7 // mozilla/security/manager/ssl/src/nsNSSCallbacks.cpp. |
| 8 | 8 |
| 9 /* ***** BEGIN LICENSE BLOCK ***** | 9 /* ***** BEGIN LICENSE BLOCK ***** |
| 10 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 | 10 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 |
| (...skipping 567 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 578 // Attempt to initialize the peer name. In the case of TCP FastOpen, | 578 // Attempt to initialize the peer name. In the case of TCP FastOpen, |
| 579 // we don't have the peer yet. | 579 // we don't have the peer yet. |
| 580 if (!UsingTCPFastOpen()) { | 580 if (!UsingTCPFastOpen()) { |
| 581 rv = InitializeSSLPeerName(); | 581 rv = InitializeSSLPeerName(); |
| 582 if (rv != OK) { | 582 if (rv != OK) { |
| 583 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_CONNECT, rv); | 583 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_CONNECT, rv); |
| 584 return rv; | 584 return rv; |
| 585 } | 585 } |
| 586 } | 586 } |
| 587 | 587 |
| 588 GotoState(STATE_HANDSHAKE); | 588 if (ssl_config_.cached_info_enabled && ssl_host_info_.get()) { |
| 589 GotoState(STATE_LOAD_SSL_HOST_INFO); |
| 590 } else { |
| 591 GotoState(STATE_HANDSHAKE); |
| 592 } |
| 589 | 593 |
| 590 rv = DoHandshakeLoop(OK); | 594 rv = DoHandshakeLoop(OK); |
| 591 if (rv == ERR_IO_PENDING) { | 595 if (rv == ERR_IO_PENDING) { |
| 592 user_connect_callback_ = callback; | 596 user_connect_callback_ = callback; |
| 593 } else { | 597 } else { |
| 594 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_CONNECT, rv); | 598 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_CONNECT, rv); |
| 595 } | 599 } |
| 596 | 600 |
| 597 LeaveFunction(""); | 601 LeaveFunction(""); |
| 598 return rv > OK ? OK : rv; | 602 return rv > OK ? OK : rv; |
| (...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 909 reinterpret_cast<const unsigned char *>(ssl_config_.next_protos.data()), | 913 reinterpret_cast<const unsigned char *>(ssl_config_.next_protos.data()), |
| 910 ssl_config_.next_protos.size()); | 914 ssl_config_.next_protos.size()); |
| 911 if (rv != SECSuccess) | 915 if (rv != SECSuccess) |
| 912 LogFailedNSSFunction(net_log_, "SSL_SetNextProtoNego", ""); | 916 LogFailedNSSFunction(net_log_, "SSL_SetNextProtoNego", ""); |
| 913 } | 917 } |
| 914 #endif | 918 #endif |
| 915 | 919 |
| 916 #ifdef SSL_ENABLE_OCSP_STAPLING | 920 #ifdef SSL_ENABLE_OCSP_STAPLING |
| 917 if (IsOCSPStaplingSupported()) { | 921 if (IsOCSPStaplingSupported()) { |
| 918 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_OCSP_STAPLING, PR_TRUE); | 922 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_OCSP_STAPLING, PR_TRUE); |
| 919 if (rv != SECSuccess) | 923 if (rv != SECSuccess) { |
| 920 LogFailedNSSFunction(net_log_, "SSL_OptionSet (OCSP stapling)", ""); | 924 LogFailedNSSFunction(net_log_, "SSL_OptionSet", |
| 925 "SSL_ENABLE_OCSP_STAPLING"); |
| 926 } |
| 921 } | 927 } |
| 922 #endif | 928 #endif |
| 923 | 929 |
| 930 #ifdef SSL_ENABLE_CACHED_INFO |
| 931 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_CACHED_INFO, |
| 932 ssl_config_.cached_info_enabled); |
| 933 if (rv != SECSuccess) |
| 934 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_ENABLE_CACHED_INFO"); |
| 935 #endif |
| 936 |
| 924 rv = SSL_OptionSet(nss_fd_, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE); | 937 rv = SSL_OptionSet(nss_fd_, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE); |
| 925 if (rv != SECSuccess) { | 938 if (rv != SECSuccess) { |
| 926 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_HANDSHAKE_AS_CLIENT"); | 939 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_HANDSHAKE_AS_CLIENT"); |
| 927 return ERR_UNEXPECTED; | 940 return ERR_UNEXPECTED; |
| 928 } | 941 } |
| 929 | 942 |
| 930 rv = SSL_AuthCertificateHook(nss_fd_, OwnAuthCertHandler, this); | 943 rv = SSL_AuthCertificateHook(nss_fd_, OwnAuthCertHandler, this); |
| 931 if (rv != SECSuccess) { | 944 if (rv != SECSuccess) { |
| 932 LogFailedNSSFunction(net_log_, "SSL_AuthCertificateHook", ""); | 945 LogFailedNSSFunction(net_log_, "SSL_AuthCertificateHook", ""); |
| 933 return ERR_UNEXPECTED; | 946 return ERR_UNEXPECTED; |
| (...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1195 // (This is a quirk carried over from the windows | 1208 // (This is a quirk carried over from the windows |
| 1196 // implementation. It makes reading the logs a bit harder.) | 1209 // implementation. It makes reading the logs a bit harder.) |
| 1197 // State handlers can and often do call GotoState just | 1210 // State handlers can and often do call GotoState just |
| 1198 // to stay in the current state. | 1211 // to stay in the current state. |
| 1199 State state = next_handshake_state_; | 1212 State state = next_handshake_state_; |
| 1200 GotoState(STATE_NONE); | 1213 GotoState(STATE_NONE); |
| 1201 switch (state) { | 1214 switch (state) { |
| 1202 case STATE_NONE: | 1215 case STATE_NONE: |
| 1203 // we're just pumping data between the buffer and the network | 1216 // we're just pumping data between the buffer and the network |
| 1204 break; | 1217 break; |
| 1218 case STATE_LOAD_SSL_HOST_INFO: |
| 1219 rv = DoLoadSSLHostInfo(); |
| 1220 break; |
| 1205 case STATE_HANDSHAKE: | 1221 case STATE_HANDSHAKE: |
| 1206 rv = DoHandshake(); | 1222 rv = DoHandshake(); |
| 1207 break; | 1223 break; |
| 1208 case STATE_VERIFY_DNSSEC: | 1224 case STATE_VERIFY_DNSSEC: |
| 1209 rv = DoVerifyDNSSEC(rv); | 1225 rv = DoVerifyDNSSEC(rv); |
| 1210 break; | 1226 break; |
| 1211 case STATE_VERIFY_CERT: | 1227 case STATE_VERIFY_CERT: |
| 1212 DCHECK(rv == OK); | 1228 DCHECK(rv == OK); |
| 1213 rv = DoVerifyCert(rv); | 1229 rv = DoVerifyCert(rv); |
| 1214 break; | 1230 break; |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1276 int rv; | 1292 int rv; |
| 1277 do { | 1293 do { |
| 1278 rv = DoPayloadWrite(); | 1294 rv = DoPayloadWrite(); |
| 1279 network_moved = DoTransportIO(); | 1295 network_moved = DoTransportIO(); |
| 1280 } while (rv == ERR_IO_PENDING && network_moved); | 1296 } while (rv == ERR_IO_PENDING && network_moved); |
| 1281 | 1297 |
| 1282 LeaveFunction(""); | 1298 LeaveFunction(""); |
| 1283 return rv; | 1299 return rv; |
| 1284 } | 1300 } |
| 1285 | 1301 |
| 1302 bool SSLClientSocketNSS::LoadSSLHostInfo() { |
| 1303 const SSLHostInfo::State& state(ssl_host_info_->state()); |
| 1304 |
| 1305 if (state.certs.empty()) |
| 1306 return false; |
| 1307 |
| 1308 SECStatus rv; |
| 1309 const std::vector<std::string>& certs_in = state.certs; |
| 1310 scoped_array<CERTCertificate*> certs(new CERTCertificate*[certs_in.size()]); |
| 1311 |
| 1312 for (size_t i = 0; i < certs_in.size(); i++) { |
| 1313 SECItem derCert; |
| 1314 derCert.data = |
| 1315 const_cast<uint8*>(reinterpret_cast<const uint8*>(certs_in[i].data())); |
| 1316 derCert.len = certs_in[i].size(); |
| 1317 certs[i] = CERT_NewTempCertificate( |
| 1318 CERT_GetDefaultCertDB(), &derCert, NULL /* no nickname given */, |
| 1319 PR_FALSE /* not permanent */, PR_TRUE /* copy DER data */); |
| 1320 if (!certs[i]) { |
| 1321 DestroyCertificates(&certs[0], i); |
| 1322 NOTREACHED(); |
| 1323 return false; |
| 1324 } |
| 1325 } |
| 1326 |
| 1327 rv = SSL_SetPredictedPeerCertificates(nss_fd_, certs.get(), certs_in.size()); |
| 1328 DestroyCertificates(&certs[0], certs_in.size()); |
| 1329 DCHECK_EQ(SECSuccess, rv); |
| 1330 |
| 1331 return true; |
| 1332 } |
| 1333 |
| 1334 int SSLClientSocketNSS::DoLoadSSLHostInfo() { |
| 1335 int rv; |
| 1336 |
| 1337 EnterFunction(""); |
| 1338 rv = ssl_host_info_->WaitForDataReady(&handshake_io_callback_); |
| 1339 GotoState(STATE_HANDSHAKE); |
| 1340 |
| 1341 if (rv == OK) { |
| 1342 if (!LoadSSLHostInfo()) |
| 1343 LOG(WARNING) << "LoadSSLHostInfo failed: " << host_and_port_.ToString(); |
| 1344 } else { |
| 1345 DCHECK_EQ(ERR_IO_PENDING, rv); |
| 1346 GotoState(STATE_LOAD_SSL_HOST_INFO); |
| 1347 } |
| 1348 |
| 1349 LeaveFunction(""); |
| 1350 return rv; |
| 1351 } |
| 1352 |
| 1286 int SSLClientSocketNSS::DoHandshake() { | 1353 int SSLClientSocketNSS::DoHandshake() { |
| 1287 EnterFunction(""); | 1354 EnterFunction(""); |
| 1288 int net_error = net::OK; | 1355 int net_error = net::OK; |
| 1289 SECStatus rv = SSL_ForceHandshake(nss_fd_); | 1356 SECStatus rv = SSL_ForceHandshake(nss_fd_); |
| 1290 | 1357 |
| 1291 if (client_auth_cert_needed_) { | 1358 if (client_auth_cert_needed_) { |
| 1292 net_error = ERR_SSL_CLIENT_AUTH_CERT_NEEDED; | 1359 net_error = ERR_SSL_CLIENT_AUTH_CERT_NEEDED; |
| 1293 net_log_.AddEvent(NetLog::TYPE_SSL_HANDSHAKE_ERROR, | 1360 net_log_.AddEvent(NetLog::TYPE_SSL_HANDSHAKE_ERROR, |
| 1294 make_scoped_refptr(new SSLErrorParams(net_error, 0))); | 1361 make_scoped_refptr(new SSLErrorParams(net_error, 0))); |
| 1295 // If the handshake already succeeded (because the server requests but | 1362 // If the handshake already succeeded (because the server requests but |
| 1296 // doesn't require a client cert), we need to invalidate the SSL session | 1363 // doesn't require a client cert), we need to invalidate the SSL session |
| 1297 // so that we won't try to resume the non-client-authenticated session in | 1364 // so that we won't try to resume the non-client-authenticated session in |
| 1298 // the next handshake. This will cause the server to ask for a client | 1365 // the next handshake. This will cause the server to ask for a client |
| 1299 // cert again. | 1366 // cert again. |
| 1300 if (rv == SECSuccess && SSL_InvalidateSession(nss_fd_) != SECSuccess) { | 1367 if (rv == SECSuccess && SSL_InvalidateSession(nss_fd_) != SECSuccess) { |
| 1301 LOG(WARNING) << "Couldn't invalidate SSL session: " << PR_GetError(); | 1368 LOG(WARNING) << "Couldn't invalidate SSL session: " << PR_GetError(); |
| 1302 } | 1369 } |
| 1303 } else if (rv == SECSuccess) { | 1370 } else if (rv == SECSuccess) { |
| 1304 if (handshake_callback_called_) { | 1371 if (handshake_callback_called_) { |
| 1305 if (eset_mitm_detected_) { | 1372 if (eset_mitm_detected_) { |
| 1306 net_error = ERR_ESET_ANTI_VIRUS_SSL_INTERCEPTION; | 1373 net_error = ERR_ESET_ANTI_VIRUS_SSL_INTERCEPTION; |
| 1307 } else { | 1374 } else { |
| 1308 // We need to see if the predicted certificate chain (in | 1375 // We need to see if the predicted certificate chain (in |
| 1309 // |ssl_host_info_->state().certs) matches the actual certificate chain | 1376 // |ssl_host_info_->state().certs) matches the actual certificate chain |
| 1310 // before we try to save it before we update |ssl_host_info_|. | 1377 // before we call SaveSSLHostInfo, as that will update |
| 1378 // |ssl_host_info_|. |
| 1311 if (ssl_host_info_.get() && !ssl_host_info_->state().certs.empty()) { | 1379 if (ssl_host_info_.get() && !ssl_host_info_->state().certs.empty()) { |
| 1312 PeerCertificateChain certs(nss_fd_); | 1380 PeerCertificateChain certs(nss_fd_); |
| 1313 const SSLHostInfo::State& state = ssl_host_info_->state(); | 1381 const SSLHostInfo::State& state = ssl_host_info_->state(); |
| 1314 predicted_cert_chain_correct_ = certs.size() == state.certs.size(); | 1382 predicted_cert_chain_correct_ = certs.size() == state.certs.size(); |
| 1315 if (predicted_cert_chain_correct_) { | 1383 if (predicted_cert_chain_correct_) { |
| 1316 for (unsigned i = 0; i < certs.size(); i++) { | 1384 for (unsigned i = 0; i < certs.size(); i++) { |
| 1317 if (certs[i]->derCert.len != state.certs[i].size() || | 1385 if (certs[i]->derCert.len != state.certs[i].size() || |
| 1318 memcmp(certs[i]->derCert.data, state.certs[i].data(), | 1386 memcmp(certs[i]->derCert.data, state.certs[i].data(), |
| 1319 certs[i]->derCert.len) != 0) { | 1387 certs[i]->derCert.len) != 0) { |
| 1320 predicted_cert_chain_correct_ = false; | 1388 predicted_cert_chain_correct_ = false; |
| (...skipping 852 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2173 valid_thread_id_ = base::PlatformThread::CurrentId(); | 2241 valid_thread_id_ = base::PlatformThread::CurrentId(); |
| 2174 } | 2242 } |
| 2175 | 2243 |
| 2176 bool SSLClientSocketNSS::CalledOnValidThread() const { | 2244 bool SSLClientSocketNSS::CalledOnValidThread() const { |
| 2177 EnsureThreadIdAssigned(); | 2245 EnsureThreadIdAssigned(); |
| 2178 base::AutoLock auto_lock(lock_); | 2246 base::AutoLock auto_lock(lock_); |
| 2179 return valid_thread_id_ == base::PlatformThread::CurrentId(); | 2247 return valid_thread_id_ == base::PlatformThread::CurrentId(); |
| 2180 } | 2248 } |
| 2181 | 2249 |
| 2182 } // namespace net | 2250 } // namespace net |
| OLD | NEW |