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 460 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
471 | 471 |
472 // static | 472 // static |
473 void SSLClientSocketNSS::ClearSessionCache() { | 473 void SSLClientSocketNSS::ClearSessionCache() { |
474 SSL_ClearSessionCache(); | 474 SSL_ClearSessionCache(); |
475 } | 475 } |
476 | 476 |
477 void SSLClientSocketNSS::GetSSLInfo(SSLInfo* ssl_info) { | 477 void SSLClientSocketNSS::GetSSLInfo(SSLInfo* ssl_info) { |
478 EnterFunction(""); | 478 EnterFunction(""); |
479 ssl_info->Reset(); | 479 ssl_info->Reset(); |
480 | 480 |
481 if (!server_cert_) | 481 if (!server_cert_nss_) |
482 return; | 482 return; |
483 | 483 |
484 ssl_info->cert_status = server_cert_verify_result_->cert_status; | 484 ssl_info->cert_status = server_cert_verify_result_->cert_status; |
485 DCHECK(server_cert_ != NULL); | |
486 ssl_info->cert = server_cert_; | 485 ssl_info->cert = server_cert_; |
487 ssl_info->connection_status = ssl_connection_status_; | 486 ssl_info->connection_status = ssl_connection_status_; |
488 ssl_info->public_key_hashes = server_cert_verify_result_->public_key_hashes; | 487 ssl_info->public_key_hashes = server_cert_verify_result_->public_key_hashes; |
489 ssl_info->is_issued_by_known_root = | 488 ssl_info->is_issued_by_known_root = |
490 server_cert_verify_result_->is_issued_by_known_root; | 489 server_cert_verify_result_->is_issued_by_known_root; |
491 | 490 |
492 PRUint16 cipher_suite = | 491 PRUint16 cipher_suite = |
493 SSLConnectionStatusToCipherSuite(ssl_connection_status_); | 492 SSLConnectionStatusToCipherSuite(ssl_connection_status_); |
494 SSLCipherSuiteInfo cipher_info; | 493 SSLCipherSuiteInfo cipher_info; |
495 SECStatus ok = SSL_GetCipherSuiteInfo(cipher_suite, | 494 SECStatus ok = SSL_GetCipherSuiteInfo(cipher_suite, |
(...skipping 535 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1031 std::string peer_id = host_and_port_.ToString(); | 1030 std::string peer_id = host_and_port_.ToString(); |
1032 SECStatus rv = SSL_SetSockPeerID(nss_fd_, const_cast<char*>(peer_id.c_str())); | 1031 SECStatus rv = SSL_SetSockPeerID(nss_fd_, const_cast<char*>(peer_id.c_str())); |
1033 if (rv != SECSuccess) | 1032 if (rv != SECSuccess) |
1034 LogFailedNSSFunction(net_log_, "SSL_SetSockPeerID", peer_id.c_str()); | 1033 LogFailedNSSFunction(net_log_, "SSL_SetSockPeerID", peer_id.c_str()); |
1035 | 1034 |
1036 return OK; | 1035 return OK; |
1037 } | 1036 } |
1038 | 1037 |
1039 | 1038 |
1040 // Sets server_cert_ and server_cert_nss_ if not yet set. | 1039 // Sets server_cert_ and server_cert_nss_ if not yet set. |
1041 // Returns server_cert_. | 1040 void SSLClientSocketNSS::UpdateServerCert() { |
1042 X509Certificate *SSLClientSocketNSS::UpdateServerCert() { | |
1043 // We set the server_cert_ from HandshakeCallback(). | 1041 // We set the server_cert_ from HandshakeCallback(). |
1044 if (server_cert_ == NULL) { | 1042 if (server_cert_ == NULL) { |
1045 server_cert_nss_ = SSL_PeerCertificate(nss_fd_); | 1043 server_cert_nss_ = SSL_PeerCertificate(nss_fd_); |
1046 if (server_cert_nss_) { | 1044 if (server_cert_nss_) { |
1047 PeerCertificateChain certs(nss_fd_); | 1045 PeerCertificateChain certs(nss_fd_); |
| 1046 // This call may fail when SSL is used inside sandbox. In that |
| 1047 // case CreateFromDERCertChain() returns NULL. |
1048 server_cert_ = X509Certificate::CreateFromDERCertChain( | 1048 server_cert_ = X509Certificate::CreateFromDERCertChain( |
1049 certs.AsStringPieceVector()); | 1049 certs.AsStringPieceVector()); |
1050 } | 1050 } |
1051 } | 1051 } |
1052 return server_cert_; | |
1053 } | 1052 } |
1054 | 1053 |
1055 // Sets ssl_connection_status_. | 1054 // Sets ssl_connection_status_. |
1056 void SSLClientSocketNSS::UpdateConnectionStatus() { | 1055 void SSLClientSocketNSS::UpdateConnectionStatus() { |
1057 SSLChannelInfo channel_info; | 1056 SSLChannelInfo channel_info; |
1058 SECStatus ok = SSL_GetChannelInfo(nss_fd_, | 1057 SECStatus ok = SSL_GetChannelInfo(nss_fd_, |
1059 &channel_info, sizeof(channel_info)); | 1058 &channel_info, sizeof(channel_info)); |
1060 if (ok == SECSuccess && | 1059 if (ok == SECSuccess && |
1061 channel_info.length == sizeof(channel_info) && | 1060 channel_info.length == sizeof(channel_info) && |
1062 channel_info.cipherSuite) { | 1061 channel_info.cipherSuite) { |
(...skipping 451 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1514 GotoState(STATE_VERIFY_CERT_COMPLETE); | 1513 GotoState(STATE_VERIFY_CERT_COMPLETE); |
1515 return OK; | 1514 return OK; |
1516 } | 1515 } |
1517 | 1516 |
1518 GotoState(STATE_VERIFY_CERT); | 1517 GotoState(STATE_VERIFY_CERT); |
1519 | 1518 |
1520 return OK; | 1519 return OK; |
1521 } | 1520 } |
1522 | 1521 |
1523 int SSLClientSocketNSS::DoVerifyCert(int result) { | 1522 int SSLClientSocketNSS::DoVerifyCert(int result) { |
1524 DCHECK(server_cert_); | 1523 DCHECK(server_cert_nss_); |
1525 | 1524 |
1526 GotoState(STATE_VERIFY_CERT_COMPLETE); | 1525 GotoState(STATE_VERIFY_CERT_COMPLETE); |
1527 | 1526 |
1528 // If the certificate is expected to be bad we can use the expectation as the | 1527 // If the certificate is expected to be bad we can use the |
1529 // cert status. | 1528 // expectation as the cert status. Don't use |server_cert_| here |
| 1529 // because it can be set to NULL in case we failed to create |
| 1530 // X509Certificate in UpdateServerCert(). This may happen when this |
| 1531 // code is used inside sandbox. |
| 1532 base::StringPiece der_cert( |
| 1533 reinterpret_cast<char*>(server_cert_nss_->derCert.data), |
| 1534 server_cert_nss_->derCert.len); |
1530 int cert_status; | 1535 int cert_status; |
1531 if (ssl_config_.IsAllowedBadCert(server_cert_, &cert_status)) { | 1536 if (ssl_config_.IsAllowedBadCert(der_cert, &cert_status)) { |
1532 DCHECK(start_cert_verification_time_.is_null()); | 1537 DCHECK(start_cert_verification_time_.is_null()); |
1533 VLOG(1) << "Received an expected bad cert with status: " << cert_status; | 1538 VLOG(1) << "Received an expected bad cert with status: " << cert_status; |
1534 server_cert_verify_result_ = &local_server_cert_verify_result_; | 1539 server_cert_verify_result_ = &local_server_cert_verify_result_; |
1535 local_server_cert_verify_result_.Reset(); | 1540 local_server_cert_verify_result_.Reset(); |
1536 local_server_cert_verify_result_.cert_status = cert_status; | 1541 local_server_cert_verify_result_.cert_status = cert_status; |
1537 return OK; | 1542 return OK; |
1538 } | 1543 } |
1539 | 1544 |
| 1545 // We may have failed to create X509Certificate object if we are |
| 1546 // running inside sandbox. |
| 1547 if (!server_cert_) { |
| 1548 server_cert_verify_result_ = &local_server_cert_verify_result_; |
| 1549 local_server_cert_verify_result_.Reset(); |
| 1550 local_server_cert_verify_result_.cert_status = CERT_STATUS_INVALID; |
| 1551 return ERR_CERT_INVALID; |
| 1552 } |
| 1553 |
1540 start_cert_verification_time_ = base::TimeTicks::Now(); | 1554 start_cert_verification_time_ = base::TimeTicks::Now(); |
1541 | 1555 |
1542 if (ssl_host_info_.get() && !ssl_host_info_->state().certs.empty() && | 1556 if (ssl_host_info_.get() && !ssl_host_info_->state().certs.empty() && |
1543 predicted_cert_chain_correct_) { | 1557 predicted_cert_chain_correct_) { |
1544 // If the SSLHostInfo had a prediction for the certificate chain of this | 1558 // If the SSLHostInfo had a prediction for the certificate chain of this |
1545 // server then it will have optimistically started a verification of that | 1559 // server then it will have optimistically started a verification of that |
1546 // chain. So, if the prediction was correct, we should wait for that | 1560 // chain. So, if the prediction was correct, we should wait for that |
1547 // verification to finish rather than start our own. | 1561 // verification to finish rather than start our own. |
1548 net_log_.AddEvent(NetLog::TYPE_SSL_VERIFICATION_MERGED, NULL); | 1562 net_log_.AddEvent(NetLog::TYPE_SSL_VERIFICATION_MERGED, NULL); |
1549 UMA_HISTOGRAM_ENUMERATION("Net.SSLVerificationMerged", 1 /* true */, 2); | 1563 UMA_HISTOGRAM_ENUMERATION("Net.SSLVerificationMerged", 1 /* true */, 2); |
(...skipping 716 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2266 valid_thread_id_ = base::PlatformThread::CurrentId(); | 2280 valid_thread_id_ = base::PlatformThread::CurrentId(); |
2267 } | 2281 } |
2268 | 2282 |
2269 bool SSLClientSocketNSS::CalledOnValidThread() const { | 2283 bool SSLClientSocketNSS::CalledOnValidThread() const { |
2270 EnsureThreadIdAssigned(); | 2284 EnsureThreadIdAssigned(); |
2271 base::AutoLock auto_lock(lock_); | 2285 base::AutoLock auto_lock(lock_); |
2272 return valid_thread_id_ == base::PlatformThread::CurrentId(); | 2286 return valid_thread_id_ == base::PlatformThread::CurrentId(); |
2273 } | 2287 } |
2274 | 2288 |
2275 } // namespace net | 2289 } // namespace net |
OLD | NEW |