/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 * 
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 * 
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from 
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 * 
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * 
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */
/* ====================================================================
 * Copyright (c) 1998-2007 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    openssl-core@openssl.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com). */

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

#include <openssl/bytestring.h>
#include <openssl/evp.h>
#include <openssl/hmac.h>
#include <openssl/mem.h>
#include <openssl/obj.h>
#include <openssl/rand.h>

#include "ssl_locl.h"


static int tls_decrypt_ticket(SSL *s, const uint8_t *tick, int ticklen,
                              const uint8_t *sess_id, int sesslen,
                              SSL_SESSION **psess);
static int ssl_check_clienthello_tlsext(SSL *s);
static int ssl_check_serverhello_tlsext(SSL *s);

const SSL3_ENC_METHOD TLSv1_enc_data = {
    tls1_enc,
    tls1_mac,
    tls1_setup_key_block,
    tls1_generate_master_secret,
    tls1_change_cipher_state,
    tls1_final_finish_mac,
    TLS1_FINISH_MAC_LENGTH,
    tls1_cert_verify_mac,
    TLS_MD_CLIENT_FINISH_CONST,TLS_MD_CLIENT_FINISH_CONST_SIZE,
    TLS_MD_SERVER_FINISH_CONST,TLS_MD_SERVER_FINISH_CONST_SIZE,
    tls1_alert_code,
    tls1_export_keying_material,
    0,
    SSL3_HM_HEADER_LENGTH,
    ssl3_set_handshake_header,
    ssl3_handshake_write,
};

const SSL3_ENC_METHOD TLSv1_1_enc_data = {
    tls1_enc,
    tls1_mac,
    tls1_setup_key_block,
    tls1_generate_master_secret,
    tls1_change_cipher_state,
    tls1_final_finish_mac,
    TLS1_FINISH_MAC_LENGTH,
    tls1_cert_verify_mac,
    TLS_MD_CLIENT_FINISH_CONST,TLS_MD_CLIENT_FINISH_CONST_SIZE,
    TLS_MD_SERVER_FINISH_CONST,TLS_MD_SERVER_FINISH_CONST_SIZE,
    tls1_alert_code,
    tls1_export_keying_material,
    SSL_ENC_FLAG_EXPLICIT_IV,
    SSL3_HM_HEADER_LENGTH,
    ssl3_set_handshake_header,
    ssl3_handshake_write,
};

const SSL3_ENC_METHOD TLSv1_2_enc_data = {
    tls1_enc,
    tls1_mac,
    tls1_setup_key_block,
    tls1_generate_master_secret,
    tls1_change_cipher_state,
    tls1_final_finish_mac,
    TLS1_FINISH_MAC_LENGTH,
    tls1_cert_verify_mac,
    TLS_MD_CLIENT_FINISH_CONST,TLS_MD_CLIENT_FINISH_CONST_SIZE,
    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,
    SSL3_HM_HEADER_LENGTH,
    ssl3_set_handshake_header,
    ssl3_handshake_write,
};

static int compare_uint16_t(const void *p1, const void *p2) {
  uint16_t u1 = *((const uint16_t *)p1);
  uint16_t u2 = *((const uint16_t *)p2);
  if (u1 < u2) {
    return -1;
  } else if (u1 > u2) {
    return 1;
  } else {
    return 0;
  }
}

/* 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. */
static int tls1_check_duplicate_extensions(const CBS *cbs) {
  CBS extensions = *cbs;
  size_t num_extensions = 0, i = 0;
  uint16_t *extension_types = NULL;
  int ret = 0;

  /* First pass: count the extensions. */
  while (CBS_len(&extensions) > 0) {
    uint16_t type;
    CBS extension;

    if (!CBS_get_u16(&extensions, &type) ||
        !CBS_get_u16_length_prefixed(&extensions, &extension)) {
      goto done;
    }

    num_extensions++;
  }

  if (num_extensions == 0) {
    return 1;
  }

  extension_types =
      (uint16_t *)OPENSSL_malloc(sizeof(uint16_t) * num_extensions);
  if (extension_types == NULL) {
    OPENSSL_PUT_ERROR(SSL, tls1_check_duplicate_extensions,
                      ERR_R_MALLOC_FAILURE);
    goto done;
  }

  /* Second pass: gather the extension types. */
  extensions = *cbs;
  for (i = 0; i < num_extensions; i++) {
    CBS extension;

    if (!CBS_get_u16(&extensions, &extension_types[i]) ||
        !CBS_get_u16_length_prefixed(&extensions, &extension)) {
      /* This should not happen. */
      goto done;
    }
  }
  assert(CBS_len(&extensions) == 0);

  /* Sort the extensions and make sure there are no duplicates. */
  qsort(extension_types, num_extensions, sizeof(uint16_t), compare_uint16_t);
  for (i = 1; i < num_extensions; i++) {
    if (extension_types[i - 1] == extension_types[i]) {
      goto done;
    }
  }

  ret = 1;

done:
  if (extension_types)
    OPENSSL_free(extension_types);
  return ret;
}

char ssl_early_callback_init(struct ssl_early_callback_ctx *ctx) {
  CBS client_hello, session_id, cipher_suites, compression_methods, extensions;

  CBS_init(&client_hello, ctx->client_hello, ctx->client_hello_len);

  if (/* Skip client version. */
      !CBS_skip(&client_hello, 2) ||
      /* Skip client nonce. */
      !CBS_skip(&client_hello, 32) ||
      /* Extract session_id. */
      !CBS_get_u8_length_prefixed(&client_hello, &session_id)) {
    return 0;
  }

  ctx->session_id = CBS_data(&session_id);
  ctx->session_id_len = CBS_len(&session_id);

  /* Skip past DTLS cookie */
  if (SSL_IS_DTLS(ctx->ssl)) {
    CBS cookie;

    if (!CBS_get_u8_length_prefixed(&client_hello, &cookie)) {
      return 0;
    }
  }

  /* Extract cipher_suites. */
  if (!CBS_get_u16_length_prefixed(&client_hello, &cipher_suites) ||
      CBS_len(&cipher_suites) < 2 || (CBS_len(&cipher_suites) & 1) != 0) {
    return 0;
  }
  ctx->cipher_suites = CBS_data(&cipher_suites);
  ctx->cipher_suites_len = CBS_len(&cipher_suites);

  /* Extract compression_methods. */
  if (!CBS_get_u8_length_prefixed(&client_hello, &compression_methods) ||
      CBS_len(&compression_methods) < 1) {
    return 0;
  }
  ctx->compression_methods = CBS_data(&compression_methods);
  ctx->compression_methods_len = CBS_len(&compression_methods);

  /* If the ClientHello ends here then it's valid, but doesn't have any
   * extensions. (E.g. SSLv3.) */
  if (CBS_len(&client_hello) == 0) {
    ctx->extensions = NULL;
    ctx->extensions_len = 0;
    return 1;
  }

  /* Extract extensions and check it is valid. */
  if (!CBS_get_u16_length_prefixed(&client_hello, &extensions) ||
      !tls1_check_duplicate_extensions(&extensions) ||
      CBS_len(&client_hello) != 0) {
    return 0;
  }
  ctx->extensions = CBS_data(&extensions);
  ctx->extensions_len = CBS_len(&extensions);

  return 1;
}

char SSL_early_callback_ctx_extension_get(
    const struct ssl_early_callback_ctx *ctx, uint16_t extension_type,
    const uint8_t **out_data, size_t *out_len) {
  CBS extensions;

  CBS_init(&extensions, ctx->extensions, ctx->extensions_len);

  while (CBS_len(&extensions) != 0) {
    uint16_t type;
    CBS extension;

    /* Decode the next extension. */
    if (!CBS_get_u16(&extensions, &type) ||
        !CBS_get_u16_length_prefixed(&extensions, &extension)) {
      return 0;
    }

    if (type == extension_type) {
      *out_data = CBS_data(&extension);
      *out_len = CBS_len(&extension);
      return 1;
    }
  }

  return 0;
}

/* ECC curves from RFC4492 */
static const int nid_list[] = {
    NID_sect163k1,        /* sect163k1 (1) */
    NID_sect163r1,        /* sect163r1 (2) */
    NID_sect163r2,        /* sect163r2 (3) */
    NID_sect193r1,        /* sect193r1 (4) */
    NID_sect193r2,        /* sect193r2 (5) */
    NID_sect233k1,        /* sect233k1 (6) */
    NID_sect233r1,        /* sect233r1 (7) */
    NID_sect239k1,        /* sect239k1 (8) */
    NID_sect283k1,        /* sect283k1 (9) */
    NID_sect283r1,        /* sect283r1 (10) */
    NID_sect409k1,        /* sect409k1 (11) */
    NID_sect409r1,        /* sect409r1 (12) */
    NID_sect571k1,        /* sect571k1 (13) */
    NID_sect571r1,        /* sect571r1 (14) */
    NID_secp160k1,        /* secp160k1 (15) */
    NID_secp160r1,        /* secp160r1 (16) */
    NID_secp160r2,        /* secp160r2 (17) */
    NID_secp192k1,        /* secp192k1 (18) */
    NID_X9_62_prime192v1, /* secp192r1 (19) */
    NID_secp224k1,        /* secp224k1 (20) */
    NID_secp224r1,        /* secp224r1 (21) */
    NID_secp256k1,        /* secp256k1 (22) */
    NID_X9_62_prime256v1, /* secp256r1 (23) */
    NID_secp384r1,        /* secp384r1 (24) */
    NID_secp521r1,        /* secp521r1 (25) */
    NID_brainpoolP256r1,  /* brainpoolP256r1 (26) */
    NID_brainpoolP384r1,  /* brainpoolP384r1 (27) */
    NID_brainpoolP512r1   /* brainpool512r1 (28) */
};

static const uint8_t ecformats_default[] = {
    TLSEXT_ECPOINTFORMAT_uncompressed,
};

static const uint16_t eccurves_default[] = {
    23, /* secp256r1 (23) */
    24, /* secp384r1 (24) */
    25, /* secp521r1 (25) */
};

int tls1_ec_curve_id2nid(uint16_t curve_id) {
  if (curve_id < 1 || curve_id > sizeof(nid_list) / sizeof(nid_list[0])) {
    return OBJ_undef;
  }
  return nid_list[curve_id - 1];
}

uint16_t tls1_ec_nid2curve_id(int nid) {
  size_t i;
  for (i = 0; i < sizeof(nid_list) / sizeof(nid_list[0]); i++) {
    /* nid_list[i] stores the NID corresponding to curve ID i+1. */
    if (nid == nid_list[i]) {
      return i + 1;
    }
  }

  /* Use 0 for non-existent curve ID. Note: this assumes that curve ID 0 will
   * never be allocated. */
  return 0;
}

