1 // Copyright 2019 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.
4 
5 #include "chrome/browser/chromeos/arc/enterprise/cert_store/arc_smart_card_manager_bridge.h"
6 
7 #include <algorithm>
8 #include <iterator>
9 #include <utility>
10 
11 #include "base/bind.h"
12 #include "base/callback.h"
13 #include "base/logging.h"
14 #include "base/memory/singleton.h"
15 #include "chrome/browser/chromeos/arc/policy/arc_policy_bridge.h"
16 #include "chrome/browser/chromeos/certificate_provider/certificate_provider_service.h"
17 #include "chrome/browser/chromeos/certificate_provider/certificate_provider_service_factory.h"
18 #include "chrome/browser/chromeos/platform_keys/platform_keys.h"
19 #include "chrome/common/net/x509_certificate_model_nss.h"
20 #include "components/arc/arc_browser_context_keyed_service_factory_base.h"
21 #include "components/policy/core/common/policy_map.h"
22 #include "components/policy/core/common/policy_namespace.h"
23 #include "crypto/rsa_private_key.h"
24 #include "net/cert/x509_util_nss.h"
25 
26 namespace arc {
27 
28 namespace {
29 
30 // Singleton factory for ArcSmartCardManagerBridge.
31 class ArcSmartCardManagerBridgeFactory
32     : public internal::ArcBrowserContextKeyedServiceFactoryBase<
33           ArcSmartCardManagerBridge,
34           ArcSmartCardManagerBridgeFactory> {
35  public:
36   // Factory name used by ArcBrowserContextKeyedServiceFactoryBase.
37   static constexpr const char* kName = "ArcSmartCardManagerBridgeFactory";
38 
GetInstance()39   static ArcSmartCardManagerBridgeFactory* GetInstance() {
40     return base::Singleton<ArcSmartCardManagerBridgeFactory>::get();
41   }
42 
43  private:
44   friend base::DefaultSingletonTraits<ArcSmartCardManagerBridgeFactory>;
ArcSmartCardManagerBridgeFactory()45   ArcSmartCardManagerBridgeFactory() {
46     DependsOn(chromeos::CertificateProviderServiceFactory::GetInstance());
47   }
48 
49   ~ArcSmartCardManagerBridgeFactory() override = default;
50 };
51 
52 }  // namespace
53 
54 // static
GetForBrowserContext(content::BrowserContext * context)55 ArcSmartCardManagerBridge* ArcSmartCardManagerBridge::GetForBrowserContext(
56     content::BrowserContext* context) {
57   return ArcSmartCardManagerBridgeFactory::GetForBrowserContext(context);
58 }
59 
60 // static
GetFactory()61 BrowserContextKeyedServiceFactory* ArcSmartCardManagerBridge::GetFactory() {
62   return ArcSmartCardManagerBridgeFactory::GetInstance();
63 }
64 
ArcSmartCardManagerBridge(content::BrowserContext * context,ArcBridgeService * bridge_service)65 ArcSmartCardManagerBridge::ArcSmartCardManagerBridge(
66     content::BrowserContext* context,
67     ArcBridgeService* bridge_service)
68     : ArcSmartCardManagerBridge(
69           context,
70           bridge_service,
71           chromeos::CertificateProviderServiceFactory::GetForBrowserContext(
72               context)
73               ->CreateCertificateProvider(),
74           std::make_unique<ArcCertInstaller>(context)) {}
75 
ArcSmartCardManagerBridge(content::BrowserContext * context,ArcBridgeService * bridge_service,std::unique_ptr<chromeos::CertificateProvider> certificate_provider,std::unique_ptr<ArcCertInstaller> installer)76 ArcSmartCardManagerBridge::ArcSmartCardManagerBridge(
77     content::BrowserContext* context,
78     ArcBridgeService* bridge_service,
79     std::unique_ptr<chromeos::CertificateProvider> certificate_provider,
80     std::unique_ptr<ArcCertInstaller> installer)
81     : context_(context),
82       arc_bridge_service_(bridge_service),
83       certificate_provider_(std::move(certificate_provider)),
84       installer_(std::move(installer)),
85       weak_ptr_factory_(this) {
86   VLOG(1) << "ArcSmartCardManagerBridge::ArcSmartCardManagerBridge";
87   arc_bridge_service_->smart_card_manager()->SetHost(this);
88 }
89 
~ArcSmartCardManagerBridge()90 ArcSmartCardManagerBridge::~ArcSmartCardManagerBridge() {
91   VLOG(1) << "ArcSmartCardManagerBridge::~ArcSmartCardManagerBridge";
92 
93   arc_bridge_service_->smart_card_manager()->SetHost(nullptr);
94 }
95 
Refresh(RefreshCallback callback)96 void ArcSmartCardManagerBridge::Refresh(RefreshCallback callback) {
97   VLOG(1) << "ArcSmartCardManagerBridge::Refresh";
98 
99   certificate_provider_->GetCertificates(
100       base::BindOnce(&ArcSmartCardManagerBridge::DidGetCerts,
101                      weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
102 }
103 
GetRealSpkiForDummySpki(const std::string & dummy_spki)104 std::string ArcSmartCardManagerBridge::GetRealSpkiForDummySpki(
105     const std::string& dummy_spki) {
106   return certificate_cache_.GetRealSpkiForDummySpki(dummy_spki);
107 }
108 
109 ArcSmartCardManagerBridge::CertificateCache::CertificateCache() = default;
110 ArcSmartCardManagerBridge::CertificateCache::~CertificateCache() = default;
111 
DidGetCerts(RefreshCallback callback,net::ClientCertIdentityList cert_identities)112 void ArcSmartCardManagerBridge::DidGetCerts(
113     RefreshCallback callback,
114     net::ClientCertIdentityList cert_identities) {
115   VLOG(1) << "ArcSmartCardManagerBridge::DidGetCerts";
116 
117   certificate_cache_.clear_need_policy_update();
118   std::vector<net::ScopedCERTCertificate> certificates =
119       certificate_cache_.Update(std::move(cert_identities));
120 
121   // Maps cert name to dummy SPKI.
122   std::map<std::string, std::string> installed_keys =
123       installer_->InstallArcCerts(std::move(certificates), std::move(callback));
124 
125   certificate_cache_.Update(installed_keys);
126 
127   if (certificate_cache_.need_policy_update()) {
128     ArcPolicyBridge* const policy_bridge =
129         ArcPolicyBridge::GetForBrowserContext(context_);
130     if (policy_bridge) {
131       policy_bridge->OnPolicyUpdated(policy::PolicyNamespace(),
132                                      policy::PolicyMap(), policy::PolicyMap());
133     }
134   }
135 }
136 
137 std::vector<net::ScopedCERTCertificate>
Update(net::ClientCertIdentityList cert_identities)138 ArcSmartCardManagerBridge::CertificateCache::Update(
139     net::ClientCertIdentityList cert_identities) {
140   std::vector<net::ScopedCERTCertificate> certificates;
141   // Map cert name to real SPKI.
142   real_spki_by_name_cache_.clear();
143   std::set<std::string> new_required_cert_names;
144   for (const auto& identity : cert_identities) {
145     net::ScopedCERTCertificate nss_cert(
146         net::x509_util::CreateCERTCertificateFromX509Certificate(
147             identity->certificate()));
148     if (!nss_cert) {
149       LOG(ERROR) << "Certificate provider returned an invalid smart card "
150                  << "certificate.";
151       continue;
152     }
153     std::string cert_name =
154         x509_certificate_model::GetCertNameOrNickname(nss_cert.get());
155     real_spki_by_name_cache_[cert_name] =
156         chromeos::platform_keys::GetSubjectPublicKeyInfo(
157             identity->certificate());
158     new_required_cert_names.insert(cert_name);
159 
160     certificates.push_back(std::move(nss_cert));
161   }
162   need_policy_update_ = (required_cert_names_ != new_required_cert_names);
163   for (auto cert_name : required_cert_names_) {
164     if (!new_required_cert_names.count(cert_name)) {
165       real_spki_by_dummy_spki_cache_.erase(
166           dummy_spki_by_name_cache_[cert_name]);
167       dummy_spki_by_name_cache_.erase(cert_name);
168     }
169   }
170   required_cert_names_ = new_required_cert_names;
171   return certificates;
172 }
173 
Update(std::map<std::string,std::string> dummy_spki_by_name)174 void ArcSmartCardManagerBridge::CertificateCache::Update(
175     std::map<std::string, std::string> dummy_spki_by_name) {
176   if (required_cert_names_.size() != dummy_spki_by_name.size())
177     return;
178   for (const auto& cert : dummy_spki_by_name) {
179     const std::string& name = cert.first;
180     if (!required_cert_names_.count(name)) {
181       VLOG(1) << "ArcSmartCardManagerBridge::CertificateCache::Update error: "
182               << "An attempt to add a non-required key " << name;
183       continue;
184     }
185 
186     std::string dummy_spki = cert.second;
187     if (dummy_spki.empty() && dummy_spki_by_name_cache_.count(name))
188       dummy_spki = dummy_spki_by_name_cache_[name];
189     if (!dummy_spki.empty()) {
190       dummy_spki_by_name_cache_[name] = dummy_spki;
191       real_spki_by_dummy_spki_cache_[dummy_spki] =
192           real_spki_by_name_cache_[name];
193     }
194   }
195 }
196 
197 std::string
GetRealSpkiForDummySpki(const std::string & dummy_spki)198 ArcSmartCardManagerBridge::CertificateCache::GetRealSpkiForDummySpki(
199     const std::string& dummy_spki) {
200   if (real_spki_by_dummy_spki_cache_.count(dummy_spki))
201     return real_spki_by_dummy_spki_cache_[dummy_spki];
202   return "";
203 }
204 
205 }  // namespace arc
206