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