Introduce bssl::Array<T> and use it in SSLKeyShare.

An Array<T> is an owning Span<T>. It's similar to absl::FixedArray<T>
but plays well with OPENSSL_malloc and doesn't implement inlining. With
OPENSSL_cleanse folded into OPENSSL_free, we could go nuts with
UniquePtr<uint8_t>, but having the pointer and length tied together is
nice for other reasons. Notably, Array<T> plays great with Span<T>.

Also switch the other parameter to a Span.

Bug: 132
Change-Id: I4cdcf810cf2838208c8ba9fcc6215c1e369dffb8
Reviewed-on: https://boringssl-review.googlesource.com/20667
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
diff --git a/ssl/handshake_client.cc b/ssl/handshake_client.cc
index 3916692..62e15e2 100644
--- a/ssl/handshake_client.cc
+++ b/ssl/handshake_client.cc
@@ -976,10 +976,13 @@
 
     // Initialize ECDH and save the peer public key for later.
     hs->key_share = SSLKeyShare::Create(group_id);
+    uint8_t *peer_key = nullptr;
+    size_t peer_key_len = 0;
     if (!hs->key_share ||
-        !CBS_stow(&point, &hs->peer_key, &hs->peer_key_len)) {
+        !CBS_stow(&point, &peer_key, &peer_key_len)) {
       return ssl_hs_error;
     }
+    hs->peer_key.Reset(peer_key, peer_key_len);
   } else if (!(alg_k & SSL_kPSK)) {
     OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE);
     ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
@@ -1229,8 +1232,7 @@
     return ssl_hs_error;
   }
 
-  uint8_t *pms = NULL;
-  size_t pms_len = 0;
+  Array<uint8_t> pms;
   uint32_t alg_k = hs->new_cipher->algorithm_mkey;
   uint32_t alg_a = hs->new_cipher->algorithm_auth;
 
@@ -1240,7 +1242,7 @@
   if (alg_a & SSL_aPSK) {
     if (ssl->psk_client_callback == NULL) {
       OPENSSL_PUT_ERROR(SSL, SSL_R_PSK_NO_CLIENT_CB);
-      goto err;
+      return ssl_hs_error;
     }
 
     char identity[PSK_MAX_IDENTITY_LEN + 1];
@@ -1251,7 +1253,7 @@
     if (psk_len == 0) {
       OPENSSL_PUT_ERROR(SSL, SSL_R_PSK_IDENTITY_NOT_FOUND);
       ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
-      goto err;
+      return ssl_hs_error;
     }
     assert(psk_len <= PSK_MAX_PSK_LEN);
 
@@ -1259,7 +1261,7 @@
     hs->new_session->psk_identity = BUF_strdup(identity);
     if (hs->new_session->psk_identity == NULL) {
       OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
-      goto err;
+      return ssl_hs_error;
     }
 
     // Write out psk_identity.
@@ -1268,29 +1270,26 @@
         !CBB_add_bytes(&child, (const uint8_t *)identity,
                        OPENSSL_strnlen(identity, sizeof(identity))) ||
         !CBB_flush(&body)) {
-      goto err;
+      return ssl_hs_error;
     }
   }
 
