| 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 b5d7673859db797b0c93294bc7787656c5e26d75..5242a539694f0ff70b546e5efb4349471b6df7a6 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),
|
| - certs_(this),
|
| - user_certs_(this),
|
| - server_certs_(this),
|
| - server_ca_certs_(this),
|
| - 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"),
|
| - 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,83 @@ int CertLibrary::CertList::FindCertByPkcs11Id(
|
| return -1; // Not found.
|
| }
|
|
|
| +void CertLibrary::OnCertificatesLoaded(const net::CertificateList& cert_list,
|
| + bool initial_load) {
|
| + CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
|
| + 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));
|
| + 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
|
|
|