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