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 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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"); | |
wtc
2011/06/17 22:57:09
Nit: add curly braces {} around the "if" statement
rkn
2011/06/20 21:21:09
Done.
| |
921 } | 926 } |
922 #endif | 927 #endif |
923 | 928 |
929 #ifdef SSL_ENABLE_CACHED_INFO | |
930 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_CACHED_INFO, | |
931 ssl_config_.cached_info_enabled); | |
932 if (rv != SECSuccess) | |
933 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_ENABLE_CACHED_INFO"); | |
934 #endif | |
935 | |
924 rv = SSL_OptionSet(nss_fd_, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE); | 936 rv = SSL_OptionSet(nss_fd_, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE); |
925 if (rv != SECSuccess) { | 937 if (rv != SECSuccess) { |
926 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_HANDSHAKE_AS_CLIENT"); | 938 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_HANDSHAKE_AS_CLIENT"); |
927 return ERR_UNEXPECTED; | 939 return ERR_UNEXPECTED; |
928 } | 940 } |
929 | 941 |
930 rv = SSL_AuthCertificateHook(nss_fd_, OwnAuthCertHandler, this); | 942 rv = SSL_AuthCertificateHook(nss_fd_, OwnAuthCertHandler, this); |
931 if (rv != SECSuccess) { | 943 if (rv != SECSuccess) { |
932 LogFailedNSSFunction(net_log_, "SSL_AuthCertificateHook", ""); | 944 LogFailedNSSFunction(net_log_, "SSL_AuthCertificateHook", ""); |
933 return ERR_UNEXPECTED; | 945 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 | 1207 // (This is a quirk carried over from the windows |
1196 // implementation. It makes reading the logs a bit harder.) | 1208 // implementation. It makes reading the logs a bit harder.) |
1197 // State handlers can and often do call GotoState just | 1209 // State handlers can and often do call GotoState just |
1198 // to stay in the current state. | 1210 // to stay in the current state. |
1199 State state = next_handshake_state_; | 1211 State state = next_handshake_state_; |
1200 GotoState(STATE_NONE); | 1212 GotoState(STATE_NONE); |
1201 switch (state) { | 1213 switch (state) { |
1202 case STATE_NONE: | 1214 case STATE_NONE: |
1203 // we're just pumping data between the buffer and the network | 1215 // we're just pumping data between the buffer and the network |
1204 break; | 1216 break; |
1217 case STATE_LOAD_SSL_HOST_INFO: | |
1218 rv = DoLoadSSLHostInfo(); | |
1219 break; | |
1205 case STATE_HANDSHAKE: | 1220 case STATE_HANDSHAKE: |
1206 rv = DoHandshake(); | 1221 rv = DoHandshake(); |
1207 break; | 1222 break; |
1208 case STATE_VERIFY_DNSSEC: | 1223 case STATE_VERIFY_DNSSEC: |
1209 rv = DoVerifyDNSSEC(rv); | 1224 rv = DoVerifyDNSSEC(rv); |
1210 break; | 1225 break; |
1211 case STATE_VERIFY_CERT: | 1226 case STATE_VERIFY_CERT: |
1212 DCHECK(rv == OK); | 1227 DCHECK(rv == OK); |
1213 rv = DoVerifyCert(rv); | 1228 rv = DoVerifyCert(rv); |
1214 break; | 1229 break; |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1276 int rv; | 1291 int rv; |
1277 do { | 1292 do { |
1278 rv = DoPayloadWrite(); | 1293 rv = DoPayloadWrite(); |
1279 network_moved = DoTransportIO(); | 1294 network_moved = DoTransportIO(); |
1280 } while (rv == ERR_IO_PENDING && network_moved); | 1295 } while (rv == ERR_IO_PENDING && network_moved); |
1281 | 1296 |
1282 LeaveFunction(""); | 1297 LeaveFunction(""); |
1283 return rv; | 1298 return rv; |
1284 } | 1299 } |
1285 | 1300 |
1301 bool SSLClientSocketNSS::LoadSSLHostInfo() { | |
1302 const SSLHostInfo::State& state(ssl_host_info_->state()); | |
1303 | |
1304 if (state.certs.empty()) { | |
1305 return false; | |
1306 } | |
wtc
2011/06/17 22:57:09
Nit: in the "net" directory, don't use curly brace
rkn
2011/06/20 21:21:09
Done.
| |
1307 | |
1308 SECStatus rv; | |
1309 | |
1310 const std::vector<std::string>& certs_in = state.certs; | |
1311 scoped_array<CERTCertificate*> certs(new CERTCertificate*[certs_in.size()]); | |
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 EnterFunction(""); | |
1336 int rv = ssl_host_info_->WaitForDataReady(&handshake_io_callback_); | |
1337 GotoState(STATE_HANDSHAKE); | |
1338 | |
1339 if (rv == OK) { | |
1340 if (!LoadSSLHostInfo()) | |
1341 LOG(WARNING) << "LoadSSLHostInfo failed: " << host_and_port_.ToString(); | |
1342 } else { | |
1343 DCHECK_EQ(ERR_IO_PENDING, rv); | |
1344 GotoState(STATE_LOAD_SSL_HOST_INFO); | |
1345 } | |
1346 | |
1347 LeaveFunction(""); | |
1348 return rv; | |
1349 } | |
1350 | |
1286 int SSLClientSocketNSS::DoHandshake() { | 1351 int SSLClientSocketNSS::DoHandshake() { |
1287 EnterFunction(""); | 1352 EnterFunction(""); |
1288 int net_error = net::OK; | 1353 int net_error = net::OK; |
1289 SECStatus rv = SSL_ForceHandshake(nss_fd_); | 1354 SECStatus rv = SSL_ForceHandshake(nss_fd_); |
1290 | 1355 |
1291 if (client_auth_cert_needed_) { | 1356 if (client_auth_cert_needed_) { |
1292 net_error = ERR_SSL_CLIENT_AUTH_CERT_NEEDED; | 1357 net_error = ERR_SSL_CLIENT_AUTH_CERT_NEEDED; |
1293 net_log_.AddEvent(NetLog::TYPE_SSL_HANDSHAKE_ERROR, | 1358 net_log_.AddEvent(NetLog::TYPE_SSL_HANDSHAKE_ERROR, |
1294 make_scoped_refptr(new SSLErrorParams(net_error, 0))); | 1359 make_scoped_refptr(new SSLErrorParams(net_error, 0))); |
1295 // If the handshake already succeeded (because the server requests but | 1360 // If the handshake already succeeded (because the server requests but |
1296 // doesn't require a client cert), we need to invalidate the SSL session | 1361 // 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 | 1362 // 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 | 1363 // the next handshake. This will cause the server to ask for a client |
1299 // cert again. | 1364 // cert again. |
1300 if (rv == SECSuccess && SSL_InvalidateSession(nss_fd_) != SECSuccess) { | 1365 if (rv == SECSuccess && SSL_InvalidateSession(nss_fd_) != SECSuccess) { |
1301 LOG(WARNING) << "Couldn't invalidate SSL session: " << PR_GetError(); | 1366 LOG(WARNING) << "Couldn't invalidate SSL session: " << PR_GetError(); |
1302 } | 1367 } |
1303 } else if (rv == SECSuccess) { | 1368 } else if (rv == SECSuccess) { |
1304 if (handshake_callback_called_) { | 1369 if (handshake_callback_called_) { |
1305 if (eset_mitm_detected_) { | 1370 if (eset_mitm_detected_) { |
1306 net_error = ERR_ESET_ANTI_VIRUS_SSL_INTERCEPTION; | 1371 net_error = ERR_ESET_ANTI_VIRUS_SSL_INTERCEPTION; |
1307 } else { | 1372 } else { |
1308 // We need to see if the predicted certificate chain (in | 1373 // We need to see if the predicted certificate chain (in |
1309 // |ssl_host_info_->state().certs) matches the actual certificate chain | 1374 // |ssl_host_info_->state().certs) matches the actual certificate chain |
1310 // before we try to save it before we update |ssl_host_info_|. | 1375 // before we call SaveSSLHostInfo, as that will update |
1376 // |ssl_host_info_|. | |
1311 if (ssl_host_info_.get() && !ssl_host_info_->state().certs.empty()) { | 1377 if (ssl_host_info_.get() && !ssl_host_info_->state().certs.empty()) { |
1312 PeerCertificateChain certs(nss_fd_); | 1378 PeerCertificateChain certs(nss_fd_); |
1313 const SSLHostInfo::State& state = ssl_host_info_->state(); | 1379 const SSLHostInfo::State& state = ssl_host_info_->state(); |
1314 predicted_cert_chain_correct_ = certs.size() == state.certs.size(); | 1380 predicted_cert_chain_correct_ = certs.size() == state.certs.size(); |
1315 if (predicted_cert_chain_correct_) { | 1381 if (predicted_cert_chain_correct_) { |
1316 for (unsigned i = 0; i < certs.size(); i++) { | 1382 for (unsigned i = 0; i < certs.size(); i++) { |
1317 if (certs[i]->derCert.len != state.certs[i].size() || | 1383 if (certs[i]->derCert.len != state.certs[i].size() || |
1318 memcmp(certs[i]->derCert.data, state.certs[i].data(), | 1384 memcmp(certs[i]->derCert.data, state.certs[i].data(), |
1319 certs[i]->derCert.len) != 0) { | 1385 certs[i]->derCert.len) != 0) { |
1320 predicted_cert_chain_correct_ = false; | 1386 predicted_cert_chain_correct_ = false; |
(...skipping 861 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2182 valid_thread_id_ = base::PlatformThread::CurrentId(); | 2248 valid_thread_id_ = base::PlatformThread::CurrentId(); |
2183 } | 2249 } |
2184 | 2250 |
2185 bool SSLClientSocketNSS::CalledOnValidThread() const { | 2251 bool SSLClientSocketNSS::CalledOnValidThread() const { |
2186 EnsureThreadIdAssigned(); | 2252 EnsureThreadIdAssigned(); |
2187 base::AutoLock auto_lock(lock_); | 2253 base::AutoLock auto_lock(lock_); |
2188 return valid_thread_id_ == base::PlatformThread::CurrentId(); | 2254 return valid_thread_id_ == base::PlatformThread::CurrentId(); |
2189 } | 2255 } |
2190 | 2256 |
2191 } // namespace net | 2257 } // namespace net |
OLD | NEW |