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/certificate_manager_model.h" 6 7 #include "base/bind.h" 8 #include "base/i18n/time_formatting.h" 9 #include "base/logging.h" 10 #include "base/strings/utf_string_conversions.h" 11 #include "chrome/browser/ui/crypto_module_password_dialog.h" 12 #include "chrome/common/net/x509_certificate_model.h" 13 #include "net/base/crypto_module.h" 14 #include "net/base/net_errors.h" 15 #include "net/cert/x509_certificate.h" 16 17 #if defined(OS_CHROMEOS) 18 #include <cert.h> 19 20 #include "crypto/nss_util.h" 21 #include "grit/generated_resources.h" 22 #include "ui/base/l10n/l10n_util.h" 23 #endif 24 25 CertificateManagerModel::CertificateManagerModel(Observer* observer) 26 : cert_db_(net::NSSCertDatabase::GetInstance()), 27 observer_(observer) { 28 } 29 30 CertificateManagerModel::~CertificateManagerModel() { 31 } 32 33 void CertificateManagerModel::Refresh() { 34 VLOG(1) << "refresh started"; 35 net::CryptoModuleList modules; 36 cert_db_->ListModules(&modules, false); 37 VLOG(1) << "refresh waiting for unlocking..."; 38 chrome::UnlockSlotsIfNecessary( 39 modules, 40 chrome::kCryptoModulePasswordListCerts, 41 std::string(), // unused. 42 base::Bind(&CertificateManagerModel::RefreshSlotsUnlocked, 43 base::Unretained(this))); 44 } 45 46 void CertificateManagerModel::RefreshSlotsUnlocked() { 47 VLOG(1) << "refresh listing certs..."; 48 cert_db_->ListCerts(&cert_list_); 49 observer_->CertificatesRefreshed(); 50 VLOG(1) << "refresh finished"; 51 } 52 53 void CertificateManagerModel::FilterAndBuildOrgGroupingMap( 54 net::CertType filter_type, 55 CertificateManagerModel::OrgGroupingMap* map) const { 56 for (net::CertificateList::const_iterator i = cert_list_.begin(); 57 i != cert_list_.end(); ++i) { 58 net::X509Certificate* cert = i->get(); 59 net::CertType type = 60 x509_certificate_model::GetType(cert->os_cert_handle()); 61 if (type != filter_type) 62 continue; 63 64 std::string org; 65 if (!cert->subject().organization_names.empty()) 66 org = cert->subject().organization_names[0]; 67 if (org.empty()) 68 org = cert->subject().GetDisplayName(); 69 70 (*map)[org].push_back(cert); 71 } 72 } 73 74 string16 CertificateManagerModel::GetColumnText( 75 const net::X509Certificate& cert, 76 Column column) const { 77 string16 rv; 78 switch (column) { 79 case COL_SUBJECT_NAME: 80 rv = UTF8ToUTF16( 81 x509_certificate_model::GetCertNameOrNickname(cert.os_cert_handle())); 82 83 #if defined(OS_CHROMEOS) 84 // TODO(xiyuan): Put this into a column when we have js tree-table. 85 if (IsHardwareBacked(&cert)) { 86 rv = l10n_util::GetStringFUTF16( 87 IDS_CERT_MANAGER_HARDWARE_BACKED_KEY_FORMAT, 88 rv, 89 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_HARDWARE_BACKED)); 90 } 91 #endif 92 break; 93 case COL_CERTIFICATE_STORE: 94 rv = UTF8ToUTF16( 95 x509_certificate_model::GetTokenName(cert.os_cert_handle())); 96 break; 97 case COL_SERIAL_NUMBER: 98 rv = ASCIIToUTF16(x509_certificate_model::GetSerialNumberHexified( 99 cert.os_cert_handle(), std::string())); 100 break; 101 case COL_EXPIRES_ON: 102 if (!cert.valid_expiry().is_null()) 103 rv = base::TimeFormatShortDateNumeric(cert.valid_expiry()); 104 break; 105 default: 106 NOTREACHED(); 107 } 108 return rv; 109 } 110 111 int CertificateManagerModel::ImportFromPKCS12(net::CryptoModule* module, 112 const std::string& data, 113 const string16& password, 114 bool is_extractable) { 115 int result = cert_db_->ImportFromPKCS12(module, data, password, 116 is_extractable, NULL); 117 if (result == net::OK) 118 Refresh(); 119 return result; 120 } 121 122 bool CertificateManagerModel::ImportCACerts( 123 const net::CertificateList& certificates, 124 net::NSSCertDatabase::TrustBits trust_bits, 125 net::NSSCertDatabase::ImportCertFailureList* not_imported) { 126 bool result = cert_db_->ImportCACerts(certificates, trust_bits, not_imported); 127 if (result && not_imported->size() != certificates.size()) 128 Refresh(); 129 return result; 130 } 131 132 bool CertificateManagerModel::ImportServerCert( 133 const net::CertificateList& certificates, 134 net::NSSCertDatabase::TrustBits trust_bits, 135 net::NSSCertDatabase::ImportCertFailureList* not_imported) { 136 bool result = cert_db_->ImportServerCert(certificates, trust_bits, 137 not_imported); 138 if (result && not_imported->size() != certificates.size()) 139 Refresh(); 140 return result; 141 } 142 143 bool CertificateManagerModel::SetCertTrust( 144 const net::X509Certificate* cert, 145 net::CertType type, 146 net::NSSCertDatabase::TrustBits trust_bits) { 147 return cert_db_->SetCertTrust(cert, type, trust_bits); 148 } 149 150 bool CertificateManagerModel::Delete(net::X509Certificate* cert) { 151 bool result = cert_db_->DeleteCertAndKey(cert); 152 if (result) 153 Refresh(); 154 return result; 155 } 156 157 bool CertificateManagerModel::IsHardwareBacked( 158 const net::X509Certificate* cert) const { 159 #if defined(OS_CHROMEOS) 160 return crypto::IsTPMTokenReady() && 161 cert->os_cert_handle()->slot == 162 cert_db_->GetPrivateModule()->os_module_handle(); 163 #else 164 return false; 165 #endif 166 } 167