summaryrefslogtreecommitdiffstats
path: root/chrome/browser/chromeos/options/wifi_config_model.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/chromeos/options/wifi_config_model.cc')
-rw-r--r--chrome/browser/chromeos/options/wifi_config_model.cc172
1 files changed, 172 insertions, 0 deletions
diff --git a/chrome/browser/chromeos/options/wifi_config_model.cc b/chrome/browser/chromeos/options/wifi_config_model.cc
new file mode 100644
index 0000000..5dc2f52
--- /dev/null
+++ b/chrome/browser/chromeos/options/wifi_config_model.cc
@@ -0,0 +1,172 @@
+// 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 "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);
+ 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:
+ 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(cert_index >= 0);
+ DCHECK(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(cert_index >= 0);
+ DCHECK(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(cert_index >= 0);
+ DCHECK(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(cert_index >= 0);
+ DCHECK(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