certificate_manager_model.cc revision 868fa2fe829687343ffae624259930155e16dbd8
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
25CertificateManagerModel::CertificateManagerModel(Observer* observer)
26    : cert_db_(net::NSSCertDatabase::GetInstance()),
27      observer_(observer) {
28}
29
30CertificateManagerModel::~CertificateManagerModel() {
31}
32
33void 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
46void CertificateManagerModel::RefreshSlotsUnlocked() {
47  VLOG(1) << "refresh listing certs...";
48  cert_db_->ListCerts(&cert_list_);
49  observer_->CertificatesRefreshed();
50  VLOG(1) << "refresh finished";
51}
52
53void 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
74string16 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
111int 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
122bool 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
132bool 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
143bool 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
150bool CertificateManagerModel::Delete(net::X509Certificate* cert) {
151  bool result = cert_db_->DeleteCertAndKey(cert);
152  if (result)
153    Refresh();
154  return result;
155}
156
157bool 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