diff options
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/ec_private_key_openssl.cc | 46 | ||||
-rw-r--r-- | crypto/ec_signature_creator_openssl.cc | 11 | ||||
-rw-r--r-- | crypto/openssl_bio_string_unittest.cc | 10 | ||||
-rw-r--r-- | crypto/openssl_util.h | 30 | ||||
-rw-r--r-- | crypto/rsa_private_key_openssl.cc | 11 | ||||
-rw-r--r-- | crypto/scoped_openssl_types.h | 49 | ||||
-rw-r--r-- | crypto/signature_verifier_openssl.cc | 11 |
7 files changed, 98 insertions, 70 deletions
diff --git a/crypto/ec_private_key_openssl.cc b/crypto/ec_private_key_openssl.cc index b7b6b48..beda29f 100644 --- a/crypto/ec_private_key_openssl.cc +++ b/crypto/ec_private_key_openssl.cc @@ -12,6 +12,7 @@ #include "base/logging.h" #include "base/memory/scoped_ptr.h" #include "crypto/openssl_util.h" +#include "crypto/scoped_openssl_types.h" namespace crypto { @@ -24,6 +25,10 @@ namespace { // style guide, hence the unusual parameter placement / types. typedef int (*ExportBioFunction)(BIO* bio, const void* key); +typedef ScopedOpenSSL<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_free>::Type + ScopedPKCS8_PRIV_KEY_INFO; +typedef ScopedOpenSSL<X509_SIG, X509_SIG_free>::Type ScopedX509_SIG; + // Helper to export |key| into |output| via the specified ExportBioFunction. bool ExportKeyWithBio(const void* key, ExportBioFunction export_fn, @@ -31,7 +36,7 @@ bool ExportKeyWithBio(const void* key, if (!key) return false; - ScopedOpenSSL<BIO, BIO_free_all> bio(BIO_new(BIO_s_mem())); + ScopedBIO bio(BIO_new(BIO_s_mem())); if (!bio.get()) return false; @@ -87,8 +92,7 @@ bool ECPrivateKey::IsSupported() { return true; } ECPrivateKey* ECPrivateKey::Create() { OpenSSLErrStackTracer err_tracer(FROM_HERE); - ScopedOpenSSL<EC_KEY, EC_KEY_free> ec_key( - EC_KEY_new_by_curve_name(NID_X9_62_prime256v1)); + ScopedEC_KEY ec_key(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1)); if (!ec_key.get() || !EC_KEY_generate_key(ec_key.get())) return NULL; @@ -118,21 +122,17 @@ ECPrivateKey* ECPrivateKey::CreateFromEncryptedPrivateKeyInfo( const_cast<uint8*>(&encrypted_private_key_info[0])); int private_key_data_len = static_cast<int>(encrypted_private_key_info.size()); - ScopedOpenSSL<BIO, BIO_free_all> bio( - BIO_new_mem_buf(private_key_data, private_key_data_len)); + 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. - ScopedOpenSSL<X509_SIG, X509_SIG_free> p8_encrypted( - d2i_PKCS8_bio(bio.get(), NULL)); + ScopedX509_SIG p8_encrypted(d2i_PKCS8_bio(bio.get(), NULL)); if (!p8_encrypted.get()) return NULL; - ScopedOpenSSL<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_free> p8_decrypted( - PKCS8_decrypt(p8_encrypted.get(), - password.c_str(), - static_cast<int>(password.size()))); + 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". @@ -156,8 +156,7 @@ bool ECPrivateKey::ExportEncryptedPrivateKey( std::vector<uint8>* output) { OpenSSLErrStackTracer err_tracer(FROM_HERE); // Convert into a PKCS#8 object. - ScopedOpenSSL<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_free> pkcs8( - EVP_PKEY2PKCS8(key_)); + ScopedPKCS8_PRIV_KEY_INFO pkcs8(EVP_PKEY2PKCS8(key_)); if (!pkcs8.get()) return false; @@ -165,15 +164,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. - ScopedOpenSSL<X509_SIG, X509_SIG_free> 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(NID_pbe_WithSHA1And3_Key_TripleDES_CBC, + NULL, + password.c_str(), + static_cast<int>(password.size()), + NULL, + 0, + iterations, + pkcs8.get())); if (!encrypted.get()) return false; @@ -211,7 +209,7 @@ bool ECPrivateKey::ExportRawPublicKey(std::string* output) { bool ECPrivateKey::ExportValue(std::vector<uint8>* output) { OpenSSLErrStackTracer err_tracer(FROM_HERE); - ScopedOpenSSL<EC_KEY, EC_KEY_free> ec_key(EVP_PKEY_get1_EC_KEY(key_)); + ScopedEC_KEY ec_key(EVP_PKEY_get1_EC_KEY(key_)); return ExportKey(ec_key.get(), reinterpret_cast<ExportDataFunction>(i2d_ECPrivateKey), output); @@ -219,7 +217,7 @@ bool ECPrivateKey::ExportValue(std::vector<uint8>* output) { bool ECPrivateKey::ExportECParams(std::vector<uint8>* output) { OpenSSLErrStackTracer err_tracer(FROM_HERE); - ScopedOpenSSL<EC_KEY, EC_KEY_free> ec_key(EVP_PKEY_get1_EC_KEY(key_)); + ScopedEC_KEY ec_key(EVP_PKEY_get1_EC_KEY(key_)); return ExportKey(ec_key.get(), reinterpret_cast<ExportDataFunction>(i2d_ECParameters), output); diff --git a/crypto/ec_signature_creator_openssl.cc b/crypto/ec_signature_creator_openssl.cc index 7f0a873..adff2c9 100644 --- a/crypto/ec_signature_creator_openssl.cc +++ b/crypto/ec_signature_creator_openssl.cc @@ -13,9 +13,16 @@ #include "base/logging.h" #include "crypto/ec_private_key.h" #include "crypto/openssl_util.h" +#include "crypto/scoped_openssl_types.h" namespace crypto { +namespace { + +typedef ScopedOpenSSL<ECDSA_SIG, ECDSA_SIG_free>::Type ScopedECDSA_SIG; + +} // namespace + ECSignatureCreatorImpl::ECSignatureCreatorImpl(ECPrivateKey* key) : key_(key), signature_len_(0) { EnsureOpenSSLInit(); @@ -27,7 +34,7 @@ bool ECSignatureCreatorImpl::Sign(const uint8* data, int data_len, std::vector<uint8>* signature) { OpenSSLErrStackTracer err_tracer(FROM_HERE); - ScopedOpenSSL<EVP_MD_CTX, EVP_MD_CTX_destroy> ctx(EVP_MD_CTX_create()); + ScopedEVP_MD_CTX ctx(EVP_MD_CTX_create()); size_t sig_len = 0; if (!ctx.get() || !EVP_DigestSignInit(ctx.get(), NULL, EVP_sha256(), NULL, key_->key()) || @@ -52,7 +59,7 @@ bool ECSignatureCreatorImpl::DecodeSignature(const std::vector<uint8>& der_sig, OpenSSLErrStackTracer err_tracer(FROM_HERE); // Create ECDSA_SIG object from DER-encoded data. const unsigned char* der_data = &der_sig.front(); - ScopedOpenSSL<ECDSA_SIG, ECDSA_SIG_free> ecdsa_sig( + ScopedECDSA_SIG ecdsa_sig( d2i_ECDSA_SIG(NULL, &der_data, static_cast<long>(der_sig.size()))); if (!ecdsa_sig.get()) return false; diff --git a/crypto/openssl_bio_string_unittest.cc b/crypto/openssl_bio_string_unittest.cc index 39d3a9a..2467215 100644 --- a/crypto/openssl_bio_string_unittest.cc +++ b/crypto/openssl_bio_string_unittest.cc @@ -6,16 +6,18 @@ #include <openssl/bio.h> -#include "crypto/openssl_util.h" +#include "crypto/scoped_openssl_types.h" #include "testing/gtest/include/gtest/gtest.h" +namespace crypto { + TEST(OpenSSLBIOString, TestWrite) { std::string s; const std::string expected1("a one\nb 2\n"); const std::string expected2("c d e f"); const std::string expected3("g h i"); { - crypto::ScopedOpenSSL<BIO, BIO_free_all> bio(crypto::BIO_new_string(&s)); + ScopedBIO bio(BIO_new_string(&s)); ASSERT_TRUE(bio.get()); EXPECT_EQ(static_cast<int>(expected1.size()), @@ -48,7 +50,7 @@ TEST(OpenSSLBIOString, TestReset) { const std::string expected1("a b c\n"); const std::string expected2("d e f g\n"); { - crypto::ScopedOpenSSL<BIO, BIO_free_all> bio(crypto::BIO_new_string(&s)); + ScopedBIO bio(BIO_new_string(&s)); ASSERT_TRUE(bio.get()); EXPECT_EQ(static_cast<int>(expected1.size()), @@ -64,3 +66,5 @@ TEST(OpenSSLBIOString, TestReset) { } EXPECT_EQ(expected2, s); } + +} // namespace crypto diff --git a/crypto/openssl_util.h b/crypto/openssl_util.h index bf83e47..2743883 100644 --- a/crypto/openssl_util.h +++ b/crypto/openssl_util.h @@ -11,36 +11,6 @@ namespace crypto { -// A helper class that takes care of destroying OpenSSL objects when they go out -// of scope. -template <typename T, void (*destructor)(T*)> -class ScopedOpenSSL { - public: - ScopedOpenSSL() : ptr_(NULL) { } - explicit ScopedOpenSSL(T* ptr) : ptr_(ptr) { } - ~ScopedOpenSSL() { - reset(NULL); - } - - T* get() const { return ptr_; } - T* release() { - T* ptr = ptr_; - ptr_ = NULL; - return ptr; - } - void reset(T* ptr) { - if (ptr != ptr_) { - if (ptr_) (*destructor)(ptr_); - ptr_ = ptr; - } - } - - private: - T* ptr_; - - DISALLOW_COPY_AND_ASSIGN(ScopedOpenSSL); -}; - // Provides a buffer of at least MIN_SIZE bytes, for use when calling OpenSSL's // SHA256, HMAC, etc functions, adapting the buffer sizing rules to meet those // of the our base wrapper APIs. diff --git a/crypto/rsa_private_key_openssl.cc b/crypto/rsa_private_key_openssl.cc index f191e39..bd00a73 100644 --- a/crypto/rsa_private_key_openssl.cc +++ b/crypto/rsa_private_key_openssl.cc @@ -11,6 +11,7 @@ #include "base/logging.h" #include "base/memory/scoped_ptr.h" #include "crypto/openssl_util.h" +#include "crypto/scoped_openssl_types.h" namespace crypto { @@ -29,7 +30,7 @@ bool ExportKey(EVP_PKEY* key, return false; OpenSSLErrStackTracer err_tracer(FROM_HERE); - ScopedOpenSSL<BIO, BIO_free_all> bio(BIO_new(BIO_s_mem())); + ScopedBIO bio(BIO_new(BIO_s_mem())); int res = export_fn(bio.get(), key); if (!res) @@ -50,8 +51,8 @@ bool ExportKey(EVP_PKEY* key, RSAPrivateKey* RSAPrivateKey::Create(uint16 num_bits) { OpenSSLErrStackTracer err_tracer(FROM_HERE); - ScopedOpenSSL<RSA, RSA_free> rsa_key(RSA_new()); - ScopedOpenSSL<BIGNUM, BN_free> bn(BN_new()); + ScopedRSA rsa_key(RSA_new()); + ScopedBIGNUM bn(BN_new()); if (!rsa_key.get() || !bn.get() || !BN_set_word(bn.get(), 65537L)) return NULL; @@ -75,14 +76,14 @@ RSAPrivateKey* RSAPrivateKey::CreateFromPrivateKeyInfo( OpenSSLErrStackTracer err_tracer(FROM_HERE); // BIO_new_mem_buf is not const aware, but it does not modify the buffer. char* data = reinterpret_cast<char*>(const_cast<uint8*>(&input[0])); - ScopedOpenSSL<BIO, BIO_free_all> bio(BIO_new_mem_buf(data, input.size())); + ScopedBIO 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( + ScopedOpenSSL<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_free>::Type p8inf( d2i_PKCS8_PRIV_KEY_INFO_bio(bio.get(), NULL)); if (!p8inf.get()) return NULL; diff --git a/crypto/scoped_openssl_types.h b/crypto/scoped_openssl_types.h new file mode 100644 index 0000000..a949233 --- /dev/null +++ b/crypto/scoped_openssl_types.h @@ -0,0 +1,49 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CRYPTO_SCOPED_OPENSSL_TYPES_H_ +#define CRYPTO_SCOPED_OPENSSL_TYPES_H_ + +#include <openssl/bn.h> +#include <openssl/dsa.h> +#include <openssl/ec.h> +#include <openssl/ecdsa.h> +#include <openssl/evp.h> +#include <openssl/rsa.h> + +#include "base/memory/scoped_ptr.h" + +namespace crypto { + +// Simplistic helper that wraps a call to a deleter function. In a C++11 world, +// this would be std::function<>. An alternative would be to re-use +// base::internal::RunnableAdapter<>, but that's far too heavy weight. +template <typename Type, void (*Destroyer)(Type*)> +struct OpenSSLDestroyer { + void operator()(Type* ptr) const { Destroyer(ptr); } +}; + +template <typename PointerType, void (*Destroyer)(PointerType*)> +struct ScopedOpenSSL { + typedef scoped_ptr<PointerType, OpenSSLDestroyer<PointerType, Destroyer> > + Type; +}; + +// Several typedefs are provided for crypto-specific primitives, for +// short-hand and prevalence. Note that OpenSSL types related to X.509 are +// intentionally not included, as crypto/ does not generally deal with +// certificates or PKI. +typedef ScopedOpenSSL<BIGNUM, BN_free>::Type ScopedBIGNUM; +typedef ScopedOpenSSL<EC_KEY, EC_KEY_free>::Type ScopedEC_KEY; +typedef ScopedOpenSSL<BIO, BIO_free_all>::Type ScopedBIO; +typedef ScopedOpenSSL<DSA, DSA_free>::Type ScopedDSA; +typedef ScopedOpenSSL<ECDSA_SIG, ECDSA_SIG_free>::Type ScopedECDSA_SIG; +typedef ScopedOpenSSL<EC_KEY, EC_KEY_free>::Type ScopedEC_KEY; +typedef ScopedOpenSSL<EVP_MD_CTX, EVP_MD_CTX_destroy>::Type ScopedEVP_MD_CTX; +typedef ScopedOpenSSL<EVP_PKEY, EVP_PKEY_free>::Type ScopedEVP_PKEY; +typedef ScopedOpenSSL<RSA, RSA_free>::Type ScopedRSA; + +} // namespace crypto + +#endif // CRYPTO_SCOPED_OPENSSL_TYPES_H_ diff --git a/crypto/signature_verifier_openssl.cc b/crypto/signature_verifier_openssl.cc index a85f00b..155a2cf3 100644 --- a/crypto/signature_verifier_openssl.cc +++ b/crypto/signature_verifier_openssl.cc @@ -13,6 +13,7 @@ #include "base/memory/scoped_ptr.h" #include "base/stl_util.h" #include "crypto/openssl_util.h" +#include "crypto/scoped_openssl_types.h" namespace crypto { @@ -31,7 +32,7 @@ const EVP_MD* ToOpenSSLDigest(SignatureVerifier::HashAlgorithm hash_alg) { } // namespace struct SignatureVerifier::VerifyContext { - ScopedOpenSSL<EVP_MD_CTX, EVP_MD_CTX_destroy> ctx; + ScopedEVP_MD_CTX ctx; }; SignatureVerifier::SignatureVerifier() @@ -49,7 +50,7 @@ bool SignatureVerifier::VerifyInit(const uint8* signature_algorithm, const uint8* public_key_info, int public_key_info_len) { OpenSSLErrStackTracer err_tracer(FROM_HERE); - ScopedOpenSSL<X509_ALGOR, X509_ALGOR_free> algorithm( + ScopedOpenSSL<X509_ALGOR, X509_ALGOR_free>::Type algorithm( d2i_X509_ALGOR(NULL, &signature_algorithm, signature_algorithm_len)); if (!algorithm.get()) return false; @@ -135,13 +136,11 @@ bool SignatureVerifier::CommonInit(const EVP_MD* digest, // BIO_new_mem_buf is not const aware, but it does not modify the buffer. char* data = reinterpret_cast<char*>(const_cast<uint8*>(public_key_info)); - ScopedOpenSSL<BIO, BIO_free_all> bio(BIO_new_mem_buf(data, - public_key_info_len)); + ScopedBIO bio(BIO_new_mem_buf(data, public_key_info_len)); if (!bio.get()) return false; - ScopedOpenSSL<EVP_PKEY, EVP_PKEY_free> public_key( - d2i_PUBKEY_bio(bio.get(), NULL)); + ScopedEVP_PKEY public_key(d2i_PUBKEY_bio(bio.get(), NULL)); if (!public_key.get()) return false; |