Index: net/base/client_cert_store_impl_win.cc |
diff --git a/net/base/client_cert_store_impl_win.cc b/net/base/client_cert_store_impl_win.cc |
deleted file mode 100644 |
index 9098076d0b4021c5da70f05af18f10c77eacd3dd..0000000000000000000000000000000000000000 |
--- a/net/base/client_cert_store_impl_win.cc |
+++ /dev/null |
@@ -1,204 +0,0 @@ |
-// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "net/base/client_cert_store_impl.h" |
- |
-#include <algorithm> |
-#include <string> |
- |
-#define SECURITY_WIN32 // Needs to be defined before including security.h |
-#include <windows.h> |
-#include <wincrypt.h> |
-#include <security.h> |
- |
-#include "base/logging.h" |
-#include "crypto/scoped_capi_types.h" |
-#include "net/base/x509_util.h" |
- |
-namespace net { |
- |
-namespace { |
- |
-// Callback required by Windows API function CertFindChainInStore(). In addition |
-// to filtering by extended/enhanced key usage, we do not show expired |
-// certificates and require digital signature usage in the key usage extension. |
-// |
-// This matches our behavior on Mac OS X and that of NSS. It also matches the |
-// default behavior of IE8. See http://support.microsoft.com/kb/890326 and |
-// http://blogs.msdn.com/b/askie/archive/2009/06/09/my-expired-client-certifica |
-// tes-no-longer-display-when-connecting-to-my-web-server-using-ie8.aspx |
-static BOOL WINAPI ClientCertFindCallback(PCCERT_CONTEXT cert_context, |
- void* find_arg) { |
- // Verify the certificate key usage is appropriate or not specified. |
- BYTE key_usage; |
- if (CertGetIntendedKeyUsage(X509_ASN_ENCODING, cert_context->pCertInfo, |
- &key_usage, 1)) { |
- if (!(key_usage & CERT_DIGITAL_SIGNATURE_KEY_USAGE)) |
- return FALSE; |
- } else { |
- DWORD err = GetLastError(); |
- // If |err| is non-zero, it's an actual error. Otherwise the extension |
- // just isn't present, and we treat it as if everything was allowed. |
- if (err) { |
- DLOG(ERROR) << "CertGetIntendedKeyUsage failed: " << err; |
- return FALSE; |
- } |
- } |
- |
- // Verify the current time is within the certificate's validity period. |
- if (CertVerifyTimeValidity(NULL, cert_context->pCertInfo) != 0) |
- return FALSE; |
- |
- // Verify private key metadata is associated with this certificate. |
- // TODO(ppi): Is this really needed? Isn't it equivalent to leaving |
- // CERT_CHAIN_FIND_BY_ISSUER_NO_KEY_FLAG not set in |find_flags| argument of |
- // CertFindChainInStore()? |
- DWORD size = 0; |
- if (!CertGetCertificateContextProperty( |
- cert_context, CERT_KEY_PROV_INFO_PROP_ID, NULL, &size)) { |
- return FALSE; |
- } |
- |
- return TRUE; |
-} |
- |
-bool GetClientCertsImpl(HCERTSTORE cert_store, |
- const SSLCertRequestInfo& request, |
- CertificateList* selected_certs) { |
- selected_certs->clear(); |
- |
- const size_t auth_count = request.cert_authorities.size(); |
- std::vector<CERT_NAME_BLOB> issuers(auth_count); |
- for (size_t i = 0; i < auth_count; ++i) { |
- issuers[i].cbData = static_cast<DWORD>(request.cert_authorities[i].size()); |
- issuers[i].pbData = reinterpret_cast<BYTE*>( |
- const_cast<char*>(request.cert_authorities[i].data())); |
- } |
- |
- // Enumerate the client certificates. |
- CERT_CHAIN_FIND_BY_ISSUER_PARA find_by_issuer_para; |
- memset(&find_by_issuer_para, 0, sizeof(find_by_issuer_para)); |
- find_by_issuer_para.cbSize = sizeof(find_by_issuer_para); |
- find_by_issuer_para.pszUsageIdentifier = szOID_PKIX_KP_CLIENT_AUTH; |
- find_by_issuer_para.cIssuer = static_cast<DWORD>(auth_count); |
- find_by_issuer_para.rgIssuer = |
- reinterpret_cast<CERT_NAME_BLOB*>(issuers.data()); |
- find_by_issuer_para.pfnFindCallback = ClientCertFindCallback; |
- |
- PCCERT_CHAIN_CONTEXT chain_context = NULL; |
- DWORD find_flags = CERT_CHAIN_FIND_BY_ISSUER_CACHE_ONLY_FLAG | |
- CERT_CHAIN_FIND_BY_ISSUER_CACHE_ONLY_URL_FLAG; |
- for (;;) { |
- // Find a certificate chain. |
- chain_context = CertFindChainInStore(cert_store, |
- X509_ASN_ENCODING, |
- find_flags, |
- CERT_CHAIN_FIND_BY_ISSUER, |
- &find_by_issuer_para, |
- chain_context); |
- if (!chain_context) { |
- if (GetLastError() != CRYPT_E_NOT_FOUND) |
- DPLOG(ERROR) << "CertFindChainInStore failed: "; |
- break; |
- } |
- |
- // Get the leaf certificate. |
- PCCERT_CONTEXT cert_context = |
- chain_context->rgpChain[0]->rgpElement[0]->pCertContext; |
- // Copy the certificate, so that it is valid after |cert_store| is closed. |
- PCCERT_CONTEXT cert_context2 = NULL; |
- BOOL ok = CertAddCertificateContextToStore(NULL, cert_context, |
- CERT_STORE_ADD_USE_EXISTING, |
- &cert_context2); |
- if (!ok) { |
- NOTREACHED(); |
- continue; |
- } |
- |
- // Grab the intermediates, if any. |
- X509Certificate::OSCertHandles intermediates; |
- for (DWORD i = 1; i < chain_context->rgpChain[0]->cElement; ++i) { |
- PCCERT_CONTEXT chain_intermediate = |
- chain_context->rgpChain[0]->rgpElement[i]->pCertContext; |
- PCCERT_CONTEXT copied_intermediate = NULL; |
- ok = CertAddCertificateContextToStore(NULL, chain_intermediate, |
- CERT_STORE_ADD_USE_EXISTING, |
- &copied_intermediate); |
- if (ok) |
- intermediates.push_back(copied_intermediate); |
- } |
- scoped_refptr<X509Certificate> cert = X509Certificate::CreateFromHandle( |
- cert_context2, intermediates); |
- selected_certs->push_back(cert); |
- CertFreeCertificateContext(cert_context2); |
- for (size_t i = 0; i < intermediates.size(); ++i) |
- CertFreeCertificateContext(intermediates[i]); |
- } |
- |
- std::sort(selected_certs->begin(), selected_certs->end(), |
- x509_util::ClientCertSorter()); |
- return true; |
-} |
- |
-} // namespace |
- |
-bool ClientCertStoreImpl::GetClientCerts(const SSLCertRequestInfo& request, |
- CertificateList* selected_certs) { |
- // Client certificates of the user are in the "MY" system certificate store. |
- HCERTSTORE my_cert_store = CertOpenSystemStore(NULL, L"MY"); |
- if (!my_cert_store) { |
- PLOG(ERROR) << "Could not open the \"MY\" system certificate store: "; |
- return false; |
- } |
- |
- bool rv = GetClientCertsImpl(my_cert_store, request, selected_certs); |
- if (!CertCloseStore(my_cert_store, CERT_CLOSE_STORE_CHECK_FLAG)) { |
- PLOG(ERROR) << "Could not close the \"MY\" system certificate store: "; |
- return false; |
- } |
- return rv; |
-} |
- |
-bool ClientCertStoreImpl::SelectClientCerts(const CertificateList& input_certs, |
- const SSLCertRequestInfo& request, |
- CertificateList* selected_certs) { |
- typedef crypto::ScopedCAPIHandle< |
- HCERTSTORE, |
- crypto::CAPIDestroyerWithFlags<HCERTSTORE, |
- CertCloseStore, 0> > ScopedHCERTSTORE; |
- |
- ScopedHCERTSTORE test_store(CertOpenStore(CERT_STORE_PROV_MEMORY, 0, NULL, 0, |
- NULL)); |
- if (!test_store) |
- return false; |
- |
- // Add available certificates to the test store. |
- for (size_t i = 0; i < input_certs.size(); ++i) { |
- // Add the certificate to the test store. |
- PCCERT_CONTEXT cert = NULL; |
- if (!CertAddCertificateContextToStore(test_store, |
- input_certs[i]->os_cert_handle(), |
- CERT_STORE_ADD_NEW, &cert)) { |
- return false; |
- } |
- // Add dummy private key data to the certificate - otherwise the certificate |
- // would be discarded by the filtering routines. |
- CRYPT_KEY_PROV_INFO private_key_data; |
- memset(&private_key_data, 0, sizeof(private_key_data)); |
- if (!CertSetCertificateContextProperty(cert, |
- CERT_KEY_PROV_INFO_PROP_ID, |
- 0, &private_key_data)) { |
- return false; |
- } |
- // Decrement the reference count of the certificate (since we requested a |
- // copy). |
- if (!CertFreeCertificateContext(cert)) |
- return false; |
- } |
- |
- bool rv = GetClientCertsImpl(test_store.get(), request, selected_certs); |
- return rv; |
-} |
- |
-} // namespace net |