OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef CHROMEOS_CERT_LOADER_H_ | 5 #ifndef CHROMEOS_CERT_LOADER_H_ |
6 #define CHROMEOS_CERT_LOADER_H_ | 6 #define CHROMEOS_CERT_LOADER_H_ |
7 | 7 |
8 #include <string> | 8 #include <string> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
11 #include "base/compiler_specific.h" | 11 #include "base/compiler_specific.h" |
12 #include "base/macros.h" | 12 #include "base/macros.h" |
13 #include "base/memory/ref_counted.h" | 13 #include "base/memory/ref_counted.h" |
14 #include "base/memory/weak_ptr.h" | 14 #include "base/memory/weak_ptr.h" |
15 #include "base/observer_list.h" | 15 #include "base/observer_list.h" |
16 #include "base/threading/thread_checker.h" | 16 #include "base/threading/thread_checker.h" |
17 #include "chromeos/chromeos_export.h" | 17 #include "chromeos/chromeos_export.h" |
18 #include "net/cert/cert_database.h" | 18 #include "net/cert/x509_certificate.h" |
19 | 19 |
20 namespace net { | 20 namespace net { |
21 class NSSCertDatabase; | 21 class NSSCertDatabase; |
22 class X509Certificate; | |
23 typedef std::vector<scoped_refptr<X509Certificate> > CertificateList; | 22 typedef std::vector<scoped_refptr<X509Certificate> > CertificateList; |
24 } | 23 } |
25 | 24 |
26 namespace chromeos { | 25 namespace chromeos { |
27 | 26 |
28 // This class is responsible for loading certificates once the TPM is | 27 // This class is responsible for loading certificates once the TPM is |
29 // initialized. It is expected to be constructed on the UI thread and public | 28 // initialized. It is expected to be constructed on the UI thread and public |
30 // methods should all be called from the UI thread. | 29 // methods should all be called from the UI thread. |
31 // When certificates have been loaded (after login completes and tpm token is | 30 // When certificates have been loaded (after login completes and tpm token is |
32 // initialized), or the cert database changes, observers are called with | 31 // initialized), or the cert database changes, observers are called with |
33 // OnCertificatesLoaded(). | 32 // OnCertificatesLoaded(). |
34 class CHROMEOS_EXPORT CertLoader : public net::CertDatabase::Observer { | 33 // This class supports using one or two cert databases. The expected usage is |
| 34 // that CertLoader is used with a NSSCertDatabase backed by the system token |
| 35 // before user sign-in, and additionally with a user-specific NSSCertDatabase |
| 36 // after user sign-in. When both NSSCertDatabase are used, CertLoader combines |
| 37 // certificates from both into |all_certs()|. |
| 38 class CHROMEOS_EXPORT CertLoader { |
35 public: | 39 public: |
36 class Observer { | 40 class Observer { |
37 public: | 41 public: |
38 // Called when the certificates, passed for convenience as |all_certs|, | 42 // Called when the certificates, passed for convenience as |all_certs|, |
39 // have completed loading. |initial_load| is true the first time this | 43 // have completed loading. |initial_load| is true the first time this |
40 // is called. | 44 // is called. It will be false if this is called because another slot has |
| 45 // been added to CertLoader's data sources. |
41 virtual void OnCertificatesLoaded(const net::CertificateList& all_certs, | 46 virtual void OnCertificatesLoaded(const net::CertificateList& all_certs, |
42 bool initial_load) = 0; | 47 bool initial_load) = 0; |
43 | 48 |
44 protected: | 49 protected: |
45 virtual ~Observer() {} | 50 virtual ~Observer() {} |
46 }; | 51 }; |
47 | 52 |
48 // Sets the global instance. Must be called before any calls to Get(). | 53 // Sets the global instance. Must be called before any calls to Get(). |
49 static void Initialize(); | 54 static void Initialize(); |
50 | 55 |
51 // Destroys the global instance. | 56 // Destroys the global instance. |
52 static void Shutdown(); | 57 static void Shutdown(); |
53 | 58 |
54 // Gets the global instance. Initialize() must be called first. | 59 // Gets the global instance. Initialize() must be called first. |
55 static CertLoader* Get(); | 60 static CertLoader* Get(); |
56 | 61 |
57 // Returns true if the global instance has been initialized. | 62 // Returns true if the global instance has been initialized. |
58 static bool IsInitialized(); | 63 static bool IsInitialized(); |
59 | 64 |
60 // Returns the PKCS#11 attribute CKA_ID for a certificate as an upper-case | 65 // Returns the PKCS#11 attribute CKA_ID for a certificate as an upper-case |
61 // hex string and sets |slot_id| to the id of the containing slot, or returns | 66 // hex string and sets |slot_id| to the id of the containing slot, or returns |
62 // an empty string and doesn't modify |slot_id| if the PKCS#11 id could not be | 67 // an empty string and doesn't modify |slot_id| if the PKCS#11 id could not be |
63 // determined. | 68 // determined. |
64 static std::string GetPkcs11IdAndSlotForCert(const net::X509Certificate& cert, | 69 static std::string GetPkcs11IdAndSlotForCert(const net::X509Certificate& cert, |
65 int* slot_id); | 70 int* slot_id); |
66 | 71 |
67 // Starts the CertLoader with the NSS cert database. | 72 // Starts the CertLoader with the passed system NSS cert database. |
| 73 // The CertLoader will _not_ take ownership of the database - see comment on |
| 74 // SetUserNSSDB. |
| 75 // CertLoader supports working with only one database or with both (system and |
| 76 // user) databases. |
| 77 void SetSystemNSSDB(net::NSSCertDatabase* system_slot_database); |
| 78 |
| 79 // Starts the CertLoader with the passed user NSS cert database. |
68 // The CertLoader will _not_ take the ownership of the database, but it | 80 // The CertLoader will _not_ take the ownership of the database, but it |
69 // expects it to stay alive at least until the shutdown starts on the main | 81 // expects it to stay alive at least until the shutdown starts on the main |
70 // thread. This assumes that |StartWithNSSDB| and other methods directly | 82 // thread. This assumes that SetUserNSSDB and other methods directly |
71 // using |database_| are not called during shutdown. | 83 // using |database_| are not called during shutdown. |
72 void StartWithNSSDB(net::NSSCertDatabase* database); | 84 // CertLoader supports working with only one database or with both (system and |
| 85 // user) databases. |
| 86 void SetUserNSSDB(net::NSSCertDatabase* user_database); |
73 | 87 |
74 void AddObserver(CertLoader::Observer* observer); | 88 void AddObserver(CertLoader::Observer* observer); |
75 void RemoveObserver(CertLoader::Observer* observer); | 89 void RemoveObserver(CertLoader::Observer* observer); |
76 | 90 |
77 // Returns true if |cert| is hardware backed. See also | 91 // Returns true if |cert| is hardware backed. See also |
78 // ForceHardwareBackedForTesting(). | 92 // ForceHardwareBackedForTesting(). |
79 static bool IsCertificateHardwareBacked(const net::X509Certificate* cert); | 93 static bool IsCertificateHardwareBacked(const net::X509Certificate* cert); |
80 | 94 |
81 // Returns true when the certificate list has been requested but not loaded. | 95 // Returns true when the certificate list has been requested but not loaded. |
82 bool CertificatesLoading() const; | 96 // When two databases are in use (SetSystemNSSDB and SetUserNSSDB have both |
| 97 // been called), this returns true when at least one of them is currently |
| 98 // loading certificates. |
| 99 // Note that this method poses an exception in the CertLoader interface: |
| 100 // While most of CertLoader's interface treats the initial load of a second |
| 101 // database the same way as an update in the first database, this method does |
| 102 // not. The reason is that it's targeted at displaying a message in the GUI, |
| 103 // so the user knows that (more) certificates will be available soon. |
| 104 bool initial_load_of_any_database_running() const; |
83 | 105 |
84 bool certificates_loaded() const { return certificates_loaded_; } | 106 // Returns true if any certificates have been loaded. If CertLoader uses a |
| 107 // system and a user NSS database, this returns true after the certificates |
| 108 // from the first (usually system) database have been loaded. |
| 109 bool initial_load_finished() const; |
85 | 110 |
86 // Returns all certificates. This will be empty until certificates_loaded() is | 111 // Returns all certificates. This will be empty until certificates_loaded() is |
87 // true. | 112 // true. |
88 const net::CertificateList& all_certs() const { | 113 const net::CertificateList& all_certs() const { |
89 DCHECK(thread_checker_.CalledOnValidThread()); | 114 DCHECK(thread_checker_.CalledOnValidThread()); |
90 return *all_certs_; | 115 return all_certs_; |
91 } | 116 } |
92 | 117 |
93 // Returns certificates from the system token. This will be empty until | 118 // Returns certificates from the system token. This will be empty until |
94 // certificates_loaded() is true. | 119 // certificates_loaded() is true. |
95 const net::CertificateList& system_certs() const { | 120 const net::CertificateList& system_certs() const { |
96 DCHECK(thread_checker_.CalledOnValidThread()); | 121 DCHECK(thread_checker_.CalledOnValidThread()); |
97 return *system_certs_; | 122 return system_certs_; |
98 } | 123 } |
99 | 124 |
100 // Called in tests if |IsCertificateHardwareBacked()| should always return | 125 // Called in tests if |IsCertificateHardwareBacked()| should always return |
101 // true. | 126 // true. |
102 static void ForceHardwareBackedForTesting(); | 127 static void ForceHardwareBackedForTesting(); |
103 | 128 |
104 private: | 129 private: |
| 130 class CertCache; |
| 131 |
105 CertLoader(); | 132 CertLoader(); |
106 ~CertLoader() override; | 133 ~CertLoader(); |
107 | 134 |
108 // Trigger a certificate load. If a certificate loading task is already in | 135 // Called by |system_cert_cache_| or |user_cert_cache| when these had an |
109 // progress, will start a reload once the current task is finished. | 136 // update. |
110 void LoadCertificates(); | 137 void CacheUpdated(); |
111 | |
112 // Called when the underlying NSS database finished loading certificates. | |
113 void CertificatesLoaded(std::unique_ptr<net::CertificateList> all_certs); | |
114 | 138 |
115 // Called if a certificate load task is finished. | 139 // Called if a certificate load task is finished. |
116 void UpdateCertificates(std::unique_ptr<net::CertificateList> all_certs, | 140 void UpdateCertificates(net::CertificateList all_certs, |
117 std::unique_ptr<net::CertificateList> system_certs); | 141 net::CertificateList system_certs); |
118 | 142 |
119 void NotifyCertificatesLoaded(bool initial_load); | 143 void NotifyCertificatesLoaded(bool initial_load); |
120 | 144 |
121 // net::CertDatabase::Observer | 145 // True if the initial load of CertLoader is still pending. This is used to |
122 void OnCertDBChanged() override; | 146 // set the |initial_load| parameter when calling Observers. |
| 147 bool pending_initial_load_; |
123 | 148 |
124 base::ObserverList<Observer> observers_; | 149 base::ObserverList<Observer> observers_; |
125 | 150 |
126 // Flags describing current CertLoader state. | 151 // Cache for certificates from the system-token NSSCertDatabase. |
127 bool certificates_loaded_; | 152 std::unique_ptr<CertCache> system_cert_cache_; |
128 bool certificates_update_required_; | 153 // Cache for certificates from the user-specific NSSCertDatabase. |
129 bool certificates_update_running_; | 154 std::unique_ptr<CertCache> user_cert_cache_; |
130 | 155 |
131 // The user-specific NSS certificate database from which the certificates | 156 // Cached certificates loaded from the database(s). |
132 // should be loaded. | 157 net::CertificateList all_certs_; |
133 net::NSSCertDatabase* database_; | |
134 | 158 |
135 // Cached certificates loaded from the database. | 159 // Cached certificates from system token. |
136 std::unique_ptr<net::CertificateList> all_certs_; | 160 net::CertificateList system_certs_; |
137 | |
138 // Cached certificates from system token. Currently this is a sublist of | |
139 // |all_certs_|. | |
140 std::unique_ptr<net::CertificateList> system_certs_; | |
141 | 161 |
142 base::ThreadChecker thread_checker_; | 162 base::ThreadChecker thread_checker_; |
143 | 163 |
144 base::WeakPtrFactory<CertLoader> weak_factory_; | 164 base::WeakPtrFactory<CertLoader> weak_factory_; |
145 | 165 |
146 DISALLOW_COPY_AND_ASSIGN(CertLoader); | 166 DISALLOW_COPY_AND_ASSIGN(CertLoader); |
147 }; | 167 }; |
148 | 168 |
149 } // namespace chromeos | 169 } // namespace chromeos |
150 | 170 |
151 #endif // CHROMEOS_CERT_LOADER_H_ | 171 #endif // CHROMEOS_CERT_LOADER_H_ |
OLD | NEW |