| Index: net/cert/nss_cert_database.cc
|
| diff --git a/net/cert/nss_cert_database.cc b/net/cert/nss_cert_database.cc
|
| index ed861b200bfeb207ee1fa6ff2fe75a9a72bb429c..73b446a8fd9ed7ee7643d6b20c506f815aff18a8 100644
|
| --- a/net/cert/nss_cert_database.cc
|
| +++ b/net/cert/nss_cert_database.cc
|
| @@ -132,6 +132,60 @@ void NSSCertDatabase::ListModules(CryptoModuleList* modules,
|
| }
|
| }
|
|
|
| +bool NSSCertDatabase::ImportPKCS8KeyAndCertificate(
|
| + const std::string& pkcs8_data,
|
| + X509Certificate* cert,
|
| + CryptoModule* module) {
|
| + DVLOG(1) << __func__ << " " << PK11_GetModuleID(module->os_module_handle())
|
| + << ":" << PK11_GetSlotID(module->os_module_handle());
|
| +
|
| + crypto::ScopedSECKEYPrivateKey private_key;
|
| + CertDatabase* db = CertDatabase::GetInstance();
|
| + int cert_status = db->CheckUserCert(cert);
|
| + if (cert_status == ERR_NO_PRIVATE_KEY_FOR_CERT) {
|
| + LOG(ERROR) << "Importing private key.";
|
| + SECItem pki_der = {
|
| + siBuffer,
|
| + // NSS requires non-const data even though it is just for input.
|
| + const_cast<unsigned char*>((const unsigned char*)pkcs8_data.data()),
|
| + pkcs8_data.size()};
|
| +
|
| + SECKEYPrivateKey* seckey_private_key = NULL;
|
| + if (PK11_ImportDERPrivateKeyInfoAndReturnKey(module->os_module_handle(),
|
| + &pki_der,
|
| + NULL, // nickname
|
| + NULL, // publicValue
|
| + true, // isPerm
|
| + true, // isPrivate
|
| + KU_ALL, // usage
|
| + &seckey_private_key,
|
| + NULL) != SECSuccess) {
|
| + LOG(ERROR) << "Could not import private key " << PORT_GetError();
|
| + return false;
|
| + }
|
| + DCHECK(seckey_private_key);
|
| + private_key.reset(seckey_private_key);
|
| +
|
| + cert_status = db->CheckUserCert(cert);
|
| + }
|
| + if (cert_status != net::OK) {
|
| + LOG(ERROR) << "Cert invalid, cannot import: " << cert_status;
|
| + return false;
|
| + }
|
| +
|
| + if (db->AddUserCert(cert) != net::OK) {
|
| + // Delete the imported private key because the certificate didn't import.
|
| + if (private_key) {
|
| + // Always destroys the private key.
|
| + if (PK11_DeleteTokenPrivateKey(private_key.release(), PR_FALSE)) {
|
| + LOG(ERROR) << "PK11_DeleteTokenCertAndKey failed: " << PORT_GetError();
|
| + }
|
| + }
|
| + return false;
|
| + }
|
| + return true;
|
| +}
|
| +
|
| int NSSCertDatabase::ImportFromPKCS12(
|
| CryptoModule* module,
|
| const std::string& data,
|
|
|