/* tls1_get_curvelist sets |*out_curve_ids| and |*out_curve_ids_len| to the
 * list of allowed curve IDs. If |get_peer_curves| is non-zero, return the
 * peer's curve list. Otherwise, return the preferred list. */
static void tls1_get_curvelist(SSL *s, int get_peer_curves,
                               const uint16_t **out_curve_ids,
                               size_t *out_curve_ids_len) {
  if (get_peer_curves) {
    *out_curve_ids = s->s3->tmp.peer_ellipticcurvelist;
    *out_curve_ids_len = s->s3->tmp.peer_ellipticcurvelist_length;
    return;
  }

  *out_curve_ids = s->tlsext_ellipticcurvelist;
  *out_curve_ids_len = s->tlsext_ellipticcurvelist_length;
  if (!*out_curve_ids) {
    *out_curve_ids = eccurves_default;
    *out_curve_ids_len = sizeof(eccurves_default) / sizeof(eccurves_default[0]);
  }
}

int tls1_check_curve(SSL *s, CBS *cbs, uint16_t *out_curve_id) {
  uint8_t curve_type;
  uint16_t curve_id;
  const uint16_t *curves;
  size_t curves_len, i;

  /* Only support named curves. */
  if (!CBS_get_u8(cbs, &curve_type) ||
      curve_type != NAMED_CURVE_TYPE ||
      !CBS_get_u16(cbs, &curve_id)) {
    return 0;
  }

  tls1_get_curvelist(s, 0, &curves, &curves_len);
  for (i = 0; i < curves_len; i++) {
    if (curve_id == curves[i]) {
      *out_curve_id = curve_id;
      return 1;
    }
  }

  return 0;
}

int tls1_get_shared_curve(SSL *s) {
  const uint16_t *pref, *supp;
  size_t preflen, supplen, i, j;

  /* Can't do anything on client side */
  if (s->server == 0) {
    return NID_undef;
  }

  /* Return first preference shared curve */
  tls1_get_curvelist(s, !!(s->options & SSL_OP_CIPHER_SERVER_PREFERENCE), &supp,
                     &supplen);
  tls1_get_curvelist(s, !(s->options & SSL_OP_CIPHER_SERVER_PREFERENCE), &pref,
                     &preflen);

  for (i = 0; i < preflen; i++) {
    for (j = 0; j < supplen; j++) {
      if (pref[i] == supp[j]) {
        return tls1_ec_curve_id2nid(pref[i]);
      }
    }
  }

  return NID_undef;
}

/* NOTE: tls1_ec_curve_id2nid and tls1_set_curves assume that
 *
 * (a) 0 is not a valid curve ID.
 *
 * (b) The largest curve ID is 31.
 *
 * Those implementations must be revised before adding support for curve IDs
 * that break these assumptions. */
OPENSSL_COMPILE_ASSERT((sizeof(nid_list) / sizeof(nid_list[0])) < 32,
                       small_curve_ids);

int tls1_set_curves(uint16_t **out_curve_ids, size_t *out_curve_ids_len,
                    const int *curves, size_t ncurves) {
  uint16_t *curve_ids;
  size_t i;

  /* Bitmap of curves included to detect duplicates: only works
   * while curve ids < 32. */
  uint32_t dup_list = 0;
  curve_ids = (uint16_t *)OPENSSL_malloc(ncurves * sizeof(uint16_t));
  if (curve_ids == NULL) {
    return 0;
  }

  for (i = 0; i < ncurves; i++) {
    uint32_t idmask;
    uint16_t id;
    id = tls1_ec_nid2curve_id(curves[i]);
    idmask = ((uint32_t)1) << id;
    if (!id || (dup_list & idmask)) {
      OPENSSL_free(curve_ids);
      return 0;
    }
    dup_list |= idmask;
    curve_ids[i] = id;
  }

  if (*out_curve_ids) {
    OPENSSL_free(*out_curve_ids);
  }
  *out_curve_ids = curve_ids;
  *out_curve_ids_len = ncurves;

  return 1;
}

/* tls1_curve_params_from_ec_key sets |*out_curve_id| and |*out_comp_id| to the
 * TLS curve ID and point format, respectively, for |ec|. It returns one on
 * success and zero on failure. */
static int tls1_curve_params_from_ec_key(uint16_t *out_curve_id,
                                         uint8_t *out_comp_id, EC_KEY *ec) {
  int nid;
  uint16_t id;
  const EC_GROUP *grp;

  if (ec == NULL) {
    return 0;
  }

  grp = EC_KEY_get0_group(ec);
  if (grp == NULL) {
    return 0;
  }

  /* Determine curve ID */
  nid = EC_GROUP_get_curve_name(grp);
  id = tls1_ec_nid2curve_id(nid);
  if (!id) {
    return 0;
  }

  /* Set the named curve ID. Arbitrary explicit curves are not supported. */
  *out_curve_id = id;

  if (out_comp_id) {
    if (EC_KEY_get0_public_key(ec) == NULL) {
      return 0;
    }
    if (EC_KEY_get_conv_form(ec) == POINT_CONVERSION_COMPRESSED) {
      *out_comp_id = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime;
    } else {
      *out_comp_id = TLSEXT_ECPOINTFORMAT_uncompressed;
    }
  }

  return 1;
}

/* tls1_check_point_format returns one if |comp_id| is consistent with the
 * peer's point format preferences. */
static int tls1_check_point_format(SSL *s, uint8_t comp_id) {
  uint8_t *p = s->s3->tmp.peer_ecpointformatlist;
  size_t plen = s->s3->tmp.peer_ecpointformatlist_length;
  size_t i;

  /* If point formats extension present check it, otherwise everything is
   * supported (see RFC4492). */
  if (p == NULL) {
    return 1;
  }

  for (i = 0; i < plen; i++) {
    if (comp_id == p[i]) {
      return 1;
    }
  }

  return 0;
}

/* tls1_check_curve_id returns one if |curve_id| is consistent with both our
 * and the peer's curve preferences. Note: if called as the client, only our
 * preferences are checked; the peer (the server) does not send preferences. */
static int tls1_check_curve_id(SSL *s, uint16_t curve_id) {
  const uint16_t *curves;
  size_t curves_len, i, j;

  /* Check against our list, then the peer's list. */
  for (j = 0; j <= 1; j++) {
    tls1_get_curvelist(s, j, &curves, &curves_len);
    for (i = 0; i < curves_len; i++) {
      if (curves[i] == curve_id) {
        break;
      }
    }

    if (i == curves_len) {
      return 0;
    }

    /* Servers do not present a preference list so, if we are a client, only
     * check our list. */
    if (!s->server) {
      return 1;
    }
  }

  return 1;
}

static void tls1_get_formatlist(SSL *s, const uint8_t **pformats,
                                size_t *pformatslen) {
  /* If we have a custom point format list use it otherwise use default */
  if (s->tlsext_ecpointformatlist) {
    *pformats = s->tlsext_ecpointformatlist;
    *pformatslen = s->tlsext_ecpointformatlist_length;
  } else {
    *pformats = ecformats_default;
    *pformatslen = sizeof(ecformats_default);
  }
}

int tls1_check_ec_cert(SSL *s, X509 *x) {
  int ret = 0;
  EVP_PKEY *pkey = X509_get_pubkey(x);
  uint16_t curve_id;
  uint8_t comp_id;

  if (!pkey ||
      pkey->type != EVP_PKEY_EC ||
      !tls1_curve_params_from_ec_key(&curve_id, &comp_id, pkey->pkey.ec) ||
      !tls1_check_curve_id(s, curve_id) ||
      !tls1_check_point_format(s, comp_id)) {
    goto done;
  }

  ret = 1;

done:
  if (pkey) {
    EVP_PKEY_free(pkey);
  }
  return ret;
}

int tls1_check_ec_tmp_key(SSL *s) {
  uint16_t curve_id;
  EC_KEY *ec = s->cert->ecdh_tmp;

  if (s->cert->ecdh_tmp_auto) {
    /* Need a shared curve */
    return tls1_get_shared_curve(s) != NID_undef;
  }

  if (!ec) {
    if (s->cert->ecdh_tmp_cb) {
      return 1;
    }
    return 0;
  }

  return tls1_curve_params_from_ec_key(&curve_id, NULL, ec) &&
         tls1_check_curve_id(s, curve_id);
}

/* List of supported signature algorithms and hashes. Should make this
 * customisable at some point, for now include everything we support. */

#define tlsext_sigalg_rsa(md) md, TLSEXT_signature_rsa,

#define tlsext_sigalg_ecdsa(md) md, TLSEXT_signature_ecdsa,

#define tlsext_sigalg(md) tlsext_sigalg_rsa(md) tlsext_sigalg_ecdsa(md)

static const uint8_t tls12_sigalgs[] = {
    tlsext_sigalg(TLSEXT_hash_sha512)
    tlsext_sigalg(TLSEXT_hash_sha384)
    tlsext_sigalg(TLSEXT_hash_sha256)
    tlsext_sigalg(TLSEXT_hash_sha224)
    tlsext_sigalg(TLSEXT_hash_sha1)
};

size_t tls12_get_psigalgs(SSL *s, const uint8_t **psigs) {
  /* If server use client authentication sigalgs if not NULL */
  if (s->server && s->cert->client_sigalgs) {
    *psigs = s->cert->client_sigalgs;
    return s->cert->client_sigalgslen;
  } else if (s->cert->conf_sigalgs) {
    *psigs = s->cert->conf_sigalgs;
    return s->cert->conf_sigalgslen;
  } else {
    *psigs = tls12_sigalgs;
    return sizeof(tls12_sigalgs);
  }
}

/* tls12_check_peer_sigalg parses a SignatureAndHashAlgorithm out of |cbs|. It
 * checks it is consistent with |s|'s sent supported signature algorithms and,
 * if so, writes the relevant digest into |*out_md| and returns 1. Otherwise it
 * returns 0 and writes an alert into |*out_alert|. */
