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

Side by Side Diff: chrome/browser/chromeos/cros/cert_library.cc

Issue 10332191: Remove TPMTokenInfoDelegate (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix logic error Created 8 years, 7 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
« no previous file with comments | « no previous file | crypto/nss_util.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 #include "chrome/browser/chromeos/cros/cert_library.h" 5 #include "chrome/browser/chromeos/cros/cert_library.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/memory/weak_ptr.h" 10 #include "base/memory/weak_ptr.h"
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
88 issued_to, 88 issued_to,
89 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_HARDWARE_BACKED)); 89 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_HARDWARE_BACKED));
90 } else { 90 } else {
91 return l10n_util::GetStringFUTF16( 91 return l10n_util::GetStringFUTF16(
92 IDS_CERT_MANAGER_KEY_FORMAT_LONG, 92 IDS_CERT_MANAGER_KEY_FORMAT_LONG,
93 issued_by, 93 issued_by,
94 issued_to); 94 issued_to);
95 } 95 }
96 } 96 }
97 97
98 class RealTPMTokenInfoDelegate : public crypto::TPMTokenInfoDelegate {
99 public:
100 RealTPMTokenInfoDelegate();
101 virtual ~RealTPMTokenInfoDelegate();
102
103 // TPMTokenInfoDeleagte overrides:
104 virtual void RequestIsTokenReady(
105 base::Callback<void(bool result)> callback) const OVERRIDE;
106 virtual void GetTokenInfo(std::string* token_name,
107 std::string* user_pin) const OVERRIDE;
108
109 private:
110 // This method is used to implement RequestIsTokenReady.
111 void OnPkcs11IsTpmTokenReady(base::Callback<void(bool result)> callback,
112 DBusMethodCallStatus call_status,
113 bool is_tpm_token_ready) const;
114
115 // This method is used to implement RequestIsTokenReady.
116 void OnPkcs11GetTpmTokenInfo(base::Callback<void(bool result)> callback,
117 DBusMethodCallStatus call_status,
118 const std::string& token_name,
119 const std::string& user_pin) const;
120
121 // These are mutable since we need to cache them in IsTokenReady().
122 mutable bool token_ready_;
123 mutable std::string token_name_;
124 mutable std::string user_pin_;
125 mutable base::WeakPtrFactory<RealTPMTokenInfoDelegate> weak_ptr_factory_;
126 };
127
128 RealTPMTokenInfoDelegate::RealTPMTokenInfoDelegate() : token_ready_(false),
129 weak_ptr_factory_(this) {
130 }
131
132 RealTPMTokenInfoDelegate::~RealTPMTokenInfoDelegate() {}
133
134 void RealTPMTokenInfoDelegate::RequestIsTokenReady(
135 base::Callback<void(bool result)> callback) const {
136 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
137 if (token_ready_) {
138 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
139 base::Bind(callback, true));
140 return;
141 }
142 DBusThreadManager::Get()->GetCryptohomeClient()->Pkcs11IsTpmTokenReady(
143 base::Bind(&RealTPMTokenInfoDelegate::OnPkcs11IsTpmTokenReady,
144 weak_ptr_factory_.GetWeakPtr(),
145 callback));
146 }
147
148 void RealTPMTokenInfoDelegate::GetTokenInfo(std::string* token_name,
149 std::string* user_pin) const {
150 // May be called from a non UI thread, but must only be called after
151 // IsTokenReady() returns true.
152 CHECK(token_ready_);
153 if (token_name)
154 *token_name = token_name_;
155 if (user_pin)
156 *user_pin = user_pin_;
157 }
158
159 void RealTPMTokenInfoDelegate::OnPkcs11IsTpmTokenReady(
160 base::Callback<void(bool result)> callback,
161 DBusMethodCallStatus call_status,
162 bool is_tpm_token_ready) const {
163 if (call_status != DBUS_METHOD_CALL_SUCCESS || !is_tpm_token_ready) {
164 callback.Run(false);
165 return;
166 }
167
168 // Retrieve token_name_ and user_pin_ here since they will never change
169 // and CryptohomeClient calls are not thread safe.
170 DBusThreadManager::Get()->GetCryptohomeClient()->Pkcs11GetTpmTokenInfo(
171 base::Bind(&RealTPMTokenInfoDelegate::OnPkcs11GetTpmTokenInfo,
172 weak_ptr_factory_.GetWeakPtr(),
173 callback));
174 }
175
176 void RealTPMTokenInfoDelegate::OnPkcs11GetTpmTokenInfo(
177 base::Callback<void(bool result)> callback,
178 DBusMethodCallStatus call_status,
179 const std::string& token_name,
180 const std::string& user_pin) const {
181 if (call_status == DBUS_METHOD_CALL_SUCCESS) {
182 token_name_ = token_name;
183 user_pin_ = user_pin;
184 token_ready_ = true;
185 }
186 callback.Run(token_ready_);
187 }
188
189 } // namespace 98 } // namespace
190 99
191 ////////////////////////////////////////////////////////////////////////////// 100 //////////////////////////////////////////////////////////////////////////////
192 101
193 // base::Unretained(this) in the class is safe. By the time this object is 102 // base::Unretained(this) in the class is safe. By the time this object is
194 // deleted as part of CrosLibrary, the DB thread and the UI message loop 103 // deleted as part of CrosLibrary, the DB thread and the UI message loop
195 // are already terminated. 104 // are already terminated.
196 class CertLibraryImpl 105 class CertLibraryImpl
197 : public CertLibrary, 106 : public CertLibrary,
198 public net::CertDatabase::Observer { 107 public net::CertDatabase::Observer {
199 public: 108 public:
200 typedef ObserverListThreadSafe<CertLibrary::Observer> CertLibraryObserverList; 109 typedef ObserverListThreadSafe<CertLibrary::Observer> CertLibraryObserverList;
201 110
202 CertLibraryImpl() : 111 CertLibraryImpl() :
203 observer_list_(new CertLibraryObserverList), 112 observer_list_(new CertLibraryObserverList),
113 tpm_token_ready_(false),
204 user_logged_in_(false), 114 user_logged_in_(false),
205 certificates_requested_(false), 115 certificates_requested_(false),
206 certificates_loaded_(false), 116 certificates_loaded_(false),
207 key_store_loaded_(false), 117 key_store_loaded_(false),
208 ALLOW_THIS_IN_INITIALIZER_LIST(certs_(this)), 118 ALLOW_THIS_IN_INITIALIZER_LIST(certs_(this)),
209 ALLOW_THIS_IN_INITIALIZER_LIST(user_certs_(this)), 119 ALLOW_THIS_IN_INITIALIZER_LIST(user_certs_(this)),
210 ALLOW_THIS_IN_INITIALIZER_LIST(server_certs_(this)), 120 ALLOW_THIS_IN_INITIALIZER_LIST(server_certs_(this)),
211 ALLOW_THIS_IN_INITIALIZER_LIST(server_ca_certs_(this)), 121 ALLOW_THIS_IN_INITIALIZER_LIST(server_ca_certs_(this)),
212 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { 122 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) {
213 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)) 123 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
214 << __FUNCTION__ << " should be called on UI thread.";
215 net::CertDatabase::AddObserver(this); 124 net::CertDatabase::AddObserver(this);
216 } 125 }
217 126
218 ~CertLibraryImpl() { 127 ~CertLibraryImpl() {
219 DCHECK(request_task_.is_null()); 128 DCHECK(request_task_.is_null());
220 net::CertDatabase::RemoveObserver(this); 129 net::CertDatabase::RemoveObserver(this);
221 } 130 }
222 131
223 // CertLibrary implementation. 132 // CertLibrary implementation.
224 virtual void AddObserver(CertLibrary::Observer* observer) OVERRIDE { 133 virtual void AddObserver(CertLibrary::Observer* observer) OVERRIDE {
(...skipping 14 matching lines...) Expand all
239 148
240 // Only load the Opencryptoki library into NSS if we have this switch. 149 // Only load the Opencryptoki library into NSS if we have this switch.
241 // TODO(gspencer): Remove this switch once cryptohomed work is finished: 150 // TODO(gspencer): Remove this switch once cryptohomed work is finished:
242 // http://crosbug.com/12295 and 12304 151 // http://crosbug.com/12295 and 12304
243 // Note: ChromeOS login with or without loginmanager will crash when 152 // Note: ChromeOS login with or without loginmanager will crash when
244 // the CertLibrary is not there (http://crosbug.com/121456). Before removing 153 // the CertLibrary is not there (http://crosbug.com/121456). Before removing
245 // make sure that that case still works. 154 // make sure that that case still works.
246 if (CommandLine::ForCurrentProcess()->HasSwitch( 155 if (CommandLine::ForCurrentProcess()->HasSwitch(
247 switches::kLoadOpencryptoki) || 156 switches::kLoadOpencryptoki) ||
248 CommandLine::ForCurrentProcess()->HasSwitch(switches::kStubCros)) { 157 CommandLine::ForCurrentProcess()->HasSwitch(switches::kStubCros)) {
249 crypto::EnableTPMTokenForNSS(new RealTPMTokenInfoDelegate()); 158 crypto::EnableTPMTokenForNSS();
250 // Note: this calls crypto::EnsureTPMTokenReady() 159 // Note: this calls crypto::EnsureTPMTokenReady()
251 RequestCertificates(); 160 RequestCertificates();
252 } 161 }
253 key_store_loaded_ = true; 162 key_store_loaded_ = true;
254 } 163 }
255 164
256 virtual bool CertificatesLoading() const OVERRIDE { 165 virtual bool CertificatesLoading() const OVERRIDE {
257 return certificates_requested_ && !certificates_loaded_; 166 return certificates_requested_ && !certificates_loaded_;
258 } 167 }
259 168
260 virtual bool CertificatesLoaded() const OVERRIDE { 169 virtual bool CertificatesLoaded() const OVERRIDE {
261 return certificates_loaded_; 170 return certificates_loaded_;
262 } 171 }
263 172
264 virtual bool IsHardwareBacked() const OVERRIDE { 173 virtual bool IsHardwareBacked() const OVERRIDE {
265 return !tpm_token_name_.empty(); 174 return !tpm_token_name_.empty();
266 } 175 }
267 176
268 virtual const CertList& GetCertificates() const OVERRIDE { 177 virtual const CertList& GetCertificates() const OVERRIDE {
269 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)) 178 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
270 << __FUNCTION__ << " should be called on UI thread.";
271 return certs_; 179 return certs_;
272 } 180 }
273 181
274 virtual const CertList& GetUserCertificates() const OVERRIDE { 182 virtual const CertList& GetUserCertificates() const OVERRIDE {
275 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)) 183 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
276 << __FUNCTION__ << " should be called on UI thread.";
277 return user_certs_; 184 return user_certs_;
278 } 185 }
279 186
280 virtual const CertList& GetServerCertificates() const OVERRIDE { 187 virtual const CertList& GetServerCertificates() const OVERRIDE {
281 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)) 188 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
282 << __FUNCTION__ << " should be called on UI thread.";
283 return server_certs_; 189 return server_certs_;
284 } 190 }
285 191
286 virtual const CertList& GetCACertificates() const OVERRIDE { 192 virtual const CertList& GetCACertificates() const OVERRIDE {
287 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)) 193 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
288 << __FUNCTION__ << " should be called on UI thread.";
289 return server_ca_certs_; 194 return server_ca_certs_;
290 } 195 }
291 196
292 virtual std::string EncryptToken(const std::string& token) OVERRIDE { 197 virtual std::string EncryptToken(const std::string& token) OVERRIDE {
293 if (!LoadSupplementalUserKey()) 198 if (!LoadSupplementalUserKey())
294 return std::string(); 199 return std::string();
295 crypto::Encryptor encryptor; 200 crypto::Encryptor encryptor;
296 if (!encryptor.Init(supplemental_user_key_.get(), crypto::Encryptor::CTR, 201 if (!encryptor.Init(supplemental_user_key_.get(), crypto::Encryptor::CTR,
297 std::string())) 202 std::string()))
298 return std::string(); 203 return std::string();
(...skipping 14 matching lines...) Expand all
313 const std::string& encrypted_token_hex) OVERRIDE { 218 const std::string& encrypted_token_hex) OVERRIDE {
314 if (!LoadSupplementalUserKey()) 219 if (!LoadSupplementalUserKey())
315 return std::string(); 220 return std::string();
316 return DecryptTokenWithKey(supplemental_user_key_.get(), 221 return DecryptTokenWithKey(supplemental_user_key_.get(),
317 CrosLibrary::Get()->GetCryptohomeLibrary()->GetSystemSalt(), 222 CrosLibrary::Get()->GetCryptohomeLibrary()->GetSystemSalt(),
318 encrypted_token_hex); 223 encrypted_token_hex);
319 } 224 }
320 225
321 // net::CertDatabase::Observer implementation. Observer added on UI thread. 226 // net::CertDatabase::Observer implementation. Observer added on UI thread.
322 virtual void OnCertTrustChanged(const net::X509Certificate* cert) OVERRIDE { 227 virtual void OnCertTrustChanged(const net::X509Certificate* cert) OVERRIDE {
323 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)) 228 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
324 << __FUNCTION__ << " should be called on UI thread.";
325 } 229 }
326 230
327 virtual void OnUserCertAdded(const net::X509Certificate* cert) OVERRIDE { 231 virtual void OnUserCertAdded(const net::X509Certificate* cert) OVERRIDE {
328 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)) 232 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
329 << __FUNCTION__ << " should be called on UI thread.";
330 // Only load certificates if we have completed an initial request. 233 // Only load certificates if we have completed an initial request.
331 if (certificates_loaded_) { 234 if (certificates_loaded_) {
332 BrowserThread::PostTask( 235 BrowserThread::PostTask(
333 BrowserThread::DB, FROM_HERE, 236 BrowserThread::DB, FROM_HERE,
334 base::Bind(&CertLibraryImpl::LoadCertificates, 237 base::Bind(&CertLibraryImpl::LoadCertificates,
335 base::Unretained(this))); 238 base::Unretained(this)));
336 } 239 }
337 } 240 }
338 241
339 virtual void OnUserCertRemoved(const net::X509Certificate* cert) OVERRIDE { 242 virtual void OnUserCertRemoved(const net::X509Certificate* cert) OVERRIDE {
340 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)) 243 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
341 << __FUNCTION__ << " should be called on UI thread.";
342 // Only load certificates if we have completed an initial request. 244 // Only load certificates if we have completed an initial request.
343 if (certificates_loaded_) { 245 if (certificates_loaded_) {
344 BrowserThread::PostTask( 246 BrowserThread::PostTask(
345 BrowserThread::DB, FROM_HERE, 247 BrowserThread::DB, FROM_HERE,
346 base::Bind(&CertLibraryImpl::LoadCertificates, 248 base::Bind(&CertLibraryImpl::LoadCertificates,
347 base::Unretained(this))); 249 base::Unretained(this)));
348 } 250 }
349 } 251 }
350 252
351 virtual const std::string& GetTpmTokenName() const OVERRIDE { 253 virtual const std::string& GetTpmTokenName() const OVERRIDE {
352 return tpm_token_name_; 254 return tpm_token_name_;
353 } 255 }
354 256
355 private: 257 private:
356 void LoadCertificates() { 258 void LoadCertificates() {
357 VLOG(1) << " Loading Certificates."; 259 VLOG(1) << " Loading Certificates.";
358 // Certificate fetch occurs on the DB thread. 260 // Certificate fetch occurs on the DB thread.
359 CHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)) 261 CHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
360 << __FUNCTION__ << " should be called on DB thread.";
361 net::CertDatabase cert_db; 262 net::CertDatabase cert_db;
362 net::CertificateList* cert_list = new net::CertificateList(); 263 net::CertificateList* cert_list = new net::CertificateList();
363 cert_db.ListCerts(cert_list); 264 cert_db.ListCerts(cert_list);
364 // Pass the list to the UI thread to safely update the local lists. 265 // Pass the list to the UI thread to safely update the local lists.
365 BrowserThread::PostTask( 266 BrowserThread::PostTask(
366 BrowserThread::UI, FROM_HERE, 267 BrowserThread::UI, FROM_HERE,
367 base::Bind(&CertLibraryImpl::UpdateCertificates, 268 base::Bind(&CertLibraryImpl::UpdateCertificates,
368 base::Unretained(this), cert_list)); 269 base::Unretained(this), cert_list));
369 } 270 }
370 271
371 // Comparison functor for locale-sensitive sorting of certificates by name. 272 // Comparison functor for locale-sensitive sorting of certificates by name.
372 class CertNameComparator { 273 class CertNameComparator {
373 public: 274 public:
374 explicit CertNameComparator(icu::Collator* collator) 275 explicit CertNameComparator(icu::Collator* collator)
375 : collator_(collator) { } 276 : collator_(collator) { }
376 277
377 bool operator()(const scoped_refptr<net::X509Certificate>& lhs, 278 bool operator()(const scoped_refptr<net::X509Certificate>& lhs,
378 const scoped_refptr<net::X509Certificate>& rhs) const { 279 const scoped_refptr<net::X509Certificate>& rhs) const {
379 string16 lhs_name = GetDisplayString(lhs.get(), false); 280 string16 lhs_name = GetDisplayString(lhs.get(), false);
380 string16 rhs_name = GetDisplayString(rhs.get(), false); 281 string16 rhs_name = GetDisplayString(rhs.get(), false);
381 if (collator_ == NULL) 282 if (collator_ == NULL)
382 return lhs_name < rhs_name; 283 return lhs_name < rhs_name;
383 return l10n_util::CompareString16WithCollator( 284 return l10n_util::CompareString16WithCollator(
384 collator_, lhs_name, rhs_name) == UCOL_LESS; 285 collator_, lhs_name, rhs_name) == UCOL_LESS;
385 } 286 }
386 private: 287 private:
387 icu::Collator* collator_; 288 icu::Collator* collator_;
388 }; 289 };
389 290
390 void RequestCertificatesTask() {
391 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI))
392 << __FUNCTION__ << " should be called on UI thread.";
393 // Reset the task to the initial state so is_null() returns true.
394 request_task_ = base::Closure();
395 RequestCertificates();
396 }
397
398 void NotifyCertificatesLoaded(bool initial_load) { 291 void NotifyCertificatesLoaded(bool initial_load) {
399 observer_list_->Notify( 292 observer_list_->Notify(
400 &CertLibrary::Observer::OnCertificatesLoaded, initial_load); 293 &CertLibrary::Observer::OnCertificatesLoaded, initial_load);
401 } 294 }
402 295
403 // |cert_list| is allocated in LoadCertificates() and must be deleted here. 296 // |cert_list| is allocated in LoadCertificates() and must be deleted here.
404 void UpdateCertificates(net::CertificateList* cert_list) { 297 void UpdateCertificates(net::CertificateList* cert_list) {
405 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)) 298 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
406 << __FUNCTION__ << " should be called on UI thread.";
407 DCHECK(cert_list); 299 DCHECK(cert_list);
408 300
409 // Clear any existing certificates. 301 // Clear any existing certificates.
410 certs_.Clear(); 302 certs_.Clear();
411 server_ca_certs_.Clear(); 303 server_ca_certs_.Clear();
412 user_certs_.Clear(); 304 user_certs_.Clear();
413 server_certs_.Clear(); 305 server_certs_.Clear();
414 306
415 // Add certificates to the appropriate list. 307 // Add certificates to the appropriate list.
416 for (net::CertificateList::const_iterator iter = cert_list->begin(); 308 for (net::CertificateList::const_iterator iter = cert_list->begin();
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
477 } 369 }
478 if (!supplemental_user_key_.get()) { 370 if (!supplemental_user_key_.get()) {
479 supplemental_user_key_.reset(crypto::GetSupplementalUserKey()); 371 supplemental_user_key_.reset(crypto::GetSupplementalUserKey());
480 } 372 }
481 return supplemental_user_key_.get() != NULL; 373 return supplemental_user_key_.get() != NULL;
482 } 374 }
483 375
484 // Call this to start the certificate list initialization process. 376 // Call this to start the certificate list initialization process.
485 // Must be called from the UI thread. 377 // Must be called from the UI thread.
486 void RequestCertificates() { 378 void RequestCertificates() {
487 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)) 379 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
488 << __FUNCTION__ << " should be called on UI thread.";
489 380
490 certificates_requested_ = true; 381 certificates_requested_ = true;
491 382
492 if (!UserManager::Get()->IsUserLoggedIn()) { 383 if (!UserManager::Get()->IsUserLoggedIn()) {
493 // If we are not logged in, we cannot load any certificates. 384 // If we are not logged in, we cannot load any certificates.
494 // Set 'loaded' to true for the UI, since we are not waiting on loading. 385 // Set 'loaded' to true for the UI, since we are not waiting on loading.
495 LOG(WARNING) << "Requesting certificates before login."; 386 LOG(WARNING) << "Requesting certificates before login.";
496 certificates_loaded_ = true; 387 certificates_loaded_ = true;
497 supplemental_user_key_.reset(NULL); 388 supplemental_user_key_.reset(NULL);
498 return; 389 return;
499 } 390 }
500 391
501 if (!user_logged_in_) { 392 if (!user_logged_in_) {
502 user_logged_in_ = true; 393 user_logged_in_ = true;
503 certificates_loaded_ = false; 394 certificates_loaded_ = false;
504 supplemental_user_key_.reset(NULL); 395 supplemental_user_key_.reset(NULL);
505 } 396 }
506 397
507 VLOG(1) << "Requesting Certificates."; 398 VLOG(1) << "Requesting Certificates.";
508 DBusThreadManager::Get()->GetCryptohomeClient()->TpmIsEnabled( 399 DBusThreadManager::Get()->GetCryptohomeClient()->TpmIsEnabled(
509 base::Bind(&CertLibraryImpl::RequestCertificatesInternal, 400 base::Bind(&CertLibraryImpl::OnTpmIsEnabled,
510 weak_ptr_factory_.GetWeakPtr())); 401 weak_ptr_factory_.GetWeakPtr()));
511 } 402 }
512 403
513 // This method is used to implement RequestCertificates. 404 // This method is used to implement RequestCertificates.
514 void RequestCertificatesInternal(DBusMethodCallStatus call_status, 405 void OnTpmIsEnabled(DBusMethodCallStatus call_status, bool tpm_is_enabled) {
515 bool tpm_is_enabled) { 406 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
516 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI))
517 << __FUNCTION__ << " should be called on UI thread.";
518 if (call_status != DBUS_METHOD_CALL_SUCCESS || !tpm_is_enabled) { 407 if (call_status != DBUS_METHOD_CALL_SUCCESS || !tpm_is_enabled) {
519 // TPM is not enabled, so proceed with empty tpm token name. 408 // TPM is not enabled, so proceed with empty tpm token name.
520 VLOG(1) << "TPM not available."; 409 VLOG(1) << "TPM not available.";
521 BrowserThread::PostTask( 410 BrowserThread::PostTask(
522 BrowserThread::DB, FROM_HERE, 411 BrowserThread::DB, FROM_HERE,
523 base::Bind(&CertLibraryImpl::LoadCertificates, 412 base::Bind(&CertLibraryImpl::LoadCertificates,
524 base::Unretained(this))); 413 base::Unretained(this)));
525 } else if (crypto::IsTPMTokenReady()) { 414 } else if (tpm_token_ready_) {
526 // Need TPM token name to filter user certificates. 415 InitializeTPMToken();
527 const bool tpm_token_ready = true;
528 GetTPMTokenName(tpm_token_ready);
529 } else { 416 } else {
530 crypto::InitializeTPMToken( 417 DBusThreadManager::Get()->GetCryptohomeClient()->Pkcs11IsTpmTokenReady(
531 base::Bind(&CertLibraryImpl::GetTPMTokenName, 418 base::Bind(&CertLibraryImpl::OnPkcs11IsTpmTokenReady,
532 weak_ptr_factory_.GetWeakPtr())); 419 weak_ptr_factory_.GetWeakPtr()));
533 } 420 }
534 } 421 }
535 422
536 // This method is used to implement RequestCertificates. 423 // This method is used to implement RequestCertificates.
537 void GetTPMTokenName(bool tpm_token_ready) { 424 void OnPkcs11IsTpmTokenReady(DBusMethodCallStatus call_status,
538 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)) 425 bool is_tpm_token_ready) {
539 << __FUNCTION__ << " should be called on UI thread."; 426 if (call_status != DBUS_METHOD_CALL_SUCCESS || !is_tpm_token_ready) {
540 if (tpm_token_ready) { 427 MaybeRetryRequestCertificates();
541 std::string unused_pin;
542 crypto::GetTPMTokenInfo(&tpm_token_name_, &unused_pin);
543 } else {
544 VLOG(1) << "TPM token not ready.";
545 if (request_task_.is_null()) {
546 // Cryptohome does not notify us when the token is ready, so call
547 // this again after a delay.
548 request_task_ = base::Bind(&CertLibraryImpl::RequestCertificatesTask,
549 weak_ptr_factory_.GetWeakPtr());
550 BrowserThread::PostDelayedTask(
551 BrowserThread::UI, FROM_HERE, request_task_,
552 base::TimeDelta::FromMilliseconds(kRequestDelayMs));
553 }
554 return; 428 return;
555 } 429 }
556 430
431 // Retrieve token_name_ and user_pin_ here since they will never change
432 // and CryptohomeClient calls are not thread safe.
433 DBusThreadManager::Get()->GetCryptohomeClient()->Pkcs11GetTpmTokenInfo(
434 base::Bind(&CertLibraryImpl::OnPkcs11GetTpmTokenInfo,
435 weak_ptr_factory_.GetWeakPtr()));
436 }
437
438 // This method is used to implement RequestCertificates.
439 void OnPkcs11GetTpmTokenInfo(DBusMethodCallStatus call_status,
440 const std::string& token_name,
441 const std::string& user_pin) {
442 if (call_status != DBUS_METHOD_CALL_SUCCESS) {
443 MaybeRetryRequestCertificates();
444 return;
445 }
446 tpm_token_name_ = token_name;
447 tpm_user_pin_ = user_pin;
448 tpm_token_ready_ = true;
449
450 InitializeTPMToken();
451 }
452
453 // This method is used to implement RequestCertificates.
454 void InitializeTPMToken() {
455 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
456 if (!crypto::InitializeTPMToken(tpm_token_name_, tpm_user_pin_)) {
457 MaybeRetryRequestCertificates();
458 return;
459 }
460
557 // tpm_token_name_ is set, load the certificates on the DB thread. 461 // tpm_token_name_ is set, load the certificates on the DB thread.
558 BrowserThread::PostTask( 462 BrowserThread::PostTask(
559 BrowserThread::DB, FROM_HERE, 463 BrowserThread::DB, FROM_HERE,
560 base::Bind(&CertLibraryImpl::LoadCertificates, base::Unretained(this))); 464 base::Bind(&CertLibraryImpl::LoadCertificates, base::Unretained(this)));
561 } 465 }
562 466
467 void MaybeRetryRequestCertificates() {
468 if (!request_task_.is_null())
469 return;
470 // Cryptohome does not notify us when the token is ready, so call
471 // this again after a delay.
472 request_task_ = base::Bind(&CertLibraryImpl::RequestCertificatesTask,
473 weak_ptr_factory_.GetWeakPtr());
474 BrowserThread::PostDelayedTask(
475 BrowserThread::UI, FROM_HERE, request_task_,
476 base::TimeDelta::FromMilliseconds(kRequestDelayMs));
477 }
478
479 void RequestCertificatesTask() {
480 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
481 // Reset the task to the initial state so is_null() returns true.
482 request_task_ = base::Closure();
483 RequestCertificates();
484 }
485
563 // Observers. 486 // Observers.
564 const scoped_refptr<CertLibraryObserverList> observer_list_; 487 const scoped_refptr<CertLibraryObserverList> observer_list_;
565 488
566 // Active request task for re-requests while waiting for TPM init. 489 // Active request task for re-requests while waiting for TPM init.
567 base::Closure request_task_; 490 base::Closure request_task_;
568 491
492 bool tpm_token_ready_;
493
569 // Cached TPM token name. 494 // Cached TPM token name.
570 std::string tpm_token_name_; 495 std::string tpm_token_name_;
571 496
497 // Cached TPM user pin.
498 std::string tpm_user_pin_;
499
572 // Supplemental user key. 500 // Supplemental user key.
573 scoped_ptr<crypto::SymmetricKey> supplemental_user_key_; 501 scoped_ptr<crypto::SymmetricKey> supplemental_user_key_;
574 502
575 // Local state. 503 // Local state.
576 bool user_logged_in_; 504 bool user_logged_in_;
577 bool certificates_requested_; 505 bool certificates_requested_;
578 bool certificates_loaded_; 506 bool certificates_loaded_;
579 // The key store for the current user has been loaded. This flag is needed to 507 // The key store for the current user has been loaded. This flag is needed to
580 // ensure that the key store will not be loaded twice in the policy recovery 508 // ensure that the key store will not be loaded twice in the policy recovery
581 // "safe-mode". 509 // "safe-mode".
(...skipping 17 matching lines...) Expand all
599 527
600 // static 528 // static
601 CertLibrary* CertLibrary::GetImpl(bool stub) { 529 CertLibrary* CertLibrary::GetImpl(bool stub) {
602 // No libcros dependencies, so always return CertLibraryImpl() (no stub). 530 // No libcros dependencies, so always return CertLibraryImpl() (no stub).
603 return new CertLibraryImpl(); 531 return new CertLibraryImpl();
604 } 532 }
605 533
606 ////////////////////////////////////////////////////////////////////////////// 534 //////////////////////////////////////////////////////////////////////////////
607 535
608 net::X509Certificate* CertLibrary::CertList::GetCertificateAt(int index) const { 536 net::X509Certificate* CertLibrary::CertList::GetCertificateAt(int index) const {
609 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)) 537 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
610 << __FUNCTION__ << " should be called on UI thread.";
611 DCHECK_GE(index, 0); 538 DCHECK_GE(index, 0);
612 DCHECK_LT(index, static_cast<int>(list_.size())); 539 DCHECK_LT(index, static_cast<int>(list_.size()));
613 return list_[index].get(); 540 return list_[index].get();
614 } 541 }
615 542
616 string16 CertLibrary::CertList::GetDisplayStringAt(int index) const { 543 string16 CertLibrary::CertList::GetDisplayStringAt(int index) const {
617 net::X509Certificate* cert = GetCertificateAt(index); 544 net::X509Certificate* cert = GetCertificateAt(index);
618 bool hardware_backed = 545 bool hardware_backed =
619 !cert_library_->GetTpmTokenName().empty() && IsHardwareBackedAt(index); 546 !cert_library_->GetTpmTokenName().empty() && IsHardwareBackedAt(index);
620 return GetDisplayString(cert, hardware_backed); 547 return GetDisplayString(cert, hardware_backed);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
655 net::X509Certificate* cert = GetCertificateAt(index); 582 net::X509Certificate* cert = GetCertificateAt(index);
656 net::X509Certificate::OSCertHandle cert_handle = cert->os_cert_handle(); 583 net::X509Certificate::OSCertHandle cert_handle = cert->os_cert_handle();
657 std::string id = x509_certificate_model::GetPkcs11Id(cert_handle); 584 std::string id = x509_certificate_model::GetPkcs11Id(cert_handle);
658 if (id == pkcs11_id) 585 if (id == pkcs11_id)
659 return index; 586 return index;
660 } 587 }
661 return -1; // Not found. 588 return -1; // Not found.
662 } 589 }
663 590
664 } // chromeos 591 } // chromeos
OLDNEW
« no previous file with comments | « no previous file | crypto/nss_util.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698