File: certificate_manager_model.h

package info (click to toggle)
chromium 120.0.6099.224-1~deb11u1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 6,112,112 kB
  • sloc: cpp: 32,907,025; ansic: 8,148,123; javascript: 3,679,536; python: 2,031,248; asm: 959,718; java: 804,675; xml: 617,256; sh: 111,417; objc: 100,835; perl: 88,443; cs: 53,032; makefile: 29,579; fortran: 24,137; php: 21,162; tcl: 21,147; sql: 20,809; ruby: 17,735; pascal: 12,864; yacc: 8,045; lisp: 3,388; lex: 1,323; ada: 727; awk: 329; jsp: 267; csh: 117; exp: 43; sed: 37
file content (288 lines) | stat: -rw-r--r-- 10,971 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
// Copyright 2012 The Chromium Authors
// 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/functional/callback.h"
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "build/chromeos_buildflags.h"
#include "chrome/browser/net/nss_service.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;
}  // namespace content

#if BUILDFLAG(IS_CHROMEOS)
namespace ash {
class PolicyCertificateProvider;
}

namespace chromeos {
class CertificateProvider;
}
#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,
             std::u16string name,
             bool can_be_deleted,
             bool untrusted,
             Source source,
             bool web_trust_anchor,
             bool hardware_backed,
             bool device_wide);

    CertInfo(const CertInfo&) = delete;
    CertInfo& operator=(const CertInfo&) = delete;

    ~CertInfo();

    CERTCertificate* cert() const { return cert_.get(); }
    net::CertType type() const { return type_; }
    const std::u16string& name() const { return name_; }
    bool can_be_deleted() const { return can_be_deleted_; }
    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.
    std::u16string name_;

    // false if the certificate is stored on a read-only slot or provided by
    // enterprise policy or an extension, otherwise true.
    bool can_be_deleted_;

    // 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_;

    FRIEND_TEST_ALL_PREFIXES(CertificateHandlerTest,
                             CanDeleteCertificateCommonTest);
    FRIEND_TEST_ALL_PREFIXES(CertificateHandlerTest,
                             CanDeleteUserCertificateTest);
    FRIEND_TEST_ALL_PREFIXES(CertificateHandlerTest,
                             CanDeleteCACertificateTest);
    FRIEND_TEST_ALL_PREFIXES(CertificateHandlerTest,
                             CanEditCertificateCommonTest);
    FRIEND_TEST_ALL_PREFIXES(CertificateHandlerTest,
                             CanEditUserCertificateTest);
    FRIEND_TEST_ALL_PREFIXES(CertificateHandlerTest, CanEditCACertificateTest);
  };

  class CertsSource;

  // Holds parameters during construction.
  struct Params {
#if BUILDFLAG(IS_CHROMEOS)
    // May be nullptr.
    raw_ptr<ash::PolicyCertificateProvider> policy_certs_provider = nullptr;
    // May be nullptr.
    std::unique_ptr<chromeos::CertificateProvider>
        extension_certificate_provider;
#endif

    Params();

    Params(const Params&) = delete;
    Params& operator=(const Params&) = delete;

    Params(Params&& other);

    ~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.
  using OrgGroupingMap =
      std::map<std::string, std::vector<std::unique_ptr<CertInfo>>>;

  using CreationCallback =
      base::OnceCallback<void(std::unique_ptr<CertificateManagerModel>)>;

  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,
                     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);

  CertificateManagerModel(const CertificateManagerModel&) = delete;
  CertificateManagerModel& operator=(const CertificateManagerModel&) = delete;

  ~CertificateManagerModel();

  // 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 std::u16string& 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);

  // Remove the cert from the cert database.
  void RemoveFromDatabase(net::ScopedCERTCertificate cert,
                          base::OnceCallback<void(bool /*success*/)> callback);

 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,
      CreationCallback callback,
      net::NSSCertDatabase* cert_db);
  static void DidGetCertDBOnIOThread(
      std::unique_ptr<Params> params,
      CertificateManagerModel::Observer* observer,
      CreationCallback callback,
      net::NSSCertDatabase* cert_db);
  static void GetCertDBOnIOThread(std::unique_ptr<Params> params,
                                  NssCertDatabaseGetter database_getter,
                                  CertificateManagerModel::Observer* observer,
                                  CreationCallback callback);

  raw_ptr<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;

  // The observer to notify when certificate list is refreshed.
  raw_ptr<Observer> observer_;
};

#endif  // CHROME_BROWSER_CERTIFICATE_MANAGER_MODEL_H_