int tls12_check_peer_sigalg(const EVP_MD **out_md, int *out_alert, SSL *s,
                            CBS *cbs, EVP_PKEY *pkey) {
  const uint8_t *sent_sigs;
  size_t sent_sigslen, i;
  int sigalg = tls12_get_sigid(pkey);
  uint8_t hash, signature;

  /* Should never happen */
  if (sigalg == -1) {
    OPENSSL_PUT_ERROR(SSL, tls12_check_peer_sigalg, ERR_R_INTERNAL_ERROR);
    *out_alert = SSL_AD_INTERNAL_ERROR;
    return 0;
  }

  if (!CBS_get_u8(cbs, &hash) ||
      !CBS_get_u8(cbs, &signature)) {
    OPENSSL_PUT_ERROR(SSL, tls12_check_peer_sigalg, SSL_R_DECODE_ERROR);
    *out_alert = SSL_AD_DECODE_ERROR;
    return 0;
  }

  /* Check key type is consistent with signature */
  if (sigalg != signature) {
    OPENSSL_PUT_ERROR(SSL, tls12_check_peer_sigalg, SSL_R_WRONG_SIGNATURE_TYPE);
    *out_alert = SSL_AD_ILLEGAL_PARAMETER;
    return 0;
  }

  if (pkey->type == EVP_PKEY_EC) {
    uint16_t curve_id;
    uint8_t comp_id;
    /* Check compression and curve matches extensions */
    if (!tls1_curve_params_from_ec_key(&curve_id, &comp_id, pkey->pkey.ec)) {
      *out_alert = SSL_AD_INTERNAL_ERROR;
      return 0;
    }

    if (s->server && (!tls1_check_curve_id(s, curve_id) ||
                      !tls1_check_point_format(s, comp_id))) {
      OPENSSL_PUT_ERROR(SSL, tls12_check_peer_sigalg, SSL_R_WRONG_CURVE);
      *out_alert = SSL_AD_ILLEGAL_PARAMETER;
      return 0;
    }
  }

  /* Check signature matches a type we sent */
  sent_sigslen = tls12_get_psigalgs(s, &sent_sigs);
  for (i = 0; i < sent_sigslen; i += 2, sent_sigs += 2) {
    if (hash == sent_sigs[0] && signature == sent_sigs[1]) {
      break;
    }
  }

  /* Allow fallback to SHA-1. */
  if (i == sent_sigslen && hash != TLSEXT_hash_sha1) {
    OPENSSL_PUT_ERROR(SSL, tls12_check_peer_sigalg, SSL_R_WRONG_SIGNATURE_TYPE);
    *out_alert = SSL_AD_ILLEGAL_PARAMETER;
    return 0;
  }

  *out_md = tls12_get_hash(hash);
  if (*out_md == NULL) {
    OPENSSL_PUT_ERROR(SSL, tls12_check_peer_sigalg, SSL_R_UNKNOWN_DIGEST);
    *out_alert = SSL_AD_ILLEGAL_PARAMETER;
    return 0;
  }

  return 1;
}

/* Get a mask of disabled algorithms: an algorithm is disabled if it isn't
 * supported or doesn't appear in supported signature algorithms. Unlike
 * ssl_cipher_get_disabled this applies to a specific session and not global
 * settings. */
void ssl_set_client_disabled(SSL *s) {
  CERT *c = s->cert;
  const uint8_t *sigalgs;
  size_t i, sigalgslen;
  int have_rsa = 0, have_ecdsa = 0;
  c->mask_a = 0;
  c->mask_k = 0;

  /* Don't allow TLS 1.2 only ciphers if we don't suppport them */
  if (!SSL_CLIENT_USE_TLS1_2_CIPHERS(s)) {
    c->mask_ssl = SSL_TLSV1_2;
  } else {
    c->mask_ssl = 0;
  }

  /* Now go through all signature algorithms seeing if we support any for RSA,
   * DSA, ECDSA. Do this for all versions not just TLS 1.2. */
  sigalgslen = tls12_get_psigalgs(s, &sigalgs);
  for (i = 0; i < sigalgslen; i += 2, sigalgs += 2) {
    switch (sigalgs[1]) {
      case TLSEXT_signature_rsa:
        have_rsa = 1;
        break;

      case TLSEXT_signature_ecdsa:
        have_ecdsa = 1;
        break;
    }
  }

  /* Disable auth if we don't include any appropriate signature algorithms. */
  if (!have_rsa) {
    c->mask_a |= SSL_aRSA;
  }
  if (!have_ecdsa) {
    c->mask_a |= SSL_aECDSA;
  }

  /* with PSK there must be client callback set */
  if (!s->psk_client_callback) {
    c->mask_a |= SSL_aPSK;
    c->mask_k |= SSL_kPSK;
  }
}

/* header_len is the length of the ClientHello header written so far, used to
 * compute padding. It does not include the record header. Pass 0 if no padding
 * is to be done. */
uint8_t *ssl_add_clienthello_tlsext(SSL *s, uint8_t *buf, uint8_t *limit,
                                    size_t header_len) {
  int extdatalen = 0;
  uint8_t *ret = buf;
  uint8_t *orig = buf;
  /* See if we support any ECC ciphersuites */
  int using_ecc = 0;

  if (s->version >= TLS1_VERSION || SSL_IS_DTLS(s)) {
    size_t 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_kEECDH) || (alg_a & SSL_aECDSA)) {
        using_ecc = 1;
        break;
      }
    }
  }

  /* don't add extensions for SSLv3 unless doing secure renegotiation */
  if (s->client_version == SSL3_VERSION && !s->s3->send_connection_binding) {
    return orig;
  }

  ret += 2;

  if (ret >= limit) {
    return NULL; /* should never occur. */
  }

  if (s->tlsext_hostname != NULL) {
    /* Add TLS extension servername to the Client Hello message */
    unsigned long size_str;
    long lenmax;

    /* check for enough space.
       4 for the servername type and entension length
       2 for servernamelist length
       1 for the hostname type
       2 for hostname length
       + hostname length */

    lenmax = limit - ret - 9;
    size_str = strlen(s->tlsext_hostname);
    if (lenmax < 0 || size_str > (unsigned long)lenmax) {
      return NULL;
    }

    /* extension type and length */
    s2n(TLSEXT_TYPE_server_name, ret);
    s2n(size_str + 5, ret);

    /* length of servername list */
    s2n(size_str + 3, ret);

    /* hostname type, length and hostname */
    *(ret++) = (uint8_t)TLSEXT_NAMETYPE_host_name;
    s2n(size_str, ret);
    memcpy(ret, s->tlsext_hostname, size_str);
    ret += size_str;
  }

  /* Add RI if renegotiating */
  if (s->renegotiate) {
    int el;

    if (!ssl_add_clienthello_renegotiate_ext(s, 0, &el, 0)) {
      OPENSSL_PUT_ERROR(SSL, ssl_add_clienthello_tlsext, ERR_R_INTERNAL_ERROR);
      return NULL;
    }

    if ((limit - ret - 4 - el) < 0) {
      return NULL;
    }

    s2n(TLSEXT_TYPE_renegotiate, ret);
    s2n(el, ret);

    if (!ssl_add_clienthello_renegotiate_ext(s, ret, &el, el)) {
      OPENSSL_PUT_ERROR(SSL, ssl_add_clienthello_tlsext, ERR_R_INTERNAL_ERROR);
      return NULL;
    }

    ret += el;
  }

  /* Add extended master secret. */
  if (s->version != SSL3_VERSION) {
    if (limit - ret - 4 < 0) {
      return NULL;
    }
    s2n(TLSEXT_TYPE_extended_master_secret, ret);
    s2n(0, ret);
  }

  if (!(SSL_get_options(s) & SSL_OP_NO_TICKET)) {
    int ticklen = 0;
    if (!s->new_session && s->session && s->session->tlsext_tick) {
      ticklen = s->session->tlsext_ticklen;
    }

    /* Check for enough room 2 for extension type, 2 for len rest for
     * ticket. */
    if ((long)(limit - ret - 4 - ticklen) < 0) {
      return NULL;
    }
    s2n(TLSEXT_TYPE_session_ticket, ret);
    s2n(ticklen, ret);
    if (ticklen) {
      memcpy(ret, s->session->tlsext_tick, ticklen);
      ret += ticklen;
    }
  }

  if (SSL_USE_SIGALGS(s)) {
    size_t salglen;
    const uint8_t *salg;
    salglen = tls12_get_psigalgs(s, &salg);
    if ((size_t)(limit - ret) < salglen + 6) {
      return NULL;
    }
    s2n(TLSEXT_TYPE_signature_algorithms, ret);
    s2n(salglen + 2, ret);
    s2n(salglen, ret);
    memcpy(ret, salg, salglen);
    ret += salglen;
  }

  if (s->ocsp_stapling_enabled) {
    /* The status_request extension is excessively extensible at every layer.
     * On the client, only support requesting OCSP responses with an empty
     * responder_id_list and no extensions. */
    if (limit - ret - 4 - 1 - 2 - 2 < 0) {
      return NULL;
    }

    s2n(TLSEXT_TYPE_status_request, ret);
    s2n(1 + 2 + 2, ret);
    /* status_type */
    *(ret++) = TLSEXT_STATUSTYPE_ocsp;
    /* responder_id_list - empty */
    s2n(0, ret);
    /* request_extensions - empty */
    s2n(0, ret);
  }

  if (s->ctx->next_proto_select_cb && !s->s3->tmp.finish_md_len) {
    /* The client advertises an emtpy extension to indicate its support for
     * Next Protocol Negotiation */
    if (limit - ret - 4 < 0) {
      return NULL;
    }
    s2n(TLSEXT_TYPE_next_proto_neg, ret);
    s2n(0, ret);
  }

  if (s->signed_cert_timestamps_enabled && !s->s3->tmp.finish_md_len) {
    /* The client advertises an empty extension to indicate its support for
     * certificate timestamps. */
    if (limit - ret - 4 < 0) {
      return NULL;
    }
    s2n(TLSEXT_TYPE_certificate_timestamp, ret);
    s2n(0, ret);
  }

  if (s->alpn_client_proto_list && !s->s3->tmp.finish_md_len) {
    if ((size_t)(limit - ret) < 6 + s->alpn_client_proto_list_len) {
      return NULL;
    }
    s2n(TLSEXT_TYPE_application_layer_protocol_negotiation, ret);
    s2n(2 + s->alpn_client_proto_list_len, ret);
    s2n(s->alpn_client_proto_list_len, ret);
    memcpy(ret, s->alpn_client_proto_list, s->alpn_client_proto_list_len);
    ret += s->alpn_client_proto_list_len;
  }

  if (s->tlsext_channel_id_enabled) {
    /* The client advertises an emtpy extension to indicate its support for
     * Channel ID. */
    if (limit - ret - 4 < 0) {
      return NULL;
    }
    if (s->ctx->tlsext_channel_id_enabled_new) {
      s2n(TLSEXT_TYPE_channel_id_new, ret);
    } else {
      s2n(TLSEXT_TYPE_channel_id, ret);
    }
    s2n(0, ret);
  }

  if (SSL_get_srtp_profiles(s)) {
    int el;

    ssl_add_clienthello_use_srtp_ext(s, 0, &el, 0);

    if ((limit - ret - 4 - el) < 0) {
      return NULL;
    }

    s2n(TLSEXT_TYPE_use_srtp, ret);
    s2n(el, ret);

    if (!ssl_add_clienthello_use_srtp_ext(s, ret, &el, el)) {
      OPENSSL_PUT_ERROR(SSL, ssl_add_clienthello_tlsext, ERR_R_INTERNAL_ERROR);
      return NULL;
    }
    ret += el;
  }

  if (using_ecc) {
    /* Add TLS extension ECPointFormats to the ClientHello message */
    long lenmax;
    const uint8_t *formats;
    const uint16_t *curves;
    size_t formats_len, curves_len, i;

    tls1_get_formatlist(s, &formats, &formats_len);

    lenmax = limit - ret - 5;
    if (lenmax < 0) {
      return NULL;
    }
    if (formats_len > (size_t)lenmax) {
      return NULL;
    }
    if (formats_len > 255) {
      OPENSSL_PUT_ERROR(SSL, ssl_add_clienthello_tlsext, ERR_R_INTERNAL_ERROR);
      return NULL;
    }

    s2n(TLSEXT_TYPE_ec_point_formats, ret);
    s2n(formats_len + 1, ret);
    *(ret++) = (uint8_t)formats_len;
    memcpy(ret, formats, formats_len);
    ret += formats_len;

    /* Add TLS extension EllipticCurves to the ClientHello message */
    tls1_get_curvelist(s, 0, &curves, &curves_len);

    lenmax = limit - ret - 6;
    if (lenmax < 0) {
      return NULL;
    }
    if (curves_len * 2 > (size_t)lenmax) {
      return NULL;
    }
    if (curves_len * 2 > 65532) {
      OPENSSL_PUT_ERROR(SSL, ssl_add_clienthello_tlsext, ERR_R_INTERNAL_ERROR);
      return NULL;
    }

    s2n(TLSEXT_TYPE_elliptic_curves, ret);
    s2n((curves_len * 2) + 2, ret);

    s2n(curves_len * 2, ret);
    for (i = 0; i < curves_len; i++) {
      s2n(curves[i], ret);
    }
  }

  if (header_len > 0) {
    size_t clienthello_minsize = 0;
    header_len += ret - orig;
    if (header_len > 0xff && header_len < 0x200) {
      /* 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. */
      clienthello_minsize = 0x200;
    }
    if (s->fastradio_padding) {
      /* Pad the ClientHello record to 1024 bytes to fast forward the radio
       * into DCH (high data rate) state in 3G networks. Note that when
       * fastradio_padding is enabled, even if the header_len is less than 255
       * bytes, the padding will be applied regardless. This is slightly
       * different from the TLS padding extension suggested in
       * https://tools.ietf.org/html/draft-agl-tls-padding-03 */
      clienthello_minsize = 0x400;
    }
    if (header_len < clienthello_minsize) {
      size_t padding_len = clienthello_minsize - header_len;
      /* Extensions take at least four bytes to encode. Always include least
       * one byte of data if including the extension. WebSphere Application
       * Server 7.0 is intolerant to the last extension being zero-length. */
      if (padding_len >= 4 + 1) {
        padding_len -= 4;
      } else {
        padding_len = 1;
      }

      if (limit - ret - 4 - (long)padding_len < 0) {
        return NULL;
      }

      s2n(TLSEXT_TYPE_padding, ret);
      s2n(padding_len, ret);
      memset(ret, 0, padding_len);
      ret += padding_len;
    }
  }

  extdatalen = ret - orig - 2;
  if (extdatalen == 0) {
    return orig;
  }

  s2n(extdatalen, orig);
  return ret;
}

