Avoid repeatedly scanning the list of extensions
[openssl.git] / ssl / t1_lib.c
index ce728b0a3423ec639ac33912694be42daca41571..f45ffcbc9416c5bb2f450f6bf4b6cc8f7a7044e4 100644 (file)
@@ -23,8 +23,6 @@
 static int tls_decrypt_ticket(SSL *s, const unsigned char *tick, size_t ticklen,
                               const unsigned char *sess_id, size_t sesslen,
                               SSL_SESSION **psess);
-static int ssl_check_clienthello_tlsext_early(SSL *s);
-static int ssl_check_serverhello_tlsext(SSL *s);
 
 SSL3_ENC_METHOD const TLSv1_enc_data = {
     tls1_enc,
@@ -79,7 +77,7 @@ SSL3_ENC_METHOD const TLSv1_2_enc_data = {
 };
 
 SSL3_ENC_METHOD const TLSv1_3_enc_data = {
-    tls1_enc,
+    tls13_enc,
     tls1_mac,
     tls13_setup_key_block,
     tls13_generate_master_secret,
@@ -89,8 +87,7 @@ SSL3_ENC_METHOD const TLSv1_3_enc_data = {
     TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE,
     tls1_alert_code,
     tls1_export_keying_material,
-    SSL_ENC_FLAG_EXPLICIT_IV | SSL_ENC_FLAG_SIGALGS | SSL_ENC_FLAG_SHA256_PRF
-        | SSL_ENC_FLAG_TLS1_2_CIPHERS,
+    SSL_ENC_FLAG_SIGALGS | SSL_ENC_FLAG_SHA256_PRF,
     ssl3_set_handshake_header,
     tls_close_construct_packet,
     ssl3_handshake_write
@@ -263,8 +260,8 @@ int tls1_ec_nid2curve_id(int nid)
  * parsed form instead. (However, this would affect binary compatibility
  * so cannot happen in the 1.0.x series.)
  */
-static int tls1_get_curvelist(SSL *s, int sess,
-                              const unsigned char **pcurves, size_t *num_curves)
+int tls1_get_curvelist(SSL *s, int sess, const unsigned char **pcurves,
+                       size_t *num_curves)
 {
     size_t pcurveslen = 0;
     if (sess) {
@@ -309,7 +306,7 @@ static int tls1_get_curvelist(SSL *s, int sess,
 }
 
 /* See if curve is allowed by security callback */
-static int tls_curve_allowed(SSL *s, const unsigned char *curve, int op)
+int tls_curve_allowed(SSL *s, const unsigned char *curve, int op)
 {
     const tls_curve_info *cinfo;
     if (curve[0])
@@ -598,8 +595,8 @@ static int tls1_check_ec_key(SSL *s,
     return 1;
 }
 
-static void tls1_get_formatlist(SSL *s, const unsigned char **pformats,
-                                size_t *num_formats)
+void tls1_get_formatlist(SSL *s, const unsigned char **pformats,
+                         size_t *num_formats)
 {
     /*
      * If we have a custom point format list use it otherwise use default
@@ -941,2293 +938,176 @@ int ssl_cipher_disabled(SSL *s, const SSL_CIPHER *c, int op)
     return !ssl_security(s, op, c->strength_bits, 0, (void *)c);
 }
 
-static int tls_use_ticket(SSL *s)
+int tls_use_ticket(SSL *s)
 {
     if ((s->options & SSL_OP_NO_TICKET) || SSL_IS_TLS13(s))
         return 0;
     return ssl_security(s, SSL_SECOP_TICKET, 0, 0, NULL);
 }
 
-static int compare_uint(const void *p1, const void *p2)
+/* Initialise digests to default values */
+void ssl_set_default_md(SSL *s)
 {
-    unsigned int u1 = *((const unsigned int *)p1);
-    unsigned int u2 = *((const unsigned int *)p2);
-    if (u1 < u2)
-        return -1;
-    else if (u1 > u2)
-        return 1;
+    const EVP_MD **pmd = s->s3->tmp.md;
+#ifndef OPENSSL_NO_DSA
+    pmd[SSL_PKEY_DSA_SIGN] = ssl_md(SSL_MD_SHA1_IDX);
+#endif
+#ifndef OPENSSL_NO_RSA
+    if (SSL_USE_SIGALGS(s))
+        pmd[SSL_PKEY_RSA_SIGN] = ssl_md(SSL_MD_SHA1_IDX);
     else
-        return 0;
+        pmd[SSL_PKEY_RSA_SIGN] = ssl_md(SSL_MD_MD5_SHA1_IDX);
+    pmd[SSL_PKEY_RSA_ENC] = pmd[SSL_PKEY_RSA_SIGN];
+#endif
+#ifndef OPENSSL_NO_EC
+    pmd[SSL_PKEY_ECC] = ssl_md(SSL_MD_SHA1_IDX);
+#endif
+#ifndef OPENSSL_NO_GOST
+    pmd[SSL_PKEY_GOST01] = ssl_md(SSL_MD_GOST94_IDX);
+    pmd[SSL_PKEY_GOST12_256] = ssl_md(SSL_MD_GOST12_256_IDX);
+    pmd[SSL_PKEY_GOST12_512] = ssl_md(SSL_MD_GOST12_512_IDX);
+#endif
 }
 
-/*
- * Per http://tools.ietf.org/html/rfc5246#section-7.4.1.4, there may not be
- * more than one extension of the same type in a ClientHello or ServerHello.
- * This function does an initial scan over the extensions block to filter those
- * out. It returns 1 if all extensions are unique, and 0 if the extensions
- * contain duplicates, could not be successfully parsed, or an internal error
- * occurred.
- */
-static int tls1_check_duplicate_extensions(const PACKET *packet)
+int tls1_set_server_sigalgs(SSL *s)
 {
-    PACKET extensions = *packet;
-    size_t num_extensions = 0, i = 0;
-    unsigned int *extension_types = NULL;
-    int ret = 0;
-
-    /* First pass: count the extensions. */
-    while (PACKET_remaining(&extensions) > 0) {
-        unsigned int type;
-        PACKET extension;
-        if (!PACKET_get_net_2(&extensions, &type) ||
-            !PACKET_get_length_prefixed_2(&extensions, &extension)) {
-            goto done;
-        }
-        num_extensions++;
-    }
-
-    if (num_extensions <= 1)
-        return 1;
+    int al;
+    size_t i;
 
-    extension_types = OPENSSL_malloc(sizeof(unsigned int) * num_extensions);
-    if (extension_types == NULL) {
-        SSLerr(SSL_F_TLS1_CHECK_DUPLICATE_EXTENSIONS, ERR_R_MALLOC_FAILURE);
-        goto done;
+    /* Clear any shared signature algorithms */
+    OPENSSL_free(s->cert->shared_sigalgs);
+    s->cert->shared_sigalgs = NULL;
+    s->cert->shared_sigalgslen = 0;
+    /* Clear certificate digests and validity flags */
+    for (i = 0; i < SSL_PKEY_NUM; i++) {
+        s->s3->tmp.md[i] = NULL;
+        s->s3->tmp.valid_flags[i] = 0;
     }
 
-    /* Second pass: gather the extension types. */
-    extensions = *packet;
-    for (i = 0; i < num_extensions; i++) {
-        PACKET extension;
-        if (!PACKET_get_net_2(&extensions, &extension_types[i]) ||
-            !PACKET_get_length_prefixed_2(&extensions, &extension)) {
-            /* This should not happen. */
-            SSLerr(SSL_F_TLS1_CHECK_DUPLICATE_EXTENSIONS, ERR_R_INTERNAL_ERROR);
-            goto done;
+    /* If sigalgs received process it. */
+    if (s->s3->tmp.peer_sigalgs) {
+        if (!tls1_process_sigalgs(s)) {
+            SSLerr(SSL_F_TLS1_SET_SERVER_SIGALGS, ERR_R_MALLOC_FAILURE);
+            al = SSL_AD_INTERNAL_ERROR;
+            goto err;
         }
+        /* Fatal error is no shared signature algorithms */
+        if (!s->cert->shared_sigalgs) {
+            SSLerr(SSL_F_TLS1_SET_SERVER_SIGALGS,
+                   SSL_R_NO_SHARED_SIGNATURE_ALGORITHMS);
+            al = SSL_AD_ILLEGAL_PARAMETER;
+            goto err;
+        }
+    } else {
+        ssl_set_default_md(s);
     }
-
-    if (PACKET_remaining(&extensions) != 0) {
-        SSLerr(SSL_F_TLS1_CHECK_DUPLICATE_EXTENSIONS, ERR_R_INTERNAL_ERROR);
-        goto done;
-    }
-    /* Sort the extensions and make sure there are no duplicates. */
-    qsort(extension_types, num_extensions, sizeof(unsigned int), compare_uint);
-    for (i = 1; i < num_extensions; i++) {
-        if (extension_types[i - 1] == extension_types[i])
-            goto done;
-    }
-    ret = 1;
- done:
-    OPENSSL_free(extension_types);
-    return ret;
+    return 1;
+ err:
+    ssl3_send_alert(s, SSL3_AL_FATAL, al);
+    return 0;
 }
 
-int ssl_add_clienthello_tlsext(SSL *s, WPACKET *pkt, int *al)
+/*
+ * Given a list of extensions that we collected earlier, find one of a given
+ * type and return it.
+ *
+ * |exts| is the set of extensions previously collected.
+ * |numexts| is the number of extensions that we have.
+ * |type| the type of the extension that we are looking for.
+ *
+ * Returns a pointer to the found RAW_EXTENSION data, or NULL if not found.
+ */
+RAW_EXTENSION *tls_get_extension_by_type(RAW_EXTENSION *exts, size_t numexts,
+                                         unsigned int type)
 {
-#ifndef OPENSSL_NO_EC
-    const unsigned char *pcurves = NULL;
-    size_t num_curves = 0;
-    int using_ecc = 0;
-    int min_version, max_version, reason;
-
-    /* See if we support any ECC ciphersuites */
-    if ((s->version >= TLS1_VERSION && s->version <= TLS1_3_VERSION)
-            || SSL_IS_DTLS(s)) {
-        int i;
-        unsigned long alg_k, alg_a;
-        STACK_OF(SSL_CIPHER) *cipher_stack = SSL_get_ciphers(s);
-
-        for (i = 0; i < sk_SSL_CIPHER_num(cipher_stack); i++) {
-            const SSL_CIPHER *c = sk_SSL_CIPHER_value(cipher_stack, i);
-
-            alg_k = c->algorithm_mkey;
-            alg_a = c->algorithm_auth;
-            if ((alg_k & (SSL_kECDHE | SSL_kECDHEPSK))
-                || (alg_a & SSL_aECDSA)
-                || c->min_tls >= TLS1_3_VERSION) {
-                using_ecc = 1;
-                break;
-            }
-        }
-    }
-#else
-    if (SSL_IS_TLS13(s)) {
-        /* Shouldn't happen! */
-        SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-        return 0;
-    }
-#endif
-
-    /* Add RI if renegotiating */
-    if (s->renegotiate) {
-        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_renegotiate)
-                || !WPACKET_start_sub_packet_u16(pkt)
-                || !WPACKET_sub_memcpy_u8(pkt, s->s3->previous_client_finished,
-                                   s->s3->previous_client_finished_len)
-                || !WPACKET_close(pkt)) {
-            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return 0;
-        }
-    }
-    /* Only add RI for SSLv3 */
-    if (s->client_version == SSL3_VERSION)
-        goto done;
-
-    if (s->tlsext_hostname != NULL) {
-        /* Add TLS extension servername to the Client Hello message */
-        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_server_name)
-                   /* Sub-packet for server_name extension */
-                || !WPACKET_start_sub_packet_u16(pkt)
-                   /* Sub-packet for servername list (always 1 hostname)*/
-                || !WPACKET_start_sub_packet_u16(pkt)
-                || !WPACKET_put_bytes_u8(pkt, TLSEXT_NAMETYPE_host_name)
-                || !WPACKET_sub_memcpy_u16(pkt, s->tlsext_hostname,
-                                           strlen(s->tlsext_hostname))
-                || !WPACKET_close(pkt)
-                || !WPACKET_close(pkt)) {
-            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return 0;
-        }
-    }
-#ifndef OPENSSL_NO_SRP
-    /* Add SRP username if there is one */
-    if (s->srp_ctx.login != NULL) {
-        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_srp)
-                   /* Sub-packet for SRP extension */
-                || !WPACKET_start_sub_packet_u16(pkt)
-                || !WPACKET_start_sub_packet_u8(pkt)
-                   /* login must not be zero...internal error if so */
-                || !WPACKET_set_flags(pkt, WPACKET_FLAGS_NON_ZERO_LENGTH)
-                || !WPACKET_memcpy(pkt, s->srp_ctx.login,
-                                   strlen(s->srp_ctx.login))
-                || !WPACKET_close(pkt)
-                || !WPACKET_close(pkt)) {
-            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return 0;
-        }
-    }
-#endif
-
-#ifndef OPENSSL_NO_EC
-    if (using_ecc) {
-        /*
-         * Add TLS extension ECPointFormats to the ClientHello message
-         */
-        const unsigned char *pformats, *pcurvestmp;
-        size_t num_formats;
-        size_t i;
-
-        tls1_get_formatlist(s, &pformats, &num_formats);
-
-        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_ec_point_formats)
-                   /* Sub-packet for formats extension */
-                || !WPACKET_start_sub_packet_u16(pkt)
-                || !WPACKET_sub_memcpy_u8(pkt, pformats, num_formats)
-                || !WPACKET_close(pkt)) {
-            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return 0;
-        }
-
-        /*
-         * Add TLS extension supported_groups to the ClientHello message
-         */
-        /* TODO(TLS1.3): Add support for DHE groups */
-        pcurves = s->tlsext_supportedgroupslist;
-        if (!tls1_get_curvelist(s, 0, &pcurves, &num_curves)) {
-            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return 0;
-        }
-        pcurvestmp = pcurves;
+    size_t loop;
 
-        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_supported_groups)
-                   /* Sub-packet for supported_groups extension */
-                || !WPACKET_start_sub_packet_u16(pkt)
-                || !WPACKET_start_sub_packet_u16(pkt)) {
-            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return 0;
-        }
-        /* Copy curve ID if supported */
-        for (i = 0; i < num_curves; i++, pcurvestmp += 2) {
-            if (tls_curve_allowed(s, pcurves, SSL_SECOP_CURVE_SUPPORTED)) {
-                if (!WPACKET_put_bytes_u8(pkt, pcurvestmp[0])
-                    || !WPACKET_put_bytes_u8(pkt, pcurvestmp[1])) {
-                        SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT,
-                               ERR_R_INTERNAL_ERROR);
-                        return 0;
-                    }
-            }
-        }
-        if (!WPACKET_close(pkt) || !WPACKET_close(pkt)) {
-            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return 0;
-        }
+    for (loop = 0; loop < numexts; loop++) {
+        if (exts[loop].type == type)
+            return &exts[loop];
     }
-#endif                          /* OPENSSL_NO_EC */
 
-    if (tls_use_ticket(s)) {
-        size_t ticklen;
-        if (!s->new_session && s->session && s->session->tlsext_tick)
-            ticklen = s->session->tlsext_ticklen;
-        else if (s->session && s->tlsext_session_ticket &&
-                 s->tlsext_session_ticket->data) {
-            ticklen = s->tlsext_session_ticket->length;
-            s->session->tlsext_tick = OPENSSL_malloc(ticklen);
-            if (s->session->tlsext_tick == NULL) {
-                SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-                return 0;
-            }
-            memcpy(s->session->tlsext_tick,
-                   s->tlsext_session_ticket->data, ticklen);
-            s->session->tlsext_ticklen = ticklen;
-        } else
-            ticklen = 0;
-        if (ticklen == 0 && s->tlsext_session_ticket &&
-            s->tlsext_session_ticket->data == NULL)
-            goto skip_ext;
-
-        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_session_ticket)
-                || !WPACKET_sub_memcpy_u16(pkt, s->session->tlsext_tick,
-                                           ticklen)) {
-            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return 0;
-        }
-    }
- skip_ext:
-
-    if (SSL_CLIENT_USE_SIGALGS(s)) {
-        size_t salglen;
-        const unsigned char *salg;
-
-        salglen = tls12_get_psigalgs(s, &salg);
-
-        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_signature_algorithms)
-                   /* Sub-packet for sig-algs extension */
-                || !WPACKET_start_sub_packet_u16(pkt)
-                   /* Sub-packet for the actual list */
-                || !WPACKET_start_sub_packet_u16(pkt)
-                || !tls12_copy_sigalgs(s, pkt, salg, salglen)
-                || !WPACKET_close(pkt)
-                || !WPACKET_close(pkt)) {
-            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return 0;
-        }
-    }
-#ifndef OPENSSL_NO_OCSP
-    if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp) {
-        int i;
-
-        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_status_request)
-                   /* Sub-packet for status request extension */
-                || !WPACKET_start_sub_packet_u16(pkt)
-                || !WPACKET_put_bytes_u8(pkt, TLSEXT_STATUSTYPE_ocsp)
-                   /* Sub-packet for the ids */
-                || !WPACKET_start_sub_packet_u16(pkt)) {
-            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return 0;
-        }
-        for (i = 0; i < sk_OCSP_RESPID_num(s->tlsext_ocsp_ids); i++) {
-            unsigned char *idbytes;
-            int idlen;
-            OCSP_RESPID *id;
-
-            id = sk_OCSP_RESPID_value(s->tlsext_ocsp_ids, i);
-            idlen = i2d_OCSP_RESPID(id, NULL);
-            if (idlen <= 0
-                       /* Sub-packet for an individual id */
-                    || !WPACKET_sub_allocate_bytes_u16(pkt, idlen, &idbytes)
-                    || i2d_OCSP_RESPID(id, &idbytes) != idlen) {
-                SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-                return 0;
-            }
-        }
-        if (!WPACKET_close(pkt)
-                || !WPACKET_start_sub_packet_u16(pkt)) {
-            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return 0;
-        }
-        if (s->tlsext_ocsp_exts) {
-            unsigned char *extbytes;
-            int extlen = i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, NULL);
+    return NULL;
+}
 
