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

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 cert_database namespace. Created 6 years, 2 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 "crypto/nss_util.h"
15 #include "crypto/nss_util_internal.h"
16 #include "net/cert/nss_cert_database_chromeos.h"
17
18 namespace cert_database {
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 chromeos::CryptohomeClient* cryptohome_client) {
39 DVLOG(1) << "Getting TPM info from cryptohome for "
40 << " " << user_email;
41 cryptohome_client->Pkcs11GetTpmTokenInfoForUser(
42 user_email,
43 base::Bind(&DidGetTPMInfoOnUICallBackToIO, callback, origin_thread));
44 }
45
46 void GetTPMInfoForUserOnIOThread(
47 const std::string& user_email,
48 const chromeos::CryptohomeClient::Pkcs11GetTpmTokenInfoCallback& callback,
49 scoped_refptr<base::SequencedTaskRunner> dbus_task_runner,
50 chromeos::CryptohomeClient* cryptohome_client) {
51 dbus_task_runner->PostTask(FROM_HERE,
52 base::Bind(&GetTPMInfoForUserOnUIThread,
53 user_email,
54 callback,
55 base::ThreadTaskRunnerHandle::Get(),
56 cryptohome_client));
57 }
58
59 } // namespace
60
61 class CertDatabaseServiceIOPartChromeOS::Internal {
62 public:
63 enum SystemTPMTokenStatus {
64 SYSTEM_TPM_TOKEN_STATUS_UNDETERMINED,
65 SYSTEM_TPM_TOKEN_STATUS_ENABLED,
66 SYSTEM_TPM_TOKEN_STATUS_DISABLED
67 };
68
69 enum State {
70 TPM_TOKEN_STATE_UNKNOWN,
71 TPM_TOKEN_ENABLED_AND_READY,
72 INITIALIZED_NSS_FOR_USER,
73 GOT_PRIVATE_SLOT_FOR_USER,
74 WAITING_FOR_SYSTEM_TPM_TOKEN,
75 SYSTEM_TPM_TOKEN_READY,
76 GOT_SYSTEM_SLOT,
77 CREATED_NSS_CERTDB
78 };
79
80 explicit Internal(
81 const std::string& user_email,
82 const std::string& username_hash,
83 bool use_system_key_slot,
84 const base::FilePath& path,
85 const scoped_refptr<base::SequencedTaskRunner>& dbus_task_runner,
86 chromeos::CryptohomeClient* cryptohome_client,
87 CertDatabaseServiceIOPartChromeOS* io_part)
88 : user_email_(user_email),
89 username_hash_(username_hash),
90 use_system_key_slot_(use_system_key_slot),
91 path_(path),
92 dbus_task_runner_(dbus_task_runner),
93 state_(TPM_TOKEN_STATE_UNKNOWN),
94 system_tpm_token_status_(SYSTEM_TPM_TOKEN_STATUS_UNDETERMINED),
95 cryptohome_client_(cryptohome_client),
96 io_part_(io_part),
97 weak_ptr_factory_(this) {
98 CHECK(dbus_task_runner_.get());
99 CHECK(cryptohome_client_);
100 CHECK(io_part_);
101 }
102
103 void Run() {
104 thread_checker_.DetachFromThread();
105 thread_checker_.CalledOnValidThread();
106
107 VLOG(1) << "Initialize NSS for chromeos user " << username_hash_;
108 crypto::InitializeNSSForChromeOSUser(username_hash_, path_);
109 RunNextStep(TPM_TOKEN_STATE_UNKNOWN);
110 }
111
112 void RunNextStep(const State& next_state) {
mattm 2014/10/18 00:45:16 hm, not entirely sure about the state machine, esp
pneubeck (no reviews) 2014/10/21 09:22:09 What specific do you mean? The fact that it's wait
mattm 2014/10/30 03:37:48 I dunno, just feels a little weird to me. But I do
113 DCHECK(thread_checker_.CalledOnValidThread());
114
115 VLOG(1) << "State transition " << state_ << " -> " << next_state;
116 state_ = next_state;
117 switch (state_) {
118 case TPM_TOKEN_STATE_UNKNOWN:
119 CheckTPMTokenState();
120 break;
121 case TPM_TOKEN_ENABLED_AND_READY:
122 GetTPMTokenInfo();
123 break;
124 case INITIALIZED_NSS_FOR_USER:
125 GetPrivateSlot();
126 break;
127 case GOT_PRIVATE_SLOT_FOR_USER:
128 if (!use_system_key_slot_) {
129 RunNextStep(GOT_SYSTEM_SLOT);
130 } else if (system_tpm_token_status_ ==
131 SYSTEM_TPM_TOKEN_STATUS_UNDETERMINED) {
132 state_ = WAITING_FOR_SYSTEM_TPM_TOKEN;
133 } else {
134 RunNextStep(SYSTEM_TPM_TOKEN_READY);
135 }
136 break;
137 case WAITING_FOR_SYSTEM_TPM_TOKEN:
138 // This step is waiting for OnSystemTPMTokenReady to be called.
139 NOTREACHED();
140 break;
141 case SYSTEM_TPM_TOKEN_READY:
142 GetSystemSlot();
143 break;
144 case GOT_SYSTEM_SLOT:
145 CreateCertDatabase();
146 break;
147 case CREATED_NSS_CERTDB:
148 NOTREACHED();
149 }
150 }
151
152 void FinishWithState(const State& state) {
153 VLOG(1) << "FinishWithState " << state;
154 state_ = state;
155 }
156
157 void CheckTPMTokenState() {
158 // Check if it's OK to initialize TPM for the user before continuing. This
159 // may not be the case if the TPM slot initialization was previously
160 // requested for the same user.
161 if (!crypto::ShouldInitializeTPMForChromeOSUser(username_hash_)) {
162 RunNextStep(INITIALIZED_NSS_FOR_USER);
163 return;
164 }
165
166 crypto::WillInitializeTPMForChromeOSUser(username_hash_);
167
168 if (crypto::IsTPMTokenEnabledForNSS()) {
169 base::Closure tpm_token_ready_callback =
170 base::Bind(&Internal::RunNextStep,
171 weak_ptr_factory_.GetWeakPtr(),
172 TPM_TOKEN_ENABLED_AND_READY);
173 if (crypto::IsTPMTokenReady(tpm_token_ready_callback))
174 tpm_token_ready_callback.Run();
175 else
176 DVLOG(1) << "Waiting for tpm ready ...";
177 } else {
178 crypto::InitializePrivateSoftwareSlotForChromeOSUser(username_hash_);
179 RunNextStep(INITIALIZED_NSS_FOR_USER);
180 }
181 }
182
183 void GetTPMTokenInfo() {
184 GetTPMInfoForUserOnIOThread(user_email_,
185 base::Bind(&Internal::GetTPMTokenInfoDONE,
186 weak_ptr_factory_.GetWeakPtr()),
187 dbus_task_runner_,
188 cryptohome_client_);
189 }
190
191 void GetTPMTokenInfoDONE(chromeos::DBusMethodCallStatus call_status,
192 const std::string& label,
193 const std::string& user_pin,
194 int slot_id) {
195 DCHECK(thread_checker_.CalledOnValidThread());
196
197 if (call_status == chromeos::DBUS_METHOD_CALL_FAILURE) {
198 LOG(ERROR) << "DBus error while getting TPM info for " << username_hash_;
199 crypto::InitializePrivateSoftwareSlotForChromeOSUser(username_hash_);
200 } else {
201 crypto::InitializeTPMForChromeOSUser(username_hash_, slot_id);
202 }
203 RunNextStep(INITIALIZED_NSS_FOR_USER);
204 }
205
206 void GetPrivateSlot() {
207 base::Callback<void(crypto::ScopedPK11Slot)> callback = base::Bind(
208 &Internal::GetPrivateSlotDONE, weak_ptr_factory_.GetWeakPtr());
209
210 crypto::ScopedPK11Slot private_slot(
211 crypto::GetPrivateSlotForChromeOSUser(username_hash_, callback));
212 if (private_slot)
213 callback.Run(private_slot.Pass());
214 }
215
216 void GetPrivateSlotDONE(crypto::ScopedPK11Slot private_slot) {
mattm 2014/10/18 00:45:16 Name style. Maybe GotPrivateSlot or DidGetPrivateS
pneubeck (no reviews) 2014/10/21 09:22:09 Done.
217 DCHECK(thread_checker_.CalledOnValidThread());
218 DCHECK(private_slot);
219
220 private_slot_ = private_slot.Pass();
221 RunNextStep(GOT_PRIVATE_SLOT_FOR_USER);
222 }
223
224 void OnSystemTPMTokenReady(bool system_tpm_token_enabled) {
225 if (!use_system_key_slot_)
226 return;
227 if (system_tpm_token_enabled)
228 system_tpm_token_status_ = SYSTEM_TPM_TOKEN_STATUS_ENABLED;
229 else
230 system_tpm_token_status_ = SYSTEM_TPM_TOKEN_STATUS_DISABLED;
231 if (state_ == WAITING_FOR_SYSTEM_TPM_TOKEN)
232 RunNextStep(SYSTEM_TPM_TOKEN_READY);
233 }
234
235 void GetSystemSlot() {
236 if (!use_system_key_slot_ ||
237 system_tpm_token_status_ == SYSTEM_TPM_TOKEN_STATUS_DISABLED) {
238 VLOG(2) << "Skip system key slot initialization";
239 RunNextStep(GOT_SYSTEM_SLOT);
240 return;
241 }
242
243 base::Callback<void(crypto::ScopedPK11Slot)> callback = base::Bind(
244 &Internal::GetSystemSlotDONE, weak_ptr_factory_.GetWeakPtr());
245
246 crypto::ScopedPK11Slot system_slot = crypto::GetSystemNSSKeySlot(callback);
247 if (system_slot)
248 callback.Run(system_slot.Pass());
249 }
250
251 void GetSystemSlotDONE(crypto::ScopedPK11Slot system_slot) {
252 if (!system_slot)
253 LOG(ERROR) << "Could not get the system key slot.";
254 system_slot_ = system_slot.Pass();
255 RunNextStep(GOT_SYSTEM_SLOT);
256 }
257
258 void CreateCertDatabase() {
259 crypto::ScopedPK11Slot public_slot =
260 crypto::GetPublicSlotForChromeOSUser(username_hash_);
261
262 scoped_ptr<net::NSSCertDatabaseChromeOS> db(
263 new net::NSSCertDatabaseChromeOS(public_slot.Pass(),
264 private_slot_.Pass()));
265 if (system_slot_)
266 db->SetSystemSlot(system_slot_.Pass());
267
268 io_part_->DidCreateNSSCertDatabase(db.PassAs<net::NSSCertDatabase>());
mattm 2014/10/18 00:45:16 can use Pass() now
pneubeck (no reviews) 2014/10/21 09:22:09 Done.
269 FinishWithState(CREATED_NSS_CERTDB);
270 }
271
272 const std::string user_email_;
273 const std::string username_hash_;
274 bool use_system_key_slot_;
275 const base::FilePath path_;
276 scoped_refptr<base::SequencedTaskRunner> dbus_task_runner_;
277 State state_;
278 crypto::ScopedPK11Slot private_slot_;
279 SystemTPMTokenStatus system_tpm_token_status_;
280 crypto::ScopedPK11Slot system_slot_;
281 chromeos::CryptohomeClient* cryptohome_client_;
282 CertDatabaseServiceIOPartChromeOS* io_part_;
283 base::ThreadChecker thread_checker_;
284 base::WeakPtrFactory<Internal> weak_ptr_factory_;
285
286 DISALLOW_COPY_AND_ASSIGN(Internal);
287 };
288
289 CertDatabaseServiceIOPartChromeOS::CertDatabaseServiceIOPartChromeOS(
290 const std::string& user_email,
291 const std::string& username_hash,
292 bool use_system_key_slot,
293 const base::FilePath& path,
294 const scoped_refptr<base::SequencedTaskRunner>& dbus_task_runner,
295 chromeos::CryptohomeClient* cryptohome_client)
296 : internal_(new Internal(user_email,
297 username_hash,
298 use_system_key_slot,
299 path,
300 dbus_task_runner,
301 cryptohome_client,
302 this)) {
303 }
304
305 CertDatabaseServiceIOPartChromeOS::~CertDatabaseServiceIOPartChromeOS() {
306 DCHECK(thread_checker_.CalledOnValidThread());
307 }
308
309 void CertDatabaseServiceIOPartChromeOS::Init() {
310 CertDatabaseServiceIOPart::Init();
311
312 internal_->Run();
313 }
314
315 void CertDatabaseServiceIOPartChromeOS::DidCreateNSSCertDatabase(
316 scoped_ptr<net::NSSCertDatabase> db) {
317 internal_.reset();
318 CertDatabaseServiceIOPart::DidCreateNSSCertDatabase(db.Pass());
319 }
320
321 CertDatabaseServiceIOPartChromeOS::SystemTPMTokenReadyCallback
322 CertDatabaseServiceIOPartChromeOS::GetSystemTPMTokenReadyCallback() {
323 return base::Bind(
324 &OnSystemTPMTokenReady, GetWeakPtr(), base::Unretained(this));
325 }
326
327 // static
328 void CertDatabaseServiceIOPartChromeOS::OnSystemTPMTokenReady(
329 const base::WeakPtr<CertDatabaseServiceIOPart>& weak_ptr,
330 CertDatabaseServiceIOPartChromeOS* io_part,
331 bool system_tpm_token_enabled) {
332 if (!weak_ptr)
333 return;
334 CHECK_EQ(io_part, weak_ptr.get());
335
336 io_part->internal_->OnSystemTPMTokenReady(system_tpm_token_enabled);
337 }
338
339 } // namespace cert_database
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698