/* 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 <openssl/ssl.h>

#include <assert.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>

#include <openssl/bytestring.h>
#include <openssl/digest.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/hmac.h>
#include <openssl/mem.h>
#include <openssl/nid.h>
#include <openssl/rand.h>
#include <openssl/type_check.h>

#include "internal.h"


static int ssl_check_clienthello_tlsext(SSL *ssl);
static int ssl_check_serverhello_tlsext(SSL *ssl);

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 = OPENSSL_malloc(sizeof(uint16_t) * num_extensions);
  if (extension_types == NULL) {
    OPENSSL_PUT_ERROR(SSL, 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:
  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;
}

int 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;
}

static const uint16_t kDefaultGroups[] = {
    SSL_GROUP_X25519,
    SSL_GROUP_SECP256R1,
    SSL_GROUP_SECP384R1,
#if defined(BORINGSSL_ANDROID_SYSTEM)
    SSL_GROUP_SECP521R1,
#endif
};

/* tls1_get_grouplist sets |*out_group_ids| and |*out_group_ids_len| to the
 * list of allowed group IDs. If |get_peer_groups| is non-zero, return the
 * peer's group list. Otherwise, return the preferred list. */
static void tls1_get_grouplist(SSL *ssl, int get_peer_groups,
                               const uint16_t **out_group_ids,
                               size_t *out_group_ids_len) {
  if (get_peer_groups) {
    /* Only clients send a supported group list, so this function is only
     * called on the server. */
    assert(ssl->server);
    *out_group_ids = ssl->s3->tmp.peer_supported_group_list;
    *out_group_ids_len = ssl->s3->tmp.peer_supported_group_list_len;
    return;
  }

  *out_group_ids = ssl->supported_group_list;
  *out_group_ids_len = ssl->supported_group_list_len;
  if (!*out_group_ids) {
    *out_group_ids = kDefaultGroups;
    *out_group_ids_len = sizeof(kDefaultGroups) / sizeof(kDefaultGroups[0]);
  }
}

int tls1_get_shared_group(SSL *ssl, uint16_t *out_group_id) {
  const uint16_t *groups, *peer_groups, *pref, *supp;
  size_t groups_len, peer_groups_len, pref_len, supp_len, i, j;

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

  tls1_get_grouplist(ssl, 0 /* local groups */, &groups, &groups_len);
  tls1_get_grouplist(ssl, 1 /* peer groups */, &peer_groups, &peer_groups_len);

  if (peer_groups_len == 0) {
    /* Clients are not required to send a supported_groups extension. In this
     * case, the server is free to pick any group it likes. See RFC 4492,
     * section 4, paragraph 3.
     *
     * However, in the interests of compatibility, we will skip ECDH if the
     * client didn't send an extension because we can't be sure that they'll
     * support our favoured group. */
    return 0;
  }

  if (ssl->options & SSL_OP_CIPHER_SERVER_PREFERENCE) {
    pref = groups;
    pref_len = groups_len;
    supp = peer_groups;
    supp_len = peer_groups_len;
  } else {
    pref = peer_groups;
    pref_len = peer_groups_len;
    supp = groups;
    supp_len = groups_len;
  }

  for (i = 0; i < pref_len; i++) {
    for (j = 0; j < supp_len; j++) {
      if (pref[i] == supp[j]) {
        *out_group_id = pref[i];
        return 1;
      }
    }
  }

  return 0;
}

int tls1_set_curves(uint16_t **out_group_ids, size_t *out_group_ids_len,
                    const int *curves, size_t ncurves) {
  uint16_t *group_ids;
  size_t i;

  group_ids = OPENSSL_malloc(ncurves * sizeof(uint16_t));
  if (group_ids == NULL) {
    return 0;
  }

  for (i = 0; i < ncurves; i++) {
    if (!ssl_nid_to_group_id(&group_ids[i], curves[i])) {
      OPENSSL_free(group_ids);
      return 0;
    }
  }

  OPENSSL_free(*out_group_ids);
  *out_group_ids = group_ids;
  *out_group_ids_len = ncurves;

  return 1;
}

/* tls1_curve_params_from_ec_key sets |*out_group_id| and |*out_comp_id| to the
 * TLS group 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_group_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 group ID */
  nid = EC_GROUP_get_curve_name(grp);
  if (!ssl_nid_to_group_id(&id, nid)) {
    return 0;
  }

  /* Set the named group ID. Arbitrary explicit groups are not supported. */
  *out_group_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_group_id returns one if |group_id| is consistent with both our
 * and the peer's group preferences. Note: if called as the client, only our
 * preferences are checked; the peer (the server) does not send preferences. */
int tls1_check_group_id(SSL *ssl, uint16_t group_id) {
  const uint16_t *groups;
  size_t groups_len, i, get_peer_groups;

  /* Check against our list, then the peer's list. */
  for (get_peer_groups = 0; get_peer_groups <= 1; get_peer_groups++) {
    if (get_peer_groups && !ssl->server) {
      /* Servers do not present a preference list so, if we are a client, only
       * check our list. */
      continue;
    }

    tls1_get_grouplist(ssl, get_peer_groups, &groups, &groups_len);
    if (get_peer_groups && groups_len == 0) {
      /* Clients are not required to send a supported_groups extension. In this
       * case, the server is free to pick any group it likes. See RFC 4492,
       * section 4, paragraph 3. */
      continue;
    }
    for (i = 0; i < groups_len; i++) {
      if (groups[i] == group_id) {
        break;
      }
    }

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

  return 1;
}

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

  if (!pkey) {
    goto done;
  }
  EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(pkey);
  if (ec_key == NULL ||
      !tls1_curve_params_from_ec_key(&group_id, &comp_id, ec_key) ||
      !tls1_check_group_id(ssl, group_id) ||
      comp_id != TLSEXT_ECPOINTFORMAT_uncompressed) {
    goto done;
  }

  ret = 1;

done:
  EVP_PKEY_free(pkey);
  return ret;
}

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

static const uint16_t kDefaultSignatureAlgorithms[] = {
    SSL_SIGN_RSA_PKCS1_SHA512,
    SSL_SIGN_ECDSA_SECP521R1_SHA512,

    SSL_SIGN_RSA_PKCS1_SHA384,
    SSL_SIGN_ECDSA_SECP384R1_SHA384,

    SSL_SIGN_RSA_PKCS1_SHA256,
    SSL_SIGN_ECDSA_SECP256R1_SHA256,

    SSL_SIGN_RSA_PKCS1_SHA1,
    SSL_SIGN_ECDSA_SHA1,
};

size_t tls12_get_psigalgs(SSL *ssl, const uint16_t **psigs) {
  *psigs = kDefaultSignatureAlgorithms;
  return sizeof(kDefaultSignatureAlgorithms) /
         sizeof(kDefaultSignatureAlgorithms[0]);
}

static int tls12_get_pkey_type(uint16_t sig_alg);
static const EVP_MD *tls12_get_hash(uint16_t sig_alg);

