blob: bf59d114f1376dca0b1e2e88964ab1f970c6bd4d [file] [log] [blame]
// 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.
#ifndef CHROME_BROWSER_CERTIFICATE_MANAGER_MODEL_H_
#define CHROME_BROWSER_CERTIFICATE_MANAGER_MODEL_H_
#include <map>
#include <memory>
#include <string>
#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/strings/string16.h"
#include "net/cert/nss_cert_database.h"
#include "net/cert/scoped_nss_types.h"
#include "net/ssl/client_cert_identity.h"
namespace content {
class BrowserContext;
class ResourceContext;
} // namespace content
#if defined(OS_CHROMEOS)
namespace chromeos {
class CertificateProvider;
class PolicyCertificateProvider;
}
#endif
// CertificateManagerModel provides the data to be displayed in the certificate
// manager dialog, and processes changes from the view.
class CertificateManagerModel {
public:
// Holds information about a certificate, along with the certificate itself.
class CertInfo {
public:
enum class Source {
// This certificate is installed in the platform certificate database.
kPlatform,
// This certificate is provided by enterprise policy.
kPolicy,
// This certificate is provided by an extension.
kExtension
};
CertInfo(net::ScopedCERTCertificate cert,
net::CertType type,
base::string16 name,
bool read_only,
bool untrusted,
Source source,
bool web_trust_anchor,
bool hardware_backed,
bool device_wide);
~CertInfo();
CERTCertificate* cert() const { return cert_.get(); }
net::CertType type() const { return type_; }
const base::string16& name() const { return name_; }
bool read_only() const { return read_only_; }
bool untrusted() const { return untrusted_; }
Source source() const { return source_; }
bool web_trust_anchor() const { return web_trust_anchor_; }
bool hardware_backed() const { return hardware_backed_; }
bool device_wide() const { return device_wide_; }
// Clones a CertInfo, duplicating the contained NSS certificate.
static std::unique_ptr<CertInfo> Clone(const CertInfo* cert_info);
private:
// The certificate itself.
net::ScopedCERTCertificate cert_;
// The type of the certificate. Used to filter certificates to be displayed
// on the tabs of the certificate manager UI.
net::CertType type_;
// A user readable certificate name.
base::string16 name_;
// true if the certificate is stored on a read-only slot or provided by
// enterprise policy or an extension.
bool read_only_;
// true if the certificate is untrusted.
bool untrusted_;
// Describes where this certificate originates from.
Source source_;
// true if the certificate is given web trust (either by its platform trust
// settings, or by enterprise policy).
bool web_trust_anchor_;
// true if the certificate is hardware-backed. Note that extension-provided
// certificates are not regarded as hardware-backed.
bool hardware_backed_;
// true if the certificate is device-wide.
// Note: can be true only on Chrome OS.
bool device_wide_;
DISALLOW_COPY_AND_ASSIGN(CertInfo);
};
class CertsSource;
// Holds parameters during construction.
struct Params {
#if defined(OS_CHROMEOS)
// May be nullptr.
chromeos::PolicyCertificateProvider* policy_certs_provider = nullptr;
// May be nullptr.
std::unique_ptr<chromeos::CertificateProvider>
extension_certificate_provider;
#endif
Params();
Params(Params&& other);
~Params();
private:
DISALLOW_COPY_AND_ASSIGN(Params);
};
// Map from the subject organization name to the list of certs from that
// organization. If a cert does not have an organization name, the
// subject's CertPrincipal::GetDisplayName() value is used instead.
typedef std::map<std::string, std::vector<std::unique_ptr<CertInfo>>>
OrgGroupingMap;
typedef base::Callback<void(std::unique_ptr<CertificateManagerModel>)>
CreationCallback;
class Observer {
public:
// Called to notify the view that the certificate list has been refreshed.
// TODO(mattm): do a more granular updating strategy? Maybe retrieve new
// list of certs, diff against past list, and then notify of the changes?
virtual void CertificatesRefreshed() = 0;
protected:
virtual ~Observer() = default;
};
// Creates a CertificateManagerModel. The model will be passed to the callback
// when it is ready. The caller must ensure the model does not outlive the
// |browser_context|.
static void Create(content::BrowserContext* browser_context,
Observer* observer,
const CreationCallback& callback);
// Use |Create| instead to create a |CertificateManagerModel| for a
// |BrowserContext|.
CertificateManagerModel(std::unique_ptr<Params> params,
Observer* observer,
net::NSSCertDatabase* nss_cert_database,
bool is_user_db_available,
bool is_tpm_available);
~CertificateManagerModel();
bool is_user_db_available() const { return is_user_db_available_; }
bool is_tpm_available() const { return is_tpm_available_; }
// Accessor for read-only access to the underlying NSSCertDatabase.
const net::NSSCertDatabase* cert_db() const { return cert_db_; }
// Trigger a refresh of the list of certs, unlock any slots if necessary.
// Following this call, the observer CertificatesRefreshed method will be
// called so the view can call FilterAndBuildOrgGroupingMap as necessary to
// refresh its tree views.
void Refresh();
// Fill |*out_org_grouping_map| with the certificates matching |filter_type|.
void FilterAndBuildOrgGroupingMap(net::CertType filter_type,
OrgGroupingMap* out_org_grouping_map) const;
// Import private keys and certificates from PKCS #12 encoded
// |data|, using the given |password|. If |is_extractable| is false,
// mark the private key as unextractable from the slot.
// Returns a net error code on failure.
int ImportFromPKCS12(PK11SlotInfo* slot_info, const std::string& data,
const base::string16& password, bool is_extractable);
// Import user certificate from DER encoded |data|.
// Returns a net error code on failure.
int ImportUserCert(const std::string& data);
// Import CA certificates.
// Tries to import all the certificates given. The root will be trusted
// according to |trust_bits|. Any certificates that could not be imported
// will be listed in |not_imported|.
// |trust_bits| should be a bit field of TRUST* values from NSSCertDatabase.
// Returns false if there is an internal error, otherwise true is returned and
// |not_imported| should be checked for any certificates that were not
// imported.
bool ImportCACerts(const net::ScopedCERTCertificateList& certificates,
net::NSSCertDatabase::TrustBits trust_bits,
net::NSSCertDatabase::ImportCertFailureList* not_imported);
// Import server certificate. The first cert should be the server cert. Any
// additional certs should be intermediate/CA certs and will be imported but
// not given any trust.
// Any certificates that could not be imported will be listed in
// |not_imported|.
// |trust_bits| can be set to explicitly trust or distrust the certificate, or
// use TRUST_DEFAULT to inherit trust as normal.
// Returns false if there is an internal error, otherwise true is returned and
// |not_imported| should be checked for any certificates that were not
// imported.
bool ImportServerCert(
const net::ScopedCERTCertificateList& certificates,
net::NSSCertDatabase::TrustBits trust_bits,
net::NSSCertDatabase::ImportCertFailureList* not_imported);
// Set trust values for certificate.
// |trust_bits| should be a bit field of TRUST* values from NSSCertDatabase.
// Returns true on success or false on failure.
bool SetCertTrust(CERTCertificate* cert,
net::CertType type,
net::NSSCertDatabase::TrustBits trust_bits);
// Delete the cert. Returns true on success. |cert| is still valid when this
// function returns.
bool Delete(CERTCertificate* cert);
private:
// Called when one of the |certs_sources_| has been updated. Will notify the
// |observer_| that the certificate list has been refreshed.
void OnCertsSourceUpdated();
// Finds the |CertsSource| which provided |cert|. Can return nullptr (e.g. if
// the cert has been deleted in the meantime).
CertsSource* FindCertsSourceForCert(CERTCertificate* cert);
// Methods used during initialization, see the comment at the top of the .cc
// file for details.
static void DidGetCertDBOnUIThread(
std::unique_ptr<Params> params,
CertificateManagerModel::Observer* observer,
const CreationCallback& callback,
net::NSSCertDatabase* cert_db,
bool is_user_db_available,
bool is_tpm_available);
static void DidGetCertDBOnIOThread(
std::unique_ptr<Params> params,
CertificateManagerModel::Observer* observer,
const CreationCallback& callback,
net::NSSCertDatabase* cert_db);
static void GetCertDBOnIOThread(std::unique_ptr<Params> params,
content::ResourceContext* resource_context,
CertificateManagerModel::Observer* observer,
const CreationCallback& callback);
net::NSSCertDatabase* cert_db_;
// CertsSource instances providing certificates. The order matters - if a
// certificate is provided by more than one CertsSource, only the first one is
// accepted.
std::vector<std::unique_ptr<CertsSource>> certs_sources_;
bool hold_back_updates_ = false;
// Whether the certificate database has a public slot associated with the
// profile. If not set, importing certificates is not allowed with this model.
bool is_user_db_available_;
bool is_tpm_available_;
// The observer to notify when certificate list is refreshed.
Observer* observer_;
DISALLOW_COPY_AND_ASSIGN(CertificateManagerModel);
};
#endif // CHROME_BROWSER_CERTIFICATE_MANAGER_MODEL_H_