Give SSL_HANDSHAKE a constructor and destructor.

SSL_HANDSHAKE is large so I have not attempted to fully switch it to
scopers in this CL. This is just a preparatory step so that we can start
switching its fields to scopers.

(I also anticipate we'll want a bssl::Array<uint8_t> to replace the
pointer/length pairs.)

Bug: 132
Change-Id: I1538d3fc7f9c7385cd8c44a7b99b5c76e8a8768c
Reviewed-on: https://boringssl-review.googlesource.com/18244
Commit-Queue: David Benjamin <davidben@google.com>
Commit-Queue: Steven Valdez <svaldez@google.com>
Reviewed-by: Steven Valdez <svaldez@google.com>
diff --git a/ssl/internal.h b/ssl/internal.h
index fe3d9fd..74f20f3 100644
--- a/ssl/internal.h
+++ b/ssl/internal.h
@@ -1077,6 +1077,9 @@
 };
 
 struct SSL_HANDSHAKE {
+  explicit SSL_HANDSHAKE(SSL *ssl);
+  ~SSL_HANDSHAKE();
+
   /* ssl is a non-owning pointer to the parent |SSL| object. */
   SSL *ssl;
 
@@ -1087,45 +1090,45 @@
 
   /* wait contains the operation |do_tls13_handshake| is currently blocking on
    * or |ssl_hs_ok| if none. */
-  enum ssl_hs_wait_t wait;
+  enum ssl_hs_wait_t wait = ssl_hs_ok;
 
   /* state contains one of the SSL3_ST_* values. */
-  int state;
+  int state = SSL_ST_INIT;
 
   /* next_state is used when SSL_ST_FLUSH_DATA is entered */
-  int next_state;
+  int next_state = 0;
 
   /* tls13_state is the internal state for the TLS 1.3 handshake. Its values
    * depend on |do_tls13_handshake| but the starting state is always zero. */
-  int tls13_state;
+  int tls13_state = 0;
 
   /* min_version is the minimum accepted protocol version, taking account both
    * |SSL_OP_NO_*| and |SSL_CTX_set_min_proto_version| APIs. */
-  uint16_t min_version;
+  uint16_t min_version = 0;
 
   /* max_version is the maximum accepted protocol version, taking account both
    * |SSL_OP_NO_*| and |SSL_CTX_set_max_proto_version| APIs. */
-  uint16_t max_version;
+  uint16_t max_version = 0;
 
   /* session_id is the session ID in the ClientHello, used for the experimental
    * TLS 1.3 variant. */
-  uint8_t session_id[SSL_MAX_SSL_SESSION_ID_LENGTH];
-  uint8_t session_id_len;
+  uint8_t session_id[SSL_MAX_SSL_SESSION_ID_LENGTH] = {0};
+  uint8_t session_id_len = 0;
 
-  size_t hash_len;
-  uint8_t secret[EVP_MAX_MD_SIZE];
-  uint8_t early_traffic_secret[EVP_MAX_MD_SIZE];
-  uint8_t client_handshake_secret[EVP_MAX_MD_SIZE];
-  uint8_t server_handshake_secret[EVP_MAX_MD_SIZE];
-  uint8_t client_traffic_secret_0[EVP_MAX_MD_SIZE];
-  uint8_t server_traffic_secret_0[EVP_MAX_MD_SIZE];
-  uint8_t expected_client_finished[EVP_MAX_MD_SIZE];
+  size_t hash_len = 0;
+  uint8_t secret[EVP_MAX_MD_SIZE] = {0};
+  uint8_t early_traffic_secret[EVP_MAX_MD_SIZE] = {0};
+  uint8_t client_handshake_secret[EVP_MAX_MD_SIZE] = {0};
+  uint8_t server_handshake_secret[EVP_MAX_MD_SIZE] = {0};
+  uint8_t client_traffic_secret_0[EVP_MAX_MD_SIZE] = {0};
+  uint8_t server_traffic_secret_0[EVP_MAX_MD_SIZE] = {0};
+  uint8_t expected_client_finished[EVP_MAX_MD_SIZE] = {0};
 
   union {
     /* sent is a bitset where the bits correspond to elements of kExtensions
      * in t1_lib.c. Each bit is set if that extension was sent in a
      * ClientHello. It's not used by servers. */
-    uint32_t sent;
+    uint32_t sent = 0;
     /* received is a bitset, like |sent|, but is used by servers to record
      * which extensions were received from a client. */
     uint32_t received;
@@ -1135,7 +1138,7 @@
     /* sent is a bitset where the bits correspond to elements of
      * |client_custom_extensions| in the |SSL_CTX|. Each bit is set if that
      * extension was sent in a ClientHello. It's not used by servers. */
-    uint16_t sent;
+    uint16_t sent = 0;
     /* received is a bitset, like |sent|, but is used by servers to record
      * which custom extensions were received from a client. The bits here
      * correspond to |server_custom_extensions|. */
@@ -1144,7 +1147,7 @@
 
   /* retry_group is the group ID selected by the server in HelloRetryRequest in
    * TLS 1.3. */
-  uint16_t retry_group;
+  uint16_t retry_group = 0;
 
   /* ecdh_ctx is the current ECDH instance. */
   SSL_ECDH_CTX ecdh_ctx;
@@ -1153,82 +1156,82 @@
   SSL_TRANSCRIPT transcript;
 
   /* cookie is the value of the cookie received from the server, if any. */
-  uint8_t *cookie;
-  size_t cookie_len;
+  uint8_t *cookie = nullptr;
+  size_t cookie_len = 0;
 
   /* key_share_bytes is the value of the previously sent KeyShare extension by
    * the client in TLS 1.3. */
-  uint8_t *key_share_bytes;
-  size_t key_share_bytes_len;
+  uint8_t *key_share_bytes = nullptr;
+  size_t key_share_bytes_len = 0;
 
   /* ecdh_public_key, for servers, is the key share to be sent to the client in
    * TLS 1.3. */
-  uint8_t *ecdh_public_key;
-  size_t ecdh_public_key_len;
+  uint8_t *ecdh_public_key = nullptr;
+  size_t ecdh_public_key_len = 0;
 
   /* peer_sigalgs are the signature algorithms that the peer supports. These are
    * taken from the contents of the signature algorithms extension for a server
    * or from the CertificateRequest for a client. */
-  uint16_t *peer_sigalgs;
+  uint16_t *peer_sigalgs = nullptr;
   /* num_peer_sigalgs is the number of entries in |peer_sigalgs|. */
-  size_t num_peer_sigalgs;
+  size_t num_peer_sigalgs = 0;
 
   /* peer_supported_group_list contains the supported group IDs advertised by
    * the peer. This is only set on the server's end. The server does not
    * advertise this extension to the client. */
-  uint16_t *peer_supported_group_list;
-  size_t peer_supported_group_list_len;
+  uint16_t *peer_supported_group_list = nullptr;
+  size_t peer_supported_group_list_len = 0;
 
   /* peer_key is the peer's ECDH key for a TLS 1.2 client. */
-  uint8_t *peer_key;
-  size_t peer_key_len;
+  uint8_t *peer_key = nullptr;
+  size_t peer_key_len = 0;
 
   /* server_params, in a TLS 1.2 server, stores the ServerKeyExchange
    * parameters. It has client and server randoms prepended for signing
    * convenience. */
-  uint8_t *server_params;
-  size_t server_params_len;
+  uint8_t *server_params = nullptr;
+  size_t server_params_len = 0;
 
   /* peer_psk_identity_hint, on the client, is the psk_identity_hint sent by the
    * server when using a TLS 1.2 PSK key exchange. */
-  char *peer_psk_identity_hint;
+  char *peer_psk_identity_hint = nullptr;
 
   /* ca_names, on the client, contains the list of CAs received in a
    * CertificateRequest message. */
-  STACK_OF(CRYPTO_BUFFER) *ca_names;
+  STACK_OF(CRYPTO_BUFFER) *ca_names = nullptr;
 
   /* cached_x509_ca_names contains a cache of parsed versions of the elements
    * of |ca_names|. */
-  STACK_OF(X509_NAME) *cached_x509_ca_names;
+  STACK_OF(X509_NAME) *cached_x509_ca_names = nullptr;
 
   /* certificate_types, on the client, contains the set of certificate types
    * received in a CertificateRequest message. */
-  uint8_t *certificate_types;
-  size_t num_certificate_types;
+  uint8_t *certificate_types = nullptr;
+  size_t num_certificate_types = 0;
 
   /* hostname, on the server, is the value of the SNI extension. */
-  char *hostname;
+  char *hostname = nullptr;
 
   /* local_pubkey is the public key we are authenticating as. */
-  EVP_PKEY *local_pubkey;
+  EVP_PKEY *local_pubkey = nullptr;
 
   /* peer_pubkey is the public key parsed from the peer's leaf certificate. */
-  EVP_PKEY *peer_pubkey;
+  EVP_PKEY *peer_pubkey = nullptr;
 
   /* new_session is the new mutable session being established by the current
    * handshake. It should not be cached. */
-  SSL_SESSION *new_session;
+  SSL_SESSION *new_session = nullptr;
 
   /* early_session is the session corresponding to the current 0-RTT state on
    * the client if |in_early_data| is true. */
-  SSL_SESSION *early_session;
+  SSL_SESSION *early_session = nullptr;
 
   /* new_cipher is the cipher being negotiated in this handshake. */
-  const SSL_CIPHER *new_cipher;
+  const SSL_CIPHER *new_cipher = nullptr;
 
   /* key_block is the record-layer key block for TLS 1.2 and earlier. */
-  uint8_t *key_block;
-  uint8_t key_block_len;
+  uint8_t *key_block = nullptr;
+  uint8_t key_block_len = 0;
 
   /* scts_requested is one if the SCT extension is in the ClientHello. */
   unsigned scts_requested:1;
@@ -1294,15 +1297,15 @@
   unsigned pending_private_key_op:1;
 
   /* client_version is the value sent or received in the ClientHello version. */
-  uint16_t client_version;
+  uint16_t client_version = 0;
 
   /* early_data_read is the amount of early data that has been read by the
    * record layer. */
-  uint16_t early_data_read;
+  uint16_t early_data_read = 0;
 
   /* early_data_written is the amount of early data that has been written by the
    * record layer. */
-  uint16_t early_data_written;
+  uint16_t early_data_written = 0;
 };
 
 SSL_HANDSHAKE *ssl_handshake_new(SSL *ssl);
diff --git a/ssl/s3_both.cc b/ssl/s3_both.cc
index 63e6917..ae0022b 100644
--- a/ssl/s3_both.cc
+++ b/ssl/s3_both.cc
@@ -132,64 +132,72 @@
 
 namespace bssl {
 
+SSL_HANDSHAKE::SSL_HANDSHAKE(SSL *ssl_arg)
+    : ssl(ssl_arg),
+      scts_requested(0),
+      needs_psk_binder(0),
+      received_hello_retry_request(0),
+      accept_psk_mode(0),
+      cert_request(0),
+      certificate_status_expected(0),
+      ocsp_stapling_requested(0),
+      should_ack_sni(0),
+      in_false_start(0),
+      in_early_data(0),
+      early_data_offered(0),
+      can_early_read(0),
+      can_early_write(0),
+      next_proto_neg_seen(0),
+      ticket_expected(0),
+      extended_master_secret(0),
+      pending_private_key_op(0) {
+  OPENSSL_memset(&ecdh_ctx, 0, sizeof(ecdh_ctx));
+  OPENSSL_memset(&transcript, 0, sizeof(transcript));
+}
+
+SSL_HANDSHAKE::~SSL_HANDSHAKE() {
+  OPENSSL_cleanse(secret, sizeof(secret));
+  OPENSSL_cleanse(early_traffic_secret, sizeof(early_traffic_secret));
+  OPENSSL_cleanse(client_handshake_secret, sizeof(client_handshake_secret));
+  OPENSSL_cleanse(server_handshake_secret, sizeof(server_handshake_secret));
+  OPENSSL_cleanse(client_traffic_secret_0, sizeof(client_traffic_secret_0));
+  OPENSSL_cleanse(server_traffic_secret_0, sizeof(server_traffic_secret_0));
+  SSL_ECDH_CTX_cleanup(&ecdh_ctx);
+  SSL_TRANSCRIPT_cleanup(&transcript);
+  OPENSSL_free(cookie);
+  OPENSSL_free(key_share_bytes);
+  OPENSSL_free(ecdh_public_key);
+  SSL_SESSION_free(new_session);
+  SSL_SESSION_free(early_session);
+  OPENSSL_free(peer_sigalgs);
+  OPENSSL_free(peer_supported_group_list);
+  OPENSSL_free(peer_key);
+  OPENSSL_free(server_params);
+  OPENSSL_free(peer_psk_identity_hint);
+  sk_CRYPTO_BUFFER_pop_free(ca_names, CRYPTO_BUFFER_free);
+  ssl->ctx->x509_method->hs_flush_cached_ca_names(this);
+  OPENSSL_free(certificate_types);
+
+  if (key_block != NULL) {
+    OPENSSL_cleanse(key_block, key_block_len);
+    OPENSSL_free(key_block);
+  }
+
+  OPENSSL_free(hostname);
+  EVP_PKEY_free(peer_pubkey);
+  EVP_PKEY_free(local_pubkey);
+}
+
 SSL_HANDSHAKE *ssl_handshake_new(SSL *ssl) {
-  SSL_HANDSHAKE *hs = (SSL_HANDSHAKE *)OPENSSL_malloc(sizeof(SSL_HANDSHAKE));
-  if (hs == NULL) {
-    OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
-    return NULL;
+  UniquePtr<SSL_HANDSHAKE> hs = MakeUnique<SSL_HANDSHAKE>(ssl);
+  if (!hs ||
+      !SSL_TRANSCRIPT_init(&hs->transcript)) {
+    return nullptr;
   }
-  OPENSSL_memset(hs, 0, sizeof(SSL_HANDSHAKE));
-  hs->ssl = ssl;
-  hs->wait = ssl_hs_ok;
-  hs->state = SSL_ST_INIT;
-  if (!SSL_TRANSCRIPT_init(&hs->transcript)) {
-    ssl_handshake_free(hs);
-    return NULL;
-  }
-  return hs;
+  return hs.release();
 }
 
-void ssl_handshake_free(SSL_HANDSHAKE *hs) {
-  if (hs == NULL) {
-    return;
-  }
-
-  OPENSSL_cleanse(hs->secret, sizeof(hs->secret));
-  OPENSSL_cleanse(hs->early_traffic_secret, sizeof(hs->early_traffic_secret));
-  OPENSSL_cleanse(hs->client_handshake_secret,
-                  sizeof(hs->client_handshake_secret));
-  OPENSSL_cleanse(hs->server_handshake_secret,
-                  sizeof(hs->server_handshake_secret));
-  OPENSSL_cleanse(hs->client_traffic_secret_0,
-                  sizeof(hs->client_traffic_secret_0));
-  OPENSSL_cleanse(hs->server_traffic_secret_0,
-                  sizeof(hs->server_traffic_secret_0));
-  SSL_ECDH_CTX_cleanup(&hs->ecdh_ctx);
-  SSL_TRANSCRIPT_cleanup(&hs->transcript);
-  OPENSSL_free(hs->cookie);
-  OPENSSL_free(hs->key_share_bytes);
-  OPENSSL_free(hs->ecdh_public_key);
-  SSL_SESSION_free(hs->new_session);
-  SSL_SESSION_free(hs->early_session);
-  OPENSSL_free(hs->peer_sigalgs);
-  OPENSSL_free(hs->peer_supported_group_list);
-  OPENSSL_free(hs->peer_key);
-  OPENSSL_free(hs->server_params);
-  OPENSSL_free(hs->peer_psk_identity_hint);
-  sk_CRYPTO_BUFFER_pop_free(hs->ca_names, CRYPTO_BUFFER_free);
-  hs->ssl->ctx->x509_method->hs_flush_cached_ca_names(hs);
-  OPENSSL_free(hs->certificate_types);
-
-  if (hs->key_block != NULL) {
-    OPENSSL_cleanse(hs->key_block, hs->key_block_len);
-    OPENSSL_free(hs->key_block);
-  }
-
-  OPENSSL_free(hs->hostname);
-  EVP_PKEY_free(hs->peer_pubkey);
-  EVP_PKEY_free(hs->local_pubkey);
-  OPENSSL_free(hs);
-}
+void ssl_handshake_free(SSL_HANDSHAKE *hs) { Delete(hs); }
 
 int ssl_check_message_type(SSL *ssl, int type) {
   if (ssl->s3->tmp.message_type != type) {