int tls12_check_peer_sigalg(SSL *ssl, const EVP_MD **out_md, int *out_alert,
                            uint16_t signature_algorithm, EVP_PKEY *pkey) {
  const uint16_t *sent_sigs;
  size_t sent_sigslen, i;

  /* Check key type is consistent with signature */
  if (pkey->type != tls12_get_pkey_type(signature_algorithm)) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SIGNATURE_TYPE);
    *out_alert = SSL_AD_ILLEGAL_PARAMETER;
    return 0;
  }

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

  if (i == sent_sigslen) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SIGNATURE_TYPE);
    *out_alert = SSL_AD_ILLEGAL_PARAMETER;
    return 0;
  }

  *out_md = tls12_get_hash(signature_algorithm);
  if (*out_md == NULL) {
    OPENSSL_PUT_ERROR(SSL, 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 *ssl) {
  CERT *c = ssl->cert;
  const uint16_t *sigalgs;
  size_t i, sigalgslen;
  int have_rsa = 0, have_ecdsa = 0;
  c->mask_a = 0;
  c->mask_k = 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(ssl, &sigalgs);
  for (i = 0; i < sigalgslen; i++) {
    switch (sigalgs[i]) {
      case SSL_SIGN_RSA_PKCS1_SHA512:
      case SSL_SIGN_RSA_PKCS1_SHA384:
      case SSL_SIGN_RSA_PKCS1_SHA256:
      case SSL_SIGN_RSA_PKCS1_SHA1:
        have_rsa = 1;
        break;

      case SSL_SIGN_ECDSA_SECP521R1_SHA512:
      case SSL_SIGN_ECDSA_SECP384R1_SHA384:
      case SSL_SIGN_ECDSA_SECP256R1_SHA256:
      case SSL_SIGN_ECDSA_SHA1:
        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 (!ssl->psk_client_callback) {
    c->mask_a |= SSL_aPSK;
    c->mask_k |= SSL_kPSK;
  }
}

/* tls_extension represents a TLS extension that is handled internally. The
 * |init| function is called for each handshake, before any other functions of
 * the extension. Then the add and parse callbacks are called as needed.
 *
 * The parse callbacks receive a |CBS| that contains the contents of the
 * extension (i.e. not including the type and length bytes). If an extension is
 * not received then the parse callbacks will be called with a NULL CBS so that
 * they can do any processing needed to handle the absence of an extension.
 *
 * The add callbacks receive a |CBB| to which the extension can be appended but
 * the function is responsible for appending the type and length bytes too.
 *
 * All callbacks return one for success and zero for error. If a parse function
 * returns zero then a fatal alert with value |*out_alert| will be sent. If
 * |*out_alert| isn't set, then a |decode_error| alert will be sent. */
struct tls_extension {
  uint16_t value;
  void (*init)(SSL *ssl);

  int (*add_clienthello)(SSL *ssl, CBB *out);
  int (*parse_serverhello)(SSL *ssl, uint8_t *out_alert, CBS *contents);

  int (*parse_clienthello)(SSL *ssl, uint8_t *out_alert, CBS *contents);
  int (*add_serverhello)(SSL *ssl, CBB *out);
};


/* Server name indication (SNI).
 *
 * https://tools.ietf.org/html/rfc6066#section-3. */

static void ext_sni_init(SSL *ssl) {
  ssl->s3->tmp.should_ack_sni = 0;
}

static int ext_sni_add_clienthello(SSL *ssl, CBB *out) {
  if (ssl->tlsext_hostname == NULL) {
    return 1;
  }

  CBB contents, server_name_list, name;
  if (!CBB_add_u16(out, TLSEXT_TYPE_server_name) ||
      !CBB_add_u16_length_prefixed(out, &contents) ||
      !CBB_add_u16_length_prefixed(&contents, &server_name_list) ||
      !CBB_add_u8(&server_name_list, TLSEXT_NAMETYPE_host_name) ||
      !CBB_add_u16_length_prefixed(&server_name_list, &name) ||
      !CBB_add_bytes(&name, (const uint8_t *)ssl->tlsext_hostname,
                     strlen(ssl->tlsext_hostname)) ||
      !CBB_flush(out)) {
    return 0;
  }

  return 1;
}

static int ext_sni_parse_serverhello(SSL *ssl, uint8_t *out_alert,
                                     CBS *contents) {
  if (contents == NULL) {
    return 1;
  }

  if (CBS_len(contents) != 0) {
    return 0;
  }

  assert(ssl->tlsext_hostname != NULL);

  if (!ssl->hit) {
    assert(ssl->session->tlsext_hostname == NULL);
    ssl->session->tlsext_hostname = BUF_strdup(ssl->tlsext_hostname);
    if (!ssl->session->tlsext_hostname) {
      *out_alert = SSL_AD_INTERNAL_ERROR;
      return 0;
    }
  }

  return 1;
}

static int ext_sni_parse_clienthello(SSL *ssl, uint8_t *out_alert,
                                     CBS *contents) {
  if (contents == NULL) {
    return 1;
  }

  CBS server_name_list, host_name;
  uint8_t name_type;
  if (!CBS_get_u16_length_prefixed(contents, &server_name_list) ||
      !CBS_get_u8(&server_name_list, &name_type) ||
      /* Although the server_name extension was intended to be extensible to
       * new name types and multiple names, OpenSSL 1.0.x had a bug which meant
       * different name types will cause an error. Further, RFC 4366 originally
       * defined syntax inextensibly. RFC 6066 corrected this mistake, but
       * adding new name types is no longer feasible.
       *
       * Act as if the extensibility does not exist to simplify parsing. */
      !CBS_get_u16_length_prefixed(&server_name_list, &host_name) ||
      CBS_len(&server_name_list) != 0 ||
      CBS_len(contents) != 0) {
    return 0;
  }

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

  /* TODO(davidben): SNI should be resolved before resumption. We have the
   * early callback as a replacement, but we should fix the current callback
   * and avoid the need for |SSL_CTX_set_session_id_context|. */
  if (!ssl->hit) {
    assert(ssl->session->tlsext_hostname == NULL);

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

    ssl->s3->tmp.should_ack_sni = 1;
  }

  return 1;
}

static int ext_sni_add_serverhello(SSL *ssl, CBB *out) {
  if (ssl->hit ||
      !ssl->s3->tmp.should_ack_sni ||
      ssl->session->tlsext_hostname == NULL) {
    return 1;
  }

  if (!CBB_add_u16(out, TLSEXT_TYPE_server_name) ||
      !CBB_add_u16(out, 0 /* length */)) {
    return 0;
  }

  return 1;
}


/* Renegotiation indication.
 *
 * https://tools.ietf.org/html/rfc5746 */

static int ext_ri_add_clienthello(SSL *ssl, CBB *out) {
  CBB contents, prev_finished;
  if (!CBB_add_u16(out, TLSEXT_TYPE_renegotiate) ||
      !CBB_add_u16_length_prefixed(out, &contents) ||
      !CBB_add_u8_length_prefixed(&contents, &prev_finished) ||
      !CBB_add_bytes(&prev_finished, ssl->s3->previous_client_finished,
                     ssl->s3->previous_client_finished_len) ||
      !CBB_flush(out)) {
    return 0;
  }

  return 1;
}

static int ext_ri_parse_serverhello(SSL *ssl, uint8_t *out_alert,
                                    CBS *contents) {
  /* Servers may not switch between omitting the extension and supporting it.
   * See RFC 5746, sections 3.5 and 4.2. */
  if (ssl->s3->initial_handshake_complete &&
      (contents != NULL) != ssl->s3->send_connection_binding) {
    *out_alert = SSL_AD_HANDSHAKE_FAILURE;
    OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_MISMATCH);
    return 0;
  }

  if (contents == NULL) {
    /* Strictly speaking, if we want to avoid an attack we should *always* see
     * RI even on initial ServerHello 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.
     *
     * OpenSSL has |SSL_OP_LEGACY_SERVER_CONNECT| to control this, but in
     * practical terms every client sets it so it's just assumed here. */
    return 1;
  }

  const size_t expected_len = ssl->s3->previous_client_finished_len +
                              ssl->s3->previous_server_finished_len;

  /* Check for logic errors */
  assert(!expected_len || ssl->s3->previous_client_finished_len);
  assert(!expected_len || ssl->s3->previous_server_finished_len);

  /* Parse out the extension contents. */
  CBS renegotiated_connection;
  if (!CBS_get_u8_length_prefixed(contents, &renegotiated_connection) ||
      CBS_len(contents) != 0) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_ENCODING_ERR);
    *out_alert = SSL_AD_ILLEGAL_PARAMETER;
    return 0;
  }

  /* Check that the extension matches. */
  if (CBS_len(&renegotiated_connection) != expected_len) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_MISMATCH);
    *out_alert = SSL_AD_HANDSHAKE_FAILURE;
    return 0;
  }

  const uint8_t *d = CBS_data(&renegotiated_connection);
  if (CRYPTO_memcmp(d, ssl->s3->previous_client_finished,
        ssl->s3->previous_client_finished_len)) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_MISMATCH);
    *out_alert = SSL_AD_HANDSHAKE_FAILURE;
    return 0;
  }
  d += ssl->s3->previous_client_finished_len;

  if (CRYPTO_memcmp(d, ssl->s3->previous_server_finished,
        ssl->s3->previous_server_finished_len)) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_MISMATCH);
    *out_alert = SSL_AD_ILLEGAL_PARAMETER;
    return 0;
  }
  ssl->s3->send_connection_binding = 1;

  return 1;
}

static int ext_ri_parse_clienthello(SSL *ssl, uint8_t *out_alert,
                                    CBS *contents) {
  /* Renegotiation isn't supported as a server so this function should never be
   * called after the initial handshake. */
  assert(!ssl->s3->initial_handshake_complete);

  CBS fake_contents;
  static const uint8_t kFakeExtension[] = {0};

  if (contents == NULL) {
    if (ssl->s3->send_connection_binding) {
      /* The renegotiation SCSV was received so pretend that we received a
       * renegotiation extension. */
      CBS_init(&fake_contents, kFakeExtension, sizeof(kFakeExtension));
      contents = &fake_contents;
      /* We require that the renegotiation extension is at index zero of
       * kExtensions. */
      ssl->s3->tmp.extensions.received |= (1u << 0);
    } else {
      return 1;
    }
  }

  CBS renegotiated_connection;

  if (!CBS_get_u8_length_prefixed(contents, &renegotiated_connection) ||
      CBS_len(contents) != 0) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_ENCODING_ERR);
    return 0;
  }

  /* Check that the extension matches */
  if (!CBS_mem_equal(&renegotiated_connection,
                     ssl->s3->previous_client_finished,
                     ssl->s3->previous_client_finished_len)) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_MISMATCH);
    *out_alert = SSL_AD_HANDSHAKE_FAILURE;
    return 0;
  }

  ssl->s3->send_connection_binding = 1;

  return 1;
}

static int ext_ri_add_serverhello(SSL *ssl, CBB *out) {
  CBB contents, prev_finished;
  if (!CBB_add_u16(out, TLSEXT_TYPE_renegotiate) ||
      !CBB_add_u16_length_prefixed(out, &contents) ||
      !CBB_add_u8_length_prefixed(&contents, &prev_finished) ||
      !CBB_add_bytes(&prev_finished, ssl->s3->previous_client_finished,
                     ssl->s3->previous_client_finished_len) ||
      !CBB_add_bytes(&prev_finished, ssl->s3->previous_server_finished,
                     ssl->s3->previous_server_finished_len) ||
      !CBB_flush(out)) {
    return 0;
  }

  return 1;
}


/* Extended Master Secret.
 *
 * https://tools.ietf.org/html/rfc7627 */

static void ext_ems_init(SSL *ssl) {
  ssl->s3->tmp.extended_master_secret = 0;
}

static int ext_ems_add_clienthello(SSL *ssl, CBB *out) {
  if (ssl->version == SSL3_VERSION) {
    return 1;
  }

  if (!CBB_add_u16(out, TLSEXT_TYPE_extended_master_secret) ||
      !CBB_add_u16(out, 0 /* length */)) {
    return 0;
  }

  return 1;
}

