NaCl: Update revision in DEPS, r12770 -> r12773
[chromium-blink-merge.git] / chrome / browser / certificate_manager_model.cc
blob96f6f3f466753f2c34edfc9c5299630dc5a6afd0
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.
5 #include "chrome/browser/certificate_manager_model.h"
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/net/nss_context.h"
12 #include "chrome/browser/ui/crypto_module_password_dialog_nss.h"
13 #include "chrome/common/net/x509_certificate_model.h"
14 #include "content/public/browser/browser_context.h"
15 #include "content/public/browser/browser_thread.h"
16 #include "content/public/browser/resource_context.h"
17 #include "crypto/nss_util.h"
18 #include "grit/generated_resources.h"
19 #include "net/base/crypto_module.h"
20 #include "net/base/net_errors.h"
21 #include "net/cert/x509_certificate.h"
22 #include "ui/base/l10n/l10n_util.h"
24 using content::BrowserThread;
26 // CertificateManagerModel is created on the UI thread. It needs a
27 // NSSCertDatabase handle (and on ChromeOS it needs to get the TPM status) which
28 // needs to be done on the IO thread.
30 // The initialization flow is roughly:
32 // UI thread IO Thread
34 // CertificateManagerModel::Create
35 // \--------------------------------------v
36 // CertificateManagerModel::GetCertDBOnIOThread
37 // |
38 // GetNSSCertDatabaseForResourceContext
39 // |
40 // CertificateManagerModel::DidGetCertDBOnIOThread
41 // |
42 // crypto::IsTPMTokenEnabledForNSS
43 // v--------------------------------------/
44 // CertificateManagerModel::DidGetCertDBOnUIThread
45 // |
46 // new CertificateManagerModel
47 // |
48 // callback
50 // static
51 void CertificateManagerModel::Create(
52 content::BrowserContext* browser_context,
53 CertificateManagerModel::Observer* observer,
54 const CreationCallback& callback) {
55 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
56 BrowserThread::PostTask(
57 BrowserThread::IO,
58 FROM_HERE,
59 base::Bind(&CertificateManagerModel::GetCertDBOnIOThread,
60 browser_context->GetResourceContext(),
61 observer,
62 callback));
65 CertificateManagerModel::CertificateManagerModel(
66 net::NSSCertDatabase* nss_cert_database,
67 bool is_tpm_available,
68 Observer* observer)
69 : cert_db_(nss_cert_database),
70 is_tpm_available_(is_tpm_available),
71 observer_(observer) {
72 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
75 CertificateManagerModel::~CertificateManagerModel() {
78 void CertificateManagerModel::Refresh() {
79 DVLOG(1) << "refresh started";
80 net::CryptoModuleList modules;
81 cert_db_->ListModules(&modules, false);
82 DVLOG(1) << "refresh waiting for unlocking...";
83 chrome::UnlockSlotsIfNecessary(
84 modules,
85 chrome::kCryptoModulePasswordListCerts,
86 net::HostPortPair(), // unused.
87 NULL, // TODO(mattm): supply parent window.
88 base::Bind(&CertificateManagerModel::RefreshSlotsUnlocked,
89 base::Unretained(this)));
92 void CertificateManagerModel::RefreshSlotsUnlocked() {
93 DVLOG(1) << "refresh listing certs...";
94 // TODO(tbarzic): Use async |ListCerts|.
95 cert_db_->ListCertsSync(&cert_list_);
96 observer_->CertificatesRefreshed();
97 DVLOG(1) << "refresh finished";
100 void CertificateManagerModel::FilterAndBuildOrgGroupingMap(
101 net::CertType filter_type,
102 CertificateManagerModel::OrgGroupingMap* map) const {
103 for (net::CertificateList::const_iterator i = cert_list_.begin();
104 i != cert_list_.end(); ++i) {
105 net::X509Certificate* cert = i->get();
106 net::CertType type =
107 x509_certificate_model::GetType(cert->os_cert_handle());
108 if (type != filter_type)
109 continue;
111 std::string org;
112 if (!cert->subject().organization_names.empty())
113 org = cert->subject().organization_names[0];
114 if (org.empty())
115 org = cert->subject().GetDisplayName();
117 (*map)[org].push_back(cert);
121 base::string16 CertificateManagerModel::GetColumnText(
122 const net::X509Certificate& cert,
123 Column column) const {
124 base::string16 rv;
125 switch (column) {
126 case COL_SUBJECT_NAME:
127 rv = base::UTF8ToUTF16(
128 x509_certificate_model::GetCertNameOrNickname(cert.os_cert_handle()));
130 // TODO(xiyuan): Put this into a column when we have js tree-table.
131 if (IsHardwareBacked(&cert)) {
132 rv = l10n_util::GetStringFUTF16(
133 IDS_CERT_MANAGER_HARDWARE_BACKED_KEY_FORMAT,
135 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_HARDWARE_BACKED));
137 break;
138 case COL_CERTIFICATE_STORE:
139 rv = base::UTF8ToUTF16(
140 x509_certificate_model::GetTokenName(cert.os_cert_handle()));
141 break;
142 case COL_SERIAL_NUMBER:
143 rv = base::ASCIIToUTF16(x509_certificate_model::GetSerialNumberHexified(
144 cert.os_cert_handle(), std::string()));
145 break;
146 case COL_EXPIRES_ON:
147 if (!cert.valid_expiry().is_null())
148 rv = base::TimeFormatShortDateNumeric(cert.valid_expiry());
149 break;
150 default:
151 NOTREACHED();
153 return rv;
156 int CertificateManagerModel::ImportFromPKCS12(net::CryptoModule* module,
157 const std::string& data,
158 const base::string16& password,
159 bool is_extractable) {
160 int result = cert_db_->ImportFromPKCS12(module, data, password,
161 is_extractable, NULL);
162 if (result == net::OK)
163 Refresh();
164 return result;
167 bool CertificateManagerModel::ImportCACerts(
168 const net::CertificateList& certificates,
169 net::NSSCertDatabase::TrustBits trust_bits,
170 net::NSSCertDatabase::ImportCertFailureList* not_imported) {
171 bool result = cert_db_->ImportCACerts(certificates, trust_bits, not_imported);
172 if (result && not_imported->size() != certificates.size())
173 Refresh();
174 return result;
177 bool CertificateManagerModel::ImportServerCert(
178 const net::CertificateList& certificates,
179 net::NSSCertDatabase::TrustBits trust_bits,
180 net::NSSCertDatabase::ImportCertFailureList* not_imported) {
181 bool result = cert_db_->ImportServerCert(certificates, trust_bits,
182 not_imported);
183 if (result && not_imported->size() != certificates.size())
184 Refresh();
185 return result;
188 bool CertificateManagerModel::SetCertTrust(
189 const net::X509Certificate* cert,
190 net::CertType type,
191 net::NSSCertDatabase::TrustBits trust_bits) {
192 return cert_db_->SetCertTrust(cert, type, trust_bits);
195 bool CertificateManagerModel::Delete(net::X509Certificate* cert) {
196 bool result = cert_db_->DeleteCertAndKey(cert);
197 if (result)
198 Refresh();
199 return result;
202 bool CertificateManagerModel::IsHardwareBacked(
203 const net::X509Certificate* cert) const {
204 return cert_db_->IsHardwareBacked(cert);
207 // static
208 void CertificateManagerModel::DidGetCertDBOnUIThread(
209 net::NSSCertDatabase* cert_db,
210 bool is_tpm_available,
211 CertificateManagerModel::Observer* observer,
212 const CreationCallback& callback) {
213 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
215 scoped_ptr<CertificateManagerModel> model(
216 new CertificateManagerModel(cert_db, is_tpm_available, observer));
217 callback.Run(model.Pass());
220 // static
221 void CertificateManagerModel::DidGetCertDBOnIOThread(
222 CertificateManagerModel::Observer* observer,
223 const CreationCallback& callback,
224 net::NSSCertDatabase* cert_db) {
225 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
227 bool is_tpm_available = false;
228 #if defined(OS_CHROMEOS)
229 is_tpm_available = crypto::IsTPMTokenEnabledForNSS();
230 #endif
231 BrowserThread::PostTask(
232 BrowserThread::UI,
233 FROM_HERE,
234 base::Bind(&CertificateManagerModel::DidGetCertDBOnUIThread,
235 cert_db,
236 is_tpm_available,
237 observer,
238 callback));
241 // static
242 void CertificateManagerModel::GetCertDBOnIOThread(
243 content::ResourceContext* context,
244 CertificateManagerModel::Observer* observer,
245 const CreationCallback& callback) {
246 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
247 net::NSSCertDatabase* cert_db = GetNSSCertDatabaseForResourceContext(
248 context,
249 base::Bind(&CertificateManagerModel::DidGetCertDBOnIOThread,
250 observer,
251 callback));
252 if (cert_db)
253 DidGetCertDBOnIOThread(observer, callback, cert_db);