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