uint8_t *ssl_add_serverhello_tlsext(SSL *s, uint8_t *buf, uint8_t *limit) {
  int extdatalen = 0;
  uint8_t *orig = buf;
  uint8_t *ret = buf;
  int next_proto_neg_seen;
  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_kEECDH) || (alg_a & SSL_aECDSA);
  using_ecc = using_ecc && (s->s3->tmp.peer_ecpointformatlist != NULL);

  /* don't add extensions for SSLv3, unless doing secure renegotiation */
  if (s->version == SSL3_VERSION && !s->s3->send_connection_binding) {
    return orig;
  }

  ret += 2;
  if (ret >= limit) {
    return NULL; /* should never happen. */
  }

  if (!s->hit && s->should_ack_sni && s->session->tlsext_hostname != NULL) {
    if ((long)(limit - ret - 4) < 0) {
      return NULL;
    }

    s2n(TLSEXT_TYPE_server_name, ret);
    s2n(0, ret);
  }

  if (s->s3->send_connection_binding) {
    int el;

    if (!ssl_add_serverhello_renegotiate_ext(s, 0, &el, 0)) {
      OPENSSL_PUT_ERROR(SSL, ssl_add_serverhello_tlsext, ERR_R_INTERNAL_ERROR);
      return NULL;
    }

    if ((limit - ret - 4 - el) < 0) {
      return NULL;
    }

    s2n(TLSEXT_TYPE_renegotiate, ret);
    s2n(el, ret);

    if (!ssl_add_serverhello_renegotiate_ext(s, ret, &el, el)) {
      OPENSSL_PUT_ERROR(SSL, ssl_add_serverhello_tlsext, ERR_R_INTERNAL_ERROR);
      return NULL;
    }

    ret += el;
  }

  if (s->s3->tmp.extended_master_secret) {
    if ((long)(limit - ret - 4) < 0) {
      return NULL;
    }

    s2n(TLSEXT_TYPE_extended_master_secret, ret);
    s2n(0, ret);
  }

  if (using_ecc) {
    const uint8_t *plist;
    size_t plistlen;
    /* Add TLS extension ECPointFormats to the ServerHello message */
    long lenmax;

    tls1_get_formatlist(s, &plist, &plistlen);

    lenmax = limit - ret - 5;
    if (lenmax < 0) {
      return NULL;
    }
    if (plistlen > (size_t)lenmax) {
      return NULL;
    }
    if (plistlen > 255) {
      OPENSSL_PUT_ERROR(SSL, ssl_add_serverhello_tlsext, ERR_R_INTERNAL_ERROR);
      return NULL;
    }

    s2n(TLSEXT_TYPE_ec_point_formats, ret);
    s2n(plistlen + 1, ret);
    *(ret++) = (uint8_t)plistlen;
    memcpy(ret, plist, plistlen);
    ret += plistlen;
  }
  /* Currently the server should not respond with a SupportedCurves extension */

  if (s->tlsext_ticket_expected && !(SSL_get_options(s) & SSL_OP_NO_TICKET)) {
    if ((long)(limit - ret - 4) < 0) {
      return NULL;
    }
    s2n(TLSEXT_TYPE_session_ticket, ret);
    s2n(0, ret);
  }

  if (s->s3->tmp.certificate_status_expected) {
    if ((long)(limit - ret - 4) < 0) {
      return NULL;
    }
    s2n(TLSEXT_TYPE_status_request, ret);
    s2n(0, ret);
  }

  if (s->srtp_profile) {
    int el;

    ssl_add_serverhello_use_srtp_ext(s, 0, &el, 0);

    if ((limit - ret - 4 - el) < 0) {
      return NULL;
    }

    s2n(TLSEXT_TYPE_use_srtp, ret);
    s2n(el, ret);

    if (!ssl_add_serverhello_use_srtp_ext(s, ret, &el, el)) {
      OPENSSL_PUT_ERROR(SSL, ssl_add_serverhello_tlsext, ERR_R_INTERNAL_ERROR);
      return NULL;
    }
    ret += el;
  }

  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 uint8_t *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 ((long)(limit - ret - 4 - npalen) < 0) {
        return NULL;
      }
      s2n(TLSEXT_TYPE_next_proto_neg, ret);
      s2n(npalen, ret);
      memcpy(ret, npa, npalen);
      ret += npalen;
      s->s3->next_proto_neg_seen = 1;
    }
  }

  if (s->s3->alpn_selected) {
    const uint8_t *selected = s->s3->alpn_selected;
    size_t len = s->s3->alpn_selected_len;

    if ((long)(limit - ret - 4 - 2 - 1 - len) < 0) {
      return NULL;
    }
    s2n(TLSEXT_TYPE_application_layer_protocol_negotiation, ret);
    s2n(3 + len, ret);
    s2n(1 + len, ret);
    *ret++ = len;
    memcpy(ret, selected, len);
    ret += len;
  }

  /* If the client advertised support for Channel ID, and we have it
   * enabled, then we want to echo it back. */
  if (s->s3->tlsext_channel_id_valid) {
    if (limit - ret - 4 < 0) {
      return NULL;
    }
    if (s->s3->tlsext_channel_id_new) {
      s2n(TLSEXT_TYPE_channel_id_new, ret);
    } else {
      s2n(TLSEXT_TYPE_channel_id, ret);
    }
    s2n(0, ret);
  }

  extdatalen = ret - orig - 2;
  if (extdatalen == 0) {
    return orig;
  }

  s2n(extdatalen, orig);
  return ret;
}

/* tls1_alpn_handle_client_hello is called to process the ALPN extension in a
 * ClientHello.
 *   cbs: the contents of the extension, not including the type and length.
 *   out_alert: a pointer to the alert value to send in the event of a zero
 *       return.
 *
 *   returns: 1 on success. */
static int tls1_alpn_handle_client_hello(SSL *s, CBS *cbs, int *out_alert) {
  CBS protocol_name_list, protocol_name_list_copy;
  const uint8_t *selected;
  uint8_t selected_len;
  int r;

  if (s->ctx->alpn_select_cb == NULL) {
    return 1;
  }

  if (!CBS_get_u16_length_prefixed(cbs, &protocol_name_list) ||
      CBS_len(cbs) != 0 || CBS_len(&protocol_name_list) < 2) {
    goto parse_error;
  }

  /* Validate the protocol list. */
  protocol_name_list_copy = protocol_name_list;
  while (CBS_len(&protocol_name_list_copy) > 0) {
    CBS protocol_name;

    if (!CBS_get_u8_length_prefixed(&protocol_name_list_copy, &protocol_name)) {
      goto parse_error;
    }
  }

  r = s->ctx->alpn_select_cb(
      s, &selected, &selected_len, CBS_data(&protocol_name_list),
      CBS_len(&protocol_name_list), s->ctx->alpn_select_cb_arg);
  if (r == SSL_TLSEXT_ERR_OK) {
    if (s->s3->alpn_selected) {
      OPENSSL_free(s->s3->alpn_selected);
    }
    s->s3->alpn_selected = BUF_memdup(selected, selected_len);
    if (!s->s3->alpn_selected) {
      *out_alert = SSL_AD_INTERNAL_ERROR;
      return 0;
    }
    s->s3->alpn_selected_len = selected_len;
  }

  return 1;

parse_error:
  *out_alert = SSL_AD_DECODE_ERROR;
  return 0;
}