-            if (extlen < 0) {
-                SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-                return 0;
-            }
-            if (!WPACKET_allocate_bytes(pkt, extlen, &extbytes)
-                    || i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, &extbytes)
-                       != extlen) {
-                SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-                return 0;
-           }
-        }
-        if (!WPACKET_close(pkt) || !WPACKET_close(pkt)) {
-            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return 0;
-        }
-    }
-#endif
+/*-
+ * Gets the ticket information supplied by the client if any.
+ *
+ *   hello: The parsed ClientHello data
+ *   ret: (output) on return, if a ticket was decrypted, then this is set to
+ *       point to the resulting session.
+ *
+ * If s->tls_session_secret_cb is set then we are expecting a pre-shared key
+ * ciphersuite, in which case we have no use for session tickets and one will
+ * never be decrypted, nor will s->tlsext_ticket_expected be set to 1.
+ *
+ * Returns:
+ *   -1: fatal error, either from parsing or decrypting the ticket.
+ *    0: no ticket was found (or was ignored, based on settings).
+ *    1: a zero length extension was found, indicating that the client supports
+ *       session tickets but doesn't currently have one to offer.
+ *    2: either s->tls_session_secret_cb was set, or a ticket was offered but
+ *       couldn't be decrypted because of a non-fatal error.
+ *    3: a ticket was successfully decrypted and *ret was set.
+ *
+ * Side effects:
+ *   Sets s->tlsext_ticket_expected to 1 if the server will have to issue
+ *   a new session ticket to the client because the client indicated support
+ *   (and s->tls_session_secret_cb is NULL) but the client either doesn't have
+ *   a session ticket or we couldn't use the one it gave us, or if
+ *   s->ctx->tlsext_ticket_key_cb asked to renew the client's ticket.
+ *   Otherwise, s->tlsext_ticket_expected is set to 0.
+ */
+int tls_get_ticket_from_client(SSL *s, CLIENTHELLO_MSG *hello,
+                               SSL_SESSION **ret)
+{
+    int retv;
+    size_t size;
+    RAW_EXTENSION *ticketext;
 
-#ifndef OPENSSL_NO_NEXTPROTONEG
-    if (s->ctx->next_proto_select_cb && !s->s3->tmp.finish_md_len) {
-        /*
-         * The client advertises an empty extension to indicate its support
-         * for Next Protocol Negotiation
-         */
-        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_next_proto_neg)
-                || !WPACKET_put_bytes_u16(pkt, 0)) {
-            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return 0;
-        }
-    }
-#endif
+    *ret = NULL;
+    s->tlsext_ticket_expected = 0;
 
     /*
-     * finish_md_len is non-zero during a renegotiation, so
-     * this avoids sending ALPN during the renegotiation
-     * (see longer comment below)
+     * If tickets disabled or not supported by the protocol version
+     * (e.g. TLSv1.3) behave as if no ticket present to permit stateful
+     * resumption.
      */
-    if (s->alpn_client_proto_list && !s->s3->tmp.finish_md_len) {
-        if (!WPACKET_put_bytes_u16(pkt,
-                    TLSEXT_TYPE_application_layer_protocol_negotiation)
-                   /* Sub-packet ALPN extension */
-                || !WPACKET_start_sub_packet_u16(pkt)
-                || !WPACKET_sub_memcpy_u16(pkt, s->alpn_client_proto_list,
-                                           s->alpn_client_proto_list_len)
-                || !WPACKET_close(pkt)) {
-            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return 0;
-        }
-        s->s3->alpn_sent = 1;
-    }
-#ifndef OPENSSL_NO_SRTP
-    if (SSL_IS_DTLS(s) && SSL_get_srtp_profiles(s)) {
-        STACK_OF(SRTP_PROTECTION_PROFILE) *clnt = SSL_get_srtp_profiles(s);
-        SRTP_PROTECTION_PROFILE *prof;
-        int i, ct;
-
-        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_use_srtp)
-                   /* Sub-packet for SRTP extension */
-                || !WPACKET_start_sub_packet_u16(pkt)
-                   /* Sub-packet for the protection profile list */
-                || !WPACKET_start_sub_packet_u16(pkt)) {
-            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return 0;
-        }
-        ct = sk_SRTP_PROTECTION_PROFILE_num(clnt);
-        for (i = 0; i < ct; i++) {
-            prof = sk_SRTP_PROTECTION_PROFILE_value(clnt, i);
-            if (prof == NULL || !WPACKET_put_bytes_u16(pkt, prof->id)) {
-                SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-                return 0;
-            }
-        }
-        if (!WPACKET_close(pkt)
-                   /* Add an empty use_mki value */
-                || !WPACKET_put_bytes_u8(pkt, 0)
-                || !WPACKET_close(pkt)) {
-            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return 0;
-        }
-    }
-#endif
-    custom_ext_init(&s->cert->cli_ext);
-    /* Add custom TLS Extensions to ClientHello */
-    if (!custom_ext_add(s, 0, pkt, al)) {
-        SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+    if (s->version <= SSL3_VERSION || !tls_use_ticket(s))
         return 0;
-    }
-
-    if (!(s->options & SSL_OP_NO_ENCRYPT_THEN_MAC)) {
-        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_encrypt_then_mac)
-            || !WPACKET_put_bytes_u16(pkt, 0)) {
-            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return 0;
-        }
-    }
-
-#ifndef OPENSSL_NO_CT
-    if (s->ct_validation_callback != NULL) {
-        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_signed_certificate_timestamp)
-                || !WPACKET_put_bytes_u16(pkt, 0)) {
-            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return 0;
-        }
-    }
-#endif
 
-    if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_extended_master_secret)
-            || !WPACKET_put_bytes_u16(pkt, 0)) {
-        SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+    ticketext = &hello->pre_proc_exts[TLSEXT_IDX_session_ticket];
+    if (!ticketext->present)
         return 0;
-    }
 
-    reason = ssl_get_client_min_max_version(s, &min_version, &max_version);
-    if (reason != 0) {
-        SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, reason);
-        return 0;
+    size = PACKET_remaining(&ticketext->data);
+    if (size == 0) {
+        /*
+         * The client will accept a ticket but doesn't currently have
+         * one.
+         */
+        s->tlsext_ticket_expected = 1;
+        return 1;
     }
