OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
43 * the provisions above, a recipient may use your version of this file under | 43 * the provisions above, a recipient may use your version of this file under |
44 * the terms of any one of the MPL, the GPL or the LGPL. | 44 * the terms of any one of the MPL, the GPL or the LGPL. |
45 * | 45 * |
46 * ***** END LICENSE BLOCK ***** */ | 46 * ***** END LICENSE BLOCK ***** */ |
47 | 47 |
48 #include "net/socket/ssl_client_socket_nss.h" | 48 #include "net/socket/ssl_client_socket_nss.h" |
49 | 49 |
50 #if defined(USE_SYSTEM_SSL) | 50 #if defined(USE_SYSTEM_SSL) |
51 #include <dlfcn.h> | 51 #include <dlfcn.h> |
52 #endif | 52 #endif |
| 53 #if defined(OS_MACOSX) |
| 54 #include <Security/Security.h> |
| 55 #endif |
53 #include <certdb.h> | 56 #include <certdb.h> |
54 #include <hasht.h> | 57 #include <hasht.h> |
55 #include <keyhi.h> | 58 #include <keyhi.h> |
56 #include <nspr.h> | 59 #include <nspr.h> |
57 #include <nss.h> | 60 #include <nss.h> |
58 #include <pk11pub.h> | 61 #include <pk11pub.h> |
59 #include <secerr.h> | 62 #include <secerr.h> |
60 #include <sechash.h> | 63 #include <sechash.h> |
61 #include <ssl.h> | 64 #include <ssl.h> |
62 #include <sslerr.h> | 65 #include <sslerr.h> |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
207 return ERR_CONNECTION_REFUSED; | 210 return ERR_CONNECTION_REFUSED; |
208 case PR_HOST_UNREACHABLE_ERROR: | 211 case PR_HOST_UNREACHABLE_ERROR: |
209 case PR_NETWORK_UNREACHABLE_ERROR: | 212 case PR_NETWORK_UNREACHABLE_ERROR: |
210 return ERR_ADDRESS_UNREACHABLE; | 213 return ERR_ADDRESS_UNREACHABLE; |
211 case PR_ADDRESS_NOT_AVAILABLE_ERROR: | 214 case PR_ADDRESS_NOT_AVAILABLE_ERROR: |
212 return ERR_ADDRESS_INVALID; | 215 return ERR_ADDRESS_INVALID; |
213 case PR_INVALID_ARGUMENT_ERROR: | 216 case PR_INVALID_ARGUMENT_ERROR: |
214 return ERR_INVALID_ARGUMENT; | 217 return ERR_INVALID_ARGUMENT; |
215 case PR_END_OF_FILE_ERROR: | 218 case PR_END_OF_FILE_ERROR: |
216 return ERR_CONNECTION_CLOSED; | 219 return ERR_CONNECTION_CLOSED; |
| 220 case PR_NOT_IMPLEMENTED_ERROR: |
| 221 return ERR_NOT_IMPLEMENTED; |
217 | 222 |
218 case SEC_ERROR_INVALID_ARGS: | 223 case SEC_ERROR_INVALID_ARGS: |
219 return ERR_INVALID_ARGUMENT; | 224 return ERR_INVALID_ARGUMENT; |
220 | 225 |
221 case SSL_ERROR_SSL_DISABLED: | 226 case SSL_ERROR_SSL_DISABLED: |
222 return ERR_NO_SSL_VERSIONS_ENABLED; | 227 return ERR_NO_SSL_VERSIONS_ENABLED; |
223 case SSL_ERROR_NO_CYPHER_OVERLAP: | 228 case SSL_ERROR_NO_CYPHER_OVERLAP: |
224 case SSL_ERROR_UNSUPPORTED_VERSION: | 229 case SSL_ERROR_UNSUPPORTED_VERSION: |
225 return ERR_SSL_VERSION_OR_CIPHER_MISMATCH; | 230 return ERR_SSL_VERSION_OR_CIPHER_MISMATCH; |
226 case SSL_ERROR_HANDSHAKE_FAILURE_ALERT: | 231 case SSL_ERROR_HANDSHAKE_FAILURE_ALERT: |
(...skipping 566 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
793 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_HANDSHAKE_AS_CLIENT"); | 798 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_HANDSHAKE_AS_CLIENT"); |
794 return ERR_UNEXPECTED; | 799 return ERR_UNEXPECTED; |
795 } | 800 } |
796 | 801 |
797 rv = SSL_AuthCertificateHook(nss_fd_, OwnAuthCertHandler, this); | 802 rv = SSL_AuthCertificateHook(nss_fd_, OwnAuthCertHandler, this); |
798 if (rv != SECSuccess) { | 803 if (rv != SECSuccess) { |
799 LogFailedNSSFunction(net_log_, "SSL_AuthCertificateHook", ""); | 804 LogFailedNSSFunction(net_log_, "SSL_AuthCertificateHook", ""); |
800 return ERR_UNEXPECTED; | 805 return ERR_UNEXPECTED; |
801 } | 806 } |
802 | 807 |
| 808 #if defined(NSS_PLATFORM_CLIENT_AUTH) |
| 809 rv = SSL_GetPlatformClientAuthDataHook(nss_fd_, PlatformClientAuthHandler, |
| 810 this); |
| 811 #else |
803 rv = SSL_GetClientAuthDataHook(nss_fd_, ClientAuthHandler, this); | 812 rv = SSL_GetClientAuthDataHook(nss_fd_, ClientAuthHandler, this); |
| 813 #endif |
804 if (rv != SECSuccess) { | 814 if (rv != SECSuccess) { |
805 LogFailedNSSFunction(net_log_, "SSL_GetClientAuthDataHook", ""); | 815 LogFailedNSSFunction(net_log_, "SSL_GetClientAuthDataHook", ""); |
806 return ERR_UNEXPECTED; | 816 return ERR_UNEXPECTED; |
807 } | 817 } |
808 | 818 |
809 rv = SSL_HandshakeCallback(nss_fd_, HandshakeCallback, this); | 819 rv = SSL_HandshakeCallback(nss_fd_, HandshakeCallback, this); |
810 if (rv != SECSuccess) { | 820 if (rv != SECSuccess) { |
811 LogFailedNSSFunction(net_log_, "SSL_HandshakeCallback", ""); | 821 LogFailedNSSFunction(net_log_, "SSL_HandshakeCallback", ""); |
812 return ERR_UNEXPECTED; | 822 return ERR_UNEXPECTED; |
813 } | 823 } |
(...skipping 543 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1357 if (result >=0) | 1367 if (result >=0) |
1358 return result; | 1368 return result; |
1359 | 1369 |
1360 switch (result) { | 1370 switch (result) { |
1361 case ERR_IO_PENDING: | 1371 case ERR_IO_PENDING: |
1362 return PR_WOULD_BLOCK_ERROR; | 1372 return PR_WOULD_BLOCK_ERROR; |
1363 case ERR_ACCESS_DENIED: | 1373 case ERR_ACCESS_DENIED: |
1364 case ERR_NETWORK_ACCESS_DENIED: | 1374 case ERR_NETWORK_ACCESS_DENIED: |
1365 // For connect, this could be mapped to PR_ADDRESS_NOT_SUPPORTED_ERROR. | 1375 // For connect, this could be mapped to PR_ADDRESS_NOT_SUPPORTED_ERROR. |
1366 return PR_NO_ACCESS_RIGHTS_ERROR; | 1376 return PR_NO_ACCESS_RIGHTS_ERROR; |
| 1377 case ERR_NOT_IMPLEMENTED: |
| 1378 return PR_NOT_IMPLEMENTED_ERROR; |
1367 case ERR_INTERNET_DISCONNECTED: // Equivalent to ENETDOWN. | 1379 case ERR_INTERNET_DISCONNECTED: // Equivalent to ENETDOWN. |
1368 return PR_NETWORK_UNREACHABLE_ERROR; // Best approximation. | 1380 return PR_NETWORK_UNREACHABLE_ERROR; // Best approximation. |
1369 case ERR_CONNECTION_TIMED_OUT: | 1381 case ERR_CONNECTION_TIMED_OUT: |
1370 case ERR_TIMED_OUT: | 1382 case ERR_TIMED_OUT: |
1371 return PR_IO_TIMEOUT_ERROR; | 1383 return PR_IO_TIMEOUT_ERROR; |
1372 case ERR_CONNECTION_RESET: | 1384 case ERR_CONNECTION_RESET: |
1373 return PR_CONNECT_RESET_ERROR; | 1385 return PR_CONNECT_RESET_ERROR; |
1374 case ERR_CONNECTION_ABORTED: | 1386 case ERR_CONNECTION_ABORTED: |
1375 return PR_CONNECT_ABORTED_ERROR; | 1387 return PR_CONNECT_ABORTED_ERROR; |
1376 case ERR_CONNECTION_REFUSED: | 1388 case ERR_CONNECTION_REFUSED: |
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1643 } | 1655 } |
1644 CERT_DestroyCertificate(cert); | 1656 CERT_DestroyCertificate(cert); |
1645 } | 1657 } |
1646 } | 1658 } |
1647 #endif | 1659 #endif |
1648 | 1660 |
1649 // Tell NSS to not verify the certificate. | 1661 // Tell NSS to not verify the certificate. |
1650 return SECSuccess; | 1662 return SECSuccess; |
1651 } | 1663 } |
1652 | 1664 |
| 1665 #if defined(NSS_PLATFORM_CLIENT_AUTH) |
1653 // static | 1666 // static |
1654 // NSS calls this if a client certificate is needed. | 1667 // NSS calls this if a client certificate is needed. |
1655 // Based on Mozilla's NSS_GetClientAuthData. | 1668 SECStatus SSLClientSocketNSS::PlatformClientAuthHandler( |
1656 SECStatus SSLClientSocketNSS::ClientAuthHandler( | |
1657 void* arg, | 1669 void* arg, |
1658 PRFileDesc* socket, | 1670 PRFileDesc* socket, |
1659 CERTDistNames* ca_names, | 1671 CERTDistNames* ca_names, |
1660 CERTCertificate** result_certificate, | 1672 CERTCertList** result_certs, |
1661 SECKEYPrivateKey** result_private_key) { | 1673 void** result_private_key) { |
1662 // NSS passes a null ca_names if SSL 2.0 is used. Just fail rather than | |
1663 // trying to make this work, as we plan to remove SSL 2.0 support soon. | |
1664 if (!ca_names) | |
1665 return SECFailure; | |
1666 | |
1667 SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg); | 1674 SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg); |
1668 | 1675 |
1669 that->client_auth_cert_needed_ = !that->ssl_config_.send_client_cert; | 1676 that->client_auth_cert_needed_ = !that->ssl_config_.send_client_cert; |
1670 | |
1671 #if defined(OS_WIN) | 1677 #if defined(OS_WIN) |
1672 if (that->ssl_config_.send_client_cert) { | 1678 if (that->ssl_config_.send_client_cert) { |
1673 // TODO(wtc): SSLClientSocketNSS can't do SSL client authentication using | 1679 if (that->ssl_config_.client_cert) { |
1674 // CryptoAPI yet (http://crbug.com/37560), so client_cert must be NULL. | 1680 PCCERT_CONTEXT cert_context = |
1675 DCHECK(!that->ssl_config_.client_cert); | 1681 that->ssl_config_.client_cert->os_cert_handle(); |
| 1682 HCRYPTPROV provider = NULL; |
| 1683 DWORD key_spec = AT_KEYEXCHANGE; |
| 1684 BOOL must_free = FALSE; |
| 1685 BOOL acquired_key = CryptAcquireCertificatePrivateKey( |
| 1686 cert_context, |
| 1687 CRYPT_ACQUIRE_CACHE_FLAG | CRYPT_ACQUIRE_COMPARE_KEY_FLAG, |
| 1688 NULL, &provider, &key_spec, &must_free); |
| 1689 if (acquired_key && provider) { |
| 1690 DCHECK_NE(key_spec, CERT_NCRYPT_KEY_SPEC); |
| 1691 |
| 1692 // The certificate cache may have been updated/used, in which case, |
| 1693 // duplicate the existing handle, since NSS will free it when no |
| 1694 // longer in use. |
| 1695 if (!must_free) |
| 1696 CryptContextAddRef(provider, NULL, 0); |
| 1697 |
| 1698 SECItem der_cert; |
| 1699 der_cert.type = siDERCertBuffer; |
| 1700 der_cert.data = cert_context->pbCertEncoded; |
| 1701 der_cert.len = cert_context->cbCertEncoded; |
| 1702 |
| 1703 // TODO(rsleevi): Error checking for NSS allocation errors. |
| 1704 *result_certs = CERT_NewCertList(); |
| 1705 CERTCertDBHandle* db_handle = CERT_GetDefaultCertDB(); |
| 1706 CERTCertificate* user_cert = CERT_NewTempCertificate( |
| 1707 db_handle, &der_cert, NULL, PR_FALSE, PR_TRUE); |
| 1708 CERT_AddCertToListTail(*result_certs, user_cert); |
| 1709 |
| 1710 // Add the intermediates. |
| 1711 X509Certificate::OSCertHandles intermediates = |
| 1712 that->ssl_config_.client_cert->GetIntermediateCertificates(); |
| 1713 for (X509Certificate::OSCertHandles::const_iterator it = |
| 1714 intermediates.begin(); it != intermediates.end(); ++it) { |
| 1715 der_cert.data = (*it)->pbCertEncoded; |
| 1716 der_cert.len = (*it)->cbCertEncoded; |
| 1717 |
| 1718 CERTCertificate* intermediate = CERT_NewTempCertificate( |
| 1719 db_handle, &der_cert, NULL, PR_FALSE, PR_TRUE); |
| 1720 CERT_AddCertToListTail(*result_certs, intermediate); |
| 1721 } |
| 1722 // TODO(wtc): |key_spec| should be passed along with |provider|. |
| 1723 *result_private_key = reinterpret_cast<void*>(provider); |
| 1724 return SECSuccess; |
| 1725 } |
| 1726 LOG(WARNING) << "Client cert found without private key"; |
| 1727 } |
1676 // Send no client certificate. | 1728 // Send no client certificate. |
1677 return SECFailure; | 1729 return SECFailure; |
1678 } | 1730 } |
1679 | 1731 |
1680 that->client_certs_.clear(); | 1732 that->client_certs_.clear(); |
1681 | 1733 |
1682 std::vector<CERT_NAME_BLOB> issuer_list(ca_names->nnames); | 1734 std::vector<CERT_NAME_BLOB> issuer_list(ca_names->nnames); |
1683 for (int i = 0; i < ca_names->nnames; ++i) { | 1735 for (int i = 0; i < ca_names->nnames; ++i) { |
1684 issuer_list[i].cbData = ca_names->names[i].len; | 1736 issuer_list[i].cbData = ca_names->names[i].len; |
1685 issuer_list[i].pbData = ca_names->names[i].data; | 1737 issuer_list[i].pbData = ca_names->names[i].data; |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1726 // certificate store before returning from this function. | 1778 // certificate store before returning from this function. |
1727 PCCERT_CONTEXT cert_context2; | 1779 PCCERT_CONTEXT cert_context2; |
1728 BOOL ok = CertAddCertificateContextToStore(X509Certificate::cert_store(), | 1780 BOOL ok = CertAddCertificateContextToStore(X509Certificate::cert_store(), |
1729 cert_context, | 1781 cert_context, |
1730 CERT_STORE_ADD_USE_EXISTING, | 1782 CERT_STORE_ADD_USE_EXISTING, |
1731 &cert_context2); | 1783 &cert_context2); |
1732 if (!ok) { | 1784 if (!ok) { |
1733 NOTREACHED(); | 1785 NOTREACHED(); |
1734 continue; | 1786 continue; |
1735 } | 1787 } |
| 1788 |
| 1789 // Copy the rest of the chain to our own store as well. Copying the chain |
| 1790 // stops gracefully if an error is encountered, with the partial chain |
| 1791 // being used as the intermediates, rather than failing to consider the |
| 1792 // client certificate. |
| 1793 net::X509Certificate::OSCertHandles intermediates; |
| 1794 for (DWORD i = 1; i < chain_context->rgpChain[0]->cElement; i++) { |
| 1795 PCCERT_CONTEXT intermediate_copy; |
| 1796 ok = CertAddCertificateContextToStore(X509Certificate::cert_store(), |
| 1797 chain_context->rgpChain[0]->rgpElement[i]->pCertContext, |
| 1798 CERT_STORE_ADD_USE_EXISTING, &intermediate_copy); |
| 1799 if (!ok) { |
| 1800 NOTREACHED(); |
| 1801 break; |
| 1802 } |
| 1803 intermediates.push_back(intermediate_copy); |
| 1804 } |
| 1805 |
1736 scoped_refptr<X509Certificate> cert = X509Certificate::CreateFromHandle( | 1806 scoped_refptr<X509Certificate> cert = X509Certificate::CreateFromHandle( |
1737 cert_context2, X509Certificate::SOURCE_LONE_CERT_IMPORT, | 1807 cert_context2, X509Certificate::SOURCE_LONE_CERT_IMPORT, |
1738 X509Certificate::OSCertHandles()); | 1808 intermediates); |
| 1809 that->client_certs_.push_back(cert); |
| 1810 |
1739 X509Certificate::FreeOSCertHandle(cert_context2); | 1811 X509Certificate::FreeOSCertHandle(cert_context2); |
1740 that->client_certs_.push_back(cert); | 1812 for (net::X509Certificate::OSCertHandles::iterator it = |
| 1813 intermediates.begin(); it != intermediates.end(); ++it) { |
| 1814 net::X509Certificate::FreeOSCertHandle(*it); |
| 1815 } |
1741 } | 1816 } |
1742 | 1817 |
1743 BOOL ok = CertCloseStore(my_cert_store, CERT_CLOSE_STORE_CHECK_FLAG); | 1818 BOOL ok = CertCloseStore(my_cert_store, CERT_CLOSE_STORE_CHECK_FLAG); |
1744 DCHECK(ok); | 1819 DCHECK(ok); |
1745 | 1820 |
1746 // Tell NSS to suspend the client authentication. We will then abort the | 1821 // Tell NSS to suspend the client authentication. We will then abort the |
1747 // handshake by returning ERR_SSL_CLIENT_AUTH_CERT_NEEDED. | 1822 // handshake by returning ERR_SSL_CLIENT_AUTH_CERT_NEEDED. |
1748 return SECWouldBlock; | 1823 return SECWouldBlock; |
1749 #elif defined(OS_MACOSX) | 1824 #elif defined(OS_MACOSX) |
1750 if (that->ssl_config_.send_client_cert) { | 1825 if (that->ssl_config_.send_client_cert) { |
1751 // TODO(wtc): SSLClientSocketNSS can't do SSL client authentication using | 1826 if (that->ssl_config_.client_cert) { |
1752 // CDSA/CSSM yet (http://crbug.com/45369), so client_cert must be NULL. | 1827 OSStatus os_error = noErr; |
1753 DCHECK(!that->ssl_config_.client_cert); | 1828 SecIdentityRef identity = NULL; |
| 1829 SecKeyRef private_key = NULL; |
| 1830 CFArrayRef chain = |
| 1831 that->ssl_config_.client_cert->CreateClientCertificateChain(); |
| 1832 if (chain) { |
| 1833 identity = reinterpret_cast<SecIdentityRef>( |
| 1834 const_cast<void*>(CFArrayGetValueAtIndex(chain, 0))); |
| 1835 } |
| 1836 if (identity) |
| 1837 os_error = SecIdentityCopyPrivateKey(identity, &private_key); |
| 1838 |
| 1839 if (chain && identity && os_error == noErr) { |
| 1840 // TODO(rsleevi): Error checking for NSS allocation errors. |
| 1841 *result_certs = CERT_NewCertList(); |
| 1842 *result_private_key = reinterpret_cast<void*>(private_key); |
| 1843 |
| 1844 for (CFIndex i = 0; i < CFArrayGetCount(chain); ++i) { |
| 1845 CSSM_DATA cert_data; |
| 1846 SecCertificateRef cert_ref; |
| 1847 if (i == 0) { |
| 1848 cert_ref = that->ssl_config_.client_cert->os_cert_handle(); |
| 1849 } else { |
| 1850 cert_ref = reinterpret_cast<SecCertificateRef>( |
| 1851 const_cast<void*>(CFArrayGetValueAtIndex(chain, i))); |
| 1852 } |
| 1853 os_error = SecCertificateGetData(cert_ref, &cert_data); |
| 1854 if (os_error != noErr) |
| 1855 break; |
| 1856 |
| 1857 SECItem der_cert; |
| 1858 der_cert.type = siDERCertBuffer; |
| 1859 der_cert.data = cert_data.Data; |
| 1860 der_cert.len = cert_data.Length; |
| 1861 CERTCertificate* nss_cert = CERT_NewTempCertificate( |
| 1862 CERT_GetDefaultCertDB(), &der_cert, NULL, PR_FALSE, PR_TRUE); |
| 1863 CERT_AddCertToListTail(*result_certs, nss_cert); |
| 1864 } |
| 1865 } |
| 1866 if (os_error == noErr) { |
| 1867 CFRelease(chain); |
| 1868 return SECSuccess; |
| 1869 } |
| 1870 LOG(WARNING) << "Client cert found, but could not be used: " |
| 1871 << os_error; |
| 1872 if (*result_certs) { |
| 1873 CERT_DestroyCertList(*result_certs); |
| 1874 *result_certs = NULL; |
| 1875 } |
| 1876 if (*result_private_key) |
| 1877 *result_private_key = NULL; |
| 1878 if (private_key) |
| 1879 CFRelease(private_key); |
| 1880 if (chain) |
| 1881 CFRelease(chain); |
| 1882 } |
1754 // Send no client certificate. | 1883 // Send no client certificate. |
1755 return SECFailure; | 1884 return SECFailure; |
1756 } | 1885 } |
1757 | 1886 |
1758 that->client_certs_.clear(); | 1887 that->client_certs_.clear(); |
1759 | 1888 |
1760 // First, get the cert issuer names allowed by the server. | 1889 // First, get the cert issuer names allowed by the server. |
1761 std::vector<CertPrincipal> valid_issuers; | 1890 std::vector<CertPrincipal> valid_issuers; |
1762 int n = ca_names->nnames; | 1891 int n = ca_names->nnames; |
1763 for (int i = 0; i < n; i++) { | 1892 for (int i = 0; i < n; i++) { |
1764 // Parse each name into a CertPrincipal object. | 1893 // Parse each name into a CertPrincipal object. |
1765 CertPrincipal p; | 1894 CertPrincipal p; |
1766 if (p.ParseDistinguishedName(ca_names->names[i].data, | 1895 if (p.ParseDistinguishedName(ca_names->names[i].data, |
1767 ca_names->names[i].len)) { | 1896 ca_names->names[i].len)) { |
1768 valid_issuers.push_back(p); | 1897 valid_issuers.push_back(p); |
1769 } | 1898 } |
1770 } | 1899 } |
1771 | 1900 |
1772 // Now get the available client certs whose issuers are allowed by the server. | 1901 // Now get the available client certs whose issuers are allowed by the server. |
1773 X509Certificate::GetSSLClientCertificates(that->hostname_, | 1902 X509Certificate::GetSSLClientCertificates(that->hostname_, |
1774 valid_issuers, | 1903 valid_issuers, |
1775 &that->client_certs_); | 1904 &that->client_certs_); |
1776 | 1905 |
1777 // Tell NSS to suspend the client authentication. We will then abort the | 1906 // Tell NSS to suspend the client authentication. We will then abort the |
1778 // handshake by returning ERR_SSL_CLIENT_AUTH_CERT_NEEDED. | 1907 // handshake by returning ERR_SSL_CLIENT_AUTH_CERT_NEEDED. |
1779 return SECWouldBlock; | 1908 return SECWouldBlock; |
1780 #else | 1909 #else |
| 1910 return SECFailure; |
| 1911 #endif |
| 1912 } |
| 1913 |
| 1914 #else // NSS_PLATFORM_CLIENT_AUTH |
| 1915 |
| 1916 // static |
| 1917 // NSS calls this if a client certificate is needed. |
| 1918 // Based on Mozilla's NSS_GetClientAuthData. |
| 1919 SECStatus SSLClientSocketNSS::ClientAuthHandler( |
| 1920 void* arg, |
| 1921 PRFileDesc* socket, |
| 1922 CERTDistNames* ca_names, |
| 1923 CERTCertificate** result_certificate, |
| 1924 SECKEYPrivateKey** result_private_key) { |
| 1925 SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg); |
| 1926 |
| 1927 that->client_auth_cert_needed_ = !that->ssl_config_.send_client_cert; |
1781 void* wincx = SSL_RevealPinArg(socket); | 1928 void* wincx = SSL_RevealPinArg(socket); |
1782 | 1929 |
1783 // Second pass: a client certificate should have been selected. | 1930 // Second pass: a client certificate should have been selected. |
1784 if (that->ssl_config_.send_client_cert) { | 1931 if (that->ssl_config_.send_client_cert) { |
1785 if (that->ssl_config_.client_cert) { | 1932 if (that->ssl_config_.client_cert) { |
1786 CERTCertificate* cert = CERT_DupCertificate( | 1933 CERTCertificate* cert = CERT_DupCertificate( |
1787 that->ssl_config_.client_cert->os_cert_handle()); | 1934 that->ssl_config_.client_cert->os_cert_handle()); |
1788 SECKEYPrivateKey* privkey = PK11_FindKeyByAnyCert(cert, wincx); | 1935 SECKEYPrivateKey* privkey = PK11_FindKeyByAnyCert(cert, wincx); |
1789 if (privkey) { | 1936 if (privkey) { |
1790 // TODO(jsorianopastor): We should wait for server certificate | 1937 // TODO(jsorianopastor): We should wait for server certificate |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1824 node->cert, X509Certificate::SOURCE_LONE_CERT_IMPORT, | 1971 node->cert, X509Certificate::SOURCE_LONE_CERT_IMPORT, |
1825 net::X509Certificate::OSCertHandles()); | 1972 net::X509Certificate::OSCertHandles()); |
1826 that->client_certs_.push_back(x509_cert); | 1973 that->client_certs_.push_back(x509_cert); |
1827 } | 1974 } |
1828 CERT_DestroyCertList(client_certs); | 1975 CERT_DestroyCertList(client_certs); |
1829 } | 1976 } |
1830 | 1977 |
1831 // Tell NSS to suspend the client authentication. We will then abort the | 1978 // Tell NSS to suspend the client authentication. We will then abort the |
1832 // handshake by returning ERR_SSL_CLIENT_AUTH_CERT_NEEDED. | 1979 // handshake by returning ERR_SSL_CLIENT_AUTH_CERT_NEEDED. |
1833 return SECWouldBlock; | 1980 return SECWouldBlock; |
1834 #endif | |
1835 } | 1981 } |
| 1982 #endif // NSS_PLATFORM_CLIENT_AUTH |
1836 | 1983 |
1837 // static | 1984 // static |
1838 // NSS calls this when handshake is completed. | 1985 // NSS calls this when handshake is completed. |
1839 // After the SSL handshake is finished, use CertVerifier to verify | 1986 // After the SSL handshake is finished, use CertVerifier to verify |
1840 // the saved server certificate. | 1987 // the saved server certificate. |
1841 void SSLClientSocketNSS::HandshakeCallback(PRFileDesc* socket, | 1988 void SSLClientSocketNSS::HandshakeCallback(PRFileDesc* socket, |
1842 void* arg) { | 1989 void* arg) { |
1843 SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg); | 1990 SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg); |
1844 | 1991 |
1845 that->handshake_callback_called_ = true; | 1992 that->handshake_callback_called_ = true; |
(...skipping 565 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2411 case SSL_CONNECTION_VERSION_TLS1_1: | 2558 case SSL_CONNECTION_VERSION_TLS1_1: |
2412 UpdateConnectionTypeHistograms(CONNECTION_SSL_TLS1_1); | 2559 UpdateConnectionTypeHistograms(CONNECTION_SSL_TLS1_1); |
2413 break; | 2560 break; |
2414 case SSL_CONNECTION_VERSION_TLS1_2: | 2561 case SSL_CONNECTION_VERSION_TLS1_2: |
2415 UpdateConnectionTypeHistograms(CONNECTION_SSL_TLS1_2); | 2562 UpdateConnectionTypeHistograms(CONNECTION_SSL_TLS1_2); |
2416 break; | 2563 break; |
2417 }; | 2564 }; |
2418 } | 2565 } |
2419 | 2566 |
2420 } // namespace net | 2567 } // namespace net |
OLD | NEW |