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,