-
-    /* TLS1.3 specific extensions */
-    if (!SSL_IS_DTLS(s) && max_version >= TLS1_3_VERSION) {
-        int currv;
-        size_t i, sharessent = 0;
-
-        /* TODO(TLS1.3): Should we add this extension for versions < TLS1.3? */
-        /* supported_versions extension */
-        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_supported_versions)
-                || !WPACKET_start_sub_packet_u16(pkt)
-                || !WPACKET_start_sub_packet_u8(pkt)) {
-            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return 0;
-        }
-
+    if (s->tls_session_secret_cb) {
         /*
-         * TODO(TLS1.3): There is some discussion on the TLS list as to wheter
-         * we should include versions <TLS1.2. For the moment we do. To be
-         * reviewed later.
+         * Indicate that the ticket couldn't be decrypted rather than
+         * generating the session from ticket now, trigger
+         * abbreviated handshake based on external mechanism to
+         * calculate the master secret later.
          */
-        for (currv = max_version; currv >= min_version; currv--) {
-            /* TODO(TLS1.3): Remove this first if clause prior to release!! */
-            if (currv == TLS1_3_VERSION) {
-                if (!WPACKET_put_bytes_u16(pkt, TLS1_3_VERSION_DRAFT)) {
-                    SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT,
-                           ERR_R_INTERNAL_ERROR);
-                    return 0;
-                }
-            } else if (!WPACKET_put_bytes_u16(pkt, currv)) {
-                SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-                return 0;
-            }
-        }
-        if (!WPACKET_close(pkt) || !WPACKET_close(pkt)) {
-            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return 0;
-        }
+        return 2;
+    }
 