static int ssl_scan_clienthello_tlsext(SSL *s, CBS *cbs, int *out_alert) {
  int renegotiate_seen = 0;
  CBS extensions;

  s->should_ack_sni = 0;
  s->s3->next_proto_neg_seen = 0;
  s->s3->tmp.certificate_status_expected = 0;
  s->s3->tmp.extended_master_secret = 0;

  if (s->s3->alpn_selected) {
    OPENSSL_free(s->s3->alpn_selected);
    s->s3->alpn_selected = NULL;
  }

  /* Clear any signature algorithms extension received */
  if (s->cert->peer_sigalgs) {
    OPENSSL_free(s->cert->peer_sigalgs);
    s->cert->peer_sigalgs = NULL;
  }

  /* Clear any shared signature algorithms */
  if (s->cert->shared_sigalgs) {
    OPENSSL_free(s->cert->shared_sigalgs);
    s->cert->shared_sigalgs = NULL;
  }

  /* Clear ECC extensions */
  if (s->s3->tmp.peer_ecpointformatlist != 0) {
    OPENSSL_free(s->s3->tmp.peer_ecpointformatlist);
    s->s3->tmp.peer_ecpointformatlist = NULL;
    s->s3->tmp.peer_ecpointformatlist_length = 0;
  }

  if (s->s3->tmp.peer_ellipticcurvelist != 0) {
    OPENSSL_free(s->s3->tmp.peer_ellipticcurvelist);
    s->s3->tmp.peer_ellipticcurvelist = NULL;
    s->s3->tmp.peer_ellipticcurvelist_length = 0;
  }

  /* There may be no extensions. */
  if (CBS_len(cbs) == 0) {
    goto ri_check;
  }

  /* Decode the extensions block and check it is valid. */
  if (!CBS_get_u16_length_prefixed(cbs, &extensions) ||
      !tls1_check_duplicate_extensions(&extensions)) {
    *out_alert = SSL_AD_DECODE_ERROR;
    return 0;
  }

  while (CBS_len(&extensions) != 0) {
    uint16_t type;
    CBS extension;

    /* Decode the next extension. */
    if (!CBS_get_u16(&extensions, &type) ||
        !CBS_get_u16_length_prefixed(&extensions, &extension)) {
      *out_alert = SSL_AD_DECODE_ERROR;
      return 0;
    }

    if (s->tlsext_debug_cb) {
      s->tlsext_debug_cb(s, 0, type, (uint8_t *)CBS_data(&extension),
                         CBS_len(&extension), s->tlsext_debug_arg);
    }

    /* 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. */

    if (type == TLSEXT_TYPE_server_name) {
      CBS server_name_list;
      char have_seen_host_name = 0;

      if (!CBS_get_u16_length_prefixed(&extension, &server_name_list) ||
          CBS_len(&server_name_list) < 1 || CBS_len(&extension) != 0) {
        *out_alert = SSL_AD_DECODE_ERROR;
        return 0;
      }

      /* Decode each ServerName in the extension. */
      while (CBS_len(&server_name_list) > 0) {
        uint8_t name_type;
        CBS host_name;

        /* Decode the NameType. */
        if (!CBS_get_u8(&server_name_list, &name_type)) {
          *out_alert = SSL_AD_DECODE_ERROR;
          return 0;
        }

        /* Only host_name is supported. */
        if (name_type != TLSEXT_NAMETYPE_host_name) {
          continue;
        }

        if (have_seen_host_name) {
          /* The ServerNameList MUST NOT contain more than one name of the same
           * name_type. */
          *out_alert = SSL_AD_DECODE_ERROR;
          return 0;
        }

        have_seen_host_name = 1;

        if (!CBS_get_u16_length_prefixed(&server_name_list, &host_name) ||
            CBS_len(&host_name) < 1) {
          *out_alert = SSL_AD_DECODE_ERROR;
          return 0;
        }

        if (CBS_len(&host_name) > TLSEXT_MAXLEN_host_name ||
            CBS_contains_zero_byte(&host_name)) {
          *out_alert = SSL_AD_UNRECOGNIZED_NAME;
          return 0;
        }

        if (!s->hit) {
          assert(s->session->tlsext_hostname == NULL);
          if (s->session->tlsext_hostname) {
            /* This should be impossible. */
            *out_alert = SSL_AD_DECODE_ERROR;
            return 0;
          }

          /* Copy the hostname as a string. */
          if (!CBS_strdup(&host_name, &s->session->tlsext_hostname)) {
            *out_alert = SSL_AD_INTERNAL_ERROR;
            return 0;
          }

          s->should_ack_sni = 1;
        }
      }
    } else if (type == TLSEXT_TYPE_ec_point_formats) {
      CBS ec_point_format_list;

      if (!CBS_get_u8_length_prefixed(&extension, &ec_point_format_list) ||
          CBS_len(&extension) != 0) {
        *out_alert = SSL_AD_DECODE_ERROR;
        return 0;
      }

      if (!CBS_stow(&ec_point_format_list, &s->s3->tmp.peer_ecpointformatlist,
                    &s->s3->tmp.peer_ecpointformatlist_length)) {
        *out_alert = SSL_AD_INTERNAL_ERROR;
        return 0;
      }
    } else if (type == TLSEXT_TYPE_elliptic_curves) {
      CBS elliptic_curve_list;
      size_t i, num_curves;

      if (!CBS_get_u16_length_prefixed(&extension, &elliptic_curve_list) ||
          CBS_len(&elliptic_curve_list) == 0 ||
          (CBS_len(&elliptic_curve_list) & 1) != 0 ||
          CBS_len(&extension) != 0) {
        *out_alert = SSL_AD_DECODE_ERROR;
        return 0;
      }

      if (s->s3->tmp.peer_ellipticcurvelist) {
        OPENSSL_free(s->s3->tmp.peer_ellipticcurvelist);
        s->s3->tmp.peer_ellipticcurvelist_length = 0;
      }

      s->s3->tmp.peer_ellipticcurvelist =
          (uint16_t *)OPENSSL_malloc(CBS_len(&elliptic_curve_list));

      if (s->s3->tmp.peer_ellipticcurvelist == NULL) {
        *out_alert = SSL_AD_INTERNAL_ERROR;
        return 0;
      }

      num_curves = CBS_len(&elliptic_curve_list) / 2;
      for (i = 0; i < num_curves; i++) {
        if (!CBS_get_u16(&elliptic_curve_list,
                         &s->s3->tmp.peer_ellipticcurvelist[i])) {
          *out_alert = SSL_AD_INTERNAL_ERROR;
          return 0;
        }
      }

      if (CBS_len(&elliptic_curve_list) != 0) {
        *out_alert = SSL_AD_INTERNAL_ERROR;
        return 0;
      }

      s->s3->tmp.peer_ellipticcurvelist_length = num_curves;
    } else if (type == TLSEXT_TYPE_renegotiate) {
      if (!ssl_parse_clienthello_renegotiate_ext(s, &extension, out_alert)) {
        return 0;
      }
      renegotiate_seen = 1;
    } else if (type == TLSEXT_TYPE_signature_algorithms) {
      CBS supported_signature_algorithms;

      if (!CBS_get_u16_length_prefixed(&extension,
                                       &supported_signature_algorithms) ||
          CBS_len(&extension) != 0) {
        *out_alert = SSL_AD_DECODE_ERROR;
        return 0;
      }

      /* Ensure the signature algorithms are non-empty. It contains a list of
       * SignatureAndHashAlgorithms which are two bytes each. */
      if (CBS_len(&supported_signature_algorithms) == 0 ||
          (CBS_len(&supported_signature_algorithms) % 2) != 0) {
        *out_alert = SSL_AD_DECODE_ERROR;
        return 0;
      }

      if (!tls1_process_sigalgs(s, &supported_signature_algorithms)) {
        *out_alert = SSL_AD_DECODE_ERROR;
        return 0;
      }
      /* If sigalgs received and no shared algorithms fatal error. */
      if (s->cert->peer_sigalgs && !s->cert->shared_sigalgs) {
        OPENSSL_PUT_ERROR(SSL, ssl_add_serverhello_tlsext,
                          SSL_R_NO_SHARED_SIGATURE_ALGORITHMS);
        *out_alert = SSL_AD_ILLEGAL_PARAMETER;
        return 0;
      }
    } else if (type == TLSEXT_TYPE_next_proto_neg &&
               s->s3->tmp.finish_md_len == 0 && s->s3->alpn_selected == NULL) {
      /* The extension must be empty. */
      if (CBS_len(&extension) != 0) {
        *out_alert = SSL_AD_DECODE_ERROR;
        return 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 renegotation 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;
    } else if (type == TLSEXT_TYPE_application_layer_protocol_negotiation &&
               s->ctx->alpn_select_cb && s->s3->tmp.finish_md_len == 0) {
      if (!tls1_alpn_handle_client_hello(s, &extension, out_alert)) {
        return 0;
      }
      /* ALPN takes precedence over NPN. */
      s->s3->next_proto_neg_seen = 0;
    } else if (type == TLSEXT_TYPE_channel_id && s->tlsext_channel_id_enabled) {
      /* The extension must be empty. */
      if (CBS_len(&extension) != 0) {
        *out_alert = SSL_AD_DECODE_ERROR;
        return 0;
      }

      s->s3->tlsext_channel_id_valid = 1;
    } else if (type == TLSEXT_TYPE_channel_id_new &&
               s->tlsext_channel_id_enabled) {
      /* The extension must be empty. */
      if (CBS_len(&extension) != 0) {
        *out_alert = SSL_AD_DECODE_ERROR;
        return 0;
      }

      s->s3->tlsext_channel_id_valid = 1;
      s->s3->tlsext_channel_id_new = 1;
    } else if (type == TLSEXT_TYPE_use_srtp) {
      if (!ssl_parse_clienthello_use_srtp_ext(s, &extension, out_alert)) {
        return 0;
      }
    } else if (type == TLSEXT_TYPE_extended_master_secret &&
               s->version != SSL3_VERSION) {
      if (CBS_len(&extension) != 0) {
        *out_alert = SSL_AD_DECODE_ERROR;
        return 0;
      }

      s->s3->tmp.extended_master_secret = 1;
    }
  }

ri_check:
  /* Need RI if renegotiating */

  if (!renegotiate_seen && s->renegotiate &&
      !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) {
    *out_alert = SSL_AD_HANDSHAKE_FAILURE;
    OPENSSL_PUT_ERROR(SSL, ssl_scan_clienthello_tlsext,
                      SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
    return 0;
  }

  return 1;
}

int ssl_parse_clienthello_tlsext(SSL *s, CBS *cbs) {
  int alert = -1;
  if (ssl_scan_clienthello_tlsext(s, cbs, &alert) <= 0) {
    ssl3_send_alert(s, SSL3_AL_FATAL, alert);
    return 0;
  }

  if (ssl_check_clienthello_tlsext(s) <= 0) {
    OPENSSL_PUT_ERROR(SSL, ssl_parse_clienthello_tlsext,
                      SSL_R_CLIENTHELLO_TLSEXT);
    return 0;
  }

  return 1;
}

/* 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(const CBS *cbs) {
  CBS copy = *cbs;

  while (CBS_len(&copy) != 0) {
    CBS proto;
    if (!CBS_get_u8_length_prefixed(&copy, &proto) || CBS_len(&proto) == 0) {
      return 0;
    }
  }

  return 1;
}

static int ssl_scan_serverhello_tlsext(SSL *s, CBS *cbs, int *out_alert) {
  int tlsext_servername = 0;
  int renegotiate_seen = 0;
  CBS extensions;

  /* TODO(davidben): Move all of these to some per-handshake state that gets
   * systematically reset on a new handshake; perhaps allocate it fresh each
   * time so it's not even kept around post-handshake. */
  s->s3->next_proto_neg_seen = 0;

  s->tlsext_ticket_expected = 0;
  s->s3->tmp.certificate_status_expected = 0;
  s->s3->tmp.extended_master_secret = 0;

  if (s->s3->alpn_selected) {
    OPENSSL_free(s->s3->alpn_selected);
    s->s3->alpn_selected = NULL;
  }

  /* Clear ECC extensions */
  if (s->s3->tmp.peer_ecpointformatlist != 0) {
    OPENSSL_free(s->s3->tmp.peer_ecpointformatlist);
    s->s3->tmp.peer_ecpointformatlist = NULL;
    s->s3->tmp.peer_ecpointformatlist_length = 0;
  }

  /* There may be no extensions. */
  if (CBS_len(cbs) == 0) {
    goto ri_check;
  }

  /* Decode the extensions block and check it is valid. */
  if (!CBS_get_u16_length_prefixed(cbs, &extensions) ||
      !tls1_check_duplicate_extensions(&extensions)) {
    *out_alert = SSL_AD_DECODE_ERROR;
    return 0;
  }

  while (CBS_len(&extensions) != 0) {
    uint16_t type;
    CBS extension;

    /* Decode the next extension. */
    if (!CBS_get_u16(&extensions, &type) ||
        !CBS_get_u16_length_prefixed(&extensions, &extension)) {
      *out_alert = SSL_AD_DECODE_ERROR;
      return 0;
    }

    if (s->tlsext_debug_cb) {
      s->tlsext_debug_cb(s, 1, type, (uint8_t *)CBS_data(&extension),
                         CBS_len(&extension), s->tlsext_debug_arg);
    }

    if (type == TLSEXT_TYPE_server_name) {
      /* The extension must be empty. */
      if (CBS_len(&extension) != 0) {
        *out_alert = SSL_AD_DECODE_ERROR;
        return 0;
      }

      /* We must have sent it in ClientHello. */
      if (s->tlsext_hostname == NULL) {
        *out_alert = SSL_AD_UNSUPPORTED_EXTENSION;
        return 0;
      }

      tlsext_servername = 1;
    } else if (type == TLSEXT_TYPE_ec_point_formats) {
      CBS ec_point_format_list;

      if (!CBS_get_u8_length_prefixed(&extension, &ec_point_format_list) ||
          CBS_len(&extension) != 0) {
        *out_alert = SSL_AD_DECODE_ERROR;
        return 0;
      }

      if (!CBS_stow(&ec_point_format_list, &s->s3->tmp.peer_ecpointformatlist,
                    &s->s3->tmp.peer_ecpointformatlist_length)) {
        *out_alert = SSL_AD_INTERNAL_ERROR;
        return 0;
      }
    } else if (type == TLSEXT_TYPE_session_ticket) {
      if ((SSL_get_options(s) & SSL_OP_NO_TICKET) || CBS_len(&extension) > 0) {
        *out_alert = SSL_AD_UNSUPPORTED_EXTENSION;
        return 0;
      }

      s->tlsext_ticket_expected = 1;
    } else if (type == TLSEXT_TYPE_status_request) {
      /* The extension MUST be empty and may only sent if we've requested a
       * status request message. */
      if (CBS_len(&extension) != 0) {
        *out_alert = SSL_AD_DECODE_ERROR;
        return 0;
      }

      if (!s->ocsp_stapling_enabled) {
        *out_alert = SSL_AD_UNSUPPORTED_EXTENSION;
        return 0;
      }

      /* Set a flag to expect a CertificateStatus message */
      s->s3->tmp.certificate_status_expected = 1;
    } else if (type == TLSEXT_TYPE_next_proto_neg &&
               s->s3->tmp.finish_md_len == 0) {
      uint8_t *selected;
      uint8_t selected_len;

      /* We must have requested it. */
      if (s->ctx->next_proto_select_cb == NULL) {
        *out_alert = SSL_AD_UNSUPPORTED_EXTENSION;
        return 0;
      }

      /* The data must be valid. */
      if (!ssl_next_proto_validate(&extension)) {
        *out_alert = SSL_AD_DECODE_ERROR;
        return 0;
      }

      if (s->ctx->next_proto_select_cb(
              s, &selected, &selected_len, CBS_data(&extension),
              CBS_len(&extension),
              s->ctx->next_proto_select_cb_arg) != SSL_TLSEXT_ERR_OK) {
        *out_alert = SSL_AD_INTERNAL_ERROR;
        return 0;
      }

      s->next_proto_negotiated = BUF_memdup(selected, selected_len);
      if (s->next_proto_negotiated == NULL) {
        *out_alert = SSL_AD_INTERNAL_ERROR;
        return 0;
      }

      s->next_proto_negotiated_len = selected_len;
      s->s3->next_proto_neg_seen = 1;
    } else if (type == TLSEXT_TYPE_application_layer_protocol_negotiation) {
      CBS protocol_name_list, protocol_name;

      /* We must have requested it. */
      if (s->alpn_client_proto_list == NULL) {
        *out_alert = SSL_AD_UNSUPPORTED_EXTENSION;
        return 0;
      }

      /* The extension data consists of a ProtocolNameList which must have
       * exactly one ProtocolName. Each of these is length-prefixed. */
      if (!CBS_get_u16_length_prefixed(&extension, &protocol_name_list) ||
          CBS_len(&extension) != 0 ||
          !CBS_get_u8_length_prefixed(&protocol_name_list, &protocol_name) ||
          CBS_len(&protocol_name_list) != 0) {
        *out_alert = SSL_AD_DECODE_ERROR;
        return 0;
      }

      if (!CBS_stow(&protocol_name, &s->s3->alpn_selected,
                    &s->s3->alpn_selected_len)) {
        *out_alert = SSL_AD_INTERNAL_ERROR;
        return 0;
      }
    } else if (type == TLSEXT_TYPE_channel_id) {
      if (CBS_len(&extension) != 0) {
        *out_alert = SSL_AD_DECODE_ERROR;
        return 0;
      }

      s->s3->tlsext_channel_id_valid = 1;
    } else if (type == TLSEXT_TYPE_channel_id_new) {
      if (CBS_len(&extension) != 0) {
        *out_alert = SSL_AD_DECODE_ERROR;
        return 0;
      }

      s->s3->tlsext_channel_id_valid = 1;
      s->s3->tlsext_channel_id_new = 1;
    } else if (type == TLSEXT_TYPE_certificate_timestamp) {
      if (CBS_len(&extension) == 0) {
        *out_alert = SSL_AD_DECODE_ERROR;
        return 0;
      }

      /* Session resumption uses the original session information. */
      if (!s->hit &&
          !CBS_stow(&extension, &s->session->tlsext_signed_cert_timestamp_list,
                    &s->session->tlsext_signed_cert_timestamp_list_length)) {
        *out_alert = SSL_AD_INTERNAL_ERROR;
        return 0;
      }
    } else if (type == TLSEXT_TYPE_renegotiate) {
      if (!ssl_parse_serverhello_renegotiate_ext(s, &extension, out_alert)) {
        return 0;
      }

      renegotiate_seen = 1;
    } else if (type == TLSEXT_TYPE_use_srtp) {
      if (!ssl_parse_serverhello_use_srtp_ext(s, &extension, out_alert)) {
        return 0;
      }
    } else if (type == TLSEXT_TYPE_extended_master_secret) {
      if (/* It is invalid for the server to select EMS and
             SSLv3. */
          s->version == SSL3_VERSION || CBS_len(&extension) != 0) {
        *out_alert = SSL_AD_DECODE_ERROR;
        return 0;
      }

      s->s3->tmp.extended_master_secret = 1;
    }
  }

  if (!s->hit && tlsext_servername == 1 && s->tlsext_hostname) {
    if (s->session->tlsext_hostname == NULL) {
      s->session->tlsext_hostname = BUF_strdup(s->tlsext_hostname);
      if (!s->session->tlsext_hostname) {
        *out_alert = SSL_AD_UNRECOGNIZED_NAME;
        return 0;
      }
    } else {
      *out_alert = 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 on initial connect only. */
  if (!renegotiate_seen && !(s->options & SSL_OP_LEGACY_SERVER_CONNECT) &&
      !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) {
    *out_alert = SSL_AD_HANDSHAKE_FAILURE;
    OPENSSL_PUT_ERROR(SSL, ssl_scan_serverhello_tlsext,
                      SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
    return 0;
  }

  return 1;
}

int ssl_prepare_clienthello_tlsext(SSL *s) { return 1; }

int ssl_prepare_serverhello_tlsext(SSL *s) { return 1; }

static int ssl_check_clienthello_tlsext(SSL *s) {
  int ret = SSL_TLSEXT_ERR_NOACK;
  int al = SSL_AD_UNRECOGNIZED_NAME;

  /* The handling of the ECPointFormats extension is done elsewhere, namely in
   * ssl3_choose_cipher in s3_lib.c. */

  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->should_ack_sni = 0;
      return 1;

    default:
      return 1;
  }
}

static int ssl_check_serverhello_tlsext(SSL *s) {
  int ret = SSL_TLSEXT_ERR_NOACK;
  int al = SSL_AD_UNRECOGNIZED_NAME;

  /* 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 (((alg_k & SSL_kEECDH) || (alg_a & SSL_aECDSA)) &&
      !tls1_check_point_format(s, TLSEXT_ECPOINTFORMAT_uncompressed)) {
    OPENSSL_PUT_ERROR(SSL, ssl_check_serverhello_tlsext,
                      SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST);
    return -1;
  }
  ret = SSL_TLSEXT_ERR_OK;

  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;

    default:
      return 1;
  }
}

int ssl_parse_serverhello_tlsext(SSL *s, CBS *cbs) {
  int alert = -1;
  if (s->version < SSL3_VERSION) {
    return 1;
  }

  if (ssl_scan_serverhello_tlsext(s, cbs, &alert) <= 0) {
    ssl3_send_alert(s, SSL3_AL_FATAL, alert);
    return 0;
  }

  if (ssl_check_serverhello_tlsext(s) <= 0) {
    OPENSSL_PUT_ERROR(SSL, ssl_parse_serverhello_tlsext,
                      SSL_R_SERVERHELLO_TLSEXT);
    return 0;
  }

  return 1;
}

/* Since the server cache lookup is done early on in the processing of the
 * ClientHello, and other operations depend on the result, we need to handle
 * any TLS session ticket extension at the same time.
 *
 *   ctx: contains the early callback context, which is the result of a
 *       shallow parse of the ClientHello.
 *   ret: (output) on return, if a ticket was decrypted, then this is set to
 *       point to the resulting session.
 *
 * 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: 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
 *   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 tls1_process_ticket(SSL *s, const struct ssl_early_callback_ctx *ctx,
                        SSL_SESSION **ret) {
  *ret = NULL;
  s->tlsext_ticket_expected = 0;
  const uint8_t *data;
  size_t len;
  int r;

  /* If tickets disabled behave as if no ticket present to permit stateful
   * resumption. */
  if ((SSL_get_options(s) & SSL_OP_NO_TICKET) ||
      (s->version <= SSL3_VERSION && !ctx->extensions) ||
      !SSL_early_callback_ctx_extension_get(ctx, TLSEXT_TYPE_session_ticket,
                                            &data, &len)) {
    return 0;
  }

  if (len == 0) {
    /* The client will accept a ticket but doesn't currently have one. */
    s->tlsext_ticket_expected = 1;
    return 1;
  }

  r = tls_decrypt_ticket(s, data, len, ctx->session_id, ctx->session_id_len,
                         ret);
  switch (r) {
    case 2: /* ticket couldn't be decrypted */
      s->tlsext_ticket_expected = 1;
      return 2;

    case 3: /* ticket was decrypted */
      return r;

    case 4: /* ticket decrypted but need to renew */
      s->tlsext_ticket_expected = 1;
      return 3;

    default: /* fatal error */
      return -1;
  }
}

/* tls_decrypt_ticket attempts to decrypt a session ticket.
 *
 *   etick: points to the body of the session ticket extension.
 *   eticklen: the length of the session tickets extenion.
 *   sess_id: points at the session ID.
 *   sesslen: the length of the session ID.
 *   psess: (output) on return, if a ticket was decrypted, then this is set to
 *       point to the resulting session.
 *
 * Returns:
 *   -1: fatal error, either from parsing or decrypting the ticket.
 *    2: the ticket couldn't be decrypted.
 *    3: a ticket was successfully decrypted and *psess was set.
 *    4: same as 3, but the ticket needs to be renewed. */
static int tls_decrypt_ticket(SSL *s, const uint8_t *etick, int eticklen,
                              const uint8_t *sess_id, int sesslen,
                              SSL_SESSION **psess) {
  SSL_SESSION *sess;
  uint8_t *sdec;
  const uint8_t *p;
  int slen, mlen, renew_ticket = 0;
  uint8_t tick_hmac[EVP_MAX_MD_SIZE];
  HMAC_CTX hctx;
  EVP_CIPHER_CTX ctx;
  SSL_CTX *tctx = s->initial_ctx;

  /* Need at least keyname + iv + some encrypted data */
  if (eticklen < 48) {
    return 2;
  }

  /* Initialize session ticket encryption and HMAC contexts */
  HMAC_CTX_init(&hctx);
  EVP_CIPHER_CTX_init(&ctx);
  if (tctx->tlsext_ticket_key_cb) {
    uint8_t *nctick = (uint8_t *)etick;
    int rv = tctx->tlsext_ticket_key_cb(s, nctick, nctick + 16, &ctx, &hctx, 0);
    if (rv < 0) {
      return -1;
    }
    if (rv == 0) {
      return 2;
    }
    if (rv == 2) {
      renew_ticket = 1;
    }
  } else {
    /* Check key name matches */
    if (memcmp(etick, tctx->tlsext_tick_key_name, 16)) {
      return 2;
    }
    if (!HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16, tlsext_tick_md(),
                      NULL) ||
        !EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL,
                            tctx->tlsext_tick_aes_key, etick + 16)) {
      HMAC_CTX_cleanup(&hctx);
      EVP_CIPHER_CTX_cleanup(&ctx);
      return -1;
    }
  }

  /* Attempt to process session ticket, first conduct sanity and integrity
   * checks on ticket. */
  mlen = HMAC_size(&hctx);
  if (mlen < 0) {
    HMAC_CTX_cleanup(&hctx);
    EVP_CIPHER_CTX_cleanup(&ctx);
    return -1;
  }
  eticklen -= mlen;
  /* Check HMAC of encrypted ticket */
  HMAC_Update(&hctx, etick, eticklen);
  HMAC_Final(&hctx, tick_hmac, NULL);
  HMAC_CTX_cleanup(&hctx);
  if (CRYPTO_memcmp(tick_hmac, etick + eticklen, mlen)) {
    EVP_CIPHER_CTX_cleanup(&ctx);
    return 2;
  }

  /* Attempt to decrypt session data */
  /* Move p after IV to start of encrypted ticket, update length */
  p = etick + 16 + EVP_CIPHER_CTX_iv_length(&ctx);
  eticklen -= 16 + EVP_CIPHER_CTX_iv_length(&ctx);
  sdec = OPENSSL_malloc(eticklen);
  if (!sdec) {
    EVP_CIPHER_CTX_cleanup(&ctx);
    return -1;
  }
  EVP_DecryptUpdate(&ctx, sdec, &slen, p, eticklen);
  if (EVP_DecryptFinal_ex(&ctx, sdec + slen, &mlen) <= 0) {
    EVP_CIPHER_CTX_cleanup(&ctx);
    OPENSSL_free(sdec);
    return 2;
  }
  slen += mlen;
  EVP_CIPHER_CTX_cleanup(&ctx);
  p = sdec;

  sess = d2i_SSL_SESSION(NULL, &p, slen);
  OPENSSL_free(sdec);
  if (sess) {
    /* The session ID, if non-empty, is used by some clients to detect that the
     * ticket has been accepted. So we copy it to the session structure. If it
     * is empty set length to zero as required by standard. */
    if (sesslen) {
      memcpy(sess->session_id, sess_id, sesslen);
    }
    sess->session_id_length = sesslen;
    *psess = sess;
    if (renew_ticket) {
      return 4;
    }
    return 3;
  }

  ERR_clear_error();
  /* For session parse failure, indicate that we need to send a new ticket. */
  return 2;
}

/* Tables to translate from NIDs to TLS v1.2 ids */
typedef struct {
  int nid;
  int id;
} tls12_lookup;

static const tls12_lookup tls12_md[] = {{NID_md5, TLSEXT_hash_md5},
                                        {NID_sha1, TLSEXT_hash_sha1},
                                        {NID_sha224, TLSEXT_hash_sha224},
                                        {NID_sha256, TLSEXT_hash_sha256},
                                        {NID_sha384, TLSEXT_hash_sha384},
                                        {NID_sha512, TLSEXT_hash_sha512}};

static const tls12_lookup tls12_sig[] = {{EVP_PKEY_RSA, TLSEXT_signature_rsa},
                                         {EVP_PKEY_EC, TLSEXT_signature_ecdsa}};

static int tls12_find_id(int nid, const tls12_lookup *table, size_t tlen) {
  size_t i;
  for (i = 0; i < tlen; i++) {
    if (table[i].nid == nid) {
      return table[i].id;
    }
  }

  return -1;
}

static int tls12_find_nid(int id, const tls12_lookup *table, size_t tlen) {
  size_t i;
  for (i = 0; i < tlen; i++) {
    if (table[i].id == id) {
      return table[i].nid;
    }
  }

  return NID_undef;
}

int tls12_get_sigandhash(uint8_t *p, const EVP_PKEY *pk, const EVP_MD *md) {
  int sig_id, md_id;

  if (!md) {
    return 0;
  }

  md_id = tls12_find_id(EVP_MD_type(md), tls12_md,
                        sizeof(tls12_md) / sizeof(tls12_lookup));
  if (md_id == -1) {
    return 0;
  }

  sig_id = tls12_get_sigid(pk);
  if (sig_id == -1) {
    return 0;
  }

  p[0] = (uint8_t)md_id;
  p[1] = (uint8_t)sig_id;
  return 1;
}

int tls12_get_sigid(const EVP_PKEY *pk) {
  return tls12_find_id(pk->type, tls12_sig,
                       sizeof(tls12_sig) / sizeof(tls12_lookup));
}

const EVP_MD *tls12_get_hash(uint8_t hash_alg) {
  switch (hash_alg) {
    case TLSEXT_hash_md5:
      return EVP_md5();

    case TLSEXT_hash_sha1:
      return EVP_sha1();

    case TLSEXT_hash_sha224:
      return EVP_sha224();

    case TLSEXT_hash_sha256:
      return EVP_sha256();

    case TLSEXT_hash_sha384:
      return EVP_sha384();

    case TLSEXT_hash_sha512:
      return EVP_sha512();

    default:
      return NULL;
  }
}

/* tls12_get_pkey_type returns the EVP_PKEY type corresponding to TLS signature
 * algorithm |sig_alg|. It returns -1 if the type is unknown. */
static int tls12_get_pkey_type(uint8_t sig_alg) {
  switch (sig_alg) {
    case TLSEXT_signature_rsa:
      return EVP_PKEY_RSA;

    case TLSEXT_signature_ecdsa:
      return EVP_PKEY_EC;

    default:
      return -1;
  }
}

/* Convert TLS 1.2 signature algorithm extension values into NIDs */
static void tls1_lookup_sigalg(int *phash_nid, int *psign_nid,
                               int *psignhash_nid, const uint8_t *data) {
  int sign_nid = 0, hash_nid = 0;
  if (!phash_nid && !psign_nid && !psignhash_nid) {
    return;
  }

  if (phash_nid || psignhash_nid) {
    hash_nid = tls12_find_nid(data[0], tls12_md,
                              sizeof(tls12_md) / sizeof(tls12_lookup));
    if (phash_nid) {
      *phash_nid = hash_nid;
    }
  }

  if (psign_nid || psignhash_nid) {
    sign_nid = tls12_find_nid(data[1], tls12_sig,
                              sizeof(tls12_sig) / sizeof(tls12_lookup));
    if (psign_nid) {
      *psign_nid = sign_nid;
    }
  }

  if (psignhash_nid) {
    if (sign_nid && hash_nid) {
      OBJ_find_sigid_by_algs(psignhash_nid, hash_nid, sign_nid);
    } else {
      *psignhash_nid = NID_undef;
    }
  }
}

/* Given preference and allowed sigalgs set shared sigalgs */
static int tls12_do_shared_sigalgs(TLS_SIGALGS *shsig, const uint8_t *pref,
                                   size_t preflen, const uint8_t *allow,
                                   size_t allowlen) {
  const uint8_t *ptmp, *atmp;
  size_t i, j, nmatch = 0;

  for (i = 0, ptmp = pref; i < preflen; i += 2, ptmp += 2) {
    /* Skip disabled hashes or signature algorithms */
    if (tls12_get_hash(ptmp[0]) == NULL ||
        tls12_get_pkey_type(ptmp[1]) == -1) {
      continue;
    }

    for (j = 0, atmp = allow; j < allowlen; j += 2, atmp += 2) {
      if (ptmp[0] == atmp[0] && ptmp[1] == atmp[1]) {
        nmatch++;
        if (shsig) {
          shsig->rhash = ptmp[0];
          shsig->rsign = ptmp[1];
          tls1_lookup_sigalg(&shsig->hash_nid, &shsig->sign_nid,
                             &shsig->signandhash_nid, ptmp);
          shsig++;
        }

        break;
      }
    }
  }

  return nmatch;
}

/* Set shared signature algorithms for SSL structures */
static int tls1_set_shared_sigalgs(SSL *s) {
  const uint8_t *pref, *allow, *conf;
  size_t preflen, allowlen, conflen;
  size_t nmatch;
  TLS_SIGALGS *salgs = NULL;
  CERT *c = s->cert;

  if (c->shared_sigalgs) {
    OPENSSL_free(c->shared_sigalgs);
    c->shared_sigalgs = NULL;
  }

  /* If client use client signature algorithms if not NULL */
  if (!s->server && c->client_sigalgs) {
    conf = c->client_sigalgs;
    conflen = c->client_sigalgslen;
  } else if (c->conf_sigalgs) {
    conf = c->conf_sigalgs;
    conflen = c->conf_sigalgslen;
  } else {
    conflen = tls12_get_psigalgs(s, &conf);
  }

  if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) {
    pref = conf;
    preflen = conflen;
    allow = c->peer_sigalgs;
    allowlen = c->peer_sigalgslen;
  } else {
    allow = conf;
    allowlen = conflen;
    pref = c->peer_sigalgs;
    preflen = c->peer_sigalgslen;
  }

  nmatch = tls12_do_shared_sigalgs(NULL, pref, preflen, allow, allowlen);
  if (!nmatch) {
    return 1;
  }

  salgs = OPENSSL_malloc(nmatch * sizeof(TLS_SIGALGS));
  if (!salgs) {
    return 0;
  }

  nmatch = tls12_do_shared_sigalgs(salgs, pref, preflen, allow, allowlen);
  c->shared_sigalgs = salgs;
  c->shared_sigalgslen = nmatch;
  return 1;
}

