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 |