static int ext_ems_parse_serverhello(SSL *ssl, uint8_t *out_alert,
                                     CBS *contents) {
  if (contents == NULL) {
    return 1;
  }

  if (ssl->version == SSL3_VERSION || CBS_len(contents) != 0) {
    return 0;
  }

  ssl->s3->tmp.extended_master_secret = 1;
  return 1;
}

static int ext_ems_parse_clienthello(SSL *ssl, uint8_t *out_alert,
                                     CBS *contents) {
  if (ssl->version == SSL3_VERSION || contents == NULL) {
    return 1;
  }

  if (CBS_len(contents) != 0) {
    return 0;
  }

  ssl->s3->tmp.extended_master_secret = 1;
  return 1;
}

static int ext_ems_add_serverhello(SSL *ssl, CBB *out) {
  if (!ssl->s3->tmp.extended_master_secret) {
    return 1;
  }

  if (!CBB_add_u16(out, TLSEXT_TYPE_extended_master_secret) ||
      !CBB_add_u16(out, 0 /* length */)) {
    return 0;
  }

  return 1;
}


/* Session tickets.
 *
 * https://tools.ietf.org/html/rfc5077 */

static int ext_ticket_add_clienthello(SSL *ssl, CBB *out) {
  if (SSL_get_options(ssl) & SSL_OP_NO_TICKET) {
    return 1;
  }

  const uint8_t *ticket_data = NULL;
  int ticket_len = 0;

  /* Renegotiation does not participate in session resumption. However, still
   * advertise the extension to avoid potentially breaking servers which carry
   * over the state from the previous handshake, such as OpenSSL servers
   * without upstream's 3c3f0259238594d77264a78944d409f2127642c4. */
  if (!ssl->s3->initial_handshake_complete &&
      ssl->session != NULL &&
      ssl->session->tlsext_tick != NULL) {
    ticket_data = ssl->session->tlsext_tick;
    ticket_len = ssl->session->tlsext_ticklen;
  }

  CBB ticket;
  if (!CBB_add_u16(out, TLSEXT_TYPE_session_ticket) ||
      !CBB_add_u16_length_prefixed(out, &ticket) ||
      !CBB_add_bytes(&ticket, ticket_data, ticket_len) ||
      !CBB_flush(out)) {
    return 0;
  }

  return 1;
}

static int ext_ticket_parse_serverhello(SSL *ssl, uint8_t *out_alert,
                                        CBS *contents) {
  ssl->tlsext_ticket_expected = 0;

  if (contents == NULL) {
    return 1;
  }

  /* If |SSL_OP_NO_TICKET| is set then no extension will have been sent and
   * this function should never be called, even if the server tries to send the
   * extension. */
  assert((SSL_get_options(ssl) & SSL_OP_NO_TICKET) == 0);

  if (CBS_len(contents) != 0) {
    return 0;
  }

  ssl->tlsext_ticket_expected = 1;
  return 1;
}

static int ext_ticket_parse_clienthello(SSL *ssl, uint8_t *out_alert,
                                        CBS *contents) {
  /* This function isn't used because the ticket extension from the client is
   * handled in ssl_session.c. */
  return 1;
}

static int ext_ticket_add_serverhello(SSL *ssl, CBB *out) {
  if (!ssl->tlsext_ticket_expected) {
    return 1;
  }

  /* If |SSL_OP_NO_TICKET| is set, |tlsext_ticket_expected| should never be
   * true. */
  assert((SSL_get_options(ssl) & SSL_OP_NO_TICKET) == 0);

  if (!CBB_add_u16(out, TLSEXT_TYPE_session_ticket) ||
      !CBB_add_u16(out, 0 /* length */)) {
    return 0;
  }

  return 1;
}


/* Signature Algorithms.
 *
 * https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */

static int ext_sigalgs_add_clienthello(SSL *ssl, CBB *out) {
  if (ssl3_version_from_wire(ssl, ssl->client_version) < TLS1_2_VERSION) {
    return 1;
  }

  const uint16_t *sigalgs_data;
  const size_t sigalgs_len = tls12_get_psigalgs(ssl, &sigalgs_data);

  CBB contents, sigalgs;
  if (!CBB_add_u16(out, TLSEXT_TYPE_signature_algorithms) ||
      !CBB_add_u16_length_prefixed(out, &contents) ||
      !CBB_add_u16_length_prefixed(&contents, &sigalgs)) {
    return 0;
  }

  size_t i;
  for (i = 0; i < sigalgs_len; i++) {
    if (!CBB_add_u16(&sigalgs, sigalgs_data[i])) {
      return 0;
    }
  }

  if (!CBB_flush(out)) {
    return 0;
  }

  return 1;
}

static int ext_sigalgs_parse_serverhello(SSL *ssl, uint8_t *out_alert,
                                         CBS *contents) {
  if (contents != NULL) {
    /* Servers MUST NOT send this extension. */
    *out_alert = SSL_AD_UNSUPPORTED_EXTENSION;
    OPENSSL_PUT_ERROR(SSL, SSL_R_SIGNATURE_ALGORITHMS_EXTENSION_SENT_BY_SERVER);
    return 0;
  }

  return 1;
}

static int ext_sigalgs_parse_clienthello(SSL *ssl, uint8_t *out_alert,
                                         CBS *contents) {
  OPENSSL_free(ssl->cert->peer_sigalgs);
  ssl->cert->peer_sigalgs = NULL;
  ssl->cert->peer_sigalgslen = 0;

  if (contents == NULL) {
    return 1;
  }

  CBS supported_signature_algorithms;
  if (!CBS_get_u16_length_prefixed(contents, &supported_signature_algorithms) ||
      CBS_len(contents) != 0 ||
      CBS_len(&supported_signature_algorithms) == 0 ||
      !tls1_parse_peer_sigalgs(ssl, &supported_signature_algorithms)) {
    return 0;
  }

  return 1;
}

static int ext_sigalgs_add_serverhello(SSL *ssl, CBB *out) {
  /* Servers MUST NOT send this extension. */
  return 1;
}


/* OCSP Stapling.
 *
 * https://tools.ietf.org/html/rfc6066#section-8 */

static void ext_ocsp_init(SSL *ssl) {
  ssl->s3->tmp.certificate_status_expected = 0;
  ssl->tlsext_status_type = -1;
}

static int ext_ocsp_add_clienthello(SSL *ssl, CBB *out) {
  if (!ssl->ocsp_stapling_enabled) {
    return 1;
  }

  CBB contents;
  if (!CBB_add_u16(out, TLSEXT_TYPE_status_request) ||
      !CBB_add_u16_length_prefixed(out, &contents) ||
      !CBB_add_u8(&contents, TLSEXT_STATUSTYPE_ocsp) ||
      !CBB_add_u16(&contents, 0 /* empty responder ID list */) ||
      !CBB_add_u16(&contents, 0 /* empty request extensions */) ||
      !CBB_flush(out)) {
    return 0;
  }

  ssl->tlsext_status_type = TLSEXT_STATUSTYPE_ocsp;
  return 1;
}

static int ext_ocsp_parse_serverhello(SSL *ssl, uint8_t *out_alert,
                                      CBS *contents) {
  if (contents == NULL) {
    return 1;
  }

  if (CBS_len(contents) != 0) {
    return 0;
  }

  ssl->s3->tmp.certificate_status_expected = 1;
  return 1;
}

static int ext_ocsp_parse_clienthello(SSL *ssl, uint8_t *out_alert,
                                      CBS *contents) {
  if (contents == NULL) {
    return 1;
  }

  uint8_t status_type;
  if (!CBS_get_u8(contents, &status_type)) {
    return 0;
  }

  /* We cannot decide whether OCSP stapling will occur yet because the correct
   * SSL_CTX might not have been selected. */
  ssl->s3->tmp.ocsp_stapling_requested = status_type == TLSEXT_STATUSTYPE_ocsp;

  return 1;
}

static int ext_ocsp_add_serverhello(SSL *ssl, CBB *out) {
  /* The extension shouldn't be sent when resuming sessions. */
  if (ssl->hit ||
      !ssl->s3->tmp.ocsp_stapling_requested ||
      ssl->ctx->ocsp_response_length == 0) {
    return 1;
  }

  ssl->s3->tmp.certificate_status_expected = 1;

  return CBB_add_u16(out, TLSEXT_TYPE_status_request) &&
         CBB_add_u16(out, 0 /* length */);
}


/* Next protocol negotiation.
 *
 * https://htmlpreview.github.io/?https://github.com/agl/technotes/blob/master/nextprotoneg.html */

static void ext_npn_init(SSL *ssl) {
  ssl->s3->next_proto_neg_seen = 0;
}

static int ext_npn_add_clienthello(SSL *ssl, CBB *out) {
  if (ssl->s3->initial_handshake_complete ||
      ssl->ctx->next_proto_select_cb == NULL ||
      (ssl->options & SSL_OP_DISABLE_NPN) ||
      SSL_IS_DTLS(ssl)) {
    return 1;
  }

  if (!CBB_add_u16(out, TLSEXT_TYPE_next_proto_neg) ||
      !CBB_add_u16(out, 0 /* length */)) {
    return 0;
  }

  return 1;
}

