Add a bunch of scopers.
I started by switching a couple fields to SSL_HANDSHAKE and then kept
following transitive bits.
Bug: 132
Change-Id: I640dadd3558615fa38c7e8498d4efe7449b0658f
Reviewed-on: https://boringssl-review.googlesource.com/18245
Reviewed-by: Steven Valdez <svaldez@google.com>
Commit-Queue: Steven Valdez <svaldez@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
diff --git a/ssl/ssl_cert.cc b/ssl/ssl_cert.cc
index caa4801..4f457f6 100644
--- a/ssl/ssl_cert.cc
+++ b/ssl/ssl_cert.cc
@@ -118,6 +118,8 @@
#include <limits.h>
#include <string.h>
+#include <utility>
+
#include <openssl/bn.h>
#include <openssl/buf.h>
#include <openssl/bytestring.h>
@@ -254,19 +256,17 @@
* |leaf_cert_and_privkey_ok|. */
static enum leaf_cert_and_privkey_result_t check_leaf_cert_and_privkey(
CRYPTO_BUFFER *leaf_buffer, EVP_PKEY *privkey) {
- enum leaf_cert_and_privkey_result_t ret = leaf_cert_and_privkey_error;
-
CBS cert_cbs;
CRYPTO_BUFFER_init_CBS(leaf_buffer, &cert_cbs);
- EVP_PKEY *pubkey = ssl_cert_parse_pubkey(&cert_cbs);
- if (pubkey == NULL) {
+ UniquePtr<EVP_PKEY> pubkey = ssl_cert_parse_pubkey(&cert_cbs);
+ if (!pubkey) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
- goto out;
+ return leaf_cert_and_privkey_error;
}
if (!ssl_is_key_type_supported(pubkey->type)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE);
- goto out;
+ return leaf_cert_and_privkey_error;
}
/* An ECC certificate may be usable for ECDH or ECDSA. We only support ECDSA
@@ -274,22 +274,17 @@
if (pubkey->type == EVP_PKEY_EC &&
!ssl_cert_check_digital_signature_key_usage(&cert_cbs)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE);
- goto out;
+ return leaf_cert_and_privkey_error;
}
if (privkey != NULL &&
/* Sanity-check that the private key and the certificate match. */
- !ssl_compare_public_and_private_key(pubkey, privkey)) {
+ !ssl_compare_public_and_private_key(pubkey.get(), privkey)) {
ERR_clear_error();
- ret = leaf_cert_and_privkey_mismatch;
- goto out;
+ return leaf_cert_and_privkey_mismatch;
}
- ret = leaf_cert_and_privkey_ok;
-
-out:
- EVP_PKEY_free(pubkey);
- return ret;
+ return leaf_cert_and_privkey_ok;
}
static int cert_set_chain_and_key(
@@ -387,25 +382,23 @@
ssl_has_private_key(ssl);
}
-STACK_OF(CRYPTO_BUFFER) *ssl_parse_cert_chain(uint8_t *out_alert,
- EVP_PKEY **out_pubkey,
- uint8_t *out_leaf_sha256,
- CBS *cbs,
- CRYPTO_BUFFER_POOL *pool) {
- *out_pubkey = NULL;
-
- STACK_OF(CRYPTO_BUFFER) *ret = sk_CRYPTO_BUFFER_new_null();
- if (ret == NULL) {
+UniquePtr<STACK_OF(CRYPTO_BUFFER)>
+ ssl_parse_cert_chain(uint8_t *out_alert, UniquePtr<EVP_PKEY> *out_pubkey,
+ uint8_t *out_leaf_sha256, CBS *cbs,
+ CRYPTO_BUFFER_POOL *pool) {
+ UniquePtr<EVP_PKEY> pubkey;
+ UniquePtr<STACK_OF(CRYPTO_BUFFER)> ret(sk_CRYPTO_BUFFER_new_null());
+ if (!ret) {
*out_alert = SSL_AD_INTERNAL_ERROR;
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
- return NULL;
+ return nullptr;
}
CBS certificate_list;
if (!CBS_get_u24_length_prefixed(cbs, &certificate_list)) {
*out_alert = SSL_AD_DECODE_ERROR;
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
- goto err;
+ return nullptr;
}
while (CBS_len(&certificate_list) > 0) {
@@ -414,14 +407,14 @@
CBS_len(&certificate) == 0) {
*out_alert = SSL_AD_DECODE_ERROR;
OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_LENGTH_MISMATCH);
- goto err;
+ return nullptr;
}
- if (sk_CRYPTO_BUFFER_num(ret) == 0) {
- *out_pubkey = ssl_cert_parse_pubkey(&certificate);
- if (*out_pubkey == NULL) {
+ if (sk_CRYPTO_BUFFER_num(ret.get()) == 0) {
+ pubkey = ssl_cert_parse_pubkey(&certificate);
+ if (!pubkey) {
*out_alert = SSL_AD_DECODE_ERROR;
- goto err;
+ return nullptr;
}
/* Retain the hash of the leaf certificate if requested. */
@@ -432,26 +425,17 @@
CRYPTO_BUFFER *buf =
CRYPTO_BUFFER_new_from_CBS(&certificate, pool);
- if (buf == NULL) {
- *out_alert = SSL_AD_DECODE_ERROR;
- goto err;
- }
-
- if (!sk_CRYPTO_BUFFER_push(ret, buf)) {
+ if (buf == NULL ||
+ !sk_CRYPTO_BUFFER_push(ret.get(), buf)) {
*out_alert = SSL_AD_INTERNAL_ERROR;
CRYPTO_BUFFER_free(buf);
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
- goto err;
+ return nullptr;
}
}
+ *out_pubkey = std::move(pubkey);
return ret;
-
-err:
- EVP_PKEY_free(*out_pubkey);
- *out_pubkey = NULL;
- sk_CRYPTO_BUFFER_pop_free(ret, CRYPTO_BUFFER_free);
- return NULL;
}
int ssl_add_cert_chain(SSL *ssl, CBB *cbb) {
@@ -526,14 +510,14 @@
return 1;
}
-EVP_PKEY *ssl_cert_parse_pubkey(const CBS *in) {
+UniquePtr<EVP_PKEY> ssl_cert_parse_pubkey(const CBS *in) {
CBS buf = *in, tbs_cert;
if (!ssl_cert_skip_to_spki(&buf, &tbs_cert)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_CANNOT_PARSE_LEAF_CERT);
- return NULL;
+ return nullptr;
}
- return EVP_parse_public_key(&tbs_cert);
+ return UniquePtr<EVP_PKEY>(EVP_parse_public_key(&tbs_cert));
}
int ssl_compare_public_and_private_key(const EVP_PKEY *pubkey,
@@ -581,15 +565,13 @@
CBS cert_cbs;
CRYPTO_BUFFER_init_CBS(sk_CRYPTO_BUFFER_value(cert->chain, 0), &cert_cbs);
- EVP_PKEY *pubkey = ssl_cert_parse_pubkey(&cert_cbs);
+ UniquePtr<EVP_PKEY> pubkey = ssl_cert_parse_pubkey(&cert_cbs);
if (!pubkey) {
OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_KEY_TYPE);
return 0;
}
- const int ok = ssl_compare_public_and_private_key(pubkey, privkey);
- EVP_PKEY_free(pubkey);
- return ok;
+ return ssl_compare_public_and_private_key(pubkey.get(), privkey);
}
int ssl_cert_check_digital_signature_key_usage(const CBS *in) {
@@ -669,22 +651,23 @@
return 0;
}
-STACK_OF(CRYPTO_BUFFER) *
- ssl_parse_client_CA_list(SSL *ssl, uint8_t *out_alert, CBS *cbs) {
+UniquePtr<STACK_OF(CRYPTO_BUFFER)> ssl_parse_client_CA_list(SSL *ssl,
+ uint8_t *out_alert,
+ CBS *cbs) {
CRYPTO_BUFFER_POOL *const pool = ssl->ctx->pool;
- STACK_OF(CRYPTO_BUFFER) *ret = sk_CRYPTO_BUFFER_new_null();
- if (ret == NULL) {
+ UniquePtr<STACK_OF(CRYPTO_BUFFER)> ret(sk_CRYPTO_BUFFER_new_null());
+ if (!ret) {
*out_alert = SSL_AD_INTERNAL_ERROR;
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
- return NULL;
+ return nullptr;
}
CBS child;
if (!CBS_get_u16_length_prefixed(cbs, &child)) {
*out_alert = SSL_AD_DECODE_ERROR;
OPENSSL_PUT_ERROR(SSL, SSL_R_LENGTH_MISMATCH);
- goto err;
+ return nullptr;
}
while (CBS_len(&child) > 0) {
@@ -692,31 +675,27 @@
if (!CBS_get_u16_length_prefixed(&child, &distinguished_name)) {
*out_alert = SSL_AD_DECODE_ERROR;
OPENSSL_PUT_ERROR(SSL, SSL_R_CA_DN_TOO_LONG);
- goto err;
+ return nullptr;
}
CRYPTO_BUFFER *buffer =
CRYPTO_BUFFER_new_from_CBS(&distinguished_name, pool);
if (buffer == NULL ||
- !sk_CRYPTO_BUFFER_push(ret, buffer)) {
+ !sk_CRYPTO_BUFFER_push(ret.get(), buffer)) {
CRYPTO_BUFFER_free(buffer);
*out_alert = SSL_AD_INTERNAL_ERROR;
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
- goto err;
+ return nullptr;
}
}
- if (!ssl->ctx->x509_method->check_client_CA_list(ret)) {
+ if (!ssl->ctx->x509_method->check_client_CA_list(ret.get())) {
*out_alert = SSL_AD_INTERNAL_ERROR;
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
- goto err;
+ return nullptr;
}
return ret;
-
-err:
- sk_CRYPTO_BUFFER_pop_free(ret, CRYPTO_BUFFER_free);
- return NULL;
}
int ssl_add_client_CA_list(SSL *ssl, CBB *cbb) {
@@ -801,7 +780,6 @@
CBS leaf;
CRYPTO_BUFFER_init_CBS(sk_CRYPTO_BUFFER_value(ssl->cert->chain, 0), &leaf);
- EVP_PKEY_free(hs->local_pubkey);
hs->local_pubkey = ssl_cert_parse_pubkey(&leaf);
return hs->local_pubkey != NULL;
}
@@ -869,7 +847,7 @@
if (ssl->s3->hs == NULL) {
return NULL;
}
- return ssl->s3->hs->ca_names;
+ return ssl->s3->hs->ca_names.get();
}
static int set_signed_cert_timestamp_list(CERT *cert, const uint8_t *list,