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

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: Separated out ClientCertStoreChromeOS change. Created 6 years, 1 month 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 explicit Internal(
Joao da Silva 2014/10/30 09:48:01 No need for explicit
pneubeck (no reviews) 2014/11/05 14:53:37 Done.
64 const std::string& user_email,
65 const std::string& username_hash,
66 bool use_system_key_slot,
67 const base::FilePath& path,
68 const scoped_refptr<base::SequencedTaskRunner>& dbus_task_runner,
69 chromeos::CryptohomeClient* cryptohome_client,
70 CertDatabaseServiceIOPartChromeOS* io_part)
71 : user_email_(user_email),
72 username_hash_(username_hash),
73 use_system_key_slot_(use_system_key_slot),
74 path_(path),
75 dbus_task_runner_(dbus_task_runner),
76 state_(NOT_STARTED),
77 system_tpm_token_status_(SYSTEM_TPM_TOKEN_STATUS_UNDETERMINED),
78 cryptohome_client_(cryptohome_client),
79 io_part_(io_part),
80 weak_ptr_factory_(this) {
81 CHECK(dbus_task_runner_.get());
82 CHECK(cryptohome_client_);
83 CHECK(io_part_);
84 }
85
86 void Run() {
87 thread_checker_.DetachFromThread();
88 thread_checker_.CalledOnValidThread();
Joao da Silva 2014/10/30 09:48:01 DCHECK
pneubeck (no reviews) 2014/11/05 14:53:37 why? This check can never fail because of the Deta
Joao da Silva 2014/11/05 15:07:51 Ah, the call to CalledOnValidThread() is just to a
89 DCHECK_EQ(NOT_STARTED, state_);
90
91 VLOG(1) << "Initialize NSS for chromeos user " << username_hash_;
92 crypto::InitializeNSSForChromeOSUser(username_hash_, path_);
93 RunNextStep(TPM_TOKEN_STATE_UNKNOWN);
94 }
95
96 typedef base::Callback<void(bool system_tpm_token_enabled)>
97 SystemTPMTokenReadyCallback;
98 SystemTPMTokenReadyCallback GetSystemTPMTokenReadyCallback() {
99 return base::Bind(&Internal::OnSystemTPMTokenReady,
100 weak_ptr_factory_.GetWeakPtr());
101 }
102
103 private:
104 enum SystemTPMTokenStatus {
105 SYSTEM_TPM_TOKEN_STATUS_UNDETERMINED,
106 SYSTEM_TPM_TOKEN_STATUS_ENABLED,
107 SYSTEM_TPM_TOKEN_STATUS_DISABLED
108 };
109
110 enum State {
111 NOT_STARTED,
112 TPM_TOKEN_STATE_UNKNOWN,
113 TPM_TOKEN_ENABLED_AND_READY,
114 INITIALIZED_NSS_FOR_USER,
115 GOT_PRIVATE_SLOT_FOR_USER,
116 WAITING_FOR_SYSTEM_TPM_TOKEN,
117 SYSTEM_TPM_TOKEN_READY,
118 GOT_SYSTEM_SLOT,
119 CREATED_NSS_CERTDB
120 };
121
122 void RunNextStep(const State& next_state) {
123 DCHECK(thread_checker_.CalledOnValidThread());
124
125 VLOG(1) << "State transition " << state_ << " -> " << next_state;
126 state_ = next_state;
127 switch (state_) {
128 case NOT_STARTED:
129 NOTREACHED();
130 break;
131 case TPM_TOKEN_STATE_UNKNOWN:
132 CheckTPMTokenState();
133 break;
134 case TPM_TOKEN_ENABLED_AND_READY:
135 GetTPMTokenInfo();
136 break;
137 case INITIALIZED_NSS_FOR_USER:
138 GetPrivateSlot();
139 break;
140 case GOT_PRIVATE_SLOT_FOR_USER:
141 if (!use_system_key_slot_) {
142 RunNextStep(GOT_SYSTEM_SLOT);
143 } else if (system_tpm_token_status_ ==
144 SYSTEM_TPM_TOKEN_STATUS_UNDETERMINED) {
145 state_ = WAITING_FOR_SYSTEM_TPM_TOKEN;
146 } else {
147 RunNextStep(SYSTEM_TPM_TOKEN_READY);
148 }
149 break;
150 case WAITING_FOR_SYSTEM_TPM_TOKEN:
151 // This step is waiting for OnSystemTPMTokenReady to be called.
152 NOTREACHED();
153 break;
154 case SYSTEM_TPM_TOKEN_READY:
155 GetSystemSlot();
156 break;
157 case GOT_SYSTEM_SLOT:
158 CreateCertDatabase();
159 break;
160 case CREATED_NSS_CERTDB:
161 NOTREACHED();
162 }
163 }
164
165 void FinishWithState(const State& state) {
166 VLOG(1) << "FinishWithState " << state;
167 state_ = state;
168 }
169
170 void CheckTPMTokenState() {
171 // Check if it's OK to initialize TPM for the user before continuing. This
172 // may not be the case if the TPM slot initialization was previously
173 // requested for the same user.
174 if (!crypto::ShouldInitializeTPMForChromeOSUser(username_hash_)) {
175 RunNextStep(INITIALIZED_NSS_FOR_USER);
176 return;
177 }
178
179 crypto::WillInitializeTPMForChromeOSUser(username_hash_);
180
181 if (crypto::IsTPMTokenEnabledForNSS()) {
182 base::Closure tpm_token_ready_callback =
183 base::Bind(&Internal::RunNextStep,
184 weak_ptr_factory_.GetWeakPtr(),
185 TPM_TOKEN_ENABLED_AND_READY);
186 if (crypto::IsTPMTokenReady(tpm_token_ready_callback))
187 tpm_token_ready_callback.Run();
188 else
189 DVLOG(1) << "Waiting for tpm ready ...";
190 } else {
191 crypto::InitializePrivateSoftwareSlotForChromeOSUser(username_hash_);
192 RunNextStep(INITIALIZED_NSS_FOR_USER);
193 }
194 }
195
196 void GetTPMTokenInfo() {
197 GetTPMInfoForUserOnIOThread(
198 user_email_,
199 base::Bind(&Internal::GotTPMTokenInfo, weak_ptr_factory_.GetWeakPtr()),
200 dbus_task_runner_,
201 cryptohome_client_);
202 }
203
204 void GotTPMTokenInfo(chromeos::DBusMethodCallStatus call_status,
205 const std::string& label,
206 const std::string& user_pin,
207 int slot_id) {
208 DCHECK(thread_checker_.CalledOnValidThread());
209
210 if (call_status == chromeos::DBUS_METHOD_CALL_FAILURE) {
211 // TODO(pneubeck, tbarzic): Retry instead of just failing.
212 // https://crbug.com/426349
213 LOG(ERROR) << "DBus error while getting TPM info for " << username_hash_;
214 crypto::InitializePrivateSoftwareSlotForChromeOSUser(username_hash_);
215 } else {
216 crypto::InitializeTPMForChromeOSUser(username_hash_, slot_id);
217 }
218 RunNextStep(INITIALIZED_NSS_FOR_USER);
219 }
220
221 void GetPrivateSlot() {
222 base::Callback<void(crypto::ScopedPK11Slot)> callback =
223 base::Bind(&Internal::GotPrivateSlot, weak_ptr_factory_.GetWeakPtr());
224
225 crypto::ScopedPK11Slot private_slot(
226 crypto::GetPrivateSlotForChromeOSUser(username_hash_, callback));
227 if (private_slot)
228 callback.Run(private_slot.Pass());
229 }
230
231 void GotPrivateSlot(crypto::ScopedPK11Slot private_slot) {
232 DCHECK(thread_checker_.CalledOnValidThread());
233 DCHECK(private_slot);
234
235 private_slot_ = private_slot.Pass();
236 RunNextStep(GOT_PRIVATE_SLOT_FOR_USER);
237 }
238
239 // This is called from external once the TPM token is ready. Must be called at
240 // most once and after Run().
241 void OnSystemTPMTokenReady(bool system_tpm_token_enabled) {
242 DCHECK(thread_checker_.CalledOnValidThread());
243 DCHECK_NE(NOT_STARTED, state_);
244 DCHECK_EQ(SYSTEM_TPM_TOKEN_STATUS_UNDETERMINED, system_tpm_token_status_);
245
246 if (!use_system_key_slot_)
247 return;
248 if (system_tpm_token_enabled)
249 system_tpm_token_status_ = SYSTEM_TPM_TOKEN_STATUS_ENABLED;
250 else
251 system_tpm_token_status_ = SYSTEM_TPM_TOKEN_STATUS_DISABLED;
252 if (state_ == WAITING_FOR_SYSTEM_TPM_TOKEN)
253 RunNextStep(SYSTEM_TPM_TOKEN_READY);
254 }
255
256 void GetSystemSlot() {
257 if (!use_system_key_slot_ ||
258 system_tpm_token_status_ == SYSTEM_TPM_TOKEN_STATUS_DISABLED) {
259 VLOG(2) << "Skip system key slot initialization";
260 RunNextStep(GOT_SYSTEM_SLOT);
261 return;
262 }
263
264 base::Callback<void(crypto::ScopedPK11Slot)> callback =
265 base::Bind(&Internal::GotSystemSlot, weak_ptr_factory_.GetWeakPtr());
266
267 crypto::ScopedPK11Slot system_slot = crypto::GetSystemNSSKeySlot(callback);
268 if (system_slot)
269 callback.Run(system_slot.Pass());
270 }
271
272 void GotSystemSlot(crypto::ScopedPK11Slot system_slot) {
273 if (!system_slot)
274 LOG(ERROR) << "Could not get the system key slot.";
275 system_slot_ = system_slot.Pass();
276 RunNextStep(GOT_SYSTEM_SLOT);
277 }
278
279 void CreateCertDatabase() {
280 crypto::ScopedPK11Slot public_slot =
281 crypto::GetPublicSlotForChromeOSUser(username_hash_);
282
283 scoped_ptr<net::NSSCertDatabaseChromeOS> db(
284 new net::NSSCertDatabaseChromeOS(public_slot.Pass(),
285 private_slot_.Pass()));
286 if (system_slot_)
287 db->SetSystemSlot(system_slot_.Pass());
288
289 FinishWithState(CREATED_NSS_CERTDB);
290 io_part_->DidCreateNSSCertDatabase(db.Pass()); // Will delete this.
291 }
292
293 const std::string user_email_;
294 const std::string username_hash_;
295 bool use_system_key_slot_;
296 const base::FilePath path_;
297 scoped_refptr<base::SequencedTaskRunner> dbus_task_runner_;
298 State state_;
299 crypto::ScopedPK11Slot private_slot_;
300 SystemTPMTokenStatus system_tpm_token_status_;
301 crypto::ScopedPK11Slot system_slot_;
302 chromeos::CryptohomeClient* cryptohome_client_;
303 CertDatabaseServiceIOPartChromeOS* io_part_;
304 base::ThreadChecker thread_checker_;
305 base::WeakPtrFactory<Internal> weak_ptr_factory_;
306
307 DISALLOW_COPY_AND_ASSIGN(Internal);
308 };
309
310 CertDatabaseServiceIOPartChromeOS::CertDatabaseServiceIOPartChromeOS(
311 const std::string& user_email,
312 const std::string& username_hash,
313 bool use_system_key_slot,
314 const base::FilePath& path,
315 const scoped_refptr<base::SequencedTaskRunner>& dbus_task_runner,
316 chromeos::CryptohomeClient* cryptohome_client)
317 : internal_(new Internal(user_email,
318 username_hash,
319 use_system_key_slot,
320 path,
321 dbus_task_runner,
322 cryptohome_client,
323 this)) {
324 }
325
326 CertDatabaseServiceIOPartChromeOS::~CertDatabaseServiceIOPartChromeOS() {
327 DCHECK(thread_checker_.CalledOnValidThread());
328 }
329
330 void CertDatabaseServiceIOPartChromeOS::Init() {
331 CertDatabaseServiceIOPart::Init();
332 internal_->Run();
333 }
334
335 void CertDatabaseServiceIOPartChromeOS::DidCreateNSSCertDatabase(
336 scoped_ptr<net::NSSCertDatabase> db) {
337 internal_.reset();
338 SetNSSCertDatabase(db.Pass());
339 }
340
341 CertDatabaseServiceIOPartChromeOS::SystemTPMTokenReadyCallback
342 CertDatabaseServiceIOPartChromeOS::GetSystemTPMTokenReadyCallback() {
343 CHECK(!IsInitialized());
344 return internal_->GetSystemTPMTokenReadyCallback();
345 }
346
347 } // namespace cert_database
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698