/* Set preferred digest for each key type */
int tls1_process_sigalgs(SSL *s, const CBS *sigalgs) {
  CERT *c = s->cert;

  /* Extension ignored for inappropriate versions */
  if (!SSL_USE_SIGALGS(s)) {
    return 1;
  }

  /* Length must be even */
  if (CBS_len(sigalgs) % 2 != 0) {
    return 0;
  }

  /* Should never happen */
  if (!c) {
    return 0;
  }

  if (!CBS_stow(sigalgs, &c->peer_sigalgs, &c->peer_sigalgslen)) {
    return 0;
  }

  tls1_set_shared_sigalgs(s);
  return 1;
}

const EVP_MD *tls1_choose_signing_digest(SSL *s, EVP_PKEY *pkey) {
  CERT *c = s->cert;
  int type = EVP_PKEY_id(pkey);
  size_t i;

  /* Select the first shared digest supported by our key. */
  for (i = 0; i < c->shared_sigalgslen; i++) {
    const EVP_MD *md = tls12_get_hash(c->shared_sigalgs[i].rhash);
    if (md == NULL ||
        tls12_get_pkey_type(c->shared_sigalgs[i].rsign) != type ||
        !EVP_PKEY_supports_digest(pkey, md)) {
      continue;
    }
    return md;
  }

  /* If no suitable digest may be found, default to SHA-1. */
  return EVP_sha1();
}