static int ext_npn_parse_serverhello(SSL *ssl, uint8_t *out_alert,
                                     CBS *contents) {
  if (contents == NULL) {
    return 1;
  }

  /* If any of these are false then we should never have sent the NPN
   * extension in the ClientHello and thus this function should never have been
   * called. */
  assert(!ssl->s3->initial_handshake_complete);
  assert(!SSL_IS_DTLS(ssl));
  assert(ssl->ctx->next_proto_select_cb != NULL);
  assert(!(ssl->options & SSL_OP_DISABLE_NPN));

  if (ssl->s3->alpn_selected != NULL) {
    /* NPN and ALPN may not be negotiated in the same connection. */
    *out_alert = SSL_AD_ILLEGAL_PARAMETER;
    OPENSSL_PUT_ERROR(SSL, SSL_R_NEGOTIATED_BOTH_NPN_AND_ALPN);
    return 0;
  }

  const uint8_t *const orig_contents = CBS_data(contents);
  const size_t orig_len = CBS_len(contents);

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

  uint8_t *selected;
  uint8_t selected_len;
  if (ssl->ctx->next_proto_select_cb(
          ssl, &selected, &selected_len, orig_contents, orig_len,
          ssl->ctx->next_proto_select_cb_arg) != SSL_TLSEXT_ERR_OK) {
    *out_alert = SSL_AD_INTERNAL_ERROR;
    return 0;
  }

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

  ssl->s3->next_proto_negotiated_len = selected_len;
  ssl->s3->next_proto_neg_seen = 1;

  return 1;
}

static int ext_npn_parse_clienthello(SSL *ssl, uint8_t *out_alert,
                                     CBS *contents) {
  if (contents != NULL && CBS_len(contents) != 0) {
    return 0;
  }

  if (contents == NULL ||
      ssl->s3->initial_handshake_complete ||
      /* If the ALPN extension is seen before NPN, ignore it. (If ALPN is seen
       * afterwards, parsing the ALPN extension will clear
       * |next_proto_neg_seen|. */
      ssl->s3->alpn_selected != NULL ||
      ssl->ctx->next_protos_advertised_cb == NULL ||
      SSL_IS_DTLS(ssl)) {
    return 1;
  }

  ssl->s3->next_proto_neg_seen = 1;
  return 1;
}

static int ext_npn_add_serverhello(SSL *ssl, CBB *out) {
  /* |next_proto_neg_seen| might have been cleared when an ALPN extension was
   * parsed. */
  if (!ssl->s3->next_proto_neg_seen) {
    return 1;
  }

  const uint8_t *npa;
  unsigned npa_len;

  if (ssl->ctx->next_protos_advertised_cb(
          ssl, &npa, &npa_len, ssl->ctx->next_protos_advertised_cb_arg) !=
      SSL_TLSEXT_ERR_OK) {
    ssl->s3->next_proto_neg_seen = 0;
    return 1;
  }

  CBB contents;
  if (!CBB_add_u16(out, TLSEXT_TYPE_next_proto_neg) ||
      !CBB_add_u16_length_prefixed(out, &contents) ||
      !CBB_add_bytes(&contents, npa, npa_len) ||
      !CBB_flush(out)) {
    return 0;
  }

  return 1;
}


/* Signed certificate timestamps.
 *
 * https://tools.ietf.org/html/rfc6962#section-3.3.1 */

static int ext_sct_add_clienthello(SSL *ssl, CBB *out) {
  if (!ssl->signed_cert_timestamps_enabled) {
    return 1;
  }

  if (!CBB_add_u16(out, TLSEXT_TYPE_certificate_timestamp) ||
      !CBB_add_u16(out, 0 /* length */)) {
    return 0;
  }

  return 1;
}

static int ext_sct_parse_serverhello(SSL *ssl, uint8_t *out_alert,
                                     CBS *contents) {
  if (contents == NULL) {
    return 1;
  }

  /* If this is false then we should never have sent the SCT extension in the
   * ClientHello and thus this function should never have been called. */
  assert(ssl->signed_cert_timestamps_enabled);

  if (CBS_len(contents) == 0) {
    *out_alert = SSL_AD_DECODE_ERROR;
    return 0;
  }

  /* Session resumption uses the original session information. */
  if (!ssl->hit &&
      !CBS_stow(contents, &ssl->session->tlsext_signed_cert_timestamp_list,
                &ssl->session->tlsext_signed_cert_timestamp_list_length)) {
    *out_alert = SSL_AD_INTERNAL_ERROR;
    return 0;
  }

  return 1;
}

static int ext_sct_parse_clienthello(SSL *ssl, uint8_t *out_alert,
                                     CBS *contents) {
  return contents == NULL || CBS_len(contents) == 0;
}

static int ext_sct_add_serverhello(SSL *ssl, CBB *out) {
  /* The extension shouldn't be sent when resuming sessions. */
  if (ssl->hit ||
      ssl->ctx->signed_cert_timestamp_list_length == 0) {
    return 1;
  }

  CBB contents;
  return CBB_add_u16(out, TLSEXT_TYPE_certificate_timestamp) &&
         CBB_add_u16_length_prefixed(out, &contents) &&
         CBB_add_bytes(&contents, ssl->ctx->signed_cert_timestamp_list,
                       ssl->ctx->signed_cert_timestamp_list_length) &&
         CBB_flush(out);
}


/* Application-level Protocol Negotiation.
 *
 * https://tools.ietf.org/html/rfc7301 */

static void ext_alpn_init(SSL *ssl) {
  OPENSSL_free(ssl->s3->alpn_selected);
  ssl->s3->alpn_selected = NULL;
}

static int ext_alpn_add_clienthello(SSL *ssl, CBB *out) {
  if (ssl->alpn_client_proto_list == NULL ||
      ssl->s3->initial_handshake_complete) {
    return 1;
  }

  CBB contents, proto_list;
  if (!CBB_add_u16(out, TLSEXT_TYPE_application_layer_protocol_negotiation) ||
      !CBB_add_u16_length_prefixed(out, &contents) ||
      !CBB_add_u16_length_prefixed(&contents, &proto_list) ||
      !CBB_add_bytes(&proto_list, ssl->alpn_client_proto_list,
                     ssl->alpn_client_proto_list_len) ||
      !CBB_flush(out)) {
    return 0;
  }

  return 1;
}

static int ext_alpn_parse_serverhello(SSL *ssl, uint8_t *out_alert,
                                      CBS *contents) {
  if (contents == NULL) {
    return 1;
  }

  assert(!ssl->s3->initial_handshake_complete);
  assert(ssl->alpn_client_proto_list != NULL);

  if (ssl->s3->next_proto_neg_seen) {
    /* NPN and ALPN may not be negotiated in the same connection. */
    *out_alert = SSL_AD_ILLEGAL_PARAMETER;
    OPENSSL_PUT_ERROR(SSL, SSL_R_NEGOTIATED_BOTH_NPN_AND_ALPN);
    return 0;
  }

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

  if (!CBS_stow(&protocol_name, &ssl->s3->alpn_selected,
                &ssl->s3->alpn_selected_len)) {
    *out_alert = SSL_AD_INTERNAL_ERROR;
    return 0;
  }

  return 1;
}

static int ext_alpn_parse_clienthello(SSL *ssl, uint8_t *out_alert,
                                      CBS *contents) {
  if (contents == NULL) {
    return 1;
  }

  if (ssl->ctx->alpn_select_cb == NULL ||
      ssl->s3->initial_handshake_complete) {
    return 1;
  }

  /* ALPN takes precedence over NPN. */
  ssl->s3->next_proto_neg_seen = 0;

  CBS protocol_name_list;
  if (!CBS_get_u16_length_prefixed(contents, &protocol_name_list) ||
      CBS_len(contents) != 0 ||
      CBS_len(&protocol_name_list) < 2) {
    return 0;
  }

  /* Validate the protocol list. */
  CBS 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) ||
        /* Empty protocol names are forbidden. */
        CBS_len(&protocol_name) == 0) {
      return 0;
    }
  }

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

  return 1;
}

static int ext_alpn_add_serverhello(SSL *ssl, CBB *out) {
  if (ssl->s3->alpn_selected == NULL) {
    return 1;
  }

  CBB contents, proto_list, proto;
  if (!CBB_add_u16(out, TLSEXT_TYPE_application_layer_protocol_negotiation) ||
      !CBB_add_u16_length_prefixed(out, &contents) ||
      !CBB_add_u16_length_prefixed(&contents, &proto_list) ||
      !CBB_add_u8_length_prefixed(&proto_list, &proto) ||
      !CBB_add_bytes(&proto, ssl->s3->alpn_selected,
                     ssl->s3->alpn_selected_len) ||
      !CBB_flush(out)) {
    return 0;
  }

  return 1;
}


/* Channel ID.
 *
 * https://tools.ietf.org/html/draft-balfanz-tls-channelid-01 */

static void ext_channel_id_init(SSL *ssl) {
  ssl->s3->tlsext_channel_id_valid = 0;
}

static int ext_channel_id_add_clienthello(SSL *ssl, CBB *out) {
  if (!ssl->tlsext_channel_id_enabled ||
      SSL_IS_DTLS(ssl)) {
    return 1;
  }

  if (!CBB_add_u16(out, TLSEXT_TYPE_channel_id) ||
      !CBB_add_u16(out, 0 /* length */)) {
    return 0;
  }

  return 1;
}

static int ext_channel_id_parse_serverhello(SSL *ssl, uint8_t *out_alert,
                                            CBS *contents) {
  if (contents == NULL) {
    return 1;
  }

  assert(!SSL_IS_DTLS(ssl));
  assert(ssl->tlsext_channel_id_enabled);

  if (CBS_len(contents) != 0) {
    return 0;
  }

  ssl->s3->tlsext_channel_id_valid = 1;
  return 1;
}

