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

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: _ 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') | crypto/nss_util.cc » ('J')
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))
(...skipping 25 matching lines...) Expand all
239 149
240 // Only load the Opencryptoki library into NSS if we have this switch. 150 // Only load the Opencryptoki library into NSS if we have this switch.
241 // TODO(gspencer): Remove this switch once cryptohomed work is finished: 151 // TODO(gspencer): Remove this switch once cryptohomed work is finished:
242 // http://crosbug.com/12295 and 12304 152 // http://crosbug.com/12295 and 12304
243 // Note: ChromeOS login with or without loginmanager will crash when 153 // Note: ChromeOS login with or without loginmanager will crash when
244 // the CertLibrary is not there (http://crosbug.com/121456). Before removing 154 // the CertLibrary is not there (http://crosbug.com/121456). Before removing
245 // make sure that that case still works. 155 // make sure that that case still works.
246 if (CommandLine::ForCurrentProcess()->HasSwitch( 156 if (CommandLine::ForCurrentProcess()->HasSwitch(
247 switches::kLoadOpencryptoki) || 157 switches::kLoadOpencryptoki) ||
248 CommandLine::ForCurrentProcess()->HasSwitch(switches::kStubCros)) { 158 CommandLine::ForCurrentProcess()->HasSwitch(switches::kStubCros)) {
249 crypto::EnableTPMTokenForNSS(new RealTPMTokenInfoDelegate()); 159 crypto::EnableTPMTokenForNSS();
Ryan Sleevi 2012/05/16 17:02:16 See comments in crypto/
250 // Note: this calls crypto::EnsureTPMTokenReady() 160 // Note: this calls crypto::EnsureTPMTokenReady()
251 RequestCertificates(); 161 RequestCertificates();
252 } 162 }
253 key_store_loaded_ = true; 163 key_store_loaded_ = true;
254 } 164 }
255 165
256 virtual bool CertificatesLoading() const OVERRIDE { 166 virtual bool CertificatesLoading() const OVERRIDE {
257 return certificates_requested_ && !certificates_loaded_; 167 return certificates_requested_ && !certificates_loaded_;
258 } 168 }
259 169
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
380 string16 rhs_name = GetDisplayString(rhs.get(), false); 290 string16 rhs_name = GetDisplayString(rhs.get(), false);
381 if (collator_ == NULL) 291 if (collator_ == NULL)
382 return lhs_name < rhs_name; 292 return lhs_name < rhs_name;
383 return l10n_util::CompareString16WithCollator( 293 return l10n_util::CompareString16WithCollator(
384 collator_, lhs_name, rhs_name) == UCOL_LESS; 294 collator_, lhs_name, rhs_name) == UCOL_LESS;
385 } 295 }
386 private: 296 private:
387 icu::Collator* collator_; 297 icu::Collator* collator_;
388 }; 298 };
389 299
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) { 300 void NotifyCertificatesLoaded(bool initial_load) {
399 observer_list_->Notify( 301 observer_list_->Notify(
400 &CertLibrary::Observer::OnCertificatesLoaded, initial_load); 302 &CertLibrary::Observer::OnCertificatesLoaded, initial_load);
401 } 303 }
402 304
403 // |cert_list| is allocated in LoadCertificates() and must be deleted here. 305 // |cert_list| is allocated in LoadCertificates() and must be deleted here.
404 void UpdateCertificates(net::CertificateList* cert_list) { 306 void UpdateCertificates(net::CertificateList* cert_list) {
405 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)) 307 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI))
406 << __FUNCTION__ << " should be called on UI thread."; 308 << __FUNCTION__ << " should be called on UI thread.";
407 DCHECK(cert_list); 309 DCHECK(cert_list);
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
499 } 401 }
500 402
501 if (!user_logged_in_) { 403 if (!user_logged_in_) {
502 user_logged_in_ = true; 404 user_logged_in_ = true;
503 certificates_loaded_ = false; 405 certificates_loaded_ = false;
504 supplemental_user_key_.reset(NULL); 406 supplemental_user_key_.reset(NULL);
505 } 407 }
506 408
507 VLOG(1) << "Requesting Certificates."; 409 VLOG(1) << "Requesting Certificates.";
508 DBusThreadManager::Get()->GetCryptohomeClient()->TpmIsEnabled( 410 DBusThreadManager::Get()->GetCryptohomeClient()->TpmIsEnabled(
509 base::Bind(&CertLibraryImpl::RequestCertificatesInternal, 411 base::Bind(&CertLibraryImpl::OnTpmIsEnabled,
510 weak_ptr_factory_.GetWeakPtr())); 412 weak_ptr_factory_.GetWeakPtr()));
511 } 413 }
512 414
513 // This method is used to implement RequestCertificates. 415 // This method is used to implement RequestCertificates.
514 void RequestCertificatesInternal(DBusMethodCallStatus call_status, 416 void OnTpmIsEnabled(DBusMethodCallStatus call_status, bool tpm_is_enabled) {
515 bool tpm_is_enabled) {
516 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)) 417 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI))
517 << __FUNCTION__ << " should be called on UI thread."; 418 << __FUNCTION__ << " should be called on UI thread.";
518 if (call_status != DBUS_METHOD_CALL_SUCCESS || !tpm_is_enabled) { 419 if (call_status != DBUS_METHOD_CALL_SUCCESS || !tpm_is_enabled) {
519 // TPM is not enabled, so proceed with empty tpm token name. 420 // TPM is not enabled, so proceed with empty tpm token name.
520 VLOG(1) << "TPM not available."; 421 VLOG(1) << "TPM not available.";
521 BrowserThread::PostTask( 422 BrowserThread::PostTask(
522 BrowserThread::DB, FROM_HERE, 423 BrowserThread::DB, FROM_HERE,
523 base::Bind(&CertLibraryImpl::LoadCertificates, 424 base::Bind(&CertLibraryImpl::LoadCertificates,
524 base::Unretained(this))); 425 base::Unretained(this)));
525 } else if (crypto::IsTPMTokenReady()) { 426 } else if (tpm_token_ready_) {
526 // Need TPM token name to filter user certificates. 427 InitializeTPMToken();
527 const bool tpm_token_ready = true;
528 GetTPMTokenName(tpm_token_ready);
529 } else { 428 } else {
530 crypto::InitializeTPMToken( 429 DBusThreadManager::Get()->GetCryptohomeClient()->Pkcs11IsTpmTokenReady(
531 base::Bind(&CertLibraryImpl::GetTPMTokenName, 430 base::Bind(&CertLibraryImpl::OnPkcs11IsTpmTokenReady,
532 weak_ptr_factory_.GetWeakPtr())); 431 weak_ptr_factory_.GetWeakPtr()));
533 } 432 }
534 } 433 }
535 434
536 // This method is used to implement RequestCertificates. 435 // This method is used to implement RequestCertificates.
537 void GetTPMTokenName(bool tpm_token_ready) { 436 void OnPkcs11IsTpmTokenReady(DBusMethodCallStatus call_status,
538 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)) 437 bool is_tpm_token_ready) {
539 << __FUNCTION__ << " should be called on UI thread."; 438 if (call_status != DBUS_METHOD_CALL_SUCCESS || !is_tpm_token_ready) {
540 if (tpm_token_ready) { 439 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; 440 return;
555 } 441 }
556 442
443 // Retrieve token_name_ and user_pin_ here since they will never change
444 // and CryptohomeClient calls are not thread safe.
445 DBusThreadManager::Get()->GetCryptohomeClient()->Pkcs11GetTpmTokenInfo(
446 base::Bind(&CertLibraryImpl::OnPkcs11GetTpmTokenInfo,
447 weak_ptr_factory_.GetWeakPtr()));
448 }
449
450 // This method is used to implement RequestCertificates.
451 void OnPkcs11GetTpmTokenInfo(DBusMethodCallStatus call_status,
452 const std::string& token_name,
453 const std::string& user_pin) {
454 if (call_status != DBUS_METHOD_CALL_SUCCESS) {
455 MaybeRetryRequestCertificates();
456 return;
457 }
458 tpm_token_name_ = token_name;
459 tpm_user_pin_ = user_pin;
460 tpm_token_ready_ = true;
461
462 InitializeTPMToken();
463 }
464
465 // This method is used to implement RequestCertificates.
466 void InitializeTPMToken() {
467 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI))
468 << __FUNCTION__ << " should be called on UI thread.";
Ryan Sleevi 2012/05/16 17:02:16 nit: These strings will not get optimized out in a
hashimoto 2012/05/17 07:35:07 Agree, CHECK itself is sufficient, removed the str
469 if (!crypto::InitializeTPMToken(tpm_token_name_, tpm_user_pin_)) {
470 MaybeRetryRequestCertificates();
471 return;
472 }
473
557 // tpm_token_name_ is set, load the certificates on the DB thread. 474 // tpm_token_name_ is set, load the certificates on the DB thread.
558 BrowserThread::PostTask( 475 BrowserThread::PostTask(
559 BrowserThread::DB, FROM_HERE, 476 BrowserThread::DB, FROM_HERE,
560 base::Bind(&CertLibraryImpl::LoadCertificates, base::Unretained(this))); 477 base::Bind(&CertLibraryImpl::LoadCertificates, base::Unretained(this)));
561 } 478 }
562 479
480 void MaybeRetryRequestCertificates() {
481 if (!request_task_.is_null())
482 return;
483 // Cryptohome does not notify us when the token is ready, so call
484 // this again after a delay.
485 request_task_ = base::Bind(&CertLibraryImpl::RequestCertificatesTask,
486 weak_ptr_factory_.GetWeakPtr());
487 BrowserThread::PostDelayedTask(
488 BrowserThread::UI, FROM_HERE, request_task_,
489 base::TimeDelta::FromMilliseconds(kRequestDelayMs));
490 }
491
492 void RequestCertificatesTask() {
493 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI))
494 << __FUNCTION__ << " should be called on UI thread.";
495 // Reset the task to the initial state so is_null() returns true.
496 request_task_ = base::Closure();
497 RequestCertificates();
498 }
499
563 // Observers. 500 // Observers.
564 const scoped_refptr<CertLibraryObserverList> observer_list_; 501 const scoped_refptr<CertLibraryObserverList> observer_list_;
565 502
566 // Active request task for re-requests while waiting for TPM init. 503 // Active request task for re-requests while waiting for TPM init.
567 base::Closure request_task_; 504 base::Closure request_task_;
568 505
506 bool tpm_token_ready_;
507
569 // Cached TPM token name. 508 // Cached TPM token name.
570 std::string tpm_token_name_; 509 std::string tpm_token_name_;
571 510
511 // Cached TPM user pin.
512 std::string tpm_user_pin_;
513
572 // Supplemental user key. 514 // Supplemental user key.
573 scoped_ptr<crypto::SymmetricKey> supplemental_user_key_; 515 scoped_ptr<crypto::SymmetricKey> supplemental_user_key_;
574 516
575 // Local state. 517 // Local state.
576 bool user_logged_in_; 518 bool user_logged_in_;
577 bool certificates_requested_; 519 bool certificates_requested_;
578 bool certificates_loaded_; 520 bool certificates_loaded_;
579 // The key store for the current user has been loaded. This flag is needed to 521 // 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 522 // ensure that the key store will not be loaded twice in the policy recovery
581 // "safe-mode". 523 // "safe-mode".
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
655 net::X509Certificate* cert = GetCertificateAt(index); 597 net::X509Certificate* cert = GetCertificateAt(index);
656 net::X509Certificate::OSCertHandle cert_handle = cert->os_cert_handle(); 598 net::X509Certificate::OSCertHandle cert_handle = cert->os_cert_handle();
657 std::string id = x509_certificate_model::GetPkcs11Id(cert_handle); 599 std::string id = x509_certificate_model::GetPkcs11Id(cert_handle);
658 if (id == pkcs11_id) 600 if (id == pkcs11_id)
659 return index; 601 return index;
660 } 602 }
661 return -1; // Not found. 603 return -1; // Not found.
662 } 604 }
663 605
664 } // chromeos 606 } // chromeos
OLDNEW
« no previous file with comments | « no previous file | crypto/nss_util.h » ('j') | crypto/nss_util.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698