Home | History | Annotate | Download | only in browser
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/browser/certificate_manager_model.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/i18n/time_formatting.h"
      9 #include "base/logging.h"
     10 #include "base/strings/utf_string_conversions.h"
     11 #include "chrome/browser/ui/crypto_module_password_dialog.h"
     12 #include "chrome/common/net/x509_certificate_model.h"
     13 #include "net/base/crypto_module.h"
     14 #include "net/base/net_errors.h"
     15 #include "net/cert/x509_certificate.h"
     16 
     17 #if defined(OS_CHROMEOS)
     18 #include <cert.h>
     19 
     20 #include "crypto/nss_util.h"
     21 #include "grit/generated_resources.h"
     22 #include "ui/base/l10n/l10n_util.h"
     23 #endif
     24 
     25 CertificateManagerModel::CertificateManagerModel(Observer* observer)
     26     : cert_db_(net::NSSCertDatabase::GetInstance()),
     27       observer_(observer) {
     28 }
     29 
     30 CertificateManagerModel::~CertificateManagerModel() {
     31 }
     32 
     33 void CertificateManagerModel::Refresh() {
     34   VLOG(1) << "refresh started";
     35   net::CryptoModuleList modules;
     36   cert_db_->ListModules(&modules, false);
     37   VLOG(1) << "refresh waiting for unlocking...";
     38   chrome::UnlockSlotsIfNecessary(
     39       modules,
     40       chrome::kCryptoModulePasswordListCerts,
     41       std::string(),  // unused.
     42       base::Bind(&CertificateManagerModel::RefreshSlotsUnlocked,
     43                  base::Unretained(this)));
     44 }
     45 
     46 void CertificateManagerModel::RefreshSlotsUnlocked() {
     47   VLOG(1) << "refresh listing certs...";
     48   cert_db_->ListCerts(&cert_list_);
     49   observer_->CertificatesRefreshed();
     50   VLOG(1) << "refresh finished";
     51 }
     52 
     53 void CertificateManagerModel::FilterAndBuildOrgGroupingMap(
     54     net::CertType filter_type,
     55     CertificateManagerModel::OrgGroupingMap* map) const {
     56   for (net::CertificateList::const_iterator i = cert_list_.begin();
     57        i != cert_list_.end(); ++i) {
     58     net::X509Certificate* cert = i->get();
     59     net::CertType type =
     60         x509_certificate_model::GetType(cert->os_cert_handle());
     61     if (type != filter_type)
     62       continue;
     63 
     64     std::string org;
     65     if (!cert->subject().organization_names.empty())
     66       org = cert->subject().organization_names[0];
     67     if (org.empty())
     68       org = cert->subject().GetDisplayName();
     69 
     70     (*map)[org].push_back(cert);
     71   }
     72 }
     73 
     74 string16 CertificateManagerModel::GetColumnText(
     75     const net::X509Certificate& cert,
     76     Column column) const {
     77   string16 rv;
     78   switch (column) {
     79     case COL_SUBJECT_NAME:
     80       rv = UTF8ToUTF16(
     81           x509_certificate_model::GetCertNameOrNickname(cert.os_cert_handle()));
     82 
     83 #if defined(OS_CHROMEOS)
     84       // TODO(xiyuan): Put this into a column when we have js tree-table.
     85       if (IsHardwareBacked(&cert)) {
     86         rv = l10n_util::GetStringFUTF16(
     87             IDS_CERT_MANAGER_HARDWARE_BACKED_KEY_FORMAT,
     88             rv,
     89             l10n_util::GetStringUTF16(IDS_CERT_MANAGER_HARDWARE_BACKED));
     90       }
     91 #endif
     92       break;
     93     case COL_CERTIFICATE_STORE:
     94       rv = UTF8ToUTF16(
     95           x509_certificate_model::GetTokenName(cert.os_cert_handle()));
     96       break;
     97     case COL_SERIAL_NUMBER:
     98       rv = ASCIIToUTF16(x509_certificate_model::GetSerialNumberHexified(
     99           cert.os_cert_handle(), std::string()));
    100       break;
    101     case COL_EXPIRES_ON:
    102       if (!cert.valid_expiry().is_null())
    103         rv = base::TimeFormatShortDateNumeric(cert.valid_expiry());
    104       break;
    105     default:
    106       NOTREACHED();
    107   }
    108   return rv;
    109 }
    110 
    111 int CertificateManagerModel::ImportFromPKCS12(net::CryptoModule* module,
    112                                               const std::string& data,
    113                                               const string16& password,
    114                                               bool is_extractable) {
    115   int result = cert_db_->ImportFromPKCS12(module, data, password,
    116                                           is_extractable, NULL);
    117   if (result == net::OK)
    118     Refresh();
    119   return result;
    120 }
    121 
    122 bool CertificateManagerModel::ImportCACerts(
    123     const net::CertificateList& certificates,
    124     net::NSSCertDatabase::TrustBits trust_bits,
    125     net::NSSCertDatabase::ImportCertFailureList* not_imported) {
    126   bool result = cert_db_->ImportCACerts(certificates, trust_bits, not_imported);
    127   if (result && not_imported->size() != certificates.size())
    128     Refresh();
    129   return result;
    130 }
    131 
    132 bool CertificateManagerModel::ImportServerCert(
    133     const net::CertificateList& certificates,
    134     net::NSSCertDatabase::TrustBits trust_bits,
    135     net::NSSCertDatabase::ImportCertFailureList* not_imported) {
    136   bool result = cert_db_->ImportServerCert(certificates, trust_bits,
    137                                            not_imported);
    138   if (result && not_imported->size() != certificates.size())
    139     Refresh();
    140   return result;
    141 }
    142 
    143 bool CertificateManagerModel::SetCertTrust(
    144     const net::X509Certificate* cert,
    145     net::CertType type,
    146     net::NSSCertDatabase::TrustBits trust_bits) {
    147   return cert_db_->SetCertTrust(cert, type, trust_bits);
    148 }
    149 
    150 bool CertificateManagerModel::Delete(net::X509Certificate* cert) {
    151   bool result = cert_db_->DeleteCertAndKey(cert);
    152   if (result)
    153     Refresh();
    154   return result;
    155 }
    156 
    157 bool CertificateManagerModel::IsHardwareBacked(
    158     const net::X509Certificate* cert) const {
    159 #if defined(OS_CHROMEOS)
    160   return crypto::IsTPMTokenReady() &&
    161          cert->os_cert_handle()->slot ==
    162              cert_db_->GetPrivateModule()->os_module_handle();
    163 #else
    164   return false;
    165 #endif
    166 }
    167