Index: crypto/ec_private_key_nss.cc |
diff --git a/crypto/ec_private_key_nss.cc b/crypto/ec_private_key_nss.cc |
index cc46101124cc10e1e74c18b79da2b9206f580c6b..1fb13e7e9ca91d8673ac397b00bd24dffd3e91b2 100644 |
--- a/crypto/ec_private_key_nss.cc |
+++ b/crypto/ec_private_key_nss.cc |
@@ -104,6 +104,76 @@ ECPrivateKey* ECPrivateKey::CreateSensitiveFromEncryptedPrivateKeyInfo( |
#endif |
} |
+// static |
+bool ECPrivateKey::ImportFromEncryptedPrivateKeyInfo( |
+ const std::string& password, |
+ const uint8* encrypted_private_key_info, |
+ size_t encrypted_private_key_info_len, |
+ CERTSubjectPublicKeyInfo* decoded_spki, |
+ bool permanent, |
+ bool sensitive, |
+ SECKEYPrivateKey** key, |
+ SECKEYPublicKey** public_key) { |
+ ScopedPK11Slot slot(GetPrivateNSSKeySlot()); |
+ if (!slot.get()) |
+ return false; |
+ |
+ *public_key = SECKEY_ExtractPublicKey(decoded_spki); |
+ |
+ if (!*public_key) { |
+ DLOG(ERROR) << "SECKEY_ExtractPublicKey: " << PORT_GetError(); |
+ return false; |
+ } |
+ |
+ SECItem encoded_epki = { |
+ siBuffer, |
+ const_cast<unsigned char*>(encrypted_private_key_info), |
+ encrypted_private_key_info_len |
+ }; |
+ SECKEYEncryptedPrivateKeyInfo epki; |
+ memset(&epki, 0, sizeof(epki)); |
+ |
+ ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE)); |
+ |
+ SECStatus rv = SEC_QuickDERDecodeItem( |
+ arena.get(), |
+ &epki, |
+ SEC_ASN1_GET(SECKEY_EncryptedPrivateKeyInfoTemplate), |
+ &encoded_epki); |
+ if (rv != SECSuccess) { |
+ DLOG(ERROR) << "SEC_QuickDERDecodeItem: " << PORT_GetError(); |
+ SECKEY_DestroyPublicKey(*public_key); |
+ *public_key = NULL; |
+ return false; |
+ } |
+ |
+ SECItem password_item = { |
+ siBuffer, |
+ reinterpret_cast<unsigned char*>(const_cast<char*>(password.data())), |
+ password.size() |
+ }; |
+ |
+ rv = ImportEncryptedECPrivateKeyInfoAndReturnKey( |
+ slot.get(), |
+ &epki, |
+ &password_item, |
+ NULL, // nickname |
+ &(*public_key)->u.ec.publicValue, |
+ permanent, |
+ sensitive, |
+ key, |
+ NULL); // wincx |
+ if (rv != SECSuccess) { |
+ DLOG(ERROR) << "ImportEncryptedECPrivateKeyInfoAndReturnKey: " |
+ << PORT_GetError(); |
+ SECKEY_DestroyPublicKey(*public_key); |
+ *public_key = NULL; |
+ return false; |
+ } |
+ |
+ return true; |
+} |
+ |
bool ECPrivateKey::ExportEncryptedPrivateKey( |
const std::string& password, |
int iterations, |
@@ -227,10 +297,6 @@ ECPrivateKey* ECPrivateKey::CreateFromEncryptedPrivateKeyInfoWithParams( |
scoped_ptr<ECPrivateKey> result(new ECPrivateKey); |
- ScopedPK11Slot slot(GetPrivateNSSKeySlot()); |
- if (!slot.get()) |
- return NULL; |
- |
SECItem encoded_spki = { |
siBuffer, |
const_cast<unsigned char*>(&subject_public_key_info[0]), |
@@ -243,58 +309,22 @@ ECPrivateKey* ECPrivateKey::CreateFromEncryptedPrivateKeyInfoWithParams( |
return NULL; |
} |
- result->public_key_ = SECKEY_ExtractPublicKey(decoded_spki); |
- |
- SECKEY_DestroySubjectPublicKeyInfo(decoded_spki); |
- |
- if (!result->public_key_) { |
- DLOG(ERROR) << "SECKEY_ExtractPublicKey: " << PORT_GetError(); |
- return NULL; |
- } |
- |
- SECItem encoded_epki = { |
- siBuffer, |
- const_cast<unsigned char*>(&encrypted_private_key_info[0]), |
- encrypted_private_key_info.size() |
- }; |
- SECKEYEncryptedPrivateKeyInfo epki; |
- memset(&epki, 0, sizeof(epki)); |
- |
- ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE)); |
- |
- SECStatus rv = SEC_QuickDERDecodeItem( |
- arena.get(), |
- &epki, |
- SEC_ASN1_GET(SECKEY_EncryptedPrivateKeyInfoTemplate), |
- &encoded_epki); |
- if (rv != SECSuccess) { |
- DLOG(ERROR) << "SEC_ASN1DecodeItem: " << PORT_GetError(); |
- return NULL; |
- } |
- |
- SECItem password_item = { |
- siBuffer, |
- reinterpret_cast<unsigned char*>(const_cast<char*>(password.data())), |
- password.size() |
- }; |
- |
- rv = ImportEncryptedECPrivateKeyInfoAndReturnKey( |
- slot.get(), |
- &epki, |
- &password_item, |
- NULL, // nickname |
- &result->public_key_->u.ec.publicValue, |
+ bool success = ECPrivateKey::ImportFromEncryptedPrivateKeyInfo( |
+ password, |
+ &encrypted_private_key_info[0], |
+ encrypted_private_key_info.size(), |
+ decoded_spki, |
permanent, |
sensitive, |
&result->key_, |
- NULL); // wincx |
- if (rv != SECSuccess) { |
- DLOG(ERROR) << "ImportEncryptedECPrivateKeyInfoAndReturnKey: " |
- << PORT_GetError(); |
- return NULL; |
- } |
+ &result->public_key_); |
- return result.release(); |
+ SECKEY_DestroySubjectPublicKeyInfo(decoded_spki); |
+ |
+ if (success) |
+ return result.release(); |
+ |
+ return NULL; |
} |
} // namespace crypto |