-  // Depending on the key exchange method, compute |pms| and |pms_len|.
+  // Depending on the key exchange method, compute |pms|.
   if (alg_k & SSL_kRSA) {
-    pms_len = SSL_MAX_MASTER_KEY_LENGTH;
-    pms = (uint8_t *)OPENSSL_malloc(pms_len);
-    if (pms == NULL) {
-      OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
-      goto err;
+    if (!pms.Init(SSL_MAX_MASTER_KEY_LENGTH)) {
+      return ssl_hs_error;
     }
 
     RSA *rsa = EVP_PKEY_get0_RSA(hs->peer_pubkey.get());
     if (rsa == NULL) {
       OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
-      goto err;
+      return ssl_hs_error;
     }
 
     pms[0] = hs->client_version >> 8;
     pms[1] = hs->client_version & 0xff;
     if (!RAND_bytes(&pms[2], SSL_MAX_MASTER_KEY_LENGTH - 2)) {
-      goto err;
+      return ssl_hs_error;
     }
 
     CBB child, *enc_pms = &body;
@@ -1298,56 +1297,50 @@
     // In TLS, there is a length prefix.
     if (ssl->version > SSL3_VERSION) {
       if (!CBB_add_u16_length_prefixed(&body, &child)) {
-        goto err;
+        return ssl_hs_error;
       }
       enc_pms = &child;
     }
 
     uint8_t *ptr;
     if (!CBB_reserve(enc_pms, &ptr, RSA_size(rsa)) ||
-        !RSA_encrypt(rsa, &enc_pms_len, ptr, RSA_size(rsa), pms, pms_len,
-                     RSA_PKCS1_PADDING) ||
+        !RSA_encrypt(rsa, &enc_pms_len, ptr, RSA_size(rsa), pms.data(),
+                     pms.size(), RSA_PKCS1_PADDING) ||
         !CBB_did_write(enc_pms, enc_pms_len) ||
         !CBB_flush(&body)) {
-      goto err;
+      return ssl_hs_error;
     }
   } else if (alg_k & SSL_kECDHE) {
     // Generate a keypair and serialize the public half.
     CBB child;
     if (!CBB_add_u8_length_prefixed(&body, &child)) {
-      goto err;
+      return ssl_hs_error;
     }
 
     // Compute the premaster.
     uint8_t alert = SSL_AD_DECODE_ERROR;
-    if (!hs->key_share->Accept(&child, &pms, &pms_len, &alert, hs->peer_key,
-                              hs->peer_key_len)) {
+    if (!hs->key_share->Accept(&child, &pms, &alert, hs->peer_key)) {
       ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
-      goto err;
+      return ssl_hs_error;
     }
     if (!CBB_flush(&body)) {
-      goto err;
+      return ssl_hs_error;
     }
 
     // The key exchange state may now be discarded.
     hs->key_share.reset();
-    OPENSSL_free(hs->peer_key);
-    hs->peer_key = NULL;
-    hs->peer_key_len = 0;
+    hs->peer_key.Reset();
   } else if (alg_k & SSL_kPSK) {
     // For plain PSK, other_secret is a block of 0s with the same length as
     // the pre-shared key.
-    pms_len = psk_len;
-    pms = (uint8_t *)OPENSSL_malloc(pms_len);
-    if (pms == NULL) {
-      OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
-      goto err;
+    if (!pms.Init(psk_len)) {
+      return ssl_hs_error;
     }
-    OPENSSL_memset(pms, 0, pms_len);
+    OPENSSL_memset(pms.data(), 0, pms.size());
   } else {
     ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
     OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
-    goto err;
+    return ssl_hs_error;
   }
 
   // For a PSK cipher suite, other_secret is combined with the pre-shared
@@ -1358,40 +1351,33 @@
     uint8_t *new_pms;
     size_t new_pms_len;
 
-    if (!CBB_init(pms_cbb.get(), 2 + psk_len + 2 + pms_len) ||
+    if (!CBB_init(pms_cbb.get(), 2 + psk_len + 2 + pms.size()) ||
         !CBB_add_u16_length_prefixed(pms_cbb.get(), &child) ||
-        !CBB_add_bytes(&child, pms, pms_len) ||
+        !CBB_add_bytes(&child, pms.data(), pms.size()) ||
         !CBB_add_u16_length_prefixed(pms_cbb.get(), &child) ||
         !CBB_add_bytes(&child, psk, psk_len) ||
         !CBB_finish(pms_cbb.get(), &new_pms, &new_pms_len)) {
       OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
-      goto err;
+      return ssl_hs_error;
     }
-    OPENSSL_free(pms);
-    pms = new_pms;
-    pms_len = new_pms_len;
+    pms.Reset(new_pms, new_pms_len);
   }
 
   // The message must be added to the finished hash before calculating the
   // master secret.
   if (!ssl_add_message_cbb(ssl, cbb.get())) {
-    goto err;
+    return ssl_hs_error;
   }
 
   hs->new_session->master_key_length = tls1_generate_master_secret(
-      hs, hs->new_session->master_key, pms, pms_len);
+      hs, hs->new_session->master_key, pms.data(), pms.size());
   if (hs->new_session->master_key_length == 0) {
-    goto err;
+    return ssl_hs_error;
   }
   hs->new_session->extended_master_secret = hs->extended_master_secret;
-  OPENSSL_free(pms);
 
   hs->state = state_send_client_certificate_verify;
   return ssl_hs_ok;
-
-err:
-  OPENSSL_free(pms);
-  return ssl_hs_error;
 }
 
 static enum ssl_hs_wait_t do_send_client_certificate_verify(SSL_HANDSHAKE *hs) {