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 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
211 CacheOCSPResponseFromSideChannelFunction | 211 CacheOCSPResponseFromSideChannelFunction |
212 GetCacheOCSPResponseFromSideChannelFunction() { | 212 GetCacheOCSPResponseFromSideChannelFunction() { |
213 return RuntimeLibNSSFunctionPointers::GetInstance() | 213 return RuntimeLibNSSFunctionPointers::GetInstance() |
214 ->GetCacheOCSPResponseFromSideChannelFunction(); | 214 ->GetCacheOCSPResponseFromSideChannelFunction(); |
215 } | 215 } |
216 | 216 |
217 bool IsOCSPStaplingSupported() { | 217 bool IsOCSPStaplingSupported() { |
218 return GetCacheOCSPResponseFromSideChannelFunction() != NULL; | 218 return GetCacheOCSPResponseFromSideChannelFunction() != NULL; |
219 } | 219 } |
220 #else | 220 #else |
221 // TODO(agl): Figure out if we can plumb the OCSP response into Mac's system | |
222 // certificate validation functions. | |
223 bool IsOCSPStaplingSupported() { | 221 bool IsOCSPStaplingSupported() { |
224 return false; | 222 return false; |
225 } | 223 } |
226 #endif | 224 #endif |
227 | 225 |
228 #if defined(OS_WIN) | 226 #if defined(OS_WIN) |
229 | 227 |
230 // This callback is intended to be used with CertFindChainInStore. In addition | 228 // This callback is intended to be used with CertFindChainInStore. In addition |
231 // to filtering by extended/enhanced key usage, we do not show expired | 229 // to filtering by extended/enhanced key usage, we do not show expired |
232 // certificates and require digital signature usage in the key usage | 230 // certificates and require digital signature usage in the key usage |
(...skipping 1052 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1285 DCHECK(core->OnNSSTaskRunner()); | 1283 DCHECK(core->OnNSSTaskRunner()); |
1286 | 1284 |
1287 core->PostOrRunCallback( | 1285 core->PostOrRunCallback( |
1288 FROM_HERE, | 1286 FROM_HERE, |
1289 base::Bind(&AddLogEvent, core->weak_net_log_, | 1287 base::Bind(&AddLogEvent, core->weak_net_log_, |
1290 NetLog::TYPE_SSL_CLIENT_CERT_REQUESTED)); | 1288 NetLog::TYPE_SSL_CLIENT_CERT_REQUESTED)); |
1291 | 1289 |
1292 core->client_auth_cert_needed_ = !core->ssl_config_.send_client_cert; | 1290 core->client_auth_cert_needed_ = !core->ssl_config_.send_client_cert; |
1293 #if defined(OS_WIN) | 1291 #if defined(OS_WIN) |
1294 if (core->ssl_config_.send_client_cert) { | 1292 if (core->ssl_config_.send_client_cert) { |
1295 if (core->ssl_config_.client_cert) { | 1293 if (core->ssl_config_.client_cert.get()) { |
1296 PCCERT_CONTEXT cert_context = | 1294 PCCERT_CONTEXT cert_context = |
1297 core->ssl_config_.client_cert->os_cert_handle(); | 1295 core->ssl_config_.client_cert->os_cert_handle(); |
1298 | 1296 |
1299 HCRYPTPROV_OR_NCRYPT_KEY_HANDLE crypt_prov = 0; | 1297 HCRYPTPROV_OR_NCRYPT_KEY_HANDLE crypt_prov = 0; |
1300 DWORD key_spec = 0; | 1298 DWORD key_spec = 0; |
1301 BOOL must_free = FALSE; | 1299 BOOL must_free = FALSE; |
1302 DWORD flags = 0; | 1300 DWORD flags = 0; |
1303 if (base::win::GetVersion() >= base::win::VERSION_VISTA) | 1301 if (base::win::GetVersion() >= base::win::VERSION_VISTA) |
1304 flags |= CRYPT_ACQUIRE_PREFER_NCRYPT_KEY_FLAG; | 1302 flags |= CRYPT_ACQUIRE_PREFER_NCRYPT_KEY_FLAG; |
1305 | 1303 |
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1623 SSL_CacheSessionUnlocked(socket); | 1621 SSL_CacheSessionUnlocked(socket); |
1624 | 1622 |
1625 // Additionally, when False Starting, DoHandshake() will have already | 1623 // Additionally, when False Starting, DoHandshake() will have already |
1626 // called HandshakeSucceeded(), so return now. | 1624 // called HandshakeSucceeded(), so return now. |
1627 return; | 1625 return; |
1628 } | 1626 } |
1629 core->HandshakeSucceeded(); | 1627 core->HandshakeSucceeded(); |
1630 } | 1628 } |
1631 | 1629 |
1632 void SSLClientSocketNSS::Core::HandshakeSucceeded() { | 1630 void SSLClientSocketNSS::Core::HandshakeSucceeded() { |
1633 // TODO(vadimt): Remove ScopedProfile below once crbug.com/424386 is fixed. | 1631 // TODO(vadimt): Remove ScopedTracker below once crbug.com/424386 is fixed. |
1634 tracked_objects::ScopedProfile tracking_profile( | 1632 tracked_objects::ScopedTracker tracking_profile( |
1635 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 1633 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
1636 "424386 SSLClientSocketNSS::Core::HandshakeSucceeded")); | 1634 "424386 SSLClientSocketNSS::Core::HandshakeSucceeded")); |
1637 | 1635 |
1638 DCHECK(OnNSSTaskRunner()); | 1636 DCHECK(OnNSSTaskRunner()); |
1639 | 1637 |
1640 PRBool last_handshake_resumed; | 1638 PRBool last_handshake_resumed; |
1641 SECStatus rv = SSL_HandshakeResumedSession(nss_fd_, &last_handshake_resumed); | 1639 SECStatus rv = SSL_HandshakeResumedSession(nss_fd_, &last_handshake_resumed); |
1642 if (rv == SECSuccess && last_handshake_resumed) { | 1640 if (rv == SECSuccess && last_handshake_resumed) { |
1643 nss_handshake_state_.resumed_handshake = true; | 1641 nss_handshake_state_.resumed_handshake = true; |
1644 } else { | 1642 } else { |
1645 nss_handshake_state_.resumed_handshake = false; | 1643 nss_handshake_state_.resumed_handshake = false; |
1646 } | 1644 } |
1647 | 1645 |
1648 RecordChannelIDSupportOnNSSTaskRunner(); | 1646 RecordChannelIDSupportOnNSSTaskRunner(); |
1649 UpdateServerCert(); | 1647 UpdateServerCert(); |
1650 UpdateSignedCertTimestamps(); | 1648 UpdateSignedCertTimestamps(); |
1651 UpdateStapledOCSPResponse(); | 1649 UpdateStapledOCSPResponse(); |
1652 UpdateConnectionStatus(); | 1650 UpdateConnectionStatus(); |
1653 UpdateNextProto(); | 1651 UpdateNextProto(); |
1654 UpdateExtensionUsed(); | 1652 UpdateExtensionUsed(); |
1655 | 1653 |
1656 // Update the network task runners view of the handshake state whenever | 1654 // Update the network task runners view of the handshake state whenever |
1657 // a handshake has completed. | 1655 // a handshake has completed. |
1658 PostOrRunCallback( | 1656 PostOrRunCallback( |
1659 FROM_HERE, base::Bind(&Core::OnHandshakeStateUpdated, this, | 1657 FROM_HERE, base::Bind(&Core::OnHandshakeStateUpdated, this, |
1660 nss_handshake_state_)); | 1658 nss_handshake_state_)); |
1661 } | 1659 } |
1662 | 1660 |
1663 int SSLClientSocketNSS::Core::HandleNSSError(PRErrorCode nss_error) { | 1661 int SSLClientSocketNSS::Core::HandleNSSError(PRErrorCode nss_error) { |
1664 // TODO(vadimt): Remove ScopedProfile below once crbug.com/424386 is fixed. | 1662 // TODO(vadimt): Remove ScopedTracker below once crbug.com/424386 is fixed. |
1665 tracked_objects::ScopedProfile tracking_profile( | 1663 tracked_objects::ScopedTracker tracking_profile( |
1666 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 1664 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
1667 "424386 SSLClientSocketNSS::Core::HandleNSSError")); | 1665 "424386 SSLClientSocketNSS::Core::HandleNSSError")); |
1668 | 1666 |
1669 DCHECK(OnNSSTaskRunner()); | 1667 DCHECK(OnNSSTaskRunner()); |
1670 | 1668 |
1671 int net_error = MapNSSClientError(nss_error); | 1669 int net_error = MapNSSClientError(nss_error); |
1672 | 1670 |
1673 #if defined(OS_WIN) | 1671 #if defined(OS_WIN) |
1674 // On Windows, a handle to the HCRYPTPROV is cached in the X509Certificate | 1672 // On Windows, a handle to the HCRYPTPROV is cached in the X509Certificate |
1675 // os_cert_handle() as an optimization. However, if the certificate | 1673 // os_cert_handle() as an optimization. However, if the certificate |
1676 // private key is stored on a smart card, and the smart card is removed, | 1674 // private key is stored on a smart card, and the smart card is removed, |
1677 // the cached HCRYPTPROV will not be able to obtain the HCRYPTKEY again, | 1675 // the cached HCRYPTPROV will not be able to obtain the HCRYPTKEY again, |
1678 // preventing client certificate authentication. Because the | 1676 // preventing client certificate authentication. Because the |
1679 // X509Certificate may outlive the individual SSLClientSocketNSS, due to | 1677 // X509Certificate may outlive the individual SSLClientSocketNSS, due to |
1680 // caching in X509Certificate, this failure ends up preventing client | 1678 // caching in X509Certificate, this failure ends up preventing client |
1681 // certificate authentication with the same certificate for all future | 1679 // certificate authentication with the same certificate for all future |
1682 // attempts, even after the smart card has been re-inserted. By setting | 1680 // attempts, even after the smart card has been re-inserted. By setting |
1683 // the CERT_KEY_PROV_HANDLE_PROP_ID to NULL, the cached HCRYPTPROV will | 1681 // the CERT_KEY_PROV_HANDLE_PROP_ID to NULL, the cached HCRYPTPROV will |
1684 // typically be freed. This allows a new HCRYPTPROV to be obtained from | 1682 // typically be freed. This allows a new HCRYPTPROV to be obtained from |
1685 // the certificate on the next attempt, which should succeed if the smart | 1683 // the certificate on the next attempt, which should succeed if the smart |
1686 // card has been re-inserted, or will typically prompt the user to | 1684 // card has been re-inserted, or will typically prompt the user to |
1687 // re-insert the smart card if not. | 1685 // re-insert the smart card if not. |
1688 if ((net_error == ERR_SSL_CLIENT_AUTH_CERT_NO_PRIVATE_KEY || | 1686 if ((net_error == ERR_SSL_CLIENT_AUTH_CERT_NO_PRIVATE_KEY || |
1689 net_error == ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED) && | 1687 net_error == ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED) && |
1690 ssl_config_.send_client_cert && ssl_config_.client_cert) { | 1688 ssl_config_.send_client_cert && ssl_config_.client_cert.get()) { |
1691 CertSetCertificateContextProperty( | 1689 CertSetCertificateContextProperty( |
1692 ssl_config_.client_cert->os_cert_handle(), | 1690 ssl_config_.client_cert->os_cert_handle(), |
1693 CERT_KEY_PROV_HANDLE_PROP_ID, 0, NULL); | 1691 CERT_KEY_PROV_HANDLE_PROP_ID, 0, NULL); |
1694 } | 1692 } |
1695 #endif | 1693 #endif |
1696 | 1694 |
1697 return net_error; | 1695 return net_error; |
1698 } | 1696 } |
1699 | 1697 |
1700 int SSLClientSocketNSS::Core::DoHandshakeLoop(int last_io_result) { | 1698 int SSLClientSocketNSS::Core::DoHandshakeLoop(int last_io_result) { |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1806 // TODO(vadimt): Remove ScopedTracker below once crbug.com/424386 is fixed. | 1804 // TODO(vadimt): Remove ScopedTracker below once crbug.com/424386 is fixed. |
1807 tracked_objects::ScopedTracker tracking_profile( | 1805 tracked_objects::ScopedTracker tracking_profile( |
1808 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 1806 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
1809 "424386 SSLClientSocketNSS::Core::DoHandshake")); | 1807 "424386 SSLClientSocketNSS::Core::DoHandshake")); |
1810 | 1808 |
1811 DCHECK(OnNSSTaskRunner()); | 1809 DCHECK(OnNSSTaskRunner()); |
1812 | 1810 |
1813 int net_error = OK; | 1811 int net_error = OK; |
1814 SECStatus rv = SSL_ForceHandshake(nss_fd_); | 1812 SECStatus rv = SSL_ForceHandshake(nss_fd_); |
1815 | 1813 |
1816 // TODO(vadimt): Remove ScopedProfile below once crbug.com/424386 is fixed. | 1814 // TODO(vadimt): Remove ScopedTracker below once crbug.com/424386 is fixed. |
1817 tracked_objects::ScopedProfile tracking_profile1( | 1815 tracked_objects::ScopedTracker tracking_profile1( |
1818 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 1816 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
1819 "424386 SSLClientSocketNSS::Core::DoHandshake 1")); | 1817 "424386 SSLClientSocketNSS::Core::DoHandshake 1")); |
1820 | 1818 |
1821 // Note: this function may be called multiple times during the handshake, so | 1819 // Note: this function may be called multiple times during the handshake, so |
1822 // even though channel id and client auth are separate else cases, they can | 1820 // even though channel id and client auth are separate else cases, they can |
1823 // both be used during a single SSL handshake. | 1821 // both be used during a single SSL handshake. |
1824 if (channel_id_needed_) { | 1822 if (channel_id_needed_) { |
1825 GotoState(STATE_GET_DOMAIN_BOUND_CERT_COMPLETE); | 1823 GotoState(STATE_GET_DOMAIN_BOUND_CERT_COMPLETE); |
1826 net_error = ERR_IO_PENDING; | 1824 net_error = ERR_IO_PENDING; |
1827 } else if (client_auth_cert_needed_) { | 1825 } else if (client_auth_cert_needed_) { |
(...skipping 601 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2429 bool ocsp_responses_present = ocsp_responses && ocsp_responses->len; | 2427 bool ocsp_responses_present = ocsp_responses && ocsp_responses->len; |
2430 if (ocsp_requested) | 2428 if (ocsp_requested) |
2431 UMA_HISTOGRAM_BOOLEAN("Net.OCSPResponseStapled", ocsp_responses_present); | 2429 UMA_HISTOGRAM_BOOLEAN("Net.OCSPResponseStapled", ocsp_responses_present); |
2432 if (!ocsp_responses_present) | 2430 if (!ocsp_responses_present) |
2433 return; | 2431 return; |
2434 | 2432 |
2435 nss_handshake_state_.stapled_ocsp_response = std::string( | 2433 nss_handshake_state_.stapled_ocsp_response = std::string( |
2436 reinterpret_cast<char*>(ocsp_responses->items[0].data), | 2434 reinterpret_cast<char*>(ocsp_responses->items[0].data), |
2437 ocsp_responses->items[0].len); | 2435 ocsp_responses->items[0].len); |
2438 | 2436 |
2439 // TODO(agl): figure out how to plumb an OCSP response into the Mac | |
2440 // system library and update IsOCSPStaplingSupported for Mac. | |
2441 if (IsOCSPStaplingSupported()) { | 2437 if (IsOCSPStaplingSupported()) { |
2442 #if defined(OS_WIN) | 2438 #if defined(OS_WIN) |
2443 if (nss_handshake_state_.server_cert) { | 2439 if (nss_handshake_state_.server_cert.get()) { |
2444 CRYPT_DATA_BLOB ocsp_response_blob; | 2440 CRYPT_DATA_BLOB ocsp_response_blob; |
2445 ocsp_response_blob.cbData = ocsp_responses->items[0].len; | 2441 ocsp_response_blob.cbData = ocsp_responses->items[0].len; |
2446 ocsp_response_blob.pbData = ocsp_responses->items[0].data; | 2442 ocsp_response_blob.pbData = ocsp_responses->items[0].data; |
2447 BOOL ok = CertSetCertificateContextProperty( | 2443 BOOL ok = CertSetCertificateContextProperty( |
2448 nss_handshake_state_.server_cert->os_cert_handle(), | 2444 nss_handshake_state_.server_cert->os_cert_handle(), |
2449 CERT_OCSP_RESPONSE_PROP_ID, | 2445 CERT_OCSP_RESPONSE_PROP_ID, |
2450 CERT_SET_PROPERTY_IGNORE_PERSIST_ERROR_FLAG, | 2446 CERT_SET_PROPERTY_IGNORE_PERSIST_ERROR_FLAG, |
2451 &ocsp_response_blob); | 2447 &ocsp_response_blob); |
2452 if (!ok) { | 2448 if (!ok) { |
2453 VLOG(1) << "Failed to set OCSP response property: " | 2449 VLOG(1) << "Failed to set OCSP response property: " |
(...skipping 1160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3614 scoped_refptr<X509Certificate> | 3610 scoped_refptr<X509Certificate> |
3615 SSLClientSocketNSS::GetUnverifiedServerCertificateChain() const { | 3611 SSLClientSocketNSS::GetUnverifiedServerCertificateChain() const { |
3616 return core_->state().server_cert.get(); | 3612 return core_->state().server_cert.get(); |
3617 } | 3613 } |
3618 | 3614 |
3619 ChannelIDService* SSLClientSocketNSS::GetChannelIDService() const { | 3615 ChannelIDService* SSLClientSocketNSS::GetChannelIDService() const { |
3620 return channel_id_service_; | 3616 return channel_id_service_; |
3621 } | 3617 } |
3622 | 3618 |
3623 } // namespace net | 3619 } // namespace net |
OLD | NEW |