More scopers.
Note the legacy client cert callback case fixes a leak.
Change-Id: I2772167bd03d308676d9e00885c751207002b31e
Reviewed-on: https://boringssl-review.googlesource.com/18824
Commit-Queue: Steven Valdez <svaldez@google.com>
Reviewed-by: Steven Valdez <svaldez@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c
index 2413a1c..b427df6 100644
--- a/crypto/x509/x509_vfy.c
+++ b/crypto/x509/x509_vfy.c
@@ -2254,10 +2254,15 @@
OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
return NULL;
}
- OPENSSL_memset(ctx, 0, sizeof(X509_STORE_CTX));
+ X509_STORE_CTX_zero(ctx);
return ctx;
}
+void X509_STORE_CTX_zero(X509_STORE_CTX *ctx)
+{
+ OPENSSL_memset(ctx, 0, sizeof(X509_STORE_CTX));
+}
+
void X509_STORE_CTX_free(X509_STORE_CTX *ctx)
{
if (ctx == NULL) {
@@ -2272,7 +2277,7 @@
{
int ret = 1;
- OPENSSL_memset(ctx, 0, sizeof(X509_STORE_CTX));
+ X509_STORE_CTX_zero(ctx);
ctx->ctx = store;
ctx->cert = x509;
ctx->untrusted = chain;
diff --git a/include/openssl/base.h b/include/openssl/base.h
index e575069..6b43c76 100644
--- a/include/openssl/base.h
+++ b/include/openssl/base.h
@@ -413,6 +413,9 @@
T *get() { return &ctx_; }
const T *get() const { return &ctx_; }
+ T *operator->() { return &ctx_; }
+ const T *operator->() const { return &ctx_; }
+
void Reset() {
cleanup(&ctx_);
init(&ctx_);
diff --git a/include/openssl/x509.h b/include/openssl/x509.h
index 40b2332..138c060 100644
--- a/include/openssl/x509.h
+++ b/include/openssl/x509.h
@@ -1094,7 +1094,9 @@
#ifdef __cplusplus
}
+#endif
+#if !defined(BORINGSSL_NO_CXX)
extern "C++" {
namespace bssl {
@@ -1118,11 +1120,14 @@
BORINGSSL_MAKE_DELETER(X509_STORE_CTX, X509_STORE_CTX_free)
BORINGSSL_MAKE_DELETER(X509_VERIFY_PARAM, X509_VERIFY_PARAM_free)
+using ScopedX509_STORE_CTX =
+ internal::StackAllocated<X509_STORE_CTX, void, X509_STORE_CTX_zero,
+ X509_STORE_CTX_cleanup>;
+
} // namespace bssl
} /* extern C++ */
-
-#endif
+#endif /* !BORINGSSL_NO_CXX */
#define X509_R_AKID_MISMATCH 100
#define X509_R_BAD_PKCS7_VERSION 101
diff --git a/include/openssl/x509_vfy.h b/include/openssl/x509_vfy.h
index ac739ea..4abd9cd 100644
--- a/include/openssl/x509_vfy.h
+++ b/include/openssl/x509_vfy.h
@@ -449,6 +449,7 @@
OPENSSL_EXPORT int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x);
+OPENSSL_EXPORT void X509_STORE_CTX_zero(X509_STORE_CTX *ctx);
OPENSSL_EXPORT void X509_STORE_CTX_free(X509_STORE_CTX *ctx);
OPENSSL_EXPORT int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store,
X509 *x509, STACK_OF(X509) *chain);
diff --git a/ssl/ssl_privkey.cc b/ssl/ssl_privkey.cc
index 3e3fa94..ecdf48f 100644
--- a/ssl/ssl_privkey.cc
+++ b/ssl/ssl_privkey.cc
@@ -320,27 +320,19 @@
using namespace bssl;
int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa) {
- EVP_PKEY *pkey;
- int ret;
-
if (rsa == NULL) {
OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
- pkey = EVP_PKEY_new();
- if (pkey == NULL) {
+ UniquePtr<EVP_PKEY> pkey(EVP_PKEY_new());
+ if (!pkey ||
+ !EVP_PKEY_set1_RSA(pkey.get(), rsa)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_EVP_LIB);
return 0;
}
- RSA_up_ref(rsa);
- EVP_PKEY_assign_RSA(pkey, rsa);
-
- ret = ssl_set_pkey(ssl->cert, pkey);
- EVP_PKEY_free(pkey);
-
- return ret;
+ return ssl_set_pkey(ssl->cert, pkey.get());
}
int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, const uint8_t *der, size_t der_len) {
@@ -370,52 +362,40 @@
}
const uint8_t *p = der;
- EVP_PKEY *pkey = d2i_PrivateKey(type, NULL, &p, (long)der_len);
- if (pkey == NULL || p != der + der_len) {
+ UniquePtr<EVP_PKEY> pkey(d2i_PrivateKey(type, NULL, &p, (long)der_len));
+ if (!pkey || p != der + der_len) {
OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB);
- EVP_PKEY_free(pkey);
return 0;
}
- int ret = SSL_use_PrivateKey(ssl, pkey);
- EVP_PKEY_free(pkey);
- return ret;
+ return SSL_use_PrivateKey(ssl, pkey.get());
}
int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa) {
- int ret;
- EVP_PKEY *pkey;
-
if (rsa == NULL) {
OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
- pkey = EVP_PKEY_new();
- if (pkey == NULL) {
+ UniquePtr<EVP_PKEY> pkey(EVP_PKEY_new());
+ if (!pkey ||
+ !EVP_PKEY_set1_RSA(pkey.get(), rsa)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_EVP_LIB);
return 0;
}
- RSA_up_ref(rsa);
- EVP_PKEY_assign_RSA(pkey, rsa);
-
- ret = ssl_set_pkey(ctx->cert, pkey);
- EVP_PKEY_free(pkey);
- return ret;
+ return ssl_set_pkey(ctx->cert, pkey.get());
}
int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const uint8_t *der,
size_t der_len) {
- RSA *rsa = RSA_private_key_from_bytes(der, der_len);
- if (rsa == NULL) {
+ UniquePtr<RSA> rsa(RSA_private_key_from_bytes(der, der_len));
+ if (!rsa) {
OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB);
return 0;
}
- int ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa);
- RSA_free(rsa);
- return ret;
+ return SSL_CTX_use_RSAPrivateKey(ctx, rsa.get());
}
int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey) {
@@ -435,16 +415,13 @@
}
const uint8_t *p = der;
- EVP_PKEY *pkey = d2i_PrivateKey(type, NULL, &p, (long)der_len);
- if (pkey == NULL || p != der + der_len) {
+ UniquePtr<EVP_PKEY> pkey(d2i_PrivateKey(type, NULL, &p, (long)der_len));
+ if (!pkey || p != der + der_len) {
OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB);
- EVP_PKEY_free(pkey);
return 0;
}
- int ret = SSL_CTX_use_PrivateKey(ctx, pkey);
- EVP_PKEY_free(pkey);
- return ret;
+ return SSL_CTX_use_PrivateKey(ctx, pkey.get());
}
void SSL_set_private_key_method(SSL *ssl,
diff --git a/ssl/ssl_x509.cc b/ssl/ssl_x509.cc
index 22f4fb4..98a5b8c 100644
--- a/ssl/ssl_x509.cc
+++ b/ssl/ssl_x509.cc
@@ -429,50 +429,47 @@
}
X509 *leaf = sk_X509_value(cert_chain, 0);
- int ret = 0;
- X509_STORE_CTX ctx;
- if (!X509_STORE_CTX_init(&ctx, verify_store, leaf, cert_chain)) {
+ ScopedX509_STORE_CTX ctx;
+ if (!X509_STORE_CTX_init(ctx.get(), verify_store, leaf, cert_chain)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_X509_LIB);
return 0;
}
- if (!X509_STORE_CTX_set_ex_data(&ctx, SSL_get_ex_data_X509_STORE_CTX_idx(),
- ssl)) {
- goto err;
+ if (!X509_STORE_CTX_set_ex_data(ctx.get(),
+ SSL_get_ex_data_X509_STORE_CTX_idx(), ssl)) {
+ return 0;
}
/* We need to inherit the verify parameters. These can be determined by the
* context: if its a server it will verify SSL client certificates or vice
* versa. */
- X509_STORE_CTX_set_default(&ctx, ssl->server ? "ssl_client" : "ssl_server");
+ X509_STORE_CTX_set_default(ctx.get(),
+ ssl->server ? "ssl_client" : "ssl_server");
/* Anything non-default in "param" should overwrite anything in the ctx. */
- X509_VERIFY_PARAM_set1(X509_STORE_CTX_get0_param(&ctx), ssl->param);
+ X509_VERIFY_PARAM_set1(X509_STORE_CTX_get0_param(ctx.get()), ssl->param);
if (ssl->verify_callback) {
- X509_STORE_CTX_set_verify_cb(&ctx, ssl->verify_callback);
+ X509_STORE_CTX_set_verify_cb(ctx.get(), ssl->verify_callback);
}
int verify_ret;
if (ssl->ctx->app_verify_callback != NULL) {
- verify_ret = ssl->ctx->app_verify_callback(&ctx, ssl->ctx->app_verify_arg);
+ verify_ret =
+ ssl->ctx->app_verify_callback(ctx.get(), ssl->ctx->app_verify_arg);
} else {
- verify_ret = X509_verify_cert(&ctx);
+ verify_ret = X509_verify_cert(ctx.get());
}
- session->verify_result = ctx.error;
+ session->verify_result = ctx->error;
/* If |SSL_VERIFY_NONE|, the error is non-fatal, but we keep the result. */
if (verify_ret <= 0 && ssl->verify_mode != SSL_VERIFY_NONE) {
- *out_alert = ssl_verify_alarm_type(ctx.error);
- goto err;
+ *out_alert = ssl_verify_alarm_type(ctx->error);
+ return 0;
}
ERR_clear_error();
- ret = 1;
-
-err:
- X509_STORE_CTX_cleanup(&ctx);
- return ret;
+ return 1;
}
static void ssl_crypto_x509_hs_flush_cached_ca_names(SSL_HANDSHAKE *hs) {
@@ -509,31 +506,27 @@
return 1;
}
- X509 *leaf =
- X509_parse_from_buffer(sk_CRYPTO_BUFFER_value(ssl->cert->chain, 0));
+ UniquePtr<X509> leaf(
+ X509_parse_from_buffer(sk_CRYPTO_BUFFER_value(ssl->cert->chain, 0)));
if (!leaf) {
OPENSSL_PUT_ERROR(SSL, ERR_R_X509_LIB);
return 0;
}
- X509_STORE_CTX ctx;
- if (!X509_STORE_CTX_init(&ctx, ssl->ctx->cert_store, leaf, NULL)) {
- X509_free(leaf);
+ ScopedX509_STORE_CTX ctx;
+ if (!X509_STORE_CTX_init(ctx.get(), ssl->ctx->cert_store, leaf.get(), NULL)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_X509_LIB);
return 0;
}
/* Attempt to build a chain, ignoring the result. */
- X509_verify_cert(&ctx);
- X509_free(leaf);
+ X509_verify_cert(ctx.get());
ERR_clear_error();
/* Remove the leaf from the generated chain. */
- X509_free(sk_X509_shift(ctx.chain));
+ X509_free(sk_X509_shift(ctx->chain));
- const int ok = ssl_cert_set_chain(ssl->cert, ctx.chain);
- X509_STORE_CTX_cleanup(&ctx);
- if (!ok) {
+ if (!ssl_cert_set_chain(ssl->cert, ctx->chain)) {
return 0;
}
@@ -1248,6 +1241,8 @@
if (ret < 0) {
return -1;
}
+ UniquePtr<X509> free_x509(x509);
+ UniquePtr<EVP_PKEY> free_pkey(pkey);
if (ret != 0) {
if (!SSL_use_certificate(ssl, x509) ||
@@ -1256,8 +1251,6 @@
}
}
- X509_free(x509);
- EVP_PKEY_free(pkey);
return 1;
}