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

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

Issue 14522013: Separate cert loading code from CertLibrary and move to src/chromeos (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 7 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
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/chromeos/chromeos_version.h" 9 #include "base/chromeos/chromeos_version.h"
10 #include "base/command_line.h" 10 #include "base/command_line.h"
(...skipping 11 matching lines...) Expand all
22 #include "chromeos/login/login_state.h" 22 #include "chromeos/login/login_state.h"
23 #include "content/public/browser/browser_thread.h" 23 #include "content/public/browser/browser_thread.h"
24 #include "crypto/nss_util.h" 24 #include "crypto/nss_util.h"
25 #include "grit/generated_resources.h" 25 #include "grit/generated_resources.h"
26 #include "net/cert/cert_database.h" 26 #include "net/cert/cert_database.h"
27 #include "net/cert/nss_cert_database.h" 27 #include "net/cert/nss_cert_database.h"
28 #include "third_party/icu/public/i18n/unicode/coll.h" // icu::Collator 28 #include "third_party/icu/public/i18n/unicode/coll.h" // icu::Collator
29 #include "ui/base/l10n/l10n_util.h" 29 #include "ui/base/l10n/l10n_util.h"
30 #include "ui/base/l10n/l10n_util_collator.h" 30 #include "ui/base/l10n/l10n_util_collator.h"
31 31
32 using content::BrowserThread;
33
34 namespace chromeos { 32 namespace chromeos {
35 33
36 namespace { 34 namespace {
37 35
38 // Root CA certificates that are built into Chrome use this token name. 36 // Root CA certificates that are built into Chrome use this token name.
39 const char kRootCertificateTokenName[] = "Builtin Object Token"; 37 const char kRootCertificateTokenName[] = "Builtin Object Token";
40 38
41 // Delay between certificate requests while waiting for TPM/PKCS#11 init.
42 const int kRequestDelayMs = 500;
43
44 string16 GetDisplayString(net::X509Certificate* cert, bool hardware_backed) { 39 string16 GetDisplayString(net::X509Certificate* cert, bool hardware_backed) {
45 std::string org; 40 std::string org;
46 if (!cert->subject().organization_names.empty()) 41 if (!cert->subject().organization_names.empty())
47 org = cert->subject().organization_names[0]; 42 org = cert->subject().organization_names[0];
48 if (org.empty()) 43 if (org.empty())
49 org = cert->subject().GetDisplayName(); 44 org = cert->subject().GetDisplayName();
50 string16 issued_by = UTF8ToUTF16( 45 string16 issued_by = UTF8ToUTF16(
51 x509_certificate_model::GetIssuerCommonName(cert->os_cert_handle(), 46 x509_certificate_model::GetIssuerCommonName(cert->os_cert_handle(),
52 org)); // alternative text 47 org)); // alternative text
53 string16 issued_to = UTF8ToUTF16( 48 string16 issued_to = UTF8ToUTF16(
54 x509_certificate_model::GetCertNameOrNickname(cert->os_cert_handle())); 49 x509_certificate_model::GetCertNameOrNickname(cert->os_cert_handle()));
55 50
56 if (hardware_backed) { 51 if (hardware_backed) {
57 return l10n_util::GetStringFUTF16( 52 return l10n_util::GetStringFUTF16(
58 IDS_CERT_MANAGER_HARDWARE_BACKED_KEY_FORMAT_LONG, 53 IDS_CERT_MANAGER_HARDWARE_BACKED_KEY_FORMAT_LONG,
59 issued_by, 54 issued_by,
60 issued_to, 55 issued_to,
61 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_HARDWARE_BACKED)); 56 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_HARDWARE_BACKED));
62 } else { 57 } else {
63 return l10n_util::GetStringFUTF16( 58 return l10n_util::GetStringFUTF16(
64 IDS_CERT_MANAGER_KEY_FORMAT_LONG, 59 IDS_CERT_MANAGER_KEY_FORMAT_LONG,
65 issued_by, 60 issued_by,
66 issued_to); 61 issued_to);
67 } 62 }
68 } 63 }
69 64
70 } // namespace 65 } // namespace
71 66
72 ////////////////////////////////////////////////////////////////////////////// 67 class CertNameComparator {
73
74 // base::Unretained(this) in the class is safe. By the time this object is
75 // deleted as part of CrosLibrary, the DB thread and the UI message loop
76 // are already terminated.
77 class CertLibraryImpl
78 : public CertLibrary,
79 public net::CertDatabase::Observer {
80 public: 68 public:
81 typedef ObserverListThreadSafe<CertLibrary::Observer> CertLibraryObserverList; 69 explicit CertNameComparator(icu::Collator* collator)
82 70 : collator_(collator) {
83 CertLibraryImpl() :
84 observer_list_(new CertLibraryObserverList),
85 tpm_token_ready_(false),
86 user_logged_in_(false),
87 certificates_requested_(false),
88 certificates_loaded_(false),
89 key_store_loaded_(false),
90 certs_(this),
91 user_certs_(this),
92 server_certs_(this),
93 server_ca_certs_(this),
94 weak_ptr_factory_(this) {
95 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
96 net::CertDatabase::GetInstance()->AddObserver(this);
97 } 71 }
98 72
99 virtual ~CertLibraryImpl() { 73 bool operator()(const scoped_refptr<net::X509Certificate>& lhs,
100 DCHECK(request_task_.is_null()); 74 const scoped_refptr<net::X509Certificate>& rhs) const {
101 net::CertDatabase::GetInstance()->RemoveObserver(this); 75 string16 lhs_name = GetDisplayString(lhs.get(), false);
102 } 76 string16 rhs_name = GetDisplayString(rhs.get(), false);
103 77 if (collator_ == NULL)
104 // CertLibrary implementation. 78 return lhs_name < rhs_name;
105 virtual void AddObserver(CertLibrary::Observer* observer) OVERRIDE { 79 return base::i18n::CompareString16WithCollator(
106 observer_list_->AddObserver(observer); 80 collator_, lhs_name, rhs_name) == UCOL_LESS;
107 }
108
109 virtual void RemoveObserver(CertLibrary::Observer* observer) OVERRIDE {
110 observer_list_->RemoveObserver(observer);
111 }
112
113 virtual void LoadKeyStore() OVERRIDE {
114 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
115 if (key_store_loaded_)
116 return;
117
118 // Ensure we've opened the real user's key/certificate database.
119 crypto::OpenPersistentNSSDB();
120
121 if (base::chromeos::IsRunningOnChromeOS() ||
122 CommandLine::ForCurrentProcess()->HasSwitch(
123 switches::kLoadOpencryptoki)) {
124 crypto::EnableTPMTokenForNSS();
125 // Note: this calls crypto::EnsureTPMTokenReady()
126 RequestCertificates();
127 }
128 key_store_loaded_ = true;
129 }
130
131 virtual bool CertificatesLoading() const OVERRIDE {
132 return certificates_requested_ && !certificates_loaded_;
133 }
134
135 virtual bool CertificatesLoaded() const OVERRIDE {
136 return certificates_loaded_;
137 }
138
139 virtual bool IsHardwareBacked() const OVERRIDE {
140 return !tpm_token_name_.empty();
141 }
142
143 virtual const CertList& GetCertificates() const OVERRIDE {
144 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
145 return certs_;
146 }
147
148 virtual const CertList& GetUserCertificates() const OVERRIDE {
149 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
150 return user_certs_;
151 }
152
153 virtual const CertList& GetServerCertificates() const OVERRIDE {
154 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
155 return server_certs_;
156 }
157
158 virtual const CertList& GetCACertificates() const OVERRIDE {
159 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
160 return server_ca_certs_;
161 }
162
163 // net::CertDatabase::Observer implementation. Observer added on UI thread.
164 virtual void OnCertTrustChanged(const net::X509Certificate* cert) OVERRIDE {
165 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
166 }
167
168 virtual void OnCertAdded(const net::X509Certificate* cert) OVERRIDE {
169 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
170 // Only load certificates if we have completed an initial request.
171 if (certificates_loaded_) {
172 BrowserThread::PostTask(
173 BrowserThread::DB, FROM_HERE,
174 base::Bind(&CertLibraryImpl::LoadCertificates,
175 base::Unretained(this)));
176 }
177 }
178
179 virtual void OnCertRemoved(const net::X509Certificate* cert) OVERRIDE {
180 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
181 // Only load certificates if we have completed an initial request.
182 if (certificates_loaded_) {
183 BrowserThread::PostTask(
184 BrowserThread::DB, FROM_HERE,
185 base::Bind(&CertLibraryImpl::LoadCertificates,
186 base::Unretained(this)));
187 }
188 }
189
190 virtual const std::string& GetTpmTokenName() const OVERRIDE {
191 return tpm_token_name_;
192 } 81 }
193 82
194 private: 83 private:
195 void LoadCertificates() { 84 icu::Collator* collator_;
196 VLOG(1) << " Loading Certificates.";
197 // Certificate fetch occurs on the DB thread.
198 CHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
199 net::CertificateList* cert_list = new net::CertificateList();
200 net::NSSCertDatabase::GetInstance()->ListCerts(cert_list);
201 // Pass the list to the UI thread to safely update the local lists.
202 BrowserThread::PostTask(
203 BrowserThread::UI, FROM_HERE,
204 base::Bind(&CertLibraryImpl::UpdateCertificates,
205 base::Unretained(this), cert_list));
206 }
207
208 // Comparison functor for locale-sensitive sorting of certificates by name.
209 class CertNameComparator {
210 public:
211 explicit CertNameComparator(icu::Collator* collator)
212 : collator_(collator) { }
213
214 bool operator()(const scoped_refptr<net::X509Certificate>& lhs,
215 const scoped_refptr<net::X509Certificate>& rhs) const {
216 string16 lhs_name = GetDisplayString(lhs.get(), false);
217 string16 rhs_name = GetDisplayString(rhs.get(), false);
218 if (collator_ == NULL)
219 return lhs_name < rhs_name;
220 return base::i18n::CompareString16WithCollator(
221 collator_, lhs_name, rhs_name) == UCOL_LESS;
222 }
223 private:
224 icu::Collator* collator_;
225 };
226
227 void NotifyCertificatesLoaded(bool initial_load) {
228 observer_list_->Notify(
229 &CertLibrary::Observer::OnCertificatesLoaded, initial_load);
230 }
231
232 // |cert_list| is allocated in LoadCertificates() and must be deleted here.
233 void UpdateCertificates(net::CertificateList* cert_list) {
234 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
235 DCHECK(cert_list);
236
237 // Clear any existing certificates.
238 certs_.Clear();
239 server_ca_certs_.Clear();
240 user_certs_.Clear();
241 server_certs_.Clear();
242
243 // Add certificates to the appropriate list.
244 for (net::CertificateList::const_iterator iter = cert_list->begin();
245 iter != cert_list->end(); ++iter) {
246 certs_.Append(iter->get());
247 net::X509Certificate::OSCertHandle cert_handle =
248 iter->get()->os_cert_handle();
249 net::CertType type = x509_certificate_model::GetType(cert_handle);
250 switch (type) {
251 case net::USER_CERT:
252 user_certs_.Append(iter->get());
253 break;
254 case net::SERVER_CERT:
255 server_certs_.Append(iter->get());
256 break;
257 case net::CA_CERT: {
258 // Exclude root CA certificates that are built into Chrome.
259 std::string token_name =
260 x509_certificate_model::GetTokenName(cert_handle);
261 if (token_name != kRootCertificateTokenName)
262 server_ca_certs_.Append(iter->get());
263 break;
264 }
265 default:
266 break;
267 }
268 }
269
270 // Perform locale-sensitive sorting by certificate name.
271 scoped_ptr<icu::Collator> collator;
272 UErrorCode error = U_ZERO_ERROR;
273 collator.reset(
274 icu::Collator::createInstance(
275 icu::Locale(g_browser_process->GetApplicationLocale().c_str()),
276 error));
277 if (U_FAILURE(error))
278 collator.reset(NULL);
279 CertNameComparator cert_name_comparator(collator.get());
280 std::sort(user_certs_.list().begin(), user_certs_.list().end(),
281 cert_name_comparator);
282 std::sort(server_certs_.list().begin(), server_certs_.list().end(),
283 cert_name_comparator);
284 std::sort(server_ca_certs_.list().begin(), server_ca_certs_.list().end(),
285 cert_name_comparator);
286
287 // cert_list is allocated in LoadCertificates(), then released here.
288 delete cert_list;
289
290 // Set loaded state and notify observers.
291 if (!certificates_loaded_) {
292 certificates_loaded_ = true;
293 NotifyCertificatesLoaded(true);
294 } else {
295 NotifyCertificatesLoaded(false);
296 }
297 }
298
299 // Call this to start the certificate list initialization process.
300 // Must be called from the UI thread.
301 void RequestCertificates() {
302 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
303
304 certificates_requested_ = true;
305
306 if (!LoginState::Get()->IsUserLoggedIn()) {
307 // If we are not logged in, we cannot load any certificates.
308 // Set 'loaded' to true for the UI, since we are not waiting on loading.
309 LOG(WARNING) << "Requesting certificates before login.";
310 certificates_loaded_ = true;
311 return;
312 }
313
314 if (!user_logged_in_) {
315 user_logged_in_ = true;
316 certificates_loaded_ = false;
317 }
318
319 VLOG(1) << "Requesting Certificates.";
320 DBusThreadManager::Get()->GetCryptohomeClient()->TpmIsEnabled(
321 base::Bind(&CertLibraryImpl::OnTpmIsEnabled,
322 weak_ptr_factory_.GetWeakPtr()));
323 }
324
325 // This method is used to implement RequestCertificates.
326 void OnTpmIsEnabled(DBusMethodCallStatus call_status, bool tpm_is_enabled) {
327 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
328 if (call_status != DBUS_METHOD_CALL_SUCCESS || !tpm_is_enabled) {
329 // TPM is not enabled, so proceed with empty tpm token name.
330 VLOG(1) << "TPM not available.";
331 BrowserThread::PostTask(
332 BrowserThread::DB, FROM_HERE,
333 base::Bind(&CertLibraryImpl::LoadCertificates,
334 base::Unretained(this)));
335 } else if (tpm_token_ready_) {
336 InitializeTPMToken();
337 } else {
338 DBusThreadManager::Get()->GetCryptohomeClient()->Pkcs11IsTpmTokenReady(
339 base::Bind(&CertLibraryImpl::OnPkcs11IsTpmTokenReady,
340 weak_ptr_factory_.GetWeakPtr()));
341 }
342 }
343
344 // This method is used to implement RequestCertificates.
345 void OnPkcs11IsTpmTokenReady(DBusMethodCallStatus call_status,
346 bool is_tpm_token_ready) {
347 if (call_status != DBUS_METHOD_CALL_SUCCESS || !is_tpm_token_ready) {
348 MaybeRetryRequestCertificates();
349 return;
350 }
351
352 // Retrieve token_name_ and user_pin_ here since they will never change
353 // and CryptohomeClient calls are not thread safe.
354 DBusThreadManager::Get()->GetCryptohomeClient()->Pkcs11GetTpmTokenInfo(
355 base::Bind(&CertLibraryImpl::OnPkcs11GetTpmTokenInfo,
356 weak_ptr_factory_.GetWeakPtr()));
357 }
358
359 // This method is used to implement RequestCertificates.
360 void OnPkcs11GetTpmTokenInfo(DBusMethodCallStatus call_status,
361 const std::string& token_name,
362 const std::string& user_pin) {
363 if (call_status != DBUS_METHOD_CALL_SUCCESS) {
364 MaybeRetryRequestCertificates();
365 return;
366 }
367 tpm_token_name_ = token_name;
368 tpm_user_pin_ = user_pin;
369 tpm_token_ready_ = true;
370
371 InitializeTPMToken();
372 }
373
374 // This method is used to implement RequestCertificates.
375 void InitializeTPMToken() {
376 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
377 if (!crypto::InitializeTPMToken(tpm_token_name_, tpm_user_pin_)) {
378 MaybeRetryRequestCertificates();
379 return;
380 }
381
382 // tpm_token_name_ is set, load the certificates on the DB thread.
383 BrowserThread::PostTask(
384 BrowserThread::DB, FROM_HERE,
385 base::Bind(&CertLibraryImpl::LoadCertificates, base::Unretained(this)));
386 }
387
388 void MaybeRetryRequestCertificates() {
389 if (!request_task_.is_null())
390 return;
391 // Cryptohome does not notify us when the token is ready, so call
392 // this again after a delay.
393 request_task_ = base::Bind(&CertLibraryImpl::RequestCertificatesTask,
394 weak_ptr_factory_.GetWeakPtr());
395 BrowserThread::PostDelayedTask(
396 BrowserThread::UI, FROM_HERE, request_task_,
397 base::TimeDelta::FromMilliseconds(kRequestDelayMs));
398 }
399
400 void RequestCertificatesTask() {
401 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
402 // Reset the task to the initial state so is_null() returns true.
403 request_task_ = base::Closure();
404 RequestCertificates();
405 }
406
407 // Observers.
408 const scoped_refptr<CertLibraryObserverList> observer_list_;
409
410 // Active request task for re-requests while waiting for TPM init.
411 base::Closure request_task_;
412
413 bool tpm_token_ready_;
414
415 // Cached TPM token name.
416 std::string tpm_token_name_;
417
418 // Cached TPM user pin.
419 std::string tpm_user_pin_;
420
421 // Local state.
422 bool user_logged_in_;
423 bool certificates_requested_;
424 bool certificates_loaded_;
425 // The key store for the current user has been loaded. This flag is needed to
426 // ensure that the key store will not be loaded twice in the policy recovery
427 // "safe-mode".
428 bool key_store_loaded_;
429
430 // Certificates.
431 CertList certs_;
432 CertList user_certs_;
433 CertList server_certs_;
434 CertList server_ca_certs_;
435
436 base::WeakPtrFactory<CertLibraryImpl> weak_ptr_factory_;
437
438 DISALLOW_COPY_AND_ASSIGN(CertLibraryImpl);
439 }; 85 };
440 86
441 ////////////////////////////////////////////////////////////////////////////// 87 static CertLibrary* g_cert_library = NULL;
442 88
443 class CertLibraryImplStub : public CertLibrary { 89 // static
444 public: 90 void CertLibrary::Initialize() {
445 CertLibraryImplStub() 91 CHECK(!g_cert_library);
446 : token_name_("StubToken"), 92 g_cert_library = new CertLibrary();
447 cert_list_(this) {
448 }
449 virtual ~CertLibraryImplStub() {}
450
451 virtual void AddObserver(Observer* observer) OVERRIDE {}
452 virtual void RemoveObserver(Observer* observer) OVERRIDE {}
453 virtual void LoadKeyStore() OVERRIDE {}
454 virtual bool CertificatesLoading() const OVERRIDE {
455 return false;
456 }
457 virtual bool CertificatesLoaded() const OVERRIDE {
458 return true;
459 }
460 virtual bool IsHardwareBacked() const OVERRIDE {
461 return false;
462 }
463 virtual const std::string& GetTpmTokenName() const OVERRIDE {
464 return token_name_;
465 }
466 virtual const CertList& GetCertificates() const OVERRIDE {
467 return cert_list_;
468 }
469 virtual const CertList& GetUserCertificates() const OVERRIDE {
470 return cert_list_;
471 }
472 virtual const CertList& GetServerCertificates() const OVERRIDE {
473 return cert_list_;
474 }
475 virtual const CertList& GetCACertificates() const OVERRIDE {
476 return cert_list_;
477 }
478
479 private:
480 std::string token_name_;
481 CertList cert_list_;
482
483 DISALLOW_COPY_AND_ASSIGN(CertLibraryImplStub);
484 };
485
486 //////////////////////////////////////////////////////////////////////////////
487
488 CertLibrary::~CertLibrary() {
489 } 93 }
490 94
491 // static 95 // static
492 CertLibrary* CertLibrary::GetImpl(bool stub) { 96 void CertLibrary::Shutdown() {
493 // TODO(stevenjb): Disassociate CertLibrary from CrosLibrary entirely. 97 CHECK(g_cert_library);
494 // crbug.com/133752 98 delete g_cert_library;
495 if (stub) 99 g_cert_library = NULL;
496 return new CertLibraryImplStub();
497 return new CertLibraryImpl();
498 } 100 }
499 101
500 ////////////////////////////////////////////////////////////////////////////// 102 // static
501 103 CertLibrary* CertLibrary::Get() {
502 CertLibrary::CertList::CertList(CertLibrary* library) 104 CHECK(g_cert_library) << "CertLibrary::Get() called before Initialize()";
503 : cert_library_(library) { 105 return g_cert_library;
504 } 106 }
505 107
506 CertLibrary::CertList::~CertList() {} 108 // static
507 109 bool CertLibrary::IsInitialized() {
508 net::X509Certificate* CertLibrary::CertList::GetCertificateAt(int index) const { 110 return g_cert_library;
509 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
510 DCHECK_GE(index, 0);
511 DCHECK_LT(index, static_cast<int>(list_.size()));
512 return list_[index].get();
513 } 111 }
514 112
515 string16 CertLibrary::CertList::GetDisplayStringAt(int index) const { 113 CertLibrary::CertLibrary() {
516 net::X509Certificate* cert = GetCertificateAt(index); 114 CertLoader::Get()->AddObserver(this);
517 bool hardware_backed = 115 }
518 !cert_library_->GetTpmTokenName().empty() && IsHardwareBackedAt(index); 116
117 CertLibrary::~CertLibrary() {
118 CertLoader::Get()->RemoveObserver(this);
119 }
120
121 void CertLibrary::AddObserver(CertLibrary::Observer* observer) {
122 observer_list_.AddObserver(observer);
123 }
124
125 void CertLibrary::RemoveObserver(CertLibrary::Observer* observer) {
126 observer_list_.RemoveObserver(observer);
127 }
128
129 bool CertLibrary::CertificatesLoading() const {
130 return CertLoader::Get()->CertificatesLoading();
131 }
132
133 bool CertLibrary::CertificatesLoaded() const {
134 return CertLoader::Get()->certificates_loaded();
135 }
136
137 bool CertLibrary::IsHardwareBacked() const {
138 return CertLoader::Get()->IsHardwareBacked();
139 }
140
141 int CertLibrary::NumCertificates(CertType type) const {
142 const net::CertificateList& cert_list = GetCertificateListForType(type);
143 return static_cast<int>(cert_list.size());
144 }
145
146 string16 CertLibrary::GetCertDisplayStringAt(CertType type, int index) const {
147 net::X509Certificate* cert = GetCertificateAt(type, index);
148 bool hardware_backed = IsCertHardwareBackedAt(type, index);
519 return GetDisplayString(cert, hardware_backed); 149 return GetDisplayString(cert, hardware_backed);
520 } 150 }
521 151
522 std::string CertLibrary::CertList::GetNicknameAt(int index) const { 152 std::string CertLibrary::GetCertNicknameAt(CertType type, int index) const {
523 net::X509Certificate* cert = GetCertificateAt(index); 153 net::X509Certificate* cert = GetCertificateAt(type, index);
524 return x509_certificate_model::GetNickname(cert->os_cert_handle()); 154 return x509_certificate_model::GetNickname(cert->os_cert_handle());
525 } 155 }
526 156
527 std::string CertLibrary::CertList::GetPkcs11IdAt(int index) const { 157 std::string CertLibrary::GetCertPkcs11IdAt(CertType type, int index) const {
528 net::X509Certificate* cert = GetCertificateAt(index); 158 net::X509Certificate* cert = GetCertificateAt(type, index);
529 return x509_certificate_model::GetPkcs11Id(cert->os_cert_handle()); 159 return x509_certificate_model::GetPkcs11Id(cert->os_cert_handle());
530 } 160 }
531 161
532 bool CertLibrary::CertList::IsHardwareBackedAt(int index) const { 162 bool CertLibrary::IsCertHardwareBackedAt(CertType type, int index) const {
533 net::X509Certificate* cert = GetCertificateAt(index); 163 if (!CertLoader::Get()->IsHardwareBacked())
164 return false;
165 net::X509Certificate* cert = GetCertificateAt(type, index);
534 std::string cert_token_name = 166 std::string cert_token_name =
535 x509_certificate_model::GetTokenName(cert->os_cert_handle()); 167 x509_certificate_model::GetTokenName(cert->os_cert_handle());
536 return cert_token_name == cert_library_->GetTpmTokenName(); 168 return cert_token_name == CertLoader::Get()->tpm_token_name();
537 } 169 }
538 170
539 int CertLibrary::CertList::FindCertByNickname( 171 int CertLibrary::GetCertIndexByNickname(CertType type,
540 const std::string& nickname) const { 172 const std::string& nickname) const {
541 for (int index = 0; index < Size(); ++index) { 173 int num_certs = NumCertificates(type);
542 net::X509Certificate* cert = GetCertificateAt(index); 174 for (int index = 0; index < num_certs; ++index) {
175 net::X509Certificate* cert = GetCertificateAt(type, index);
543 net::X509Certificate::OSCertHandle cert_handle = cert->os_cert_handle(); 176 net::X509Certificate::OSCertHandle cert_handle = cert->os_cert_handle();
544 std::string nick = x509_certificate_model::GetNickname(cert_handle); 177 std::string nick = x509_certificate_model::GetNickname(cert_handle);
545 if (nick == nickname) 178 if (nick == nickname)
546 return index; 179 return index;
547 } 180 }
548 return -1; // Not found. 181 return -1; // Not found.
549 } 182 }
550 183
551 int CertLibrary::CertList::FindCertByPkcs11Id( 184 int CertLibrary::GetCertIndexByPkcs11Id(CertType type,
552 const std::string& pkcs11_id) const { 185 const std::string& pkcs11_id) const {
553 for (int index = 0; index < Size(); ++index) { 186 int num_certs = NumCertificates(type);
554 net::X509Certificate* cert = GetCertificateAt(index); 187 for (int index = 0; index < num_certs; ++index) {
188 net::X509Certificate* cert = GetCertificateAt(type, index);
555 net::X509Certificate::OSCertHandle cert_handle = cert->os_cert_handle(); 189 net::X509Certificate::OSCertHandle cert_handle = cert->os_cert_handle();
556 std::string id = x509_certificate_model::GetPkcs11Id(cert_handle); 190 std::string id = x509_certificate_model::GetPkcs11Id(cert_handle);
557 if (id == pkcs11_id) 191 if (id == pkcs11_id)
558 return index; 192 return index;
559 } 193 }
560 return -1; // Not found. 194 return -1; // Not found.
561 } 195 }
562 196
197 void CertLibrary::OnCertificatesLoaded(const net::CertificateList& cert_list,
198 bool initial_load) {
199 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
200 VLOG(1) << "CertLibrary::OnCertificatesLoaded: " << cert_list.size();
201 certs_.clear();
202 user_certs_.clear();
203 server_certs_.clear();
204 server_ca_certs_.clear();
205
206 // Add certificates to the appropriate list.
207 for (net::CertificateList::const_iterator iter = cert_list.begin();
208 iter != cert_list.end(); ++iter) {
209 certs_.push_back(iter->get());
210 net::X509Certificate::OSCertHandle cert_handle =
211 iter->get()->os_cert_handle();
212 net::CertType type = x509_certificate_model::GetType(cert_handle);
213 switch (type) {
214 case net::USER_CERT:
215 user_certs_.push_back(iter->get());
216 break;
217 case net::SERVER_CERT:
218 server_certs_.push_back(iter->get());
219 break;
220 case net::CA_CERT: {
221 // Exclude root CA certificates that are built into Chrome.
222 std::string token_name =
223 x509_certificate_model::GetTokenName(cert_handle);
224 if (token_name != kRootCertificateTokenName)
225 server_ca_certs_.push_back(iter->get());
226 break;
227 }
228 default:
229 break;
230 }
231 }
232
233 // Perform locale-sensitive sorting by certificate name.
234 UErrorCode error = U_ZERO_ERROR;
235 scoped_ptr<icu::Collator> collator(icu::Collator::createInstance(
236 icu::Locale(g_browser_process->GetApplicationLocale().c_str()), error));
237 if (U_FAILURE(error))
238 collator.reset();
239 CertNameComparator cert_name_comparator(collator.get());
240 std::sort(certs_.begin(), certs_.end(), cert_name_comparator);
241 std::sort(user_certs_.begin(), user_certs_.end(), cert_name_comparator);
242 std::sort(server_certs_.begin(), server_certs_.end(), cert_name_comparator);
243 std::sort(server_ca_certs_.begin(), server_ca_certs_.end(),
244 cert_name_comparator);
245
246 VLOG(1) << "certs_: " << certs_.size();
247 VLOG(1) << "user_certs_: " << user_certs_.size();
248 VLOG(1) << "server_certs_: " << server_certs_.size();
249 VLOG(1) << "server_ca_certs_: " << server_ca_certs_.size();
250
251 FOR_EACH_OBSERVER(CertLibrary::Observer, observer_list_,
252 OnCertificatesLoaded(initial_load));
253 }
254
255 net::X509Certificate* CertLibrary::GetCertificateAt(CertType type,
256 int index) const {
257 const net::CertificateList& cert_list = GetCertificateListForType(type);
258 DCHECK_GE(index, 0);
259 DCHECK_LT(index, static_cast<int>(cert_list.size()));
260 return cert_list[index].get();
261 }
262
263 const net::CertificateList& CertLibrary::GetCertificateListForType(
264 CertType type) const {
265 if (type == CERT_TYPE_USER)
266 return user_certs_;
267 if (type == CERT_TYPE_SERVER)
268 return server_certs_;
269 if (type == CERT_TYPE_SERVER_CA)
270 return server_ca_certs_;
271 DCHECK(type == CERT_TYPE_DEFAULT);
272 return certs_;
273 }
274
563 } // chromeos 275 } // chromeos
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/cros/cert_library.h ('k') | chrome/browser/chromeos/cros/cros_library.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698