| 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 |