Index: crypto/rsa_private_key_openssl.cc |
diff --git a/crypto/rsa_private_key_openssl.cc b/crypto/rsa_private_key_openssl.cc |
index f7fdd9d1d16298ed6eb44c5071901949c870c250..3e87a0a5ff5b6b78aebdd59c9c1812b9ba706b0a 100644 |
--- a/crypto/rsa_private_key_openssl.cc |
+++ b/crypto/rsa_private_key_openssl.cc |
@@ -4,55 +4,21 @@ |
#include "crypto/rsa_private_key.h" |
-#include <openssl/bio.h> |
+#include <openssl/bytestring.h> |
#include <openssl/bn.h> |
#include <openssl/evp.h> |
-#include <openssl/pkcs12.h> |
+#include <openssl/mem.h> |
#include <openssl/rsa.h> |
#include <stdint.h> |
#include "base/logging.h" |
#include "base/memory/scoped_ptr.h" |
+#include "crypto/auto_cbb.h" |
#include "crypto/openssl_util.h" |
#include "crypto/scoped_openssl_types.h" |
namespace crypto { |
-namespace { |
- |
-using ScopedPKCS8_PRIV_KEY_INFO = |
- ScopedOpenSSL<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_free>; |
- |
-// Function pointer definition, for injecting the required key export function |
-// into ExportKey, below. The supplied function should export EVP_PKEY into |
-// the supplied BIO, returning 1 on success or 0 on failure. |
-using ExportFunction = int (*)(BIO*, EVP_PKEY*); |
- |
-// Helper to export |key| into |output| via the specified ExportFunction. |
-bool ExportKey(EVP_PKEY* key, |
- ExportFunction export_fn, |
- std::vector<uint8_t>* output) { |
- if (!key) |
- return false; |
- |
- OpenSSLErrStackTracer err_tracer(FROM_HERE); |
- ScopedBIO bio(BIO_new(BIO_s_mem())); |
- |
- int res = export_fn(bio.get(), key); |
- if (!res) |
- return false; |
- |
- char* data = NULL; |
- long len = BIO_get_mem_data(bio.get(), &data); |
- if (!data || len < 0) |
- return false; |
- |
- output->assign(data, data + len); |
- return true; |
-} |
- |
-} // namespace |
- |
// static |
RSAPrivateKey* RSAPrivateKey::Create(uint16_t num_bits) { |
OpenSSLErrStackTracer err_tracer(FROM_HERE); |
@@ -76,25 +42,16 @@ RSAPrivateKey* RSAPrivateKey::Create(uint16_t num_bits) { |
// static |
RSAPrivateKey* RSAPrivateKey::CreateFromPrivateKeyInfo( |
const std::vector<uint8_t>& input) { |
- if (input.empty()) |
- return NULL; |
- |
OpenSSLErrStackTracer err_tracer(FROM_HERE); |
- // Importing is a little more involved than exporting, as we must first |
- // PKCS#8 decode the input, and then import the EVP_PKEY from Private Key |
- // Info structure returned. |
- const uint8_t* ptr = &input[0]; |
- ScopedPKCS8_PRIV_KEY_INFO p8inf( |
- d2i_PKCS8_PRIV_KEY_INFO(nullptr, &ptr, input.size())); |
- if (!p8inf.get() || ptr != &input[0] + input.size()) |
- return NULL; |
+ CBS cbs; |
+ CBS_init(&cbs, input.data(), input.size()); |
+ ScopedEVP_PKEY pkey(EVP_parse_private_key(&cbs)); |
+ if (!pkey || CBS_len(&cbs) != 0 || EVP_PKEY_id(pkey.get()) != EVP_PKEY_RSA) |
+ return nullptr; |
scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey); |
- result->key_ = EVP_PKCS82PKEY(p8inf.get()); |
- if (!result->key_ || EVP_PKEY_id(result->key_) != EVP_PKEY_RSA) |
- return NULL; |
- |
+ result->key_ = pkey.release(); |
return result.release(); |
} |
@@ -129,11 +86,31 @@ RSAPrivateKey* RSAPrivateKey::Copy() const { |
} |
bool RSAPrivateKey::ExportPrivateKey(std::vector<uint8_t>* output) const { |
- return ExportKey(key_, i2d_PKCS8PrivateKeyInfo_bio, output); |
+ uint8_t *der; |
+ size_t der_len; |
+ AutoCBB cbb; |
+ if (!CBB_init(cbb.get(), 0) || |
+ !EVP_marshal_private_key(cbb.get(), key_) || |
+ !CBB_finish(cbb.get(), &der, &der_len)) { |
+ return false; |
+ } |
+ output->assign(der, der + der_len); |
+ OPENSSL_free(der); |
+ return true; |
} |
bool RSAPrivateKey::ExportPublicKey(std::vector<uint8_t>* output) const { |
- return ExportKey(key_, i2d_PUBKEY_bio, output); |
+ uint8_t *der; |
+ size_t der_len; |
+ AutoCBB cbb; |
+ if (!CBB_init(cbb.get(), 0) || |
+ !EVP_marshal_public_key(cbb.get(), key_) || |
+ !CBB_finish(cbb.get(), &der, &der_len)) { |
+ return false; |
+ } |
+ output->assign(der, der + der_len); |
+ OPENSSL_free(der); |
+ return true; |
} |
} // namespace crypto |