static int ext_channel_id_parse_clienthello(SSL *ssl, uint8_t *out_alert,
                                            CBS *contents) {
  if (contents == NULL ||
      !ssl->tlsext_channel_id_enabled ||
      SSL_IS_DTLS(ssl)) {
    return 1;
  }

  if (CBS_len(contents) != 0) {
    return 0;
  }

  ssl->s3->tlsext_channel_id_valid = 1;
  return 1;
}

static int ext_channel_id_add_serverhello(SSL *ssl, CBB *out) {
  if (!ssl->s3->tlsext_channel_id_valid) {
    return 1;
  }

  if (!CBB_add_u16(out, TLSEXT_TYPE_channel_id) ||
      !CBB_add_u16(out, 0 /* length */)) {
    return 0;
  }

  return 1;
}


/* Secure Real-time Transport Protocol (SRTP) extension.
 *
 * https://tools.ietf.org/html/rfc5764 */


static void ext_srtp_init(SSL *ssl) {
  ssl->srtp_profile = NULL;
}

static int ext_srtp_add_clienthello(SSL *ssl, CBB *out) {
  STACK_OF(SRTP_PROTECTION_PROFILE) *profiles = SSL_get_srtp_profiles(ssl);
  if (profiles == NULL) {
    return 1;
  }
  const size_t num_profiles = sk_SRTP_PROTECTION_PROFILE_num(profiles);
  if (num_profiles == 0) {
    return 1;
  }

  CBB contents, profile_ids;
  if (!CBB_add_u16(out, TLSEXT_TYPE_srtp) ||
      !CBB_add_u16_length_prefixed(out, &contents) ||
      !CBB_add_u16_length_prefixed(&contents, &profile_ids)) {
    return 0;
  }

  size_t i;
  for (i = 0; i < num_profiles; i++) {
    if (!CBB_add_u16(&profile_ids,
                     sk_SRTP_PROTECTION_PROFILE_value(profiles, i)->id)) {
      return 0;
    }
  }

  if (!CBB_add_u8(&contents, 0 /* empty use_mki value */) ||
      !CBB_flush(out)) {
    return 0;
  }

  return 1;
}

static int ext_srtp_parse_serverhello(SSL *ssl, uint8_t *out_alert,
                                      CBS *contents) {
  if (contents == NULL) {
    return 1;
  }

  /* The extension consists of a u16-prefixed profile ID list containing a
   * single uint16_t profile ID, then followed by a u8-prefixed srtp_mki field.
   *
   * See https://tools.ietf.org/html/rfc5764#section-4.1.1 */
  CBS profile_ids, srtp_mki;
  uint16_t profile_id;
  if (!CBS_get_u16_length_prefixed(contents, &profile_ids) ||
      !CBS_get_u16(&profile_ids, &profile_id) ||
      CBS_len(&profile_ids) != 0 ||
      !CBS_get_u8_length_prefixed(contents, &srtp_mki) ||
      CBS_len(contents) != 0) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
    return 0;
  }

  if (CBS_len(&srtp_mki) != 0) {
    /* Must be no MKI, since we never offer one. */
    OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SRTP_MKI_VALUE);
    *out_alert = SSL_AD_ILLEGAL_PARAMETER;
    return 0;
  }

  STACK_OF(SRTP_PROTECTION_PROFILE) *profiles = SSL_get_srtp_profiles(ssl);

  /* Check to see if the server gave us something we support (and presumably
   * offered). */
  size_t i;
  for (i = 0; i < sk_SRTP_PROTECTION_PROFILE_num(profiles); i++) {
    const SRTP_PROTECTION_PROFILE *profile =
        sk_SRTP_PROTECTION_PROFILE_value(profiles, i);

    if (profile->id == profile_id) {
      ssl->srtp_profile = profile;
      return 1;
    }
  }

  OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
  *out_alert = SSL_AD_ILLEGAL_PARAMETER;
  return 0;
}

static int ext_srtp_parse_clienthello(SSL *ssl, uint8_t *out_alert,
                                      CBS *contents) {
  if (contents == NULL) {
    return 1;
  }

  CBS profile_ids, srtp_mki;
  if (!CBS_get_u16_length_prefixed(contents, &profile_ids) ||
      CBS_len(&profile_ids) < 2 ||
      !CBS_get_u8_length_prefixed(contents, &srtp_mki) ||
      CBS_len(contents) != 0) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
    return 0;
  }
  /* Discard the MKI value for now. */

  const STACK_OF(SRTP_PROTECTION_PROFILE) *server_profiles =
      SSL_get_srtp_profiles(ssl);

  /* Pick the server's most preferred profile. */
  size_t i;
  for (i = 0; i < sk_SRTP_PROTECTION_PROFILE_num(server_profiles); i++) {
    const SRTP_PROTECTION_PROFILE *server_profile =
        sk_SRTP_PROTECTION_PROFILE_value(server_profiles, i);

    CBS profile_ids_tmp;
    CBS_init(&profile_ids_tmp, CBS_data(&profile_ids), CBS_len(&profile_ids));

    while (CBS_len(&profile_ids_tmp) > 0) {
      uint16_t profile_id;
      if (!CBS_get_u16(&profile_ids_tmp, &profile_id)) {
        return 0;
      }

      if (server_profile->id == profile_id) {
        ssl->srtp_profile = server_profile;
        return 1;
      }
    }
  }

  return 1;
}

static int ext_srtp_add_serverhello(SSL *ssl, CBB *out) {
  if (ssl->srtp_profile == NULL) {
    return 1;
  }

  CBB contents, profile_ids;
  if (!CBB_add_u16(out, TLSEXT_TYPE_srtp) ||
      !CBB_add_u16_length_prefixed(out, &contents) ||
      !CBB_add_u16_length_prefixed(&contents, &profile_ids) ||
      !CBB_add_u16(&profile_ids, ssl->srtp_profile->id) ||
      !CBB_add_u8(&contents, 0 /* empty MKI */) ||
      !CBB_flush(out)) {
    return 0;
  }

  return 1;
}


/* EC point formats.
 *
 * https://tools.ietf.org/html/rfc4492#section-5.1.2 */

static int ssl_any_ec_cipher_suites_enabled(const SSL *ssl) {
  if (ssl->version < TLS1_VERSION && !SSL_IS_DTLS(ssl)) {
    return 0;
  }

  const STACK_OF(SSL_CIPHER) *cipher_stack = SSL_get_ciphers(ssl);

  size_t i;
  for (i = 0; i < sk_SSL_CIPHER_num(cipher_stack); i++) {
    const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(cipher_stack, i);

    const uint32_t alg_k = cipher->algorithm_mkey;
    const uint32_t alg_a = cipher->algorithm_auth;
    if ((alg_k & SSL_kECDHE) || (alg_a & SSL_aECDSA)) {
      return 1;
    }
  }

  return 0;
}

static int ext_ec_point_add_extension(SSL *ssl, CBB *out) {
  CBB contents, formats;
  if (!CBB_add_u16(out, TLSEXT_TYPE_ec_point_formats) ||
      !CBB_add_u16_length_prefixed(out, &contents) ||
      !CBB_add_u8_length_prefixed(&contents, &formats) ||
      !CBB_add_u8(&formats, TLSEXT_ECPOINTFORMAT_uncompressed) ||
      !CBB_flush(out)) {
    return 0;
  }

  return 1;
}

static int ext_ec_point_add_clienthello(SSL *ssl, CBB *out) {
  if (!ssl_any_ec_cipher_suites_enabled(ssl)) {
    return 1;
  }

  return ext_ec_point_add_extension(ssl, out);
}

static int ext_ec_point_parse_serverhello(SSL *ssl, uint8_t *out_alert,
                                          CBS *contents) {
  if (contents == NULL) {
    return 1;
  }

  CBS ec_point_format_list;
  if (!CBS_get_u8_length_prefixed(contents, &ec_point_format_list) ||
      CBS_len(contents) != 0) {
    return 0;
  }

  /* Per RFC 4492, section 5.1.2, implementations MUST support the uncompressed
   * point format. */
  if (memchr(CBS_data(&ec_point_format_list), TLSEXT_ECPOINTFORMAT_uncompressed,
             CBS_len(&ec_point_format_list)) == NULL) {
    *out_alert = SSL_AD_ILLEGAL_PARAMETER;
    return 0;
  }

  return 1;
}

static int ext_ec_point_parse_clienthello(SSL *ssl, uint8_t *out_alert,
                                          CBS *contents) {
  return ext_ec_point_parse_serverhello(ssl, out_alert, contents);
}

static int ext_ec_point_add_serverhello(SSL *ssl, CBB *out) {
  const uint32_t alg_k = ssl->s3->tmp.new_cipher->algorithm_mkey;
  const uint32_t alg_a = ssl->s3->tmp.new_cipher->algorithm_auth;
  const int using_ecc = (alg_k & SSL_kECDHE) || (alg_a & SSL_aECDSA);

  if (!using_ecc) {
    return 1;
  }

  return ext_ec_point_add_extension(ssl, out);
}


/* Negotiated Groups
 *
 * https://tools.ietf.org/html/rfc4492#section-5.1.2
 * https://tools.ietf.org/html/draft-ietf-tls-tls13-12#section-6.3.2.2 */

static void ext_supported_groups_init(SSL *ssl) {
  OPENSSL_free(ssl->s3->tmp.peer_supported_group_list);
  ssl->s3->tmp.peer_supported_group_list = NULL;
  ssl->s3->tmp.peer_supported_group_list_len = 0;
}

