| 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" |
| 69 #include "base/compiler_specific.h" | 70 #include "base/compiler_specific.h" |
| 70 #include "base/logging.h" | 71 #include "base/logging.h" |
| 71 #include "base/memory/singleton.h" | 72 #include "base/memory/singleton.h" |
| 72 #include "base/metrics/histogram.h" | 73 #include "base/metrics/histogram.h" |
| 73 #include "base/string_number_conversions.h" | 74 #include "base/string_number_conversions.h" |
| 74 #include "base/string_util.h" | 75 #include "base/string_util.h" |
| 75 #include "base/stringprintf.h" | 76 #include "base/stringprintf.h" |
| 76 #include "base/threading/thread_restrictions.h" | 77 #include "base/threading/thread_restrictions.h" |
| 77 #include "base/values.h" | 78 #include "base/values.h" |
| 78 #include "crypto/ec_private_key.h" | 79 #include "crypto/ec_private_key.h" |
| (...skipping 10 matching lines...) Expand all Loading... |
| 89 #include "net/base/io_buffer.h" | 90 #include "net/base/io_buffer.h" |
| 90 #include "net/base/net_errors.h" | 91 #include "net/base/net_errors.h" |
| 91 #include "net/base/net_log.h" | 92 #include "net/base/net_log.h" |
| 92 #include "net/base/ssl_cert_request_info.h" | 93 #include "net/base/ssl_cert_request_info.h" |
| 93 #include "net/base/ssl_connection_status_flags.h" | 94 #include "net/base/ssl_connection_status_flags.h" |
| 94 #include "net/base/ssl_info.h" | 95 #include "net/base/ssl_info.h" |
| 95 #include "net/base/sys_addrinfo.h" | 96 #include "net/base/sys_addrinfo.h" |
| 96 #include "net/base/x509_certificate_net_log_param.h" | 97 #include "net/base/x509_certificate_net_log_param.h" |
| 97 #include "net/ocsp/nss_ocsp.h" | 98 #include "net/ocsp/nss_ocsp.h" |
| 98 #include "net/socket/client_socket_handle.h" | 99 #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 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 461 handshake_callback_called_(false), | 461 handshake_callback_called_(false), |
| 462 completed_handshake_(false), | 462 completed_handshake_(false), |
| 463 eset_mitm_detected_(false), | 463 eset_mitm_detected_(false), |
| 464 kaspersky_mitm_detected_(false), | 464 kaspersky_mitm_detected_(false), |
| 465 predicted_cert_chain_correct_(false), | 465 predicted_cert_chain_correct_(false), |
| 466 next_handshake_state_(STATE_NONE), | 466 next_handshake_state_(STATE_NONE), |
| 467 nss_fd_(NULL), | 467 nss_fd_(NULL), |
| 468 nss_bufs_(NULL), | 468 nss_bufs_(NULL), |
| 469 net_log_(transport_socket->socket()->NetLog()), | 469 net_log_(transport_socket->socket()->NetLog()), |
| 470 ssl_host_info_(ssl_host_info), | 470 ssl_host_info_(ssl_host_info), |
| 471 dns_cert_checker_(context.dns_cert_checker), | 471 transport_security_state_(context.transport_security_state), |
| 472 next_proto_status_(kNextProtoUnsupported), | 472 next_proto_status_(kNextProtoUnsupported), |
| 473 valid_thread_id_(base::kInvalidThreadId) { | 473 valid_thread_id_(base::kInvalidThreadId) { |
| 474 EnterFunction(""); | 474 EnterFunction(""); |
| 475 } | 475 } |
| 476 | 476 |
| 477 SSLClientSocketNSS::~SSLClientSocketNSS() { | 477 SSLClientSocketNSS::~SSLClientSocketNSS() { |
| 478 EnterFunction(""); | 478 EnterFunction(""); |
| 479 Disconnect(); | 479 Disconnect(); |
| 480 LeaveFunction(""); | 480 LeaveFunction(""); |
| 481 } | 481 } |
| (...skipping 1232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1714 SECStatus rv; | 1714 SECStatus rv; |
| 1715 rv = SSL_RestartHandshakeAfterCertReq(nss_fd_, cert, key, cert_chain); | 1715 rv = SSL_RestartHandshakeAfterCertReq(nss_fd_, cert, key, cert_chain); |
| 1716 if (rv != SECSuccess) | 1716 if (rv != SECSuccess) |
| 1717 return MapNSSError(PORT_GetError()); | 1717 return MapNSSError(PORT_GetError()); |
| 1718 | 1718 |
| 1719 GotoState(STATE_HANDSHAKE); | 1719 GotoState(STATE_HANDSHAKE); |
| 1720 return OK; | 1720 return OK; |
| 1721 } | 1721 } |
| 1722 | 1722 |
| 1723 int SSLClientSocketNSS::DoVerifyDNSSEC(int result) { | 1723 int SSLClientSocketNSS::DoVerifyDNSSEC(int result) { |
| 1724 if (ssl_config_.dns_cert_provenance_checking_enabled && | |
| 1725 dns_cert_checker_) { | |
| 1726 PeerCertificateChain certs(nss_fd_); | |
| 1727 dns_cert_checker_->DoAsyncVerification( | |
| 1728 host_and_port_.host(), certs.AsStringPieceVector()); | |
| 1729 } | |
| 1730 | |
| 1731 DNSValidationResult r = CheckDNSSECChain(host_and_port_.host(), | 1724 DNSValidationResult r = CheckDNSSECChain(host_and_port_.host(), |
| 1732 server_cert_nss_, | 1725 server_cert_nss_, |
| 1733 host_and_port_.port()); | 1726 host_and_port_.port()); |
| 1734 if (r == DNSVR_SUCCESS) { | 1727 if (r == DNSVR_SUCCESS) { |
| 1735 local_server_cert_verify_result_.cert_status |= CERT_STATUS_IS_DNSSEC; | 1728 local_server_cert_verify_result_.cert_status |= CERT_STATUS_IS_DNSSEC; |
| 1736 local_server_cert_verify_result_.verified_cert = server_cert_; | 1729 local_server_cert_verify_result_.verified_cert = server_cert_; |
| 1737 server_cert_verify_result_ = &local_server_cert_verify_result_; | 1730 server_cert_verify_result_ = &local_server_cert_verify_result_; |
| 1738 GotoState(STATE_VERIFY_CERT_COMPLETE); | 1731 GotoState(STATE_VERIFY_CERT_COMPLETE); |
| 1739 return OK; | 1732 return OK; |
| 1740 } | 1733 } |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1882 // persistently. However, NSS opens a connection to the SQLite database | 1875 // persistently. However, NSS opens a connection to the SQLite database |
| 1883 // during NSS initialization and doesn't close the connection until NSS | 1876 // during NSS initialization and doesn't close the connection until NSS |
| 1884 // shuts down. If the file system where the database resides is gone, | 1877 // shuts down. If the file system where the database resides is gone, |
| 1885 // the database connection goes bad. What's worse, the connection won't | 1878 // the database connection goes bad. What's worse, the connection won't |
| 1886 // recover when the file system comes back. Until this NSS or SQLite bug | 1879 // recover when the file system comes back. Until this NSS or SQLite bug |
| 1887 // is fixed, we need to avoid using the NSS database for non-essential | 1880 // is fixed, we need to avoid using the NSS database for non-essential |
| 1888 // purposes. See https://bugzilla.mozilla.org/show_bug.cgi?id=508081 and | 1881 // purposes. See https://bugzilla.mozilla.org/show_bug.cgi?id=508081 and |
| 1889 // http://crbug.com/15630 for more info. | 1882 // http://crbug.com/15630 for more info. |
| 1890 | 1883 |
| 1891 // TODO(hclam): Skip logging if server cert was expected to be bad because | 1884 // TODO(hclam): Skip logging if server cert was expected to be bad because |
| 1892 // |server_cert_verify_results_| doesn't contain all the information about | 1885 // |server_cert_verify_result_| doesn't contain all the information about |
| 1893 // the cert. | 1886 // the cert. |
| 1894 if (result == OK) | 1887 if (result == OK) |
| 1895 LogConnectionTypeMetrics(); | 1888 LogConnectionTypeMetrics(); |
| 1896 | 1889 |
| 1897 completed_handshake_ = true; | 1890 completed_handshake_ = true; |
| 1898 | 1891 |
| 1899 if (old_user_read_callback_ || !user_read_callback_.is_null()) { | 1892 if (old_user_read_callback_ || !user_read_callback_.is_null()) { |
| 1900 int rv = DoReadLoop(OK); | 1893 int rv = DoReadLoop(OK); |
| 1901 if (rv != ERR_IO_PENDING) | 1894 if (rv != ERR_IO_PENDING) |
| 1902 DoReadCallback(rv); | 1895 DoReadCallback(rv); |
| 1903 } | 1896 } |
| 1904 | 1897 |
| 1898 //#if defined(OFFICIAL_BUILD) && !defined(OS_ANDROID) |
| 1899 // Take care of any mandates for public key pinning. |
| 1900 // |
| 1901 // Pinning is only enabled for official builds to make sure that others don't |
| 1902 // end up with pins that cannot be easily updated. |
| 1903 // |
| 1904 // TODO(agl): we might have an issue here where a request for foo.example.com |
| 1905 // merges into a SPDY connection to www.example.com, and gets a different |
| 1906 // certificate. |
| 1907 |
| 1908 const CertStatus cert_status = server_cert_verify_result_->cert_status; |
| 1909 if ((result == OK || (IsCertificateError(result) && |
| 1910 IsCertStatusMinorError(cert_status))) && |
| 1911 server_cert_verify_result_->is_issued_by_known_root && |
| 1912 transport_security_state_) { |
| 1913 bool sni_available = ssl_config_.tls1_enabled || ssl_config_.ssl3_fallback; |
| 1914 const std::string& host = host_and_port_.host(); |
| 1915 |
| 1916 TransportSecurityState::DomainState domain_state; |
| 1917 if (transport_security_state_->HasPinsForHost( |
| 1918 &domain_state, host, sni_available)) { |
| 1919 if (!domain_state.IsChainOfPublicKeysPermitted( |
| 1920 server_cert_verify_result_->public_key_hashes)) { |
| 1921 const base::Time build_time = base::GetBuildTime(); |
| 1922 // Pins are not enforced if the build is sufficiently old. Chrome |
| 1923 // users should get updates every six weeks or so, but it's possible |
| 1924 // that some users will stop getting updates for some reason. We |
| 1925 // don't want those users building up as a pool of people with bad |
| 1926 // pins. |
| 1927 if ((base::Time::Now() - build_time).InDays() < 70 /* 10 weeks */) { |
| 1928 result = ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN; |
| 1929 UMA_HISTOGRAM_BOOLEAN("Net.PublicKeyPinSuccess", false); |
| 1930 TransportSecurityState::ReportUMAOnPinFailure(host); |
| 1931 } |
| 1932 } else { |
| 1933 UMA_HISTOGRAM_BOOLEAN("Net.PublicKeyPinSuccess", true); |
| 1934 } |
| 1935 } |
| 1936 } |
| 1937 //#endif |
| 1938 |
| 1905 // Exit DoHandshakeLoop and return the result to the caller to Connect. | 1939 // Exit DoHandshakeLoop and return the result to the caller to Connect. |
| 1906 DCHECK(next_handshake_state_ == STATE_NONE); | 1940 DCHECK(next_handshake_state_ == STATE_NONE); |
| 1907 return result; | 1941 return result; |
| 1908 } | 1942 } |
| 1909 | 1943 |
| 1910 int SSLClientSocketNSS::DoPayloadRead() { | 1944 int SSLClientSocketNSS::DoPayloadRead() { |
| 1911 EnterFunction(user_read_buf_len_); | 1945 EnterFunction(user_read_buf_len_); |
| 1912 DCHECK(user_read_buf_); | 1946 DCHECK(user_read_buf_); |
| 1913 DCHECK_GT(user_read_buf_len_, 0); | 1947 DCHECK_GT(user_read_buf_len_, 0); |
| 1914 int rv = PR_Read(nss_fd_, user_read_buf_->data(), user_read_buf_len_); | 1948 int rv = PR_Read(nss_fd_, user_read_buf_->data(), user_read_buf_len_); |
| (...skipping 839 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2754 valid_thread_id_ = base::PlatformThread::CurrentId(); | 2788 valid_thread_id_ = base::PlatformThread::CurrentId(); |
| 2755 } | 2789 } |
| 2756 | 2790 |
| 2757 bool SSLClientSocketNSS::CalledOnValidThread() const { | 2791 bool SSLClientSocketNSS::CalledOnValidThread() const { |
| 2758 EnsureThreadIdAssigned(); | 2792 EnsureThreadIdAssigned(); |
| 2759 base::AutoLock auto_lock(lock_); | 2793 base::AutoLock auto_lock(lock_); |
| 2760 return valid_thread_id_ == base::PlatformThread::CurrentId(); | 2794 return valid_thread_id_ == base::PlatformThread::CurrentId(); |
| 2761 } | 2795 } |
| 2762 | 2796 |
| 2763 } // namespace net | 2797 } // namespace net |
| OLD | NEW |