Index: chrome/browser/chromeos/cros/cert_library.cc |
diff --git a/chrome/browser/chromeos/cros/cert_library.cc b/chrome/browser/chromeos/cros/cert_library.cc |
index c096157758eb697ce42ee9ce375f3e941379c23f..7085bfd49928ece66ec3c7d8f8436aca4f9c80f4 100644 |
--- a/chrome/browser/chromeos/cros/cert_library.cc |
+++ b/chrome/browser/chromeos/cros/cert_library.cc |
@@ -29,8 +29,6 @@ |
#include "ui/base/l10n/l10n_util.h" |
#include "ui/base/l10n/l10n_util_collator.h" |
-using content::BrowserThread; |
- |
namespace chromeos { |
namespace { |
@@ -38,9 +36,6 @@ namespace { |
// Root CA certificates that are built into Chrome use this token name. |
const char kRootCertificateTokenName[] = "Builtin Object Token"; |
-// Delay between certificate requests while waiting for TPM/PKCS#11 init. |
-const int kRequestDelayMs = 500; |
- |
string16 GetDisplayString(net::X509Certificate* cert, bool hardware_backed) { |
std::string org; |
if (!cert->subject().organization_names.empty()) |
@@ -69,477 +64,115 @@ string16 GetDisplayString(net::X509Certificate* cert, bool hardware_backed) { |
} // namespace |
-////////////////////////////////////////////////////////////////////////////// |
- |
-// base::Unretained(this) in the class is safe. By the time this object is |
-// deleted as part of CrosLibrary, the DB thread and the UI message loop |
-// are already terminated. |
-class CertLibraryImpl |
- : public CertLibrary, |
- public net::CertDatabase::Observer { |
+class CertNameComparator { |
public: |
- typedef ObserverListThreadSafe<CertLibrary::Observer> CertLibraryObserverList; |
- |
- CertLibraryImpl() : |
- observer_list_(new CertLibraryObserverList), |
- tpm_token_ready_(false), |
- user_logged_in_(false), |
- certificates_requested_(false), |
- certificates_loaded_(false), |
- key_store_loaded_(false), |
- ALLOW_THIS_IN_INITIALIZER_LIST(certs_(this)), |
- ALLOW_THIS_IN_INITIALIZER_LIST(user_certs_(this)), |
- ALLOW_THIS_IN_INITIALIZER_LIST(server_certs_(this)), |
- ALLOW_THIS_IN_INITIALIZER_LIST(server_ca_certs_(this)), |
- ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { |
- CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- net::CertDatabase::GetInstance()->AddObserver(this); |
- } |
- |
- virtual ~CertLibraryImpl() { |
- DCHECK(request_task_.is_null()); |
- net::CertDatabase::GetInstance()->RemoveObserver(this); |
- } |
- |
- // CertLibrary implementation. |
- virtual void AddObserver(CertLibrary::Observer* observer) OVERRIDE { |
- observer_list_->AddObserver(observer); |
- } |
- |
- virtual void RemoveObserver(CertLibrary::Observer* observer) OVERRIDE { |
- observer_list_->RemoveObserver(observer); |
- } |
- |
- virtual void LoadKeyStore() OVERRIDE { |
- CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- if (key_store_loaded_) |
- return; |
- |
- // Ensure we've opened the real user's key/certificate database. |
- crypto::OpenPersistentNSSDB(); |
- |
- if (base::chromeos::IsRunningOnChromeOS() || |
- CommandLine::ForCurrentProcess()->HasSwitch( |
- switches::kLoadOpencryptoki)) { |
- crypto::EnableTPMTokenForNSS(); |
- // Note: this calls crypto::EnsureTPMTokenReady() |
- RequestCertificates(); |
- } |
- key_store_loaded_ = true; |
- } |
- |
- virtual bool CertificatesLoading() const OVERRIDE { |
- return certificates_requested_ && !certificates_loaded_; |
- } |
- |
- virtual bool CertificatesLoaded() const OVERRIDE { |
- return certificates_loaded_; |
- } |
- |
- virtual bool IsHardwareBacked() const OVERRIDE { |
- return !tpm_token_name_.empty(); |
- } |
- |
- virtual const CertList& GetCertificates() const OVERRIDE { |
- CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- return certs_; |
- } |
- |
- virtual const CertList& GetUserCertificates() const OVERRIDE { |
- CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- return user_certs_; |
- } |
- |
- virtual const CertList& GetServerCertificates() const OVERRIDE { |
- CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- return server_certs_; |
- } |
- |
- virtual const CertList& GetCACertificates() const OVERRIDE { |
- CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- return server_ca_certs_; |
- } |
- |
- // net::CertDatabase::Observer implementation. Observer added on UI thread. |
- virtual void OnCertTrustChanged(const net::X509Certificate* cert) OVERRIDE { |
- CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- } |
- |
- virtual void OnCertAdded(const net::X509Certificate* cert) OVERRIDE { |
- CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- // Only load certificates if we have completed an initial request. |
- if (certificates_loaded_) { |
- BrowserThread::PostTask( |
- BrowserThread::DB, FROM_HERE, |
- base::Bind(&CertLibraryImpl::LoadCertificates, |
- base::Unretained(this))); |
- } |
+ explicit CertNameComparator(icu::Collator* collator) |
+ : collator_(collator) { |
} |
- virtual void OnCertRemoved(const net::X509Certificate* cert) OVERRIDE { |
- CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- // Only load certificates if we have completed an initial request. |
- if (certificates_loaded_) { |
- BrowserThread::PostTask( |
- BrowserThread::DB, FROM_HERE, |
- base::Bind(&CertLibraryImpl::LoadCertificates, |
- base::Unretained(this))); |
- } |
- } |
- |
- virtual const std::string& GetTpmTokenName() const OVERRIDE { |
- return tpm_token_name_; |
+ bool operator()(const scoped_refptr<net::X509Certificate>& lhs, |
+ const scoped_refptr<net::X509Certificate>& rhs) const { |
+ string16 lhs_name = GetDisplayString(lhs.get(), false); |
+ string16 rhs_name = GetDisplayString(rhs.get(), false); |
+ if (collator_ == NULL) |
+ return lhs_name < rhs_name; |
+ return base::i18n::CompareString16WithCollator( |
+ collator_, lhs_name, rhs_name) == UCOL_LESS; |
} |
private: |
- void LoadCertificates() { |
- VLOG(1) << " Loading Certificates."; |
- // Certificate fetch occurs on the DB thread. |
- CHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); |
- net::CertificateList* cert_list = new net::CertificateList(); |
- net::NSSCertDatabase::GetInstance()->ListCerts(cert_list); |
- // Pass the list to the UI thread to safely update the local lists. |
- BrowserThread::PostTask( |
- BrowserThread::UI, FROM_HERE, |
- base::Bind(&CertLibraryImpl::UpdateCertificates, |
- base::Unretained(this), cert_list)); |
- } |
- |
- // Comparison functor for locale-sensitive sorting of certificates by name. |
- class CertNameComparator { |
- public: |
- explicit CertNameComparator(icu::Collator* collator) |
- : collator_(collator) { } |
- |
- bool operator()(const scoped_refptr<net::X509Certificate>& lhs, |
- const scoped_refptr<net::X509Certificate>& rhs) const { |
- string16 lhs_name = GetDisplayString(lhs.get(), false); |
- string16 rhs_name = GetDisplayString(rhs.get(), false); |
- if (collator_ == NULL) |
- return lhs_name < rhs_name; |
- return base::i18n::CompareString16WithCollator( |
- collator_, lhs_name, rhs_name) == UCOL_LESS; |
- } |
- private: |
- icu::Collator* collator_; |
- }; |
- |
- void NotifyCertificatesLoaded(bool initial_load) { |
- observer_list_->Notify( |
- &CertLibrary::Observer::OnCertificatesLoaded, initial_load); |
- } |
- |
- // |cert_list| is allocated in LoadCertificates() and must be deleted here. |
- void UpdateCertificates(net::CertificateList* cert_list) { |
- CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- DCHECK(cert_list); |
- |
- // Clear any existing certificates. |
- certs_.Clear(); |
- server_ca_certs_.Clear(); |
- user_certs_.Clear(); |
- server_certs_.Clear(); |
- |
- // Add certificates to the appropriate list. |
- for (net::CertificateList::const_iterator iter = cert_list->begin(); |
- iter != cert_list->end(); ++iter) { |
- certs_.Append(iter->get()); |
- net::X509Certificate::OSCertHandle cert_handle = |
- iter->get()->os_cert_handle(); |
- net::CertType type = x509_certificate_model::GetType(cert_handle); |
- switch (type) { |
- case net::USER_CERT: |
- user_certs_.Append(iter->get()); |
- break; |
- case net::SERVER_CERT: |
- server_certs_.Append(iter->get()); |
- break; |
- case net::CA_CERT: { |
- // Exclude root CA certificates that are built into Chrome. |
- std::string token_name = |
- x509_certificate_model::GetTokenName(cert_handle); |
- if (token_name != kRootCertificateTokenName) |
- server_ca_certs_.Append(iter->get()); |
- break; |
- } |
- default: |
- break; |
- } |
- } |
- |
- // Perform locale-sensitive sorting by certificate name. |
- scoped_ptr<icu::Collator> collator; |
- UErrorCode error = U_ZERO_ERROR; |
- collator.reset( |
- icu::Collator::createInstance( |
- icu::Locale(g_browser_process->GetApplicationLocale().c_str()), |
- error)); |
- if (U_FAILURE(error)) |
- collator.reset(NULL); |
- CertNameComparator cert_name_comparator(collator.get()); |
- std::sort(user_certs_.list().begin(), user_certs_.list().end(), |
- cert_name_comparator); |
- std::sort(server_certs_.list().begin(), server_certs_.list().end(), |
- cert_name_comparator); |
- std::sort(server_ca_certs_.list().begin(), server_ca_certs_.list().end(), |
- cert_name_comparator); |
- |
- // cert_list is allocated in LoadCertificates(), then released here. |
- delete cert_list; |
- |
- // Set loaded state and notify observers. |
- if (!certificates_loaded_) { |
- certificates_loaded_ = true; |
- NotifyCertificatesLoaded(true); |
- } else { |
- NotifyCertificatesLoaded(false); |
- } |
- } |
- |
- // Call this to start the certificate list initialization process. |
- // Must be called from the UI thread. |
- void RequestCertificates() { |
- CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- |
- certificates_requested_ = true; |
- |
- if (!LoginState::Get()->IsUserLoggedIn()) { |
- // If we are not logged in, we cannot load any certificates. |
- // Set 'loaded' to true for the UI, since we are not waiting on loading. |
- LOG(WARNING) << "Requesting certificates before login."; |
- certificates_loaded_ = true; |
- return; |
- } |
- |
- if (!user_logged_in_) { |
- user_logged_in_ = true; |
- certificates_loaded_ = false; |
- } |
- |
- VLOG(1) << "Requesting Certificates."; |
- DBusThreadManager::Get()->GetCryptohomeClient()->TpmIsEnabled( |
- base::Bind(&CertLibraryImpl::OnTpmIsEnabled, |
- weak_ptr_factory_.GetWeakPtr())); |
- } |
- |
- // This method is used to implement RequestCertificates. |
- void OnTpmIsEnabled(DBusMethodCallStatus call_status, bool tpm_is_enabled) { |
- CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- if (call_status != DBUS_METHOD_CALL_SUCCESS || !tpm_is_enabled) { |
- // TPM is not enabled, so proceed with empty tpm token name. |
- VLOG(1) << "TPM not available."; |
- BrowserThread::PostTask( |
- BrowserThread::DB, FROM_HERE, |
- base::Bind(&CertLibraryImpl::LoadCertificates, |
- base::Unretained(this))); |
- } else if (tpm_token_ready_) { |
- InitializeTPMToken(); |
- } else { |
- DBusThreadManager::Get()->GetCryptohomeClient()->Pkcs11IsTpmTokenReady( |
- base::Bind(&CertLibraryImpl::OnPkcs11IsTpmTokenReady, |
- weak_ptr_factory_.GetWeakPtr())); |
- } |
- } |
- |
- // This method is used to implement RequestCertificates. |
- void OnPkcs11IsTpmTokenReady(DBusMethodCallStatus call_status, |
- bool is_tpm_token_ready) { |
- if (call_status != DBUS_METHOD_CALL_SUCCESS || !is_tpm_token_ready) { |
- MaybeRetryRequestCertificates(); |
- return; |
- } |
- |
- // Retrieve token_name_ and user_pin_ here since they will never change |
- // and CryptohomeClient calls are not thread safe. |
- DBusThreadManager::Get()->GetCryptohomeClient()->Pkcs11GetTpmTokenInfo( |
- base::Bind(&CertLibraryImpl::OnPkcs11GetTpmTokenInfo, |
- weak_ptr_factory_.GetWeakPtr())); |
- } |
- |
- // This method is used to implement RequestCertificates. |
- void OnPkcs11GetTpmTokenInfo(DBusMethodCallStatus call_status, |
- const std::string& token_name, |
- const std::string& user_pin) { |
- if (call_status != DBUS_METHOD_CALL_SUCCESS) { |
- MaybeRetryRequestCertificates(); |
- return; |
- } |
- tpm_token_name_ = token_name; |
- tpm_user_pin_ = user_pin; |
- tpm_token_ready_ = true; |
- |
- InitializeTPMToken(); |
- } |
- |
- // This method is used to implement RequestCertificates. |
- void InitializeTPMToken() { |
- CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- if (!crypto::InitializeTPMToken(tpm_token_name_, tpm_user_pin_)) { |
- MaybeRetryRequestCertificates(); |
- return; |
- } |
- |
- // tpm_token_name_ is set, load the certificates on the DB thread. |
- BrowserThread::PostTask( |
- BrowserThread::DB, FROM_HERE, |
- base::Bind(&CertLibraryImpl::LoadCertificates, base::Unretained(this))); |
- } |
- |
- void MaybeRetryRequestCertificates() { |
- if (!request_task_.is_null()) |
- return; |
- // Cryptohome does not notify us when the token is ready, so call |
- // this again after a delay. |
- request_task_ = base::Bind(&CertLibraryImpl::RequestCertificatesTask, |
- weak_ptr_factory_.GetWeakPtr()); |
- BrowserThread::PostDelayedTask( |
- BrowserThread::UI, FROM_HERE, request_task_, |
- base::TimeDelta::FromMilliseconds(kRequestDelayMs)); |
- } |
- |
- void RequestCertificatesTask() { |
- CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- // Reset the task to the initial state so is_null() returns true. |
- request_task_ = base::Closure(); |
- RequestCertificates(); |
- } |
- |
- // Observers. |
- const scoped_refptr<CertLibraryObserverList> observer_list_; |
- |
- // Active request task for re-requests while waiting for TPM init. |
- base::Closure request_task_; |
- |
- bool tpm_token_ready_; |
- |
- // Cached TPM token name. |
- std::string tpm_token_name_; |
- |
- // Cached TPM user pin. |
- std::string tpm_user_pin_; |
- |
- // Local state. |
- bool user_logged_in_; |
- bool certificates_requested_; |
- bool certificates_loaded_; |
- // The key store for the current user has been loaded. This flag is needed to |
- // ensure that the key store will not be loaded twice in the policy recovery |
- // "safe-mode". |
- bool key_store_loaded_; |
- |
- // Certificates. |
- CertList certs_; |
- CertList user_certs_; |
- CertList server_certs_; |
- CertList server_ca_certs_; |
- |
- base::WeakPtrFactory<CertLibraryImpl> weak_ptr_factory_; |
- |
- DISALLOW_COPY_AND_ASSIGN(CertLibraryImpl); |
+ icu::Collator* collator_; |
}; |
-////////////////////////////////////////////////////////////////////////////// |
+static CertLibrary* g_cert_library = NULL; |
-class CertLibraryImplStub : public CertLibrary { |
- public: |
- CertLibraryImplStub() |
- : token_name_("StubToken"), |
- ALLOW_THIS_IN_INITIALIZER_LIST(cert_list_(this)) { |
- } |
- virtual ~CertLibraryImplStub() {} |
+// static |
+void CertLibrary::Initialize() { |
+ CHECK(!g_cert_library); |
+ g_cert_library = new CertLibrary(); |
+} |
- virtual void AddObserver(Observer* observer) {} |
- virtual void RemoveObserver(Observer* observer) {} |
- virtual void LoadKeyStore() {} |
- virtual bool CertificatesLoading() const { |
- return false; |
- } |
- virtual bool CertificatesLoaded() const { |
- return true; |
- } |
- virtual bool IsHardwareBacked() const { |
- return false; |
- } |
- virtual const std::string& GetTpmTokenName() const { |
- return token_name_; |
- } |
- virtual const CertList& GetCertificates() const { |
- return cert_list_; |
- } |
- virtual const CertList& GetUserCertificates() const { |
- return cert_list_; |
- } |
- virtual const CertList& GetServerCertificates() const { |
- return cert_list_; |
- } |
- virtual const CertList& GetCACertificates() const { |
- return cert_list_; |
- } |
+// static |
+void CertLibrary::Shutdown() { |
+ CHECK(g_cert_library); |
+ delete g_cert_library; |
+ g_cert_library = NULL; |
+} |
- private: |
- std::string token_name_; |
- CertList cert_list_; |
+// static |
+CertLibrary* CertLibrary::Get() { |
+ CHECK(g_cert_library) << "CertLibrary::Get() called before Initialize()"; |
+ return g_cert_library; |
+} |
- DISALLOW_COPY_AND_ASSIGN(CertLibraryImplStub); |
-}; |
+// static |
+bool CertLibrary::IsInitialized() { |
+ return g_cert_library; |
+} |
-////////////////////////////////////////////////////////////////////////////// |
+CertLibrary::CertLibrary() { |
+ CertLoader::Get()->AddObserver(this); |
+} |
CertLibrary::~CertLibrary() { |
+ CertLoader::Get()->RemoveObserver(this); |
} |
-// static |
-CertLibrary* CertLibrary::GetImpl(bool stub) { |
- // TODO(stevenjb): Disassociate CertLibrary from CrosLibrary entirely. |
- // crbug.com/133752 |
- if (stub) |
- return new CertLibraryImplStub(); |
- return new CertLibraryImpl(); |
+void CertLibrary::AddObserver(CertLibrary::Observer* observer) { |
+ observer_list_.AddObserver(observer); |
} |
-////////////////////////////////////////////////////////////////////////////// |
+void CertLibrary::RemoveObserver(CertLibrary::Observer* observer) { |
+ observer_list_.RemoveObserver(observer); |
+} |
-CertLibrary::CertList::CertList(CertLibrary* library) |
- : cert_library_(library) { |
+bool CertLibrary::CertificatesLoading() const { |
+ return CertLoader::Get()->CertificatesLoading(); |
} |
-CertLibrary::CertList::~CertList() {} |
+bool CertLibrary::CertificatesLoaded() const { |
+ return CertLoader::Get()->certificates_loaded(); |
+} |
-net::X509Certificate* CertLibrary::CertList::GetCertificateAt(int index) const { |
- CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- DCHECK_GE(index, 0); |
- DCHECK_LT(index, static_cast<int>(list_.size())); |
- return list_[index].get(); |
+bool CertLibrary::IsHardwareBacked() const { |
+ return CertLoader::Get()->IsHardwareBacked(); |
} |
-string16 CertLibrary::CertList::GetDisplayStringAt(int index) const { |
- net::X509Certificate* cert = GetCertificateAt(index); |
+int CertLibrary::NumCertificates(CertType type) const { |
+ const net::CertificateList& cert_list = GetCertificateListForType(type); |
+ return static_cast<int>(cert_list.size()); |
+} |
+ |
+string16 CertLibrary::GetCertDisplayStringAt(CertType type, int index) const { |
+ net::X509Certificate* cert = GetCertificateAt(type, index); |
bool hardware_backed = |
- !cert_library_->GetTpmTokenName().empty() && IsHardwareBackedAt(index); |
+ CertLoader::Get()->IsHardwareBacked() && |
+ IsCertHardwareBackedAt(type, index); |
return GetDisplayString(cert, hardware_backed); |
} |
-std::string CertLibrary::CertList::GetNicknameAt(int index) const { |
- net::X509Certificate* cert = GetCertificateAt(index); |
+std::string CertLibrary::GetCertNicknameAt(CertType type, int index) const { |
+ net::X509Certificate* cert = GetCertificateAt(type, index); |
return x509_certificate_model::GetNickname(cert->os_cert_handle()); |
} |
-std::string CertLibrary::CertList::GetPkcs11IdAt(int index) const { |
- net::X509Certificate* cert = GetCertificateAt(index); |
+std::string CertLibrary::GetCertPkcs11IdAt(CertType type, int index) const { |
+ net::X509Certificate* cert = GetCertificateAt(type, index); |
return x509_certificate_model::GetPkcs11Id(cert->os_cert_handle()); |
} |
-bool CertLibrary::CertList::IsHardwareBackedAt(int index) const { |
- net::X509Certificate* cert = GetCertificateAt(index); |
+bool CertLibrary::IsCertHardwareBackedAt(CertType type, int index) const { |
+ net::X509Certificate* cert = GetCertificateAt(type, index); |
std::string cert_token_name = |
x509_certificate_model::GetTokenName(cert->os_cert_handle()); |
- return cert_token_name == cert_library_->GetTpmTokenName(); |
+ return cert_token_name == CertLoader::Get()->tpm_token_name(); |
} |
-int CertLibrary::CertList::FindCertByNickname( |
- const std::string& nickname) const { |
- for (int index = 0; index < Size(); ++index) { |
- net::X509Certificate* cert = GetCertificateAt(index); |
+int CertLibrary::GetCertIndexByNickname(CertType type, |
+ const std::string& nickname) const { |
+ int num_certs = NumCertificates(type); |
+ for (int index = 0; index < num_certs; ++index) { |
+ net::X509Certificate* cert = GetCertificateAt(type, index); |
net::X509Certificate::OSCertHandle cert_handle = cert->os_cert_handle(); |
std::string nick = x509_certificate_model::GetNickname(cert_handle); |
if (nick == nickname) |
@@ -548,10 +181,11 @@ int CertLibrary::CertList::FindCertByNickname( |
return -1; // Not found. |
} |
-int CertLibrary::CertList::FindCertByPkcs11Id( |
- const std::string& pkcs11_id) const { |
- for (int index = 0; index < Size(); ++index) { |
- net::X509Certificate* cert = GetCertificateAt(index); |
+int CertLibrary::GetCertIndexByPkcs11Id(CertType type, |
+ const std::string& pkcs11_id) const { |
+ int num_certs = NumCertificates(type); |
+ for (int index = 0; index < num_certs; ++index) { |
+ net::X509Certificate* cert = GetCertificateAt(type, index); |
net::X509Certificate::OSCertHandle cert_handle = cert->os_cert_handle(); |
std::string id = x509_certificate_model::GetPkcs11Id(cert_handle); |
if (id == pkcs11_id) |
@@ -560,4 +194,82 @@ int CertLibrary::CertList::FindCertByPkcs11Id( |
return -1; // Not found. |
} |
+void CertLibrary::OnCertificatesLoaded(const net::CertificateList& cert_list, |
+ bool initial_load) { |
+ VLOG(1) << "CertLibrary::OnCertificatesLoaded: " << cert_list.size(); |
+ certs_.clear(); |
+ user_certs_.clear(); |
+ server_certs_.clear(); |
+ server_ca_certs_.clear(); |
+ |
+ // Add certificates to the appropriate list. |
+ for (net::CertificateList::const_iterator iter = cert_list.begin(); |
+ iter != cert_list.end(); ++iter) { |
+ certs_.push_back(iter->get()); |
+ net::X509Certificate::OSCertHandle cert_handle = |
+ iter->get()->os_cert_handle(); |
+ net::CertType type = x509_certificate_model::GetType(cert_handle); |
+ switch (type) { |
+ case net::USER_CERT: |
+ user_certs_.push_back(iter->get()); |
+ break; |
+ case net::SERVER_CERT: |
+ server_certs_.push_back(iter->get()); |
+ break; |
+ case net::CA_CERT: { |
+ // Exclude root CA certificates that are built into Chrome. |
+ std::string token_name = |
+ x509_certificate_model::GetTokenName(cert_handle); |
+ if (token_name != kRootCertificateTokenName) |
+ server_ca_certs_.push_back(iter->get()); |
+ break; |
+ } |
+ default: |
+ break; |
+ } |
+ } |
+ |
+ // Perform locale-sensitive sorting by certificate name. |
+ scoped_ptr<icu::Collator> collator; |
+ UErrorCode error = U_ZERO_ERROR; |
+ collator.reset(icu::Collator::createInstance( |
+ icu::Locale(g_browser_process->GetApplicationLocale().c_str()), error)); |
Ryan Sleevi
2013/05/01 18:16:18
FYI, http://crbug.com/225830
stevenjb
2013/05/01 20:47:59
Yep. That's one of several issues preventing this
|
+ if (U_FAILURE(error)) |
+ collator.reset(NULL); |
+ CertNameComparator cert_name_comparator(collator.get()); |
+ std::sort(certs_.begin(), certs_.end(), cert_name_comparator); |
+ std::sort(user_certs_.begin(), user_certs_.end(), cert_name_comparator); |
+ std::sort(server_certs_.begin(), server_certs_.end(), cert_name_comparator); |
+ std::sort(server_ca_certs_.begin(), server_ca_certs_.end(), |
+ cert_name_comparator); |
+ |
+ VLOG(1) << "certs_: " << certs_.size(); |
+ VLOG(1) << "user_certs_: " << user_certs_.size(); |
+ VLOG(1) << "server_certs_: " << server_certs_.size(); |
+ VLOG(1) << "server_ca_certs_: " << server_ca_certs_.size(); |
+ |
+ FOR_EACH_OBSERVER(CertLibrary::Observer, observer_list_, |
+ OnCertificatesLoaded(initial_load)); |
+} |
+ |
+net::X509Certificate* CertLibrary::GetCertificateAt(CertType type, |
+ int index) const { |
+ const net::CertificateList& cert_list = GetCertificateListForType(type); |
+ DCHECK_GE(index, 0); |
+ DCHECK_LT(index, static_cast<int>(cert_list.size())); |
+ return cert_list[index].get(); |
+} |
+ |
+const net::CertificateList& CertLibrary::GetCertificateListForType( |
+ CertType type) const { |
+ if (type == CERT_TYPE_USER) |
+ return user_certs_; |
+ if (type == CERT_TYPE_SERVER) |
+ return server_certs_; |
+ if (type == CERT_TYPE_SERVER_CA) |
+ return server_ca_certs_; |
+ DCHECK(type == CERT_TYPE_DEFAULT); |
+ return certs_; |
+} |
+ |
} // chromeos |