int SSL_get_sigalgs(SSL *s, int idx, int *psign, int *phash, int *psignhash,
                    uint8_t *rsig, uint8_t *rhash) {
  const uint8_t *psig = s->cert->peer_sigalgs;

  if (psig == NULL) {
    return 0;
  }

  if (idx >= 0) {
    idx <<= 1;
    if (idx >= (int)s->cert->peer_sigalgslen) {
      return 0;
    }
    psig += idx;
    if (rhash) {
      *rhash = psig[0];
    }
    if (rsig) {
      *rsig = psig[1];
    }
    tls1_lookup_sigalg(phash, psign, psignhash, psig);
  }

  return s->cert->peer_sigalgslen / 2;
}

int SSL_get_shared_sigalgs(SSL *s, int idx, int *psign, int *phash,
                           int *psignhash, uint8_t *rsig, uint8_t *rhash) {
  TLS_SIGALGS *shsigalgs = s->cert->shared_sigalgs;

  if (!shsigalgs || idx >= (int)s->cert->shared_sigalgslen) {
    return 0;
  }

  shsigalgs += idx;
  if (phash) {
    *phash = shsigalgs->hash_nid;
  }
  if (psign) {
    *psign = shsigalgs->sign_nid;
  }
  if (psignhash) {
    *psignhash = shsigalgs->signandhash_nid;
  }
  if (rsig) {
    *rsig = shsigalgs->rsign;
  }
  if (rhash) {
    *rhash = shsigalgs->rhash;
  }

  return s->cert->shared_sigalgslen;
}