+    retv = tls_decrypt_ticket(s, PACKET_data(&ticketext->data), size,
+                              hello->session_id, hello->session_id_len, ret);
+    switch (retv) {
+    case 2:            /* ticket couldn't be decrypted */
+        s->tlsext_ticket_expected = 1;
+        return 2;
 
-        /* key_share extension */
-        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_key_share)
-                   /* Extension data sub-packet */
-                || !WPACKET_start_sub_packet_u16(pkt)
-                   /* KeyShare list sub-packet */
-                || !WPACKET_start_sub_packet_u16(pkt)) {
-            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return 0;
-        }
-
-        /*
-         * TODO(TLS1.3): Make the number of key_shares sent configurable. For
-         * now, just send one
-         */
-        for (i = 0; i < num_curves && sharessent < 1; i++, pcurves += 2) {
-            unsigned char *encodedPoint = NULL;
-            unsigned int curve_id = 0;
-            EVP_PKEY *key_share_key = NULL;
-            size_t encodedlen;
-
-            if (!tls_curve_allowed(s, pcurves, SSL_SECOP_CURVE_SUPPORTED))
-                continue;
-
-            if (s->s3->tmp.pkey != NULL) {
-                /* Shouldn't happen! */
-                SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT,
-                       ERR_R_INTERNAL_ERROR);
-                return 0;
-            }
-
-            /* Generate a key for this key_share */
-            curve_id = (pcurves[0] << 8) | pcurves[1];
-            key_share_key = ssl_generate_pkey_curve(curve_id);
-            if (key_share_key == NULL) {
-                SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_EVP_LIB);
-                return 0;
-            }
-
-            /* Encode the public key. */
-            encodedlen = EVP_PKEY_get1_tls_encodedpoint(key_share_key,
-                                                        &encodedPoint);
-            if (encodedlen == 0) {
-                SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_EC_LIB);
-                EVP_PKEY_free(key_share_key);
-                return 0;
-            }
-
-            /* Create KeyShareEntry */
-            if (!WPACKET_put_bytes_u16(pkt, curve_id)
-                    || !WPACKET_sub_memcpy_u16(pkt, encodedPoint, encodedlen)) {
-                SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT,
-                       ERR_R_INTERNAL_ERROR);
-                EVP_PKEY_free(key_share_key);
-                OPENSSL_free(encodedPoint);
-                return 0;
-            }
-
-            /*
-             * TODO(TLS1.3): When changing to send more than one key_share we're
-             * going to need to be able to save more than one EVP_PKEY. For now
-             * we reuse the existing tmp.pkey
-             */
-            s->s3->group_id = curve_id;
-            s->s3->tmp.pkey = key_share_key;
-            sharessent++;
-            OPENSSL_free(encodedPoint);
-        }
-        if (!WPACKET_close(pkt) || !WPACKET_close(pkt)) {
-            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return 0;
-        }
-    }
-
-    /*
-     * Add padding to workaround bugs in F5 terminators. See
-     * https://tools.ietf.org/html/draft-agl-tls-padding-03 NB: because this
-     * code works out the length of all existing extensions it MUST always
-     * appear last.
-     */
-    if (s->options & SSL_OP_TLSEXT_PADDING) {
-        unsigned char *padbytes;
-        size_t hlen;
-
-        if (!WPACKET_get_total_written(pkt, &hlen)) {
-            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return 0;
-        }
-
-        if (hlen > 0xff && hlen < 0x200) {
-            hlen = 0x200 - hlen;
-            if (hlen >= 4)
-                hlen -= 4;
-            else
-                hlen = 0;
-
-            if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_padding)
-                    || !WPACKET_sub_allocate_bytes_u16(pkt, hlen, &padbytes)) {
-                SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-                return 0;
-            }
-            memset(padbytes, 0, hlen);
-        }
-    }
-
- done:
-    return 1;
-}
-
-/*
- * Add the key_share extension.
- *
- * Returns 1 on success or 0 on failure.
- */
-static int add_client_key_share_ext(SSL *s, WPACKET *pkt, int *al)
-{
-    unsigned char *encodedPoint;
-    size_t encoded_pt_len = 0;
-    EVP_PKEY *ckey = s->s3->peer_tmp, *skey = NULL;
-
-    if (ckey == NULL) {
-        SSLerr(SSL_F_ADD_CLIENT_KEY_SHARE_EXT, ERR_R_INTERNAL_ERROR);
-        return 0;
-    }
-
-    if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_key_share)
-            || !WPACKET_start_sub_packet_u16(pkt)
-            || !WPACKET_put_bytes_u16(pkt, s->s3->group_id)) {
-        SSLerr(SSL_F_ADD_CLIENT_KEY_SHARE_EXT, ERR_R_INTERNAL_ERROR);
-        return 0;
-    }
-
-    skey = ssl_generate_pkey(ckey);
-    if (skey == NULL) {
-        SSLerr(SSL_F_ADD_CLIENT_KEY_SHARE_EXT, ERR_R_MALLOC_FAILURE);
-        return 0;
-    }
-
-    /* Generate encoding of server key */
-    encoded_pt_len = EVP_PKEY_get1_tls_encodedpoint(skey, &encodedPoint);
-    if (encoded_pt_len == 0) {
-        SSLerr(SSL_F_ADD_CLIENT_KEY_SHARE_EXT, ERR_R_EC_LIB);
-        EVP_PKEY_free(skey);
-        return 0;
-    }
-
-    if (!WPACKET_sub_memcpy_u16(pkt, encodedPoint, encoded_pt_len)
-            || !WPACKET_close(pkt)) {
-        SSLerr(SSL_F_ADD_CLIENT_KEY_SHARE_EXT, ERR_R_INTERNAL_ERROR);
-        EVP_PKEY_free(skey);
-        OPENSSL_free(encodedPoint);
-        return 0;
-    }
-    OPENSSL_free(encodedPoint);
-
-    /* This causes the crypto state to be updated based on the derived keys */
-    s->s3->tmp.pkey = skey;
-    if (ssl_derive(s, skey, ckey, 1) == 0) {
-        *al = SSL_AD_INTERNAL_ERROR;
-        SSLerr(SSL_F_ADD_CLIENT_KEY_SHARE_EXT, ERR_R_INTERNAL_ERROR);
-        return 0;
-    }
-
-    return 1;
-}
-
-int ssl_add_serverhello_tlsext(SSL *s, WPACKET *pkt, int *al)
-{
-#ifndef OPENSSL_NO_NEXTPROTONEG
-    int next_proto_neg_seen;
-#endif
-#ifndef OPENSSL_NO_EC
-    unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
-    unsigned long alg_a = s->s3->tmp.new_cipher->algorithm_auth;
-    int using_ecc = (alg_k & SSL_kECDHE) || (alg_a & SSL_aECDSA);
-    using_ecc = using_ecc && (s->session->tlsext_ecpointformatlist != NULL);
-#endif
-
-    if (!WPACKET_start_sub_packet_u16(pkt)
-            || !WPACKET_set_flags(pkt, WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH)) {
-        SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-        return 0;
-    }
-
-    if (s->s3->send_connection_binding &&
-            !ssl_add_serverhello_renegotiate_ext(s, pkt)) {
-        SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-        return 0;
-    }
-
-    /* Only add RI for SSLv3 */
-    if (s->version == SSL3_VERSION)
-        goto done;
-
-    if (!s->hit && s->servername_done == 1
-            && s->session->tlsext_hostname != NULL) {
-        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_server_name)
-                || !WPACKET_put_bytes_u16(pkt, 0)) {
-            SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return 0;
-        }
-    }
-#ifndef OPENSSL_NO_EC
-    if (using_ecc) {
-        const unsigned char *plist;
-        size_t plistlen;
-        /*
-         * Add TLS extension ECPointFormats to the ServerHello message
-         */
-        tls1_get_formatlist(s, &plist, &plistlen);
-
-        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_ec_point_formats)
-                || !WPACKET_start_sub_packet_u16(pkt)
-                || !WPACKET_sub_memcpy_u8(pkt, plist, plistlen)
-                || !WPACKET_close(pkt)) {
-            SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return 0;
-        }
-    }
-    /*
-     * Currently the server should not respond with a SupportedCurves
-     * extension
-     */
-#endif                          /* OPENSSL_NO_EC */
-
-    if (s->tlsext_ticket_expected && tls_use_ticket(s)) {
-        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_session_ticket)
-                || !WPACKET_put_bytes_u16(pkt, 0)) {
-            SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return 0;
-        }
-    } else {
-        /*
-         * if we don't add the above TLSEXT, we can't add a session ticket
-         * later
-         */
-        s->tlsext_ticket_expected = 0;
-    }
-
-    if (s->tlsext_status_expected) {
-        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_status_request)
-                || !WPACKET_put_bytes_u16(pkt, 0)) {
-            SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return 0;
-        }
-    }
-#ifndef OPENSSL_NO_SRTP
-    if (SSL_IS_DTLS(s) && s->srtp_profile) {
-        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_use_srtp)
-                || !WPACKET_start_sub_packet_u16(pkt)
-                || !WPACKET_put_bytes_u16(pkt, 2)
-                || !WPACKET_put_bytes_u16(pkt, s->srtp_profile->id)
-                || !WPACKET_put_bytes_u8(pkt, 0)
-                || !WPACKET_close(pkt)) {
-            SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return 0;
-        }
-    }
-#endif
-
-    if (((s->s3->tmp.new_cipher->id & 0xFFFF) == 0x80
-         || (s->s3->tmp.new_cipher->id & 0xFFFF) == 0x81)
-        && (SSL_get_options(s) & SSL_OP_CRYPTOPRO_TLSEXT_BUG)) {
-        const unsigned char cryptopro_ext[36] = {
-            0xfd, 0xe8,         /* 65000 */
-            0x00, 0x20,         /* 32 bytes length */
-            0x30, 0x1e, 0x30, 0x08, 0x06, 0x06, 0x2a, 0x85,
-            0x03, 0x02, 0x02, 0x09, 0x30, 0x08, 0x06, 0x06,
-            0x2a, 0x85, 0x03, 0x02, 0x02, 0x16, 0x30, 0x08,
-            0x06, 0x06, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x17
-        };
-        if (!WPACKET_memcpy(pkt, cryptopro_ext, sizeof(cryptopro_ext))) {
-            SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return 0;
-        }
-    }
-
-#ifndef OPENSSL_NO_NEXTPROTONEG
-    next_proto_neg_seen = s->s3->next_proto_neg_seen;
-    s->s3->next_proto_neg_seen = 0;
-    if (next_proto_neg_seen && s->ctx->next_protos_advertised_cb) {
-        const unsigned char *npa;
-        unsigned int npalen;
-        int r;
-
-        r = s->ctx->next_protos_advertised_cb(s, &npa, &npalen,
-                                              s->
-                                              ctx->next_protos_advertised_cb_arg);
-        if (r == SSL_TLSEXT_ERR_OK) {
-            if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_next_proto_neg)
-                    || !WPACKET_sub_memcpy_u16(pkt, npa, npalen)) {
-                SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-                return 0;
-            }
-            s->s3->next_proto_neg_seen = 1;
-        }
-    }
-#endif
-
-    if (SSL_IS_TLS13(s) && !s->hit && !add_client_key_share_ext(s, pkt, al))
-        return 0;
-
-    if (!custom_ext_add(s, 1, pkt, al)) {
-        SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-        return 0;
-    }
-
-    if (s->s3->flags & TLS1_FLAGS_ENCRYPT_THEN_MAC) {
-        /*
-         * Don't use encrypt_then_mac if AEAD or RC4 might want to disable
-         * for other cases too.
-         */
-        if (s->s3->tmp.new_cipher->algorithm_mac == SSL_AEAD
-            || s->s3->tmp.new_cipher->algorithm_enc == SSL_RC4
-            || s->s3->tmp.new_cipher->algorithm_enc == SSL_eGOST2814789CNT
-            || s->s3->tmp.new_cipher->algorithm_enc == SSL_eGOST2814789CNT12)
-            s->s3->flags &= ~TLS1_FLAGS_ENCRYPT_THEN_MAC;
-        else {
-            if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_encrypt_then_mac)
-                    || !WPACKET_put_bytes_u16(pkt, 0)) {
-                SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-                return 0;
-            }
-        }
-    }
-    if (s->s3->flags & TLS1_FLAGS_RECEIVED_EXTMS) {
-        if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_extended_master_secret)
-                || !WPACKET_put_bytes_u16(pkt, 0)) {
-            SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return 0;
-        }
-    }
-
-    if (s->s3->alpn_selected != NULL) {
-        if (!WPACKET_put_bytes_u16(pkt,
-                    TLSEXT_TYPE_application_layer_protocol_negotiation)
-                || !WPACKET_start_sub_packet_u16(pkt)
-                || !WPACKET_start_sub_packet_u16(pkt)
-                || !WPACKET_sub_memcpy_u8(pkt, s->s3->alpn_selected,
-                                          s->s3->alpn_selected_len)
-                || !WPACKET_close(pkt)
-                || !WPACKET_close(pkt)) {
-            SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-            return 0;
-        }
-    }
-
- done:
-    if (!WPACKET_close(pkt)) {
-        SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-        return 0;
-    }
-    return 1;
-}
-
-/*
- * Save the ALPN extension in a ClientHello.
- * pkt: the contents of the ALPN extension, not including type and length.
- * al: a pointer to the  alert value to send in the event of a failure.
- * returns: 1 on success, 0 on error.
- */
-static int tls1_alpn_handle_client_hello(SSL *s, PACKET *pkt, int *al)
-{
-    PACKET protocol_list, save_protocol_list, protocol;
-
-    *al = SSL_AD_DECODE_ERROR;
-
-    if (!PACKET_as_length_prefixed_2(pkt, &protocol_list)
-        || PACKET_remaining(&protocol_list) < 2) {
-        return 0;
-    }
-
-    save_protocol_list = protocol_list;
-    do {
-        /* Protocol names can't be empty. */
-        if (!PACKET_get_length_prefixed_1(&protocol_list, &protocol)
-            || PACKET_remaining(&protocol) == 0) {
-            return 0;
-        }
-    } while (PACKET_remaining(&protocol_list) != 0);
-
-    if (!PACKET_memdup(&save_protocol_list,
-                       &s->s3->alpn_proposed, &s->s3->alpn_proposed_len)) {
-        *al = TLS1_AD_INTERNAL_ERROR;
-        return 0;
-    }
-
-    return 1;
-}
-
-/*
- * Process the ALPN extension in a ClientHello.
- * al: a pointer to the alert value to send in the event of a failure.
- * returns 1 on success, 0 on error.
- */
-static int tls1_alpn_handle_client_hello_late(SSL *s, int *al)
-{
-    const unsigned char *selected = NULL;
-    unsigned char selected_len = 0;
-
-    if (s->ctx->alpn_select_cb != NULL && s->s3->alpn_proposed != NULL) {
-        int r = s->ctx->alpn_select_cb(s, &selected, &selected_len,
-                                       s->s3->alpn_proposed,
-                                       (unsigned int)s->s3->alpn_proposed_len,
-                                       s->ctx->alpn_select_cb_arg);
-
-        if (r == SSL_TLSEXT_ERR_OK) {
-            OPENSSL_free(s->s3->alpn_selected);
-            s->s3->alpn_selected = OPENSSL_memdup(selected, selected_len);
-            if (s->s3->alpn_selected == NULL) {
-                *al = SSL_AD_INTERNAL_ERROR;
-                return 0;
-            }
-            s->s3->alpn_selected_len = selected_len;
-#ifndef OPENSSL_NO_NEXTPROTONEG
-            /* ALPN takes precedence over NPN. */
-            s->s3->next_proto_neg_seen = 0;
-#endif
-        } else {
-            *al = SSL_AD_NO_APPLICATION_PROTOCOL;
-            return 0;
-        }
-    }
-
-    return 1;
-}
-
-#ifndef OPENSSL_NO_EC
-/*-
- * ssl_check_for_safari attempts to fingerprint Safari using OS X
- * SecureTransport using the TLS extension block in |hello|.
- * Safari, since 10.6, sends exactly these extensions, in this order:
- *   SNI,
- *   elliptic_curves
- *   ec_point_formats
- *
- * We wish to fingerprint Safari because they broke ECDHE-ECDSA support in 10.8,
- * but they advertise support. So enabling ECDHE-ECDSA ciphers breaks them.
- * Sadly we cannot differentiate 10.6, 10.7 and 10.8.4 (which work), from
- * 10.8..10.8.3 (which don't work).
- */
-static void ssl_check_for_safari(SSL *s, const CLIENTHELLO_MSG *hello)
-{
-    unsigned int type;
-    PACKET sni, tmppkt;
-    size_t ext_len;
-
-    static const unsigned char kSafariExtensionsBlock[] = {
-        0x00, 0x0a,             /* elliptic_curves extension */
-        0x00, 0x08,             /* 8 bytes */
-        0x00, 0x06,             /* 6 bytes of curve ids */
-        0x00, 0x17,             /* P-256 */
-        0x00, 0x18,             /* P-384 */
-        0x00, 0x19,             /* P-521 */
-
-        0x00, 0x0b,             /* ec_point_formats */
-        0x00, 0x02,             /* 2 bytes */
-        0x01,                   /* 1 point format */
-        0x00,                   /* uncompressed */
-        /* The following is only present in TLS 1.2 */
-        0x00, 0x0d,             /* signature_algorithms */
-        0x00, 0x0c,             /* 12 bytes */
-        0x00, 0x0a,             /* 10 bytes */
-        0x05, 0x01,             /* SHA-384/RSA */
-        0x04, 0x01,             /* SHA-256/RSA */
-        0x02, 0x01,             /* SHA-1/RSA */
-        0x04, 0x03,             /* SHA-256/ECDSA */
-        0x02, 0x03,             /* SHA-1/ECDSA */
-    };
-
-    /* Length of the common prefix (first two extensions). */
-    static const size_t kSafariCommonExtensionsLength = 18;
-
-    tmppkt = hello->extensions;
-
-    if (!PACKET_forward(&tmppkt, 2)
-        || !PACKET_get_net_2(&tmppkt, &type)
-        || !PACKET_get_length_prefixed_2(&tmppkt, &sni)) {
-        return;
-    }
-
-    if (type != TLSEXT_TYPE_server_name)
-        return;
-
-    ext_len = TLS1_get_client_version(s) >= TLS1_2_VERSION ?
-        sizeof(kSafariExtensionsBlock) : kSafariCommonExtensionsLength;
-
-    s->s3->is_probably_safari = PACKET_equal(&tmppkt, kSafariExtensionsBlock,
-                                             ext_len);
-}
-#endif                          /* !OPENSSL_NO_EC */
-
-
-/*
- * Process the supported_groups extension if present. Returns success if the
- * extension is absent, or if it has been successfully processed.
- *
- * Returns 1 on success or 0 on failure
- */
-static int tls_process_supported_groups(SSL *s, CLIENTHELLO_MSG *hello)
-{
-#ifndef OPENSSL_NO_EC
-    PACKET supported_groups_list;
-    RAW_EXTENSION *suppgroups = tls_get_extension_by_type(hello->pre_proc_exts,
-                                    hello->num_extensions,
-                                    TLSEXT_TYPE_supported_groups);
-
-    if (suppgroups == NULL)
-        return 1;
-
-    /* Each group is 2 bytes and we must have at least 1. */
-    if (!PACKET_as_length_prefixed_2(&suppgroups->data,
-                                     &supported_groups_list)
-        || PACKET_remaining(&supported_groups_list) == 0
-        || (PACKET_remaining(&supported_groups_list) % 2) != 0) {
-        return 0;
-    }
-
-    if (!s->hit
-            && !PACKET_memdup(&supported_groups_list,
-                              &s->session->tlsext_supportedgroupslist,
-                              &s->session->tlsext_supportedgroupslist_length)) {
-        return 0;
-    }
-#endif
-    return 1;
-}
-
-/*
- * Checks a list of |groups| to determine if the |group_id| is in it. If it is
- * and |checkallow| is 1 then additionally check if the group is allowed to be
- * used. Returns 1 if the group is in the list (and allowed if |checkallow| is
- * 1) or 0 otherwise.
- */
-static int check_in_list(SSL *s, unsigned int group_id,
-                         const unsigned char *groups, size_t num_groups,
-                         int checkallow)
-{
-    size_t i;
-
-    if (groups == NULL || num_groups == 0)
-        return 0;
-
-    for (i = 0; i < num_groups; i++, groups += 2) {
-        unsigned int share_id = (groups[0] << 8) | (groups[1]);
-
-        if (group_id == share_id
-                && (!checkallow || tls_curve_allowed(s, groups,
-                                                     SSL_SECOP_CURVE_CHECK))) {
-            break;
-        }
-    }
-
-    /* If i == num_groups then not in the list */
-    return i < num_groups;
-}
-
-/*
- * Process a key_share extension received in the ClientHello. |pkt| contains
- * the raw PACKET data for the extension. Returns 1 on success or 0 on failure.
- * If a failure occurs then |*al| is set to an appropriate alert value.
- */
-static int process_key_share_ext(SSL *s, PACKET *pkt, int *al)
-{
-    unsigned int group_id;
-    PACKET key_share_list, encoded_pt;
-    const unsigned char *clntcurves, *srvrcurves;
-    size_t clnt_num_curves, srvr_num_curves;
-    int group_nid, found = 0;
-    unsigned int curve_flags;
-
-    /* Sanity check */
-    if (s->s3->peer_tmp != NULL) {
-        *al = SSL_AD_INTERNAL_ERROR;
-        SSLerr(SSL_F_PROCESS_KEY_SHARE_EXT, ERR_R_INTERNAL_ERROR);
-        return 0;
-    }
-
-    if (!PACKET_as_length_prefixed_2(pkt, &key_share_list)) {
-        *al = SSL_AD_HANDSHAKE_FAILURE;
-        SSLerr(SSL_F_PROCESS_KEY_SHARE_EXT,
-               SSL_R_LENGTH_MISMATCH);
-        return 0;
-    }
-
-    /* Get our list of supported curves */
-    if (!tls1_get_curvelist(s, 0, &srvrcurves, &srvr_num_curves)) {
-        *al = SSL_AD_INTERNAL_ERROR;
-        SSLerr(SSL_F_PROCESS_KEY_SHARE_EXT,
-               ERR_R_INTERNAL_ERROR);
-        return 0;
-    }
-
-    /* Get the clients list of supported curves */
-    if (!tls1_get_curvelist(s, 1, &clntcurves, &clnt_num_curves)) {
-        *al = SSL_AD_INTERNAL_ERROR;
-        SSLerr(SSL_F_PROCESS_KEY_SHARE_EXT,
-               ERR_R_INTERNAL_ERROR);
-        return 0;
-    }
-
-    while (PACKET_remaining(&key_share_list) > 0) {
-        if (!PACKET_get_net_2(&key_share_list, &group_id)
-                || !PACKET_get_length_prefixed_2(&key_share_list, &encoded_pt)
-                || PACKET_remaining(&encoded_pt) == 0) {
-            *al = SSL_AD_HANDSHAKE_FAILURE;
-            SSLerr(SSL_F_PROCESS_KEY_SHARE_EXT,
-                   SSL_R_LENGTH_MISMATCH);
-            return 0;
-        }
-
-        /*
-         * If we already found a suitable key_share we loop through the
-         * rest to verify the structure, but don't process them.
-         */
-        if (found)
-            continue;
-
-        /* Check if this share is in supported_groups sent from client */
-        if (!check_in_list(s, group_id, clntcurves, clnt_num_curves, 0)) {
-            *al = SSL_AD_HANDSHAKE_FAILURE;
-            SSLerr(SSL_F_PROCESS_KEY_SHARE_EXT,
-                   SSL_R_BAD_KEY_SHARE);
-            return 0;
-        }
-
-        /* Check if this share is for a group we can use */
-        if (!check_in_list(s, group_id, srvrcurves, srvr_num_curves, 1)) {
-            /* Share not suitable */
-            continue;
-        }
-
-        group_nid = tls1_ec_curve_id2nid(group_id, &curve_flags);
-
-        if (group_nid == 0) {
-            *al = SSL_AD_INTERNAL_ERROR;
-            SSLerr(SSL_F_PROCESS_KEY_SHARE_EXT,
-                   SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS);
-            return 0;
-        }
-
-        if ((curve_flags & TLS_CURVE_TYPE) == TLS_CURVE_CUSTOM) {
-            /* Can happen for some curves, e.g. X25519 */
-            EVP_PKEY *key = EVP_PKEY_new();
-
-            if (key == NULL || !EVP_PKEY_set_type(key, group_nid)) {
-                *al = SSL_AD_INTERNAL_ERROR;
-                SSLerr(SSL_F_PROCESS_KEY_SHARE_EXT, ERR_R_EVP_LIB);
-                EVP_PKEY_free(key);
-                return 0;
-            }
-            s->s3->peer_tmp = key;
-        } else {
-            /* Set up EVP_PKEY with named curve as parameters */
-            EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL);
-            if (pctx == NULL
-                    || EVP_PKEY_paramgen_init(pctx) <= 0
-                    || EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx,
-                                                              group_nid) <= 0
-                    || EVP_PKEY_paramgen(pctx, &s->s3->peer_tmp) <= 0) {
-                *al = SSL_AD_INTERNAL_ERROR;
-                SSLerr(SSL_F_PROCESS_KEY_SHARE_EXT, ERR_R_EVP_LIB);
-                EVP_PKEY_CTX_free(pctx);
-                return 0;
-            }
-            EVP_PKEY_CTX_free(pctx);
-            pctx = NULL;
-        }
-        s->s3->group_id = group_id;
-
-        if (!EVP_PKEY_set1_tls_encodedpoint(s->s3->peer_tmp,
-                PACKET_data(&encoded_pt),
-                PACKET_remaining(&encoded_pt))) {
-            *al = SSL_AD_DECODE_ERROR;
-            SSLerr(SSL_F_PROCESS_KEY_SHARE_EXT, SSL_R_BAD_ECPOINT);
-            return 0;
-        }
-
-        found = 1;
-    }
-
-    return 1;
-}
-
-/*
- * Loop through all remaining ClientHello extensions that we collected earlier
- * and haven't already processed. For each one parse it and update the SSL
- * object as required.
- *
- * Behaviour upon resumption is extension-specific. If the extension has no
- * effect during resumption, it is parsed (to verify its format) but otherwise
- * ignored.
- *
- * Returns 1 on success and 0 on failure.
- * Upon failure, sets |al| to the appropriate alert.
- */
-static int ssl_scan_clienthello_tlsext(SSL *s, CLIENTHELLO_MSG *hello, int *al)
-{
-    size_t loop;
-    int renegotiate_seen = 0;
-
-    *al = SSL_AD_DECODE_ERROR;
-    s->servername_done = 0;
-    s->tlsext_status_type = -1;
-#ifndef OPENSSL_NO_NEXTPROTONEG
-    s->s3->next_proto_neg_seen = 0;
-#endif
-
-    OPENSSL_free(s->s3->alpn_selected);
-    s->s3->alpn_selected = NULL;
-    s->s3->alpn_selected_len = 0;
-    OPENSSL_free(s->s3->alpn_proposed);
-    s->s3->alpn_proposed = NULL;
-    s->s3->alpn_proposed_len = 0;
-
-#ifndef OPENSSL_NO_EC
-    if (s->options & SSL_OP_SAFARI_ECDHE_ECDSA_BUG)
-        ssl_check_for_safari(s, hello);
-#endif                          /* !OPENSSL_NO_EC */
-
-    /* Clear any signature algorithms extension received */
-    OPENSSL_free(s->s3->tmp.peer_sigalgs);
-    s->s3->tmp.peer_sigalgs = NULL;
-    s->s3->flags &= ~TLS1_FLAGS_ENCRYPT_THEN_MAC;
-
-#ifndef OPENSSL_NO_SRP
-    OPENSSL_free(s->srp_ctx.login);
-    s->srp_ctx.login = NULL;
-#endif
-
-    s->srtp_profile = NULL;
-
-    /*
-     * We process the supported_groups extension first so that is done before
-     * we get to key_share which needs to use the information in it.
-     */
-    if (!tls_process_supported_groups(s, hello)) {
-        *al = TLS1_AD_INTERNAL_ERROR;
-        return 0;
-    }
-
-    /*
-     * We parse all extensions to ensure the ClientHello is well-formed but,
-     * unless an extension specifies otherwise, we ignore extensions upon
-     * resumption.
-     */
-    for (loop = 0; loop < hello->num_extensions; loop++) {
-        RAW_EXTENSION *currext = &hello->pre_proc_exts[loop];
-
-        if (s->tlsext_debug_cb)
-            s->tlsext_debug_cb(s, 0, currext->type,
-                               PACKET_data(&currext->data),
-                               PACKET_remaining(&currext->data),
-                               s->tlsext_debug_arg);
-
-        if (currext->type == TLSEXT_TYPE_renegotiate) {
-            if (!ssl_parse_clienthello_renegotiate_ext(s,
-                    &currext->data, al))
-                return 0;
-            renegotiate_seen = 1;
-        } else if (s->version == SSL3_VERSION) {
-        }
-/*-
- * The servername extension is treated as follows:
- *
- * - Only the hostname type is supported with a maximum length of 255.
- * - The servername is rejected if too long or if it contains zeros,
- *   in which case an fatal alert is generated.
- * - The servername field is maintained together with the session cache.
- * - When a session is resumed, the servername call back invoked in order
- *   to allow the application to position itself to the right context.
- * - The servername is acknowledged if it is new for a session or when
- *   it is identical to a previously used for the same session.
- *   Applications can control the behaviour.  They can at any time
- *   set a 'desirable' servername for a new SSL object. This can be the
- *   case for example with HTTPS when a Host: header field is received and
- *   a renegotiation is requested. In this case, a possible servername
- *   presented in the new client hello is only acknowledged if it matches
- *   the value of the Host: field.
- * - Applications must  use SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
- *   if they provide for changing an explicit servername context for the
- *   session, i.e. when the session has been established with a servername
- *   extension.
- * - On session reconnect, the servername extension may be absent.
- *
- */
-
-        else if (currext->type == TLSEXT_TYPE_server_name) {
-            unsigned int servname_type;
-            PACKET sni, hostname;
-
-            if (!PACKET_as_length_prefixed_2(&currext->data, &sni)
-                /* ServerNameList must be at least 1 byte long. */
-                || PACKET_remaining(&sni) == 0) {
-                return 0;
-            }
-
-            /*
-             * Although the server_name extension was intended to be
-             * extensible to new name types, RFC 4366 defined the
-             * syntax inextensibility and OpenSSL 1.0.x parses it as
-             * such.
-             * RFC 6066 corrected the mistake but adding new name types
-             * is nevertheless no longer feasible, so act as if no other
-             * SNI types can exist, to simplify parsing.
-             *
-             * Also note that the RFC permits only one SNI value per type,
-             * i.e., we can only have a single hostname.
-             */
-            if (!PACKET_get_1(&sni, &servname_type)
-                || servname_type != TLSEXT_NAMETYPE_host_name
-                || !PACKET_as_length_prefixed_2(&sni, &hostname)) {
-                return 0;
-            }
-
-            if (!s->hit) {
-                if (PACKET_remaining(&hostname) > TLSEXT_MAXLEN_host_name) {
-                    *al = TLS1_AD_UNRECOGNIZED_NAME;
-                    return 0;
-                }
-
-                if (PACKET_contains_zero_byte(&hostname)) {
-                    *al = TLS1_AD_UNRECOGNIZED_NAME;
-                    return 0;
-                }
-
-                if (!PACKET_strndup(&hostname, &s->session->tlsext_hostname)) {
-                    *al = TLS1_AD_INTERNAL_ERROR;
-                    return 0;
-                }
-
-                s->servername_done = 1;
-            } else {
-                /*
-                 * TODO(openssl-team): if the SNI doesn't match, we MUST
-                 * fall back to a full handshake.
-                 */
-                s->servername_done = s->session->tlsext_hostname
-                    && PACKET_equal(&hostname, s->session->tlsext_hostname,
-                                    strlen(s->session->tlsext_hostname));
-            }
-        }
-#ifndef OPENSSL_NO_SRP
-        else if (currext->type == TLSEXT_TYPE_srp) {
-            PACKET srp_I;
-
-            if (!PACKET_as_length_prefixed_1(&currext->data, &srp_I))
-                return 0;
-
-            if (PACKET_contains_zero_byte(&srp_I))
-                return 0;
-
-            /*
-             * TODO(openssl-team): currently, we re-authenticate the user
-             * upon resumption. Instead, we MUST ignore the login.
-             */
-            if (!PACKET_strndup(&srp_I, &s->srp_ctx.login)) {
-                *al = TLS1_AD_INTERNAL_ERROR;
-                return 0;
-            }
-        }
-#endif
-
-#ifndef OPENSSL_NO_EC
-        else if (currext->type == TLSEXT_TYPE_ec_point_formats) {
-            PACKET ec_point_format_list;
-
-            if (!PACKET_as_length_prefixed_1(&currext->data,
-                                             &ec_point_format_list)
-                || PACKET_remaining(&ec_point_format_list) == 0) {
-                return 0;
-            }
-
-            if (!s->hit) {
-                if (!PACKET_memdup(&ec_point_format_list,
-                                   &s->session->tlsext_ecpointformatlist,
-                                   &s->
-                                   session->tlsext_ecpointformatlist_length)) {
-                    *al = TLS1_AD_INTERNAL_ERROR;
-                    return 0;
-                }
-            }
-        }
-#endif                          /* OPENSSL_NO_EC */
-        else if (currext->type == TLSEXT_TYPE_session_ticket
-                && !SSL_IS_TLS13(s)) {
-            if (s->tls_session_ticket_ext_cb &&
-                !s->tls_session_ticket_ext_cb(s,
-                    PACKET_data(&currext->data),
-                    PACKET_remaining(&currext->data),
-                    s->tls_session_ticket_ext_cb_arg)) {
-                *al = TLS1_AD_INTERNAL_ERROR;
-                return 0;
-            }
-        } else if (currext->type == TLSEXT_TYPE_signature_algorithms) {
-            PACKET supported_sig_algs;
-
-            if (!PACKET_as_length_prefixed_2(&currext->data,
-                                             &supported_sig_algs)
-                || (PACKET_remaining(&supported_sig_algs) % 2) != 0
-                || PACKET_remaining(&supported_sig_algs) == 0) {
-                return 0;
-            }
-
-            if (!s->hit) {
-                if (!tls1_save_sigalgs(s, PACKET_data(&supported_sig_algs),
-                                       PACKET_remaining(&supported_sig_algs))) {
-                    return 0;
-                }
-            }
-        } else if (currext->type == TLSEXT_TYPE_status_request) {
-            if (!PACKET_get_1(&currext->data,
-                              (unsigned int *)&s->tlsext_status_type)) {
-                return 0;
-            }
-#ifndef OPENSSL_NO_OCSP
-            if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp) {
-                const unsigned char *ext_data;
-                PACKET responder_id_list, exts;
-                if (!PACKET_get_length_prefixed_2
-                    (&currext->data, &responder_id_list))
-                    return 0;
-
-                /*
-                 * We remove any OCSP_RESPIDs from a previous handshake
-                 * to prevent unbounded memory growth - CVE-2016-6304
-                 */
-                sk_OCSP_RESPID_pop_free(s->tlsext_ocsp_ids,
-                                        OCSP_RESPID_free);
-                if (PACKET_remaining(&responder_id_list) > 0) {
-                    s->tlsext_ocsp_ids = sk_OCSP_RESPID_new_null();
-                    if (s->tlsext_ocsp_ids == NULL) {
-                        *al = SSL_AD_INTERNAL_ERROR;
-                        return 0;
-                    }
-                } else {
-                    s->tlsext_ocsp_ids = NULL;
-                }
-
-                while (PACKET_remaining(&responder_id_list) > 0) {
-                    OCSP_RESPID *id;
-                    PACKET responder_id;
-                    const unsigned char *id_data;
-
-                    if (!PACKET_get_length_prefixed_2(&responder_id_list,
-                                                      &responder_id)
-                        || PACKET_remaining(&responder_id) == 0) {
-                        return 0;
-                    }
-
-                    id_data = PACKET_data(&responder_id);
-                    /* TODO(size_t): Convert d2i_* to size_t */
-                    id = d2i_OCSP_RESPID(NULL, &id_data,
-                                         (int)PACKET_remaining(&responder_id));
-                    if (id == NULL)
-                        return 0;
-
-                    if (id_data != PACKET_end(&responder_id)) {
-                        OCSP_RESPID_free(id);
-                        return 0;
-                    }
-
-                    if (!sk_OCSP_RESPID_push(s->tlsext_ocsp_ids, id)) {
-                        OCSP_RESPID_free(id);
-                        *al = SSL_AD_INTERNAL_ERROR;
-                        return 0;
-                    }
-                }
-
-                /* Read in request_extensions */
-                if (!PACKET_as_length_prefixed_2(
-                        &currext->data, &exts))
-                    return 0;
-
-                if (PACKET_remaining(&exts) > 0) {
-                    ext_data = PACKET_data(&exts);
-                    sk_X509_EXTENSION_pop_free(s->tlsext_ocsp_exts,
-                                               X509_EXTENSION_free);
-                    s->tlsext_ocsp_exts =
-                        d2i_X509_EXTENSIONS(NULL, &ext_data,
-                                            (int)PACKET_remaining(&exts));
-                    if (s->tlsext_ocsp_exts == NULL
-                        || ext_data != PACKET_end(&exts)) {
-                        return 0;
-                    }
-                }
-            } else
-#endif
-            {
-                /*
-                 * We don't know what to do with any other type so ignore it.
-                 */
-                s->tlsext_status_type = -1;
-            }
-        }
-#ifndef OPENSSL_NO_NEXTPROTONEG
-        else if (currext->type == TLSEXT_TYPE_next_proto_neg
-                 && s->s3->tmp.finish_md_len == 0) {
-            /*-
-             * We shouldn't accept this extension on a
-             * renegotiation.
-             *
-             * s->new_session will be set on renegotiation, but we
-             * probably shouldn't rely that it couldn't be set on
-             * the initial renegotiation too in certain cases (when
-             * there's some other reason to disallow resuming an
-             * earlier session -- the current code won't be doing
-             * anything like that, but this might change).
-             *
-             * A valid sign that there's been a previous handshake
-             * in this connection is if s->s3->tmp.finish_md_len >
-             * 0.  (We are talking about a check that will happen
-             * in the Hello protocol round, well before a new
-             * Finished message could have been computed.)
-             */
-            s->s3->next_proto_neg_seen = 1;
-        }
-#endif
-
-        else if (currext->type
-                     == TLSEXT_TYPE_application_layer_protocol_negotiation
-                 && s->s3->tmp.finish_md_len == 0) {
-            if (!tls1_alpn_handle_client_hello(s,
-                    &currext->data, al))
-                return 0;
-        }
-
-        /* session ticket processed earlier */
-#ifndef OPENSSL_NO_SRTP
-        else if (SSL_IS_DTLS(s) && SSL_get_srtp_profiles(s)
-                 && currext->type == TLSEXT_TYPE_use_srtp) {
-            if (ssl_parse_clienthello_use_srtp_ext(s,
-                    &currext->data, al))
-                return 0;
-        }
-#endif
-        else if (currext->type == TLSEXT_TYPE_encrypt_then_mac
-                 && !(s->options & SSL_OP_NO_ENCRYPT_THEN_MAC)) {
-            s->s3->flags |= TLS1_FLAGS_ENCRYPT_THEN_MAC;
-        } else if (currext->type == TLSEXT_TYPE_key_share
-                   && SSL_IS_TLS13(s) && !s->hit
-                   && !process_key_share_ext(s, &currext->data, al)) {
-            return 0;
-        }
-        /*
-         * Note: extended master secret extension handled in
-         * tls_check_client_ems_support()
-         */
-
-        /*
-         * If this ClientHello extension was unhandled and this is a
-         * nonresumed connection, check whether the extension is a custom
-         * TLS Extension (has a custom_srv_ext_record), and if so call the
-         * callback and record the extension number so that an appropriate
-         * ServerHello may be later returned.
-         */
-        else if (!s->hit) {
-            if (custom_ext_parse(s, 1, currext->type,
-                    PACKET_data(&currext->data),
-                    PACKET_remaining(&currext->data), al) <= 0)
-                return 0;
-        }
-    }
-
-    /* Need RI if renegotiating */
-
-    if (!renegotiate_seen && s->renegotiate &&
-        !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) {
-        *al = SSL_AD_HANDSHAKE_FAILURE;
-        SSLerr(SSL_F_SSL_SCAN_CLIENTHELLO_TLSEXT,
-               SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
-        return 0;
-    }
-
-    /*
-     * This function currently has no state to clean up, so it returns directly.
-     * If parsing fails at any point, the function returns early.
-     * The SSL object may be left with partial data from extensions, but it must
-     * then no longer be used, and clearing it up will free the leftovers.
-     */
-    return 1;
-}
-
-int ssl_parse_clienthello_tlsext(SSL *s, CLIENTHELLO_MSG *hello)
-{
-    int al = -1;
-    custom_ext_init(&s->cert->srv_ext);
-    if (ssl_scan_clienthello_tlsext(s, hello, &al) <= 0) {
-        ssl3_send_alert(s, SSL3_AL_FATAL, al);
-        return 0;
-    }
-    if (ssl_check_clienthello_tlsext_early(s) <= 0) {
-        SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT, SSL_R_CLIENTHELLO_TLSEXT);
-        return 0;
-    }
-    return 1;
-}
-
-#ifndef OPENSSL_NO_NEXTPROTONEG
-/*
- * ssl_next_proto_validate validates a Next Protocol Negotiation block. No
- * elements of zero length are allowed and the set of elements must exactly
- * fill the length of the block.
- */
-static char ssl_next_proto_validate(PACKET *pkt)
-{
-    PACKET tmp_protocol;
-
-    while (PACKET_remaining(pkt)) {
-        if (!PACKET_get_length_prefixed_1(pkt, &tmp_protocol)
-            || PACKET_remaining(&tmp_protocol) == 0)
-            return 0;
-    }
-
-    return 1;
-}
-#endif
-
-static int ssl_scan_serverhello_tlsext(SSL *s, PACKET *pkt, int *al)
-{
-    unsigned int length, type, size;
-    int tlsext_servername = 0;
-    int renegotiate_seen = 0;
-
-#ifndef OPENSSL_NO_NEXTPROTONEG
-    s->s3->next_proto_neg_seen = 0;
-#endif
-    s->tlsext_ticket_expected = 0;
-
-    OPENSSL_free(s->s3->alpn_selected);
-    s->s3->alpn_selected = NULL;
-
-    s->s3->flags &= ~TLS1_FLAGS_ENCRYPT_THEN_MAC;
-
-    s->s3->flags &= ~TLS1_FLAGS_RECEIVED_EXTMS;
-
-    if (!PACKET_get_net_2(pkt, &length))
-        goto ri_check;
-
-    if (PACKET_remaining(pkt) != length) {
-        *al = SSL_AD_DECODE_ERROR;
-        return 0;
-    }
-
-    if (!tls1_check_duplicate_extensions(pkt)) {
-        *al = SSL_AD_DECODE_ERROR;
-        return 0;
-    }
-
-    while (PACKET_get_net_2(pkt, &type) && PACKET_get_net_2(pkt, &size)) {
-        const unsigned char *data;
-        PACKET spkt;
-
-        if (!PACKET_get_sub_packet(pkt, &spkt, size)
-            || !PACKET_peek_bytes(&spkt, &data, size))
-            goto ri_check;
-
-        if (s->tlsext_debug_cb)
-            s->tlsext_debug_cb(s, 1, type, data, size, s->tlsext_debug_arg);
-
-        if (type == TLSEXT_TYPE_renegotiate) {
-            if (!ssl_parse_serverhello_renegotiate_ext(s, &spkt, al))
-                return 0;
-            renegotiate_seen = 1;
-        } else if (s->version == SSL3_VERSION) {
-        } else if (type == TLSEXT_TYPE_server_name) {
-            if (s->tlsext_hostname == NULL || size > 0) {
-                *al = TLS1_AD_UNRECOGNIZED_NAME;
-                return 0;
-            }
-            tlsext_servername = 1;
-        }
-#ifndef OPENSSL_NO_EC
-        else if (type == TLSEXT_TYPE_ec_point_formats) {
-            unsigned int ecpointformatlist_length;
-            if (!PACKET_get_1(&spkt, &ecpointformatlist_length)
-                || ecpointformatlist_length != size - 1) {
-                *al = TLS1_AD_DECODE_ERROR;
-                return 0;
-            }
-            if (!s->hit) {
-                s->session->tlsext_ecpointformatlist_length = 0;
-                OPENSSL_free(s->session->tlsext_ecpointformatlist);
-                if ((s->session->tlsext_ecpointformatlist =
-                     OPENSSL_malloc(ecpointformatlist_length)) == NULL) {
-                    *al = TLS1_AD_INTERNAL_ERROR;
-                    return 0;
-                }
-                s->session->tlsext_ecpointformatlist_length =
-                    ecpointformatlist_length;
-                if (!PACKET_copy_bytes(&spkt,
-                                       s->session->tlsext_ecpointformatlist,
-                                       ecpointformatlist_length)) {
-                    *al = TLS1_AD_DECODE_ERROR;
-                    return 0;
-                }
-
-            }
-        }
-#endif                          /* OPENSSL_NO_EC */
-
-        else if (type == TLSEXT_TYPE_session_ticket) {
-            if (s->tls_session_ticket_ext_cb &&
-                !s->tls_session_ticket_ext_cb(s, data, size,
-                                              s->tls_session_ticket_ext_cb_arg))
-            {
-                *al = TLS1_AD_INTERNAL_ERROR;
-                return 0;
-            }
-            if (!tls_use_ticket(s) || (size > 0)) {
-                *al = TLS1_AD_UNSUPPORTED_EXTENSION;
-                return 0;
-            }
-            s->tlsext_ticket_expected = 1;
-        } else if (type == TLSEXT_TYPE_status_request) {
-            /*
-             * MUST be empty and only sent if we've requested a status
-             * request message.
-             */
-            if ((s->tlsext_status_type == -1) || (size > 0)) {
-                *al = TLS1_AD_UNSUPPORTED_EXTENSION;
-                return 0;
-            }
-            /* Set flag to expect CertificateStatus message */
-            s->tlsext_status_expected = 1;
-        }
-#ifndef OPENSSL_NO_CT
-        /*
-         * Only take it if we asked for it - i.e if there is no CT validation
-         * callback set, then a custom extension MAY be processing it, so we
-         * need to let control continue to flow to that.
-         */
-        else if (type == TLSEXT_TYPE_signed_certificate_timestamp &&
-                 s->ct_validation_callback != NULL) {
-            /* Simply copy it off for later processing */
-            if (s->tlsext_scts != NULL) {
-                OPENSSL_free(s->tlsext_scts);
-                s->tlsext_scts = NULL;
-            }
-            s->tlsext_scts_len = size;
-            if (size > 0) {
-                s->tlsext_scts = OPENSSL_malloc(size);
-                if (s->tlsext_scts == NULL) {
-                    *al = TLS1_AD_INTERNAL_ERROR;
-                    return 0;
-                }
-                memcpy(s->tlsext_scts, data, size);
-            }
-        }
-#endif
-#ifndef OPENSSL_NO_NEXTPROTONEG
-        else if (type == TLSEXT_TYPE_next_proto_neg &&
-                 s->s3->tmp.finish_md_len == 0) {
-            unsigned char *selected;
-            unsigned char selected_len;
-            /* We must have requested it. */
-            if (s->ctx->next_proto_select_cb == NULL) {
-                *al = TLS1_AD_UNSUPPORTED_EXTENSION;
-                return 0;
-            }
-            /* The data must be valid */
-            if (!ssl_next_proto_validate(&spkt)) {
-                *al = TLS1_AD_DECODE_ERROR;
-                return 0;
-            }
-            if (s->ctx->next_proto_select_cb(s, &selected, &selected_len, data,
-                                             size,
-                                             s->
-                                             ctx->next_proto_select_cb_arg) !=
-                SSL_TLSEXT_ERR_OK) {
-                *al = TLS1_AD_INTERNAL_ERROR;
-                return 0;
-            }
-            /*
-             * Could be non-NULL if server has sent multiple NPN extensions in
-             * a single Serverhello
-             */
-            OPENSSL_free(s->next_proto_negotiated);
-            s->next_proto_negotiated = OPENSSL_malloc(selected_len);
-            if (s->next_proto_negotiated == NULL) {
-                *al = TLS1_AD_INTERNAL_ERROR;
-                return 0;
-            }
-            memcpy(s->next_proto_negotiated, selected, selected_len);
-            s->next_proto_negotiated_len = selected_len;
-            s->s3->next_proto_neg_seen = 1;
-        }
-#endif
-
-        else if (type == TLSEXT_TYPE_application_layer_protocol_negotiation) {
-            unsigned len;
-            /* We must have requested it. */
-            if (!s->s3->alpn_sent) {
-                *al = TLS1_AD_UNSUPPORTED_EXTENSION;
-                return 0;
-            }
-            /*-
-             * The extension data consists of:
-             *   uint16 list_length
-             *   uint8 proto_length;
-             *   uint8 proto[proto_length];
-             */
-            if (!PACKET_get_net_2(&spkt, &len)
-                || PACKET_remaining(&spkt) != len || !PACKET_get_1(&spkt, &len)
-                || PACKET_remaining(&spkt) != len) {
-                *al = TLS1_AD_DECODE_ERROR;
-                return 0;
-            }
-            OPENSSL_free(s->s3->alpn_selected);
-            s->s3->alpn_selected = OPENSSL_malloc(len);
-            if (s->s3->alpn_selected == NULL) {
-                *al = TLS1_AD_INTERNAL_ERROR;
-                return 0;
-            }
-            if (!PACKET_copy_bytes(&spkt, s->s3->alpn_selected, len)) {
-                *al = TLS1_AD_DECODE_ERROR;
-                return 0;
-            }
-            s->s3->alpn_selected_len = len;
-        }
-#ifndef OPENSSL_NO_SRTP
-        else if (SSL_IS_DTLS(s) && type == TLSEXT_TYPE_use_srtp) {
-            if (ssl_parse_serverhello_use_srtp_ext(s, &spkt, al))
-                return 0;
-        }
-#endif
-        else if (type == TLSEXT_TYPE_encrypt_then_mac) {
-            /* Ignore if inappropriate ciphersuite */
-            if (!(s->options & SSL_OP_NO_ENCRYPT_THEN_MAC) &&
-                s->s3->tmp.new_cipher->algorithm_mac != SSL_AEAD
-                && s->s3->tmp.new_cipher->algorithm_enc != SSL_RC4)
-                s->s3->flags |= TLS1_FLAGS_ENCRYPT_THEN_MAC;
-        } else if (type == TLSEXT_TYPE_extended_master_secret &&
-                (SSL_IS_DTLS(s) || !SSL_IS_TLS13(s))) {
-            s->s3->flags |= TLS1_FLAGS_RECEIVED_EXTMS;
-            if (!s->hit)
-                s->session->flags |= SSL_SESS_FLAG_EXTMS;
-        } else if (type == TLSEXT_TYPE_key_share
-                && SSL_IS_TLS13(s)) {
-            unsigned int group_id;
-            PACKET encoded_pt;
-            EVP_PKEY *ckey = s->s3->tmp.pkey, *skey = NULL;
-
-            /* Sanity check */
-            if (ckey == NULL) {
-                *al = SSL_AD_INTERNAL_ERROR;
-                SSLerr(SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-                return 0;
-            }
-
-            if (!PACKET_get_net_2(&spkt, &group_id)) {
-                *al = SSL_AD_HANDSHAKE_FAILURE;
-                SSLerr(SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT,
-                       SSL_R_LENGTH_MISMATCH);
-                return 0;
-            }
-
-            if (group_id != s->s3->group_id) {
-                /*
-                 * This isn't for the group that we sent in the original
-                 * key_share!
-                 */
-                *al = SSL_AD_HANDSHAKE_FAILURE;
-                SSLerr(SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT,
-                       SSL_R_BAD_KEY_SHARE);
-                return 0;
-            }
-
-            if (!PACKET_as_length_prefixed_2(&spkt, &encoded_pt)
-                    || PACKET_remaining(&encoded_pt) == 0) {
-                *al = SSL_AD_DECODE_ERROR;
-                SSLerr(SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT,
-                       SSL_R_LENGTH_MISMATCH);
-                return 0;
-            }
-
-            skey = ssl_generate_pkey(ckey);
-            if (skey == NULL) {
-                *al = SSL_AD_INTERNAL_ERROR;
-                SSLerr(SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT, ERR_R_MALLOC_FAILURE);
-                return 0;
-            }
-            if (!EVP_PKEY_set1_tls_encodedpoint(skey, PACKET_data(&encoded_pt),
-                                                PACKET_remaining(&encoded_pt))) {
-                *al = SSL_AD_DECODE_ERROR;
-                SSLerr(SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT, SSL_R_BAD_ECPOINT);
-                return 0;
-            }
-
-            if (ssl_derive(s, ckey, skey, 1) == 0) {
-                *al = SSL_AD_INTERNAL_ERROR;
-                SSLerr(SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-                EVP_PKEY_free(skey);
-                return 0;
-            }
-            EVP_PKEY_free(skey);
-        /*
-         * If this extension type was not otherwise handled, but matches a
-         * custom_cli_ext_record, then send it to the c callback
-         */
-        } else if (custom_ext_parse(s, 0, type, data, size, al) <= 0)
-            return 0;
-    }
-
-    if (PACKET_remaining(pkt) != 0) {
-        *al = SSL_AD_DECODE_ERROR;
-        return 0;
-    }
-
-    if (!s->hit && tlsext_servername == 1) {
-        if (s->tlsext_hostname) {
-            if (s->session->tlsext_hostname == NULL) {
-                s->session->tlsext_hostname =
-                    OPENSSL_strdup(s->tlsext_hostname);
-                if (!s->session->tlsext_hostname) {
-                    *al = SSL_AD_UNRECOGNIZED_NAME;
-                    return 0;
-                }
-            } else {
-                *al = SSL_AD_DECODE_ERROR;
-                return 0;
-            }
-        }
-    }
-
- ri_check:
-
-    /*
-     * Determine if we need to see RI. Strictly speaking if we want to avoid
-     * an attack we should *always* see RI even on initial server hello
-     * because the client doesn't see any renegotiation during an attack.
-     * However this would mean we could not connect to any server which
-     * doesn't support RI so for the immediate future tolerate RI absence
-     */
-    if (!renegotiate_seen && !(s->options & SSL_OP_LEGACY_SERVER_CONNECT)
-        && !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) {
-        *al = SSL_AD_HANDSHAKE_FAILURE;
-        SSLerr(SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT,
-               SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
-        return 0;
-    }
-
-    if (s->hit) {
-        /*
-         * Check extended master secret extension is consistent with
-         * original session.
-         */
-        if (!(s->s3->flags & TLS1_FLAGS_RECEIVED_EXTMS) !=
-            !(s->session->flags & SSL_SESS_FLAG_EXTMS)) {
-            *al = SSL_AD_HANDSHAKE_FAILURE;
-            SSLerr(SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT, SSL_R_INCONSISTENT_EXTMS);
-            return 0;
-        }
-    }
-
-    return 1;
-}
-
-int ssl_prepare_clienthello_tlsext(SSL *s)
-{
-    s->s3->alpn_sent = 0;
-    return 1;
-}
-
-int ssl_prepare_serverhello_tlsext(SSL *s)
-{
-    return 1;
-}
-
-static int ssl_check_clienthello_tlsext_early(SSL *s)
-{
-    int ret = SSL_TLSEXT_ERR_NOACK;
-    int al = SSL_AD_UNRECOGNIZED_NAME;
-
-#ifndef OPENSSL_NO_EC
-    /*
-     * The handling of the ECPointFormats extension is done elsewhere, namely
-     * in ssl3_choose_cipher in s3_lib.c.
-     */
-    /*
-     * The handling of the EllipticCurves extension is done elsewhere, namely
-     * in ssl3_choose_cipher in s3_lib.c.
-     */
-#endif
-
-    if (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0)
-        ret =
-            s->ctx->tlsext_servername_callback(s, &al,
-                                               s->ctx->tlsext_servername_arg);
-    else if (s->initial_ctx != NULL
-             && s->initial_ctx->tlsext_servername_callback != 0)
-        ret =
-            s->initial_ctx->tlsext_servername_callback(s, &al,
-                                                       s->
-                                                       initial_ctx->tlsext_servername_arg);
-
-    switch (ret) {
-    case SSL_TLSEXT_ERR_ALERT_FATAL:
-        ssl3_send_alert(s, SSL3_AL_FATAL, al);
-        return -1;
-
-    case SSL_TLSEXT_ERR_ALERT_WARNING:
-        ssl3_send_alert(s, SSL3_AL_WARNING, al);
-        return 1;
-
-    case SSL_TLSEXT_ERR_NOACK:
-        s->servername_done = 0;
-    default:
-        return 1;
-    }
-}
-
-/* Initialise digests to default values */
-void ssl_set_default_md(SSL *s)
-{
-    const EVP_MD **pmd = s->s3->tmp.md;
-#ifndef OPENSSL_NO_DSA
-    pmd[SSL_PKEY_DSA_SIGN] = ssl_md(SSL_MD_SHA1_IDX);
-#endif
-#ifndef OPENSSL_NO_RSA
-    if (SSL_USE_SIGALGS(s))
-        pmd[SSL_PKEY_RSA_SIGN] = ssl_md(SSL_MD_SHA1_IDX);
-    else
-        pmd[SSL_PKEY_RSA_SIGN] = ssl_md(SSL_MD_MD5_SHA1_IDX);
-    pmd[SSL_PKEY_RSA_ENC] = pmd[SSL_PKEY_RSA_SIGN];
-#endif
-#ifndef OPENSSL_NO_EC
-    pmd[SSL_PKEY_ECC] = ssl_md(SSL_MD_SHA1_IDX);
-#endif
-#ifndef OPENSSL_NO_GOST
-    pmd[SSL_PKEY_GOST01] = ssl_md(SSL_MD_GOST94_IDX);
-    pmd[SSL_PKEY_GOST12_256] = ssl_md(SSL_MD_GOST12_256_IDX);
-    pmd[SSL_PKEY_GOST12_512] = ssl_md(SSL_MD_GOST12_512_IDX);
-#endif
-}
-
-int tls1_set_server_sigalgs(SSL *s)
-{
-    int al;
-    size_t i;
-
-    /* Clear any shared signature algorithms */
-    OPENSSL_free(s->cert->shared_sigalgs);
-    s->cert->shared_sigalgs = NULL;
-    s->cert->shared_sigalgslen = 0;
-    /* Clear certificate digests and validity flags */
-    for (i = 0; i < SSL_PKEY_NUM; i++) {
-        s->s3->tmp.md[i] = NULL;
-        s->s3->tmp.valid_flags[i] = 0;
-    }
-
-    /* If sigalgs received process it. */
-    if (s->s3->tmp.peer_sigalgs) {
-        if (!tls1_process_sigalgs(s)) {
-            SSLerr(SSL_F_TLS1_SET_SERVER_SIGALGS, ERR_R_MALLOC_FAILURE);
-            al = SSL_AD_INTERNAL_ERROR;
-            goto err;
-        }
-        /* Fatal error is no shared signature algorithms */
-        if (!s->cert->shared_sigalgs) {
-            SSLerr(SSL_F_TLS1_SET_SERVER_SIGALGS,
-                   SSL_R_NO_SHARED_SIGNATURE_ALGORITHMS);
-            al = SSL_AD_ILLEGAL_PARAMETER;
-            goto err;
-        }
-    } else {
-        ssl_set_default_md(s);
-    }
-    return 1;
- err:
-    ssl3_send_alert(s, SSL3_AL_FATAL, al);
-    return 0;
-}
-
-/*
- * Upon success, returns 1.
- * Upon failure, returns 0 and sets |al| to the appropriate fatal alert.
- */
-int ssl_check_clienthello_tlsext_late(SSL *s, int *al)
-{
-    s->tlsext_status_expected = 0;
-
-    /*
-     * If status request then ask callback what to do. Note: this must be
-     * called after servername callbacks in case the certificate has changed,
-     * and must be called after the cipher has been chosen because this may
-     * influence which certificate is sent
-     */
-    if ((s->tlsext_status_type != -1) && s->ctx && s->ctx->tlsext_status_cb) {
-        int ret;
-        CERT_PKEY *certpkey;
-        certpkey = ssl_get_server_send_pkey(s);
-        /* If no certificate can't return certificate status */
-        if (certpkey != NULL) {
-            /*
-             * Set current certificate to one we will use so SSL_get_certificate
-             * et al can pick it up.
-             */
-            s->cert->key = certpkey;
-            ret = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg);
-            switch (ret) {
-                /* We don't want to send a status request response */
-            case SSL_TLSEXT_ERR_NOACK:
-                s->tlsext_status_expected = 0;
-                break;
-                /* status request response should be sent */
-            case SSL_TLSEXT_ERR_OK:
-                if (s->tlsext_ocsp_resp)
-                    s->tlsext_status_expected = 1;
-                break;
-                /* something bad happened */
-            case SSL_TLSEXT_ERR_ALERT_FATAL:
-            default:
-                *al = SSL_AD_INTERNAL_ERROR;
-                return 0;
-            }
-        }
-    }
-
-    if (!tls1_alpn_handle_client_hello_late(s, al)) {
-        return 0;
-    }
-
-    return 1;
-}
-
-int ssl_check_serverhello_tlsext(SSL *s)
-{
-    int ret = SSL_TLSEXT_ERR_NOACK;
-    int al = SSL_AD_UNRECOGNIZED_NAME;
-
-#ifndef OPENSSL_NO_EC
-    /*
-     * If we are client and using an elliptic curve cryptography cipher
-     * suite, then if server returns an EC point formats lists extension it
-     * must contain uncompressed.
-     */
-    unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
-    unsigned long alg_a = s->s3->tmp.new_cipher->algorithm_auth;
-    if ((s->tlsext_ecpointformatlist != NULL)
-        && (s->tlsext_ecpointformatlist_length > 0)
-        && (s->session->tlsext_ecpointformatlist != NULL)
-        && (s->session->tlsext_ecpointformatlist_length > 0)
-        && ((alg_k & SSL_kECDHE) || (alg_a & SSL_aECDSA))) {
-        /* we are using an ECC cipher */
-        size_t i;
-        unsigned char *list;
-        int found_uncompressed = 0;
-        list = s->session->tlsext_ecpointformatlist;
-        for (i = 0; i < s->session->tlsext_ecpointformatlist_length; i++) {
-            if (*(list++) == TLSEXT_ECPOINTFORMAT_uncompressed) {
-                found_uncompressed = 1;
-                break;
-            }
-        }
-        if (!found_uncompressed) {
-            SSLerr(SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT,
-                   SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST);
-            return -1;
-        }
-    }
-    ret = SSL_TLSEXT_ERR_OK;
-#endif                          /* OPENSSL_NO_EC */
-
-    if (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0)
-        ret =
-            s->ctx->tlsext_servername_callback(s, &al,
-                                               s->ctx->tlsext_servername_arg);
-    else if (s->initial_ctx != NULL
-             && s->initial_ctx->tlsext_servername_callback != 0)
-        ret =
-            s->initial_ctx->tlsext_servername_callback(s, &al,
-                                                       s->
-                                                       initial_ctx->tlsext_servername_arg);
-
-    /*
-     * Ensure we get sensible values passed to tlsext_status_cb in the event
-     * that we don't receive a status message
-     */
-    OPENSSL_free(s->tlsext_ocsp_resp);
-    s->tlsext_ocsp_resp = NULL;
-    s->tlsext_ocsp_resplen = 0;
-
-    switch (ret) {
-    case SSL_TLSEXT_ERR_ALERT_FATAL:
-        ssl3_send_alert(s, SSL3_AL_FATAL, al);
-        return -1;
-
-    case SSL_TLSEXT_ERR_ALERT_WARNING:
-        ssl3_send_alert(s, SSL3_AL_WARNING, al);
-        return 1;
-
-    case SSL_TLSEXT_ERR_NOACK:
-        s->servername_done = 0;
-    default:
-        return 1;
-    }
-}
-
-int ssl_parse_serverhello_tlsext(SSL *s, PACKET *pkt)
-{
-    int al = -1;
-    if (s->version < SSL3_VERSION)
-        return 1;
-    if (ssl_scan_serverhello_tlsext(s, pkt, &al) <= 0) {
-        ssl3_send_alert(s, SSL3_AL_FATAL, al);
-        return 0;
-    }
-
-    if (ssl_check_serverhello_tlsext(s) <= 0) {
-        SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT, SSL_R_SERVERHELLO_TLSEXT);
-        return 0;
-    }
-    return 1;
-}
-
-/*
- * Given a list of extensions that we collected earlier, find one of a given
- * type and return it.
- *
- * |exts| is the set of extensions previously collected.
- * |numexts| is the number of extensions that we have.
- * |type| the type of the extension that we are looking for.
- *
- * Returns a pointer to the found RAW_EXTENSION data, or NULL if not found.
- */
-RAW_EXTENSION *tls_get_extension_by_type(RAW_EXTENSION *exts, size_t numexts,
-                                         unsigned int type)
-{
-    size_t loop;
-
-    for (loop = 0; loop < numexts; loop++) {
-        if (exts[loop].type == type)
-            return &exts[loop];
-    }
-
-    return NULL;
-}
-
-/*-
- * Gets the ticket information supplied by the client if any.
- *
- *   hello: The parsed ClientHello data
- *   ret: (output) on return, if a ticket was decrypted, then this is set to
- *       point to the resulting session.
- *
- * If s->tls_session_secret_cb is set then we are expecting a pre-shared key
- * ciphersuite, in which case we have no use for session tickets and one will
- * never be decrypted, nor will s->tlsext_ticket_expected be set to 1.
- *
- * Returns:
- *   -1: fatal error, either from parsing or decrypting the ticket.
- *    0: no ticket was found (or was ignored, based on settings).
- *    1: a zero length extension was found, indicating that the client supports
- *       session tickets but doesn't currently have one to offer.
- *    2: either s->tls_session_secret_cb was set, or a ticket was offered but
- *       couldn't be decrypted because of a non-fatal error.
- *    3: a ticket was successfully decrypted and *ret was set.
- *
- * Side effects:
- *   Sets s->tlsext_ticket_expected to 1 if the server will have to issue
- *   a new session ticket to the client because the client indicated support
- *   (and s->tls_session_secret_cb is NULL) but the client either doesn't have
- *   a session ticket or we couldn't use the one it gave us, or if
- *   s->ctx->tlsext_ticket_key_cb asked to renew the client's ticket.
- *   Otherwise, s->tlsext_ticket_expected is set to 0.
- */
-int tls_get_ticket_from_client(SSL *s, CLIENTHELLO_MSG *hello,
-                               SSL_SESSION **ret)
-{
-    int retv;
-    const unsigned char *etick;
-    size_t size;
-    RAW_EXTENSION *ticketext;
-
-    *ret = NULL;
-    s->tlsext_ticket_expected = 0;
-
-    /*
-     * If tickets disabled or not supported by the protocol version
-     * (e.g. TLSv1.3) behave as if no ticket present to permit stateful
-     * resumption.
-     */
-    if (s->version <= SSL3_VERSION || !tls_use_ticket(s))
-        return 0;
-
-    ticketext = tls_get_extension_by_type(hello->pre_proc_exts,
-                                          hello->num_extensions,
-                                          TLSEXT_TYPE_session_ticket);
-    if (ticketext == NULL)
-        return 0;
-
-    size = PACKET_remaining(&ticketext->data);
-    if (size == 0) {
-        /*
-         * The client will accept a ticket but doesn't currently have
-         * one.
-         */
-        s->tlsext_ticket_expected = 1;
-        return 1;
-    }
-    if (s->tls_session_secret_cb) {
-        /*
-         * Indicate that the ticket couldn't be decrypted rather than
-         * generating the session from ticket now, trigger
-         * abbreviated handshake based on external mechanism to
-         * calculate the master secret later.
-         */
-        return 2;
-    }
-    if (!PACKET_get_bytes(&ticketext->data, &etick, size)) {
-        /* Shouldn't ever happen */
-        return -1;
-    }
-    retv = tls_decrypt_ticket(s, etick, size, hello->session_id,
-                           hello->session_id_len, ret);
-    switch (retv) {
-    case 2:            /* ticket couldn't be decrypted */
-        s->tlsext_ticket_expected = 1;
-        return 2;
-
-    case 3:            /* ticket was decrypted */
-        return 3;
+    case 3:            /* ticket was decrypted */
+        return 3;
 
     case 4:            /* ticket decrypted but need to renew */
         s->tlsext_ticket_expected = 1;
@@ -3238,43 +1118,6 @@ int tls_get_ticket_from_client(SSL *s, CLIENTHELLO_MSG *hello,
     }
 }
 
-/*
- * Sets the extended master secret flag if the extension is present in the
- * ClientHello and we can support it
- * Returns:
- *  1 on success
- *  0 on error
- */
-int tls_check_client_ems_support(SSL *s, const CLIENTHELLO_MSG *hello)
-{
-    RAW_EXTENSION *emsext;
-
-    s->s3->flags &= ~TLS1_FLAGS_RECEIVED_EXTMS;
-
-    if (!SSL_IS_DTLS(s) && (s->version < TLS1_VERSION
-                            || s->version > TLS1_2_VERSION))
-        return 1;
-
-    emsext = tls_get_extension_by_type(hello->pre_proc_exts,
-                                       hello->num_extensions,
-                                       TLSEXT_TYPE_extended_master_secret);
-
-    /*
-     * No extensions is a success - we have successfully discovered that the
-     * client doesn't support EMS.
-     */
-    if (emsext == NULL)
-        return 1;
-
-    /* The extensions must always be empty */
-    if (PACKET_remaining(&emsext->data) != 0)
-        return 0;
-
-    s->s3->flags |= TLS1_FLAGS_RECEIVED_EXTMS;
-
-    return 1;
-}
-
 /*-
  * tls_decrypt_ticket attempts to decrypt a session ticket.
  *