Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chromeos/network/onc/onc_certificate_importer_impl.h" | 5 #include "chromeos/network/onc/onc_certificate_importer_impl.h" |
| 6 | 6 |
| 7 #include <cert.h> | 7 #include <cert.h> |
| 8 #include <keyhi.h> | 8 #include <keyhi.h> |
| 9 #include <pk11pub.h> | 9 #include <pk11pub.h> |
| 10 | 10 |
| 11 #include "base/base64.h" | 11 #include "base/base64.h" |
| 12 #include "base/bind.h" | |
| 13 #include "base/bind_helpers.h" | |
| 14 #include "base/callback.h" | |
| 15 #include "base/location.h" | |
| 12 #include "base/logging.h" | 16 #include "base/logging.h" |
| 17 #include "base/sequenced_task_runner.h" | |
| 18 #include "base/single_thread_task_runner.h" | |
| 19 #include "base/thread_task_runner_handle.h" | |
| 13 #include "base/values.h" | 20 #include "base/values.h" |
| 14 #include "chromeos/network/network_event_log.h" | 21 #include "chromeos/network/network_event_log.h" |
| 15 #include "chromeos/network/onc/onc_utils.h" | 22 #include "chromeos/network/onc/onc_utils.h" |
| 16 #include "components/onc/onc_constants.h" | 23 #include "components/onc/onc_constants.h" |
| 17 #include "crypto/scoped_nss_types.h" | 24 #include "crypto/scoped_nss_types.h" |
| 18 #include "net/base/crypto_module.h" | 25 #include "net/base/crypto_module.h" |
| 19 #include "net/base/net_errors.h" | 26 #include "net/base/net_errors.h" |
| 20 #include "net/cert/nss_cert_database.h" | 27 #include "net/cert/nss_cert_database.h" |
| 21 #include "net/cert/x509_certificate.h" | 28 #include "net/cert/x509_certificate.h" |
| 22 | 29 |
| 23 #define ONC_LOG_WARNING(message) \ | |
| 24 NET_LOG_DEBUG("ONC Certificate Import Warning", message) | |
| 25 #define ONC_LOG_ERROR(message) \ | |
| 26 NET_LOG_ERROR("ONC Certificate Import Error", message) | |
| 27 | |
| 28 namespace chromeos { | 30 namespace chromeos { |
| 29 namespace onc { | 31 namespace onc { |
| 30 | 32 |
| 33 namespace { | |
| 34 | |
| 35 void CallBackOnOriginLoop( | |
| 36 const scoped_refptr<base::SingleThreadTaskRunner>& origin_loop, | |
| 37 const CertificateImporter::DoneCallback& callback, | |
| 38 bool success, | |
| 39 const net::CertificateList& onc_trusted_certificates) { | |
| 40 origin_loop->PostTask( | |
| 41 FROM_HERE, base::Bind(callback, success, onc_trusted_certificates)); | |
| 42 } | |
| 43 | |
| 44 } // namespace | |
| 45 | |
| 31 CertificateImporterImpl::CertificateImporterImpl( | 46 CertificateImporterImpl::CertificateImporterImpl( |
| 47 const scoped_refptr<base::SequencedTaskRunner>& task_runner, | |
| 32 net::NSSCertDatabase* target_nssdb) | 48 net::NSSCertDatabase* target_nssdb) |
| 33 : target_nssdb_(target_nssdb) { | 49 : task_runner_(task_runner), |
| 50 target_nssdb_(target_nssdb), | |
| 51 weak_factory_(this) { | |
| 34 CHECK(target_nssdb); | 52 CHECK(target_nssdb); |
| 35 } | 53 } |
| 36 | 54 |
| 37 bool CertificateImporterImpl::ImportCertificates( | 55 CertificateImporterImpl::~CertificateImporterImpl() { |
| 56 } | |
| 57 | |
| 58 void CertificateImporterImpl::ImportCertificates( | |
| 38 const base::ListValue& certificates, | 59 const base::ListValue& certificates, |
| 39 ::onc::ONCSource source, | 60 ::onc::ONCSource source, |
| 40 net::CertificateList* onc_trusted_certificates) { | 61 const DoneCallback& done_callback) { |
| 41 VLOG(2) << "ONC file has " << certificates.GetSize() << " certificates"; | 62 VLOG(2) << "ONC file has " << certificates.GetSize() << " certificates"; |
| 63 DoneCallback callback_on_origin_loop = | |
| 64 base::Bind(&CallBackOnOriginLoop, | |
| 65 base::ThreadTaskRunnerHandle::Get(), | |
| 66 base::Bind(&CertificateImporterImpl::RunDoneCallback, | |
| 67 weak_factory_.GetWeakPtr(), | |
| 68 done_callback)); | |
| 42 | 69 |
| 70 task_runner_->PostTask(FROM_HERE, | |
| 71 base::Bind(&ParseAndStoreCertificates, | |
| 72 source, | |
| 73 callback_on_origin_loop, | |
| 74 base::Owned(certificates.DeepCopy()), | |
| 75 target_nssdb_)); | |
|
Joao da Silva
2014/09/15 12:38:24
This is essentially PostTaskAndReply, can you use
pneubeck (no reviews)
2014/09/17 12:44:21
Indeed, in this case something like
PostTaskAndRe
| |
| 76 } | |
| 77 | |
| 78 // static | |
| 79 void CertificateImporterImpl::ParseAndStoreCertificates( | |
| 80 ::onc::ONCSource source, | |
| 81 const DoneCallback& done_callback, | |
| 82 base::ListValue* certificates, | |
| 83 net::NSSCertDatabase* nssdb) { | |
| 43 // Web trust is only granted to certificates imported by the user. | 84 // Web trust is only granted to certificates imported by the user. |
| 44 bool allow_trust_imports = source == ::onc::ONC_SOURCE_USER_IMPORT; | 85 bool allow_trust_imports = source == ::onc::ONC_SOURCE_USER_IMPORT; |
| 45 if (!ParseAndStoreCertificates(allow_trust_imports, | 86 net::CertificateList onc_trusted_certificates; |
| 46 certificates, | |
| 47 onc_trusted_certificates, | |
| 48 NULL)) { | |
| 49 LOG(ERROR) << "Cannot parse some of the certificates in the ONC from " | |
| 50 << onc::GetSourceAsString(source); | |
| 51 return false; | |
| 52 } | |
| 53 return true; | |
| 54 } | |
| 55 | |
| 56 bool CertificateImporterImpl::ParseAndStoreCertificates( | |
| 57 bool allow_trust_imports, | |
| 58 const base::ListValue& certificates, | |
| 59 net::CertificateList* onc_trusted_certificates, | |
| 60 CertsByGUID* imported_server_and_ca_certs) { | |
| 61 bool success = true; | 87 bool success = true; |
| 62 for (size_t i = 0; i < certificates.GetSize(); ++i) { | 88 for (size_t i = 0; i < certificates->GetSize(); ++i) { |
| 63 const base::DictionaryValue* certificate = NULL; | 89 const base::DictionaryValue* certificate = NULL; |
| 64 certificates.GetDictionary(i, &certificate); | 90 certificates->GetDictionary(i, &certificate); |
| 65 DCHECK(certificate != NULL); | 91 DCHECK(certificate != NULL); |
| 66 | 92 |
| 67 VLOG(2) << "Parsing certificate at index " << i << ": " << *certificate; | 93 VLOG(2) << "Parsing certificate at index " << i << ": " << *certificate; |
| 68 | 94 |
| 69 if (!ParseAndStoreCertificate(allow_trust_imports, | 95 if (!ParseAndStoreCertificate(allow_trust_imports, |
| 70 *certificate, | 96 *certificate, |
| 71 onc_trusted_certificates, | 97 nssdb, |
| 72 imported_server_and_ca_certs)) { | 98 &onc_trusted_certificates)) { |
| 73 success = false; | 99 success = false; |
| 74 ONC_LOG_ERROR( | 100 LOG(ERROR) << "Cannot parse certificate at index " << i; |
| 75 base::StringPrintf("Cannot parse certificate at index %zu", i)); | |
| 76 } else { | 101 } else { |
| 77 VLOG(2) << "Successfully imported certificate at index " << i; | 102 VLOG(2) << "Successfully imported certificate at index " << i; |
| 78 } | 103 } |
| 79 } | 104 } |
| 80 return success; | 105 |
| 106 done_callback.Run(success, onc_trusted_certificates); | |
| 81 } | 107 } |
| 82 | 108 |
| 83 // static | 109 // static |
| 84 void CertificateImporterImpl::ListCertsWithNickname( | 110 void CertificateImporterImpl::ListCertsWithNickname( |
| 85 const std::string& label, | 111 const std::string& label, |
| 86 net::CertificateList* result, | 112 net::CertificateList* result, |
| 87 net::NSSCertDatabase* target_nssdb) { | 113 net::NSSCertDatabase* target_nssdb) { |
| 88 net::CertificateList all_certs; | 114 net::CertificateList all_certs; |
| 89 // TODO(tbarzic): Use async |ListCerts|. | 115 // TODO(tbarzic): Use async |ListCerts|. |
| 90 target_nssdb->ListCertsSync(&all_certs); | 116 target_nssdb->ListCertsSync(&all_certs); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 136 // Luckily there should only be one cert with a particular | 162 // Luckily there should only be one cert with a particular |
| 137 // label, and the cert not being found is one of the few reasons the | 163 // label, and the cert not being found is one of the few reasons the |
| 138 // delete could fail, but still... The other choice is to return | 164 // delete could fail, but still... The other choice is to return |
| 139 // failure immediately, but that doesn't seem to do what is intended. | 165 // failure immediately, but that doesn't seem to do what is intended. |
| 140 if (!target_nssdb->DeleteCertAndKey(iter->get())) | 166 if (!target_nssdb->DeleteCertAndKey(iter->get())) |
| 141 result = false; | 167 result = false; |
| 142 } | 168 } |
| 143 return result; | 169 return result; |
| 144 } | 170 } |
| 145 | 171 |
| 172 void CertificateImporterImpl::RunDoneCallback( | |
| 173 const CertificateImporter::DoneCallback& callback, | |
| 174 bool success, | |
| 175 const net::CertificateList& onc_trusted_certificates) { | |
| 176 if (!success) | |
| 177 NET_LOG_ERROR("ONC Certificate Import Error", ""); | |
| 178 callback.Run(success, onc_trusted_certificates); | |
| 179 } | |
| 180 | |
| 146 bool CertificateImporterImpl::ParseAndStoreCertificate( | 181 bool CertificateImporterImpl::ParseAndStoreCertificate( |
| 147 bool allow_trust_imports, | 182 bool allow_trust_imports, |
| 148 const base::DictionaryValue& certificate, | 183 const base::DictionaryValue& certificate, |
| 149 net::CertificateList* onc_trusted_certificates, | 184 net::NSSCertDatabase* nssdb, |
| 150 CertsByGUID* imported_server_and_ca_certs) { | 185 net::CertificateList* onc_trusted_certificates) { |
| 151 // Get out the attributes of the given certificate. | 186 // Get out the attributes of the given certificate. |
| 152 std::string guid; | 187 std::string guid; |
| 153 certificate.GetStringWithoutPathExpansion(::onc::certificate::kGUID, &guid); | 188 certificate.GetStringWithoutPathExpansion(::onc::certificate::kGUID, &guid); |
| 154 DCHECK(!guid.empty()); | 189 DCHECK(!guid.empty()); |
| 155 | 190 |
| 156 bool remove = false; | 191 bool remove = false; |
| 157 if (certificate.GetBooleanWithoutPathExpansion(::onc::kRemove, &remove) && | 192 if (certificate.GetBooleanWithoutPathExpansion(::onc::kRemove, &remove) && |
| 158 remove) { | 193 remove) { |
| 159 if (!DeleteCertAndKeyByNickname(guid, target_nssdb_)) { | 194 if (!DeleteCertAndKeyByNickname(guid, nssdb)) { |
| 160 ONC_LOG_ERROR("Unable to delete certificate"); | 195 LOG(ERROR) << "Unable to delete certificate"; |
| 161 return false; | 196 return false; |
| 162 } else { | 197 } else { |
| 163 return true; | 198 return true; |
| 164 } | 199 } |
| 165 } | 200 } |
| 166 | 201 |
| 167 // Not removing, so let's get the data we need to add this certificate. | 202 // Not removing, so let's get the data we need to add this certificate. |
| 168 std::string cert_type; | 203 std::string cert_type; |
| 169 certificate.GetStringWithoutPathExpansion(::onc::certificate::kType, | 204 certificate.GetStringWithoutPathExpansion(::onc::certificate::kType, |
| 170 &cert_type); | 205 &cert_type); |
| 171 if (cert_type == ::onc::certificate::kServer || | 206 if (cert_type == ::onc::certificate::kServer || |
| 172 cert_type == ::onc::certificate::kAuthority) { | 207 cert_type == ::onc::certificate::kAuthority) { |
| 173 return ParseServerOrCaCertificate(allow_trust_imports, | 208 return ParseServerOrCaCertificate(allow_trust_imports, |
| 174 cert_type, | 209 cert_type, |
| 175 guid, | 210 guid, |
| 176 certificate, | 211 certificate, |
| 177 onc_trusted_certificates, | 212 nssdb, |
| 178 imported_server_and_ca_certs); | 213 onc_trusted_certificates); |
| 179 } else if (cert_type == ::onc::certificate::kClient) { | 214 } else if (cert_type == ::onc::certificate::kClient) { |
| 180 return ParseClientCertificate(guid, certificate); | 215 return ParseClientCertificate(guid, certificate, nssdb); |
| 181 } | 216 } |
| 182 | 217 |
| 183 NOTREACHED(); | 218 NOTREACHED(); |
| 184 return false; | 219 return false; |
| 185 } | 220 } |
| 186 | 221 |
| 187 bool CertificateImporterImpl::ParseServerOrCaCertificate( | 222 bool CertificateImporterImpl::ParseServerOrCaCertificate( |
| 188 bool allow_trust_imports, | 223 bool allow_trust_imports, |
| 189 const std::string& cert_type, | 224 const std::string& cert_type, |
| 190 const std::string& guid, | 225 const std::string& guid, |
| 191 const base::DictionaryValue& certificate, | 226 const base::DictionaryValue& certificate, |
| 192 net::CertificateList* onc_trusted_certificates, | 227 net::NSSCertDatabase* nssdb, |
| 193 CertsByGUID* imported_server_and_ca_certs) { | 228 net::CertificateList* onc_trusted_certificates) { |
| 194 bool web_trust_flag = false; | 229 bool web_trust_flag = false; |
| 195 const base::ListValue* trust_list = NULL; | 230 const base::ListValue* trust_list = NULL; |
| 196 if (certificate.GetListWithoutPathExpansion(::onc::certificate::kTrustBits, | 231 if (certificate.GetListWithoutPathExpansion(::onc::certificate::kTrustBits, |
| 197 &trust_list)) { | 232 &trust_list)) { |
| 198 for (base::ListValue::const_iterator it = trust_list->begin(); | 233 for (base::ListValue::const_iterator it = trust_list->begin(); |
| 199 it != trust_list->end(); ++it) { | 234 it != trust_list->end(); ++it) { |
| 200 std::string trust_type; | 235 std::string trust_type; |
| 201 if (!(*it)->GetAsString(&trust_type)) | 236 if (!(*it)->GetAsString(&trust_type)) |
| 202 NOTREACHED(); | 237 NOTREACHED(); |
| 203 | 238 |
| 204 if (trust_type == ::onc::certificate::kWeb) { | 239 if (trust_type == ::onc::certificate::kWeb) { |
| 205 // "Web" implies that the certificate is to be trusted for SSL | 240 // "Web" implies that the certificate is to be trusted for SSL |
| 206 // identification. | 241 // identification. |
| 207 web_trust_flag = true; | 242 web_trust_flag = true; |
| 208 } else { | 243 } else { |
| 209 // Trust bits should only increase trust and never restrict. Thus, | 244 // Trust bits should only increase trust and never restrict. Thus, |
| 210 // ignoring unknown bits should be safe. | 245 // ignoring unknown bits should be safe. |
| 211 ONC_LOG_WARNING("Certificate contains unknown trust type " + | 246 LOG(WARNING) << "Certificate contains unknown trust type " |
| 212 trust_type); | 247 << trust_type; |
| 213 } | 248 } |
| 214 } | 249 } |
| 215 } | 250 } |
| 216 | 251 |
| 217 bool import_with_ssl_trust = false; | 252 bool import_with_ssl_trust = false; |
| 218 if (web_trust_flag) { | 253 if (web_trust_flag) { |
| 219 if (!allow_trust_imports) | 254 if (!allow_trust_imports) |
| 220 ONC_LOG_WARNING("Web trust not granted for certificate: " + guid); | 255 LOG(WARNING) << "Web trust not granted for certificate: " << guid; |
| 221 else | 256 else |
| 222 import_with_ssl_trust = true; | 257 import_with_ssl_trust = true; |
| 223 } | 258 } |
| 224 | 259 |
| 225 std::string x509_data; | 260 std::string x509_data; |
| 226 if (!certificate.GetStringWithoutPathExpansion(::onc::certificate::kX509, | 261 if (!certificate.GetStringWithoutPathExpansion(::onc::certificate::kX509, |
| 227 &x509_data) || | 262 &x509_data) || |
| 228 x509_data.empty()) { | 263 x509_data.empty()) { |
| 229 ONC_LOG_ERROR( | 264 LOG(ERROR) << "Certificate missing appropriate certificate data for type: " |
| 230 "Certificate missing appropriate certificate data for type: " + | 265 << cert_type; |
| 231 cert_type); | |
| 232 return false; | 266 return false; |
| 233 } | 267 } |
| 234 | 268 |
| 235 scoped_refptr<net::X509Certificate> x509_cert = | 269 scoped_refptr<net::X509Certificate> x509_cert = |
| 236 DecodePEMCertificate(x509_data); | 270 DecodePEMCertificate(x509_data); |
| 237 if (!x509_cert.get()) { | 271 if (!x509_cert.get()) { |
| 238 ONC_LOG_ERROR("Unable to create certificate from PEM encoding, type: " + | 272 LOG(ERROR) << "Unable to create certificate from PEM encoding, type: " |
| 239 cert_type); | 273 << cert_type; |
| 240 return false; | 274 return false; |
| 241 } | 275 } |
| 242 | 276 |
| 243 net::NSSCertDatabase::TrustBits trust = (import_with_ssl_trust ? | 277 net::NSSCertDatabase::TrustBits trust = (import_with_ssl_trust ? |
| 244 net::NSSCertDatabase::TRUSTED_SSL : | 278 net::NSSCertDatabase::TRUSTED_SSL : |
| 245 net::NSSCertDatabase::TRUST_DEFAULT); | 279 net::NSSCertDatabase::TRUST_DEFAULT); |
| 246 | 280 |
| 247 if (x509_cert->os_cert_handle()->isperm) { | 281 if (x509_cert->os_cert_handle()->isperm) { |
| 248 net::CertType net_cert_type = | 282 net::CertType net_cert_type = |
| 249 cert_type == ::onc::certificate::kServer ? net::SERVER_CERT | 283 cert_type == ::onc::certificate::kServer ? net::SERVER_CERT |
| 250 : net::CA_CERT; | 284 : net::CA_CERT; |
| 251 VLOG(1) << "Certificate is already installed."; | 285 VLOG(1) << "Certificate is already installed."; |
| 252 net::NSSCertDatabase::TrustBits missing_trust_bits = | 286 net::NSSCertDatabase::TrustBits missing_trust_bits = |
| 253 trust & ~target_nssdb_->GetCertTrust(x509_cert.get(), net_cert_type); | 287 trust & ~nssdb->GetCertTrust(x509_cert.get(), net_cert_type); |
| 254 if (missing_trust_bits) { | 288 if (missing_trust_bits) { |
| 255 std::string error_reason; | 289 std::string error_reason; |
| 256 bool success = false; | 290 bool success = false; |
| 257 if (target_nssdb_->IsReadOnly(x509_cert.get())) { | 291 if (nssdb->IsReadOnly(x509_cert.get())) { |
| 258 error_reason = " Certificate is stored read-only."; | 292 error_reason = " Certificate is stored read-only."; |
| 259 } else { | 293 } else { |
| 260 success = target_nssdb_->SetCertTrust(x509_cert.get(), | 294 success = nssdb->SetCertTrust(x509_cert.get(), net_cert_type, trust); |
| 261 net_cert_type, | |
| 262 trust); | |
| 263 } | 295 } |
| 264 if (!success) { | 296 if (!success) { |
| 265 ONC_LOG_ERROR("Certificate of type " + cert_type + | 297 LOG(ERROR) << "Certificate of type " << cert_type |
| 266 " was already present, but trust couldn't be set." + | 298 << " was already present, but trust couldn't be set." |
| 267 error_reason); | 299 << error_reason; |
| 268 } | 300 } |
| 269 } | 301 } |
| 270 } else { | 302 } else { |
| 271 net::CertificateList cert_list; | 303 net::CertificateList cert_list; |
| 272 cert_list.push_back(x509_cert); | 304 cert_list.push_back(x509_cert); |
| 273 net::NSSCertDatabase::ImportCertFailureList failures; | 305 net::NSSCertDatabase::ImportCertFailureList failures; |
| 274 bool success = false; | 306 bool success = false; |
| 275 if (cert_type == ::onc::certificate::kServer) | 307 if (cert_type == ::onc::certificate::kServer) |
| 276 success = target_nssdb_->ImportServerCert(cert_list, trust, &failures); | 308 success = nssdb->ImportServerCert(cert_list, trust, &failures); |
| 277 else // Authority cert | 309 else // Authority cert |
| 278 success = target_nssdb_->ImportCACerts(cert_list, trust, &failures); | 310 success = nssdb->ImportCACerts(cert_list, trust, &failures); |
| 279 | 311 |
| 280 if (!failures.empty()) { | 312 if (!failures.empty()) { |
| 281 std::string error_string = net::ErrorToString(failures[0].net_error); | 313 std::string error_string = net::ErrorToString(failures[0].net_error); |
| 282 ONC_LOG_ERROR( | 314 LOG(ERROR) << "Error ( " << error_string |
| 283 base::StringPrintf("Error ( %s ) importing %s certificate", | 315 << " ) importing certificate of type " << cert_type; |
| 284 error_string.c_str(), | |
| 285 cert_type.c_str())); | |
| 286 return false; | 316 return false; |
| 287 } | 317 } |
| 288 | 318 |
| 289 if (!success) { | 319 if (!success) { |
| 290 ONC_LOG_ERROR("Unknown error importing " + cert_type + " certificate."); | 320 LOG(ERROR) << "Unknown error importing " << cert_type << " certificate."; |
| 291 return false; | 321 return false; |
| 292 } | 322 } |
| 293 } | 323 } |
| 294 | 324 |
| 295 if (web_trust_flag && onc_trusted_certificates) | 325 if (web_trust_flag && onc_trusted_certificates) |
| 296 onc_trusted_certificates->push_back(x509_cert); | 326 onc_trusted_certificates->push_back(x509_cert); |
| 297 | 327 |
| 298 if (imported_server_and_ca_certs) | |
| 299 (*imported_server_and_ca_certs)[guid] = x509_cert; | |
| 300 | |
| 301 return true; | 328 return true; |
| 302 } | 329 } |
| 303 | 330 |
| 304 bool CertificateImporterImpl::ParseClientCertificate( | 331 bool CertificateImporterImpl::ParseClientCertificate( |
| 305 const std::string& guid, | 332 const std::string& guid, |
| 306 const base::DictionaryValue& certificate) { | 333 const base::DictionaryValue& certificate, |
| 334 net::NSSCertDatabase* nssdb) { | |
| 307 std::string pkcs12_data; | 335 std::string pkcs12_data; |
| 308 if (!certificate.GetStringWithoutPathExpansion(::onc::certificate::kPKCS12, | 336 if (!certificate.GetStringWithoutPathExpansion(::onc::certificate::kPKCS12, |
| 309 &pkcs12_data) || | 337 &pkcs12_data) || |
| 310 pkcs12_data.empty()) { | 338 pkcs12_data.empty()) { |
| 311 ONC_LOG_ERROR("PKCS12 data is missing for client certificate."); | 339 LOG(ERROR) << "PKCS12 data is missing for client certificate."; |
| 312 return false; | 340 return false; |
| 313 } | 341 } |
| 314 | 342 |
| 315 std::string decoded_pkcs12; | 343 std::string decoded_pkcs12; |
| 316 if (!base::Base64Decode(pkcs12_data, &decoded_pkcs12)) { | 344 if (!base::Base64Decode(pkcs12_data, &decoded_pkcs12)) { |
| 317 ONC_LOG_ERROR( | 345 LOG(ERROR) << "Unable to base64 decode PKCS#12 data: \"" << pkcs12_data |
| 318 "Unable to base64 decode PKCS#12 data: \"" + pkcs12_data + "\"."); | 346 << "\"."; |
| 319 return false; | 347 return false; |
| 320 } | 348 } |
| 321 | 349 |
| 322 // Since this has a private key, always use the private module. | 350 // Since this has a private key, always use the private module. |
| 323 crypto::ScopedPK11Slot private_slot(target_nssdb_->GetPrivateSlot()); | 351 crypto::ScopedPK11Slot private_slot(nssdb->GetPrivateSlot()); |
| 324 if (!private_slot) | 352 if (!private_slot) |
| 325 return false; | 353 return false; |
| 326 scoped_refptr<net::CryptoModule> module( | 354 scoped_refptr<net::CryptoModule> module( |
| 327 net::CryptoModule::CreateFromHandle(private_slot.get())); | 355 net::CryptoModule::CreateFromHandle(private_slot.get())); |
| 328 net::CertificateList imported_certs; | 356 net::CertificateList imported_certs; |
| 329 | 357 |
| 330 int import_result = target_nssdb_->ImportFromPKCS12( | 358 int import_result = nssdb->ImportFromPKCS12( |
| 331 module.get(), decoded_pkcs12, base::string16(), false, &imported_certs); | 359 module.get(), decoded_pkcs12, base::string16(), false, &imported_certs); |
| 332 if (import_result != net::OK) { | 360 if (import_result != net::OK) { |
| 333 std::string error_string = net::ErrorToString(import_result); | 361 std::string error_string = net::ErrorToString(import_result); |
| 334 ONC_LOG_ERROR( | 362 LOG(ERROR) << "Unable to import client certificate, error: " |
| 335 base::StringPrintf("Unable to import client certificate (error %s)", | 363 << error_string; |
| 336 error_string.c_str())); | |
| 337 return false; | 364 return false; |
| 338 } | 365 } |
| 339 | 366 |
| 340 if (imported_certs.size() == 0) { | 367 if (imported_certs.size() == 0) { |
| 341 ONC_LOG_WARNING("PKCS12 data contains no importable certificates."); | 368 LOG(WARNING) << "PKCS12 data contains no importable certificates."; |
| 342 return true; | 369 return true; |
| 343 } | 370 } |
| 344 | 371 |
| 345 if (imported_certs.size() != 1) { | 372 if (imported_certs.size() != 1) { |
| 346 ONC_LOG_WARNING("ONC File: PKCS12 data contains more than one certificate. " | 373 LOG(WARNING) << "ONC File: PKCS12 data contains more than one certificate. " |
| 347 "Only the first one will be imported."); | 374 "Only the first one will be imported."; |
| 348 } | 375 } |
| 349 | 376 |
| 350 scoped_refptr<net::X509Certificate> cert_result = imported_certs[0]; | 377 scoped_refptr<net::X509Certificate> cert_result = imported_certs[0]; |
| 351 | 378 |
| 352 // Find the private key associated with this certificate, and set the | 379 // Find the private key associated with this certificate, and set the |
| 353 // nickname on it. | 380 // nickname on it. |
| 354 SECKEYPrivateKey* private_key = PK11_FindPrivateKeyFromCert( | 381 SECKEYPrivateKey* private_key = PK11_FindPrivateKeyFromCert( |
| 355 cert_result->os_cert_handle()->slot, | 382 cert_result->os_cert_handle()->slot, |
| 356 cert_result->os_cert_handle(), | 383 cert_result->os_cert_handle(), |
| 357 NULL); // wincx | 384 NULL); // wincx |
| 358 if (private_key) { | 385 if (private_key) { |
| 359 PK11_SetPrivateKeyNickname(private_key, const_cast<char*>(guid.c_str())); | 386 PK11_SetPrivateKeyNickname(private_key, const_cast<char*>(guid.c_str())); |
| 360 SECKEY_DestroyPrivateKey(private_key); | 387 SECKEY_DestroyPrivateKey(private_key); |
| 361 } else { | 388 } else { |
| 362 ONC_LOG_WARNING("Unable to find private key for certificate."); | 389 LOG(WARNING) << "Unable to find private key for certificate."; |
| 363 } | 390 } |
| 364 return true; | 391 return true; |
| 365 } | 392 } |
| 366 | 393 |
| 367 } // namespace onc | 394 } // namespace onc |
| 368 } // namespace chromeos | 395 } // namespace chromeos |
| OLD | NEW |