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

Side by Side Diff: net/socket/ssl_client_socket_nss.cc

Issue 7058049: Added client-side support for the TLS cached info extension. This feature is disabled by default ... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Added Null pointer check Created 9 years, 6 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
OLDNEW
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 602 matching lines...) Expand 10 before | Expand all | Expand 10 after
613 // Attempt to initialize the peer name. In the case of TCP FastOpen, 613 // Attempt to initialize the peer name. In the case of TCP FastOpen,
614 // we don't have the peer yet. 614 // we don't have the peer yet.
615 if (!UsingTCPFastOpen()) { 615 if (!UsingTCPFastOpen()) {
616 rv = InitializeSSLPeerName(); 616 rv = InitializeSSLPeerName();
617 if (rv != OK) { 617 if (rv != OK) {
618 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_CONNECT, rv); 618 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_CONNECT, rv);
619 return rv; 619 return rv;
620 } 620 }
621 } 621 }
622 622
623 GotoState(STATE_HANDSHAKE); 623 if (ssl_host_info_.get()) {
wtc 2011/06/03 22:56:55 This should also check that the cached info extens
rkn 2011/06/04 20:50:19 Done.
624 GotoState(STATE_LOAD_SSL_HOST_INFO);
625 } else {
626 GotoState(STATE_HANDSHAKE);
627 }
624 628
625 rv = DoHandshakeLoop(OK); 629 rv = DoHandshakeLoop(OK);
626 if (rv == ERR_IO_PENDING) { 630 if (rv == ERR_IO_PENDING) {
627 user_connect_callback_ = callback; 631 user_connect_callback_ = callback;
628 } else { 632 } else {
629 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_CONNECT, rv); 633 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_CONNECT, rv);
630 } 634 }
631 635
632 LeaveFunction(""); 636 LeaveFunction("");
633 return rv > OK ? OK : rv; 637 return rv > OK ? OK : rv;
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after
949 #endif 953 #endif
950 954
951 #ifdef SSL_ENABLE_OCSP_STAPLING 955 #ifdef SSL_ENABLE_OCSP_STAPLING
952 if (IsOCSPStaplingSupported()) { 956 if (IsOCSPStaplingSupported()) {
953 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_OCSP_STAPLING, PR_TRUE); 957 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_OCSP_STAPLING, PR_TRUE);
954 if (rv != SECSuccess) 958 if (rv != SECSuccess)
955 LogFailedNSSFunction(net_log_, "SSL_OptionSet (OCSP stapling)", ""); 959 LogFailedNSSFunction(net_log_, "SSL_OptionSet (OCSP stapling)", "");
956 } 960 }
957 #endif 961 #endif
958 962
963 #ifdef SSL_ENABLE_CACHED_INFO
964 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_CACHED_INFO,
965 ssl_config_.cached_info_enabled);
966 if (rv != SECSuccess)
967 LogFailedNSSFunction(net_log_, "SSL_OptionSet (CachedInfo)", "");
wtc 2011/06/03 22:56:55 I think we should imitate lines 940 and 972 instea
rkn 2011/06/04 20:50:19 Done.
968 #endif
969
959 rv = SSL_OptionSet(nss_fd_, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE); 970 rv = SSL_OptionSet(nss_fd_, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE);
960 if (rv != SECSuccess) { 971 if (rv != SECSuccess) {
961 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_HANDSHAKE_AS_CLIENT"); 972 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_HANDSHAKE_AS_CLIENT");
962 return ERR_UNEXPECTED; 973 return ERR_UNEXPECTED;
963 } 974 }
964 975
965 rv = SSL_AuthCertificateHook(nss_fd_, OwnAuthCertHandler, this); 976 rv = SSL_AuthCertificateHook(nss_fd_, OwnAuthCertHandler, this);
966 if (rv != SECSuccess) { 977 if (rv != SECSuccess) {
967 LogFailedNSSFunction(net_log_, "SSL_AuthCertificateHook", ""); 978 LogFailedNSSFunction(net_log_, "SSL_AuthCertificateHook", "");
968 return ERR_UNEXPECTED; 979 return ERR_UNEXPECTED;
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
1230 // (This is a quirk carried over from the windows 1241 // (This is a quirk carried over from the windows
1231 // implementation. It makes reading the logs a bit harder.) 1242 // implementation. It makes reading the logs a bit harder.)
1232 // State handlers can and often do call GotoState just 1243 // State handlers can and often do call GotoState just
1233 // to stay in the current state. 1244 // to stay in the current state.
1234 State state = next_handshake_state_; 1245 State state = next_handshake_state_;
1235 GotoState(STATE_NONE); 1246 GotoState(STATE_NONE);
1236 switch (state) { 1247 switch (state) {
1237 case STATE_NONE: 1248 case STATE_NONE:
1238 // we're just pumping data between the buffer and the network 1249 // we're just pumping data between the buffer and the network
1239 break; 1250 break;
1251 case STATE_LOAD_SSL_HOST_INFO:
1252 rv = DoLoadSSLHostInfo();
1253 break;
1240 case STATE_HANDSHAKE: 1254 case STATE_HANDSHAKE:
1241 rv = DoHandshake(); 1255 rv = DoHandshake();
1242 break; 1256 break;
1243 case STATE_VERIFY_DNSSEC: 1257 case STATE_VERIFY_DNSSEC:
1244 rv = DoVerifyDNSSEC(rv); 1258 rv = DoVerifyDNSSEC(rv);
1245 break; 1259 break;
1246 case STATE_VERIFY_DNSSEC_COMPLETE: 1260 case STATE_VERIFY_DNSSEC_COMPLETE:
1247 rv = DoVerifyDNSSECComplete(rv); 1261 rv = DoVerifyDNSSECComplete(rv);
1248 break; 1262 break;
1249 case STATE_VERIFY_CERT: 1263 case STATE_VERIFY_CERT:
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1314 int rv; 1328 int rv;
1315 do { 1329 do {
1316 rv = DoPayloadWrite(); 1330 rv = DoPayloadWrite();
1317 network_moved = DoTransportIO(); 1331 network_moved = DoTransportIO();
1318 } while (rv == ERR_IO_PENDING && network_moved); 1332 } while (rv == ERR_IO_PENDING && network_moved);
1319 1333
1320 LeaveFunction(""); 1334 LeaveFunction("");
1321 return rv; 1335 return rv;
1322 } 1336 }
1323 1337
1338 bool SSLClientSocketNSS::LoadSSLHostInfo() {
1339 const SSLHostInfo::State& state(ssl_host_info_->state());
1340
1341 if (state.certs.empty()) {
1342 return false;
1343 }
1344
1345 SECStatus rv;
1346
1347 const std::vector<std::string>& certs_in = state.certs;
1348 scoped_array<CERTCertificate*> certs(new CERTCertificate*[certs_in.size()]);
1349 for (size_t i = 0; i < certs_in.size(); i++) {
1350 SECItem derCert;
1351 derCert.data =
1352 const_cast<uint8*>(reinterpret_cast<const uint8*>(certs_in[i].data()));
1353 derCert.len = certs_in[i].size();
1354 certs[i] = CERT_NewTempCertificate(
1355 CERT_GetDefaultCertDB(), &derCert, NULL /* no nickname given */,
1356 PR_FALSE /* not permanent */, PR_TRUE /* copy DER data */);
1357 if (!certs[i]) {
1358 DestroyCertificates(&certs[0], i);
1359 NOTREACHED(); // I don't understand this line.
1360 return false;
1361 }
1362 }
1363
1364 rv = SSL_SetPredictedPeerCertificates(nss_fd_, certs.get(), certs_in.size());
1365 DestroyCertificates(&certs[0], certs_in.size());
1366 DCHECK_EQ(SECSuccess, rv);
1367
1368 return true;
1369 }
1370
1371 int SSLClientSocketNSS::DoLoadSSLHostInfo() {
1372 EnterFunction("");
1373 int rv = ssl_host_info_->WaitForDataReady(&handshake_io_callback_);
1374 GotoState(STATE_HANDSHAKE);
1375
1376 if (rv == OK) {
1377 if (!LoadSSLHostInfo())
1378 LOG(WARNING) << "LoadSSLHostInfo failed: " << host_and_port_.ToString();
1379 } else {
1380 DCHECK_EQ(ERR_IO_PENDING, rv);
1381 GotoState(STATE_LOAD_SSL_HOST_INFO);
1382 }
1383
1384 LeaveFunction("");
1385 return rv;
1386 }
1387
1324 int SSLClientSocketNSS::DoHandshake() { 1388 int SSLClientSocketNSS::DoHandshake() {
1325 EnterFunction(""); 1389 EnterFunction("");
1326 int net_error = net::OK; 1390 int net_error = net::OK;
1327 SECStatus rv = SSL_ForceHandshake(nss_fd_); 1391 SECStatus rv = SSL_ForceHandshake(nss_fd_);
1328 1392
1329 if (client_auth_cert_needed_) { 1393 if (client_auth_cert_needed_) {
1330 net_error = ERR_SSL_CLIENT_AUTH_CERT_NEEDED; 1394 net_error = ERR_SSL_CLIENT_AUTH_CERT_NEEDED;
1331 net_log_.AddEvent(NetLog::TYPE_SSL_HANDSHAKE_ERROR, 1395 net_log_.AddEvent(NetLog::TYPE_SSL_HANDSHAKE_ERROR,
1332 make_scoped_refptr(new SSLErrorParams(net_error, 0))); 1396 make_scoped_refptr(new SSLErrorParams(net_error, 0)));
1333 // If the handshake already succeeded (because the server requests but 1397 // If the handshake already succeeded (because the server requests but
1334 // doesn't require a client cert), we need to invalidate the SSL session 1398 // doesn't require a client cert), we need to invalidate the SSL session
1335 // so that we won't try to resume the non-client-authenticated session in 1399 // so that we won't try to resume the non-client-authenticated session in
1336 // the next handshake. This will cause the server to ask for a client 1400 // the next handshake. This will cause the server to ask for a client
1337 // cert again. 1401 // cert again.
1338 if (rv == SECSuccess && SSL_InvalidateSession(nss_fd_) != SECSuccess) { 1402 if (rv == SECSuccess && SSL_InvalidateSession(nss_fd_) != SECSuccess) {
1339 LOG(WARNING) << "Couldn't invalidate SSL session: " << PR_GetError(); 1403 LOG(WARNING) << "Couldn't invalidate SSL session: " << PR_GetError();
1340 } 1404 }
1341 } else if (rv == SECSuccess) { 1405 } else if (rv == SECSuccess) {
1342 if (handshake_callback_called_) { 1406 if (handshake_callback_called_) {
1343 if (eset_mitm_detected_) { 1407 if (eset_mitm_detected_) {
1344 net_error = ERR_ESET_ANTI_VIRUS_SSL_INTERCEPTION; 1408 net_error = ERR_ESET_ANTI_VIRUS_SSL_INTERCEPTION;
1345 } else { 1409 } else {
1346 // We need to see if the predicted certificate chain (in 1410 // We need to see if the predicted certificate chain (in
1347 // |ssl_host_info_->state().certs) matches the actual certificate chain 1411 // |ssl_host_info_->state().certs) matches the actual certificate chain
1348 // before we try to save it before we update |ssl_host_info_|. 1412 // before we call SaveSSLHostInfo, as that will update
1413 // |ssl_host_info_|.
1349 if (ssl_host_info_.get() && !ssl_host_info_->state().certs.empty()) { 1414 if (ssl_host_info_.get() && !ssl_host_info_->state().certs.empty()) {
1350 PeerCertificateChain certs(nss_fd_); 1415 PeerCertificateChain certs(nss_fd_);
1351 const SSLHostInfo::State& state = ssl_host_info_->state(); 1416 const SSLHostInfo::State& state = ssl_host_info_->state();
1352 predicted_cert_chain_correct_ = certs.size() == state.certs.size(); 1417 predicted_cert_chain_correct_ = certs.size() == state.certs.size();
1353 if (predicted_cert_chain_correct_) { 1418 if (predicted_cert_chain_correct_) {
1354 for (unsigned i = 0; i < certs.size(); i++) { 1419 for (unsigned i = 0; i < certs.size(); i++) {
1355 if (certs[i]->derCert.len != state.certs[i].size() || 1420 if (certs[i]->derCert.len != state.certs[i].size() ||
1356 memcmp(certs[i]->derCert.data, state.certs[i].data(), 1421 memcmp(certs[i]->derCert.data, state.certs[i].data(),
1357 certs[i]->derCert.len) != 0) { 1422 certs[i]->derCert.len) != 0) {
1358 predicted_cert_chain_correct_ = false; 1423 predicted_cert_chain_correct_ = false;
(...skipping 905 matching lines...) Expand 10 before | Expand all | Expand 10 after
2264 valid_thread_id_ = base::PlatformThread::CurrentId(); 2329 valid_thread_id_ = base::PlatformThread::CurrentId();
2265 } 2330 }
2266 2331
2267 bool SSLClientSocketNSS::CalledOnValidThread() const { 2332 bool SSLClientSocketNSS::CalledOnValidThread() const {
2268 EnsureThreadIdAssigned(); 2333 EnsureThreadIdAssigned();
2269 base::AutoLock auto_lock(lock_); 2334 base::AutoLock auto_lock(lock_);
2270 return valid_thread_id_ == base::PlatformThread::CurrentId(); 2335 return valid_thread_id_ == base::PlatformThread::CurrentId();
2271 } 2336 }
2272 2337
2273 } // namespace net 2338 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698