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/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/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 "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" 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 40 using base::UTF8ToUTF16; 41 using content::BrowserThread; 42 43 namespace { 44 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"; 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.) 56 enum { 57 EXPORT_PERSONAL_FILE_SELECTED = 1, 58 IMPORT_PERSONAL_FILE_SELECTED, 59 IMPORT_SERVER_FILE_SELECTED, 60 IMPORT_CA_FILE_SELECTED, 61 }; 62 63 std::string OrgNameToId(const std::string& org) { 64 return "org-" + org; 65 } 66 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; 71 72 *result = string_value[0] == 't'; 73 return true; 74 } 75 76 struct 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 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); 112 } 113 } 114 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()); 120 } 121 const net::X509Certificate* cert_; 122 }; 123 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(); 130 } 131 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); 138 } 139 #endif 140 141 } // namespace 142 143 namespace options { 144 145 /////////////////////////////////////////////////////////////////////////////// 146 // CertIdMap 147 148 class CertIdMap { 149 public: 150 CertIdMap() {} 151 ~CertIdMap() {} 152 153 std::string CertToId(net::X509Certificate* cert); 154 net::X509Certificate* IdToCert(const std::string& id); 155 net::X509Certificate* CallbackArgsToCert(const base::ListValue* args); 156 157 private: 158 typedef std::map<net::X509Certificate*, int32> CertMap; 159 160 // Creates an ID for cert and looks up the cert for an ID. 161 IDMap<net::X509Certificate>id_map_; 162 163 // Finds the ID for a cert. 164 CertMap cert_map_; 165 166 DISALLOW_COPY_AND_ASSIGN(CertIdMap); 167 }; 168 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); 173 174 int32 new_id = id_map_.Add(cert); 175 cert_map_[cert] = new_id; 176 return base::IntToString(new_id); 177 } 178 179 net::X509Certificate* CertIdMap::IdToCert(const std::string& id) { 180 int32 cert_id = 0; 181 if (!base::StringToInt(id, &cert_id)) 182 return NULL; 183 184 return id_map_.Lookup(cert_id); 185 } 186 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; 192 193 net::X509Certificate* cert = IdToCert(node_id); 194 if (!cert) { 195 NOTREACHED(); 196 return NULL; 197 } 198 199 return cert; 200 } 201 202 /////////////////////////////////////////////////////////////////////////////// 203 // FileAccessProvider 204 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; 212 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; 216 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); 226 227 private: 228 friend class base::RefCountedThreadSafe<FileAccessProvider>; 229 virtual ~FileAccessProvider() {} 230 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); 242 }; 243 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(); 251 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))); 258 } 259 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); 268 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))); 281 } 282 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; 288 } 289 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; 296 } 297 298 /////////////////////////////////////////////////////////////////////////////// 299 // CertificateManagerHandler 300 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) {} 309 310 CertificateManagerHandler::~CertificateManagerHandler() { 311 } 312 313 void CertificateManagerHandler::GetLocalizedValues( 314 base::DictionaryValue* localized_strings) { 315 DCHECK(localized_strings); 316 317 RegisterTitle(localized_strings, "certificateManagerPage", 318 IDS_CERTIFICATE_MANAGER_TITLE); 319 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)); 329 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)); 339 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)); 351 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()); 368 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)); 374 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)); 382 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)); 402 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)); 408 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) 413 } 414 415 void CertificateManagerHandler::RegisterMessages() { 416 web_ui()->RegisterMessageCallback( 417 "viewCertificate", 418 base::Bind(&CertificateManagerHandler::View, base::Unretained(this))); 419 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))); 428 429 web_ui()->RegisterMessageCallback( 430 "editServerCertificate", 431 base::Bind(&CertificateManagerHandler::EditServer, 432 base::Unretained(this))); 433 434 web_ui()->RegisterMessageCallback( 435 "cancelImportExportCertificate", 436 base::Bind(&CertificateManagerHandler::CancelImportExportProcess, 437 base::Unretained(this))); 438 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))); 451 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))); 460 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))); 469 470 web_ui()->RegisterMessageCallback( 471 "importServerCertificate", 472 base::Bind(&CertificateManagerHandler::ImportServer, 473 base::Unretained(this))); 474 475 web_ui()->RegisterMessageCallback( 476 "exportCertificate", 477 base::Bind(&CertificateManagerHandler::Export, 478 base::Unretained(this))); 479 480 web_ui()->RegisterMessageCallback( 481 "deleteCertificate", 482 base::Bind(&CertificateManagerHandler::Delete, 483 base::Unretained(this))); 484 485 web_ui()->RegisterMessageCallback( 486 "populateCertificateManager", 487 base::Bind(&CertificateManagerHandler::Populate, 488 base::Unretained(this))); 489 } 490 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); 504 } 505 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(); 524 } 525 } 526 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(); 537 } 538 } 539 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; 550 } 551 #endif 552 ShowCertificateViewer(web_ui()->GetWebContents(), GetParentWindow(), cert); 553 } 554 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; 560 } 561 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); 573 } 574 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; 588 } 589 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)); 602 } 603 } 604 605 void CertificateManagerHandler::EditServer(const base::ListValue* args) { 606 NOTIMPLEMENTED(); 607 } 608 609 void CertificateManagerHandler::ExportPersonal(const base::ListValue* args) { 610 net::X509Certificate* cert = cert_id_map_->CallbackArgsToCert(args); 611 if (!cert) 612 return; 613 614 selected_cert_list_.push_back(cert); 615 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)); 629 } 630 631 void CertificateManagerHandler::ExportAllPersonal(const base::ListValue* args) { 632 NOTIMPLEMENTED(); 633 } 634 635 void CertificateManagerHandler::ExportPersonalFileSelected( 636 const base::FilePath& path) { 637 file_path_ = path; 638 web_ui()->CallJavascriptFunction( 639 "CertificateManager.exportPersonalAskPassword"); 640 } 641 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; 648 } 649 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); 654 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))); 663 } 664 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; 678 } 679 file_access_provider_->StartWrite( 680 file_path_, 681 output, 682 base::Bind(&CertificateManagerHandler::ExportPersonalFileWritten, 683 base::Unretained(this)), 684 &tracker_); 685 } 686 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(safe_strerror(*write_errno)))); 696 } 697 } 698 699 void CertificateManagerHandler::StartImportPersonal( 700 const base::ListValue* args) { 701 ui::SelectFileDialog::FileTypeInfo file_type_info; 702 if (!args->GetBoolean(0, &use_hardware_backed_)) { 703 // Unable to retrieve the hardware backed attribute from the args, 704 // so bail. 705 web_ui()->CallJavascriptFunction("CertificateRestoreOverlay.dismiss"); 706 ImportExportCleanup(); 707 return; 708 } 709 file_type_info.extensions.resize(1); 710 file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("p12")); 711 file_type_info.extension_description_overrides.push_back( 712 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_PKCS12_FILES)); 713 file_type_info.include_all_files = true; 714 select_file_dialog_ = ui::SelectFileDialog::Create( 715 this, new ChromeSelectFilePolicy(web_ui()->GetWebContents())); 716 select_file_dialog_->SelectFile( 717 ui::SelectFileDialog::SELECT_OPEN_FILE, base::string16(), 718 base::FilePath(), &file_type_info, 1, FILE_PATH_LITERAL("p12"), 719 GetParentWindow(), 720 reinterpret_cast<void*>(IMPORT_PERSONAL_FILE_SELECTED)); 721 } 722 723 void CertificateManagerHandler::ImportPersonalFileSelected( 724 const base::FilePath& path) { 725 file_path_ = path; 726 web_ui()->CallJavascriptFunction( 727 "CertificateManager.importPersonalAskPassword"); 728 } 729 730 void CertificateManagerHandler::ImportPersonalPasswordSelected( 731 const base::ListValue* args) { 732 if (!args->GetString(0, &password_)) { 733 web_ui()->CallJavascriptFunction("CertificateRestoreOverlay.dismiss"); 734 ImportExportCleanup(); 735 return; 736 } 737 file_access_provider_->StartRead( 738 file_path_, 739 base::Bind(&CertificateManagerHandler::ImportPersonalFileRead, 740 base::Unretained(this)), 741 &tracker_); 742 } 743 744 void CertificateManagerHandler::ImportPersonalFileRead( 745 const int* read_errno, const std::string* data) { 746 if (*read_errno) { 747 ImportExportCleanup(); 748 web_ui()->CallJavascriptFunction("CertificateRestoreOverlay.dismiss"); 749 ShowError( 750 l10n_util::GetStringUTF8(IDS_CERT_MANAGER_PKCS12_IMPORT_ERROR_TITLE), 751 l10n_util::GetStringFUTF8(IDS_CERT_MANAGER_READ_ERROR_FORMAT, 752 UTF8ToUTF16(safe_strerror(*read_errno)))); 753 return; 754 } 755 756 file_data_ = *data; 757 758 if (use_hardware_backed_) { 759 module_ = certificate_manager_model_->cert_db()->GetPrivateModule(); 760 } else { 761 module_ = certificate_manager_model_->cert_db()->GetPublicModule(); 762 } 763 764 net::CryptoModuleList modules; 765 modules.push_back(module_); 766 chrome::UnlockSlotsIfNecessary( 767 modules, 768 chrome::kCryptoModulePasswordCertImport, 769 net::HostPortPair(), // unused. 770 GetParentWindow(), 771 base::Bind(&CertificateManagerHandler::ImportPersonalSlotUnlocked, 772 base::Unretained(this))); 773 } 774 775 void CertificateManagerHandler::ImportPersonalSlotUnlocked() { 776 // Determine if the private key should be unextractable after the import. 777 // We do this by checking the value of |use_hardware_backed_| which is set 778 // to true if importing into a hardware module. Currently, this only happens 779 // for Chrome OS when the "Import and Bind" option is chosen. 780 bool is_extractable = !use_hardware_backed_; 781 int result = certificate_manager_model_->ImportFromPKCS12( 782 module_.get(), file_data_, password_, is_extractable); 783 ImportExportCleanup(); 784 web_ui()->CallJavascriptFunction("CertificateRestoreOverlay.dismiss"); 785 int string_id; 786 switch (result) { 787 case net::OK: 788 return; 789 case net::ERR_PKCS12_IMPORT_BAD_PASSWORD: 790 // TODO(mattm): if the error was a bad password, we should reshow the 791 // password dialog after the user dismisses the error dialog. 792 string_id = IDS_CERT_MANAGER_BAD_PASSWORD; 793 break; 794 case net::ERR_PKCS12_IMPORT_INVALID_MAC: 795 string_id = IDS_CERT_MANAGER_PKCS12_IMPORT_INVALID_MAC; 796 break; 797 case net::ERR_PKCS12_IMPORT_INVALID_FILE: 798 string_id = IDS_CERT_MANAGER_PKCS12_IMPORT_INVALID_FILE; 799 break; 800 case net::ERR_PKCS12_IMPORT_UNSUPPORTED: 801 string_id = IDS_CERT_MANAGER_PKCS12_IMPORT_UNSUPPORTED; 802 break; 803 default: 804 string_id = IDS_CERT_MANAGER_UNKNOWN_ERROR; 805 break; 806 } 807 ShowError( 808 l10n_util::GetStringUTF8(IDS_CERT_MANAGER_PKCS12_IMPORT_ERROR_TITLE), 809 l10n_util::GetStringUTF8(string_id)); 810 } 811 812 void CertificateManagerHandler::CancelImportExportProcess( 813 const base::ListValue* args) { 814 ImportExportCleanup(); 815 } 816 817 void CertificateManagerHandler::ImportExportCleanup() { 818 file_path_.clear(); 819 password_.clear(); 820 file_data_.clear(); 821 use_hardware_backed_ = false; 822 selected_cert_list_.clear(); 823 module_ = NULL; 824 825 // There may be pending file dialogs, we need to tell them that we've gone 826 // away so they don't try and call back to us. 827 if (select_file_dialog_.get()) 828 select_file_dialog_->ListenerDestroyed(); 829 select_file_dialog_ = NULL; 830 } 831 832 void CertificateManagerHandler::ImportServer(const base::ListValue* args) { 833 select_file_dialog_ = ui::SelectFileDialog::Create( 834 this, new ChromeSelectFilePolicy(web_ui()->GetWebContents())); 835 ShowCertSelectFileDialog( 836 select_file_dialog_.get(), 837 ui::SelectFileDialog::SELECT_OPEN_FILE, 838 base::FilePath(), 839 GetParentWindow(), 840 reinterpret_cast<void*>(IMPORT_SERVER_FILE_SELECTED)); 841 } 842 843 void CertificateManagerHandler::ImportServerFileSelected( 844 const base::FilePath& path) { 845 file_path_ = path; 846 file_access_provider_->StartRead( 847 file_path_, 848 base::Bind(&CertificateManagerHandler::ImportServerFileRead, 849 base::Unretained(this)), 850 &tracker_); 851 } 852 853 void CertificateManagerHandler::ImportServerFileRead(const int* read_errno, 854 const std::string* data) { 855 if (*read_errno) { 856 ImportExportCleanup(); 857 ShowError( 858 l10n_util::GetStringUTF8(IDS_CERT_MANAGER_SERVER_IMPORT_ERROR_TITLE), 859 l10n_util::GetStringFUTF8(IDS_CERT_MANAGER_READ_ERROR_FORMAT, 860 UTF8ToUTF16(safe_strerror(*read_errno)))); 861 return; 862 } 863 864 selected_cert_list_ = net::X509Certificate::CreateCertificateListFromBytes( 865 data->data(), data->size(), net::X509Certificate::FORMAT_AUTO); 866 if (selected_cert_list_.empty()) { 867 ImportExportCleanup(); 868 ShowError( 869 l10n_util::GetStringUTF8(IDS_CERT_MANAGER_SERVER_IMPORT_ERROR_TITLE), 870 l10n_util::GetStringUTF8(IDS_CERT_MANAGER_CERT_PARSE_ERROR)); 871 return; 872 } 873 874 net::NSSCertDatabase::ImportCertFailureList not_imported; 875 // TODO(mattm): Add UI for trust. http://crbug.com/76274 876 bool result = certificate_manager_model_->ImportServerCert( 877 selected_cert_list_, 878 net::NSSCertDatabase::TRUST_DEFAULT, 879 ¬_imported); 880 if (!result) { 881 ShowError( 882 l10n_util::GetStringUTF8(IDS_CERT_MANAGER_SERVER_IMPORT_ERROR_TITLE), 883 l10n_util::GetStringUTF8(IDS_CERT_MANAGER_UNKNOWN_ERROR)); 884 } else if (!not_imported.empty()) { 885 ShowImportErrors( 886 l10n_util::GetStringUTF8(IDS_CERT_MANAGER_SERVER_IMPORT_ERROR_TITLE), 887 not_imported); 888 } 889 ImportExportCleanup(); 890 } 891 892 void CertificateManagerHandler::ImportCA(const base::ListValue* args) { 893 select_file_dialog_ = ui::SelectFileDialog::Create( 894 this, new ChromeSelectFilePolicy(web_ui()->GetWebContents())); 895 ShowCertSelectFileDialog(select_file_dialog_.get(), 896 ui::SelectFileDialog::SELECT_OPEN_FILE, 897 base::FilePath(), 898 GetParentWindow(), 899 reinterpret_cast<void*>(IMPORT_CA_FILE_SELECTED)); 900 } 901 902 void CertificateManagerHandler::ImportCAFileSelected( 903 const base::FilePath& path) { 904 file_path_ = path; 905 file_access_provider_->StartRead( 906 file_path_, 907 base::Bind(&CertificateManagerHandler::ImportCAFileRead, 908 base::Unretained(this)), 909 &tracker_); 910 } 911 912 void CertificateManagerHandler::ImportCAFileRead(const int* read_errno, 913 const std::string* data) { 914 if (*read_errno) { 915 ImportExportCleanup(); 916 ShowError( 917 l10n_util::GetStringUTF8(IDS_CERT_MANAGER_CA_IMPORT_ERROR_TITLE), 918 l10n_util::GetStringFUTF8(IDS_CERT_MANAGER_READ_ERROR_FORMAT, 919 UTF8ToUTF16(safe_strerror(*read_errno)))); 920 return; 921 } 922 923 selected_cert_list_ = net::X509Certificate::CreateCertificateListFromBytes( 924 data->data(), data->size(), net::X509Certificate::FORMAT_AUTO); 925 if (selected_cert_list_.empty()) { 926 ImportExportCleanup(); 927 ShowError( 928 l10n_util::GetStringUTF8(IDS_CERT_MANAGER_CA_IMPORT_ERROR_TITLE), 929 l10n_util::GetStringUTF8(IDS_CERT_MANAGER_CERT_PARSE_ERROR)); 930 return; 931 } 932 933 scoped_refptr<net::X509Certificate> root_cert = 934 certificate_manager_model_->cert_db()->FindRootInList( 935 selected_cert_list_); 936 937 // TODO(mattm): check here if root_cert is not a CA cert and show error. 938 939 base::StringValue cert_name(root_cert->subject().GetDisplayName()); 940 web_ui()->CallJavascriptFunction("CertificateEditCaTrustOverlay.showImport", 941 cert_name); 942 } 943 944 void CertificateManagerHandler::ImportCATrustSelected( 945 const base::ListValue* args) { 946 bool fail = false; 947 bool trust_ssl = false; 948 bool trust_email = false; 949 bool trust_obj_sign = false; 950 fail |= !CallbackArgsToBool(args, 0, &trust_ssl); 951 fail |= !CallbackArgsToBool(args, 1, &trust_email); 952 fail |= !CallbackArgsToBool(args, 2, &trust_obj_sign); 953 if (fail) { 954 LOG(ERROR) << "ImportCATrustSelected args fail"; 955 ImportExportCleanup(); 956 web_ui()->CallJavascriptFunction("CertificateEditCaTrustOverlay.dismiss"); 957 return; 958 } 959 960 // TODO(mattm): add UI for setting explicit distrust, too. 961 // http://crbug.com/128411 962 net::NSSCertDatabase::ImportCertFailureList not_imported; 963 bool result = certificate_manager_model_->ImportCACerts( 964 selected_cert_list_, 965 trust_ssl * net::NSSCertDatabase::TRUSTED_SSL + 966 trust_email * net::NSSCertDatabase::TRUSTED_EMAIL + 967 trust_obj_sign * net::NSSCertDatabase::TRUSTED_OBJ_SIGN, 968 ¬_imported); 969 web_ui()->CallJavascriptFunction("CertificateEditCaTrustOverlay.dismiss"); 970 if (!result) { 971 ShowError( 972 l10n_util::GetStringUTF8(IDS_CERT_MANAGER_CA_IMPORT_ERROR_TITLE), 973 l10n_util::GetStringUTF8(IDS_CERT_MANAGER_UNKNOWN_ERROR)); 974 } else if (!not_imported.empty()) { 975 ShowImportErrors( 976 l10n_util::GetStringUTF8(IDS_CERT_MANAGER_CA_IMPORT_ERROR_TITLE), 977 not_imported); 978 } 979 ImportExportCleanup(); 980 } 981 982 void CertificateManagerHandler::Export(const base::ListValue* args) { 983 net::X509Certificate* cert = cert_id_map_->CallbackArgsToCert(args); 984 if (!cert) 985 return; 986 ShowCertExportDialog(web_ui()->GetWebContents(), GetParentWindow(), cert); 987 } 988 989 void CertificateManagerHandler::Delete(const base::ListValue* args) { 990 net::X509Certificate* cert = cert_id_map_->CallbackArgsToCert(args); 991 if (!cert) 992 return; 993 bool result = certificate_manager_model_->Delete(cert); 994 if (!result) { 995 // TODO(mattm): better error messages? 996 ShowError( 997 l10n_util::GetStringUTF8(IDS_CERT_MANAGER_DELETE_CERT_ERROR_TITLE), 998 l10n_util::GetStringUTF8(IDS_CERT_MANAGER_UNKNOWN_ERROR)); 999 } 1000 } 1001 1002 void CertificateManagerHandler::OnCertificateManagerModelCreated( 1003 scoped_ptr<CertificateManagerModel> model) { 1004 certificate_manager_model_ = model.Pass(); 1005 CertificateManagerModelReady(); 1006 } 1007 1008 void CertificateManagerHandler::CertificateManagerModelReady() { 1009 base::FundamentalValue user_db_available_value( 1010 certificate_manager_model_->is_user_db_available()); 1011 base::FundamentalValue tpm_available_value( 1012 certificate_manager_model_->is_tpm_available()); 1013 web_ui()->CallJavascriptFunction("CertificateManager.onModelReady", 1014 user_db_available_value, 1015 tpm_available_value); 1016 certificate_manager_model_->Refresh(); 1017 } 1018 1019 void CertificateManagerHandler::Populate(const base::ListValue* args) { 1020 if (certificate_manager_model_) { 1021 // Already have a model, the webui must be re-loading. Just re-run the 1022 // webui initialization. 1023 CertificateManagerModelReady(); 1024 return; 1025 } 1026 1027 if (!requested_certificate_manager_model_) { 1028 // Request that a model be created. 1029 CertificateManagerModel::Create( 1030 Profile::FromWebUI(web_ui()), 1031 this, 1032 base::Bind(&CertificateManagerHandler::OnCertificateManagerModelCreated, 1033 weak_ptr_factory_.GetWeakPtr())); 1034 requested_certificate_manager_model_ = true; 1035 return; 1036 } 1037 1038 // We are already waiting for a CertificateManagerModel to be created, no need 1039 // to do anything. 1040 } 1041 1042 void CertificateManagerHandler::PopulateTree( 1043 const std::string& tab_name, 1044 net::CertType type, 1045 const net::CertificateList& web_trust_certs) { 1046 const std::string tree_name = tab_name + "-tree"; 1047 1048 scoped_ptr<icu::Collator> collator; 1049 UErrorCode error = U_ZERO_ERROR; 1050 collator.reset( 1051 icu::Collator::createInstance( 1052 icu::Locale(g_browser_process->GetApplicationLocale().c_str()), 1053 error)); 1054 if (U_FAILURE(error)) 1055 collator.reset(NULL); 1056 DictionaryIdComparator comparator(collator.get()); 1057 CertificateManagerModel::OrgGroupingMap map; 1058 1059 certificate_manager_model_->FilterAndBuildOrgGroupingMap(type, &map); 1060 1061 { 1062 base::ListValue* nodes = new base::ListValue; 1063 for (CertificateManagerModel::OrgGroupingMap::iterator i = map.begin(); 1064 i != map.end(); ++i) { 1065 // Populate first level (org name). 1066 base::DictionaryValue* dict = new base::DictionaryValue; 1067 dict->SetString(kKeyId, OrgNameToId(i->first)); 1068 dict->SetString(kNameId, i->first); 1069 1070 // Populate second level (certs). 1071 base::ListValue* subnodes = new base::ListValue; 1072 for (net::CertificateList::const_iterator org_cert_it = i->second.begin(); 1073 org_cert_it != i->second.end(); ++org_cert_it) { 1074 base::DictionaryValue* cert_dict = new base::DictionaryValue; 1075 net::X509Certificate* cert = org_cert_it->get(); 1076 cert_dict->SetString(kKeyId, cert_id_map_->CertToId(cert)); 1077 cert_dict->SetString(kNameId, certificate_manager_model_->GetColumnText( 1078 *cert, CertificateManagerModel::COL_SUBJECT_NAME)); 1079 cert_dict->SetBoolean( 1080 kReadOnlyId, 1081 certificate_manager_model_->cert_db()->IsReadOnly(cert)); 1082 // Policy-installed certificates with web trust are trusted. 1083 bool policy_trusted = 1084 IsPolicyInstalledWithWebTrust(web_trust_certs, cert); 1085 cert_dict->SetBoolean( 1086 kUntrustedId, 1087 !policy_trusted && 1088 certificate_manager_model_->cert_db()->IsUntrusted(cert)); 1089 cert_dict->SetBoolean(kPolicyTrustedId, policy_trusted); 1090 // TODO(hshi): This should be determined by testing for PKCS #11 1091 // CKA_EXTRACTABLE attribute. We may need to use the NSS function 1092 // PK11_ReadRawAttribute to do that. 1093 cert_dict->SetBoolean( 1094 kExtractableId, 1095 !certificate_manager_model_->IsHardwareBacked(cert)); 1096 // TODO(mattm): Other columns. 1097 subnodes->Append(cert_dict); 1098 } 1099 std::sort(subnodes->begin(), subnodes->end(), comparator); 1100 1101 dict->Set(kSubNodesId, subnodes); 1102 nodes->Append(dict); 1103 } 1104 std::sort(nodes->begin(), nodes->end(), comparator); 1105 1106 base::ListValue args; 1107 args.Append(new base::StringValue(tree_name)); 1108 args.Append(nodes); 1109 web_ui()->CallJavascriptFunction("CertificateManager.onPopulateTree", args); 1110 } 1111 } 1112 1113 void CertificateManagerHandler::ShowError(const std::string& title, 1114 const std::string& error) const { 1115 ScopedVector<const base::Value> args; 1116 args.push_back(new base::StringValue(title)); 1117 args.push_back(new base::StringValue(error)); 1118 args.push_back(new base::StringValue(l10n_util::GetStringUTF8(IDS_OK))); 1119 args.push_back(base::Value::CreateNullValue()); // cancelTitle 1120 args.push_back(base::Value::CreateNullValue()); // okCallback 1121 args.push_back(base::Value::CreateNullValue()); // cancelCallback 1122 web_ui()->CallJavascriptFunction("AlertOverlay.show", args.get()); 1123 } 1124 1125 void CertificateManagerHandler::ShowImportErrors( 1126 const std::string& title, 1127 const net::NSSCertDatabase::ImportCertFailureList& not_imported) const { 1128 std::string error; 1129 if (selected_cert_list_.size() == 1) 1130 error = l10n_util::GetStringUTF8( 1131 IDS_CERT_MANAGER_IMPORT_SINGLE_NOT_IMPORTED); 1132 else if (not_imported.size() == selected_cert_list_.size()) 1133 error = l10n_util::GetStringUTF8(IDS_CERT_MANAGER_IMPORT_ALL_NOT_IMPORTED); 1134 else 1135 error = l10n_util::GetStringUTF8(IDS_CERT_MANAGER_IMPORT_SOME_NOT_IMPORTED); 1136 1137 base::ListValue cert_error_list; 1138 for (size_t i = 0; i < not_imported.size(); ++i) { 1139 const net::NSSCertDatabase::ImportCertFailure& failure = not_imported[i]; 1140 base::DictionaryValue* dict = new base::DictionaryValue; 1141 dict->SetString(kNameId, failure.certificate->subject().GetDisplayName()); 1142 dict->SetString(kErrorId, NetErrorToString(failure.net_error)); 1143 cert_error_list.Append(dict); 1144 } 1145 1146 base::StringValue title_value(title); 1147 base::StringValue error_value(error); 1148 web_ui()->CallJavascriptFunction("CertificateImportErrorOverlay.show", 1149 title_value, 1150 error_value, 1151 cert_error_list); 1152 } 1153 1154 gfx::NativeWindow CertificateManagerHandler::GetParentWindow() const { 1155 return web_ui()->GetWebContents()->GetTopLevelNativeWindow(); 1156 } 1157 1158 } // namespace options 1159