summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/app/generated_resources.grd6
-rw-r--r--chrome/browser/chromeos/cros/cert_library.cc373
-rw-r--r--chrome/browser/chromeos/cros/cert_library.h96
-rw-r--r--chrome/browser/chromeos/cros/cros_library.cc3
-rw-r--r--chrome/browser/chromeos/cros/cros_library.h4
-rw-r--r--chrome/browser/chromeos/login/user_manager.cc9
-rw-r--r--chrome/browser/chromeos/options/vpn_config_view.cc284
-rw-r--r--chrome/browser/chromeos/options/vpn_config_view.h30
-rw-r--r--chrome/browser/chromeos/options/wifi_config_model.cc191
-rw-r--r--chrome/browser/chromeos/options/wifi_config_model.h70
-rw-r--r--chrome/browser/chromeos/options/wifi_config_view.cc171
-rw-r--r--chrome/browser/chromeos/options/wifi_config_view.h34
-rw-r--r--chrome/chrome_browser.gypi4
-rw-r--r--crypto/nss_util.cc89
-rw-r--r--crypto/nss_util.h17
15 files changed, 828 insertions, 553 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 3fce9e4..d1cf62d 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -10762,9 +10762,15 @@ Keep your key file in a safe place. You will need it to create new versions of y
<message name="IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_USER_CERT_NONE_INSTALLED" desc="In settings Internet options, when creating a VPN or enterprise Wi-Fi connection, combobox item to display when no user certificates are installed.">
None installed
</message>
+ <message name="IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT_LOADING" desc="In settings Internet options, when creating a VPN or enterprise Wi-Fi connection, combobox item to display when certificates are loading.">
+ Loading...
+ </message>
<message name="IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PLEASE_INSTALL_USER_CERT" desc="In settings Internet options, when creating a VPN or enterprise Wi-Fi connection, error message to display when no user certificates are installed.">
Please install a user certificate.
</message>
+ <message name="IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_LOGIN_FOR_USER_CERT" desc="In settings Internet options, when creating a VPN or enterprise Wi-Fi connection, error message to display when not logged in and user certificates are required.">
+ Login required for user certificate.
+ </message>
<message name="IDS_NETWORK_RECONNECT_TITLE" desc="In network menu, title of the reconnect button that allows user to retry connection on error.">
Reconnect
</message>
diff --git a/chrome/browser/chromeos/cros/cert_library.cc b/chrome/browser/chromeos/cros/cert_library.cc
new file mode 100644
index 0000000..f4e4750
--- /dev/null
+++ b/chrome/browser/chromeos/cros/cert_library.cc
@@ -0,0 +1,373 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/cros/cert_library.h"
+
+#include <algorithm>
+
+#include "base/observer_list_threadsafe.h"
+#include "base/utf_string_conversions.h"
+#include "chrome/browser/browser_process.h" // g_browser_process
+#include "chrome/browser/chromeos/login/user_manager.h"
+#include "chrome/common/net/x509_certificate_model.h"
+#include "content/browser/browser_thread.h"
+#include "crypto/nss_util.h"
+#include "net/base/cert_database.h"
+#include "ui/base/l10n/l10n_util_collator.h"
+#include "unicode/coll.h" // icu::Collator
+
+//////////////////////////////////////////////////////////////////////////////
+
+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) {
+ std::string name_or_nick =
+ x509_certificate_model::GetCertNameOrNickname(cert->os_cert_handle());
+ return UTF8ToUTF16(name_or_nick);
+}
+
+} // namespace
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace chromeos {
+
+//////////////////////////////////////////////////////////////////////////////
+
+class CertLibraryImpl
+ : public CertLibrary,
+ public net::CertDatabase::Observer {
+ public:
+ typedef ObserverListThreadSafe<CertLibrary::Observer> CertLibraryObserverList;
+
+ CertLibraryImpl() :
+ observer_list_(new CertLibraryObserverList),
+ request_task_(NULL),
+ user_logged_in_(false),
+ certificates_loaded_(false) {
+ CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ net::CertDatabase::AddObserver(this);
+ }
+
+ ~CertLibraryImpl() {
+ CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ if (request_task_) {
+ request_task_->Cancel();
+ request_task_ = NULL;
+ }
+ net::CertDatabase::RemoveObserver(this);
+ }
+
+ // CertLibrary implementation.
+ virtual void RequestCertificates() OVERRIDE {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ if (!UserManager::Get()->user_is_logged_in()) {
+ // 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.";
+
+ // Need TPM token name to filter user certificates.
+ // TODO(stevenjb): crypto::EnsureTPMTokenReady() may block if init has
+ // not succeeded. It is not clear whether or not TPM / PKCS#11 init can
+ // be done safely on a non blocking thread. Blocking time is low.
+ if (crypto::EnsureTPMTokenReady()) {
+ std::string unused_pin;
+ // TODO(stevenjb): Make this asynchronous. It results in a synchronous
+ // D-Bus call in cryptohome (~3 ms).
+ crypto::GetTPMTokenInfo(&tpm_token_name_, &unused_pin);
+ } else {
+ if (crypto::IsTPMTokenAvailable()) {
+ VLOG(1) << "TPM token not ready.";
+ if (request_task_ == NULL) {
+ // Cryptohome does not notify us when the token is ready, so call
+ // this again after a delay.
+ request_task_ = NewRunnableMethod(
+ this, &CertLibraryImpl::RequestCertificatesTask);
+ BrowserThread::PostDelayedTask(
+ BrowserThread::UI, FROM_HERE, request_task_, kRequestDelayMs);
+ }
+ return;
+ }
+ // TPM is not enabled, so proceed with empty tpm token name.
+ VLOG(1) << "TPM not available.";
+ }
+
+ // tpm_token_name_ is set, load the certificates on the DB thread.
+ BrowserThread::PostTask(
+ BrowserThread::DB, FROM_HERE,
+ NewRunnableMethod(this, &CertLibraryImpl::LoadCertificates));
+ }
+
+ virtual void AddObserver(CertLibrary::Observer* observer) OVERRIDE {
+ observer_list_->AddObserver(observer);
+ }
+
+ virtual void RemoveObserver(CertLibrary::Observer* observer) OVERRIDE {
+ observer_list_->RemoveObserver(observer);
+ }
+
+ virtual bool CertificatesLoaded() const OVERRIDE {
+ return certificates_loaded_;
+ }
+
+ virtual const CertList& GetCertificates() const OVERRIDE {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ return certs_;
+ }
+
+ virtual const CertList& GetUserCertificates() const OVERRIDE {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ return user_certs_;
+ }
+
+ virtual const CertList& GetServerCertificates() const OVERRIDE {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ return server_certs_;
+ }
+
+ virtual const CertList& GetCACertificates() const OVERRIDE {
+ DCHECK(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 {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ }
+
+ virtual void OnUserCertAdded(const net::X509Certificate* cert) OVERRIDE {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ VLOG(1) << "Certificate Added.";
+ // Only load certificates if we have completed an initial request.
+ if (certificates_loaded_) {
+ VLOG(1) << " Loading Certificates.";
+ // The certificate passed in is const, so we cannot add it to our
+ // ref counted list directly. Instead, re-load the certificate list.
+ BrowserThread::PostTask(
+ BrowserThread::DB, FROM_HERE,
+ NewRunnableMethod(this, &CertLibraryImpl::LoadCertificates));
+ }
+ }
+
+ private:
+ void LoadCertificates() {
+ // Certificate fetch occurs on the DB thread.
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
+ net::CertDatabase cert_db;
+ net::CertificateList* cert_list = new net::CertificateList();
+ cert_db.ListCerts(cert_list);
+ // Pass the list to the UI thread to safely update the local lists.
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ NewRunnableMethod(this, &CertLibraryImpl::UpdateCertificates,
+ 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());
+ string16 rhs_name = GetDisplayString(rhs.get());
+ if (collator_ == NULL)
+ return lhs_name < rhs_name;
+ return l10n_util::CompareString16WithCollator(
+ collator_, lhs_name, rhs_name) == UCOL_LESS;
+ }
+ private:
+ icu::Collator* collator_;
+ };
+
+ void RequestCertificatesTask() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ // This will only get called from request_task_ which will delete itself.
+ request_task_ = NULL;
+ RequestCertificates();
+ }
+
+ 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) {
+ DCHECK(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: {
+ // Only include user certs that are in the TPM token (and hence
+ // available via PKCS#11 to flimflam and wpa_supplicant).
+ std::string cert_token_name =
+ x509_certificate_model::GetTokenName(cert_handle);
+ if (tpm_token_name_.empty() || cert_token_name == tpm_token_name_)
+ 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);
+ }
+ }
+
+ // Observers.
+ const scoped_refptr<CertLibraryObserverList> observer_list_;
+
+ // Active request task for re-requests while waiting for TPM init.
+ CancelableTask* request_task_;
+
+ // Cached TPM token name.
+ std::string tpm_token_name_;
+
+ // Local state.
+ bool user_logged_in_;
+ bool certificates_loaded_;
+
+ // Certificates.
+ CertList certs_;
+ CertList user_certs_;
+ CertList server_certs_;
+ CertList server_ca_certs_;
+
+ DISALLOW_COPY_AND_ASSIGN(CertLibraryImpl);
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+CertLibrary::~CertLibrary() {
+}
+
+// static
+CertLibrary* CertLibrary::GetImpl(bool stub) {
+ // No libcros dependencies, so always return CertLibraryImpl() (no stub).
+ return new CertLibraryImpl();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+net::X509Certificate* CertLibrary::CertList::GetCertificateAt(int index) const {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ DCHECK_GE(index, 0);
+ DCHECK_LT(index, static_cast<int>(list_.size()));
+ return list_[index].get();
+}
+
+string16 CertLibrary::CertList::GetDisplayStringAt(int index) const {
+ net::X509Certificate* cert = GetCertificateAt(index);
+ return GetDisplayString(cert);
+}
+
+std::string CertLibrary::CertList::GetNicknameAt(int index) const {
+ net::X509Certificate* cert = GetCertificateAt(index);
+ return x509_certificate_model::GetNickname(cert->os_cert_handle());
+}
+
+std::string CertLibrary::CertList::GetPkcs11IdAt(int index) const {
+ net::X509Certificate* cert = GetCertificateAt(index);
+ return x509_certificate_model::GetPkcs11Id(cert->os_cert_handle());
+}
+
+int CertLibrary::CertList::FindCertByNickname(
+ const std::string& nickname) const {
+ for (int index = 0; index < Size(); ++index) {
+ net::X509Certificate* cert = GetCertificateAt(index);
+ net::X509Certificate::OSCertHandle cert_handle = cert->os_cert_handle();
+ std::string nick = x509_certificate_model::GetNickname(cert_handle);
+ if (nick == nickname)
+ return index;
+ }
+ 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);
+ net::X509Certificate::OSCertHandle cert_handle = cert->os_cert_handle();
+ std::string id = x509_certificate_model::GetPkcs11Id(cert_handle);
+ if (id == pkcs11_id)
+ return index;
+ }
+ return -1; // Not found.
+}
+
+} // chromeos
+
+// Allows InvokeLater without adding refcounting. This class is a singleton and
+// won't be deleted until it's last InvokeLater is run.
+DISABLE_RUNNABLE_METHOD_REFCOUNT(chromeos::CertLibraryImpl);
diff --git a/chrome/browser/chromeos/cros/cert_library.h b/chrome/browser/chromeos/cros/cert_library.h
new file mode 100644
index 0000000..87fecd6
--- /dev/null
+++ b/chrome/browser/chromeos/cros/cert_library.h
@@ -0,0 +1,96 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CHROMEOS_CROS_CERT_LIBRARY_H_
+#define CHROME_BROWSER_CHROMEOS_CROS_CERT_LIBRARY_H_
+#pragma once
+
+#include <string>
+
+#include "base/string16.h"
+#include "net/base/cert_database.h"
+#include "net/base/x509_certificate.h"
+
+namespace chromeos {
+
+class CertLibrary {
+ public:
+
+ // Observers can register themselves via CertLibrary::AddObserver, and can
+ // un-register with CertLibrary::RemoveObserver.
+ class Observer {
+ public:
+ virtual ~Observer() {}
+
+ // Called for any Observers whenever the certificates are loaded.
+ // |initial_load| is true the first time this is called.
+ virtual void OnCertificatesLoaded(bool initial_load) = 0;
+
+ protected:
+ Observer() {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(Observer);
+ };
+
+ // Wrapper class to provide an additional interface for net::CertificateList.
+ class CertList {
+ public:
+ explicit CertList() {}
+ ~CertList() {}
+ void Append(net::X509Certificate* cert) { list_.push_back(cert); }
+ void Clear() { list_.clear(); }
+ int Size() const { return static_cast<int>(list_.size()); }
+ net::X509Certificate* GetCertificateAt(int index) const;
+ string16 GetDisplayStringAt(int index) const; // User-visible name.
+ std::string GetNicknameAt(int index) const;
+ std::string GetPkcs11IdAt(int index) const;
+ // Finds the index of a Certificate matching |nickname|.
+ // Returns -1 if none found.
+ int FindCertByNickname(const std::string& nickname) const;
+ // Same as above but for a pkcs#11 id.
+ int FindCertByPkcs11Id(const std::string& pkcs11_id) const;
+ net::CertificateList& list() { return list_; }
+
+ private:
+ net::CertificateList list_;
+
+ DISALLOW_COPY_AND_ASSIGN(CertList);
+ };
+
+ virtual ~CertLibrary();
+
+ static CertLibrary* GetImpl(bool stub);
+
+ // Registers |observer|. The thread on which this is called is the thread
+ // on which |observer| will be called back with notifications.
+ virtual void AddObserver(Observer* observer) = 0;
+
+ // Unregisters |observer| from receiving notifications. This must be called
+ // on the same thread on which AddObserver() was called.
+ virtual void RemoveObserver(Observer* observer) = 0;
+
+ // Call this to start the certificate list initialization process.
+ // Must be called from the UI thread.
+ virtual void RequestCertificates() = 0;
+
+ // Returns true when the certificate list has been initiailized.
+ virtual bool CertificatesLoaded() const = 0;
+
+ // Returns the current list of all certificates.
+ virtual const CertList& GetCertificates() const = 0;
+
+ // Returns the current list of user certificates.
+ virtual const CertList& GetUserCertificates() const = 0;
+
+ // Returns the current list of server certificates.
+ virtual const CertList& GetServerCertificates() const = 0;
+
+ // Returns the current list of server CA certificates.
+ virtual const CertList& GetCACertificates() const = 0;
+};
+
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_CHROMEOS_CROS_CERT_LIBRARY_H_
diff --git a/chrome/browser/chromeos/cros/cros_library.cc b/chrome/browser/chromeos/cros/cros_library.cc
index 9315fa1..7a0373a 100644
--- a/chrome/browser/chromeos/cros/cros_library.cc
+++ b/chrome/browser/chromeos/cros/cros_library.cc
@@ -7,6 +7,7 @@
#include "base/lazy_instance.h"
#include "chrome/browser/chromeos/cros/brightness_library.h"
#include "chrome/browser/chromeos/cros/burn_library.h"
+#include "chrome/browser/chromeos/cros/cert_library.h"
#include "chrome/browser/chromeos/cros/cros_library_loader.h"
#include "chrome/browser/chromeos/cros/cryptohome_library.h"
#include "chrome/browser/chromeos/cros/input_method_library.h"
@@ -57,6 +58,7 @@ CrosLibrary* CrosLibrary::Get() {
DEFINE_GET_LIBRARY_METHOD(Brightness, brightness);
DEFINE_GET_LIBRARY_METHOD(Burn, burn);
+DEFINE_GET_LIBRARY_METHOD(Cert, cert);
DEFINE_GET_LIBRARY_METHOD(Cryptohome, crypto);
DEFINE_GET_LIBRARY_METHOD(InputMethod, input_method);
DEFINE_GET_LIBRARY_METHOD(LibCrosService, libcros_service);
@@ -112,6 +114,7 @@ void CrosLibrary::TestApi::SetLibraryLoader(LibraryLoader* loader, bool own) {
}
DEFINE_SET_LIBRARY_METHOD(Brightness, brightness);
+DEFINE_SET_LIBRARY_METHOD(Cert, cert);
DEFINE_SET_LIBRARY_METHOD(Burn, burn);
DEFINE_SET_LIBRARY_METHOD(Cryptohome, crypto);
DEFINE_SET_LIBRARY_METHOD(InputMethod, input_method);
diff --git a/chrome/browser/chromeos/cros/cros_library.h b/chrome/browser/chromeos/cros/cros_library.h
index 7c67095..8148b3a 100644
--- a/chrome/browser/chromeos/cros/cros_library.h
+++ b/chrome/browser/chromeos/cros/cros_library.h
@@ -20,6 +20,7 @@ namespace chromeos {
class BrightnessLibrary;
class BurnLibrary;
+class CertLibrary;
class CryptohomeLibrary;
class InputMethodLibrary;
class LibCrosServiceLibrary;
@@ -56,6 +57,7 @@ class CrosLibrary {
// Setter for LibraryLoader.
void SetLibraryLoader(LibraryLoader* loader, bool own);
void SetBrightnessLibrary(BrightnessLibrary* library, bool own);
+ void SetCertLibrary(CertLibrary* library, bool own);
void SetBurnLibrary(BurnLibrary* library, bool own);
void SetCryptohomeLibrary(CryptohomeLibrary* library, bool own);
void SetInputMethodLibrary(InputMethodLibrary* library, bool own);
@@ -80,6 +82,7 @@ class CrosLibrary {
BrightnessLibrary* GetBrightnessLibrary();
BurnLibrary* GetBurnLibrary();
+ CertLibrary* GetCertLibrary();
CryptohomeLibrary* GetCryptohomeLibrary();
InputMethodLibrary* GetInputMethodLibrary();
LibCrosServiceLibrary* GetLibCrosServiceLibrary();
@@ -154,6 +157,7 @@ class CrosLibrary {
Library<BrightnessLibrary> brightness_lib_;
Library<BurnLibrary> burn_lib_;
+ Library<CertLibrary> cert_lib_;
Library<CryptohomeLibrary> crypto_lib_;
Library<InputMethodLibrary> input_method_lib_;
Library<LibCrosServiceLibrary> libcros_service_lib_;
diff --git a/chrome/browser/chromeos/login/user_manager.cc b/chrome/browser/chromeos/login/user_manager.cc
index 535b59c..d2e9d52 100644
--- a/chrome/browser/chromeos/login/user_manager.cc
+++ b/chrome/browser/chromeos/login/user_manager.cc
@@ -571,14 +571,19 @@ class RealTPMTokenInfoDelegate : public crypto::TPMTokenInfoDelegate {
public:
RealTPMTokenInfoDelegate();
virtual ~RealTPMTokenInfoDelegate();
- virtual bool IsTokenReady() const;
+ virtual bool IsTokenAvailable() const OVERRIDE;
+ virtual bool IsTokenReady() const OVERRIDE;
virtual void GetTokenInfo(std::string* token_name,
- std::string* user_pin) const;
+ std::string* user_pin) const OVERRIDE;
};
RealTPMTokenInfoDelegate::RealTPMTokenInfoDelegate() {}
RealTPMTokenInfoDelegate::~RealTPMTokenInfoDelegate() {}
+bool RealTPMTokenInfoDelegate::IsTokenAvailable() const {
+ return CrosLibrary::Get()->GetCryptohomeLibrary()->TpmIsEnabled();
+}
+
bool RealTPMTokenInfoDelegate::IsTokenReady() const {
return CrosLibrary::Get()->GetCryptohomeLibrary()->Pkcs11IsTpmTokenReady();
}
diff --git a/chrome/browser/chromeos/options/vpn_config_view.cc b/chrome/browser/chromeos/options/vpn_config_view.cc
index a11e98d..144d3d7 100644
--- a/chrome/browser/chromeos/options/vpn_config_view.cc
+++ b/chrome/browser/chromeos/options/vpn_config_view.cc
@@ -68,134 +68,76 @@ class ProviderTypeComboboxModel : public ui::ComboboxModel {
DISALLOW_COPY_AND_ASSIGN(ProviderTypeComboboxModel);
};
-// TODO(stevenjb): Integrate with changes from chromium-os:15829.
class ServerCACertComboboxModel : public ui::ComboboxModel {
public:
- ServerCACertComboboxModel() {
- net::CertDatabase cert_db;
- net::CertificateList cert_list;
- cert_db.ListCerts(&cert_list);
- // Find all the CA certificates.
- for (net::CertificateList::const_iterator it = cert_list.begin();
- it != cert_list.end(); ++it) {
- net::X509Certificate* cert = it->get();
- net::X509Certificate::OSCertHandle cert_handle = cert->os_cert_handle();
- net::CertType type = x509_certificate_model::GetType(cert_handle);
- if (type == 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)
- ca_certs_.push_back(*it);
- }
- }
+ explicit ServerCACertComboboxModel(CertLibrary* cert_library)
+ : cert_library_(cert_library) {
}
virtual ~ServerCACertComboboxModel() {}
-
virtual int GetItemCount() {
- return static_cast<int>(ca_certs_.size() + 1); // "Default" + certs
+ if (!cert_library_->CertificatesLoaded())
+ return 1; // "Loading"
+ // "Default" + certs.
+ return cert_library_->GetCACertificates().Size() + 1;
}
-
- virtual string16 GetItemAt(int index) {
- if (index == 0)
+ virtual string16 GetItemAt(int combo_index) {
+ if (!cert_library_->CertificatesLoaded())
+ return l10n_util::GetStringUTF16(
+ IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT_LOADING);
+ if (combo_index == 0)
return l10n_util::GetStringUTF16(
IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT_SERVER_CA_DEFAULT);
- int cert_index = index - 1;
- if (cert_index >= 0 && cert_index < static_cast<int>(ca_certs_.size())) {
- net::X509Certificate* cert = ca_certs_[cert_index].get();
- std::string name =
- x509_certificate_model::GetCertNameOrNickname(cert->os_cert_handle());
- return UTF8ToUTF16(name);
- }
- return string16();
- }
-
- int GetCertCount() {
- return static_cast<int>(ca_certs_.size());
- }
-
- std::string GetCertNssNickname(int cert_index) {
- if (0 <= cert_index && cert_index < static_cast<int>(ca_certs_.size())) {
- net::X509Certificate* cert = ca_certs_[cert_index].get();
- return x509_certificate_model::GetNickname(cert->os_cert_handle());
- }
- return std::string();
+ int cert_index = combo_index - 1;
+ return cert_library_->GetCACertificates().GetDisplayStringAt(cert_index);
}
-
private:
- net::CertificateList ca_certs_;
+ CertLibrary* cert_library_;
DISALLOW_COPY_AND_ASSIGN(ServerCACertComboboxModel);
};
-// TODO(stevenjb): Integrate with changes from chromium-os:15829.
class UserCertComboboxModel : public ui::ComboboxModel {
public:
- UserCertComboboxModel() {
- net::CertDatabase cert_db;
- net::CertificateList cert_list;
- cert_db.ListCerts(&cert_list);
- // Find all the user certificates. There shouldn't be many.
- for (net::CertificateList::const_iterator it = cert_list.begin();
- it != cert_list.end(); ++it) {
- net::X509Certificate* cert = it->get();
- net::X509Certificate::OSCertHandle cert_handle = cert->os_cert_handle();
- net::CertType type = x509_certificate_model::GetType(cert_handle);
- if (type == net::USER_CERT)
- user_certs_.push_back(*it);
- }
+ explicit UserCertComboboxModel(CertLibrary* cert_library)
+ : cert_library_(cert_library) {
}
virtual ~UserCertComboboxModel() {}
-
virtual int GetItemCount() {
- if (user_certs_.empty())
- return 1; // "None installed" item
- return static_cast<int>(user_certs_.size());
+ if (!cert_library_->CertificatesLoaded())
+ return 1; // "Loading"
+ int num_certs = cert_library_->GetUserCertificates().Size();
+ if (num_certs == 0)
+ return 1; // "None installed"
+ return num_certs;
}
-
- virtual string16 GetItemAt(int index) {
- if (user_certs_.empty()) {
- // "None installed" item.
+ virtual string16 GetItemAt(int combo_index) {
+ if (!cert_library_->CertificatesLoaded())
+ return l10n_util::GetStringUTF16(
+ IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT_LOADING);
+ if (cert_library_->GetUserCertificates().Size() == 0)
return l10n_util::GetStringUTF16(
IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_USER_CERT_NONE_INSTALLED);
- }
- if (index >= 0 && index < static_cast<int>(user_certs_.size())) {
- net::X509Certificate* cert = user_certs_[index].get();
- std::string name =
- x509_certificate_model::GetCertNameOrNickname(cert->os_cert_handle());
- return UTF8ToUTF16(name);
- }
- return string16();
- }
-
- bool HaveCerts() {
- return !user_certs_.empty();
- }
-
- // Gets PKCS#11 certificate ID, or empty string on failure.
- std::string GetCertID(int index) {
- if (0 <= index && index < static_cast<int>(user_certs_.size())) {
- net::X509Certificate* cert = user_certs_[index].get();
- return x509_certificate_model::GetPkcs11Id(cert->os_cert_handle());
- }
- return std::string();
+ return cert_library_->GetUserCertificates().GetDisplayStringAt(combo_index);
}
-
private:
- net::CertificateList user_certs_;
+ CertLibrary* cert_library_;
DISALLOW_COPY_AND_ASSIGN(UserCertComboboxModel);
};
VPNConfigView::VPNConfigView(NetworkConfigView* parent, VirtualNetwork* vpn)
- : ChildNetworkConfigView(parent, vpn) {
+ : ChildNetworkConfigView(parent, vpn),
+ cert_library_(NULL) {
Init(vpn);
}
VPNConfigView::VPNConfigView(NetworkConfigView* parent)
- : ChildNetworkConfigView(parent) {
+ : ChildNetworkConfigView(parent),
+ cert_library_(NULL) {
Init(NULL);
}
VPNConfigView::~VPNConfigView() {
+ if (cert_library_)
+ cert_library_->RemoveObserver(this);
}
void VPNConfigView::UpdateCanLogin() {
@@ -218,41 +160,13 @@ bool VPNConfigView::CanLogin() {
return true;
}
-void VPNConfigView::UpdateErrorLabel() {
- std::string error_msg;
- if (UserCertRequired() && !HaveUserCerts())
- error_msg = l10n_util::GetStringUTF8(
- IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PLEASE_INSTALL_USER_CERT);
- if (!service_path_.empty()) {
- // TODO(kuan): differentiate between bad psk and user passphrases.
- NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
- VirtualNetwork* vpn = cros->FindVirtualNetworkByPath(service_path_);
- if (vpn && vpn->failed()) {
- if (vpn->error() == ERROR_BAD_PASSPHRASE) {
- error_msg = l10n_util::GetStringUTF8(
- IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_BAD_PASSPHRASE);
- } else {
- error_msg = vpn->GetErrorString();
- }
- }
- }
- if (!error_msg.empty()) {
- error_label_->SetText(UTF8ToWide(error_msg));
- error_label_->SetVisible(true);
- } else {
- error_label_->SetVisible(false);
- }
-}
-
bool VPNConfigView::UserCertRequired() const {
return provider_type_ == VirtualNetwork::PROVIDER_TYPE_L2TP_IPSEC_USER_CERT
|| provider_type_ == VirtualNetwork::PROVIDER_TYPE_OPEN_VPN;
}
bool VPNConfigView::HaveUserCerts() const {
- UserCertComboboxModel* model = static_cast<UserCertComboboxModel*>(
- user_cert_combobox_->model());
- return model->HaveCerts();
+ return cert_library_->GetUserCertificates().Size() > 0;
}
void VPNConfigView::ContentsChanged(views::Textfield* sender,
@@ -294,8 +208,7 @@ void VPNConfigView::ItemChanged(views::Combobox* combo_box,
return;
if (combo_box == provider_type_combobox_) {
provider_type_ = static_cast<VirtualNetwork::ProviderType>(new_index);
- EnableControls();
- UpdateErrorLabel();
+ Refresh();
} else if (combo_box == user_cert_combobox_) {
// Nothing to do for now.
} else if (combo_box == server_ca_cert_combobox_) {
@@ -306,6 +219,10 @@ void VPNConfigView::ItemChanged(views::Combobox* combo_box,
UpdateCanLogin();
}
+void VPNConfigView::OnCertificatesLoaded(bool initial_load) {
+ Refresh();
+}
+
bool VPNConfigView::Login() {
NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
if (service_path_.empty()) {
@@ -422,29 +339,41 @@ const std::string VPNConfigView::GetUserPassphrase() const {
}
const std::string VPNConfigView::GetServerCACertNssNickname() const {
+ DCHECK(server_ca_cert_combobox_);
+ DCHECK(cert_library_);
int selected = server_ca_cert_combobox_->selected_item();
if (selected == 0) {
// First item is "Default".
return std::string();
} else {
+ DCHECK(cert_library_);
+ DCHECK(cert_library_->GetCACertificates().Size() > 0);
int cert_index = selected - 1;
- ServerCACertComboboxModel* model = static_cast<ServerCACertComboboxModel*>(
- server_ca_cert_combobox_->model());
- return model->GetCertNssNickname(cert_index);
+ return cert_library_->GetCACertificates().GetNicknameAt(cert_index);
}
}
const std::string VPNConfigView::GetUserCertID() const {
- int selected = user_cert_combobox_->selected_item();
- UserCertComboboxModel* model = static_cast<UserCertComboboxModel*>(
- user_cert_combobox_->model());
- return model->GetCertID(selected);
+ DCHECK(user_cert_combobox_);
+ DCHECK(cert_library_);
+ if (cert_library_->GetUserCertificates().Size() == 0) {
+ return std::string(); // "None installed"
+ } else {
+ // Certificates are listed in the order they appear in the model.
+ int selected = user_cert_combobox_->selected_item();
+ return cert_library_->GetUserCertificates().GetPkcs11IdAt(selected);
+ }
}
void VPNConfigView::Init(VirtualNetwork* vpn) {
views::GridLayout* layout = views::GridLayout::CreatePanel(this);
SetLayoutManager(layout);
+ // VPN may require certificates, so always set the library and observe.
+ cert_library_ = chromeos::CrosLibrary::Get()->GetCertLibrary();
+ cert_library_->AddObserver(this);
+ cert_library_->RequestCertificates();
+
int column_view_set_id = 0;
views::ColumnSet* column_set = layout->AddColumnSet(column_view_set_id);
// Label.
@@ -540,19 +469,8 @@ void VPNConfigView::Init(VirtualNetwork* vpn) {
IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT_SERVER_CA)));
layout->AddView(server_ca_cert_label_);
ServerCACertComboboxModel* server_ca_cert_model =
- new ServerCACertComboboxModel();
+ new ServerCACertComboboxModel(cert_library_);
server_ca_cert_combobox_ = new views::Combobox(server_ca_cert_model);
- if (vpn && !vpn->ca_cert_nss().empty()) {
- // Select the current server CA certificate in the combobox.
- for (int i = 0; i < server_ca_cert_model->GetCertCount(); ++i) {
- std::string cert_name = server_ca_cert_model->GetCertNssNickname(i);
- if (cert_name == vpn->ca_cert_nss()) {
- int item_index = i + 1; // First item is "Default"
- server_ca_cert_combobox_->SetSelectedItem(item_index);
- break;
- }
- }
- }
layout->AddView(server_ca_cert_combobox_);
layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
@@ -561,19 +479,10 @@ void VPNConfigView::Init(VirtualNetwork* vpn) {
user_cert_label_ = new views::Label(UTF16ToWide(l10n_util::GetStringUTF16(
IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_VPN_USER_CERT)));
layout->AddView(user_cert_label_);
- UserCertComboboxModel* user_cert_model = new UserCertComboboxModel();
+ UserCertComboboxModel* user_cert_model =
+ new UserCertComboboxModel(cert_library_);
user_cert_combobox_ = new views::Combobox(user_cert_model);
user_cert_combobox_->set_listener(this);
- if (vpn && !vpn->client_cert_id().empty()) {
- // Select the current user certificate in the combobox.
- for (int i = 0; i < user_cert_model->GetItemCount(); ++i) {
- std::string cert_id = user_cert_model->GetCertID(i);
- if (cert_id == vpn->client_cert_id()) {
- user_cert_combobox_->SetSelectedItem(i);
- break;
- }
- }
- }
layout->AddView(user_cert_combobox_);
layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
@@ -609,14 +518,14 @@ void VPNConfigView::Init(VirtualNetwork* vpn) {
error_label_->SetColor(SK_ColorRED);
layout->AddView(error_label_);
- // Enable controls based on provider type combo.
- EnableControls();
-
- // Set or hide the error text.
- UpdateErrorLabel();
+ // Set or hide the UI, update comboboxes and error labels.
+ Refresh();
}
-void VPNConfigView::EnableControls() {
+void VPNConfigView::Refresh() {
+ NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
+
+ // Enable controls.
switch (provider_type_) {
case VirtualNetwork::PROVIDER_TYPE_L2TP_IPSEC_PSK:
psk_passphrase_label_->SetEnabled(true);
@@ -648,6 +557,61 @@ void VPNConfigView::EnableControls() {
NOTREACHED();
break;
}
+
+ // Set certificate combo boxes.
+ VirtualNetwork* vpn = cros->FindVirtualNetworkByPath(service_path_);
+ server_ca_cert_combobox_->ModelChanged();
+ if (server_ca_cert_combobox_->IsEnabled() &&
+ (vpn && !vpn->ca_cert_nss().empty())) {
+ // Select the current server CA certificate in the combobox.
+ int cert_index = cert_library_->GetCACertificates().FindCertByNickname(
+ vpn->ca_cert_nss());
+ if (cert_index >= 0) {
+ // Skip item for "Default"
+ server_ca_cert_combobox_->SetSelectedItem(1 + cert_index);
+ } else {
+ server_ca_cert_combobox_->SetSelectedItem(0);
+ }
+ } else {
+ server_ca_cert_combobox_->SetSelectedItem(0);
+ }
+
+ user_cert_combobox_->ModelChanged();
+ if (user_cert_combobox_->IsEnabled() &&
+ (vpn && !vpn->client_cert_id().empty())) {
+ int cert_index = cert_library_->GetUserCertificates().FindCertByPkcs11Id(
+ vpn->client_cert_id());
+ if (cert_index >= 0)
+ user_cert_combobox_->SetSelectedItem(cert_index);
+ else
+ user_cert_combobox_->SetSelectedItem(0);
+ } else {
+ user_cert_combobox_->SetSelectedItem(0);
+ }
+
+ // Error message.
+ std::string error_msg;
+ if (UserCertRequired() && !HaveUserCerts())
+ error_msg = l10n_util::GetStringUTF8(
+ IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PLEASE_INSTALL_USER_CERT);
+ if (!service_path_.empty()) {
+ // TODO(kuan): differentiate between bad psk and user passphrases.
+ VirtualNetwork* vpn = cros->FindVirtualNetworkByPath(service_path_);
+ if (vpn && vpn->failed()) {
+ if (vpn->error() == ERROR_BAD_PASSPHRASE) {
+ error_msg = l10n_util::GetStringUTF8(
+ IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_BAD_PASSPHRASE);
+ } else {
+ error_msg = vpn->GetErrorString();
+ }
+ }
+ }
+ if (!error_msg.empty()) {
+ error_label_->SetText(UTF8ToWide(error_msg));
+ error_label_->SetVisible(true);
+ } else {
+ error_label_->SetVisible(false);
+ }
}
} // namespace chromeos
diff --git a/chrome/browser/chromeos/options/vpn_config_view.h b/chrome/browser/chromeos/options/vpn_config_view.h
index a2c6c5c..3280545 100644
--- a/chrome/browser/chromeos/options/vpn_config_view.h
+++ b/chrome/browser/chromeos/options/vpn_config_view.h
@@ -9,7 +9,7 @@
#include <string>
#include "base/string16.h"
-#include "chrome/browser/chromeos/cros/network_library.h"
+#include "chrome/browser/chromeos/cros/cert_library.h"
#include "chrome/browser/chromeos/options/network_config_view.h"
#include "chrome/browser/ui/shell_dialogs.h"
#include "views/controls/button/button.h"
@@ -27,24 +27,29 @@ namespace chromeos {
class VPNConfigView : public ChildNetworkConfigView,
public views::TextfieldController,
public views::ButtonListener,
- public views::Combobox::Listener {
+ public views::Combobox::Listener,
+ public CertLibrary::Observer {
public:
VPNConfigView(NetworkConfigView* parent, VirtualNetwork* vpn);
explicit VPNConfigView(NetworkConfigView* parent);
virtual ~VPNConfigView();
// views::TextfieldController methods.
- virtual void ContentsChanged(views::Textfield* sender,
- const string16& new_contents);
- virtual bool HandleKeyEvent(views::Textfield* sender,
- const views::KeyEvent& key_event);
+ virtual void ContentsChanged(
+ views::Textfield* sender, const string16& new_contents) OVERRIDE;
+ virtual bool HandleKeyEvent(
+ views::Textfield* sender, const views::KeyEvent& key_event) OVERRIDE;
// views::ButtonListener
- virtual void ButtonPressed(views::Button* sender, const views::Event& event);
+ virtual void ButtonPressed(
+ views::Button* sender, const views::Event& event) OVERRIDE;
// views::Combobox::Listener
- virtual void ItemChanged(views::Combobox* combo_box,
- int prev_index, int new_index);
+ virtual void ItemChanged(
+ views::Combobox* combo_box, int prev_index, int new_index) OVERRIDE;
+
+ // CertLibrary::Observer:
+ virtual void OnCertificatesLoaded(bool initial_load) OVERRIDE;
// ChildNetworkConfigView implementation.
virtual string16 GetTitle() OVERRIDE;
@@ -57,14 +62,11 @@ class VPNConfigView : public ChildNetworkConfigView,
// Initializes data members and create UI controls.
void Init(VirtualNetwork* vpn);
- void EnableControls();
+ void Refresh();
// Update state of the Login button.
void UpdateCanLogin();
- // Update the error text label.
- void UpdateErrorLabel();
-
// Returns true if the provider type requires a user certificate.
bool UserCertRequired() const;
@@ -84,6 +86,8 @@ class VPNConfigView : public ChildNetworkConfigView,
const std::string GetServerCACertNssNickname() const;
const std::string GetUserCertID() const;
+ CertLibrary* cert_library_;
+
std::string server_hostname_;
string16 service_name_from_server_;
bool service_text_modified_;
diff --git a/chrome/browser/chromeos/options/wifi_config_model.cc b/chrome/browser/chromeos/options/wifi_config_model.cc
deleted file mode 100644
index 9147d8c..0000000
--- a/chrome/browser/chromeos/options/wifi_config_model.cc
+++ /dev/null
@@ -1,191 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/chromeos/options/wifi_config_model.h"
-
-#include <algorithm>
-
-#include "base/utf_string_conversions.h"
-#include "chrome/browser/browser_process.h" // g_browser_process
-#include "chrome/common/net/x509_certificate_model.h"
-#include "crypto/nss_util.h" // crypto::GetTPMTokenInfo()
-#include "net/base/cert_database.h"
-#include "net/base/x509_certificate.h"
-#include "ui/base/l10n/l10n_util_collator.h" // CompareString16WithCollator
-#include "unicode/coll.h" // icu::Collator
-
-namespace chromeos {
-
-namespace {
-
-typedef scoped_refptr<net::X509Certificate> X509CertificateRefPtr;
-
-// Root CA certificates that are built into Chrome use this token name.
-const char* const kRootCertificateTokenName = "Builtin Object Token";
-
-// Returns a user-visible name for a given certificate.
-string16 GetCertDisplayString(const net::X509Certificate* cert) {
- DCHECK(cert);
- std::string name_or_nick =
- x509_certificate_model::GetCertNameOrNickname(cert->os_cert_handle());
- return UTF8ToUTF16(name_or_nick);
-}
-
-// Comparison functor for locale-sensitive sorting of certificates by name.
-class CertNameComparator {
- public:
- explicit CertNameComparator(icu::Collator* collator)
- : collator_(collator) {
- }
-
- bool operator()(const X509CertificateRefPtr& lhs,
- const X509CertificateRefPtr& rhs) const {
- string16 lhs_name = GetCertDisplayString(lhs);
- string16 rhs_name = GetCertDisplayString(rhs);
- if (collator_ == NULL)
- return lhs_name < rhs_name;
- return l10n_util::CompareString16WithCollator(
- collator_, lhs_name, rhs_name) == UCOL_LESS;
- }
-
- private:
- icu::Collator* collator_;
-};
-
-} // namespace
-
-WifiConfigModel::WifiConfigModel() {
-}
-
-WifiConfigModel::~WifiConfigModel() {
-}
-
-void WifiConfigModel::UpdateCertificates() {
- // CertDatabase and its wrappers do not have random access to certificates,
- // so build filtered lists once.
- net::CertificateList cert_list;
- cert_db_.ListCerts(&cert_list);
-
- // Need TPM token name to filter user certificates.
- std::string tpm_token_name;
- if (crypto::IsTPMTokenReady()) {
- std::string unused_pin;
- // TODO(jamescook): Make this asynchronous. It results in a synchronous
- // D-Bus call to cryptohome.
- crypto::GetTPMTokenInfo(&tpm_token_name, &unused_pin);
- } else {
- LOG(WARNING) << "TPM token not ready";
- }
-
- for (net::CertificateList::const_iterator it = cert_list.begin();
- it != cert_list.end();
- ++it) {
- net::X509Certificate* cert = it->get();
- net::X509Certificate::OSCertHandle cert_handle = cert->os_cert_handle();
- net::CertType type = x509_certificate_model::GetType(cert_handle);
- switch (type) {
- case net::USER_CERT: {
- // Only include user certs that are in the TPM token (and hence
- // available via PKCS#11 to flimflam and wpa_supplicant).
- std::string cert_token_name =
- x509_certificate_model::GetTokenName(cert_handle);
- if (cert_token_name == tpm_token_name)
- user_certs_.push_back(*it);
- 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(*it);
- break;
- }
- default:
- // We only care about those two types.
- 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_.begin(), user_certs_.end(), cert_name_comparator);
- std::sort(server_ca_certs_.begin(), server_ca_certs_.end(),
- cert_name_comparator);
-}
-
-int WifiConfigModel::GetUserCertCount() const {
- return static_cast<int>(user_certs_.size());
-}
-
-string16 WifiConfigModel::GetUserCertName(int cert_index) const {
- DCHECK_GE(cert_index, 0);
- DCHECK_LT(cert_index, static_cast<int>(user_certs_.size()));
- net::X509Certificate* cert = user_certs_[cert_index].get();
- return GetCertDisplayString(cert);
-}
-
-std::string WifiConfigModel::GetUserCertPkcs11Id(int cert_index) const {
- DCHECK_GE(cert_index, 0);
- DCHECK_LT(cert_index, static_cast<int>(user_certs_.size()));
- net::X509Certificate* cert = user_certs_[cert_index].get();
- net::X509Certificate::OSCertHandle cert_handle = cert->os_cert_handle();
- return x509_certificate_model::GetPkcs11Id(cert_handle);
-}
-
-int WifiConfigModel::GetUserCertIndex(const std::string& pkcs11_id) const {
- // The list of user certs is small, so just test each one.
- for (int index = 0; index < static_cast<int>(user_certs_.size()); ++index) {
- net::X509Certificate* cert = user_certs_[index].get();
- net::X509Certificate::OSCertHandle cert_handle = cert->os_cert_handle();
- std::string id = x509_certificate_model::GetPkcs11Id(cert_handle);
- if (id == pkcs11_id)
- return index;
- }
- // Not found.
- return -1;
-}
-
-int WifiConfigModel::GetServerCaCertCount() const {
- return static_cast<int>(server_ca_certs_.size());
-}
-
-string16 WifiConfigModel::GetServerCaCertName(int cert_index) const {
- DCHECK_GE(cert_index, 0);
- DCHECK_LT(cert_index, static_cast<int>(server_ca_certs_.size()));
- net::X509Certificate* cert = server_ca_certs_[cert_index].get();
- return GetCertDisplayString(cert);
-}
-
-std::string WifiConfigModel::GetServerCaCertNssNickname(int cert_index) const {
- DCHECK_GE(cert_index, 0);
- DCHECK_LT(cert_index, static_cast<int>(server_ca_certs_.size()));
- net::X509Certificate* cert = server_ca_certs_[cert_index].get();
- net::X509Certificate::OSCertHandle cert_handle = cert->os_cert_handle();
- return x509_certificate_model::GetNickname(cert_handle);
-}
-
-int WifiConfigModel::GetServerCaCertIndex(
- const std::string& nss_nickname) const {
- // List of server certs is small, so just test each one.
- for (int i = 0; i < static_cast<int>(server_ca_certs_.size()); ++i) {
- net::X509Certificate* cert = server_ca_certs_[i].get();
- net::X509Certificate::OSCertHandle cert_handle = cert->os_cert_handle();
- std::string nickname = x509_certificate_model::GetNickname(cert_handle);
- if (nickname == nss_nickname)
- return i;
- }
- // Not found.
- return -1;
-}
-
-} // namespace chromeos
diff --git a/chrome/browser/chromeos/options/wifi_config_model.h b/chrome/browser/chromeos/options/wifi_config_model.h
deleted file mode 100644
index b56822b..0000000
--- a/chrome/browser/chromeos/options/wifi_config_model.h
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_CHROMEOS_OPTIONS_WIFI_CONFIG_MODEL_H_
-#define CHROME_BROWSER_CHROMEOS_OPTIONS_WIFI_CONFIG_MODEL_H_
-#pragma once
-
-#include <string>
-
-#include "base/string16.h"
-#include "net/base/cert_database.h"
-
-namespace chromeos {
-
-// Data model for Wi-Fi connection configuration dialog. Mostly concerned
-// with certificate management for Extensible Authentication Protocol (EAP)
-// enterprise networks.
-class WifiConfigModel {
- public:
- // Constructs a model with empty lists of certificates. If you are
- // configuring a 802.1X network, call UpdateCertificates() to build the
- // internal cache of certificate names and IDs.
- WifiConfigModel();
- ~WifiConfigModel();
-
- // Updates the cached certificate lists.
- void UpdateCertificates();
-
- // Returns the number of user certificates.
- int GetUserCertCount() const;
-
- // Returns a user-visible name for a given user certificate.
- string16 GetUserCertName(int cert_index) const;
-
- // Returns the PKCS#11 ID for a given user certificate.
- std::string GetUserCertPkcs11Id(int cert_index) const;
-
- // Returns the cert_index for a given PKCS#11 user certificate ID,
- // or -1 if no certificate with that ID exists.
- int GetUserCertIndex(const std::string& pkcs11_id) const;
-
- // Returns the number of server CA certificates.
- int GetServerCaCertCount() const;
-
- // Returns a user-visible name for a given server CA certificate.
- string16 GetServerCaCertName(int cert_index) const;
-
- // Returns the NSS nickname for a given server CA certificate.
- std::string GetServerCaCertNssNickname(int cert_index) const;
-
- // Returns the cert_index for a given server CA certificate NSS nickname,
- // or -1 if no certificate with that ID exists.
- int GetServerCaCertIndex(const std::string& nss_nickname) const;
-
- private:
- net::CertDatabase cert_db_;
-
- // List of user certificates, sorted by name.
- net::CertificateList user_certs_;
-
- // List of server CA certificates, sorted by name.
- net::CertificateList server_ca_certs_;
-
- DISALLOW_COPY_AND_ASSIGN(WifiConfigModel);
-};
-
-} // namespace chromeos
-
-#endif // CHROME_BROWSER_CHROMEOS_OPTIONS_WIFI_CONFIG_MODEL_H_
diff --git a/chrome/browser/chromeos/options/wifi_config_view.cc b/chrome/browser/chromeos/options/wifi_config_view.cc
index 63e640c..d39be7b 100644
--- a/chrome/browser/chromeos/options/wifi_config_view.cc
+++ b/chrome/browser/chromeos/options/wifi_config_view.cc
@@ -7,8 +7,8 @@
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/chromeos/cros/cros_library.h"
+#include "chrome/browser/chromeos/cros/network_library.h"
#include "chrome/browser/chromeos/login/user_manager.h"
-#include "chrome/browser/chromeos/options/wifi_config_model.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "grit/locale_settings.h"
@@ -179,15 +179,21 @@ class ComboboxWithWidth : public views::Combobox {
class ServerCACertComboboxModel : public ui::ComboboxModel {
public:
- explicit ServerCACertComboboxModel(WifiConfigModel* wifi_config_model)
- : wifi_config_model_(wifi_config_model) {
+ explicit ServerCACertComboboxModel(CertLibrary* cert_library)
+ : cert_library_(cert_library) {
+ DCHECK(cert_library);
}
virtual ~ServerCACertComboboxModel() {}
virtual int GetItemCount() {
+ if (!cert_library_->CertificatesLoaded())
+ return 1; // "Loading"
// First "Default", then the certs, then "Do not check".
- return wifi_config_model_->GetServerCaCertCount() + 2;
+ return cert_library_->GetCACertificates().Size() + 2;
}
virtual string16 GetItemAt(int combo_index) {
+ if (!cert_library_->CertificatesLoaded())
+ return l10n_util::GetStringUTF16(
+ IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT_LOADING);
if (combo_index == 0)
return l10n_util::GetStringUTF16(
IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT_SERVER_CA_DEFAULT);
@@ -195,46 +201,53 @@ class ServerCACertComboboxModel : public ui::ComboboxModel {
return l10n_util::GetStringUTF16(
IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT_SERVER_CA_DO_NOT_CHECK);
int cert_index = combo_index - 1;
- return wifi_config_model_->GetServerCaCertName(cert_index);
+ return cert_library_->GetCACertificates().GetDisplayStringAt(cert_index);
}
private:
- WifiConfigModel* wifi_config_model_;
+ CertLibrary* cert_library_;
DISALLOW_COPY_AND_ASSIGN(ServerCACertComboboxModel);
};
-class ClientCertComboboxModel : public ui::ComboboxModel {
+class UserCertComboboxModel : public ui::ComboboxModel {
public:
- explicit ClientCertComboboxModel(WifiConfigModel* wifi_config_model)
- : wifi_config_model_(wifi_config_model) {
+ explicit UserCertComboboxModel(CertLibrary* cert_library)
+ : cert_library_(cert_library) {
+ DCHECK(cert_library);
}
- virtual ~ClientCertComboboxModel() {}
+ virtual ~UserCertComboboxModel() {}
virtual int GetItemCount() {
- if (wifi_config_model_->GetUserCertCount() == 0)
- return 1; // "None installed" item.
- return wifi_config_model_->GetUserCertCount();
+ if (!cert_library_->CertificatesLoaded())
+ return 1; // "Loading"
+ int num_certs = cert_library_->GetUserCertificates().Size();
+ if (num_certs == 0)
+ return 1; // "None installed"
+ return num_certs;
}
virtual string16 GetItemAt(int combo_index) {
- if (wifi_config_model_->GetUserCertCount() == 0)
+ if (!cert_library_->CertificatesLoaded())
+ return l10n_util::GetStringUTF16(
+ IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT_LOADING);
+ if (cert_library_->GetUserCertificates().Size() == 0)
return l10n_util::GetStringUTF16(
IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_USER_CERT_NONE_INSTALLED);
- return wifi_config_model_->GetUserCertName(combo_index);
+ return cert_library_->GetUserCertificates().GetDisplayStringAt(combo_index);
}
private:
- WifiConfigModel* wifi_config_model_;
- DISALLOW_COPY_AND_ASSIGN(ClientCertComboboxModel);
+ CertLibrary* cert_library_;
+ DISALLOW_COPY_AND_ASSIGN(UserCertComboboxModel);
};
} // namespace
WifiConfigView::WifiConfigView(NetworkConfigView* parent, WifiNetwork* wifi)
: ChildNetworkConfigView(parent, wifi),
- wifi_config_model_(new WifiConfigModel()),
+ cert_library_(NULL),
ssid_textfield_(NULL),
eap_method_combobox_(NULL),
phase_2_auth_label_(NULL),
phase_2_auth_combobox_(NULL),
- client_cert_label_(NULL),
- client_cert_combobox_(NULL),
+ user_cert_label_(NULL),
+ user_cert_combobox_(NULL),
server_ca_cert_label_(NULL),
server_ca_cert_combobox_(NULL),
identity_label_(NULL),
@@ -252,13 +265,13 @@ WifiConfigView::WifiConfigView(NetworkConfigView* parent, WifiNetwork* wifi)
WifiConfigView::WifiConfigView(NetworkConfigView* parent, bool show_8021x)
: ChildNetworkConfigView(parent),
- wifi_config_model_(new WifiConfigModel()),
+ cert_library_(NULL),
ssid_textfield_(NULL),
eap_method_combobox_(NULL),
phase_2_auth_label_(NULL),
phase_2_auth_combobox_(NULL),
- client_cert_label_(NULL),
- client_cert_combobox_(NULL),
+ user_cert_label_(NULL),
+ user_cert_combobox_(NULL),
server_ca_cert_label_(NULL),
server_ca_cert_combobox_(NULL),
identity_label_(NULL),
@@ -275,6 +288,8 @@ WifiConfigView::WifiConfigView(NetworkConfigView* parent, bool show_8021x)
}
WifiConfigView::~WifiConfigView() {
+ if (cert_library_)
+ cert_library_->RemoveObserver(this);
}
string16 WifiConfigView::GetTitle() {
@@ -300,18 +315,23 @@ bool WifiConfigView::CanLogin() {
&& eap_method_combobox_->selected_item() == EAP_METHOD_INDEX_NONE)
return false;
- // Show an error and block login if certs are required but user has none.
- if (UserCertRequired() && wifi_config_model_->GetUserCertCount() == 0)
+ // Block login if certs are required but user has none.
+ if (UserCertRequired() && cert_library_->GetUserCertificates().Size() == 0)
return false;
return true;
}
-bool WifiConfigView::UserCertRequired() const {
+bool WifiConfigView::UserCertRequired() {
+ if (!cert_library_)
+ return false; // return false until cert_library_ is initialized.
// Only EAP-TLS requires a user certificate.
- return eap_method_combobox_ &&
+ if (eap_method_combobox_ &&
eap_method_combobox_->IsEnabled() &&
- eap_method_combobox_->selected_item() == EAP_METHOD_INDEX_TLS;
+ eap_method_combobox_->selected_item() == EAP_METHOD_INDEX_TLS) {
+ return true;
+ }
+ return false;
}
void WifiConfigView::UpdateDialogButtons() {
@@ -319,6 +339,7 @@ void WifiConfigView::UpdateDialogButtons() {
}
void WifiConfigView::RefreshEapFields() {
+ DCHECK(cert_library_);
int selected = eap_method_combobox_->selected_item();
// If EAP method changes, the phase 2 auth choices may have changed also.
@@ -335,16 +356,23 @@ void WifiConfigView::RefreshEapFields() {
if (!passphrase_textfield_->IsEnabled())
passphrase_textfield_->SetText(string16());
- // Client certs only for EAP-TLS
- bool is_tls = selected == EAP_METHOD_INDEX_TLS;
- client_cert_label_->SetEnabled(is_tls);
- bool have_user_certs = wifi_config_model_->GetUserCertCount() > 0;
- client_cert_combobox_->SetEnabled(is_tls && have_user_certs);
+ // User certs only for EAP-TLS
+ bool certs_loading = !cert_library_->CertificatesLoaded();
+ bool user_cert_enabled = (selected == EAP_METHOD_INDEX_TLS);
+ user_cert_label_->SetEnabled(user_cert_enabled);
+ bool have_user_certs =
+ !certs_loading && cert_library_->GetUserCertificates().Size() > 0;
+ user_cert_combobox_->SetEnabled(user_cert_enabled && have_user_certs);
+ user_cert_combobox_->ModelChanged();
+ user_cert_combobox_->SetSelectedItem(0);
// No server CA certs for LEAP
- server_ca_cert_combobox_->SetEnabled(selected != EAP_METHOD_INDEX_NONE &&
- selected != EAP_METHOD_INDEX_LEAP);
- server_ca_cert_label_->SetEnabled(server_ca_cert_combobox_->IsEnabled());
+ bool ca_cert_enabled =
+ (selected != EAP_METHOD_INDEX_NONE && selected != EAP_METHOD_INDEX_LEAP);
+ server_ca_cert_label_->SetEnabled(ca_cert_enabled);
+ server_ca_cert_combobox_->SetEnabled(ca_cert_enabled && !certs_loading);
+ server_ca_cert_combobox_->ModelChanged();
+ server_ca_cert_combobox_->SetSelectedItem(0);
// No anonymous identity if no phase 2 auth.
identity_anonymous_textfield_->SetEnabled(
@@ -357,9 +385,17 @@ void WifiConfigView::RefreshEapFields() {
void WifiConfigView::UpdateErrorLabel() {
std::string error_msg;
- if (UserCertRequired() && wifi_config_model_->GetUserCertCount() == 0)
- error_msg = l10n_util::GetStringUTF8(
- IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PLEASE_INSTALL_USER_CERT);
+ if (UserCertRequired() &&
+ cert_library_->CertificatesLoaded() &&
+ cert_library_->GetUserCertificates().Size() == 0) {
+ if (!UserManager::Get()->user_is_logged_in()) {
+ error_msg = l10n_util::GetStringUTF8(
+ IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_LOGIN_FOR_USER_CERT);
+ } else {
+ error_msg = l10n_util::GetStringUTF8(
+ IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PLEASE_INSTALL_USER_CERT);
+ }
+ }
if (!service_path_.empty()) {
NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
const WifiNetwork* wifi = cros->FindWifiNetworkByPath(service_path_);
@@ -438,6 +474,11 @@ void WifiConfigView::ItemChanged(views::Combobox* combo_box,
UpdateDialogButtons();
}
+void WifiConfigView::OnCertificatesLoaded(bool initial_load) {
+ RefreshEapFields();
+ UpdateErrorLabel();
+}
+
bool WifiConfigView::Login() {
NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
if (service_path_.empty()) {
@@ -540,6 +581,7 @@ EAPPhase2Auth WifiConfigView::GetEapPhase2Auth() const {
std::string WifiConfigView::GetEapServerCaCertNssNickname() const {
DCHECK(server_ca_cert_combobox_);
+ DCHECK(cert_library_);
int selected = server_ca_cert_combobox_->selected_item();
if (selected == 0) {
// First item is "Default".
@@ -549,8 +591,9 @@ std::string WifiConfigView::GetEapServerCaCertNssNickname() const {
// Last item is "Do not check".
return std::string();
} else {
+ DCHECK(cert_library_);
int cert_index = selected - 1;
- return wifi_config_model_->GetServerCaCertNssNickname(cert_index);
+ return cert_library_->GetCACertificates().GetNicknameAt(cert_index);
}
}
@@ -561,13 +604,14 @@ bool WifiConfigView::GetEapUseSystemCas() const {
}
std::string WifiConfigView::GetEapClientCertPkcs11Id() const {
- DCHECK(client_cert_combobox_);
- if (wifi_config_model_->GetUserCertCount() == 0) {
+ DCHECK(user_cert_combobox_);
+ DCHECK(cert_library_);
+ if (cert_library_->GetUserCertificates().Size() == 0) {
return std::string(); // "None installed"
} else {
// Certificates are listed in the order they appear in the model.
- int selected = client_cert_combobox_->selected_item();
- return wifi_config_model_->GetUserCertPkcs11Id(selected);
+ int selected = user_cert_combobox_->selected_item();
+ return cert_library_->GetUserCertificates().GetPkcs11IdAt(selected);
}
}
@@ -656,9 +700,12 @@ void WifiConfigView::Init(WifiNetwork* wifi, bool show_8021x) {
layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
}
+ // Only enumerate certificates in the data model for 802.1X networks.
if (show_8021x) {
- // Only enumerate certificates in the data model for 802.1X networks.
- wifi_config_model_->UpdateCertificates();
+ // Initialize cert_library_ for 802.1X netoworks.
+ cert_library_ = chromeos::CrosLibrary::Get()->GetCertLibrary();
+ cert_library_->AddObserver(this);
+ cert_library_->RequestCertificates();
// EAP method
layout->StartRow(0, column_view_set_id);
@@ -690,7 +737,7 @@ void WifiConfigView::Init(WifiNetwork* wifi, bool show_8021x) {
IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT_SERVER_CA)));
layout->AddView(server_ca_cert_label_);
server_ca_cert_combobox_ = new ComboboxWithWidth(
- new ServerCACertComboboxModel(wifi_config_model_.get()),
+ new ServerCACertComboboxModel(cert_library_),
ChildNetworkConfigView::kPassphraseWidth);
server_ca_cert_label_->SetEnabled(false);
server_ca_cert_combobox_->SetEnabled(false);
@@ -698,18 +745,18 @@ void WifiConfigView::Init(WifiNetwork* wifi, bool show_8021x) {
layout->AddView(server_ca_cert_combobox_);
layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
- // Client certificate
+ // User certificate
layout->StartRow(0, column_view_set_id);
- client_cert_label_ = new views::Label(
+ user_cert_label_ = new views::Label(
UTF16ToWide(l10n_util::GetStringUTF16(
IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT)));
- layout->AddView(client_cert_label_);
- client_cert_combobox_ = new views::Combobox(
- new ClientCertComboboxModel(wifi_config_model_.get()));
- client_cert_label_->SetEnabled(false);
- client_cert_combobox_->SetEnabled(false);
- client_cert_combobox_->set_listener(this);
- layout->AddView(client_cert_combobox_);
+ layout->AddView(user_cert_label_);
+ user_cert_combobox_ = new views::Combobox(
+ new UserCertComboboxModel(cert_library_));
+ user_cert_label_->SetEnabled(false);
+ user_cert_combobox_->SetEnabled(false);
+ user_cert_combobox_->set_listener(this);
+ layout->AddView(user_cert_combobox_);
layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
// Identity
@@ -843,7 +890,8 @@ void WifiConfigView::Init(WifiNetwork* wifi, bool show_8021x) {
}
} else {
// select the certificate if available
- int cert_index = wifi_config_model_->GetServerCaCertIndex(nss_nickname);
+ int cert_index =
+ cert_library_->GetCACertificates().FindCertByNickname(nss_nickname);
if (cert_index >= 0) {
// Skip item for "Default"
server_ca_cert_combobox_->SetSelectedItem(1 + cert_index);
@@ -851,14 +899,15 @@ void WifiConfigView::Init(WifiNetwork* wifi, bool show_8021x) {
}
}
- // Client certificate
- if (client_cert_combobox_->IsEnabled()) {
+ // User certificate
+ if (user_cert_combobox_->IsEnabled()) {
const std::string& pkcs11_id =
(wifi ? wifi->eap_client_cert_pkcs11_id() : std::string());
if (!pkcs11_id.empty()) {
- int cert_index = wifi_config_model_->GetUserCertIndex(pkcs11_id);
+ int cert_index =
+ cert_library_->GetUserCertificates().FindCertByPkcs11Id(pkcs11_id);
if (cert_index >= 0) {
- client_cert_combobox_->SetSelectedItem(cert_index);
+ user_cert_combobox_->SetSelectedItem(cert_index);
}
}
}
diff --git a/chrome/browser/chromeos/options/wifi_config_view.h b/chrome/browser/chromeos/options/wifi_config_view.h
index da5ae79..6f21e45 100644
--- a/chrome/browser/chromeos/options/wifi_config_view.h
+++ b/chrome/browser/chromeos/options/wifi_config_view.h
@@ -10,7 +10,7 @@
#include "base/memory/scoped_ptr.h"
#include "base/string16.h"
-#include "chrome/browser/chromeos/cros/network_library.h"
+#include "chrome/browser/chromeos/cros/cert_library.h"
#include "chrome/browser/chromeos/options/network_config_view.h"
#include "ui/base/models/combobox_model.h"
#include "views/controls/button/button.h"
@@ -23,17 +23,17 @@ class Checkbox;
class ImageButton;
class Label;
}
+
class FilePath;
namespace chromeos {
-class WifiConfigModel;
-
// A dialog box for showing a password textfield.
class WifiConfigView : public ChildNetworkConfigView,
public views::TextfieldController,
public views::ButtonListener,
- public views::Combobox::Listener {
+ public views::Combobox::Listener,
+ public CertLibrary::Observer {
public:
// Wifi login dialog for wifi network |wifi|. |wifi| must be a non NULL
// pointer to a WifiNetwork in NetworkLibrary.
@@ -43,17 +43,21 @@ class WifiConfigView : public ChildNetworkConfigView,
virtual ~WifiConfigView();
// views::TextfieldController:
- virtual void ContentsChanged(views::Textfield* sender,
- const string16& new_contents);
- virtual bool HandleKeyEvent(views::Textfield* sender,
- const views::KeyEvent& key_event);
+ virtual void ContentsChanged(
+ views::Textfield* sender, const string16& new_contents) OVERRIDE;
+ virtual bool HandleKeyEvent(
+ views::Textfield* sender, const views::KeyEvent& key_event) OVERRIDE;
// views::ButtonListener:
- virtual void ButtonPressed(views::Button* sender, const views::Event& event);
+ virtual void ButtonPressed(
+ views::Button* sender, const views::Event& event) OVERRIDE;
// views::Combobox::Listener:
- virtual void ItemChanged(views::Combobox* combo_box,
- int prev_index, int new_index);
+ virtual void ItemChanged(
+ views::Combobox* combo_box, int prev_index, int new_index) OVERRIDE;
+
+ // CertLibrary::Observer:
+ virtual void OnCertificatesLoaded(bool initial_load) OVERRIDE;
// ChildNetworkConfigView implementation.
virtual string16 GetTitle() OVERRIDE;
@@ -83,7 +87,7 @@ class WifiConfigView : public ChildNetworkConfigView,
bool GetSaveCredentials() const;
// Returns true if the EAP method requires a user certificate.
- bool UserCertRequired() const;
+ bool UserCertRequired();
// Updates state of the Login button.
void UpdateDialogButtons();
@@ -94,14 +98,14 @@ class WifiConfigView : public ChildNetworkConfigView,
// Updates the error text label.
void UpdateErrorLabel();
- scoped_ptr<WifiConfigModel> wifi_config_model_;
+ CertLibrary* cert_library_;
views::Textfield* ssid_textfield_;
views::Combobox* eap_method_combobox_;
views::Label* phase_2_auth_label_;
views::Combobox* phase_2_auth_combobox_;
- views::Label* client_cert_label_;
- views::Combobox* client_cert_combobox_;
+ views::Label* user_cert_label_;
+ views::Combobox* user_cert_combobox_;
views::Label* server_ca_cert_label_;
views::Combobox* server_ca_cert_combobox_;
views::Label* identity_label_;
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 435c88b..ea52c53 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -359,6 +359,8 @@
'browser/chromeos/cros/brightness_library.h',
'browser/chromeos/cros/burn_library.cc',
'browser/chromeos/cros/burn_library.h',
+ 'browser/chromeos/cros/cert_library.cc',
+ 'browser/chromeos/cros/cert_library.h',
'browser/chromeos/cros/cros_library.cc',
'browser/chromeos/cros/cros_library.h',
'browser/chromeos/cros/cros_library_loader.cc',
@@ -654,8 +656,6 @@
'browser/chromeos/options/network_config_view.h',
'browser/chromeos/options/take_photo_dialog.cc',
'browser/chromeos/options/take_photo_dialog.h',
- 'browser/chromeos/options/wifi_config_model.cc',
- 'browser/chromeos/options/wifi_config_model.h',
'browser/chromeos/options/wifi_config_view.cc',
'browser/chromeos/options/wifi_config_view.h',
'browser/chromeos/options/vpn_config_view.cc',
diff --git a/crypto/nss_util.cc b/crypto/nss_util.cc
index e484abe..3b393fc 100644
--- a/crypto/nss_util.cc
+++ b/crypto/nss_util.cc
@@ -226,6 +226,47 @@ class NSSInitSingleton {
EnsureTPMTokenReady();
}
+ // This is called whenever we want to make sure opencryptoki is
+ // properly loaded, because it can fail shortly after the initial
+ // login while the PINs are being initialized, and we want to retry
+ // if this happens.
+ bool EnsureTPMTokenReady() {
+ // If EnableTPMTokenForNSS hasn't been called, or if everything is
+ // already initialized, then this call succeeds.
+ if (tpm_token_info_delegate_.get() == NULL ||
+ (opencryptoki_module_ && tpm_slot_)) {
+ return true;
+ }
+
+ if (tpm_token_info_delegate_->IsTokenReady()) {
+ // This tries to load the opencryptoki module so NSS can talk to
+ // the hardware TPM.
+ if (!opencryptoki_module_) {
+ opencryptoki_module_ = LoadModule(
+ kOpencryptokiModuleName,
+ kOpencryptokiPath,
+ // trustOrder=100 -- means it'll select this as the most
+ // trusted slot for the mechanisms it provides.
+ // slotParams=... -- selects RSA as the only mechanism, and only
+ // asks for the password when necessary (instead of every
+ // time, or after a timeout).
+ "trustOrder=100 slotParams=(1={slotFlags=[RSA] askpw=only})");
+ }
+ if (opencryptoki_module_) {
+ // If this gets set, then we'll use the TPM for certs with
+ // private keys, otherwise we'll fall back to the software
+ // implementation.
+ tpm_slot_ = GetTPMSlot();
+ return tpm_slot_ != NULL;
+ }
+ }
+ return false;
+ }
+
+ bool IsTPMTokenAvailable() {
+ return tpm_token_info_delegate_->IsTokenAvailable();
+ }
+
void GetTPMTokenInfo(std::string* token_name, std::string* user_pin) {
tpm_token_info_delegate_->GetTokenInfo(token_name, user_pin);
}
@@ -239,6 +280,7 @@ class NSSInitSingleton {
GetTPMTokenInfo(&token_name, NULL);
return FindSlotWithTokenName(token_name);
}
+
#endif // defined(OS_CHROMEOS)
@@ -487,45 +529,6 @@ class NSSInitSingleton {
return db_slot;
}
-#if defined(OS_CHROMEOS)
- // This is called whenever we want to make sure opencryptoki is
- // properly loaded, because it can fail shortly after the initial
- // login while the PINs are being initialized, and we want to retry
- // if this happens.
- bool EnsureTPMTokenReady() {
- // If EnableTPMTokenForNSS hasn't been called, or if everything is
- // already initialized, then this call succeeds.
- if (tpm_token_info_delegate_.get() == NULL ||
- (opencryptoki_module_ && tpm_slot_)) {
- return true;
- }
-
- if (tpm_token_info_delegate_->IsTokenReady()) {
- // This tries to load the opencryptoki module so NSS can talk to
- // the hardware TPM.
- if (!opencryptoki_module_) {
- opencryptoki_module_ = LoadModule(
- kOpencryptokiModuleName,
- kOpencryptokiPath,
- // trustOrder=100 -- means it'll select this as the most
- // trusted slot for the mechanisms it provides.
- // slotParams=... -- selects RSA as the only mechanism, and only
- // asks for the password when necessary (instead of every
- // time, or after a timeout).
- "trustOrder=100 slotParams=(1={slotFlags=[RSA] askpw=only})");
- }
- if (opencryptoki_module_) {
- // If this gets set, then we'll use the TPM for certs with
- // private keys, otherwise we'll fall back to the software
- // implementation.
- tpm_slot_ = GetTPMSlot();
- return tpm_slot_ != NULL;
- }
- }
- return false;
- }
-#endif
-
// If this is set to true NSS is forced to be initialized without a DB.
static bool force_nodb_init_;
@@ -680,10 +683,18 @@ void GetTPMTokenInfo(std::string* token_name, std::string* user_pin) {
g_nss_singleton.Get().GetTPMTokenInfo(token_name, user_pin);
}
+bool IsTPMTokenAvailable() {
+ return g_nss_singleton.Get().IsTPMTokenAvailable();
+}
+
bool IsTPMTokenReady() {
return g_nss_singleton.Get().IsTPMTokenReady();
}
+bool EnsureTPMTokenReady() {
+ return g_nss_singleton.Get().EnsureTPMTokenReady();
+}
+
#endif // defined(OS_CHROMEOS)
// TODO(port): Implement this more simply. We can convert by subtracting an
diff --git a/crypto/nss_util.h b/crypto/nss_util.h
index 1244db9..19298ca 100644
--- a/crypto/nss_util.h
+++ b/crypto/nss_util.h
@@ -93,7 +93,17 @@ class TPMTokenInfoDelegate {
public:
TPMTokenInfoDelegate();
virtual ~TPMTokenInfoDelegate();
+
+ // Returns true if the hardware supports a TPM Token and the TPM is enabled.
+ virtual bool IsTokenAvailable() const = 0;
+
+ // Returns true if the TPM and PKCS#11 token slot is ready to be used.
+ // If IsTokenAvailable() is false this should return false.
+ // If IsTokenAvailable() is true, this should eventually return true.
virtual bool IsTokenReady() const = 0;
+
+ // Fetches token properties. TODO(stevenjb): make this interface asynchronous
+ // so that the implementation does not have to be blocking.
virtual void GetTokenInfo(std::string* token_name,
std::string* user_pin) const = 0;
};
@@ -110,11 +120,18 @@ void EnableTPMTokenForNSS(TPMTokenInfoDelegate* delegate);
// EnableTPMTokenForNSS has been called with a non-null delegate.
void GetTPMTokenInfo(std::string* token_name, std::string* user_pin);
+// Returns true if the machine has a TPM and it can be used to store tokens.
+bool IsTPMTokenAvailable();
+
// Returns true if the TPM is owned and PKCS#11 initialized with the
// user and security officer PINs, and has been enabled in NSS by
// calling EnableTPMForNSS, and opencryptoki has been successfully
// loaded into NSS.
bool IsTPMTokenReady();
+
+// Same as IsTPMTokenReady() except this attempts to initialize the token
+// if necessary.
+bool EnsureTPMTokenReady();
#endif
// Convert a NSS PRTime value into a base::Time object.