1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/chromeos/net/client_cert_store_chromeos.h"
10 #include "base/bind.h"
11 #include "base/bind_helpers.h"
12 #include "base/callback.h"
13 #include "base/location.h"
14 #include "base/threading/worker_pool.h"
15 #include "chrome/browser/chromeos/certificate_provider/certificate_provider.h"
16 #include "crypto/nss_crypto_module_delegate.h"
17 #include "net/ssl/ssl_cert_request_info.h"
23 class CertNotAllowedPredicate
{
25 explicit CertNotAllowedPredicate(
26 const ClientCertStoreChromeOS::CertFilter
* filter
)
28 bool operator()(const scoped_refptr
<net::X509Certificate
>& cert
) const {
29 return !filter_
->IsCertAllowed(cert
);
33 const ClientCertStoreChromeOS::CertFilter
* const filter_
;
38 ClientCertStoreChromeOS::ClientCertStoreChromeOS(
39 scoped_ptr
<CertificateProvider
> cert_provider
,
40 scoped_ptr
<CertFilter
> cert_filter
,
41 const PasswordDelegateFactory
& password_delegate_factory
)
42 : cert_provider_(cert_provider
.Pass()), cert_filter_(cert_filter
.Pass()) {}
44 ClientCertStoreChromeOS::~ClientCertStoreChromeOS() {}
46 void ClientCertStoreChromeOS::GetClientCerts(
47 const net::SSLCertRequestInfo
& cert_request_info
,
48 net::CertificateList
* selected_certs
,
49 const base::Closure
& callback
) {
50 // Caller is responsible for keeping the ClientCertStore alive until the
52 base::Callback
<void(const net::CertificateList
&)>
53 get_platform_certs_and_filter
= base::Bind(
54 &ClientCertStoreChromeOS::GotAdditionalCerts
, base::Unretained(this),
55 &cert_request_info
, selected_certs
, callback
);
57 base::Closure get_additional_certs_and_continue
;
59 get_additional_certs_and_continue
= base::Bind(
60 &CertificateProvider::GetCertificates
,
61 base::Unretained(cert_provider_
.get()), get_platform_certs_and_filter
);
63 get_additional_certs_and_continue
=
64 base::Bind(get_platform_certs_and_filter
, net::CertificateList());
67 if (cert_filter_
->Init(get_additional_certs_and_continue
))
68 get_additional_certs_and_continue
.Run();
71 void ClientCertStoreChromeOS::GotAdditionalCerts(
72 const net::SSLCertRequestInfo
* request
,
73 net::CertificateList
* selected_certs
,
74 const base::Closure
& callback
,
75 const net::CertificateList
& additional_certs
) {
76 scoped_ptr
<crypto::CryptoModuleBlockingPasswordDelegate
> password_delegate
;
77 if (!password_delegate_factory_
.is_null()) {
78 password_delegate
.reset(
79 password_delegate_factory_
.Run(request
->host_and_port
));
81 if (base::WorkerPool::PostTaskAndReply(
83 base::Bind(&ClientCertStoreChromeOS::GetAndFilterCertsOnWorkerThread
,
84 base::Unretained(this), base::Passed(&password_delegate
),
85 request
, additional_certs
, selected_certs
),
89 // If the task could not be posted, behave as if there were no certificates
90 // which requires to clear |selected_certs|.
91 selected_certs
->clear();
95 void ClientCertStoreChromeOS::GetAndFilterCertsOnWorkerThread(
96 scoped_ptr
<crypto::CryptoModuleBlockingPasswordDelegate
> password_delegate
,
97 const net::SSLCertRequestInfo
* request
,
98 const net::CertificateList
& additional_certs
,
99 net::CertificateList
* selected_certs
) {
100 net::CertificateList unfiltered_certs
;
101 net::ClientCertStoreNSS::GetPlatformCertsOnWorkerThread(
102 password_delegate
.Pass(), &unfiltered_certs
);
104 unfiltered_certs
.erase(
105 std::remove_if(unfiltered_certs
.begin(), unfiltered_certs
.end(),
106 CertNotAllowedPredicate(cert_filter_
.get())),
107 unfiltered_certs
.end());
109 unfiltered_certs
.insert(unfiltered_certs
.end(), additional_certs
.begin(),
110 additional_certs
.end());
112 net::ClientCertStoreNSS::FilterCertsOnWorkerThread(unfiltered_certs
, *request
,
113 true, selected_certs
);
116 } // namespace chromeos