static int ext_supported_groups_add_clienthello(SSL *ssl, CBB *out) {
  if (!ssl_any_ec_cipher_suites_enabled(ssl)) {
    return 1;
  }

  CBB contents, groups_bytes;
  if (!CBB_add_u16(out, TLSEXT_TYPE_supported_groups) ||
      !CBB_add_u16_length_prefixed(out, &contents) ||
      !CBB_add_u16_length_prefixed(&contents, &groups_bytes)) {
    return 0;
  }

  const uint16_t *groups;
  size_t groups_len;
  tls1_get_grouplist(ssl, 0, &groups, &groups_len);

  size_t i;
  for (i = 0; i < groups_len; i++) {
    if (!CBB_add_u16(&groups_bytes, groups[i])) {
      return 0;
    }
  }

  return CBB_flush(out);
}

static int ext_supported_groups_parse_serverhello(SSL *ssl, uint8_t *out_alert,
                                                  CBS *contents) {
  /* This extension is not expected to be echoed by servers and is ignored. */
  return 1;
}

static int ext_supported_groups_parse_clienthello(SSL *ssl, uint8_t *out_alert,
                                                  CBS *contents) {
  if (contents == NULL) {
    return 1;
  }

  CBS supported_group_list;
  if (!CBS_get_u16_length_prefixed(contents, &supported_group_list) ||
      CBS_len(&supported_group_list) == 0 ||
      (CBS_len(&supported_group_list) & 1) != 0 ||
      CBS_len(contents) != 0) {
    return 0;
  }

  ssl->s3->tmp.peer_supported_group_list = OPENSSL_malloc(
      CBS_len(&supported_group_list));
  if (ssl->s3->tmp.peer_supported_group_list == NULL) {
    *out_alert = SSL_AD_INTERNAL_ERROR;
    return 0;
  }

  const size_t num_groups = CBS_len(&supported_group_list) / 2;
  size_t i;
  for (i = 0; i < num_groups; i++) {
    if (!CBS_get_u16(&supported_group_list,
                     &ssl->s3->tmp.peer_supported_group_list[i])) {
      goto err;
    }
  }

  assert(CBS_len(&supported_group_list) == 0);
  ssl->s3->tmp.peer_supported_group_list_len = num_groups;

  return 1;

err:
  OPENSSL_free(ssl->s3->tmp.peer_supported_group_list);
  ssl->s3->tmp.peer_supported_group_list = NULL;
  *out_alert = SSL_AD_INTERNAL_ERROR;
  return 0;
}

static int ext_supported_groups_add_serverhello(SSL *ssl, CBB *out) {
  /* Servers don't echo this extension. */
  return 1;
}


/* kExtensions contains all the supported extensions. */
static const struct tls_extension kExtensions[] = {
  {
    /* The renegotiation extension must always be at index zero because the
     * |received| and |sent| bitsets need to be tweaked when the "extension" is
     * sent as an SCSV. */
    TLSEXT_TYPE_renegotiate,
    NULL,
    ext_ri_add_clienthello,
    ext_ri_parse_serverhello,
    ext_ri_parse_clienthello,
    ext_ri_add_serverhello,
  },
  {
    TLSEXT_TYPE_server_name,
    ext_sni_init,
    ext_sni_add_clienthello,
    ext_sni_parse_serverhello,
    ext_sni_parse_clienthello,
    ext_sni_add_serverhello,
  },
  {
    TLSEXT_TYPE_extended_master_secret,
    ext_ems_init,
    ext_ems_add_clienthello,
    ext_ems_parse_serverhello,
    ext_ems_parse_clienthello,
    ext_ems_add_serverhello,
  },
  {
    TLSEXT_TYPE_session_ticket,
    NULL,
    ext_ticket_add_clienthello,
    ext_ticket_parse_serverhello,
    ext_ticket_parse_clienthello,
    ext_ticket_add_serverhello,
  },
  {
    TLSEXT_TYPE_signature_algorithms,
    NULL,
    ext_sigalgs_add_clienthello,
    ext_sigalgs_parse_serverhello,
    ext_sigalgs_parse_clienthello,
    ext_sigalgs_add_serverhello,
  },
  {
    TLSEXT_TYPE_status_request,
    ext_ocsp_init,
    ext_ocsp_add_clienthello,
    ext_ocsp_parse_serverhello,
    ext_ocsp_parse_clienthello,
    ext_ocsp_add_serverhello,
  },
  {
    TLSEXT_TYPE_next_proto_neg,
    ext_npn_init,
    ext_npn_add_clienthello,
    ext_npn_parse_serverhello,
    ext_npn_parse_clienthello,
    ext_npn_add_serverhello,
  },
  {
    TLSEXT_TYPE_certificate_timestamp,
    NULL,
    ext_sct_add_clienthello,
    ext_sct_parse_serverhello,
    ext_sct_parse_clienthello,
    ext_sct_add_serverhello,
  },
  {
    TLSEXT_TYPE_application_layer_protocol_negotiation,
    ext_alpn_init,
    ext_alpn_add_clienthello,
    ext_alpn_parse_serverhello,
    ext_alpn_parse_clienthello,
    ext_alpn_add_serverhello,
  },
  {
    TLSEXT_TYPE_channel_id,
    ext_channel_id_init,
    ext_channel_id_add_clienthello,
    ext_channel_id_parse_serverhello,
    ext_channel_id_parse_clienthello,
    ext_channel_id_add_serverhello,
  },
  {
    TLSEXT_TYPE_srtp,
    ext_srtp_init,
    ext_srtp_add_clienthello,
    ext_srtp_parse_serverhello,
    ext_srtp_parse_clienthello,
    ext_srtp_add_serverhello,
  },
  {
    TLSEXT_TYPE_ec_point_formats,
    NULL,
    ext_ec_point_add_clienthello,
    ext_ec_point_parse_serverhello,
    ext_ec_point_parse_clienthello,
    ext_ec_point_add_serverhello,
  },
  /* The final extension must be non-empty. WebSphere Application Server 7.0 is
   * intolerant to the last extension being zero-length. See
   * https://crbug.com/363583. */
  {
    TLSEXT_TYPE_supported_groups,
    ext_supported_groups_init,
    ext_supported_groups_add_clienthello,
    ext_supported_groups_parse_serverhello,
    ext_supported_groups_parse_clienthello,
    ext_supported_groups_add_serverhello,
  },
};

#define kNumExtensions (sizeof(kExtensions) / sizeof(struct tls_extension))

OPENSSL_COMPILE_ASSERT(kNumExtensions <=
                           sizeof(((SSL *)NULL)->s3->tmp.extensions.sent) * 8,
                       too_many_extensions_for_sent_bitset);
OPENSSL_COMPILE_ASSERT(kNumExtensions <=
                           sizeof(((SSL *)NULL)->s3->tmp.extensions.received) *
                               8,
                       too_many_extensions_for_received_bitset);

static const struct tls_extension *tls_extension_find(uint32_t *out_index,
                                                      uint16_t value) {
  unsigned i;
  for (i = 0; i < kNumExtensions; i++) {
    if (kExtensions[i].value == value) {
      *out_index = i;
      return &kExtensions[i];
    }
  }

  return NULL;
}

int SSL_extension_supported(unsigned extension_value) {
  uint32_t index;
  return extension_value == TLSEXT_TYPE_padding ||
         tls_extension_find(&index, extension_value) != NULL;
}

int ssl_add_clienthello_tlsext(SSL *ssl, CBB *out, size_t header_len) {
  /* don't add extensions for SSLv3 unless doing secure renegotiation */
  if (ssl->client_version == SSL3_VERSION &&
      !ssl->s3->send_connection_binding) {
    return 1;
  }

  CBB extensions;
  if (!CBB_add_u16_length_prefixed(out, &extensions)) {
    goto err;
  }

  ssl->s3->tmp.extensions.sent = 0;
  ssl->s3->tmp.custom_extensions.sent = 0;

  size_t i;
  for (i = 0; i < kNumExtensions; i++) {
    if (kExtensions[i].init != NULL) {
      kExtensions[i].init(ssl);
    }
  }

  for (i = 0; i < kNumExtensions; i++) {
    const size_t len_before = CBB_len(&extensions);
    if (!kExtensions[i].add_clienthello(ssl, &extensions)) {
      OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_ADDING_EXTENSION);
      ERR_add_error_dataf("extension: %u", (unsigned)kExtensions[i].value);
      goto err;
    }

    if (CBB_len(&extensions) != len_before) {
      ssl->s3->tmp.extensions.sent |= (1u << i);
    }
  }

  if (!custom_ext_add_clienthello(ssl, &extensions)) {
    goto err;
  }

  if (!SSL_IS_DTLS(ssl)) {
    header_len += 2 + CBB_len(&extensions);
    if (header_len > 0xff && header_len < 0x200) {
      /* Add padding to workaround bugs in F5 terminators. See RFC 7685.
       *
       * NB: because this code works out the length of all existing extensions
       * it MUST always appear last. */
      size_t padding_len = 0x200 - header_len;
      /* Extensions take at least four bytes to encode. Always include at least
       * one byte of data if including the extension. WebSphere Application
       * Server 7.0 is intolerant to the last extension being zero-length. See
       * https://crbug.com/363583. */
      if (padding_len >= 4 + 1) {
        padding_len -= 4;
      } else {
        padding_len = 1;
      }

      uint8_t *padding_bytes;
      if (!CBB_add_u16(&extensions, TLSEXT_TYPE_padding) ||
          !CBB_add_u16(&extensions, padding_len) ||
          !CBB_add_space(&extensions, &padding_bytes, padding_len)) {
        goto err;
      }

      memset(padding_bytes, 0, padding_len);
    }
  }

  /* Discard empty extensions blocks. */
  if (CBB_len(&extensions) == 0) {
    CBB_discard_child(out);
  }

  return CBB_flush(out);

