Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(191)

Side by Side Diff: components/cert_database/chromeos/cert_database_service_io_part_chromeos.cc

Issue 419013003: Replace c/b/nss_context by a KeyedService. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Added Linux implementation. Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2014 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 "components/cert_database/public/chromeos/cert_database_service_io_part _chromeos.h"
6
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/callback.h"
10 #include "base/location.h"
11 #include "base/single_thread_task_runner.h"
12 #include "base/thread_task_runner_handle.h"
13 #include "chromeos/dbus/cryptohome_client.h"
14 #include "chromeos/dbus/dbus_thread_manager.h"
15 #include "chromeos/tpm_token_loader.h"
16 #include "crypto/nss_util.h"
17 #include "crypto/nss_util_internal.h"
18 #include "net/cert/nss_cert_database_chromeos.h"
19
20 namespace {
21
22 void DidGetTPMInfoOnUICallBackToIO(
23 const chromeos::CryptohomeClient::Pkcs11GetTpmTokenInfoCallback& callback,
24 scoped_refptr<base::SingleThreadTaskRunner> origin_thread,
25 chromeos::DBusMethodCallStatus call_status,
26 const std::string& label,
27 const std::string& user_pin,
28 int slot_id) {
29 DVLOG(1) << "Got TPM info for slot " << slot_id;
30 origin_thread->PostTask(
31 FROM_HERE, base::Bind(callback, call_status, label, user_pin, slot_id));
32 }
33
34 void GetTPMInfoForUserOnUIThread(
35 const std::string& user_email,
36 const chromeos::CryptohomeClient::Pkcs11GetTpmTokenInfoCallback& callback,
37 scoped_refptr<base::SingleThreadTaskRunner> origin_thread) {
38 DVLOG(1) << "Getting TPM info from cryptohome for "
39 << " " << user_email;
40 chromeos::DBusThreadManager::Get()
41 ->GetCryptohomeClient()
42 ->Pkcs11GetTpmTokenInfoForUser(
43 user_email,
44 base::Bind(&DidGetTPMInfoOnUICallBackToIO, callback, origin_thread));
45 }
46
47 void GetTPMInfoForUserOnIOThread(
48 const std::string& user_email,
49 const chromeos::CryptohomeClient::Pkcs11GetTpmTokenInfoCallback& callback,
50 scoped_refptr<base::SequencedTaskRunner> dbus_task_runner) {
51 dbus_task_runner->PostTask(FROM_HERE,
52 base::Bind(&GetTPMInfoForUserOnUIThread,
53 user_email,
54 callback,
55 base::ThreadTaskRunnerHandle::Get()));
56 }
57
58 } // namespace
59
60 class CertDatabaseServiceIOPartChromeOS::Internal {
61 public:
62 enum SystemTPMTokenStatus {
63 SYSTEM_TPM_TOKEN_STATUS_UNDETERMINED,
64 SYSTEM_TPM_TOKEN_STATUS_ENABLED,
65 SYSTEM_TPM_TOKEN_STATUS_DISABLED
66 };
67
68 enum State {
69 TPM_TOKEN_STATE_UNKNOWN,
70 TPM_TOKEN_ENABLED_AND_READY,
71 INITIALIZED_NSS_FOR_USER,
72 GOT_PRIVATE_SLOT_FOR_USER,
73 WAITING_FOR_SYSTEM_TPM_TOKEN,
74 SYSTEM_TPM_TOKEN_READY,
75 GOT_SYSTEM_SLOT,
76 CREATED_NSS_CERTDB
77 };
78
79 explicit Internal(
80 const std::string& user_email,
81 const std::string& username_hash,
82 bool use_system_key_slot,
83 const base::FilePath& path,
84 const scoped_refptr<base::SequencedTaskRunner>& dbus_task_runner,
85 CertDatabaseServiceIOPartChromeOS* io_part)
86 : user_email_(user_email),
87 username_hash_(username_hash),
88 use_system_key_slot_(use_system_key_slot),
89 path_(path),
90 dbus_task_runner_(dbus_task_runner),
91 state_(TPM_TOKEN_STATE_UNKNOWN),
92 system_tpm_token_status_(SYSTEM_TPM_TOKEN_STATUS_UNDETERMINED),
93 io_part_(io_part),
94 weak_ptr_factory_(this) {}
95
96 void Run() {
97 DCHECK(thread_checker_.CalledOnValidThread());
98
99 VLOG(1) << "Initialize NSS for chromeos user " << username_hash_;
100 crypto::InitializeNSSForChromeOSUser(username_hash_, path_);
101 RunNextStep(TPM_TOKEN_STATE_UNKNOWN);
102 }
103
104 void RunNextStep(const State& next_state) {
105 DCHECK(thread_checker_.CalledOnValidThread());
106
107 VLOG(1) << "State transition " << state_ << " -> " << next_state;
108 state_ = next_state;
109 switch (state_) {
110 case TPM_TOKEN_STATE_UNKNOWN:
111 CheckTPMTokenState();
112 break;
113 case TPM_TOKEN_ENABLED_AND_READY:
114 GetTPMTokenInfo();
115 break;
116 case INITIALIZED_NSS_FOR_USER:
117 GetPrivateSlot();
118 break;
119 case GOT_PRIVATE_SLOT_FOR_USER:
120 if (!use_system_key_slot_) {
121 RunNextStep(GOT_SYSTEM_SLOT);
122 } else if (system_tpm_token_status_ ==
123 SYSTEM_TPM_TOKEN_STATUS_UNDETERMINED) {
124 state_ = WAITING_FOR_SYSTEM_TPM_TOKEN;
125 } else {
126 RunNextStep(SYSTEM_TPM_TOKEN_READY);
127 }
128 break;
129 case WAITING_FOR_SYSTEM_TPM_TOKEN:
130 // This step is waiting for OnSystemTPMTokenReady to be called.
131 NOTREACHED();
132 break;
133 case SYSTEM_TPM_TOKEN_READY:
134 GetSystemSlot();
135 break;
136 case GOT_SYSTEM_SLOT:
137 CreateCertDatabase();
138 break;
139 case CREATED_NSS_CERTDB:
140 NOTREACHED();
141 }
142 }
143
144 void FinishWithState(const State& state) {
145 VLOG(1) << "FinishWithState " << state;
146 state_ = state;
147 }
148
149 void CheckTPMTokenState() {
150 // Check if it's OK to initialize TPM for the user before continuing. This
151 // may not be the case if the TPM slot initialization was previously
152 // requested for the same user.
153 if (!crypto::ShouldInitializeTPMForChromeOSUser(username_hash_)) {
154 RunNextStep(INITIALIZED_NSS_FOR_USER);
155 return;
156 }
157
158 crypto::WillInitializeTPMForChromeOSUser(username_hash_);
159
160 if (crypto::IsTPMTokenEnabledForNSS()) {
161 base::Closure tpm_token_ready_callback =
162 base::Bind(&Internal::RunNextStep,
163 weak_ptr_factory_.GetWeakPtr(),
164 TPM_TOKEN_ENABLED_AND_READY);
165 if (crypto::IsTPMTokenReady(tpm_token_ready_callback))
166 tpm_token_ready_callback.Run();
167 else
168 DVLOG(1) << "Waiting for tpm ready ...";
169 } else {
170 crypto::InitializePrivateSoftwareSlotForChromeOSUser(username_hash_);
171 RunNextStep(INITIALIZED_NSS_FOR_USER);
172 }
173 }
174
175 void GetTPMTokenInfo() {
176 GetTPMInfoForUserOnIOThread(user_email_,
177 base::Bind(&Internal::GetTPMTokenInfoDONE,
178 weak_ptr_factory_.GetWeakPtr()),
179 dbus_task_runner_);
180 }
181
182 void GetTPMTokenInfoDONE(chromeos::DBusMethodCallStatus call_status,
183 const std::string& label,
184 const std::string& user_pin,
185 int slot_id) {
186 DCHECK(thread_checker_.CalledOnValidThread());
187
188 if (call_status == chromeos::DBUS_METHOD_CALL_FAILURE) {
189 LOG(ERROR) << "DBus error while getting TPM info for " << username_hash_;
190 crypto::InitializePrivateSoftwareSlotForChromeOSUser(username_hash_);
191 } else {
192 crypto::InitializeTPMForChromeOSUser(username_hash_, slot_id);
193 }
194 RunNextStep(INITIALIZED_NSS_FOR_USER);
195 }
196
197 void GetPrivateSlot() {
198 base::Callback<void(crypto::ScopedPK11Slot)> callback = base::Bind(
199 &Internal::GetPrivateSlotDONE, weak_ptr_factory_.GetWeakPtr());
200
201 crypto::ScopedPK11Slot private_slot(
202 crypto::GetPrivateSlotForChromeOSUser(username_hash_, callback));
203 if (private_slot)
204 callback.Run(private_slot.Pass());
205 }
206
207 void GetPrivateSlotDONE(crypto::ScopedPK11Slot private_slot) {
208 DCHECK(thread_checker_.CalledOnValidThread());
209 DCHECK(private_slot);
210
211 private_slot_ = private_slot.Pass();
212 RunNextStep(GOT_PRIVATE_SLOT_FOR_USER);
213 }
214
215 void OnSystemTPMTokenReady(bool system_tpm_token_enabled) {
216 if (!use_system_key_slot_)
217 return;
218 if (system_tpm_token_enabled)
219 system_tpm_token_status_ = SYSTEM_TPM_TOKEN_STATUS_ENABLED;
220 else
221 system_tpm_token_status_ = SYSTEM_TPM_TOKEN_STATUS_DISABLED;
222 if (state_ == WAITING_FOR_SYSTEM_TPM_TOKEN)
223 RunNextStep(SYSTEM_TPM_TOKEN_READY);
224 }
225
226 void GetSystemSlot() {
227 if (!use_system_key_slot_ ||
228 system_tpm_token_status_ == SYSTEM_TPM_TOKEN_STATUS_DISABLED) {
229 VLOG(2) << "Skip system key slot initialization";
230 RunNextStep(GOT_SYSTEM_SLOT);
231 return;
232 }
233
234 base::Callback<void(crypto::ScopedPK11Slot)> callback = base::Bind(
235 &Internal::GetSystemSlotDONE, weak_ptr_factory_.GetWeakPtr());
236
237 crypto::ScopedPK11Slot system_slot = crypto::GetSystemNSSKeySlot(callback);
238 if (system_slot)
239 callback.Run(system_slot.Pass());
240 }
241
242 void GetSystemSlotDONE(crypto::ScopedPK11Slot system_slot) {
243 if (!system_slot)
244 LOG(ERROR) << "Could not get the system key slot.";
245 system_slot_ = system_slot.Pass();
246 RunNextStep(GOT_SYSTEM_SLOT);
247 }
248
249 void CreateCertDatabase() {
250 crypto::ScopedPK11Slot public_slot =
251 crypto::GetPublicSlotForChromeOSUser(username_hash_);
252
253 scoped_ptr<net::NSSCertDatabaseChromeOS> db(
254 new net::NSSCertDatabaseChromeOS(public_slot.Pass(),
255 private_slot_.Pass()));
256 if (system_slot_)
257 db->SetSystemSlot(system_slot_.Pass());
258
259 io_part_->DidCreateNSSCertDatabase(db.PassAs<net::NSSCertDatabase>());
260 FinishWithState(CREATED_NSS_CERTDB);
261 }
262
263 const std::string user_email_;
264 const std::string username_hash_;
265 bool use_system_key_slot_;
266 const base::FilePath path_;
267 scoped_refptr<base::SequencedTaskRunner> dbus_task_runner_;
268 State state_;
269 crypto::ScopedPK11Slot private_slot_;
270 SystemTPMTokenStatus system_tpm_token_status_;
271 crypto::ScopedPK11Slot system_slot_;
272 CertDatabaseServiceIOPartChromeOS* io_part_;
273 base::ThreadChecker thread_checker_;
274 base::WeakPtrFactory<Internal> weak_ptr_factory_;
275
276 DISALLOW_COPY_AND_ASSIGN(Internal);
277 };
278
279 CertDatabaseServiceIOPartChromeOS::CertDatabaseServiceIOPartChromeOS(
280 const std::string& user_email,
281 const std::string& username_hash,
282 bool use_system_key_slot,
283 const base::FilePath& path,
284 const scoped_refptr<base::SequencedTaskRunner>& dbus_task_runner)
285 : internal_(new Internal(user_email,
286 username_hash,
287 use_system_key_slot,
288 path,
289 dbus_task_runner,
290 this)) {
291 }
292
293 CertDatabaseServiceIOPartChromeOS::~CertDatabaseServiceIOPartChromeOS() {
294 DCHECK(thread_checker_.CalledOnValidThread());
295 }
296
297 void CertDatabaseServiceIOPartChromeOS::Init() {
298 CertDatabaseServiceIOPart::Init();
299
300 internal_->Run();
301 }
302
303 void CertDatabaseServiceIOPartChromeOS::DidCreateNSSCertDatabase(
304 scoped_ptr<net::NSSCertDatabase> db) {
305 internal_.reset();
306 CertDatabaseServiceIOPart::DidCreateNSSCertDatabase(db.Pass());
307 }
308
309 CertDatabaseServiceIOPartChromeOS::SystemTPMTokenReadyCallback
310 CertDatabaseServiceIOPartChromeOS::GetSystemTPMTokenReadyCallback() {
311 return base::Bind(
312 &OnSystemTPMTokenReady, GetWeakPtr(), base::Unretained(this));
313 }
314
315 // static
316 void OnSystemTPMTokenReady(
317 const base::WeakPtr<CertDatabaseServiceIOPartChromeOS>& weak_ptr,
318 CertDatabaseServiceIOPartChromeOS* io_part,
319 bool system_tpm_token_enabled) {
320 if (!weak_ptr)
321 return;
322
323 io_part->internal_->OnSystemTPMTokenReady(system_tpm_token_enabled);
324 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698