diff options
Diffstat (limited to 'chrome/browser/chromeos/options/wifi_config_model.cc')
-rw-r--r-- | chrome/browser/chromeos/options/wifi_config_model.cc | 172 |
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 |