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, |