diff options
author | joth@chromium.org <joth@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-17 14:39:22 +0000 |
---|---|---|
committer | joth@chromium.org <joth@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-17 14:39:22 +0000 |
commit | 1f9239433087c7e4bf87ff8b431b0c83566165da (patch) | |
tree | cdbecef8364217ef2bfcd776d5b7ddc91ddd52e8 /base/crypto | |
parent | ad3d692a21bd7b3596eee562f70a4dfd5a4308f3 (diff) | |
download | chromium_src-1f9239433087c7e4bf87ff8b431b0c83566165da.zip chromium_src-1f9239433087c7e4bf87ff8b431b0c83566165da.tar.gz chromium_src-1f9239433087c7e4bf87ff8b431b0c83566165da.tar.bz2 |
Implements RSAPrivateKey for openssl.
Leaves the declared NSS-only methods (CreateSensitive.. & FindFromPublicKeyInfo) as UNIMPLEMENTED.
BUG=None
TEST=base_unittests --gtest_filter=RSA*
Review URL: http://codereview.chromium.org/5047003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@66438 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/crypto')
-rw-r--r-- | base/crypto/rsa_private_key.h | 11 | ||||
-rw-r--r-- | base/crypto/rsa_private_key_openssl.cc | 111 |
2 files changed, 91 insertions, 31 deletions
diff --git a/base/crypto/rsa_private_key.h b/base/crypto/rsa_private_key.h index 4492c3d..ea5daac 100644 --- a/base/crypto/rsa_private_key.h +++ b/base/crypto/rsa_private_key.h @@ -8,7 +8,10 @@ #include "build/build_config.h" -#if defined(USE_NSS) +#if defined(USE_OPENSSL) +// Forward declaration for openssl/*.h +typedef struct evp_pkey_st EVP_PKEY; +#elif defined(USE_NSS) // Forward declaration. struct SECKEYPrivateKeyStr; struct SECKEYPublicKeyStr; @@ -216,7 +219,7 @@ class RSAPrivateKey { // Exports the public key to an X509 SubjectPublicKeyInfo block. bool ExportPublicKey(std::vector<uint8>* output); -private: + private: #if defined(USE_NSS) FRIEND_TEST_ALL_PREFIXES(RSAPrivateKeyNSSTest, FindFromPublicKey); FRIEND_TEST_ALL_PREFIXES(RSAPrivateKeyNSSTest, FailedFindFromPublicKey); @@ -238,7 +241,9 @@ private: static RSAPrivateKey* CreateFromPrivateKeyInfoWithParams( const std::vector<uint8>& input, bool permanent, bool sensitive); -#if defined(USE_NSS) +#if defined(USE_OPENSSL) + EVP_PKEY* key_; +#elif defined(USE_NSS) SECKEYPrivateKeyStr* key_; SECKEYPublicKeyStr* public_key_; #elif defined(OS_WIN) diff --git a/base/crypto/rsa_private_key_openssl.cc b/base/crypto/rsa_private_key_openssl.cc index ec1d8b5..e14965f 100644 --- a/base/crypto/rsa_private_key_openssl.cc +++ b/base/crypto/rsa_private_key_openssl.cc @@ -4,35 +4,69 @@ #include "base/crypto/rsa_private_key.h" +#include <openssl/evp.h> +#include <openssl/pkcs12.h> +#include <openssl/rsa.h> + #include "base/logging.h" +#include "base/openssl_util.h" +#include "base/scoped_ptr.h" +#include "base/stl_util-inl.h" namespace base { -// static -RSAPrivateKey* RSAPrivateKey::CreateWithParams(uint16 num_bits, - bool permanent, - bool sensitive) { - NOTIMPLEMENTED(); - return NULL; +namespace { + +// 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. +typedef int (ExportFunction)(BIO*, EVP_PKEY*); + +// Helper to export |key| into |output| via the specified ExportFunction. +bool ExportKey(EVP_PKEY* key, + ExportFunction export_fn, + std::vector<uint8>* output) { + if (!key) + return false; + + ScopedOpenSSL<BIO, BIO_free_all> bio(BIO_new(BIO_s_mem())); + + int res = export_fn(bio.get(), key); + ClearOpenSSLERRStack(); + if (!res) + return false; + + char* data = NULL; + long len = BIO_get_mem_data(bio.get(), &data); + if (!data || len < 0) + return false; + + STLAssignToVector(output, reinterpret_cast<const uint8*>(data), len); + return true; } +} // namespace + // static RSAPrivateKey* RSAPrivateKey::Create(uint16 num_bits) { - return CreateWithParams(num_bits, - false /* not permanent */, - false /* not sensitive */); -} + EnsureOpenSSLInit(); -// static -RSAPrivateKey* RSAPrivateKey::CreateSensitive(uint16 num_bits) { - return CreateWithParams(num_bits, - true /* permanent */, - true /* sensitive */); + ScopedOpenSSL<RSA, RSA_free> rsa_key(RSA_generate_key(num_bits, 65537L, + NULL, NULL)); + ClearOpenSSLERRStack(); + if (!rsa_key.get()) + return NULL; + + scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey); + result->key_ = EVP_PKEY_new(); + if (!result->key_ || !EVP_PKEY_set1_RSA(result->key_, rsa_key.get())) + return NULL; + + return result.release(); } // static -RSAPrivateKey* RSAPrivateKey::CreateFromPrivateKeyInfoWithParams( - const std::vector<uint8>& input, bool permanent, bool sensitive) { +RSAPrivateKey* RSAPrivateKey::CreateSensitive(uint16 num_bits) { NOTIMPLEMENTED(); return NULL; } @@ -40,17 +74,37 @@ RSAPrivateKey* RSAPrivateKey::CreateFromPrivateKeyInfoWithParams( // static RSAPrivateKey* RSAPrivateKey::CreateFromPrivateKeyInfo( const std::vector<uint8>& input) { - return CreateFromPrivateKeyInfoWithParams(input, - false /* not permanent */, - false /* not sensitive */); + EnsureOpenSSLInit(); + + // BIO_new_mem_buf is not const aware, but it does not modify the buffer. + char* data = reinterpret_cast<char*>(const_cast<uint8*>(input.data())); + ScopedOpenSSL<BIO, BIO_free_all> bio(BIO_new_mem_buf(data, input.size())); + if (!bio.get()) + return NULL; + + // 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. + ScopedOpenSSL<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_free> p8inf( + d2i_PKCS8_PRIV_KEY_INFO_bio(bio.get(), NULL)); + ClearOpenSSLERRStack(); + if (!p8inf.get()) + return NULL; + + scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey); + result->key_ = EVP_PKCS82PKEY(p8inf.get()); + ClearOpenSSLERRStack(); + if (!result->key_) + return NULL; + + return result.release(); } // static RSAPrivateKey* RSAPrivateKey::CreateSensitiveFromPrivateKeyInfo( const std::vector<uint8>& input) { - return CreateFromPrivateKeyInfoWithParams(input, - true /* permanent */, - true /* seneitive */); + NOTIMPLEMENTED(); + return NULL; } // static @@ -60,20 +114,21 @@ RSAPrivateKey* RSAPrivateKey::FindFromPublicKeyInfo( return NULL; } -RSAPrivateKey::RSAPrivateKey() { +RSAPrivateKey::RSAPrivateKey() + : key_(NULL) { } RSAPrivateKey::~RSAPrivateKey() { + if (key_) + EVP_PKEY_free(key_); } bool RSAPrivateKey::ExportPrivateKey(std::vector<uint8>* output) { - NOTIMPLEMENTED(); - return false; + return ExportKey(key_, i2d_PKCS8PrivateKeyInfo_bio, output); } bool RSAPrivateKey::ExportPublicKey(std::vector<uint8>* output) { - NOTIMPLEMENTED(); - return false; + return ExportKey(key_, i2d_PUBKEY_bio, output); } } // namespace base |