blob: cc6e9bf876a336535122a28d5615c0f858ed3163 [file] [log] [blame]
// Copyright 2020 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.
#ifndef CHROME_BROWSER_ASH_ARC_ENTERPRISE_CERT_STORE_CERT_STORE_SERVICE_H_
#define CHROME_BROWSER_ASH_ARC_ENTERPRISE_CERT_STORE_CERT_STORE_SERVICE_H_
#include <map>
#include <memory>
#include <set>
#include <string>
#include <vector>
#include "base/containers/queue.h"
#include "base/memory/weak_ptr.h"
#include "chrome/browser/ash/arc/enterprise/cert_store/arc_cert_installer.h"
#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
#include "components/keyed_service/core/keyed_service.h"
#include "content/public/browser/browser_context.h"
#include "net/cert/cert_database.h"
#include "net/cert/nss_cert_database.h"
#include "net/cert/scoped_nss_types.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
namespace arc {
// This service makes corporate usage keys available to ARC apps.
class CertStoreService : public KeyedService,
public net::CertDatabase::Observer {
public:
struct KeyInfo {
std::string nickname;
std::string id;
};
// Returns singleton instance for the given BrowserContext,
// or nullptr if the browser |context| is not allowed to use ARC.
static CertStoreService* GetForBrowserContext(
content::BrowserContext* context);
// Return the factory instance for this class.
static BrowserContextKeyedServiceFactory* GetFactory();
explicit CertStoreService(content::BrowserContext* context);
// This constructor is public only for testing.
CertStoreService(content::BrowserContext* context,
std::unique_ptr<ArcCertInstaller> installer);
~CertStoreService() override;
CertStoreService(const CertStoreService&) = delete;
CertStoreService& operator=(const CertStoreService&) = delete;
// CertDatabase::Observer overrides.
void OnCertDBChanged() override;
// Returns a real nickname and chaps id for a dummy SPKI |dummy_spki|.
// Returns nullopt if the key is unknown.
absl::optional<KeyInfo> GetKeyInfoForDummySpki(const std::string& dummy_spki);
std::vector<std::string> get_required_cert_names() const {
return certificate_cache_.get_required_cert_names();
}
void set_required_cert_names_for_testing(
const std::vector<std::string>& cert_names) {
certificate_cache_.set_required_cert_names_for_testing(
std::set<std::string>(cert_names.begin(), cert_names.end()));
}
private:
using FilterAllowedCertificatesCallback =
base::OnceCallback<void(net::ScopedCERTCertificateList allowed_certs)>;
// TODO(b/177051802) Some of certificate cache is obsolete. Clean up.
class CertificateCache {
public:
CertificateCache();
CertificateCache(const CertificateCache& other) = delete;
CertificateCache& operator=(const CertificateCache&) = delete;
~CertificateCache();
void Update(const std::vector<CertDescription>& certificates);
void Update(std::map<std::string, std::string> dummy_spki_by_name);
absl::optional<KeyInfo> GetKeyInfoForDummySpki(
const std::string& dummy_spki);
bool need_policy_update() { return need_policy_update_; }
void clear_need_policy_update() { need_policy_update_ = false; }
std::vector<std::string> get_required_cert_names() const {
return std::vector<std::string>(required_cert_names_.begin(),
required_cert_names_.end());
}
void set_required_cert_names_for_testing(std::set<std::string> cert_names) {
required_cert_names_ = std::move(cert_names);
}
private:
bool need_policy_update_ = false;
std::set<std::string> required_cert_names_;
// Map dummy SPKI to real key info.
std::map<std::string, KeyInfo> key_info_by_dummy_spki_cache_;
// Map cert name to dummy SPKI.
std::map<std::string, std::string> dummy_spki_by_name_cache_;
// Intermediate map name to real SPKI.
std::map<std::string, KeyInfo> key_info_by_name_cache_;
};
void UpdateCertificates();
void FilterAllowedCertificatesRecursively(
FilterAllowedCertificatesCallback callback,
base::queue<net::ScopedCERTCertificate> cert_queue,
net::ScopedCERTCertificateList allowed_certs) const;
void FilterAllowedCertificateAndRecurse(
FilterAllowedCertificatesCallback callback,
base::queue<net::ScopedCERTCertificate> cert_queue,
net::ScopedCERTCertificateList allowed_certs,
net::ScopedCERTCertificate cert,
bool certificate_allowed) const;
void OnGetNSSCertDatabaseForProfile(net::NSSCertDatabase* database);
void OnCertificatesListed(net::ScopedCERTCertificateList cert_list);
void OnFilteredAllowedCertificates(
net::ScopedCERTCertificateList allowed_certs);
void OnUpdatedKeymasterKeys(std::vector<CertDescription> certificates,
bool success);
void OnArcCertsInstalled(bool success);
content::BrowserContext* const context_;
std::unique_ptr<ArcCertInstaller> installer_;
CertificateCache certificate_cache_;
base::WeakPtrFactory<CertStoreService> weak_ptr_factory_{this};
};
} // namespace arc
#endif // CHROME_BROWSER_ASH_ARC_ENTERPRISE_CERT_STORE_CERT_STORE_SERVICE_H_