err:
  OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
  return 0;
}

int ssl_add_serverhello_tlsext(SSL *ssl, CBB *out) {
  CBB extensions;
  if (!CBB_add_u16_length_prefixed(out, &extensions)) {
    goto err;
  }

  unsigned i;
  for (i = 0; i < kNumExtensions; i++) {
    if (!(ssl->s3->tmp.extensions.received & (1u << i))) {
      /* Don't send extensions that were not received. */
      continue;
    }

    if (!kExtensions[i].add_serverhello(ssl, &extensions)) {
      OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_ADDING_EXTENSION);
      ERR_add_error_dataf("extension: %u", (unsigned)kExtensions[i].value);
      goto err;
    }
  }

  if (!custom_ext_add_serverhello(ssl, &extensions)) {
    goto err;
  }

  /* Discard empty extensions blocks. */
  if (CBB_len(&extensions) == 0) {
    CBB_discard_child(out);
  }

  return CBB_flush(out);

err:
  OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
  return 0;
}

static int ssl_scan_clienthello_tlsext(SSL *ssl, CBS *cbs, int *out_alert) {
  size_t i;
  for (i = 0; i < kNumExtensions; i++) {
    if (kExtensions[i].init != NULL) {
      kExtensions[i].init(ssl);
    }
  }

  ssl->s3->tmp.extensions.received = 0;
  ssl->s3->tmp.custom_extensions.received = 0;
  /* The renegotiation extension must always be at index zero because the
   * |received| and |sent| bitsets need to be tweaked when the "extension" is
   * sent as an SCSV. */
  assert(kExtensions[0].value == TLSEXT_TYPE_renegotiate);

  /* There may be no extensions. */
  if (CBS_len(cbs) != 0) {
    /* Decode the extensions block and check it is valid. */
    CBS extensions;
    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;
      }

      /* RFC 5746 made the existence of extensions in SSL 3.0 somewhat
       * ambiguous. Ignore all but the renegotiation_info extension. */
      if (ssl->version == SSL3_VERSION && type != TLSEXT_TYPE_renegotiate) {
        continue;
      }

      unsigned ext_index;
      const struct tls_extension *const ext =
          tls_extension_find(&ext_index, type);

      if (ext == NULL) {
        if (!custom_ext_parse_clienthello(ssl, out_alert, type, &extension)) {
          OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_PARSING_EXTENSION);
          return 0;
        }
        continue;
      }

      ssl->s3->tmp.extensions.received |= (1u << ext_index);
      uint8_t alert = SSL_AD_DECODE_ERROR;
      if (!ext->parse_clienthello(ssl, &alert, &extension)) {
        *out_alert = alert;
        OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_PARSING_EXTENSION);
        ERR_add_error_dataf("extension: %u", (unsigned)type);
        return 0;
      }
    }
  }

  for (i = 0; i < kNumExtensions; i++) {
    if (!(ssl->s3->tmp.extensions.received & (1u << i))) {
      /* Extension wasn't observed so call the callback with a NULL
       * parameter. */
      uint8_t alert = SSL_AD_DECODE_ERROR;
      if (!kExtensions[i].parse_clienthello(ssl, &alert, NULL)) {
        OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_EXTENSION);
        ERR_add_error_dataf("extension: %u", (unsigned)kExtensions[i].value);
        *out_alert = alert;
        return 0;
      }
    }
  }

  return 1;
}

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

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

  return 1;
}

OPENSSL_COMPILE_ASSERT(kNumExtensions <= sizeof(uint32_t) * 8, too_many_bits);

static int ssl_scan_serverhello_tlsext(SSL *ssl, CBS *cbs, int *out_alert) {
  uint32_t received = 0;

  if (CBS_len(cbs) != 0) {
    /* Decode the extensions block and check it is valid. */
    CBS extensions;
    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;
      }

      unsigned ext_index;
      const struct tls_extension *const ext =
          tls_extension_find(&ext_index, type);

      if (ext == NULL) {
        if (!custom_ext_parse_serverhello(ssl, out_alert, type, &extension)) {
          return 0;
        }
        continue;
      }

      if (!(ssl->s3->tmp.extensions.sent & (1u << ext_index))) {
        /* If the extension was never sent then it is illegal. */
        OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION);
        ERR_add_error_dataf("extension :%u", (unsigned)type);
        *out_alert = SSL_AD_DECODE_ERROR;
        return 0;
      }

      received |= (1u << ext_index);

      uint8_t alert = SSL_AD_DECODE_ERROR;
      if (!ext->parse_serverhello(ssl, &alert, &extension)) {
        OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_PARSING_EXTENSION);
        ERR_add_error_dataf("extension: %u", (unsigned)type);
        *out_alert = alert;
        return 0;
      }
    }
  }

  size_t i;
  for (i = 0; i < kNumExtensions; i++) {
    if (!(received & (1u << i))) {
      /* Extension wasn't observed so call the callback with a NULL
       * parameter. */
      uint8_t alert = SSL_AD_DECODE_ERROR;
      if (!kExtensions[i].parse_serverhello(ssl, &alert, NULL)) {
        OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_EXTENSION);
        ERR_add_error_dataf("extension: %u", (unsigned)kExtensions[i].value);
        *out_alert = alert;
        return 0;
      }
    }
  }

  return 1;
}

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

  if (ssl->ctx->tlsext_servername_callback != 0) {
    ret = ssl->ctx->tlsext_servername_callback(ssl, &al,
                                               ssl->ctx->tlsext_servername_arg);
  } else if (ssl->initial_ctx->tlsext_servername_callback != 0) {
    ret = ssl->initial_ctx->tlsext_servername_callback(
        ssl, &al, ssl->initial_ctx->tlsext_servername_arg);
  }

  switch (ret) {
    case SSL_TLSEXT_ERR_ALERT_FATAL:
      ssl3_send_alert(ssl, SSL3_AL_FATAL, al);
      return -1;

    case SSL_TLSEXT_ERR_ALERT_WARNING:
      ssl3_send_alert(ssl, SSL3_AL_WARNING, al);
      return 1;

    case SSL_TLSEXT_ERR_NOACK:
      ssl->s3->tmp.should_ack_sni = 0;
      return 1;

    default:
      return 1;
  }
}

static int ssl_check_serverhello_tlsext(SSL *ssl) {
  int ret = SSL_TLSEXT_ERR_OK;
  int al = SSL_AD_UNRECOGNIZED_NAME;

  if (ssl->ctx->tlsext_servername_callback != 0) {
    ret = ssl->ctx->tlsext_servername_callback(ssl, &al,
                                               ssl->ctx->tlsext_servername_arg);
  } else if (ssl->initial_ctx->tlsext_servername_callback != 0) {
    ret = ssl->initial_ctx->tlsext_servername_callback(
        ssl, &al, ssl->initial_ctx->tlsext_servername_arg);
  }

  switch (ret) {
    case SSL_TLSEXT_ERR_ALERT_FATAL:
      ssl3_send_alert(ssl, SSL3_AL_FATAL, al);
      return -1;

    case SSL_TLSEXT_ERR_ALERT_WARNING:
      ssl3_send_alert(ssl, SSL3_AL_WARNING, al);
      return 1;

    default:
      return 1;
  }
}

int ssl_parse_serverhello_tlsext(SSL *ssl, CBS *cbs) {
  int alert = -1;
  if (ssl_scan_serverhello_tlsext(ssl, cbs, &alert) <= 0) {
    ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
    return 0;
  }

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

  return 1;
}

