summaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
Diffstat (limited to 'crypto')
-rw-r--r--crypto/ec_private_key_openssl.cc46
-rw-r--r--crypto/ec_signature_creator_openssl.cc11
-rw-r--r--crypto/openssl_bio_string_unittest.cc10
-rw-r--r--crypto/openssl_util.h30
-rw-r--r--crypto/rsa_private_key_openssl.cc11
-rw-r--r--crypto/scoped_openssl_types.h49
-rw-r--r--crypto/signature_verifier_openssl.cc11
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;