Commit 24176aff authored by davidben@chromium.org's avatar davidben@chromium.org

Remove manual CRYPTO_add calls.

Use X509_chain_up_ref, EVP_PKEY_dup, and newly-added X509_up_ref
instead. Also RAII OpenSSLClientKeyStore.

BUG=none

Review URL: https://codereview.chromium.org/474663002

Cr-Commit-Position: refs/heads/master@{#289498}
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@289498 0039d316-1c4b-4281-b951-d872f2087c98
parent ac33c2f0
...@@ -36,7 +36,7 @@ class MemoryKeyPairStore { ...@@ -36,7 +36,7 @@ class MemoryKeyPairStore {
} }
bool StoreKeyPair(EVP_PKEY* pkey) { bool StoreKeyPair(EVP_PKEY* pkey) {
CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY); EVP_PKEY_dup(pkey);
base::AutoLock lock(lock_); base::AutoLock lock(lock_);
keys_.push_back(pkey); keys_.push_back(pkey);
return true; return true;
......
...@@ -241,13 +241,7 @@ void sk_X509_NAME_free_all(STACK_OF(X509_NAME)* sk) { ...@@ -241,13 +241,7 @@ void sk_X509_NAME_free_all(STACK_OF(X509_NAME)* sk) {
X509Certificate::OSCertHandle X509Certificate::DupOSCertHandle( X509Certificate::OSCertHandle X509Certificate::DupOSCertHandle(
OSCertHandle cert_handle) { OSCertHandle cert_handle) {
DCHECK(cert_handle); DCHECK(cert_handle);
// Using X509_dup causes the entire certificate to be reparsed. This return X509_up_ref(cert_handle);
// conversion, besides being non-trivial, drops any associated
// application-specific data set by X509_set_ex_data. Using CRYPTO_add
// just bumps up the ref-count for the cert, without causing any allocations
// or deallocations.
CRYPTO_add(&cert_handle->references, 1, CRYPTO_LOCK_X509);
return cert_handle;
} }
// static // static
......
...@@ -244,12 +244,8 @@ SSLClientSocketOpenSSL::PeerCertificateChain::operator=( ...@@ -244,12 +244,8 @@ SSLClientSocketOpenSSL::PeerCertificateChain::operator=(
// os_chain_ is reference counted by scoped_refptr; // os_chain_ is reference counted by scoped_refptr;
os_chain_ = other.os_chain_; os_chain_ = other.os_chain_;
// Must increase the reference count manually for sk_X509_dup openssl_chain_.reset(X509_chain_up_ref(other.openssl_chain_.get()));
openssl_chain_.reset(sk_X509_dup(other.openssl_chain_.get()));
for (size_t i = 0; i < sk_X509_num(openssl_chain_.get()); ++i) {
X509* x = sk_X509_value(openssl_chain_.get(), i);
CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
}
return *this; return *this;
} }
...@@ -271,15 +267,7 @@ void SSLClientSocketOpenSSL::PeerCertificateChain::Reset( ...@@ -271,15 +267,7 @@ void SSLClientSocketOpenSSL::PeerCertificateChain::Reset(
os_chain_ = os_chain_ =
X509Certificate::CreateFromHandle(sk_X509_value(chain, 0), intermediates); X509Certificate::CreateFromHandle(sk_X509_value(chain, 0), intermediates);
// sk_X509_dup does not increase reference count on the certs in the stack. openssl_chain_.reset(X509_chain_up_ref(chain));
openssl_chain_.reset(sk_X509_dup(chain));
std::vector<base::StringPiece> der_chain;
for (size_t i = 0; i < sk_X509_num(openssl_chain_.get()); ++i) {
X509* x = sk_X509_value(openssl_chain_.get(), i);
// Increase the reference count for the certs in openssl_chain_.
CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
}
} }
#else // !defined(USE_OPENSSL_CERTS) #else // !defined(USE_OPENSSL_CERTS)
void SSLClientSocketOpenSSL::PeerCertificateChain::Reset( void SSLClientSocketOpenSSL::PeerCertificateChain::Reset(
...@@ -290,16 +278,12 @@ void SSLClientSocketOpenSSL::PeerCertificateChain::Reset( ...@@ -290,16 +278,12 @@ void SSLClientSocketOpenSSL::PeerCertificateChain::Reset(
if (!chain) if (!chain)
return; return;
// sk_X509_dup does not increase reference count on the certs in the stack. openssl_chain_.reset(X509_chain_up_ref(chain));
openssl_chain_.reset(sk_X509_dup(chain));
std::vector<base::StringPiece> der_chain; std::vector<base::StringPiece> der_chain;
for (size_t i = 0; i < sk_X509_num(openssl_chain_.get()); ++i) { for (size_t i = 0; i < sk_X509_num(openssl_chain_.get()); ++i) {
X509* x = sk_X509_value(openssl_chain_.get(), i); X509* x = sk_X509_value(openssl_chain_.get(), i);
// Increase the reference count for the certs in openssl_chain_.
CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
unsigned char* cert_data = NULL; unsigned char* cert_data = NULL;
int cert_data_length = i2d_X509(x, &cert_data); int cert_data_length = i2d_X509(x, &cert_data);
if (cert_data_length && cert_data) if (cert_data_length && cert_data)
......
...@@ -15,17 +15,6 @@ namespace net { ...@@ -15,17 +15,6 @@ namespace net {
namespace { namespace {
// Increment the reference count of a given EVP_PKEY. This function
// is similar to EVP_PKEY_dup which is not available from the OpenSSL
// version used by Chromium at the moment. Its name is distinct to
// avoid compiler warnings about ambiguous function calls at caller
// sites.
EVP_PKEY* CopyEVP_PKEY(EVP_PKEY* key) {
if (key)
CRYPTO_add(&key->references, 1, CRYPTO_LOCK_EVP_PKEY);
return key;
}
// Return the EVP_PKEY holding the public key of a given certificate. // Return the EVP_PKEY holding the public key of a given certificate.
// |cert| is a certificate. // |cert| is a certificate.
// Returns a scoped EVP_PKEY for it. // Returns a scoped EVP_PKEY for it.
...@@ -48,35 +37,35 @@ OpenSSLClientKeyStore::~OpenSSLClientKeyStore() { ...@@ -48,35 +37,35 @@ OpenSSLClientKeyStore::~OpenSSLClientKeyStore() {
} }
OpenSSLClientKeyStore::KeyPair::KeyPair(EVP_PKEY* pub_key, OpenSSLClientKeyStore::KeyPair::KeyPair(EVP_PKEY* pub_key,
EVP_PKEY* priv_key) { EVP_PKEY* priv_key)
public_key = CopyEVP_PKEY(pub_key); : public_key(EVP_PKEY_dup(pub_key)),
private_key = CopyEVP_PKEY(priv_key); private_key(EVP_PKEY_dup(priv_key)) {
} }
OpenSSLClientKeyStore::KeyPair::~KeyPair() { OpenSSLClientKeyStore::KeyPair::~KeyPair() {
EVP_PKEY_free(public_key);
EVP_PKEY_free(private_key);
} }
OpenSSLClientKeyStore::KeyPair::KeyPair(const KeyPair& other) { OpenSSLClientKeyStore::KeyPair::KeyPair(const KeyPair& other)
public_key = CopyEVP_PKEY(other.public_key); : public_key(EVP_PKEY_dup(other.public_key.get())),
private_key = CopyEVP_PKEY(other.private_key); private_key(EVP_PKEY_dup(other.private_key.get())) {
} }
void OpenSSLClientKeyStore::KeyPair::operator=(const KeyPair& other) { void OpenSSLClientKeyStore::KeyPair::operator=(const KeyPair& other) {
EVP_PKEY* old_public_key = public_key; // Use a temporary ScopedEVP_PKEY because scoped_ptr does not allow resetting
EVP_PKEY* old_private_key = private_key; // to the current value, even though it's safe here.
public_key = CopyEVP_PKEY(other.public_key); crypto::ScopedEVP_PKEY public_key_tmp(EVP_PKEY_dup(other.public_key.get()));
private_key = CopyEVP_PKEY(other.private_key); crypto::ScopedEVP_PKEY private_key_tmp(EVP_PKEY_dup(other.private_key.get()));
EVP_PKEY_free(old_private_key); public_key.reset();
EVP_PKEY_free(old_public_key); public_key = public_key_tmp.Pass();
private_key.reset();
private_key = private_key_tmp.Pass();
} }
int OpenSSLClientKeyStore::FindKeyPairIndex(EVP_PKEY* public_key) { int OpenSSLClientKeyStore::FindKeyPairIndex(EVP_PKEY* public_key) {
if (!public_key) if (!public_key)
return -1; return -1;
for (size_t n = 0; n < pairs_.size(); ++n) { for (size_t n = 0; n < pairs_.size(); ++n) {
if (EVP_PKEY_cmp(pairs_[n].public_key, public_key) == 1) if (EVP_PKEY_cmp(pairs_[n].public_key.get(), public_key) == 1)
return static_cast<int>(n); return static_cast<int>(n);
} }
return -1; return -1;
...@@ -120,7 +109,7 @@ crypto::ScopedEVP_PKEY OpenSSLClientKeyStore::FetchClientCertPrivateKey( ...@@ -120,7 +109,7 @@ crypto::ScopedEVP_PKEY OpenSSLClientKeyStore::FetchClientCertPrivateKey(
if (index < 0) if (index < 0)
return crypto::ScopedEVP_PKEY(); return crypto::ScopedEVP_PKEY();
return crypto::ScopedEVP_PKEY(CopyEVP_PKEY(pairs_[index].private_key)); return crypto::ScopedEVP_PKEY(EVP_PKEY_dup(pairs_[index].private_key.get()));
} }
void OpenSSLClientKeyStore::Flush() { void OpenSSLClientKeyStore::Flush() {
......
...@@ -76,8 +76,8 @@ class NET_EXPORT OpenSSLClientKeyStore { ...@@ -76,8 +76,8 @@ class NET_EXPORT OpenSSLClientKeyStore {
void operator=(const KeyPair& other); void operator=(const KeyPair& other);
~KeyPair(); ~KeyPair();
EVP_PKEY* public_key; crypto::ScopedEVP_PKEY public_key;
EVP_PKEY* private_key; crypto::ScopedEVP_PKEY private_key;
private: private:
KeyPair(); // intentionally not implemented. KeyPair(); // intentionally not implemented.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment