Pass explicit hs parameters to kExtensions callbacks.

This takes care of many of the explicit ssl->s3->hs accesses.

Change-Id: I380fae959f3a7021d6de9d19a4ca451b9a0aefe5
Reviewed-on: https://boringssl-review.googlesource.com/12317
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/t1_lib.c b/ssl/t1_lib.c
index 19c36d7..a908a99 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -127,8 +127,8 @@
 #include "../crypto/internal.h"
 
 
-static int ssl_check_clienthello_tlsext(SSL *ssl);
-static int ssl_check_serverhello_tlsext(SSL *ssl);
+static int ssl_check_clienthello_tlsext(SSL_HANDSHAKE *hs);
+static int ssl_check_serverhello_tlsext(SSL_HANDSHAKE *hs);
 
 static int compare_uint16_t(const void *p1, const void *p2) {
   uint16_t u1 = *((const uint16_t *)p1);
@@ -597,16 +597,19 @@
  * |*out_alert| isn't set, then a |decode_error| alert will be sent. */
 struct tls_extension {
   uint16_t value;
-  void (*init)(SSL *ssl);
+  void (*init)(SSL_HANDSHAKE *hs);
 
-  int (*add_clienthello)(SSL *ssl, CBB *out);
-  int (*parse_serverhello)(SSL *ssl, uint8_t *out_alert, CBS *contents);
+  int (*add_clienthello)(SSL_HANDSHAKE *hs, CBB *out);
+  int (*parse_serverhello)(SSL_HANDSHAKE *hs, uint8_t *out_alert,
+                           CBS *contents);
 
-  int (*parse_clienthello)(SSL *ssl, uint8_t *out_alert, CBS *contents);
-  int (*add_serverhello)(SSL *ssl, CBB *out);
+  int (*parse_clienthello)(SSL_HANDSHAKE *hs, uint8_t *out_alert,
+                           CBS *contents);
+  int (*add_serverhello)(SSL_HANDSHAKE *hs, CBB *out);
 };
 
-static int forbid_parse_serverhello(SSL *ssl, uint8_t *out_alert, CBS *contents) {
+static int forbid_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
+                                    CBS *contents) {
   if (contents != NULL) {
     /* Servers MUST NOT send this extension. */
     *out_alert = SSL_AD_UNSUPPORTED_EXTENSION;
@@ -617,12 +620,13 @@
   return 1;
 }
 
-static int ignore_parse_clienthello(SSL *ssl, uint8_t *out_alert, CBS *contents) {
+static int ignore_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
+                                    CBS *contents) {
   /* This extension from the client is handled elsewhere. */
   return 1;
 }
 
-static int dont_add_serverhello(SSL *ssl, CBB *out) {
+static int dont_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
   return 1;
 }
 
@@ -630,7 +634,8 @@
  *
  * https://tools.ietf.org/html/rfc6066#section-3. */
 
-static int ext_sni_add_clienthello(SSL *ssl, CBB *out) {
+static int ext_sni_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) {
+  SSL *const ssl = hs->ssl;
   if (ssl->tlsext_hostname == NULL) {
     return 1;
   }
@@ -650,8 +655,9 @@
   return 1;
 }
 
-static int ext_sni_parse_serverhello(SSL *ssl, uint8_t *out_alert,
+static int ext_sni_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
                                      CBS *contents) {
+  SSL *const ssl = hs->ssl;
   if (contents == NULL) {
     return 1;
   }
@@ -674,7 +680,7 @@
   return 1;
 }
 
-static int ext_sni_parse_clienthello(SSL *ssl, uint8_t *out_alert,
+static int ext_sni_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
                                      CBS *contents) {
   if (contents == NULL) {
     return 1;
@@ -706,18 +712,18 @@
   }
 
   /* Copy the hostname as a string. */
-  if (!CBS_strdup(&host_name, &ssl->s3->hs->hostname)) {
+  if (!CBS_strdup(&host_name, &hs->hostname)) {
     *out_alert = SSL_AD_INTERNAL_ERROR;
     return 0;
   }
 
-  ssl->s3->hs->should_ack_sni = 1;
+  hs->should_ack_sni = 1;
   return 1;
 }
 
-static int ext_sni_add_serverhello(SSL *ssl, CBB *out) {
-  if (ssl->s3->session_reused ||
-      !ssl->s3->hs->should_ack_sni) {
+static int ext_sni_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
+  if (hs->ssl->s3->session_reused ||
+      !hs->should_ack_sni) {
     return 1;
   }
 
@@ -734,7 +740,8 @@
  *
  * https://tools.ietf.org/html/rfc5746 */
 
-static int ext_ri_add_clienthello(SSL *ssl, CBB *out) {
+static int ext_ri_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) {
+  SSL *const ssl = hs->ssl;
   uint16_t min_version, max_version;
   if (!ssl_get_version_range(ssl, &min_version, &max_version)) {
     return 0;
@@ -761,8 +768,9 @@
   return 1;
 }
 
-static int ext_ri_parse_serverhello(SSL *ssl, uint8_t *out_alert,
+static int ext_ri_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
                                     CBS *contents) {
+  SSL *const ssl = hs->ssl;
   if (contents != NULL && ssl3_protocol_version(ssl) >= TLS1_3_VERSION) {
     return 0;
   }
@@ -834,8 +842,9 @@
   return 1;
 }
 
-static int ext_ri_parse_clienthello(SSL *ssl, uint8_t *out_alert,
+static int ext_ri_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
                                     CBS *contents) {
+  SSL *const ssl = hs->ssl;
   /* Renegotiation isn't supported as a server so this function should never be
    * called after the initial handshake. */
   assert(!ssl->s3->initial_handshake_complete);
@@ -868,7 +877,8 @@
   return 1;
 }
 
-static int ext_ri_add_serverhello(SSL *ssl, CBB *out) {
+static int ext_ri_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
+  SSL *const ssl = hs->ssl;
   /* Renegotiation isn't supported as a server so this function should never be
    * called after the initial handshake. */
   assert(!ssl->s3->initial_handshake_complete);
@@ -891,9 +901,9 @@
  *
  * https://tools.ietf.org/html/rfc7627 */
 
-static int ext_ems_add_clienthello(SSL *ssl, CBB *out) {
+static int ext_ems_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) {
   uint16_t min_version, max_version;
-  if (!ssl_get_version_range(ssl, &min_version, &max_version)) {
+  if (!ssl_get_version_range(hs->ssl, &min_version, &max_version)) {
     return 0;
   }
 
@@ -910,8 +920,9 @@
   return 1;
 }
 
-static int ext_ems_parse_serverhello(SSL *ssl, uint8_t *out_alert,
+static int ext_ems_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
                                      CBS *contents) {
+  SSL *const ssl = hs->ssl;
   /* Whether EMS is negotiated may not change on renegotation. */
   if (ssl->s3->initial_handshake_complete) {
     if ((contents != NULL) != ssl->s3->tmp.extended_master_secret) {
@@ -940,10 +951,12 @@
   return 1;
 }
 
-static int ext_ems_parse_clienthello(SSL *ssl, uint8_t *out_alert,
+static int ext_ems_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
                                      CBS *contents) {
-  if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION ||
-      ssl->version == SSL3_VERSION) {
+  SSL *const ssl = hs->ssl;
+  uint16_t version = ssl3_protocol_version(ssl);
+  if (version >= TLS1_3_VERSION ||
+      version == SSL3_VERSION) {
     return 1;
   }
 
@@ -959,8 +972,8 @@
   return 1;
 }
 
-static int ext_ems_add_serverhello(SSL *ssl, CBB *out) {
-  if (!ssl->s3->tmp.extended_master_secret) {
+static int ext_ems_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
+  if (!hs->ssl->s3->tmp.extended_master_secret) {
     return 1;
   }
 
@@ -977,7 +990,8 @@
  *
  * https://tools.ietf.org/html/rfc5077 */
 
-static int ext_ticket_add_clienthello(SSL *ssl, CBB *out) {
+static int ext_ticket_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) {
+  SSL *const ssl = hs->ssl;
   uint16_t min_version, max_version;
   if (!ssl_get_version_range(ssl, &min_version, &max_version)) {
     return 0;
@@ -1019,8 +1033,9 @@
   return 1;
 }
 
-static int ext_ticket_parse_serverhello(SSL *ssl, uint8_t *out_alert,
+static int ext_ticket_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
                                         CBS *contents) {
+  SSL *const ssl = hs->ssl;
   if (contents == NULL) {
     return 1;
   }
@@ -1038,17 +1053,17 @@
     return 0;
   }
 
-  ssl->s3->hs->ticket_expected = 1;
+  hs->ticket_expected = 1;
   return 1;
 }
 
-static int ext_ticket_add_serverhello(SSL *ssl, CBB *out) {
-  if (!ssl->s3->hs->ticket_expected) {
+static int ext_ticket_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
+  if (!hs->ticket_expected) {
     return 1;
   }
 
   /* If |SSL_OP_NO_TICKET| is set, |ticket_expected| should never be true. */
-  assert((SSL_get_options(ssl) & SSL_OP_NO_TICKET) == 0);
+  assert((SSL_get_options(hs->ssl) & SSL_OP_NO_TICKET) == 0);
 
   if (!CBB_add_u16(out, TLSEXT_TYPE_session_ticket) ||
       !CBB_add_u16(out, 0 /* length */)) {
@@ -1063,7 +1078,8 @@
  *
  * https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */
 
-static int ext_sigalgs_add_clienthello(SSL *ssl, CBB *out) {
+static int ext_sigalgs_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) {
+  SSL *const ssl = hs->ssl;
   uint16_t min_version, max_version;
   if (!ssl_get_version_range(ssl, &min_version, &max_version)) {
     return 0;
@@ -1096,11 +1112,12 @@
   return 1;
 }
 
-static int ext_sigalgs_parse_clienthello(SSL *ssl, uint8_t *out_alert,
+static int ext_sigalgs_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
                                          CBS *contents) {
-  OPENSSL_free(ssl->s3->hs->peer_sigalgs);
-  ssl->s3->hs->peer_sigalgs = NULL;
-  ssl->s3->hs->num_peer_sigalgs = 0;
+  SSL *const ssl = hs->ssl;
+  OPENSSL_free(hs->peer_sigalgs);
+  hs->peer_sigalgs = NULL;
+  hs->num_peer_sigalgs = 0;
 
   if (contents == NULL) {
     return 1;
@@ -1122,11 +1139,12 @@
  *
  * https://tools.ietf.org/html/rfc6066#section-8 */
 
-static void ext_ocsp_init(SSL *ssl) {
-  ssl->tlsext_status_type = -1;
+static void ext_ocsp_init(SSL_HANDSHAKE *hs) {
+  hs->ssl->tlsext_status_type = -1;
 }
 
-static int ext_ocsp_add_clienthello(SSL *ssl, CBB *out) {
+static int ext_ocsp_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) {
+  SSL *const ssl = hs->ssl;
   if (!ssl->ocsp_stapling_enabled) {
     return 1;
   }
@@ -1145,8 +1163,9 @@
   return 1;
 }
 
-static int ext_ocsp_parse_serverhello(SSL *ssl, uint8_t *out_alert,
+static int ext_ocsp_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
                                       CBS *contents) {
+  SSL *const ssl = hs->ssl;
   if (contents == NULL) {
     return 1;
   }
@@ -1166,11 +1185,11 @@
    * status_request here does not make sense, but OpenSSL does so and the
    * specification does not say anything. Tolerate it but ignore it. */
 
-  ssl->s3->hs->certificate_status_expected = 1;
+  hs->certificate_status_expected = 1;
   return 1;
 }
 
-static int ext_ocsp_parse_clienthello(SSL *ssl, uint8_t *out_alert,
+static int ext_ocsp_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
                                       CBS *contents) {
   if (contents == NULL) {
     return 1;
@@ -1183,21 +1202,22 @@
 
   /* We cannot decide whether OCSP stapling will occur yet because the correct
    * SSL_CTX might not have been selected. */
-  ssl->s3->hs->ocsp_stapling_requested = status_type == TLSEXT_STATUSTYPE_ocsp;
+  hs->ocsp_stapling_requested = status_type == TLSEXT_STATUSTYPE_ocsp;
 
   return 1;
 }
 
-static int ext_ocsp_add_serverhello(SSL *ssl, CBB *out) {
+static int ext_ocsp_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
+  SSL *const ssl = hs->ssl;
   if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION ||
-      !ssl->s3->hs->ocsp_stapling_requested ||
+      !hs->ocsp_stapling_requested ||
       ssl->ctx->ocsp_response_length == 0 ||
       ssl->s3->session_reused ||
       !ssl_cipher_uses_certificate_auth(ssl->s3->tmp.new_cipher)) {
     return 1;
   }
 
-  ssl->s3->hs->certificate_status_expected = 1;
+  hs->certificate_status_expected = 1;
 
   return CBB_add_u16(out, TLSEXT_TYPE_status_request) &&
          CBB_add_u16(out, 0 /* length */);
@@ -1208,11 +1228,11 @@
  *
  * https://htmlpreview.github.io/?https://github.com/agl/technotes/blob/master/nextprotoneg.html */
 
-static int ext_npn_add_clienthello(SSL *ssl, CBB *out) {
+static int ext_npn_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) {
+  SSL *const ssl = hs->ssl;
   if (ssl->s3->initial_handshake_complete ||
       ssl->ctx->next_proto_select_cb == NULL ||
-      (ssl->options & SSL_OP_DISABLE_NPN) ||
-      SSL_is_dtls(ssl)) {
+      (ssl->options & SSL_OP_DISABLE_NPN) || SSL_is_dtls(ssl)) {
     return 1;
   }
 
@@ -1224,8 +1244,9 @@
   return 1;
 }
 
-static int ext_npn_parse_serverhello(SSL *ssl, uint8_t *out_alert,
+static int ext_npn_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
                                      CBS *contents) {
+  SSL *const ssl = hs->ssl;
   if (contents == NULL) {
     return 1;
   }
@@ -1277,13 +1298,14 @@
   }
 
   ssl->s3->next_proto_negotiated_len = selected_len;
-  ssl->s3->hs->next_proto_neg_seen = 1;
+  hs->next_proto_neg_seen = 1;
 
   return 1;
 }
 
-static int ext_npn_parse_clienthello(SSL *ssl, uint8_t *out_alert,
+static int ext_npn_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
                                      CBS *contents) {
+  SSL *const ssl = hs->ssl;
   if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION) {
     return 1;
   }
@@ -1299,14 +1321,15 @@
     return 1;
   }
 
-  ssl->s3->hs->next_proto_neg_seen = 1;
+  hs->next_proto_neg_seen = 1;
   return 1;
 }
 
-static int ext_npn_add_serverhello(SSL *ssl, CBB *out) {
+static int ext_npn_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
+  SSL *const ssl = hs->ssl;
   /* |next_proto_neg_seen| might have been cleared when an ALPN extension was
    * parsed. */
-  if (!ssl->s3->hs->next_proto_neg_seen) {
+  if (!hs->next_proto_neg_seen) {
     return 1;
   }
 
@@ -1316,7 +1339,7 @@
   if (ssl->ctx->next_protos_advertised_cb(
           ssl, &npa, &npa_len, ssl->ctx->next_protos_advertised_cb_arg) !=
       SSL_TLSEXT_ERR_OK) {
-    ssl->s3->hs->next_proto_neg_seen = 0;
+    hs->next_proto_neg_seen = 0;
     return 1;
   }
 
@@ -1336,7 +1359,8 @@
  *
  * https://tools.ietf.org/html/rfc6962#section-3.3.1 */
 
-static int ext_sct_add_clienthello(SSL *ssl, CBB *out) {
+static int ext_sct_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) {
+  SSL *const ssl = hs->ssl;
   if (!ssl->signed_cert_timestamps_enabled) {
     return 1;
   }
@@ -1349,8 +1373,9 @@
   return 1;
 }
 
-static int ext_sct_parse_serverhello(SSL *ssl, uint8_t *out_alert,
+static int ext_sct_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
                                      CBS *contents) {
+  SSL *const ssl = hs->ssl;
   if (contents == NULL) {
     return 1;
   }
@@ -1387,7 +1412,7 @@
   return 1;
 }
 
-static int ext_sct_parse_clienthello(SSL *ssl, uint8_t *out_alert,
+static int ext_sct_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
                                      CBS *contents) {
   if (contents == NULL) {
     return 1;
@@ -1397,11 +1422,12 @@
     return 0;
   }
 
-  ssl->s3->hs->scts_requested = 1;
+  hs->scts_requested = 1;
   return 1;
 }
 
-static int ext_sct_add_serverhello(SSL *ssl, CBB *out) {
+static int ext_sct_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
+  SSL *const ssl = hs->ssl;
   /* The extension shouldn't be sent when resuming sessions. */
   if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION ||
       ssl->s3->session_reused ||
@@ -1422,7 +1448,8 @@
  *
  * https://tools.ietf.org/html/rfc7301 */
 
-static int ext_alpn_add_clienthello(SSL *ssl, CBB *out) {
+static int ext_alpn_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) {
+  SSL *const ssl = hs->ssl;
   if (ssl->alpn_client_proto_list == NULL ||
       ssl->s3->initial_handshake_complete) {
     return 1;
@@ -1441,8 +1468,9 @@
   return 1;
 }
 
-static int ext_alpn_parse_serverhello(SSL *ssl, uint8_t *out_alert,
+static int ext_alpn_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
                                       CBS *contents) {
+  SSL *const ssl = hs->ssl;
   if (contents == NULL) {
     return 1;
   }
@@ -1450,7 +1478,7 @@
   assert(!ssl->s3->initial_handshake_complete);
   assert(ssl->alpn_client_proto_list != NULL);
 
-  if (ssl->s3->hs->next_proto_neg_seen) {
+  if (hs->next_proto_neg_seen) {
     /* NPN and ALPN may not be negotiated in the same connection. */
     *out_alert = SSL_AD_ILLEGAL_PARAMETER;
     OPENSSL_PUT_ERROR(SSL, SSL_R_NEGOTIATED_BOTH_NPN_AND_ALPN);
@@ -1559,7 +1587,8 @@
   return 1;
 }
 
-static int ext_alpn_add_serverhello(SSL *ssl, CBB *out) {
+static int ext_alpn_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
+  SSL *const ssl = hs->ssl;
   if (ssl->s3->alpn_selected == NULL) {
     return 1;
   }
@@ -1583,11 +1612,12 @@
  *
  * https://tools.ietf.org/html/draft-balfanz-tls-channelid-01 */
 
-static void ext_channel_id_init(SSL *ssl) {
-  ssl->s3->tlsext_channel_id_valid = 0;
+static void ext_channel_id_init(SSL_HANDSHAKE *hs) {
+  hs->ssl->s3->tlsext_channel_id_valid = 0;
 }
 
-static int ext_channel_id_add_clienthello(SSL *ssl, CBB *out) {
+static int ext_channel_id_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) {
+  SSL *const ssl = hs->ssl;
   if (!ssl->tlsext_channel_id_enabled ||
       SSL_is_dtls(ssl)) {
     return 1;
@@ -1601,8 +1631,9 @@
   return 1;
 }
 
-static int ext_channel_id_parse_serverhello(SSL *ssl, uint8_t *out_alert,
-                                            CBS *contents) {
+static int ext_channel_id_parse_serverhello(SSL_HANDSHAKE *hs,
+                                            uint8_t *out_alert, CBS *contents) {
+  SSL *const ssl = hs->ssl;
   if (contents == NULL) {
     return 1;
   }
@@ -1618,8 +1649,9 @@
   return 1;
 }
 
-static int ext_channel_id_parse_clienthello(SSL *ssl, uint8_t *out_alert,
-                                            CBS *contents) {
+static int ext_channel_id_parse_clienthello(SSL_HANDSHAKE *hs,
+                                            uint8_t *out_alert, CBS *contents) {
+  SSL *const ssl = hs->ssl;
   if (contents == NULL ||
       !ssl->tlsext_channel_id_enabled ||
       SSL_is_dtls(ssl)) {
@@ -1634,7 +1666,8 @@
   return 1;
 }
 
-static int ext_channel_id_add_serverhello(SSL *ssl, CBB *out) {
+static int ext_channel_id_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
+  SSL *const ssl = hs->ssl;
   if (!ssl->s3->tlsext_channel_id_valid) {
     return 1;
   }
@@ -1653,11 +1686,12 @@
  * https://tools.ietf.org/html/rfc5764 */
 
 
-static void ext_srtp_init(SSL *ssl) {
-  ssl->srtp_profile = NULL;
+static void ext_srtp_init(SSL_HANDSHAKE *hs) {
+  hs->ssl->srtp_profile = NULL;
 }
 
-static int ext_srtp_add_clienthello(SSL *ssl, CBB *out) {
+static int ext_srtp_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) {
+  SSL *const ssl = hs->ssl;
   STACK_OF(SRTP_PROTECTION_PROFILE) *profiles = SSL_get_srtp_profiles(ssl);
   if (profiles == NULL) {
     return 1;
@@ -1689,8 +1723,9 @@
   return 1;
 }
 
-static int ext_srtp_parse_serverhello(SSL *ssl, uint8_t *out_alert,
+static int ext_srtp_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
                                       CBS *contents) {
+  SSL *const ssl = hs->ssl;
   if (contents == NULL) {
     return 1;
   }
@@ -1736,8 +1771,9 @@
   return 0;
 }
 
-static int ext_srtp_parse_clienthello(SSL *ssl, uint8_t *out_alert,
+static int ext_srtp_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
                                       CBS *contents) {
+  SSL *const ssl = hs->ssl;
   if (contents == NULL) {
     return 1;
   }
@@ -1779,7 +1815,8 @@
   return 1;
 }
 
-static int ext_srtp_add_serverhello(SSL *ssl, CBB *out) {
+static int ext_srtp_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
+  SSL *const ssl = hs->ssl;
   if (ssl->srtp_profile == NULL) {
     return 1;
   }
@@ -1802,7 +1839,7 @@
  *
  * https://tools.ietf.org/html/rfc4492#section-5.1.2 */
 
-static int ext_ec_point_add_extension(SSL *ssl, CBB *out) {
+static int ext_ec_point_add_extension(SSL_HANDSHAKE *hs, CBB *out) {
   CBB contents, formats;
   if (!CBB_add_u16(out, TLSEXT_TYPE_ec_point_formats) ||
       !CBB_add_u16_length_prefixed(out, &contents) ||
@@ -1815,9 +1852,9 @@
   return 1;
 }
 
-static int ext_ec_point_add_clienthello(SSL *ssl, CBB *out) {
+static int ext_ec_point_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) {
   uint16_t min_version, max_version;
-  if (!ssl_get_version_range(ssl, &min_version, &max_version)) {
+  if (!ssl_get_version_range(hs->ssl, &min_version, &max_version)) {
     return 0;
   }
 
@@ -1826,16 +1863,16 @@
     return 1;
   }
 
-  return ext_ec_point_add_extension(ssl, out);
+  return ext_ec_point_add_extension(hs, out);
 }
 
-static int ext_ec_point_parse_serverhello(SSL *ssl, uint8_t *out_alert,
+static int ext_ec_point_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
                                           CBS *contents) {
   if (contents == NULL) {
     return 1;
   }
 
-  if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION) {
+  if (ssl3_protocol_version(hs->ssl) >= TLS1_3_VERSION) {
     return 0;
   }
 
@@ -1856,16 +1893,17 @@
   return 1;
 }
 
-static int ext_ec_point_parse_clienthello(SSL *ssl, uint8_t *out_alert,
+static int ext_ec_point_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
                                           CBS *contents) {
-  if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION) {
+  if (ssl3_protocol_version(hs->ssl) >= TLS1_3_VERSION) {
     return 1;
   }
 
-  return ext_ec_point_parse_serverhello(ssl, out_alert, contents);
+  return ext_ec_point_parse_serverhello(hs, out_alert, contents);
 }
 
-static int ext_ec_point_add_serverhello(SSL *ssl, CBB *out) {
+static int ext_ec_point_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
+  SSL *const ssl = hs->ssl;
   if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION) {
     return 1;
   }
@@ -1878,7 +1916,7 @@
     return 1;
   }
 
-  return ext_ec_point_add_extension(ssl, out);
+  return ext_ec_point_add_extension(hs, out);
 }
 
 
@@ -1886,7 +1924,8 @@
  *
  * https://tools.ietf.org/html/draft-ietf-tls-tls13-18#section-4.2.6 */
 
-static size_t ext_pre_shared_key_clienthello_length(SSL *ssl) {
+static size_t ext_pre_shared_key_clienthello_length(SSL_HANDSHAKE *hs) {
+  SSL *const ssl = hs->ssl;
   uint16_t min_version, max_version;
   if (!ssl_get_version_range(ssl, &min_version, &max_version)) {
     return 0;
@@ -1906,7 +1945,8 @@
   return 15 + ssl->session->tlsext_ticklen + binder_len;
 }
 
-static int ext_pre_shared_key_add_clienthello(SSL *ssl, CBB *out) {
+static int ext_pre_shared_key_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) {
+  SSL *const ssl = hs->ssl;
   uint16_t min_version, max_version;
   if (!ssl_get_version_range(ssl, &min_version, &max_version)) {
     return 0;
@@ -1946,7 +1986,7 @@
     return 0;
   }
 
-  ssl->s3->hs->needs_psk_binder = 1;
+  hs->needs_psk_binder = 1;
   return CBB_flush(out);
 }
 
@@ -2063,7 +2103,9 @@
  *
  * https://tools.ietf.org/html/draft-ietf-tls-tls13-18#section-4.2.7 */
 
-static int ext_psk_key_exchange_modes_add_clienthello(SSL *ssl, CBB *out) {
+static int ext_psk_key_exchange_modes_add_clienthello(SSL_HANDSHAKE *hs,
+                                                      CBB *out) {
+  SSL *const ssl = hs->ssl;
   uint16_t min_version, max_version;
   if (!ssl_get_version_range(ssl, &min_version, &max_version)) {
     return 0;
@@ -2084,7 +2126,7 @@
   return CBB_flush(out);
 }
 
-static int ext_psk_key_exchange_modes_parse_clienthello(SSL *ssl,
+static int ext_psk_key_exchange_modes_parse_clienthello(SSL_HANDSHAKE *hs,
                                                         uint8_t *out_alert,
                                                         CBS *contents) {
   if (contents == NULL) {
@@ -2100,7 +2142,7 @@
   }
 
   /* We only support tickets with PSK_DHE_KE. */
-  ssl->s3->hs->accept_psk_mode =
+  hs->accept_psk_mode =
       memchr(CBS_data(&ke_modes), SSL_PSK_DHE_KE, CBS_len(&ke_modes)) != NULL;
 
   return 1;
@@ -2111,13 +2153,14 @@
  *
  * https://tools.ietf.org/html/draft-ietf-tls-tls13-18#section-4.2.8 */
 
-static int ext_early_data_add_clienthello(SSL *ssl, CBB *out) {
+static int ext_early_data_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) {
   /* TODO(svaldez): Support 0RTT. */
   return 1;
 }
 
-static int ext_early_data_parse_clienthello(SSL *ssl, uint8_t *out_alert,
-                                            CBS *contents) {
+static int ext_early_data_parse_clienthello(SSL_HANDSHAKE *hs,
+                                            uint8_t *out_alert, CBS *contents) {
+  SSL *const ssl = hs->ssl;
   if (contents == NULL) {
     return 1;
   }
@@ -2140,7 +2183,8 @@
  *
  * https://tools.ietf.org/html/draft-ietf-tls-tls13-16#section-4.2.5 */
 
-static int ext_key_share_add_clienthello(SSL *ssl, CBB *out) {
+static int ext_key_share_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) {
+  SSL *const ssl = hs->ssl;
   uint16_t min_version, max_version;
   if (!ssl_get_version_range(ssl, &min_version, &max_version)) {
     return 0;
@@ -2157,18 +2201,18 @@
     return 0;
   }
 
-  uint16_t group_id = ssl->s3->hs->retry_group;
-  if (ssl->s3->hs->received_hello_retry_request) {
+  uint16_t group_id = hs->retry_group;
+  if (hs->received_hello_retry_request) {
     /* We received a HelloRetryRequest without a new curve, so there is no new
      * share to append. Leave |ecdh_ctx| as-is. */
     if (group_id == 0 &&
-        !CBB_add_bytes(&kse_bytes, ssl->s3->hs->key_share_bytes,
-                       ssl->s3->hs->key_share_bytes_len)) {
+        !CBB_add_bytes(&kse_bytes, hs->key_share_bytes,
+                       hs->key_share_bytes_len)) {
       return 0;
     }
-    OPENSSL_free(ssl->s3->hs->key_share_bytes);
-    ssl->s3->hs->key_share_bytes = NULL;
-    ssl->s3->hs->key_share_bytes_len = 0;
+    OPENSSL_free(hs->key_share_bytes);
+    hs->key_share_bytes = NULL;
+    hs->key_share_bytes_len = 0;
     if (group_id == 0) {
       return CBB_flush(out);
     }
@@ -2197,19 +2241,18 @@
   CBB key_exchange;
   if (!CBB_add_u16(&kse_bytes, group_id) ||
       !CBB_add_u16_length_prefixed(&kse_bytes, &key_exchange) ||
-      !SSL_ECDH_CTX_init(&ssl->s3->hs->ecdh_ctx, group_id) ||
-      !SSL_ECDH_CTX_offer(&ssl->s3->hs->ecdh_ctx, &key_exchange) ||
+      !SSL_ECDH_CTX_init(&hs->ecdh_ctx, group_id) ||
+      !SSL_ECDH_CTX_offer(&hs->ecdh_ctx, &key_exchange) ||
       !CBB_flush(&kse_bytes)) {
     return 0;
   }
 
-  if (!ssl->s3->hs->received_hello_retry_request) {
+  if (!hs->received_hello_retry_request) {
     /* Save the contents of the extension to repeat it in the second
      * ClientHello. */
-    ssl->s3->hs->key_share_bytes_len = CBB_len(&kse_bytes);
-    ssl->s3->hs->key_share_bytes = BUF_memdup(CBB_data(&kse_bytes),
-                                              CBB_len(&kse_bytes));
-    if (ssl->s3->hs->key_share_bytes == NULL) {
+    hs->key_share_bytes_len = CBB_len(&kse_bytes);
+    hs->key_share_bytes = BUF_memdup(CBB_data(&kse_bytes), CBB_len(&kse_bytes));
+    if (hs->key_share_bytes == NULL) {
       return 0;
     }
   }
@@ -2352,7 +2395,8 @@
  *
  * https://tools.ietf.org/html/draft-ietf-tls-tls13-16#section-4.2.1 */
 
-static int ext_supported_versions_add_clienthello(SSL *ssl, CBB *out) {
+static int ext_supported_versions_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) {
+  SSL *const ssl = hs->ssl;
   uint16_t min_version, max_version;
   if (!ssl_get_version_range(ssl, &min_version, &max_version)) {
     return 0;
@@ -2393,8 +2437,8 @@
  *
  * https://tools.ietf.org/html/draft-ietf-tls-tls13-16#section-4.2.2 */
 
-static int ext_cookie_add_clienthello(SSL *ssl, CBB *out) {
-  if (ssl->s3->hs->cookie == NULL) {
+static int ext_cookie_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) {
+  if (hs->cookie == NULL) {
     return 1;
   }
 
@@ -2402,15 +2446,15 @@
   if (!CBB_add_u16(out, TLSEXT_TYPE_cookie) ||
       !CBB_add_u16_length_prefixed(out, &contents) ||
       !CBB_add_u16_length_prefixed(&contents, &cookie) ||
-      !CBB_add_bytes(&cookie, ssl->s3->hs->cookie, ssl->s3->hs->cookie_len) ||
+      !CBB_add_bytes(&cookie, hs->cookie, hs->cookie_len) ||
       !CBB_flush(out)) {
     return 0;
   }
 
   /* The cookie is no longer needed in memory. */
-  OPENSSL_free(ssl->s3->hs->cookie);
-  ssl->s3->hs->cookie = NULL;
-  ssl->s3->hs->cookie_len = 0;
+  OPENSSL_free(hs->cookie);
+  hs->cookie = NULL;
+  hs->cookie_len = 0;
   return 1;
 }
 
@@ -2420,7 +2464,8 @@
  * https://tools.ietf.org/html/rfc4492#section-5.1.2
  * https://tools.ietf.org/html/draft-ietf-tls-tls13-16#section-4.2.4 */
 
-static int ext_supported_groups_add_clienthello(SSL *ssl, CBB *out) {
+static int ext_supported_groups_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) {
+  SSL *const ssl = hs->ssl;
   CBB contents, groups_bytes;
   if (!CBB_add_u16(out, TLSEXT_TYPE_supported_groups) ||
       !CBB_add_u16_length_prefixed(out, &contents) ||
@@ -2448,14 +2493,16 @@
   return CBB_flush(out);
 }
 
-static int ext_supported_groups_parse_serverhello(SSL *ssl, uint8_t *out_alert,
+static int ext_supported_groups_parse_serverhello(SSL_HANDSHAKE *hs,
+                                                  uint8_t *out_alert,
                                                   CBS *contents) {
   /* This extension is not expected to be echoed by servers in TLS 1.2, but some
    * BigIP servers send it nonetheless, so do not enforce this. */
   return 1;
 }
 
-static int ext_supported_groups_parse_clienthello(SSL *ssl, uint8_t *out_alert,
+static int ext_supported_groups_parse_clienthello(SSL_HANDSHAKE *hs,
+                                                  uint8_t *out_alert,
                                                   CBS *contents) {
   if (contents == NULL) {
     return 1;
@@ -2469,9 +2516,9 @@
     return 0;
   }
 
-  ssl->s3->hs->peer_supported_group_list = OPENSSL_malloc(
-      CBS_len(&supported_group_list));
-  if (ssl->s3->hs->peer_supported_group_list == NULL) {
+  hs->peer_supported_group_list =
+      OPENSSL_malloc(CBS_len(&supported_group_list));
+  if (hs->peer_supported_group_list == NULL) {
     *out_alert = SSL_AD_INTERNAL_ERROR;
     return 0;
   }
@@ -2479,24 +2526,24 @@
   const size_t num_groups = CBS_len(&supported_group_list) / 2;
   for (size_t i = 0; i < num_groups; i++) {
     if (!CBS_get_u16(&supported_group_list,
-                     &ssl->s3->hs->peer_supported_group_list[i])) {
+                     &hs->peer_supported_group_list[i])) {
       goto err;
     }
   }
 
   assert(CBS_len(&supported_group_list) == 0);
-  ssl->s3->hs->peer_supported_group_list_len = num_groups;
+  hs->peer_supported_group_list_len = num_groups;
 
   return 1;
 
 err:
-  OPENSSL_free(ssl->s3->hs->peer_supported_group_list);
-  ssl->s3->hs->peer_supported_group_list = NULL;
+  OPENSSL_free(hs->peer_supported_group_list);
+  hs->peer_supported_group_list = NULL;
   *out_alert = SSL_AD_INTERNAL_ERROR;
   return 0;
 }
 
-static int ext_supported_groups_add_serverhello(SSL *ssl, CBB *out) {
+static int ext_supported_groups_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
   /* Servers don't echo this extension. */
   return 1;
 }
@@ -2683,7 +2730,8 @@
          tls_extension_find(&index, extension_value) != NULL;
 }
 
-int ssl_add_clienthello_tlsext(SSL *ssl, CBB *out, size_t header_len) {
+int ssl_add_clienthello_tlsext(SSL_HANDSHAKE *hs, CBB *out, size_t header_len) {
+  SSL *const ssl = hs->ssl;
   /* don't add extensions for SSLv3 unless doing secure renegotiation */
   if (ssl->client_version == SSL3_VERSION &&
       !ssl->s3->send_connection_binding) {
@@ -2695,12 +2743,12 @@
     goto err;
   }
 
-  ssl->s3->hs->extensions.sent = 0;
-  ssl->s3->hs->custom_extensions.sent = 0;
+  hs->extensions.sent = 0;
+  hs->custom_extensions.sent = 0;
 
   for (size_t i = 0; i < kNumExtensions; i++) {
     if (kExtensions[i].init != NULL) {
-      kExtensions[i].init(ssl);
+      kExtensions[i].init(hs);
     }
   }
 
@@ -2716,14 +2764,14 @@
 
   for (size_t i = 0; i < kNumExtensions; i++) {
     const size_t len_before = CBB_len(&extensions);
-    if (!kExtensions[i].add_clienthello(ssl, &extensions)) {
+    if (!kExtensions[i].add_clienthello(hs, &extensions)) {
       OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_ADDING_EXTENSION);
       ERR_add_error_dataf("extension %u", (unsigned)kExtensions[i].value);
       goto err;
     }
 
     if (CBB_len(&extensions) != len_before) {
-      ssl->s3->hs->extensions.sent |= (1u << i);
+      hs->extensions.sent |= (1u << i);
     }
   }
 
@@ -2750,7 +2798,7 @@
   }
 
   if (!SSL_is_dtls(ssl)) {
-    size_t psk_extension_len = ext_pre_shared_key_clienthello_length(ssl);
+    size_t psk_extension_len = ext_pre_shared_key_clienthello_length(hs);
     header_len += 2 + CBB_len(&extensions) + psk_extension_len;
     if (header_len > 0xff && header_len < 0x200) {
       /* Add padding to workaround bugs in F5 terminators. See RFC 7685.
@@ -2780,7 +2828,7 @@
   }
 
   /* The PSK extension must be last, including after the padding. */
-  if (!ext_pre_shared_key_add_clienthello(ssl, &extensions)) {
+  if (!ext_pre_shared_key_add_clienthello(hs, &extensions)) {
     goto err;
   }
 
@@ -2796,20 +2844,20 @@
   return 0;
 }
 
-int ssl_add_serverhello_tlsext(SSL *ssl, CBB *out) {
+int ssl_add_serverhello_tlsext(SSL_HANDSHAKE *hs, CBB *out) {
+  SSL *const ssl = hs->ssl;
   CBB extensions;
   if (!CBB_add_u16_length_prefixed(out, &extensions)) {
     goto err;
   }
 
-  unsigned i;
-  for (i = 0; i < kNumExtensions; i++) {
-    if (!(ssl->s3->hs->extensions.received & (1u << i))) {
+  for (unsigned i = 0; i < kNumExtensions; i++) {
+    if (!(hs->extensions.received & (1u << i))) {
       /* Don't send extensions that were not received. */
       continue;
     }
 
-    if (!kExtensions[i].add_serverhello(ssl, &extensions)) {
+    if (!kExtensions[i].add_serverhello(hs, &extensions)) {
       OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_ADDING_EXTENSION);
       ERR_add_error_dataf("extension %u", (unsigned)kExtensions[i].value);
       goto err;
@@ -2834,16 +2882,17 @@
 }
 
 static int ssl_scan_clienthello_tlsext(
-    SSL *ssl, const struct ssl_early_callback_ctx *client_hello,
+    SSL_HANDSHAKE *hs, const struct ssl_early_callback_ctx *client_hello,
     int *out_alert) {
+  SSL *const ssl = hs->ssl;
   for (size_t i = 0; i < kNumExtensions; i++) {
     if (kExtensions[i].init != NULL) {
-      kExtensions[i].init(ssl);
+      kExtensions[i].init(hs);
     }
   }
 
-  ssl->s3->hs->extensions.received = 0;
-  ssl->s3->hs->custom_extensions.received = 0;
+  hs->extensions.received = 0;
+  hs->custom_extensions.received = 0;
 
   CBS extensions;
   CBS_init(&extensions, client_hello->extensions, client_hello->extensions_len);
@@ -2876,9 +2925,9 @@
       continue;
     }
 
-    ssl->s3->hs->extensions.received |= (1u << ext_index);
+    hs->extensions.received |= (1u << ext_index);
     uint8_t alert = SSL_AD_DECODE_ERROR;
-    if (!ext->parse_clienthello(ssl, &alert, &extension)) {
+    if (!ext->parse_clienthello(hs, &alert, &extension)) {
       *out_alert = alert;
       OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_PARSING_EXTENSION);
       ERR_add_error_dataf("extension %u", (unsigned)type);
@@ -2887,7 +2936,7 @@
   }
 
   for (size_t i = 0; i < kNumExtensions; i++) {
-    if (ssl->s3->hs->extensions.received & (1u << i)) {
+    if (hs->extensions.received & (1u << i)) {
       continue;
     }
 
@@ -2901,13 +2950,13 @@
       CBS_init(&fake_contents, kFakeRenegotiateExtension,
                sizeof(kFakeRenegotiateExtension));
       contents = &fake_contents;
-      ssl->s3->hs->extensions.received |= (1u << i);
+      hs->extensions.received |= (1u << i);
     }
 
     /* Extension wasn't observed so call the callback with a NULL
      * parameter. */
     uint8_t alert = SSL_AD_DECODE_ERROR;
-    if (!kExtensions[i].parse_clienthello(ssl, &alert, contents)) {
+    if (!kExtensions[i].parse_clienthello(hs, &alert, contents)) {
       OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_EXTENSION);
       ERR_add_error_dataf("extension %u", (unsigned)kExtensions[i].value);
       *out_alert = alert;
@@ -2919,14 +2968,15 @@
 }
 
 int ssl_parse_clienthello_tlsext(
-    SSL *ssl, const struct ssl_early_callback_ctx *client_hello) {
+    SSL_HANDSHAKE *hs, const struct ssl_early_callback_ctx *client_hello) {
+  SSL *const ssl = hs->ssl;
   int alert = -1;
-  if (ssl_scan_clienthello_tlsext(ssl, client_hello, &alert) <= 0) {
+  if (ssl_scan_clienthello_tlsext(hs, client_hello, &alert) <= 0) {
     ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
     return 0;
   }
 
-  if (ssl_check_clienthello_tlsext(ssl) <= 0) {
+  if (ssl_check_clienthello_tlsext(hs) <= 0) {
     OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_TLSEXT);
     return 0;
   }
@@ -2936,7 +2986,9 @@
 
 OPENSSL_COMPILE_ASSERT(kNumExtensions <= sizeof(uint32_t) * 8, too_many_bits);
 
-static int ssl_scan_serverhello_tlsext(SSL *ssl, CBS *cbs, int *out_alert) {
+static int ssl_scan_serverhello_tlsext(SSL_HANDSHAKE *hs, CBS *cbs,
+                                       int *out_alert) {
+  SSL *const ssl = hs->ssl;
   /* Before TLS 1.3, ServerHello extensions blocks may be omitted if empty. */
   if (CBS_len(cbs) == 0 && ssl3_protocol_version(ssl) < TLS1_3_VERSION) {
     return 1;
@@ -2973,7 +3025,7 @@
       continue;
     }
 
-    if (!(ssl->s3->hs->extensions.sent & (1u << ext_index)) &&
+    if (!(hs->extensions.sent & (1u << ext_index)) &&
         type != TLSEXT_TYPE_renegotiate) {
       /* If the extension was never sent then it is illegal, except for the
        * renegotiation extension which, in SSL 3.0, is signaled via SCSV. */
@@ -2986,7 +3038,7 @@
     received |= (1u << ext_index);
 
     uint8_t alert = SSL_AD_DECODE_ERROR;
-    if (!ext->parse_serverhello(ssl, &alert, &extension)) {
+    if (!ext->parse_serverhello(hs, &alert, &extension)) {
       OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_PARSING_EXTENSION);
       ERR_add_error_dataf("extension %u", (unsigned)type);
       *out_alert = alert;
@@ -2999,7 +3051,7 @@
       /* Extension wasn't observed so call the callback with a NULL
        * parameter. */
       uint8_t alert = SSL_AD_DECODE_ERROR;
-      if (!kExtensions[i].parse_serverhello(ssl, &alert, NULL)) {
+      if (!kExtensions[i].parse_serverhello(hs, &alert, NULL)) {
         OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_EXTENSION);
         ERR_add_error_dataf("extension %u", (unsigned)kExtensions[i].value);
         *out_alert = alert;
@@ -3011,7 +3063,8 @@
   return 1;
 }
 
-static int ssl_check_clienthello_tlsext(SSL *ssl) {
+static int ssl_check_clienthello_tlsext(SSL_HANDSHAKE *hs) {
+  SSL *const ssl = hs->ssl;
   int ret = SSL_TLSEXT_ERR_NOACK;
   int al = SSL_AD_UNRECOGNIZED_NAME;
 
@@ -3033,7 +3086,7 @@
       return 1;
 
     case SSL_TLSEXT_ERR_NOACK:
-      ssl->s3->hs->should_ack_sni = 0;
+      hs->should_ack_sni = 0;
       return 1;
 
     default:
@@ -3041,7 +3094,8 @@
   }
 }
 
-static int ssl_check_serverhello_tlsext(SSL *ssl) {
+static int ssl_check_serverhello_tlsext(SSL_HANDSHAKE *hs) {
+  SSL *const ssl = hs->ssl;
   int ret = SSL_TLSEXT_ERR_OK;
   int al = SSL_AD_UNRECOGNIZED_NAME;
 
@@ -3067,14 +3121,15 @@
   }
 }
 
-int ssl_parse_serverhello_tlsext(SSL *ssl, CBS *cbs) {
+int ssl_parse_serverhello_tlsext(SSL_HANDSHAKE *hs, CBS *cbs) {
+  SSL *const ssl = hs->ssl;
   int alert = -1;
-  if (ssl_scan_serverhello_tlsext(ssl, cbs, &alert) <= 0) {
+  if (ssl_scan_serverhello_tlsext(hs, cbs, &alert) <= 0) {
     ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
     return 0;
   }
 
-  if (ssl_check_serverhello_tlsext(ssl) <= 0) {
+  if (ssl_check_serverhello_tlsext(hs) <= 0) {
     OPENSSL_PUT_ERROR(SSL, SSL_R_SERVERHELLO_TLSEXT);
     return 0;
   }