/* tls1_channel_id_hash calculates the signed data for a Channel ID on the
 * given SSL connection and writes it to |md|. */
int tls1_channel_id_hash(EVP_MD_CTX *md, SSL *s) {
  EVP_MD_CTX ctx;
  uint8_t temp_digest[EVP_MAX_MD_SIZE];
  unsigned temp_digest_len;
  int i;
  static const char kClientIDMagic[] = "TLS Channel ID signature";

  if (s->s3->handshake_buffer &&
      !ssl3_digest_cached_records(s, free_handshake_buffer)) {
    return 0;
  }

  EVP_DigestUpdate(md, kClientIDMagic, sizeof(kClientIDMagic));

  if (s->hit && s->s3->tlsext_channel_id_new) {
    static const char kResumptionMagic[] = "Resumption";
    EVP_DigestUpdate(md, kResumptionMagic, sizeof(kResumptionMagic));
    if (s->session->original_handshake_hash_len == 0) {
      return 0;
    }
    EVP_DigestUpdate(md, s->session->original_handshake_hash,
                     s->session->original_handshake_hash_len);
  }

  EVP_MD_CTX_init(&ctx);
  for (i = 0; i < SSL_MAX_DIGEST; i++) {
    if (s->s3->handshake_dgst[i] == NULL) {
      continue;
    }
    EVP_MD_CTX_copy_ex(&ctx, s->s3->handshake_dgst[i]);
    EVP_DigestFinal_ex(&ctx, temp_digest, &temp_digest_len);
    EVP_DigestUpdate(md, temp_digest, temp_digest_len);
  }
  EVP_MD_CTX_cleanup(&ctx);

  return 1;
}

/* tls1_record_handshake_hashes_for_channel_id records the current handshake
 * hashes in |s->session| so that Channel ID resumptions can sign that data. */
int tls1_record_handshake_hashes_for_channel_id(SSL *s) {
  int digest_len;
  /* This function should never be called for a resumed session because the
   * handshake hashes that we wish to record are for the original, full
   * handshake. */
  if (s->hit) {
    return -1;
  }

  /* It only makes sense to call this function if Channel IDs have been
   * negotiated. */
  if (!s->s3->tlsext_channel_id_new) {
    return -1;
  }

  digest_len =
      tls1_handshake_digest(s, s->session->original_handshake_hash,
                            sizeof(s->session->original_handshake_hash));
  if (digest_len < 0) {
    return -1;
  }

  s->session->original_handshake_hash_len = digest_len;

  return 1;
}

int tls1_set_sigalgs(CERT *c, const int *psig_nids, size_t salglen,
                     int client) {
  uint8_t *sigalgs, *sptr;
  int rhash, rsign;
  size_t i;

  if (salglen & 1) {
    return 0;
  }

  sigalgs = OPENSSL_malloc(salglen);
  if (sigalgs == NULL) {
    return 0;
  }

  for (i = 0, sptr = sigalgs; i < salglen; i += 2) {
    rhash = tls12_find_id(*psig_nids++, tls12_md,
                          sizeof(tls12_md) / sizeof(tls12_lookup));
    rsign = tls12_find_id(*psig_nids++, tls12_sig,
                          sizeof(tls12_sig) / sizeof(tls12_lookup));

    if (rhash == -1 || rsign == -1) {
      goto err;
    }
    *sptr++ = rhash;
    *sptr++ = rsign;
  }

  if (client) {
    if (c->client_sigalgs) {
      OPENSSL_free(c->client_sigalgs);
    }
    c->client_sigalgs = sigalgs;
    c->client_sigalgslen = salglen;
  } else {
    if (c->conf_sigalgs) {
      OPENSSL_free(c->conf_sigalgs);
    }
    c->conf_sigalgs = sigalgs;
    c->conf_sigalgslen = salglen;
  }

  return 1;

err:
  OPENSSL_free(sigalgs);
  return 0;
}
