Popular sites on the NTP: check that experiment group StartsWith (rather than IS...
[chromium-blink-merge.git] / chrome / browser / ui / webui / options / certificate_manager_handler.cc
blobcf03f83b97bb1c5e7a01363601e52618cea1bb7f
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/ui/webui/options/certificate_manager_handler.h"
7 #include <algorithm>
8 #include <map>
10 #include "base/bind.h"
11 #include "base/bind_helpers.h"
12 #include "base/files/file_util.h" // for FileAccessProvider
13 #include "base/i18n/string_compare.h"
14 #include "base/id_map.h"
15 #include "base/memory/scoped_vector.h"
16 #include "base/posix/safe_strerror.h"
17 #include "base/strings/string_number_conversions.h"
18 #include "base/strings/utf_string_conversions.h"
19 #include "base/values.h"
20 #include "chrome/browser/browser_process.h"
21 #include "chrome/browser/certificate_viewer.h"
22 #include "chrome/browser/profiles/profile.h"
23 #include "chrome/browser/ui/certificate_dialogs.h"
24 #include "chrome/browser/ui/chrome_select_file_policy.h"
25 #include "chrome/browser/ui/crypto_module_password_dialog_nss.h"
26 #include "chrome/browser/ui/webui/certificate_viewer_webui.h"
27 #include "chrome/grit/generated_resources.h"
28 #include "content/public/browser/browser_thread.h"
29 #include "content/public/browser/web_contents.h"
30 #include "net/base/crypto_module.h"
31 #include "net/base/net_errors.h"
32 #include "net/cert/x509_certificate.h"
33 #include "ui/base/l10n/l10n_util.h"
35 #if defined(OS_CHROMEOS)
36 #include "chrome/browser/chromeos/policy/user_network_configuration_updater.h"
37 #include "chrome/browser/chromeos/policy/user_network_configuration_updater_factory.h"
38 #endif
40 using base::UTF8ToUTF16;
41 using content::BrowserThread;
43 namespace {
45 static const char kKeyId[] = "id";
46 static const char kSubNodesId[] = "subnodes";
47 static const char kNameId[] = "name";
48 static const char kReadOnlyId[] = "readonly";
49 static const char kUntrustedId[] = "untrusted";
50 static const char kExtractableId[] = "extractable";
51 static const char kErrorId[] = "error";
52 static const char kPolicyTrustedId[] = "policy";
54 // Enumeration of different callers of SelectFile. (Start counting at 1 so
55 // if SelectFile is accidentally called with params=NULL it won't match any.)
56 enum {
57 EXPORT_PERSONAL_FILE_SELECTED = 1,
58 IMPORT_PERSONAL_FILE_SELECTED,
59 IMPORT_SERVER_FILE_SELECTED,
60 IMPORT_CA_FILE_SELECTED,
63 std::string OrgNameToId(const std::string& org) {
64 return "org-" + org;
67 bool CallbackArgsToBool(const base::ListValue* args, int index, bool* result) {
68 std::string string_value;
69 if (!args->GetString(index, &string_value))
70 return false;
72 *result = string_value[0] == 't';
73 return true;
76 struct DictionaryIdComparator {
77 explicit DictionaryIdComparator(icu::Collator* collator)
78 : collator_(collator) {
81 bool operator()(const base::Value* a,
82 const base::Value* b) const {
83 DCHECK(a->GetType() == base::Value::TYPE_DICTIONARY);
84 DCHECK(b->GetType() == base::Value::TYPE_DICTIONARY);
85 const base::DictionaryValue* a_dict =
86 reinterpret_cast<const base::DictionaryValue*>(a);
87 const base::DictionaryValue* b_dict =
88 reinterpret_cast<const base::DictionaryValue*>(b);
89 base::string16 a_str;
90 base::string16 b_str;
91 a_dict->GetString(kNameId, &a_str);
92 b_dict->GetString(kNameId, &b_str);
93 if (collator_ == NULL)
94 return a_str < b_str;
95 return base::i18n::CompareString16WithCollator(*collator_, a_str, b_str) ==
96 UCOL_LESS;
99 icu::Collator* collator_;
102 std::string NetErrorToString(int net_error) {
103 switch (net_error) {
104 // TODO(mattm): handle more cases.
105 case net::ERR_IMPORT_CA_CERT_NOT_CA:
106 return l10n_util::GetStringUTF8(IDS_CERT_MANAGER_ERROR_NOT_CA);
107 case net::ERR_IMPORT_CERT_ALREADY_EXISTS:
108 return l10n_util::GetStringUTF8(
109 IDS_CERT_MANAGER_ERROR_CERT_ALREADY_EXISTS);
110 default:
111 return l10n_util::GetStringUTF8(IDS_CERT_MANAGER_UNKNOWN_ERROR);
115 // Struct to bind the Equals member function to an object for use in find_if.
116 struct CertEquals {
117 explicit CertEquals(const net::X509Certificate* cert) : cert_(cert) {}
118 bool operator()(const scoped_refptr<net::X509Certificate> cert) const {
119 return cert_->Equals(cert.get());
121 const net::X509Certificate* cert_;
124 // Determine whether a certificate was stored with web trust by a policy.
125 bool IsPolicyInstalledWithWebTrust(
126 const net::CertificateList& web_trust_certs,
127 net::X509Certificate* cert) {
128 return std::find_if(web_trust_certs.begin(), web_trust_certs.end(),
129 CertEquals(cert)) != web_trust_certs.end();
132 #if defined(OS_CHROMEOS)
133 void ShowCertificateViewerModalDialog(content::WebContents* web_contents,
134 gfx::NativeWindow parent,
135 net::X509Certificate* cert) {
136 CertificateViewerModalDialog* dialog = new CertificateViewerModalDialog(cert);
137 dialog->Show(web_contents, parent);
139 #endif
141 } // namespace
143 namespace options {
145 ///////////////////////////////////////////////////////////////////////////////
146 // CertIdMap
148 class CertIdMap {
149 public:
150 CertIdMap() {}
151 ~CertIdMap() {}
153 std::string CertToId(net::X509Certificate* cert);
154 net::X509Certificate* IdToCert(const std::string& id);
155 net::X509Certificate* CallbackArgsToCert(const base::ListValue* args);
157 private:
158 typedef std::map<net::X509Certificate*, int32> CertMap;
160 // Creates an ID for cert and looks up the cert for an ID.
161 IDMap<net::X509Certificate>id_map_;
163 // Finds the ID for a cert.
164 CertMap cert_map_;
166 DISALLOW_COPY_AND_ASSIGN(CertIdMap);
169 std::string CertIdMap::CertToId(net::X509Certificate* cert) {
170 CertMap::const_iterator iter = cert_map_.find(cert);
171 if (iter != cert_map_.end())
172 return base::IntToString(iter->second);
174 int32 new_id = id_map_.Add(cert);
175 cert_map_[cert] = new_id;
176 return base::IntToString(new_id);
179 net::X509Certificate* CertIdMap::IdToCert(const std::string& id) {
180 int32 cert_id = 0;
181 if (!base::StringToInt(id, &cert_id))
182 return NULL;
184 return id_map_.Lookup(cert_id);
187 net::X509Certificate* CertIdMap::CallbackArgsToCert(
188 const base::ListValue* args) {
189 std::string node_id;
190 if (!args->GetString(0, &node_id))
191 return NULL;
193 net::X509Certificate* cert = IdToCert(node_id);
194 if (!cert) {
195 NOTREACHED();
196 return NULL;
199 return cert;
202 ///////////////////////////////////////////////////////////////////////////////
203 // FileAccessProvider
205 // TODO(mattm): Move to some shared location?
206 class FileAccessProvider
207 : public base::RefCountedThreadSafe<FileAccessProvider> {
208 public:
209 // The first parameter is 0 on success or errno on failure. The second
210 // parameter is read result.
211 typedef base::Callback<void(const int*, const std::string*)> ReadCallback;
213 // The first parameter is 0 on success or errno on failure. The second
214 // parameter is the number of bytes written on success.
215 typedef base::Callback<void(const int*, const int*)> WriteCallback;
217 base::CancelableTaskTracker::TaskId StartRead(
218 const base::FilePath& path,
219 const ReadCallback& callback,
220 base::CancelableTaskTracker* tracker);
221 base::CancelableTaskTracker::TaskId StartWrite(
222 const base::FilePath& path,
223 const std::string& data,
224 const WriteCallback& callback,
225 base::CancelableTaskTracker* tracker);
227 private:
228 friend class base::RefCountedThreadSafe<FileAccessProvider>;
229 virtual ~FileAccessProvider() {}
231 // Reads file at |path|. |saved_errno| is 0 on success or errno on failure.
232 // When success, |data| has file content.
233 void DoRead(const base::FilePath& path,
234 int* saved_errno,
235 std::string* data);
236 // Writes data to file at |path|. |saved_errno| is 0 on success or errno on
237 // failure. When success, |bytes_written| has number of bytes written.
238 void DoWrite(const base::FilePath& path,
239 const std::string& data,
240 int* saved_errno,
241 int* bytes_written);
244 base::CancelableTaskTracker::TaskId FileAccessProvider::StartRead(
245 const base::FilePath& path,
246 const ReadCallback& callback,
247 base::CancelableTaskTracker* tracker) {
248 // Owned by reply callback posted below.
249 int* saved_errno = new int(0);
250 std::string* data = new std::string();
252 // Post task to file thread to read file.
253 return tracker->PostTaskAndReply(
254 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE).get(),
255 FROM_HERE,
256 base::Bind(&FileAccessProvider::DoRead, this, path, saved_errno, data),
257 base::Bind(callback, base::Owned(saved_errno), base::Owned(data)));
260 base::CancelableTaskTracker::TaskId FileAccessProvider::StartWrite(
261 const base::FilePath& path,
262 const std::string& data,
263 const WriteCallback& callback,
264 base::CancelableTaskTracker* tracker) {
265 // Owned by reply callback posted below.
266 int* saved_errno = new int(0);
267 int* bytes_written = new int(0);
269 // Post task to file thread to write file.
270 return tracker->PostTaskAndReply(
271 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE).get(),
272 FROM_HERE,
273 base::Bind(&FileAccessProvider::DoWrite,
274 this,
275 path,
276 data,
277 saved_errno,
278 bytes_written),
279 base::Bind(
280 callback, base::Owned(saved_errno), base::Owned(bytes_written)));
283 void FileAccessProvider::DoRead(const base::FilePath& path,
284 int* saved_errno,
285 std::string* data) {
286 bool success = base::ReadFileToString(path, data);
287 *saved_errno = success ? 0 : errno;
290 void FileAccessProvider::DoWrite(const base::FilePath& path,
291 const std::string& data,
292 int* saved_errno,
293 int* bytes_written) {
294 *bytes_written = base::WriteFile(path, data.data(), data.size());
295 *saved_errno = *bytes_written >= 0 ? 0 : errno;
298 ///////////////////////////////////////////////////////////////////////////////
299 // CertificateManagerHandler
301 CertificateManagerHandler::CertificateManagerHandler(
302 bool show_certs_in_modal_dialog)
303 : show_certs_in_modal_dialog_(show_certs_in_modal_dialog),
304 requested_certificate_manager_model_(false),
305 use_hardware_backed_(false),
306 file_access_provider_(new FileAccessProvider()),
307 cert_id_map_(new CertIdMap),
308 weak_ptr_factory_(this) {}
310 CertificateManagerHandler::~CertificateManagerHandler() {
313 void CertificateManagerHandler::GetLocalizedValues(
314 base::DictionaryValue* localized_strings) {
315 DCHECK(localized_strings);
317 RegisterTitle(localized_strings, "certificateManagerPage",
318 IDS_CERTIFICATE_MANAGER_TITLE);
320 // Tabs.
321 localized_strings->SetString("personalCertsTabTitle",
322 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_PERSONAL_CERTS_TAB_LABEL));
323 localized_strings->SetString("serverCertsTabTitle",
324 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_SERVER_CERTS_TAB_LABEL));
325 localized_strings->SetString("caCertsTabTitle",
326 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_CERT_AUTHORITIES_TAB_LABEL));
327 localized_strings->SetString("otherCertsTabTitle",
328 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_OTHER_TAB_LABEL));
330 // Tab descriptions.
331 localized_strings->SetString("personalCertsTabDescription",
332 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_USER_TREE_DESCRIPTION));
333 localized_strings->SetString("serverCertsTabDescription",
334 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_SERVER_TREE_DESCRIPTION));
335 localized_strings->SetString("caCertsTabDescription",
336 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_AUTHORITIES_TREE_DESCRIPTION));
337 localized_strings->SetString("otherCertsTabDescription",
338 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_OTHER_TREE_DESCRIPTION));
340 // Buttons.
341 localized_strings->SetString("view_certificate",
342 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_VIEW_CERT_BUTTON));
343 localized_strings->SetString("import_certificate",
344 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_IMPORT_BUTTON));
345 localized_strings->SetString("export_certificate",
346 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_EXPORT_BUTTON));
347 localized_strings->SetString("edit_certificate",
348 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_EDIT_BUTTON));
349 localized_strings->SetString("delete_certificate",
350 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_DELETE_BUTTON));
352 // Certificate Delete overlay strings.
353 localized_strings->SetString("personalCertsTabDeleteConfirm",
354 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_DELETE_USER_FORMAT));
355 localized_strings->SetString("personalCertsTabDeleteImpact",
356 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_DELETE_USER_DESCRIPTION));
357 localized_strings->SetString("serverCertsTabDeleteConfirm",
358 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_DELETE_SERVER_FORMAT));
359 localized_strings->SetString("serverCertsTabDeleteImpact",
360 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_DELETE_SERVER_DESCRIPTION));
361 localized_strings->SetString("caCertsTabDeleteConfirm",
362 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_DELETE_CA_FORMAT));
363 localized_strings->SetString("caCertsTabDeleteImpact",
364 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_DELETE_CA_DESCRIPTION));
365 localized_strings->SetString("otherCertsTabDeleteConfirm",
366 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_DELETE_OTHER_FORMAT));
367 localized_strings->SetString("otherCertsTabDeleteImpact", std::string());
369 // Certificate Restore overlay strings.
370 localized_strings->SetString("certificateRestorePasswordDescription",
371 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_RESTORE_PASSWORD_DESC));
372 localized_strings->SetString("certificatePasswordLabel",
373 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_PASSWORD_LABEL));
375 // Personal Certificate Export overlay strings.
376 localized_strings->SetString("certificateExportPasswordDescription",
377 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_EXPORT_PASSWORD_DESC));
378 localized_strings->SetString("certificateExportPasswordHelp",
379 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_EXPORT_PASSWORD_HELP));
380 localized_strings->SetString("certificateConfirmPasswordLabel",
381 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_CONFIRM_PASSWORD_LABEL));
383 // Edit CA Trust & Import CA overlay strings.
384 localized_strings->SetString("certificateEditCaTitle",
385 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_EDIT_CA_TITLE));
386 localized_strings->SetString("certificateEditTrustLabel",
387 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_EDIT_TRUST_LABEL));
388 localized_strings->SetString("certificateEditCaTrustDescriptionFormat",
389 l10n_util::GetStringUTF16(
390 IDS_CERT_MANAGER_EDIT_CA_TRUST_DESCRIPTION_FORMAT));
391 localized_strings->SetString("certificateImportCaDescriptionFormat",
392 l10n_util::GetStringUTF16(
393 IDS_CERT_MANAGER_IMPORT_CA_DESCRIPTION_FORMAT));
394 localized_strings->SetString("certificateCaTrustSSLLabel",
395 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_EDIT_CA_TRUST_SSL_LABEL));
396 localized_strings->SetString("certificateCaTrustEmailLabel",
397 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_EDIT_CA_TRUST_EMAIL_LABEL));
398 localized_strings->SetString("certificateCaTrustObjSignLabel",
399 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_EDIT_CA_TRUST_OBJSIGN_LABEL));
400 localized_strings->SetString("certificateImportErrorFormat",
401 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_IMPORT_ERROR_FORMAT));
403 // Badges next to certificates
404 localized_strings->SetString("badgeCertUntrusted",
405 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_UNTRUSTED));
406 localized_strings->SetString("certPolicyInstalled",
407 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_POLICY_INSTALLED));
409 #if defined(OS_CHROMEOS)
410 localized_strings->SetString("importAndBindCertificate",
411 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_IMPORT_AND_BIND_BUTTON));
412 #endif // defined(OS_CHROMEOS)
415 void CertificateManagerHandler::RegisterMessages() {
416 web_ui()->RegisterMessageCallback(
417 "viewCertificate",
418 base::Bind(&CertificateManagerHandler::View, base::Unretained(this)));
420 web_ui()->RegisterMessageCallback(
421 "getCaCertificateTrust",
422 base::Bind(&CertificateManagerHandler::GetCATrust,
423 base::Unretained(this)));
424 web_ui()->RegisterMessageCallback(
425 "editCaCertificateTrust",
426 base::Bind(&CertificateManagerHandler::EditCATrust,
427 base::Unretained(this)));
429 web_ui()->RegisterMessageCallback(
430 "editServerCertificate",
431 base::Bind(&CertificateManagerHandler::EditServer,
432 base::Unretained(this)));
434 web_ui()->RegisterMessageCallback(
435 "cancelImportExportCertificate",
436 base::Bind(&CertificateManagerHandler::CancelImportExportProcess,
437 base::Unretained(this)));
439 web_ui()->RegisterMessageCallback(
440 "exportPersonalCertificate",
441 base::Bind(&CertificateManagerHandler::ExportPersonal,
442 base::Unretained(this)));
443 web_ui()->RegisterMessageCallback(
444 "exportAllPersonalCertificates",
445 base::Bind(&CertificateManagerHandler::ExportAllPersonal,
446 base::Unretained(this)));
447 web_ui()->RegisterMessageCallback(
448 "exportPersonalCertificatePasswordSelected",
449 base::Bind(&CertificateManagerHandler::ExportPersonalPasswordSelected,
450 base::Unretained(this)));
452 web_ui()->RegisterMessageCallback(
453 "importPersonalCertificate",
454 base::Bind(&CertificateManagerHandler::StartImportPersonal,
455 base::Unretained(this)));
456 web_ui()->RegisterMessageCallback(
457 "importPersonalCertificatePasswordSelected",
458 base::Bind(&CertificateManagerHandler::ImportPersonalPasswordSelected,
459 base::Unretained(this)));
461 web_ui()->RegisterMessageCallback(
462 "importCaCertificate",
463 base::Bind(&CertificateManagerHandler::ImportCA,
464 base::Unretained(this)));
465 web_ui()->RegisterMessageCallback(
466 "importCaCertificateTrustSelected",
467 base::Bind(&CertificateManagerHandler::ImportCATrustSelected,
468 base::Unretained(this)));
470 web_ui()->RegisterMessageCallback(
471 "importServerCertificate",
472 base::Bind(&CertificateManagerHandler::ImportServer,
473 base::Unretained(this)));
475 web_ui()->RegisterMessageCallback(
476 "exportCertificate",
477 base::Bind(&CertificateManagerHandler::Export,
478 base::Unretained(this)));
480 web_ui()->RegisterMessageCallback(
481 "deleteCertificate",
482 base::Bind(&CertificateManagerHandler::Delete,
483 base::Unretained(this)));
485 web_ui()->RegisterMessageCallback(
486 "populateCertificateManager",
487 base::Bind(&CertificateManagerHandler::Populate,
488 base::Unretained(this)));
491 void CertificateManagerHandler::CertificatesRefreshed() {
492 net::CertificateList web_trusted_certs;
493 #if defined(OS_CHROMEOS)
494 policy::UserNetworkConfigurationUpdater* service =
495 policy::UserNetworkConfigurationUpdaterFactory::GetForProfile(
496 Profile::FromWebUI(web_ui()));
497 if (service)
498 service->GetWebTrustedCertificates(&web_trusted_certs);
499 #endif
500 PopulateTree("personalCertsTab", net::USER_CERT, web_trusted_certs);
501 PopulateTree("serverCertsTab", net::SERVER_CERT, web_trusted_certs);
502 PopulateTree("caCertsTab", net::CA_CERT, web_trusted_certs);
503 PopulateTree("otherCertsTab", net::OTHER_CERT, web_trusted_certs);
506 void CertificateManagerHandler::FileSelected(const base::FilePath& path,
507 int index,
508 void* params) {
509 switch (reinterpret_cast<intptr_t>(params)) {
510 case EXPORT_PERSONAL_FILE_SELECTED:
511 ExportPersonalFileSelected(path);
512 break;
513 case IMPORT_PERSONAL_FILE_SELECTED:
514 ImportPersonalFileSelected(path);
515 break;
516 case IMPORT_SERVER_FILE_SELECTED:
517 ImportServerFileSelected(path);
518 break;
519 case IMPORT_CA_FILE_SELECTED:
520 ImportCAFileSelected(path);
521 break;
522 default:
523 NOTREACHED();
527 void CertificateManagerHandler::FileSelectionCanceled(void* params) {
528 switch (reinterpret_cast<intptr_t>(params)) {
529 case EXPORT_PERSONAL_FILE_SELECTED:
530 case IMPORT_PERSONAL_FILE_SELECTED:
531 case IMPORT_SERVER_FILE_SELECTED:
532 case IMPORT_CA_FILE_SELECTED:
533 ImportExportCleanup();
534 break;
535 default:
536 NOTREACHED();
540 void CertificateManagerHandler::View(const base::ListValue* args) {
541 net::X509Certificate* cert = cert_id_map_->CallbackArgsToCert(args);
542 if (!cert)
543 return;
544 #if defined(OS_CHROMEOS)
545 if (show_certs_in_modal_dialog_) {
546 ShowCertificateViewerModalDialog(web_ui()->GetWebContents(),
547 GetParentWindow(),
548 cert);
549 return;
551 #endif
552 ShowCertificateViewer(web_ui()->GetWebContents(), GetParentWindow(), cert);
555 void CertificateManagerHandler::GetCATrust(const base::ListValue* args) {
556 net::X509Certificate* cert = cert_id_map_->CallbackArgsToCert(args);
557 if (!cert) {
558 web_ui()->CallJavascriptFunction("CertificateEditCaTrustOverlay.dismiss");
559 return;
562 net::NSSCertDatabase::TrustBits trust_bits =
563 certificate_manager_model_->cert_db()->GetCertTrust(cert, net::CA_CERT);
564 base::FundamentalValue ssl_value(
565 static_cast<bool>(trust_bits & net::NSSCertDatabase::TRUSTED_SSL));
566 base::FundamentalValue email_value(
567 static_cast<bool>(trust_bits & net::NSSCertDatabase::TRUSTED_EMAIL));
568 base::FundamentalValue obj_sign_value(
569 static_cast<bool>(trust_bits & net::NSSCertDatabase::TRUSTED_OBJ_SIGN));
570 web_ui()->CallJavascriptFunction(
571 "CertificateEditCaTrustOverlay.populateTrust",
572 ssl_value, email_value, obj_sign_value);
575 void CertificateManagerHandler::EditCATrust(const base::ListValue* args) {
576 net::X509Certificate* cert = cert_id_map_->CallbackArgsToCert(args);
577 bool fail = !cert;
578 bool trust_ssl = false;
579 bool trust_email = false;
580 bool trust_obj_sign = false;
581 fail |= !CallbackArgsToBool(args, 1, &trust_ssl);
582 fail |= !CallbackArgsToBool(args, 2, &trust_email);
583 fail |= !CallbackArgsToBool(args, 3, &trust_obj_sign);
584 if (fail) {
585 LOG(ERROR) << "EditCATrust args fail";
586 web_ui()->CallJavascriptFunction("CertificateEditCaTrustOverlay.dismiss");
587 return;
590 bool result = certificate_manager_model_->SetCertTrust(
591 cert,
592 net::CA_CERT,
593 trust_ssl * net::NSSCertDatabase::TRUSTED_SSL +
594 trust_email * net::NSSCertDatabase::TRUSTED_EMAIL +
595 trust_obj_sign * net::NSSCertDatabase::TRUSTED_OBJ_SIGN);
596 web_ui()->CallJavascriptFunction("CertificateEditCaTrustOverlay.dismiss");
597 if (!result) {
598 // TODO(mattm): better error messages?
599 ShowError(
600 l10n_util::GetStringUTF8(IDS_CERT_MANAGER_SET_TRUST_ERROR_TITLE),
601 l10n_util::GetStringUTF8(IDS_CERT_MANAGER_UNKNOWN_ERROR));
605 void CertificateManagerHandler::EditServer(const base::ListValue* args) {
606 NOTIMPLEMENTED();
609 void CertificateManagerHandler::ExportPersonal(const base::ListValue* args) {
610 net::X509Certificate* cert = cert_id_map_->CallbackArgsToCert(args);
611 if (!cert)
612 return;
614 selected_cert_list_.push_back(cert);
616 ui::SelectFileDialog::FileTypeInfo file_type_info;
617 file_type_info.extensions.resize(1);
618 file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("p12"));
619 file_type_info.extension_description_overrides.push_back(
620 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_PKCS12_FILES));
621 file_type_info.include_all_files = true;
622 select_file_dialog_ = ui::SelectFileDialog::Create(
623 this, new ChromeSelectFilePolicy(web_ui()->GetWebContents()));
624 select_file_dialog_->SelectFile(
625 ui::SelectFileDialog::SELECT_SAVEAS_FILE, base::string16(),
626 base::FilePath(), &file_type_info, 1, FILE_PATH_LITERAL("p12"),
627 GetParentWindow(),
628 reinterpret_cast<void*>(EXPORT_PERSONAL_FILE_SELECTED));
631 void CertificateManagerHandler::ExportAllPersonal(const base::ListValue* args) {
632 NOTIMPLEMENTED();
635 void CertificateManagerHandler::ExportPersonalFileSelected(
636 const base::FilePath& path) {
637 file_path_ = path;
638 web_ui()->CallJavascriptFunction(
639 "CertificateManager.exportPersonalAskPassword");
642 void CertificateManagerHandler::ExportPersonalPasswordSelected(
643 const base::ListValue* args) {
644 if (!args->GetString(0, &password_)) {
645 web_ui()->CallJavascriptFunction("CertificateRestoreOverlay.dismiss");
646 ImportExportCleanup();
647 return;
650 // Currently, we don't support exporting more than one at a time. If we do,
651 // this would need to either change this to use UnlockSlotsIfNecessary or
652 // change UnlockCertSlotIfNecessary to take a CertificateList.
653 DCHECK_EQ(selected_cert_list_.size(), 1U);
655 // TODO(mattm): do something smarter about non-extractable keys
656 chrome::UnlockCertSlotIfNecessary(
657 selected_cert_list_[0].get(),
658 chrome::kCryptoModulePasswordCertExport,
659 net::HostPortPair(), // unused.
660 GetParentWindow(),
661 base::Bind(&CertificateManagerHandler::ExportPersonalSlotsUnlocked,
662 base::Unretained(this)));
665 void CertificateManagerHandler::ExportPersonalSlotsUnlocked() {
666 std::string output;
667 int num_exported = certificate_manager_model_->cert_db()->ExportToPKCS12(
668 selected_cert_list_,
669 password_,
670 &output);
671 if (!num_exported) {
672 web_ui()->CallJavascriptFunction("CertificateRestoreOverlay.dismiss");
673 ShowError(
674 l10n_util::GetStringUTF8(IDS_CERT_MANAGER_PKCS12_EXPORT_ERROR_TITLE),
675 l10n_util::GetStringUTF8(IDS_CERT_MANAGER_UNKNOWN_ERROR));
676 ImportExportCleanup();
677 return;
679 file_access_provider_->StartWrite(
680 file_path_,
681 output,
682 base::Bind(&CertificateManagerHandler::ExportPersonalFileWritten,
683 base::Unretained(this)),
684 &tracker_);
687 void CertificateManagerHandler::ExportPersonalFileWritten(
688 const int* write_errno, const int* bytes_written) {
689 web_ui()->CallJavascriptFunction("CertificateRestoreOverlay.dismiss");
690 ImportExportCleanup();
691 if (*write_errno) {
692 ShowError(
693 l10n_util::GetStringUTF8(IDS_CERT_MANAGER_PKCS12_EXPORT_ERROR_TITLE),
694 l10n_util::GetStringFUTF8(IDS_CERT_MANAGER_WRITE_ERROR_FORMAT,
695 UTF8ToUTF16(
696 base::safe_strerror(*write_errno))));
700 void CertificateManagerHandler::StartImportPersonal(
701 const base::ListValue* args) {
702 ui::SelectFileDialog::FileTypeInfo file_type_info;
703 if (!args->GetBoolean(0, &use_hardware_backed_)) {
704 // Unable to retrieve the hardware backed attribute from the args,
705 // so bail.
706 web_ui()->CallJavascriptFunction("CertificateRestoreOverlay.dismiss");
707 ImportExportCleanup();
708 return;
710 file_type_info.extensions.resize(1);
711 file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("p12"));
712 file_type_info.extension_description_overrides.push_back(
713 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_PKCS12_FILES));
714 file_type_info.include_all_files = true;
715 select_file_dialog_ = ui::SelectFileDialog::Create(
716 this, new ChromeSelectFilePolicy(web_ui()->GetWebContents()));
717 select_file_dialog_->SelectFile(
718 ui::SelectFileDialog::SELECT_OPEN_FILE, base::string16(),
719 base::FilePath(), &file_type_info, 1, FILE_PATH_LITERAL("p12"),
720 GetParentWindow(),
721 reinterpret_cast<void*>(IMPORT_PERSONAL_FILE_SELECTED));
724 void CertificateManagerHandler::ImportPersonalFileSelected(
725 const base::FilePath& path) {
726 file_path_ = path;
727 web_ui()->CallJavascriptFunction(
728 "CertificateManager.importPersonalAskPassword");
731 void CertificateManagerHandler::ImportPersonalPasswordSelected(
732 const base::ListValue* args) {
733 if (!args->GetString(0, &password_)) {
734 web_ui()->CallJavascriptFunction("CertificateRestoreOverlay.dismiss");
735 ImportExportCleanup();
736 return;
738 file_access_provider_->StartRead(
739 file_path_,
740 base::Bind(&CertificateManagerHandler::ImportPersonalFileRead,
741 base::Unretained(this)),
742 &tracker_);
745 void CertificateManagerHandler::ImportPersonalFileRead(
746 const int* read_errno, const std::string* data) {
747 if (*read_errno) {
748 ImportExportCleanup();
749 web_ui()->CallJavascriptFunction("CertificateRestoreOverlay.dismiss");
750 ShowError(
751 l10n_util::GetStringUTF8(IDS_CERT_MANAGER_PKCS12_IMPORT_ERROR_TITLE),
752 l10n_util::GetStringFUTF8(IDS_CERT_MANAGER_READ_ERROR_FORMAT,
753 UTF8ToUTF16(
754 base::safe_strerror(*read_errno))));
755 return;
758 file_data_ = *data;
760 if (use_hardware_backed_) {
761 module_ = certificate_manager_model_->cert_db()->GetPrivateModule();
762 } else {
763 module_ = certificate_manager_model_->cert_db()->GetPublicModule();
766 net::CryptoModuleList modules;
767 modules.push_back(module_);
768 chrome::UnlockSlotsIfNecessary(
769 modules,
770 chrome::kCryptoModulePasswordCertImport,
771 net::HostPortPair(), // unused.
772 GetParentWindow(),
773 base::Bind(&CertificateManagerHandler::ImportPersonalSlotUnlocked,
774 base::Unretained(this)));
777 void CertificateManagerHandler::ImportPersonalSlotUnlocked() {
778 // Determine if the private key should be unextractable after the import.
779 // We do this by checking the value of |use_hardware_backed_| which is set
780 // to true if importing into a hardware module. Currently, this only happens
781 // for Chrome OS when the "Import and Bind" option is chosen.
782 bool is_extractable = !use_hardware_backed_;
783 int result = certificate_manager_model_->ImportFromPKCS12(
784 module_.get(), file_data_, password_, is_extractable);
785 ImportExportCleanup();
786 web_ui()->CallJavascriptFunction("CertificateRestoreOverlay.dismiss");
787 int string_id;
788 switch (result) {
789 case net::OK:
790 return;
791 case net::ERR_PKCS12_IMPORT_BAD_PASSWORD:
792 // TODO(mattm): if the error was a bad password, we should reshow the
793 // password dialog after the user dismisses the error dialog.
794 string_id = IDS_CERT_MANAGER_BAD_PASSWORD;
795 break;
796 case net::ERR_PKCS12_IMPORT_INVALID_MAC:
797 string_id = IDS_CERT_MANAGER_PKCS12_IMPORT_INVALID_MAC;
798 break;
799 case net::ERR_PKCS12_IMPORT_INVALID_FILE:
800 string_id = IDS_CERT_MANAGER_PKCS12_IMPORT_INVALID_FILE;
801 break;
802 case net::ERR_PKCS12_IMPORT_UNSUPPORTED:
803 string_id = IDS_CERT_MANAGER_PKCS12_IMPORT_UNSUPPORTED;
804 break;
805 default:
806 string_id = IDS_CERT_MANAGER_UNKNOWN_ERROR;
807 break;
809 ShowError(
810 l10n_util::GetStringUTF8(IDS_CERT_MANAGER_PKCS12_IMPORT_ERROR_TITLE),
811 l10n_util::GetStringUTF8(string_id));
814 void CertificateManagerHandler::CancelImportExportProcess(
815 const base::ListValue* args) {
816 ImportExportCleanup();
819 void CertificateManagerHandler::ImportExportCleanup() {
820 file_path_.clear();
821 password_.clear();
822 file_data_.clear();
823 use_hardware_backed_ = false;
824 selected_cert_list_.clear();
825 module_ = NULL;
827 // There may be pending file dialogs, we need to tell them that we've gone
828 // away so they don't try and call back to us.
829 if (select_file_dialog_.get())
830 select_file_dialog_->ListenerDestroyed();
831 select_file_dialog_ = NULL;
834 void CertificateManagerHandler::ImportServer(const base::ListValue* args) {
835 select_file_dialog_ = ui::SelectFileDialog::Create(
836 this, new ChromeSelectFilePolicy(web_ui()->GetWebContents()));
837 ShowCertSelectFileDialog(
838 select_file_dialog_.get(),
839 ui::SelectFileDialog::SELECT_OPEN_FILE,
840 base::FilePath(),
841 GetParentWindow(),
842 reinterpret_cast<void*>(IMPORT_SERVER_FILE_SELECTED));
845 void CertificateManagerHandler::ImportServerFileSelected(
846 const base::FilePath& path) {
847 file_path_ = path;
848 file_access_provider_->StartRead(
849 file_path_,
850 base::Bind(&CertificateManagerHandler::ImportServerFileRead,
851 base::Unretained(this)),
852 &tracker_);
855 void CertificateManagerHandler::ImportServerFileRead(const int* read_errno,
856 const std::string* data) {
857 if (*read_errno) {
858 ImportExportCleanup();
859 ShowError(
860 l10n_util::GetStringUTF8(IDS_CERT_MANAGER_SERVER_IMPORT_ERROR_TITLE),
861 l10n_util::GetStringFUTF8(IDS_CERT_MANAGER_READ_ERROR_FORMAT,
862 UTF8ToUTF16(
863 base::safe_strerror(*read_errno))));
864 return;
867 selected_cert_list_ = net::X509Certificate::CreateCertificateListFromBytes(
868 data->data(), data->size(), net::X509Certificate::FORMAT_AUTO);
869 if (selected_cert_list_.empty()) {
870 ImportExportCleanup();
871 ShowError(
872 l10n_util::GetStringUTF8(IDS_CERT_MANAGER_SERVER_IMPORT_ERROR_TITLE),
873 l10n_util::GetStringUTF8(IDS_CERT_MANAGER_CERT_PARSE_ERROR));
874 return;
877 net::NSSCertDatabase::ImportCertFailureList not_imported;
878 // TODO(mattm): Add UI for trust. http://crbug.com/76274
879 bool result = certificate_manager_model_->ImportServerCert(
880 selected_cert_list_,
881 net::NSSCertDatabase::TRUST_DEFAULT,
882 &not_imported);
883 if (!result) {
884 ShowError(
885 l10n_util::GetStringUTF8(IDS_CERT_MANAGER_SERVER_IMPORT_ERROR_TITLE),
886 l10n_util::GetStringUTF8(IDS_CERT_MANAGER_UNKNOWN_ERROR));
887 } else if (!not_imported.empty()) {
888 ShowImportErrors(
889 l10n_util::GetStringUTF8(IDS_CERT_MANAGER_SERVER_IMPORT_ERROR_TITLE),
890 not_imported);
892 ImportExportCleanup();
895 void CertificateManagerHandler::ImportCA(const base::ListValue* args) {
896 select_file_dialog_ = ui::SelectFileDialog::Create(
897 this, new ChromeSelectFilePolicy(web_ui()->GetWebContents()));
898 ShowCertSelectFileDialog(select_file_dialog_.get(),
899 ui::SelectFileDialog::SELECT_OPEN_FILE,
900 base::FilePath(),
901 GetParentWindow(),
902 reinterpret_cast<void*>(IMPORT_CA_FILE_SELECTED));
905 void CertificateManagerHandler::ImportCAFileSelected(
906 const base::FilePath& path) {
907 file_path_ = path;
908 file_access_provider_->StartRead(
909 file_path_,
910 base::Bind(&CertificateManagerHandler::ImportCAFileRead,
911 base::Unretained(this)),
912 &tracker_);
915 void CertificateManagerHandler::ImportCAFileRead(const int* read_errno,
916 const std::string* data) {
917 if (*read_errno) {
918 ImportExportCleanup();
919 ShowError(
920 l10n_util::GetStringUTF8(IDS_CERT_MANAGER_CA_IMPORT_ERROR_TITLE),
921 l10n_util::GetStringFUTF8(IDS_CERT_MANAGER_READ_ERROR_FORMAT,
922 UTF8ToUTF16(
923 base::safe_strerror(*read_errno))));
924 return;
927 selected_cert_list_ = net::X509Certificate::CreateCertificateListFromBytes(
928 data->data(), data->size(), net::X509Certificate::FORMAT_AUTO);
929 if (selected_cert_list_.empty()) {
930 ImportExportCleanup();
931 ShowError(
932 l10n_util::GetStringUTF8(IDS_CERT_MANAGER_CA_IMPORT_ERROR_TITLE),
933 l10n_util::GetStringUTF8(IDS_CERT_MANAGER_CERT_PARSE_ERROR));
934 return;
937 scoped_refptr<net::X509Certificate> root_cert =
938 certificate_manager_model_->cert_db()->FindRootInList(
939 selected_cert_list_);
941 // TODO(mattm): check here if root_cert is not a CA cert and show error.
943 base::StringValue cert_name(root_cert->subject().GetDisplayName());
944 web_ui()->CallJavascriptFunction("CertificateEditCaTrustOverlay.showImport",
945 cert_name);
948 void CertificateManagerHandler::ImportCATrustSelected(
949 const base::ListValue* args) {
950 bool fail = false;
951 bool trust_ssl = false;
952 bool trust_email = false;
953 bool trust_obj_sign = false;
954 fail |= !CallbackArgsToBool(args, 0, &trust_ssl);
955 fail |= !CallbackArgsToBool(args, 1, &trust_email);
956 fail |= !CallbackArgsToBool(args, 2, &trust_obj_sign);
957 if (fail) {
958 LOG(ERROR) << "ImportCATrustSelected args fail";
959 ImportExportCleanup();
960 web_ui()->CallJavascriptFunction("CertificateEditCaTrustOverlay.dismiss");
961 return;
964 // TODO(mattm): add UI for setting explicit distrust, too.
965 // http://crbug.com/128411
966 net::NSSCertDatabase::ImportCertFailureList not_imported;
967 bool result = certificate_manager_model_->ImportCACerts(
968 selected_cert_list_,
969 trust_ssl * net::NSSCertDatabase::TRUSTED_SSL +
970 trust_email * net::NSSCertDatabase::TRUSTED_EMAIL +
971 trust_obj_sign * net::NSSCertDatabase::TRUSTED_OBJ_SIGN,
972 &not_imported);
973 web_ui()->CallJavascriptFunction("CertificateEditCaTrustOverlay.dismiss");
974 if (!result) {
975 ShowError(
976 l10n_util::GetStringUTF8(IDS_CERT_MANAGER_CA_IMPORT_ERROR_TITLE),
977 l10n_util::GetStringUTF8(IDS_CERT_MANAGER_UNKNOWN_ERROR));
978 } else if (!not_imported.empty()) {
979 ShowImportErrors(
980 l10n_util::GetStringUTF8(IDS_CERT_MANAGER_CA_IMPORT_ERROR_TITLE),
981 not_imported);
983 ImportExportCleanup();
986 void CertificateManagerHandler::Export(const base::ListValue* args) {
987 net::X509Certificate* cert = cert_id_map_->CallbackArgsToCert(args);
988 if (!cert)
989 return;
990 ShowCertExportDialog(web_ui()->GetWebContents(), GetParentWindow(), cert);
993 void CertificateManagerHandler::Delete(const base::ListValue* args) {
994 net::X509Certificate* cert = cert_id_map_->CallbackArgsToCert(args);
995 if (!cert)
996 return;
997 bool result = certificate_manager_model_->Delete(cert);
998 if (!result) {
999 // TODO(mattm): better error messages?
1000 ShowError(
1001 l10n_util::GetStringUTF8(IDS_CERT_MANAGER_DELETE_CERT_ERROR_TITLE),
1002 l10n_util::GetStringUTF8(IDS_CERT_MANAGER_UNKNOWN_ERROR));
1006 void CertificateManagerHandler::OnCertificateManagerModelCreated(
1007 scoped_ptr<CertificateManagerModel> model) {
1008 certificate_manager_model_ = model.Pass();
1009 CertificateManagerModelReady();
1012 void CertificateManagerHandler::CertificateManagerModelReady() {
1013 base::FundamentalValue user_db_available_value(
1014 certificate_manager_model_->is_user_db_available());
1015 base::FundamentalValue tpm_available_value(
1016 certificate_manager_model_->is_tpm_available());
1017 web_ui()->CallJavascriptFunction("CertificateManager.onModelReady",
1018 user_db_available_value,
1019 tpm_available_value);
1020 certificate_manager_model_->Refresh();
1023 void CertificateManagerHandler::Populate(const base::ListValue* args) {
1024 if (certificate_manager_model_) {
1025 // Already have a model, the webui must be re-loading. Just re-run the
1026 // webui initialization.
1027 CertificateManagerModelReady();
1028 return;
1031 if (!requested_certificate_manager_model_) {
1032 // Request that a model be created.
1033 CertificateManagerModel::Create(
1034 Profile::FromWebUI(web_ui()),
1035 this,
1036 base::Bind(&CertificateManagerHandler::OnCertificateManagerModelCreated,
1037 weak_ptr_factory_.GetWeakPtr()));
1038 requested_certificate_manager_model_ = true;
1039 return;
1042 // We are already waiting for a CertificateManagerModel to be created, no need
1043 // to do anything.
1046 void CertificateManagerHandler::PopulateTree(
1047 const std::string& tab_name,
1048 net::CertType type,
1049 const net::CertificateList& web_trust_certs) {
1050 const std::string tree_name = tab_name + "-tree";
1052 scoped_ptr<icu::Collator> collator;
1053 UErrorCode error = U_ZERO_ERROR;
1054 collator.reset(
1055 icu::Collator::createInstance(
1056 icu::Locale(g_browser_process->GetApplicationLocale().c_str()),
1057 error));
1058 if (U_FAILURE(error))
1059 collator.reset(NULL);
1060 DictionaryIdComparator comparator(collator.get());
1061 CertificateManagerModel::OrgGroupingMap map;
1063 certificate_manager_model_->FilterAndBuildOrgGroupingMap(type, &map);
1066 base::ListValue* nodes = new base::ListValue;
1067 for (CertificateManagerModel::OrgGroupingMap::iterator i = map.begin();
1068 i != map.end(); ++i) {
1069 // Populate first level (org name).
1070 base::DictionaryValue* dict = new base::DictionaryValue;
1071 dict->SetString(kKeyId, OrgNameToId(i->first));
1072 dict->SetString(kNameId, i->first);
1074 // Populate second level (certs).
1075 base::ListValue* subnodes = new base::ListValue;
1076 for (net::CertificateList::const_iterator org_cert_it = i->second.begin();
1077 org_cert_it != i->second.end(); ++org_cert_it) {
1078 base::DictionaryValue* cert_dict = new base::DictionaryValue;
1079 net::X509Certificate* cert = org_cert_it->get();
1080 cert_dict->SetString(kKeyId, cert_id_map_->CertToId(cert));
1081 cert_dict->SetString(kNameId, certificate_manager_model_->GetColumnText(
1082 *cert, CertificateManagerModel::COL_SUBJECT_NAME));
1083 cert_dict->SetBoolean(
1084 kReadOnlyId,
1085 certificate_manager_model_->cert_db()->IsReadOnly(cert));
1086 // Policy-installed certificates with web trust are trusted.
1087 bool policy_trusted =
1088 IsPolicyInstalledWithWebTrust(web_trust_certs, cert);
1089 cert_dict->SetBoolean(
1090 kUntrustedId,
1091 !policy_trusted &&
1092 certificate_manager_model_->cert_db()->IsUntrusted(cert));
1093 cert_dict->SetBoolean(kPolicyTrustedId, policy_trusted);
1094 // TODO(hshi): This should be determined by testing for PKCS #11
1095 // CKA_EXTRACTABLE attribute. We may need to use the NSS function
1096 // PK11_ReadRawAttribute to do that.
1097 cert_dict->SetBoolean(
1098 kExtractableId,
1099 !certificate_manager_model_->IsHardwareBacked(cert));
1100 // TODO(mattm): Other columns.
1101 subnodes->Append(cert_dict);
1103 std::sort(subnodes->begin(), subnodes->end(), comparator);
1105 dict->Set(kSubNodesId, subnodes);
1106 nodes->Append(dict);
1108 std::sort(nodes->begin(), nodes->end(), comparator);
1110 base::ListValue args;
1111 args.Append(new base::StringValue(tree_name));
1112 args.Append(nodes);
1113 web_ui()->CallJavascriptFunction("CertificateManager.onPopulateTree", args);
1117 void CertificateManagerHandler::ShowError(const std::string& title,
1118 const std::string& error) const {
1119 ScopedVector<const base::Value> args;
1120 args.push_back(new base::StringValue(title));
1121 args.push_back(new base::StringValue(error));
1122 args.push_back(new base::StringValue(l10n_util::GetStringUTF8(IDS_OK)));
1123 args.push_back(base::Value::CreateNullValue().release()); // cancelTitle
1124 args.push_back(base::Value::CreateNullValue().release()); // okCallback
1125 args.push_back(base::Value::CreateNullValue().release()); // cancelCallback
1126 web_ui()->CallJavascriptFunction("AlertOverlay.show", args.get());
1129 void CertificateManagerHandler::ShowImportErrors(
1130 const std::string& title,
1131 const net::NSSCertDatabase::ImportCertFailureList& not_imported) const {
1132 std::string error;
1133 if (selected_cert_list_.size() == 1)
1134 error = l10n_util::GetStringUTF8(
1135 IDS_CERT_MANAGER_IMPORT_SINGLE_NOT_IMPORTED);
1136 else if (not_imported.size() == selected_cert_list_.size())
1137 error = l10n_util::GetStringUTF8(IDS_CERT_MANAGER_IMPORT_ALL_NOT_IMPORTED);
1138 else
1139 error = l10n_util::GetStringUTF8(IDS_CERT_MANAGER_IMPORT_SOME_NOT_IMPORTED);
1141 base::ListValue cert_error_list;
1142 for (size_t i = 0; i < not_imported.size(); ++i) {
1143 const net::NSSCertDatabase::ImportCertFailure& failure = not_imported[i];
1144 base::DictionaryValue* dict = new base::DictionaryValue;
1145 dict->SetString(kNameId, failure.certificate->subject().GetDisplayName());
1146 dict->SetString(kErrorId, NetErrorToString(failure.net_error));
1147 cert_error_list.Append(dict);
1150 base::StringValue title_value(title);
1151 base::StringValue error_value(error);
1152 web_ui()->CallJavascriptFunction("CertificateImportErrorOverlay.show",
1153 title_value,
1154 error_value,
1155 cert_error_list);
1158 gfx::NativeWindow CertificateManagerHandler::GetParentWindow() const {
1159 return web_ui()->GetWebContents()->GetTopLevelNativeWindow();
1162 } // namespace options