| 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 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 59 #include <ssl.h> | 59 #include <ssl.h> |
| 60 #include <sslerr.h> | 60 #include <sslerr.h> |
| 61 #include <sslproto.h> | 61 #include <sslproto.h> |
| 62 | 62 |
| 63 #include <algorithm> | 63 #include <algorithm> |
| 64 #include <limits> | 64 #include <limits> |
| 65 #include <map> | 65 #include <map> |
| 66 | 66 |
| 67 #include "base/bind.h" | 67 #include "base/bind.h" |
| 68 #include "base/bind_helpers.h" | 68 #include "base/bind_helpers.h" |
| 69 #include "base/build_time.h" | |
| 70 #include "base/compiler_specific.h" | 69 #include "base/compiler_specific.h" |
| 71 #include "base/logging.h" | 70 #include "base/logging.h" |
| 72 #include "base/memory/singleton.h" | 71 #include "base/memory/singleton.h" |
| 73 #include "base/metrics/histogram.h" | 72 #include "base/metrics/histogram.h" |
| 74 #include "base/string_number_conversions.h" | 73 #include "base/string_number_conversions.h" |
| 75 #include "base/string_util.h" | 74 #include "base/string_util.h" |
| 76 #include "base/stringprintf.h" | 75 #include "base/stringprintf.h" |
| 77 #include "base/threading/thread_restrictions.h" | 76 #include "base/threading/thread_restrictions.h" |
| 78 #include "base/values.h" | 77 #include "base/values.h" |
| 79 #include "crypto/ec_private_key.h" | 78 #include "crypto/ec_private_key.h" |
| (...skipping 10 matching lines...) Expand all Loading... |
| 90 #include "net/base/io_buffer.h" | 89 #include "net/base/io_buffer.h" |
| 91 #include "net/base/net_errors.h" | 90 #include "net/base/net_errors.h" |
| 92 #include "net/base/net_log.h" | 91 #include "net/base/net_log.h" |
| 93 #include "net/base/ssl_cert_request_info.h" | 92 #include "net/base/ssl_cert_request_info.h" |
| 94 #include "net/base/ssl_connection_status_flags.h" | 93 #include "net/base/ssl_connection_status_flags.h" |
| 95 #include "net/base/ssl_info.h" | 94 #include "net/base/ssl_info.h" |
| 96 #include "net/base/sys_addrinfo.h" | 95 #include "net/base/sys_addrinfo.h" |
| 97 #include "net/base/x509_certificate_net_log_param.h" | 96 #include "net/base/x509_certificate_net_log_param.h" |
| 98 #include "net/ocsp/nss_ocsp.h" | 97 #include "net/ocsp/nss_ocsp.h" |
| 99 #include "net/socket/client_socket_handle.h" | 98 #include "net/socket/client_socket_handle.h" |
| 99 #include "net/socket/dns_cert_provenance_checker.h" |
| 100 #include "net/socket/nss_ssl_util.h" | 100 #include "net/socket/nss_ssl_util.h" |
| 101 #include "net/socket/ssl_error_params.h" | 101 #include "net/socket/ssl_error_params.h" |
| 102 #include "net/socket/ssl_host_info.h" | 102 #include "net/socket/ssl_host_info.h" |
| 103 | 103 |
| 104 #if defined(OS_WIN) | 104 #if defined(OS_WIN) |
| 105 #include <windows.h> | 105 #include <windows.h> |
| 106 #include <wincrypt.h> | 106 #include <wincrypt.h> |
| 107 #elif defined(OS_MACOSX) | 107 #elif defined(OS_MACOSX) |
| 108 #include <Security/SecBase.h> | 108 #include <Security/SecBase.h> |
| 109 #include <Security/SecCertificate.h> | 109 #include <Security/SecCertificate.h> |
| (...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 451 handshake_callback_called_(false), | 451 handshake_callback_called_(false), |
| 452 completed_handshake_(false), | 452 completed_handshake_(false), |
| 453 eset_mitm_detected_(false), | 453 eset_mitm_detected_(false), |
| 454 kaspersky_mitm_detected_(false), | 454 kaspersky_mitm_detected_(false), |
| 455 predicted_cert_chain_correct_(false), | 455 predicted_cert_chain_correct_(false), |
| 456 next_handshake_state_(STATE_NONE), | 456 next_handshake_state_(STATE_NONE), |
| 457 nss_fd_(NULL), | 457 nss_fd_(NULL), |
| 458 nss_bufs_(NULL), | 458 nss_bufs_(NULL), |
| 459 net_log_(transport_socket->socket()->NetLog()), | 459 net_log_(transport_socket->socket()->NetLog()), |
| 460 ssl_host_info_(ssl_host_info), | 460 ssl_host_info_(ssl_host_info), |
| 461 transport_security_state_(context.transport_security_state), | 461 dns_cert_checker_(context.dns_cert_checker), |
| 462 next_proto_status_(kNextProtoUnsupported), | 462 next_proto_status_(kNextProtoUnsupported), |
| 463 valid_thread_id_(base::kInvalidThreadId) { | 463 valid_thread_id_(base::kInvalidThreadId) { |
| 464 EnterFunction(""); | 464 EnterFunction(""); |
| 465 } | 465 } |
| 466 | 466 |
| 467 SSLClientSocketNSS::~SSLClientSocketNSS() { | 467 SSLClientSocketNSS::~SSLClientSocketNSS() { |
| 468 EnterFunction(""); | 468 EnterFunction(""); |
| 469 Disconnect(); | 469 Disconnect(); |
| 470 LeaveFunction(""); | 470 LeaveFunction(""); |
| 471 } | 471 } |
| (...skipping 1145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1617 rv = SSL_RestartHandshakeAfterCertReq(nss_fd_, cert, key, cert_chain); | 1617 rv = SSL_RestartHandshakeAfterCertReq(nss_fd_, cert, key, cert_chain); |
| 1618 if (rv != SECSuccess) | 1618 if (rv != SECSuccess) |
| 1619 return MapNSSError(PORT_GetError()); | 1619 return MapNSSError(PORT_GetError()); |
| 1620 | 1620 |
| 1621 GotoState(STATE_HANDSHAKE); | 1621 GotoState(STATE_HANDSHAKE); |
| 1622 set_was_origin_bound_cert_sent(true); | 1622 set_was_origin_bound_cert_sent(true); |
| 1623 return OK; | 1623 return OK; |
| 1624 } | 1624 } |
| 1625 | 1625 |
| 1626 int SSLClientSocketNSS::DoVerifyDNSSEC(int result) { | 1626 int SSLClientSocketNSS::DoVerifyDNSSEC(int result) { |
| 1627 if (ssl_config_.dns_cert_provenance_checking_enabled && |
| 1628 dns_cert_checker_) { |
| 1629 PeerCertificateChain certs(nss_fd_); |
| 1630 dns_cert_checker_->DoAsyncVerification( |
| 1631 host_and_port_.host(), certs.AsStringPieceVector()); |
| 1632 } |
| 1633 |
| 1627 DNSValidationResult r = CheckDNSSECChain(host_and_port_.host(), | 1634 DNSValidationResult r = CheckDNSSECChain(host_and_port_.host(), |
| 1628 server_cert_nss_, | 1635 server_cert_nss_, |
| 1629 host_and_port_.port()); | 1636 host_and_port_.port()); |
| 1630 if (r == DNSVR_SUCCESS) { | 1637 if (r == DNSVR_SUCCESS) { |
| 1631 local_server_cert_verify_result_.cert_status |= CERT_STATUS_IS_DNSSEC; | 1638 local_server_cert_verify_result_.cert_status |= CERT_STATUS_IS_DNSSEC; |
| 1632 local_server_cert_verify_result_.verified_cert = server_cert_; | 1639 local_server_cert_verify_result_.verified_cert = server_cert_; |
| 1633 server_cert_verify_result_ = &local_server_cert_verify_result_; | 1640 server_cert_verify_result_ = &local_server_cert_verify_result_; |
| 1634 GotoState(STATE_VERIFY_CERT_COMPLETE); | 1641 GotoState(STATE_VERIFY_CERT_COMPLETE); |
| 1635 return OK; | 1642 return OK; |
| 1636 } | 1643 } |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1780 // persistently. However, NSS opens a connection to the SQLite database | 1787 // persistently. However, NSS opens a connection to the SQLite database |
| 1781 // during NSS initialization and doesn't close the connection until NSS | 1788 // during NSS initialization and doesn't close the connection until NSS |
| 1782 // shuts down. If the file system where the database resides is gone, | 1789 // shuts down. If the file system where the database resides is gone, |
| 1783 // the database connection goes bad. What's worse, the connection won't | 1790 // the database connection goes bad. What's worse, the connection won't |
| 1784 // recover when the file system comes back. Until this NSS or SQLite bug | 1791 // recover when the file system comes back. Until this NSS or SQLite bug |
| 1785 // is fixed, we need to avoid using the NSS database for non-essential | 1792 // is fixed, we need to avoid using the NSS database for non-essential |
| 1786 // purposes. See https://bugzilla.mozilla.org/show_bug.cgi?id=508081 and | 1793 // purposes. See https://bugzilla.mozilla.org/show_bug.cgi?id=508081 and |
| 1787 // http://crbug.com/15630 for more info. | 1794 // http://crbug.com/15630 for more info. |
| 1788 | 1795 |
| 1789 // TODO(hclam): Skip logging if server cert was expected to be bad because | 1796 // TODO(hclam): Skip logging if server cert was expected to be bad because |
| 1790 // |server_cert_verify_result_| doesn't contain all the information about | 1797 // |server_cert_verify_results_| doesn't contain all the information about |
| 1791 // the cert. | 1798 // the cert. |
| 1792 if (result == OK) | 1799 if (result == OK) |
| 1793 LogConnectionTypeMetrics(); | 1800 LogConnectionTypeMetrics(); |
| 1794 | 1801 |
| 1795 completed_handshake_ = true; | 1802 completed_handshake_ = true; |
| 1796 | 1803 |
| 1797 if (!user_read_callback_.is_null()) { | 1804 if (!user_read_callback_.is_null()) { |
| 1798 int rv = DoReadLoop(OK); | 1805 int rv = DoReadLoop(OK); |
| 1799 if (rv != ERR_IO_PENDING) | 1806 if (rv != ERR_IO_PENDING) |
| 1800 DoReadCallback(rv); | 1807 DoReadCallback(rv); |
| 1801 } | 1808 } |
| 1802 | 1809 |
| 1803 //#if defined(OFFICIAL_BUILD) && !defined(OS_ANDROID) | |
| 1804 // Take care of any mandates for public key pinning. | |
| 1805 // | |
| 1806 // Pinning is only enabled for official builds to make sure that others don't | |
| 1807 // end up with pins that cannot be easily updated. | |
| 1808 // | |
| 1809 // TODO(agl): we might have an issue here where a request for foo.example.com | |
| 1810 // merges into a SPDY connection to www.example.com, and gets a different | |
| 1811 // certificate. | |
| 1812 | |
| 1813 const CertStatus cert_status = server_cert_verify_result_->cert_status; | |
| 1814 if ((result == OK || (IsCertificateError(result) && | |
| 1815 IsCertStatusMinorError(cert_status))) && | |
| 1816 server_cert_verify_result_->is_issued_by_known_root && | |
| 1817 transport_security_state_) { | |
| 1818 bool sni_available = ssl_config_.tls1_enabled || ssl_config_.ssl3_fallback; | |
| 1819 const std::string& host = host_and_port_.host(); | |
| 1820 | |
| 1821 TransportSecurityState::DomainState domain_state; | |
| 1822 if (transport_security_state_->HasPinsForHost( | |
| 1823 &domain_state, host, sni_available)) { | |
| 1824 if (!domain_state.IsChainOfPublicKeysPermitted( | |
| 1825 server_cert_verify_result_->public_key_hashes)) { | |
| 1826 const base::Time build_time = base::GetBuildTime(); | |
| 1827 // Pins are not enforced if the build is sufficiently old. Chrome | |
| 1828 // users should get updates every six weeks or so, but it's possible | |
| 1829 // that some users will stop getting updates for some reason. We | |
| 1830 // don't want those users building up as a pool of people with bad | |
| 1831 // pins. | |
| 1832 if ((base::Time::Now() - build_time).InDays() < 70 /* 10 weeks */) { | |
| 1833 result = ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN; | |
| 1834 UMA_HISTOGRAM_BOOLEAN("Net.PublicKeyPinSuccess", false); | |
| 1835 TransportSecurityState::ReportUMAOnPinFailure(host); | |
| 1836 } | |
| 1837 } else { | |
| 1838 UMA_HISTOGRAM_BOOLEAN("Net.PublicKeyPinSuccess", true); | |
| 1839 } | |
| 1840 } | |
| 1841 } | |
| 1842 //#endif | |
| 1843 | |
| 1844 // Exit DoHandshakeLoop and return the result to the caller to Connect. | 1810 // Exit DoHandshakeLoop and return the result to the caller to Connect. |
| 1845 DCHECK(next_handshake_state_ == STATE_NONE); | 1811 DCHECK(next_handshake_state_ == STATE_NONE); |
| 1846 return result; | 1812 return result; |
| 1847 } | 1813 } |
| 1848 | 1814 |
| 1849 int SSLClientSocketNSS::DoPayloadRead() { | 1815 int SSLClientSocketNSS::DoPayloadRead() { |
| 1850 EnterFunction(user_read_buf_len_); | 1816 EnterFunction(user_read_buf_len_); |
| 1851 DCHECK(user_read_buf_); | 1817 DCHECK(user_read_buf_); |
| 1852 DCHECK_GT(user_read_buf_len_, 0); | 1818 DCHECK_GT(user_read_buf_len_, 0); |
| 1853 int rv = PR_Read(nss_fd_, user_read_buf_->data(), user_read_buf_len_); | 1819 int rv = PR_Read(nss_fd_, user_read_buf_->data(), user_read_buf_len_); |
| (...skipping 847 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2701 valid_thread_id_ = base::PlatformThread::CurrentId(); | 2667 valid_thread_id_ = base::PlatformThread::CurrentId(); |
| 2702 } | 2668 } |
| 2703 | 2669 |
| 2704 bool SSLClientSocketNSS::CalledOnValidThread() const { | 2670 bool SSLClientSocketNSS::CalledOnValidThread() const { |
| 2705 EnsureThreadIdAssigned(); | 2671 EnsureThreadIdAssigned(); |
| 2706 base::AutoLock auto_lock(lock_); | 2672 base::AutoLock auto_lock(lock_); |
| 2707 return valid_thread_id_ == base::PlatformThread::CurrentId(); | 2673 return valid_thread_id_ == base::PlatformThread::CurrentId(); |
| 2708 } | 2674 } |
| 2709 | 2675 |
| 2710 } // namespace net | 2676 } // namespace net |
| OLD | NEW |