| Index: crypto/ec_private_key_openssl.cc
|
| diff --git a/crypto/ec_private_key_openssl.cc b/crypto/ec_private_key_openssl.cc
|
| index beda29fe13b7a5966027f335855966de2e415ac7..2d44759d8b0f92faad620624001767b5517ebe59 100644
|
| --- a/crypto/ec_private_key_openssl.cc
|
| +++ b/crypto/ec_private_key_openssl.cc
|
| @@ -117,28 +117,31 @@ ECPrivateKey* ECPrivateKey::CreateFromEncryptedPrivateKeyInfo(
|
| return NULL;
|
|
|
| OpenSSLErrStackTracer err_tracer(FROM_HERE);
|
| - // Write the encrypted private key into a memory BIO.
|
| - char* private_key_data = reinterpret_cast<char*>(
|
| - const_cast<uint8*>(&encrypted_private_key_info[0]));
|
| - int private_key_data_len =
|
| - static_cast<int>(encrypted_private_key_info.size());
|
| - ScopedBIO bio(BIO_new_mem_buf(private_key_data, private_key_data_len));
|
| - if (!bio.get())
|
| - return NULL;
|
|
|
| - // Convert it, then decrypt it into a PKCS#8 object.
|
| - ScopedX509_SIG p8_encrypted(d2i_PKCS8_bio(bio.get(), NULL));
|
| - if (!p8_encrypted.get())
|
| + const uint8_t* data = &encrypted_private_key_info[0];
|
| + const uint8_t* ptr = data;
|
| + ScopedX509_SIG p8_encrypted(
|
| + d2i_X509_SIG(NULL, &ptr, encrypted_private_key_info.size()));
|
| + if (!p8_encrypted || ptr != data + encrypted_private_key_info.size())
|
| return NULL;
|
|
|
| - ScopedPKCS8_PRIV_KEY_INFO p8_decrypted(PKCS8_decrypt(
|
| - p8_encrypted.get(), password.c_str(), static_cast<int>(password.size())));
|
| - if (!p8_decrypted.get() && password.empty()) {
|
| - // Hack for reading keys generated by ec_private_key_nss. Passing NULL
|
| - // causes OpenSSL to use an empty password instead of "\0\0".
|
| - p8_decrypted.reset(PKCS8_decrypt(p8_encrypted.get(), NULL, 0));
|
| + ScopedPKCS8_PRIV_KEY_INFO p8_decrypted;
|
| + if (password.empty()) {
|
| + // Hack for reading keys generated by an older version of the OpenSSL
|
| + // code. OpenSSL used to use "\0\0" rather than the empty string because it
|
| + // would treat the password as an ASCII string to be converted to UCS-2
|
| + // while NSS used a byte string.
|
| + p8_decrypted.reset(PKCS8_decrypt_pbe(
|
| + p8_encrypted.get(), reinterpret_cast<const uint8_t*>("\0\0"), 2));
|
| }
|
| - if (!p8_decrypted.get())
|
| + if (!p8_decrypted) {
|
| + p8_decrypted.reset(PKCS8_decrypt_pbe(
|
| + p8_encrypted.get(),
|
| + reinterpret_cast<const uint8_t*>(password.data()),
|
| + password.size()));
|
| + }
|
| +
|
| + if (!p8_decrypted)
|
| return NULL;
|
|
|
| // Create a new EVP_PKEY for it.
|
| @@ -164,14 +167,14 @@ bool ECPrivateKey::ExportEncryptedPrivateKey(
|
| // NOTE: NSS uses SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC
|
| // so use NID_pbe_WithSHA1And3_Key_TripleDES_CBC which should be the OpenSSL
|
| // equivalent.
|
| - ScopedX509_SIG encrypted(PKCS8_encrypt(NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
|
| - NULL,
|
| - password.c_str(),
|
| - static_cast<int>(password.size()),
|
| - NULL,
|
| - 0,
|
| - iterations,
|
| - pkcs8.get()));
|
| + ScopedX509_SIG encrypted(PKCS8_encrypt_pbe(
|
| + NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
|
| + reinterpret_cast<const uint8_t*>(password.data()),
|
| + password.size(),
|
| + NULL,
|
| + 0,
|
| + iterations,
|
| + pkcs8.get()));
|
| if (!encrypted.get())
|
| return false;
|
|
|
|
|