int tls_process_ticket(SSL *ssl, SSL_SESSION **out_session,
                       int *out_renew_ticket, const uint8_t *ticket,
                       size_t ticket_len, const uint8_t *session_id,
                       size_t session_id_len) {
  int ret = 1; /* Most errors are non-fatal. */
  SSL_CTX *ssl_ctx = ssl->initial_ctx;
  uint8_t *plaintext = NULL;

  HMAC_CTX hmac_ctx;
  HMAC_CTX_init(&hmac_ctx);
  EVP_CIPHER_CTX cipher_ctx;
  EVP_CIPHER_CTX_init(&cipher_ctx);

  *out_renew_ticket = 0;
  *out_session = NULL;

  if (session_id_len > SSL_MAX_SSL_SESSION_ID_LENGTH) {
    goto done;
  }

  /* Ensure there is room for the key name and the largest IV
   * |tlsext_ticket_key_cb| may try to consume. The real limit may be lower, but
   * the maximum IV length should be well under the minimum size for the
   * session material and HMAC. */
  if (ticket_len < SSL_TICKET_KEY_NAME_LEN + EVP_MAX_IV_LENGTH) {
    goto done;
  }
  const uint8_t *iv = ticket + SSL_TICKET_KEY_NAME_LEN;

  if (ssl_ctx->tlsext_ticket_key_cb != NULL) {
    int cb_ret = ssl_ctx->tlsext_ticket_key_cb(
        ssl, (uint8_t *)ticket /* name */, (uint8_t *)iv, &cipher_ctx,
        &hmac_ctx, 0 /* decrypt */);
    if (cb_ret < 0) {
      ret = 0;
      goto done;
    }
    if (cb_ret == 0) {
      goto done;
    }
    if (cb_ret == 2) {
      *out_renew_ticket = 1;
    }
  } else {
    /* Check the key name matches. */
    if (memcmp(ticket, ssl_ctx->tlsext_tick_key_name,
               SSL_TICKET_KEY_NAME_LEN) != 0) {
      goto done;
    }
    if (!HMAC_Init_ex(&hmac_ctx, ssl_ctx->tlsext_tick_hmac_key,
                      sizeof(ssl_ctx->tlsext_tick_hmac_key), tlsext_tick_md(),
                      NULL) ||
        !EVP_DecryptInit_ex(&cipher_ctx, EVP_aes_128_cbc(), NULL,
                            ssl_ctx->tlsext_tick_aes_key, iv)) {
      ret = 0;
      goto done;
    }
  }
  size_t iv_len = EVP_CIPHER_CTX_iv_length(&cipher_ctx);

  /* Check the MAC at the end of the ticket. */
  uint8_t mac[EVP_MAX_MD_SIZE];
  size_t mac_len = HMAC_size(&hmac_ctx);
  if (ticket_len < SSL_TICKET_KEY_NAME_LEN + iv_len + 1 + mac_len) {
    /* The ticket must be large enough for key name, IV, data, and MAC. */
    goto done;
  }
  HMAC_Update(&hmac_ctx, ticket, ticket_len - mac_len);
  HMAC_Final(&hmac_ctx, mac, NULL);
  if (CRYPTO_memcmp(mac, ticket + (ticket_len - mac_len), mac_len) != 0) {
    goto done;
  }

  /* Decrypt the session data. */
  const uint8_t *ciphertext = ticket + SSL_TICKET_KEY_NAME_LEN + iv_len;
  size_t ciphertext_len = ticket_len - SSL_TICKET_KEY_NAME_LEN - iv_len -
                          mac_len;
  plaintext = OPENSSL_malloc(ciphertext_len);
  if (plaintext == NULL) {
    ret = 0;
    goto done;
  }
  if (ciphertext_len >= INT_MAX) {
    goto done;
  }
  int len1, len2;
  if (!EVP_DecryptUpdate(&cipher_ctx, plaintext, &len1, ciphertext,
                         (int)ciphertext_len) ||
      !EVP_DecryptFinal_ex(&cipher_ctx, plaintext + len1, &len2)) {
    ERR_clear_error(); /* Don't leave an error on the queue. */
    goto done;
  }

  /* Decode the session. */
  SSL_SESSION *session = SSL_SESSION_from_bytes(plaintext, len1 + len2);
  if (session == NULL) {
    ERR_clear_error(); /* Don't leave an error on the queue. */
    goto done;
  }

  /* Copy the client's session ID into the new session, to denote the ticket has
   * been accepted. */
  memcpy(session->session_id, session_id, session_id_len);
  session->session_id_length = session_id_len;

  *out_session = session;

done:
  OPENSSL_free(plaintext);
  HMAC_CTX_cleanup(&hmac_ctx);
  EVP_CIPHER_CTX_cleanup(&cipher_ctx);
  return ret;
}

/* Tables to translate from NIDs to TLS v1.2 ids
 *
 * TODO(svaldez): Remove decomposition of SignatureAlgorithm IDs. */
typedef struct {
  int pkey_type;
  int md_type;
  uint16_t id;
} tls12_lookup;

static const tls12_lookup kTLS12SignatureAlgorithmIDs[] = {
    {EVP_PKEY_RSA, NID_sha512, SSL_SIGN_RSA_PKCS1_SHA512},
    {EVP_PKEY_EC, NID_sha512, SSL_SIGN_ECDSA_SECP521R1_SHA512},
    {EVP_PKEY_RSA, NID_sha384, SSL_SIGN_RSA_PKCS1_SHA384},
    {EVP_PKEY_EC, NID_sha384, SSL_SIGN_ECDSA_SECP384R1_SHA384},
    {EVP_PKEY_RSA, NID_sha256, SSL_SIGN_RSA_PKCS1_SHA256},
    {EVP_PKEY_EC, NID_sha256, SSL_SIGN_ECDSA_SECP256R1_SHA256},
    {EVP_PKEY_RSA, NID_sha1, SSL_SIGN_RSA_PKCS1_SHA1},
    {EVP_PKEY_EC, NID_sha1, SSL_SIGN_ECDSA_SHA1},
};

int tls12_add_sigalg(SSL *ssl, CBB *out, const EVP_MD *md) {
  int pkey_type = ssl_private_key_type(ssl);
  int md_type = EVP_MD_type(md);

  size_t i;
  for (i = 0; i < sizeof(kTLS12SignatureAlgorithmIDs) / sizeof(tls12_lookup);
       i++) {
    if (kTLS12SignatureAlgorithmIDs[i].pkey_type == pkey_type &&
        kTLS12SignatureAlgorithmIDs[i].md_type == md_type) {
      return CBB_add_u16(out, kTLS12SignatureAlgorithmIDs[i].id);
    }
  }

  return 0;
}

static const EVP_MD *tls12_get_hash(uint16_t sig_alg) {
  switch (sig_alg >> 8) {
    case TLSEXT_hash_sha1:
      return EVP_sha1();

    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(uint16_t sig_alg) {
  switch (sig_alg & 0xff) {
    case TLSEXT_signature_rsa:
      return EVP_PKEY_RSA;

    case TLSEXT_signature_ecdsa:
      return EVP_PKEY_EC;

    default:
      return -1;
  }
}

int tls1_parse_peer_sigalgs(SSL *ssl, const CBS *in_sigalgs) {
  /* Extension ignored for inappropriate versions */
  if (ssl3_protocol_version(ssl) < TLS1_2_VERSION) {
    return 1;
  }

  CERT *const cert = ssl->cert;
  OPENSSL_free(cert->peer_sigalgs);
  cert->peer_sigalgs = NULL;
  cert->peer_sigalgslen = 0;

  size_t num_sigalgs = CBS_len(in_sigalgs);

  if (num_sigalgs % 2 != 0) {
    return 0;
  }
  num_sigalgs /= 2;

  /* supported_signature_algorithms in the certificate request is
   * allowed to be empty. */
  if (num_sigalgs == 0) {
    return 1;
  }

  /* This multiplication doesn't overflow because sizeof(uint16_t) is two
   * and we just divided |num_sigalgs| by two. */
  cert->peer_sigalgs = OPENSSL_malloc(num_sigalgs * sizeof(uint16_t));
  if (cert->peer_sigalgs == NULL) {
    return 0;
  }
  cert->peer_sigalgslen = num_sigalgs;

  CBS sigalgs;
  CBS_init(&sigalgs, CBS_data(in_sigalgs), CBS_len(in_sigalgs));

  size_t i;
  for (i = 0; i < num_sigalgs; i++) {
    if (!CBS_get_u16(&sigalgs, &cert->peer_sigalgs[i])) {
      return 0;
    }
  }

  return 1;
}

const EVP_MD *tls1_choose_signing_digest(SSL *ssl) {
  CERT *cert = ssl->cert;
  int type = ssl_private_key_type(ssl);
  size_t i, j;

  static const int kDefaultDigestList[] = {NID_sha256, NID_sha384, NID_sha512,
                                           NID_sha1};

  const int *digest_nids = kDefaultDigestList;
  size_t num_digest_nids =
      sizeof(kDefaultDigestList) / sizeof(kDefaultDigestList[0]);
  if (cert->digest_nids != NULL) {
    digest_nids = cert->digest_nids;
    num_digest_nids = cert->num_digest_nids;
  }

  for (i = 0; i < num_digest_nids; i++) {
    const int digest_nid = digest_nids[i];
    for (j = 0; j < cert->peer_sigalgslen; j++) {
      const EVP_MD *md = tls12_get_hash(cert->peer_sigalgs[j]);
      if (md == NULL ||
          digest_nid != EVP_MD_type(md) ||
          tls12_get_pkey_type(cert->peer_sigalgs[j]) != type) {
        continue;
      }

      return md;
    }
  }

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

int tls1_channel_id_hash(SSL *ssl, uint8_t *out, size_t *out_len) {
  int ret = 0;
  EVP_MD_CTX ctx;

  EVP_MD_CTX_init(&ctx);
  if (!EVP_DigestInit_ex(&ctx, EVP_sha256(), NULL)) {
    goto err;
  }

  static const char kClientIDMagic[] = "TLS Channel ID signature";
  EVP_DigestUpdate(&ctx, kClientIDMagic, sizeof(kClientIDMagic));

  if (ssl->hit) {
    static const char kResumptionMagic[] = "Resumption";
    EVP_DigestUpdate(&ctx, kResumptionMagic, sizeof(kResumptionMagic));
    if (ssl->session->original_handshake_hash_len == 0) {
      OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
      goto err;
    }
    EVP_DigestUpdate(&ctx, ssl->session->original_handshake_hash,
                     ssl->session->original_handshake_hash_len);
  }

  uint8_t handshake_hash[EVP_MAX_MD_SIZE];
  int handshake_hash_len = tls1_handshake_digest(ssl, handshake_hash,
                                                 sizeof(handshake_hash));
  if (handshake_hash_len < 0) {
    goto err;
  }
  EVP_DigestUpdate(&ctx, handshake_hash, (size_t)handshake_hash_len);
  unsigned len_u;
  EVP_DigestFinal_ex(&ctx, out, &len_u);
  *out_len = len_u;

  ret = 1;

err:
  EVP_MD_CTX_cleanup(&ctx);
  return ret;
}

/* tls1_record_handshake_hashes_for_channel_id records the current handshake
 * hashes in |ssl->session| so that Channel ID resumptions can sign that
 * data. */
int tls1_record_handshake_hashes_for_channel_id(SSL *ssl) {
  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 (ssl->hit) {
    return -1;
  }

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

  ssl->session->original_handshake_hash_len = digest_len;

  return 1;
}
