OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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/callback_helpers.h" | 69 #include "base/callback_helpers.h" |
70 #include "base/compiler_specific.h" | 70 #include "base/compiler_specific.h" |
71 #include "base/logging.h" | 71 #include "base/logging.h" |
72 #include "base/memory/singleton.h" | 72 #include "base/memory/singleton.h" |
73 #include "base/metrics/histogram.h" | 73 #include "base/metrics/histogram.h" |
74 #include "base/profiler/scoped_tracker.h" | |
75 #include "base/single_thread_task_runner.h" | 74 #include "base/single_thread_task_runner.h" |
76 #include "base/stl_util.h" | 75 #include "base/stl_util.h" |
77 #include "base/strings/string_number_conversions.h" | 76 #include "base/strings/string_number_conversions.h" |
78 #include "base/strings/string_util.h" | 77 #include "base/strings/string_util.h" |
79 #include "base/strings/stringprintf.h" | 78 #include "base/strings/stringprintf.h" |
80 #include "base/thread_task_runner_handle.h" | 79 #include "base/thread_task_runner_handle.h" |
81 #include "base/threading/thread_restrictions.h" | 80 #include "base/threading/thread_restrictions.h" |
82 #include "base/values.h" | 81 #include "base/values.h" |
83 #include "crypto/ec_private_key.h" | 82 #include "crypto/ec_private_key.h" |
84 #include "crypto/nss_util.h" | 83 #include "crypto/nss_util.h" |
(...skipping 1564 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1649 SSL_CacheSessionUnlocked(socket); | 1648 SSL_CacheSessionUnlocked(socket); |
1650 | 1649 |
1651 // Additionally, when False Starting, DoHandshake() will have already | 1650 // Additionally, when False Starting, DoHandshake() will have already |
1652 // called HandshakeSucceeded(), so return now. | 1651 // called HandshakeSucceeded(), so return now. |
1653 return; | 1652 return; |
1654 } | 1653 } |
1655 core->HandshakeSucceeded(); | 1654 core->HandshakeSucceeded(); |
1656 } | 1655 } |
1657 | 1656 |
1658 void SSLClientSocketNSS::Core::HandshakeSucceeded() { | 1657 void SSLClientSocketNSS::Core::HandshakeSucceeded() { |
1659 // TODO(vadimt): Remove ScopedTracker below once crbug.com/424386 is fixed. | |
1660 tracked_objects::ScopedTracker tracking_profile( | |
1661 FROM_HERE_WITH_EXPLICIT_FUNCTION( | |
1662 "424386 SSLClientSocketNSS::Core::HandshakeSucceeded")); | |
1663 | |
1664 DCHECK(OnNSSTaskRunner()); | 1658 DCHECK(OnNSSTaskRunner()); |
1665 | 1659 |
1666 PRBool last_handshake_resumed; | 1660 PRBool last_handshake_resumed; |
1667 SECStatus rv = SSL_HandshakeResumedSession(nss_fd_, &last_handshake_resumed); | 1661 SECStatus rv = SSL_HandshakeResumedSession(nss_fd_, &last_handshake_resumed); |
1668 if (rv == SECSuccess && last_handshake_resumed) { | 1662 if (rv == SECSuccess && last_handshake_resumed) { |
1669 nss_handshake_state_.resumed_handshake = true; | 1663 nss_handshake_state_.resumed_handshake = true; |
1670 } else { | 1664 } else { |
1671 nss_handshake_state_.resumed_handshake = false; | 1665 nss_handshake_state_.resumed_handshake = false; |
1672 } | 1666 } |
1673 | 1667 |
1674 RecordChannelIDSupportOnNSSTaskRunner(); | 1668 RecordChannelIDSupportOnNSSTaskRunner(); |
1675 UpdateServerCert(); | 1669 UpdateServerCert(); |
1676 UpdateSignedCertTimestamps(); | 1670 UpdateSignedCertTimestamps(); |
1677 UpdateStapledOCSPResponse(); | 1671 UpdateStapledOCSPResponse(); |
1678 UpdateConnectionStatus(); | 1672 UpdateConnectionStatus(); |
1679 UpdateNextProto(); | 1673 UpdateNextProto(); |
1680 UpdateExtensionUsed(); | 1674 UpdateExtensionUsed(); |
1681 | 1675 |
1682 // Update the network task runners view of the handshake state whenever | 1676 // Update the network task runners view of the handshake state whenever |
1683 // a handshake has completed. | 1677 // a handshake has completed. |
1684 PostOrRunCallback( | 1678 PostOrRunCallback( |
1685 FROM_HERE, base::Bind(&Core::OnHandshakeStateUpdated, this, | 1679 FROM_HERE, base::Bind(&Core::OnHandshakeStateUpdated, this, |
1686 nss_handshake_state_)); | 1680 nss_handshake_state_)); |
1687 } | 1681 } |
1688 | 1682 |
1689 int SSLClientSocketNSS::Core::HandleNSSError(PRErrorCode nss_error) { | 1683 int SSLClientSocketNSS::Core::HandleNSSError(PRErrorCode nss_error) { |
1690 // TODO(vadimt): Remove ScopedTracker below once crbug.com/424386 is fixed. | |
1691 tracked_objects::ScopedTracker tracking_profile( | |
1692 FROM_HERE_WITH_EXPLICIT_FUNCTION( | |
1693 "424386 SSLClientSocketNSS::Core::HandleNSSError")); | |
1694 | |
1695 DCHECK(OnNSSTaskRunner()); | 1684 DCHECK(OnNSSTaskRunner()); |
1696 | 1685 |
1697 int net_error = MapNSSClientError(nss_error); | 1686 int net_error = MapNSSClientError(nss_error); |
1698 | 1687 |
1699 #if defined(OS_WIN) | 1688 #if defined(OS_WIN) |
1700 // On Windows, a handle to the HCRYPTPROV is cached in the X509Certificate | 1689 // On Windows, a handle to the HCRYPTPROV is cached in the X509Certificate |
1701 // os_cert_handle() as an optimization. However, if the certificate | 1690 // os_cert_handle() as an optimization. However, if the certificate |
1702 // private key is stored on a smart card, and the smart card is removed, | 1691 // private key is stored on a smart card, and the smart card is removed, |
1703 // the cached HCRYPTPROV will not be able to obtain the HCRYPTKEY again, | 1692 // the cached HCRYPTPROV will not be able to obtain the HCRYPTKEY again, |
1704 // preventing client certificate authentication. Because the | 1693 // preventing client certificate authentication. Because the |
(...skipping 12 matching lines...) Expand all Loading... |
1717 CertSetCertificateContextProperty( | 1706 CertSetCertificateContextProperty( |
1718 ssl_config_.client_cert->os_cert_handle(), | 1707 ssl_config_.client_cert->os_cert_handle(), |
1719 CERT_KEY_PROV_HANDLE_PROP_ID, 0, NULL); | 1708 CERT_KEY_PROV_HANDLE_PROP_ID, 0, NULL); |
1720 } | 1709 } |
1721 #endif | 1710 #endif |
1722 | 1711 |
1723 return net_error; | 1712 return net_error; |
1724 } | 1713 } |
1725 | 1714 |
1726 int SSLClientSocketNSS::Core::DoHandshakeLoop(int last_io_result) { | 1715 int SSLClientSocketNSS::Core::DoHandshakeLoop(int last_io_result) { |
1727 // TODO(vadimt): Remove ScopedTracker below once crbug.com/424386 is fixed. | |
1728 tracked_objects::ScopedTracker tracking_profile( | |
1729 FROM_HERE_WITH_EXPLICIT_FUNCTION( | |
1730 "424386 SSLClientSocketNSS::Core::DoHandshakeLoop")); | |
1731 | |
1732 DCHECK(OnNSSTaskRunner()); | 1716 DCHECK(OnNSSTaskRunner()); |
1733 | 1717 |
1734 int rv = last_io_result; | 1718 int rv = last_io_result; |
1735 do { | 1719 do { |
1736 // Default to STATE_NONE for next state. | 1720 // Default to STATE_NONE for next state. |
1737 State state = next_handshake_state_; | 1721 State state = next_handshake_state_; |
1738 GotoState(STATE_NONE); | 1722 GotoState(STATE_NONE); |
1739 | 1723 |
1740 switch (state) { | 1724 switch (state) { |
1741 case STATE_HANDSHAKE: | 1725 case STATE_HANDSHAKE: |
(...skipping 16 matching lines...) Expand all Loading... |
1758 // special case we keep looping even if rv is ERR_IO_PENDING because | 1742 // special case we keep looping even if rv is ERR_IO_PENDING because |
1759 // the transport IO may allow DoHandshake to make progress. | 1743 // the transport IO may allow DoHandshake to make progress. |
1760 DCHECK(rv == OK || rv == ERR_IO_PENDING); | 1744 DCHECK(rv == OK || rv == ERR_IO_PENDING); |
1761 rv = OK; // This causes us to stay in the loop. | 1745 rv = OK; // This causes us to stay in the loop. |
1762 } | 1746 } |
1763 } while (rv != ERR_IO_PENDING && next_handshake_state_ != STATE_NONE); | 1747 } while (rv != ERR_IO_PENDING && next_handshake_state_ != STATE_NONE); |
1764 return rv; | 1748 return rv; |
1765 } | 1749 } |
1766 | 1750 |
1767 int SSLClientSocketNSS::Core::DoReadLoop(int result) { | 1751 int SSLClientSocketNSS::Core::DoReadLoop(int result) { |
1768 // TODO(vadimt): Remove ScopedTracker below once crbug.com/424386 is fixed. | |
1769 tracked_objects::ScopedTracker tracking_profile( | |
1770 FROM_HERE_WITH_EXPLICIT_FUNCTION( | |
1771 "424386 SSLClientSocketNSS::Core::DoReadLoop")); | |
1772 | |
1773 DCHECK(OnNSSTaskRunner()); | 1752 DCHECK(OnNSSTaskRunner()); |
1774 DCHECK(false_started_ || handshake_callback_called_); | 1753 DCHECK(false_started_ || handshake_callback_called_); |
1775 DCHECK_EQ(STATE_NONE, next_handshake_state_); | 1754 DCHECK_EQ(STATE_NONE, next_handshake_state_); |
1776 | 1755 |
1777 if (result < 0) | 1756 if (result < 0) |
1778 return result; | 1757 return result; |
1779 | 1758 |
1780 if (!nss_bufs_) { | 1759 if (!nss_bufs_) { |
1781 LOG(DFATAL) << "!nss_bufs_"; | 1760 LOG(DFATAL) << "!nss_bufs_"; |
1782 int rv = ERR_UNEXPECTED; | 1761 int rv = ERR_UNEXPECTED; |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1822 do { | 1801 do { |
1823 rv = DoPayloadWrite(); | 1802 rv = DoPayloadWrite(); |
1824 network_moved = DoTransportIO(); | 1803 network_moved = DoTransportIO(); |
1825 } while (rv == ERR_IO_PENDING && network_moved); | 1804 } while (rv == ERR_IO_PENDING && network_moved); |
1826 | 1805 |
1827 LeaveFunction(rv); | 1806 LeaveFunction(rv); |
1828 return rv; | 1807 return rv; |
1829 } | 1808 } |
1830 | 1809 |
1831 int SSLClientSocketNSS::Core::DoHandshake() { | 1810 int SSLClientSocketNSS::Core::DoHandshake() { |
1832 // TODO(vadimt): Remove ScopedTracker below once crbug.com/424386 is fixed. | |
1833 tracked_objects::ScopedTracker tracking_profile( | |
1834 FROM_HERE_WITH_EXPLICIT_FUNCTION( | |
1835 "424386 SSLClientSocketNSS::Core::DoHandshake")); | |
1836 | |
1837 DCHECK(OnNSSTaskRunner()); | 1811 DCHECK(OnNSSTaskRunner()); |
1838 | 1812 |
1839 int net_error = OK; | 1813 int net_error = OK; |
1840 SECStatus rv = SSL_ForceHandshake(nss_fd_); | 1814 SECStatus rv = SSL_ForceHandshake(nss_fd_); |
1841 | 1815 |
1842 // TODO(vadimt): Remove ScopedTracker below once crbug.com/424386 is fixed. | |
1843 tracked_objects::ScopedTracker tracking_profile1( | |
1844 FROM_HERE_WITH_EXPLICIT_FUNCTION( | |
1845 "424386 SSLClientSocketNSS::Core::DoHandshake 1")); | |
1846 | |
1847 // Note: this function may be called multiple times during the handshake, so | 1816 // Note: this function may be called multiple times during the handshake, so |
1848 // even though channel id and client auth are separate else cases, they can | 1817 // even though channel id and client auth are separate else cases, they can |
1849 // both be used during a single SSL handshake. | 1818 // both be used during a single SSL handshake. |
1850 if (channel_id_needed_) { | 1819 if (channel_id_needed_) { |
1851 GotoState(STATE_GET_DOMAIN_BOUND_CERT_COMPLETE); | 1820 GotoState(STATE_GET_DOMAIN_BOUND_CERT_COMPLETE); |
1852 net_error = ERR_IO_PENDING; | 1821 net_error = ERR_IO_PENDING; |
1853 } else if (client_auth_cert_needed_) { | 1822 } else if (client_auth_cert_needed_) { |
1854 net_error = ERR_SSL_CLIENT_AUTH_CERT_NEEDED; | 1823 net_error = ERR_SSL_CLIENT_AUTH_CERT_NEEDED; |
1855 PostOrRunCallback( | 1824 PostOrRunCallback( |
1856 FROM_HERE, | 1825 FROM_HERE, |
(...skipping 18 matching lines...) Expand all Loading... |
1875 base::Bind(&AddLogEventWithCallback, weak_net_log_, | 1844 base::Bind(&AddLogEventWithCallback, weak_net_log_, |
1876 NetLog::TYPE_SSL_HANDSHAKE_ERROR, | 1845 NetLog::TYPE_SSL_HANDSHAKE_ERROR, |
1877 CreateNetLogSSLErrorCallback(net_error, prerr))); | 1846 CreateNetLogSSLErrorCallback(net_error, prerr))); |
1878 } | 1847 } |
1879 } | 1848 } |
1880 | 1849 |
1881 return net_error; | 1850 return net_error; |
1882 } | 1851 } |
1883 | 1852 |
1884 int SSLClientSocketNSS::Core::DoGetDBCertComplete(int result) { | 1853 int SSLClientSocketNSS::Core::DoGetDBCertComplete(int result) { |
1885 // TODO(vadimt): Remove ScopedTracker below once crbug.com/424386 is fixed. | |
1886 tracked_objects::ScopedTracker tracking_profile( | |
1887 FROM_HERE_WITH_EXPLICIT_FUNCTION( | |
1888 "424386 SSLClientSocketNSS::Core::DoGetDBCertComplete")); | |
1889 | |
1890 SECStatus rv; | 1854 SECStatus rv; |
1891 PostOrRunCallback( | 1855 PostOrRunCallback( |
1892 FROM_HERE, | 1856 FROM_HERE, |
1893 base::Bind(&BoundNetLog::EndEventWithNetErrorCode, weak_net_log_, | 1857 base::Bind(&BoundNetLog::EndEventWithNetErrorCode, weak_net_log_, |
1894 NetLog::TYPE_SSL_GET_DOMAIN_BOUND_CERT, result)); | 1858 NetLog::TYPE_SSL_GET_DOMAIN_BOUND_CERT, result)); |
1895 | 1859 |
1896 channel_id_needed_ = false; | 1860 channel_id_needed_ = false; |
1897 | 1861 |
1898 if (result != OK) | 1862 if (result != OK) |
1899 return result; | 1863 return result; |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2064 base::Bind(&AddLogEventWithCallback, weak_net_log_, | 2028 base::Bind(&AddLogEventWithCallback, weak_net_log_, |
2065 NetLog::TYPE_SSL_WRITE_ERROR, | 2029 NetLog::TYPE_SSL_WRITE_ERROR, |
2066 CreateNetLogSSLErrorCallback(rv, prerr))); | 2030 CreateNetLogSSLErrorCallback(rv, prerr))); |
2067 return rv; | 2031 return rv; |
2068 } | 2032 } |
2069 | 2033 |
2070 // Do as much network I/O as possible between the buffer and the | 2034 // Do as much network I/O as possible between the buffer and the |
2071 // transport socket. Return true if some I/O performed, false | 2035 // transport socket. Return true if some I/O performed, false |
2072 // otherwise (error or ERR_IO_PENDING). | 2036 // otherwise (error or ERR_IO_PENDING). |
2073 bool SSLClientSocketNSS::Core::DoTransportIO() { | 2037 bool SSLClientSocketNSS::Core::DoTransportIO() { |
2074 // TODO(vadimt): Remove ScopedTracker below once crbug.com/424386 is fixed. | |
2075 tracked_objects::ScopedTracker tracking_profile( | |
2076 FROM_HERE_WITH_EXPLICIT_FUNCTION( | |
2077 "424386 SSLClientSocketNSS::Core::DoTransportIO")); | |
2078 | |
2079 DCHECK(OnNSSTaskRunner()); | 2038 DCHECK(OnNSSTaskRunner()); |
2080 | 2039 |
2081 bool network_moved = false; | 2040 bool network_moved = false; |
2082 if (nss_bufs_ != NULL) { | 2041 if (nss_bufs_ != NULL) { |
2083 int rv; | 2042 int rv; |
2084 // Read and write as much data as we can. The loop is neccessary | 2043 // Read and write as much data as we can. The loop is neccessary |
2085 // because Write() may return synchronously. | 2044 // because Write() may return synchronously. |
2086 do { | 2045 do { |
2087 rv = BufferSend(); | 2046 rv = BufferSend(); |
2088 if (rv != ERR_IO_PENDING && rv != 0) | 2047 if (rv != ERR_IO_PENDING && rv != 0) |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2245 DoWriteCallback(rv_write); | 2204 DoWriteCallback(rv_write); |
2246 } | 2205 } |
2247 | 2206 |
2248 // As part of Connect(), the SSLClientSocketNSS object performs an SSL | 2207 // As part of Connect(), the SSLClientSocketNSS object performs an SSL |
2249 // handshake. This requires network IO, which in turn calls | 2208 // handshake. This requires network IO, which in turn calls |
2250 // BufferRecvComplete() with a non-zero byte count. This byte count eventually | 2209 // BufferRecvComplete() with a non-zero byte count. This byte count eventually |
2251 // winds its way through the state machine and ends up being passed to the | 2210 // winds its way through the state machine and ends up being passed to the |
2252 // callback. For Read() and Write(), that's what we want. But for Connect(), | 2211 // callback. For Read() and Write(), that's what we want. But for Connect(), |
2253 // the caller expects OK (i.e. 0) for success. | 2212 // the caller expects OK (i.e. 0) for success. |
2254 void SSLClientSocketNSS::Core::DoConnectCallback(int rv) { | 2213 void SSLClientSocketNSS::Core::DoConnectCallback(int rv) { |
2255 // TODO(vadimt): Remove ScopedTracker below once crbug.com/424386 is fixed. | |
2256 tracked_objects::ScopedTracker tracking_profile( | |
2257 FROM_HERE_WITH_EXPLICIT_FUNCTION( | |
2258 "424386 SSLClientSocketNSS::Core::DoConnectCallback")); | |
2259 | |
2260 DCHECK(OnNSSTaskRunner()); | 2214 DCHECK(OnNSSTaskRunner()); |
2261 DCHECK_NE(rv, ERR_IO_PENDING); | 2215 DCHECK_NE(rv, ERR_IO_PENDING); |
2262 DCHECK(!user_connect_callback_.is_null()); | 2216 DCHECK(!user_connect_callback_.is_null()); |
2263 | 2217 |
2264 base::Closure c = base::Bind( | 2218 base::Closure c = base::Bind( |
2265 base::ResetAndReturn(&user_connect_callback_), | 2219 base::ResetAndReturn(&user_connect_callback_), |
2266 rv > OK ? OK : rv); | 2220 rv > OK ? OK : rv); |
2267 PostOrRunCallback(FROM_HERE, c); | 2221 PostOrRunCallback(FROM_HERE, c); |
2268 } | 2222 } |
2269 | 2223 |
2270 void SSLClientSocketNSS::Core::DoReadCallback(int rv) { | 2224 void SSLClientSocketNSS::Core::DoReadCallback(int rv) { |
2271 // TODO(vadimt): Remove ScopedTracker below once crbug.com/424386 is fixed. | |
2272 tracked_objects::ScopedTracker tracking_profile( | |
2273 FROM_HERE_WITH_EXPLICIT_FUNCTION( | |
2274 "424386 SSLClientSocketNSS::Core::DoReadCallback")); | |
2275 | |
2276 DCHECK(OnNSSTaskRunner()); | 2225 DCHECK(OnNSSTaskRunner()); |
2277 DCHECK_NE(ERR_IO_PENDING, rv); | 2226 DCHECK_NE(ERR_IO_PENDING, rv); |
2278 DCHECK(!user_read_callback_.is_null()); | 2227 DCHECK(!user_read_callback_.is_null()); |
2279 | 2228 |
2280 user_read_buf_ = NULL; | 2229 user_read_buf_ = NULL; |
2281 user_read_buf_len_ = 0; | 2230 user_read_buf_len_ = 0; |
2282 int amount_in_read_buffer = memio_GetReadableBufferSize(nss_bufs_); | 2231 int amount_in_read_buffer = memio_GetReadableBufferSize(nss_bufs_); |
2283 // This is used to curry the |amount_int_read_buffer| and |user_cb| back to | 2232 // This is used to curry the |amount_int_read_buffer| and |user_cb| back to |
2284 // the network task runner. | 2233 // the network task runner. |
2285 PostOrRunCallback( | 2234 PostOrRunCallback( |
(...skipping 1347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3633 scoped_refptr<X509Certificate> | 3582 scoped_refptr<X509Certificate> |
3634 SSLClientSocketNSS::GetUnverifiedServerCertificateChain() const { | 3583 SSLClientSocketNSS::GetUnverifiedServerCertificateChain() const { |
3635 return core_->state().server_cert.get(); | 3584 return core_->state().server_cert.get(); |
3636 } | 3585 } |
3637 | 3586 |
3638 ChannelIDService* SSLClientSocketNSS::GetChannelIDService() const { | 3587 ChannelIDService* SSLClientSocketNSS::GetChannelIDService() const { |
3639 return channel_id_service_; | 3588 return channel_id_service_; |
3640 } | 3589 } |
3641 | 3590 |
3642 } // namespace net | 3591 } // namespace net |
OLD | NEW |