// Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <openssl/ssl.h>

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

#include <algorithm>
#include <optional>
#include <variant>
#include <utility>

#include <openssl/aead.h>
#include <openssl/bytestring.h>
#include <openssl/chacha.h>
#include <openssl/cipher.h>
#include <openssl/curve25519.h>
#include <openssl/digest.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/hmac.h>
#include <openssl/hpke.h>
#include <openssl/mem.h>
#include <openssl/nid.h>
#include <openssl/pool.h>
#include <openssl/rand.h>

#include "../crypto/bytestring/internal.h"
#include "../crypto/internal.h"
#include "../crypto/mem_internal.h"
#include "../crypto/spake2plus/internal.h"
#include "internal.h"


BSSL_NAMESPACE_BEGIN

static bool ssl_check_clienthello_tlsext(SSL_HANDSHAKE *hs);
static bool ssl_check_serverhello_tlsext(SSL_HANDSHAKE *hs);

// 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 bool tls1_check_duplicate_extensions(const CBS *cbs) {
  // First pass: count the extensions.
  size_t num_extensions = 0;
  CBS extensions = *cbs;
  while (CBS_len(&extensions) > 0) {
    uint16_t type;
    CBS extension;

    if (!CBS_get_u16(&extensions, &type) ||
        !CBS_get_u16_length_prefixed(&extensions, &extension)) {
      return false;
    }

    num_extensions++;
  }

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

  Array<uint16_t> extension_types;
  if (!extension_types.InitForOverwrite(num_extensions)) {
    return false;
  }

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

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

  // Sort the extensions and make sure there are no duplicates.
  std::sort(extension_types.begin(), extension_types.end());
  for (size_t i = 1; i < num_extensions; i++) {
    if (extension_types[i - 1] == extension_types[i]) {
      return false;
    }
  }

  return true;
}

static bool is_post_quantum_group(uint16_t id) {
  switch (id) {
    case SSL_GROUP_X25519_KYBER768_DRAFT00:
    case SSL_GROUP_X25519_MLKEM768:
    case SSL_GROUP_MLKEM1024:
      return true;
    default:
      return false;
  }
}

bool ssl_parse_client_hello_with_trailing_data(const SSL *ssl, CBS *cbs,
                                               SSL_CLIENT_HELLO *out) {
  OPENSSL_memset(out, 0, sizeof(*out));
  out->ssl = const_cast<SSL *>(ssl);

  CBS copy = *cbs;
  CBS random, session_id;
  if (!CBS_get_u16(cbs, &out->version) ||
      !CBS_get_bytes(cbs, &random, SSL3_RANDOM_SIZE) ||
      !CBS_get_u8_length_prefixed(cbs, &session_id) ||
      CBS_len(&session_id) > SSL_MAX_SSL_SESSION_ID_LENGTH) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED);
    return false;
  }

  out->random = CBS_data(&random);
  out->random_len = CBS_len(&random);
  out->session_id = CBS_data(&session_id);
  out->session_id_len = CBS_len(&session_id);

  if (SSL_is_dtls(out->ssl)) {
    CBS cookie;
    if (!CBS_get_u8_length_prefixed(cbs, &cookie)) {
      OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED);
      return false;
    }
    out->dtls_cookie = CBS_data(&cookie);
    out->dtls_cookie_len = CBS_len(&cookie);
  } else {
    out->dtls_cookie = nullptr;
    out->dtls_cookie_len = 0;
  }

  CBS cipher_suites, compression_methods;
  if (!CBS_get_u16_length_prefixed(cbs, &cipher_suites) ||
      CBS_len(&cipher_suites) < 2 || (CBS_len(&cipher_suites) & 1) != 0 ||
      !CBS_get_u8_length_prefixed(cbs, &compression_methods) ||
      CBS_len(&compression_methods) < 1) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED);
    return false;
  }

  out->cipher_suites = CBS_data(&cipher_suites);
  out->cipher_suites_len = CBS_len(&cipher_suites);
  out->compression_methods = CBS_data(&compression_methods);
  out->compression_methods_len = CBS_len(&compression_methods);

  // If the ClientHello ends here then it's valid, but doesn't have any
  // extensions.
  if (CBS_len(cbs) == 0) {
    out->extensions = nullptr;
    out->extensions_len = 0;
  } else {
    // Extract extensions and check it is valid.
    CBS extensions;
    if (!CBS_get_u16_length_prefixed(cbs, &extensions) ||
        !tls1_check_duplicate_extensions(&extensions)) {
      OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED);
      return false;
    }
    out->extensions = CBS_data(&extensions);
    out->extensions_len = CBS_len(&extensions);
  }

  out->client_hello = CBS_data(&copy);
  out->client_hello_len = CBS_len(&copy) - CBS_len(cbs);
  return true;
}

bool ssl_client_hello_get_extension(const SSL_CLIENT_HELLO *client_hello,
                                    CBS *out, uint16_t extension_type) {
  CBS extensions;
  CBS_init(&extensions, client_hello->extensions, client_hello->extensions_len);
  while (CBS_len(&extensions) != 0) {
    // Decode the next extension.
    uint16_t type;
    CBS extension;
    if (!CBS_get_u16(&extensions, &type) ||
        !CBS_get_u16_length_prefixed(&extensions, &extension)) {
      return false;
    }

    if (type == extension_type) {
      *out = extension;
      return true;
    }
  }

  return false;
}

bool tls1_get_shared_group(SSL_HANDSHAKE *hs, uint16_t *out_group_id) {
  SSL *const ssl = hs->ssl;
  assert(ssl->server);

  // 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. Thus we do not special-case an empty
  // |peer_supported_group_list|.

  Span<const uint16_t> groups = hs->config->supported_group_list;
  Span<const uint16_t> pref, supp;
  Span<const uint32_t> pref_flags;
  if (ssl->options & SSL_OP_CIPHER_SERVER_PREFERENCE) {
    pref = groups;
    pref_flags = hs->config->supported_group_list_flags;
    supp = hs->peer_supported_group_list;
  } else {
    pref = hs->peer_supported_group_list;
    supp = groups;
  }

  // Index within `supp` of the best matching group so far.
  std::optional<size_t> best_match;
  for (size_t i = 0u; i < pref.size(); ++i) {
    uint16_t candidate_group = pref[i];
    auto match_it = std::find(supp.begin(), supp.end(), candidate_group);
    // Post-quantum key agreements don't fit in the u8-length-prefixed
    // ECPoint field in TLS 1.2 and below.
    if (ssl_protocol_version(ssl) < TLS1_3_VERSION &&
        is_post_quantum_group(candidate_group)) {
      match_it = supp.end();
    }
    if (match_it != supp.end()) {
      size_t match_idx = match_it - supp.begin();
      if (!best_match.has_value() || match_idx < *best_match) {
        best_match = match_idx;
      }
    }

    // If we found a match, stop at the current equipreference group.
    bool equal_with_next =
        !pref_flags.empty() &&
        (pref_flags[i] & SSL_GROUP_FLAG_EQUAL_PREFERENCE_WITH_NEXT);
    if (!equal_with_next && best_match.has_value()) {
      break;
    }
  }

  if (!best_match.has_value()) {
    return false;
  }
  *out_group_id = supp[*best_match];
  return true;
}

bool tls1_check_group_id(const SSL_HANDSHAKE *hs, uint16_t group_id) {
  if (is_post_quantum_group(group_id) &&
      ssl_protocol_version(hs->ssl) < TLS1_3_VERSION) {
    // Post-quantum "groups" require TLS 1.3.
    return false;
  }

  // We internally assume zero is never allocated as a group ID.
  if (group_id == 0) {
    return false;
  }

  for (uint16_t supported : hs->config->supported_group_list) {
    if (supported == group_id) {
      return true;
    }
  }

  return false;
}

// kVerifySignatureAlgorithms is the default list of accepted signature
// algorithms for verifying.
static const uint16_t kVerifySignatureAlgorithms[] = {
    // List our preferred algorithms first.
    SSL_SIGN_ECDSA_SECP256R1_SHA256,
    SSL_SIGN_RSA_PSS_RSAE_SHA256,
    SSL_SIGN_RSA_PKCS1_SHA256,

    // Larger hashes are acceptable.
    SSL_SIGN_ECDSA_SECP384R1_SHA384,
    SSL_SIGN_RSA_PSS_RSAE_SHA384,
    SSL_SIGN_RSA_PKCS1_SHA384,

    SSL_SIGN_RSA_PSS_RSAE_SHA512,
    SSL_SIGN_RSA_PKCS1_SHA512,

    // For now, SHA-1 is still accepted but least preferable.
    SSL_SIGN_RSA_PKCS1_SHA1,
};

// kSignSignatureAlgorithms is the default list of supported signature
// algorithms for signing.
static const uint16_t kSignSignatureAlgorithms[] = {
    // List our preferred algorithms first.
    SSL_SIGN_ML_DSA_44,
    SSL_SIGN_ML_DSA_65,
    SSL_SIGN_ML_DSA_87,

    // Classical signature algorithms.
    SSL_SIGN_ED25519,
    SSL_SIGN_ECDSA_SECP256R1_SHA256,
    SSL_SIGN_RSA_PSS_RSAE_SHA256,
    SSL_SIGN_RSA_PKCS1_SHA256,

    // If needed, sign larger hashes.
    //
    // TODO(davidben): Determine which of these may be pruned.
    SSL_SIGN_ECDSA_SECP384R1_SHA384,
    SSL_SIGN_RSA_PSS_RSAE_SHA384,
    SSL_SIGN_RSA_PKCS1_SHA384,

    SSL_SIGN_ECDSA_SECP521R1_SHA512,
    SSL_SIGN_RSA_PSS_RSAE_SHA512,
    SSL_SIGN_RSA_PKCS1_SHA512,

    // If the peer supports nothing else, sign with SHA-1.
    SSL_SIGN_ECDSA_SHA1,
    SSL_SIGN_RSA_PKCS1_SHA1,
};

static Span<const uint16_t> tls12_get_verify_sigalgs(const SSL_HANDSHAKE *hs) {
  if (hs->config->verify_sigalgs.empty()) {
    return Span<const uint16_t>(kVerifySignatureAlgorithms);
  }
  return hs->config->verify_sigalgs;
}

bool tls12_add_verify_sigalgs(const SSL_HANDSHAKE *hs, CBB *out) {
  for (uint16_t sigalg : tls12_get_verify_sigalgs(hs)) {
    if (!CBB_add_u16(out, sigalg)) {
      return false;
    }
  }
  return true;
}

bool tls12_check_peer_sigalg(const SSL_HANDSHAKE *hs, uint8_t *out_alert,
                             uint16_t sigalg, EVP_PKEY *pkey) {
  // The peer must have selected an algorithm that is consistent with its public
  // key, the TLS version, and what we advertised.
  Span<const uint16_t> sigalgs = tls12_get_verify_sigalgs(hs);
  if (std::find(sigalgs.begin(), sigalgs.end(), sigalg) == sigalgs.end() ||
      !ssl_pkey_supports_algorithm(hs->ssl, pkey, sigalg, /*is_verify=*/true)) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SIGNATURE_TYPE);
    *out_alert = SSL_AD_ILLEGAL_PARAMETER;
    return false;
  }

  return true;
}

// Flags.
//
// https://www.ietf.org/archive/id/draft-ietf-tls-tlsflags-14.html

bool ssl_add_flags_extension(CBB *cbb, SSLFlags flags) {
  if (flags == 0) {
    return true;
  }

  CBB body, child;
  if (!CBB_add_u16(cbb, TLSEXT_TYPE_tls_flags) ||
      !CBB_add_u16_length_prefixed(cbb, &body) ||
      !CBB_add_u8_length_prefixed(&body, &child)) {
    return false;
  }

  while (flags != 0) {
    if (!CBB_add_u8(&child, static_cast<uint8_t>(flags))) {
      return false;
    }
    flags >>= 8;
  }

  return CBB_flush(cbb);
}

static bool ssl_parse_flags_extension(const CBS *cbs, SSLFlags *out,
                                      uint8_t *out_alert, bool allow_unknown) {
  CBS copy = *cbs, flags;
  if (!CBS_get_u8_length_prefixed(&copy, &flags) ||  //
      CBS_len(&copy) != 0 ||                         //
      CBS_len(&flags) == 0) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
    *out_alert = SSL_AD_DECODE_ERROR;
    return false;
  }

  // There may not be any trailing zeros.
  if (CBS_data(&flags)[CBS_len(&flags) - 1] == 0) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
    *out_alert = SSL_AD_ILLEGAL_PARAMETER;
    return false;
  }

  // We can only represent flags that fit in SSLFlags, so any bits beyond that
  // are necessarily unsolicited. Unsolicited flags are allowed in CH, CR, and
  // NST, but forbidden in SH, EE, CT, and HRR. See Section 3 of
  // draft-ietf-tls-tlsflags-14.
  if (!allow_unknown && CBS_len(&flags) > sizeof(SSLFlags)) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION);
    *out_alert = SSL_AD_ILLEGAL_PARAMETER;
    return false;
  }

  // We currently use the same in-memory and wire representation for flags.
  uint8_t padded[sizeof(SSLFlags)] = {0};
  OPENSSL_memcpy(padded, CBS_data(&flags),
                 std::min(CBS_len(&flags), size_t{4}));
  static_assert(sizeof(SSLFlags) == sizeof(uint32_t),
                "We currently assume SSLFlags is 32-bit");
  *out = CRYPTO_load_u32_le(padded);
  return true;
}

bool ssl_parse_flags_extension_request(const CBS *cbs, SSLFlags *out,
                                       uint8_t *out_alert) {
  // In a request message, unsolicited flags are allowed and ignored.
  return ssl_parse_flags_extension(cbs, out, out_alert,
                                   /*allow_unknown=*/true);
}

bool ssl_parse_flags_extension_response(const CBS *cbs, SSLFlags *out,
                                        uint8_t *out_alert,
                                        SSLFlags allowed_flags) {
  // In a response message, unsolicited flags are not allowed.
  if (!ssl_parse_flags_extension(cbs, out, out_alert,
                                 /*allow_unknown=*/false)) {
    return false;
  }

  // Check for unsolicited flags that fit in |SSLFlags|.
  if ((*out & allowed_flags) != *out) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION);
    *out_alert = SSL_AD_ILLEGAL_PARAMETER;
    return false;
  }

  return true;
}

// tls_extension represents a TLS extension that is handled internally.
//
// 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.
//
// |add_clienthello| may be called multiple times and must not mutate |hs|. It
// is additionally passed two output |CBB|s. If the extension is the same
// independent of the value of |type|, the callback may write to
// |out_compressible| instead of |out|. When serializing the ClientHelloInner,
// all compressible extensions will be made contiguous and replaced with
// ech_outer_extensions when encrypted. When serializing the ClientHelloOuter
// or not offering ECH, |out| will be equal to |out_compressible|, so writing to
// |out_compressible| still works.
//
// Note the |parse_serverhello| and |add_serverhello| callbacks refer to the
// TLS 1.2 ServerHello. In TLS 1.3, these callbacks act on EncryptedExtensions,
// with ServerHello extensions handled elsewhere in the handshake.
//
// All callbacks return true for success and false 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;

  bool (*add_clienthello)(const SSL_HANDSHAKE *hs, CBB *out,
                          CBB *out_compressible, ssl_client_hello_type_t type);
  bool (*parse_serverhello)(SSL_HANDSHAKE *hs, uint8_t *out_alert,
                            CBS *contents);

  bool (*parse_clienthello)(SSL_HANDSHAKE *hs, uint8_t *out_alert,
                            CBS *contents);
  bool (*add_serverhello)(SSL_HANDSHAKE *hs, CBB *out);
};

static bool forbid_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
                                     CBS *contents) {
  if (contents != nullptr) {
    // Servers MUST NOT send this extension.
    *out_alert = SSL_AD_UNSUPPORTED_EXTENSION;
    OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION);
    return false;
  }

  return true;
}

static bool ignore_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
                                     CBS *contents) {
  // This extension from the client is handled elsewhere.
  return true;
}

static bool dont_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { return true; }

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

static bool ext_sni_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
                                    CBB *out_compressible,
                                    ssl_client_hello_type_t type) {
  const SSL *const ssl = hs->ssl;
  // If offering ECH, send the public name instead of the configured name.
  Span<const uint8_t> hostname;
  if (type == ssl_client_hello_outer) {
    hostname = hs->selected_ech_config->public_name;
  } else {
    if (ssl->hostname == nullptr) {
      return true;
    }
    hostname = StringAsBytes(ssl->hostname.get());
  }

  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, hostname.data(), hostname.size()) ||
      !CBB_flush(out)) {
    return false;
  }

  return true;
}

static bool ext_sni_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
                                      CBS *contents) {
  // The server may acknowledge SNI with an empty extension. We check the syntax
  // but otherwise ignore this signal.
  return contents == nullptr || CBS_len(contents) == 0;
}

static bool ext_sni_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
                                      CBS *contents) {
  // SNI has already been parsed earlier in the handshake. See |extract_sni|.
  return true;
}

static bool ext_sni_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
  // RFC 6066 says "When resuming a session, the server MUST NOT include a
  // server_name extension in the server hello."
  if (hs->ssl->s3->session_reused ||  //
      !hs->should_ack_sni) {
    return true;
  }

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

  return true;
}


// Encrypted ClientHello (ECH)
//
// https://www.rfc-editor.org/rfc/rfc9849.html

static bool ext_ech_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
                                    CBB *out_compressible,
                                    ssl_client_hello_type_t type) {
  if (type == ssl_client_hello_inner) {
    if (!CBB_add_u16(out, TLSEXT_TYPE_encrypted_client_hello) ||
        !CBB_add_u16(out, /* length */ 1) ||
        !CBB_add_u8(out, ECH_CLIENT_INNER)) {
      return false;
    }
    return true;
  }

  if (hs->ech_client_outer.empty()) {
    return true;
  }

  CBB ech_body;
  if (!CBB_add_u16(out, TLSEXT_TYPE_encrypted_client_hello) ||
      !CBB_add_u16_length_prefixed(out, &ech_body) ||
      !CBB_add_u8(&ech_body, ECH_CLIENT_OUTER) ||
      !CBB_add_bytes(&ech_body, hs->ech_client_outer.data(),
                     hs->ech_client_outer.size()) ||
      !CBB_flush(out)) {
    return false;
  }
  return true;
}

static bool ext_ech_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
                                      CBS *contents) {
  SSL *const ssl = hs->ssl;
  if (contents == nullptr) {
    return true;
  }

  // The ECH extension may not be sent in TLS 1.2 ServerHello, only TLS 1.3
  // EncryptedExtensions. It also may not be sent in response to an inner ECH
  // extension.
  if (ssl_protocol_version(ssl) < TLS1_3_VERSION ||
      ssl->s3->ech_status == ssl_ech_accepted) {
    *out_alert = SSL_AD_UNSUPPORTED_EXTENSION;
    OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION);
    return false;
  }

  if (!ssl_is_valid_ech_config_list(*contents)) {
    *out_alert = SSL_AD_DECODE_ERROR;
    return false;
  }

  if (ssl->s3->ech_status == ssl_ech_rejected &&
      !hs->ech_retry_configs.CopyFrom(*contents)) {
    *out_alert = SSL_AD_INTERNAL_ERROR;
    return false;
  }

  return true;
}

static bool ext_ech_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
                                      CBS *contents) {
  if (contents == nullptr) {
    return true;
  }

  uint8_t type;
  if (!CBS_get_u8(contents, &type)) {
    return false;
  }
  if (type == ECH_CLIENT_OUTER) {
    // Outer ECH extensions are handled outside the callback.
    return true;
  }
  if (type != ECH_CLIENT_INNER || CBS_len(contents) != 0) {
    return false;
  }

  hs->ech_is_inner = true;
  return true;
}

static bool ext_ech_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
  SSL *const ssl = hs->ssl;
  if (ssl_protocol_version(ssl) < TLS1_3_VERSION ||
      ssl->s3->ech_status == ssl_ech_accepted ||  //
      hs->ech_keys == nullptr) {
    return true;
  }

  // Write the list of retry configs to |out|. Note |SSL_CTX_set1_ech_keys|
  // ensures |ech_keys| contains at least one retry config.
  CBB body, retry_configs;
  if (!CBB_add_u16(out, TLSEXT_TYPE_encrypted_client_hello) ||
      !CBB_add_u16_length_prefixed(out, &body) ||
      !CBB_add_u16_length_prefixed(&body, &retry_configs)) {
    return false;
  }
  for (const auto &config : hs->ech_keys->configs) {
    if (!config->is_retry_config()) {
      continue;
    }
    if (!CBB_add_bytes(&retry_configs, config->ech_config().raw.data(),
                       config->ech_config().raw.size())) {
      return false;
    }
  }
  return CBB_flush(out);
}


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

static bool ext_ri_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
                                   CBB *out_compressible,
                                   ssl_client_hello_type_t type) {
  const SSL *const ssl = hs->ssl;
  // Renegotiation indication is not necessary in TLS 1.3.
  if (hs->min_version >= TLS1_3_VERSION ||  //
      type == ssl_client_hello_inner) {
    return true;
  }

  assert(ssl->s3->initial_handshake_complete ==
         !ssl->s3->previous_client_finished.empty());

  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.data(),
                     ssl->s3->previous_client_finished.size()) ||
      !CBB_flush(out)) {
    return false;
  }

  return true;
}

static bool ext_ri_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
                                     CBS *contents) {
  SSL *const ssl = hs->ssl;
  if (contents != nullptr && ssl_protocol_version(ssl) >= TLS1_3_VERSION) {
    *out_alert = SSL_AD_ILLEGAL_PARAMETER;
    return false;
  }

  // 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 != nullptr) != ssl->s3->send_connection_binding) {
    *out_alert = SSL_AD_HANDSHAKE_FAILURE;
    OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_MISMATCH);
    return false;
  }

  if (contents == nullptr) {
    // 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 true;
  }

  // Check for logic errors.
  assert(ssl->s3->previous_client_finished.size() ==
         ssl->s3->previous_server_finished.size());
  assert(ssl->s3->initial_handshake_complete ==
         !ssl->s3->previous_client_finished.empty());

  // 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 false;
  }

  // Check that the extension matches.
  CBS client_verify, server_verify;
  if (!CBS_get_bytes(&renegotiated_connection, &client_verify,
                     ssl->s3->previous_client_finished.size()) ||
      !CBS_get_bytes(&renegotiated_connection, &server_verify,
                     ssl->s3->previous_server_finished.size()) ||
      CBS_len(&renegotiated_connection) != 0) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_MISMATCH);
    *out_alert = SSL_AD_HANDSHAKE_FAILURE;
    return false;
  }

  bool ok =
      CBS_mem_equal(&client_verify, ssl->s3->previous_client_finished.data(),
                    ssl->s3->previous_client_finished.size()) &&
      CBS_mem_equal(&server_verify, ssl->s3->previous_server_finished.data(),
                    ssl->s3->previous_server_finished.size());
  if (CRYPTO_fuzzer_mode_enabled()) {
    ok = true;
  }
  if (!ok) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_MISMATCH);
    *out_alert = SSL_AD_HANDSHAKE_FAILURE;
    return false;
  }

  ssl->s3->send_connection_binding = true;
  return true;
}

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

  if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) {
    return true;
  }

  if (contents == nullptr) {
    return true;
  }

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

  // Check that the extension matches. We do not support renegotiation as a
  // server, so this must be empty.
  if (CBS_len(&renegotiated_connection) != 0) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_MISMATCH);
    *out_alert = SSL_AD_HANDSHAKE_FAILURE;
    return false;
  }

  ssl->s3->send_connection_binding = true;

  return true;
}

static bool ext_ri_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
  SSL *const ssl = hs->ssl;
  // Renegotiation isn't supported as a server so this function should never be
  // called after the initial handshake.
  assert(!ssl->s3->initial_handshake_complete);

  if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) {
    return true;
  }

  if (!CBB_add_u16(out, TLSEXT_TYPE_renegotiate) ||
      !CBB_add_u16(out, 1 /* length */) ||
      !CBB_add_u8(out, 0 /* empty renegotiation info */)) {
    return false;
  }

  return true;
}


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

static bool ext_ems_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
                                    CBB *out_compressible,
                                    ssl_client_hello_type_t type) {
  // Extended master secret is not necessary in TLS 1.3.
  if (hs->min_version >= TLS1_3_VERSION || type == ssl_client_hello_inner) {
    return true;
  }

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

  return true;
}

static bool ext_ems_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
                                      CBS *contents) {
  SSL *const ssl = hs->ssl;

  if (contents != nullptr) {
    if (ssl_protocol_version(ssl) >= TLS1_3_VERSION ||  //
        CBS_len(contents) != 0) {
      return false;
    }

    hs->extended_master_secret = true;
  }

  // Whether EMS is negotiated may not change on renegotiation.
  if (ssl->s3->established_session != nullptr &&
      hs->extended_master_secret !=
          !!ssl->s3->established_session->extended_master_secret) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_EMS_MISMATCH);
    *out_alert = SSL_AD_ILLEGAL_PARAMETER;
    return false;
  }

  return true;
}

static bool ext_ems_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
                                      CBS *contents) {
  if (ssl_protocol_version(hs->ssl) >= TLS1_3_VERSION) {
    return true;
  }

  if (contents == nullptr) {
    return true;
  }

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

  hs->extended_master_secret = true;
  return true;
}

static bool ext_ems_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
  if (!hs->extended_master_secret) {
    return true;
  }

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

  return true;
}


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

static bool ext_ticket_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
                                       CBB *out_compressible,
                                       ssl_client_hello_type_t type) {
  const SSL *const ssl = hs->ssl;
  // TLS 1.3 uses a different ticket extension.
  if (hs->min_version >= TLS1_3_VERSION || type == ssl_client_hello_inner ||
      SSL_get_options(ssl) & SSL_OP_NO_TICKET) {
    return true;
  }

  // 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.
  Span<const uint8_t> ticket;
  if (!ssl->s3->initial_handshake_complete &&  //
      ssl->session != nullptr &&
      ssl_session_get_type(ssl->session.get()) == SSLSessionType::kTicket) {
    ticket = ssl->session->ticket;
  }

  CBB ticket_cbb;
  if (!CBB_add_u16(out, TLSEXT_TYPE_session_ticket) ||
      !CBB_add_u16_length_prefixed(out, &ticket_cbb) ||
      !CBB_add_bytes(&ticket_cbb, ticket.data(), ticket.size()) ||
      !CBB_flush(out)) {
    return false;
  }

  return true;
}

static bool ext_ticket_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
                                         CBS *contents) {
  SSL *const ssl = hs->ssl;
  if (contents == nullptr) {
    return true;
  }

  if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) {
    return false;
  }

  // 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 false;
  }

  hs->ticket_expected = true;
  return true;
}

static bool ext_ticket_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
  if (!hs->ticket_expected) {
    return true;
  }

  // If |SSL_OP_NO_TICKET| is set, |ticket_expected| should never be true.
  assert((SSL_get_options(hs->ssl) & SSL_OP_NO_TICKET) == 0);

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

  return true;
}


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

static bool ext_sigalgs_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
                                        CBB *out_compressible,
                                        ssl_client_hello_type_t type) {
  if (hs->max_version < TLS1_2_VERSION) {
    return true;
  }
  // Skip signature_algorithms if we wouldn't accept a certificate mode anyway.
  if (!ssl_accepts_server_certificate_auth(hs)) {
    return true;
  }

  CBB contents, sigalgs_cbb;
  if (!CBB_add_u16(out_compressible, TLSEXT_TYPE_signature_algorithms) ||
      !CBB_add_u16_length_prefixed(out_compressible, &contents) ||
      !CBB_add_u16_length_prefixed(&contents, &sigalgs_cbb) ||
      !tls12_add_verify_sigalgs(hs, &sigalgs_cbb) ||
      !CBB_flush(out_compressible)) {
    return false;
  }

  return true;
}

static bool ext_sigalgs_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
                                          CBS *contents) {
  hs->peer_sigalgs.Reset();
  if (contents == nullptr) {
    return true;
  }

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

  return true;
}


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

static bool ext_ocsp_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
                                     CBB *out_compressible,
                                     ssl_client_hello_type_t type) {
  if (!hs->config->ocsp_stapling_enabled) {
    return true;
  }

  CBB contents;
  if (!CBB_add_u16(out_compressible, TLSEXT_TYPE_status_request) ||
      !CBB_add_u16_length_prefixed(out_compressible, &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_compressible)) {
    return false;
  }

  return true;
}

static bool ext_ocsp_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
                                       CBS *contents) {
  SSL *const ssl = hs->ssl;
  if (contents == nullptr) {
    return true;
  }

  // TLS 1.3 OCSP responses are included in the Certificate extensions.
  if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) {
    return false;
  }

  // OCSP stapling is forbidden on non-certificate ciphers.
  if (CBS_len(contents) != 0 ||
      !ssl_cipher_uses_certificate_auth(hs->new_cipher)) {
    return false;
  }

  // Note this does not check for resumption in TLS 1.2. Sending
  // status_request here does not make sense, but OpenSSL does so and the
  // specification does not say anything. Tolerate it but ignore it.

  hs->certificate_status_expected = true;
  return true;
}

static bool ext_ocsp_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
                                       CBS *contents) {
  if (contents == nullptr) {
    return true;
  }

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

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

  return true;
}

static bool ext_ocsp_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
  SSL *const ssl = hs->ssl;
  if (ssl_protocol_version(ssl) >= TLS1_3_VERSION ||
      !hs->ocsp_stapling_requested || ssl->s3->session_reused ||
      !ssl_cipher_uses_certificate_auth(hs->new_cipher) ||
      hs->credential->ocsp_response == nullptr) {
    return true;
  }

  hs->certificate_status_expected = true;

  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 bool ext_npn_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
                                    CBB *out_compressible,
                                    ssl_client_hello_type_t type) {
  const SSL *const ssl = hs->ssl;
  if (ssl->ctx->next_proto_select_cb == nullptr ||
      // Do not allow NPN to change on renegotiation.
      ssl->s3->initial_handshake_complete ||
      // NPN is not defined in DTLS or TLS 1.3.
      SSL_is_dtls(ssl) || hs->min_version >= TLS1_3_VERSION ||
      type == ssl_client_hello_inner) {
    return true;
  }

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

  return true;
}

static bool ext_npn_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
                                      CBS *contents) {
  SSL *const ssl = hs->ssl;
  if (contents == nullptr) {
    return true;
  }

  if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) {
    return false;
  }

  // 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 != nullptr);

  if (!ssl->s3->alpn_selected.empty()) {
    // 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 false;
  }

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

  // |orig_len| fits in |unsigned| because TLS extensions use 16-bit lengths.
  uint8_t *selected;
  uint8_t selected_len;
  if (ssl->ctx->next_proto_select_cb(
          ssl, &selected, &selected_len, orig_contents,
          static_cast<unsigned>(orig_len),
          ssl->ctx->next_proto_select_cb_arg) != SSL_TLSEXT_ERR_OK ||
      !ssl->s3->next_proto_negotiated.CopyFrom(Span(selected, selected_len))) {
    *out_alert = SSL_AD_INTERNAL_ERROR;
    return false;
  }

  hs->next_proto_neg_seen = true;
  return true;
}

static bool ext_npn_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
                                      CBS *contents) {
  SSL *const ssl = hs->ssl;
  if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) {
    return true;
  }

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

  if (contents == nullptr ||                             //
      ssl->s3->initial_handshake_complete ||             //
      ssl->ctx->next_protos_advertised_cb == nullptr ||  //
      SSL_is_dtls(ssl)) {
    return true;
  }

  hs->next_proto_neg_seen = true;
  return true;
}

static bool ext_npn_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
  SSL *const ssl = hs->ssl;
  // |next_proto_neg_seen| might have been cleared when an ALPN extension was
  // parsed.
  if (!hs->next_proto_neg_seen) {
    return true;
  }

  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) {
    hs->next_proto_neg_seen = false;
    return true;
  }

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

  return true;
}


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

static bool ext_sct_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
                                    CBB *out_compressible,
                                    ssl_client_hello_type_t type) {
  if (!hs->config->signed_cert_timestamps_enabled) {
    return true;
  }

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

  return true;
}

static bool ext_sct_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
                                      CBS *contents) {
  SSL *const ssl = hs->ssl;
  if (contents == nullptr) {
    return true;
  }

  // TLS 1.3 SCTs are included in the Certificate extensions.
  if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) {
    *out_alert = SSL_AD_DECODE_ERROR;
    return false;
  }

  // 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(hs->config->signed_cert_timestamps_enabled);

  if (!ssl_is_sct_list_valid(contents)) {
    *out_alert = SSL_AD_DECODE_ERROR;
    return false;
  }

  // Session resumption uses the original session information. The extension
  // should not be sent on resumption, but RFC 6962 did not make it a
  // requirement, so tolerate this.
  //
  // TODO(davidben): Enforce this anyway.
  if (!ssl->s3->session_reused) {
    hs->new_session->signed_cert_timestamp_list.reset(
        CRYPTO_BUFFER_new_from_CBS(contents, ssl->ctx->pool.get()));
    if (hs->new_session->signed_cert_timestamp_list == nullptr) {
      *out_alert = SSL_AD_INTERNAL_ERROR;
      return false;
    }
  }

  return true;
}

static bool ext_sct_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
                                      CBS *contents) {
  if (contents == nullptr) {
    return true;
  }

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

  hs->scts_requested = true;
  return true;
}

static bool ext_sct_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
  SSL *const ssl = hs->ssl;
  assert(hs->scts_requested);
  // The extension shouldn't be sent when resuming sessions.
  if (ssl_protocol_version(ssl) >= TLS1_3_VERSION || ssl->s3->session_reused ||
      !ssl_cipher_uses_certificate_auth(hs->new_cipher) ||
      hs->credential->signed_cert_timestamp_list == nullptr) {
    return true;
  }

  CBB contents;
  return CBB_add_u16(out, TLSEXT_TYPE_certificate_timestamp) &&
         CBB_add_u16_length_prefixed(out, &contents) &&
         CBB_add_bytes(&contents,
                       CRYPTO_BUFFER_data(
                           hs->credential->signed_cert_timestamp_list.get()),
                       CRYPTO_BUFFER_len(
                           hs->credential->signed_cert_timestamp_list.get())) &&
         CBB_flush(out);
}


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

static bool ext_alpn_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
                                     CBB *out_compressible,
                                     ssl_client_hello_type_t type) {
  const SSL *const ssl = hs->ssl;
  if (hs->config->alpn_client_proto_list.empty() && SSL_is_quic(ssl)) {
    // ALPN MUST be used with QUIC.
    OPENSSL_PUT_ERROR(SSL, SSL_R_NO_APPLICATION_PROTOCOL);
    return false;
  }

  if (hs->config->alpn_client_proto_list.empty() ||
      ssl->s3->initial_handshake_complete) {
    return true;
  }

  CBB contents, proto_list;
  if (!CBB_add_u16(out_compressible,
                   TLSEXT_TYPE_application_layer_protocol_negotiation) ||
      !CBB_add_u16_length_prefixed(out_compressible, &contents) ||
      !CBB_add_u16_length_prefixed(&contents, &proto_list) ||
      !CBB_add_bytes(&proto_list, hs->config->alpn_client_proto_list.data(),
                     hs->config->alpn_client_proto_list.size()) ||
      !CBB_flush(out_compressible)) {
    return false;
  }

  return true;
}

static bool ext_alpn_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
                                       CBS *contents) {
  SSL *const ssl = hs->ssl;
  if (contents == nullptr) {
    if (SSL_is_quic(ssl)) {
      // ALPN is required when QUIC is used.
      OPENSSL_PUT_ERROR(SSL, SSL_R_NO_APPLICATION_PROTOCOL);
      *out_alert = SSL_AD_NO_APPLICATION_PROTOCOL;
      return false;
    }
    return true;
  }

  assert(!ssl->s3->initial_handshake_complete);
  assert(!hs->config->alpn_client_proto_list.empty());

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

  // 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 false;
  }

  if (!ssl_is_alpn_protocol_allowed(hs, protocol_name)) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_ALPN_PROTOCOL);
    *out_alert = SSL_AD_ILLEGAL_PARAMETER;
    return false;
  }

  if (!ssl->s3->alpn_selected.CopyFrom(protocol_name)) {
    *out_alert = SSL_AD_INTERNAL_ERROR;
    return false;
  }

  return true;
}

bool ssl_is_valid_alpn_list(Span<const uint8_t> in) {
  CBS protocol_name_list = in;
  if (CBS_len(&protocol_name_list) == 0) {
    return false;
  }
  while (CBS_len(&protocol_name_list) > 0) {
    CBS protocol_name;
    if (!CBS_get_u8_length_prefixed(&protocol_name_list, &protocol_name) ||
        // Empty protocol names are forbidden.
        CBS_len(&protocol_name) == 0) {
      return false;
    }
  }
  return true;
}

bool ssl_is_alpn_protocol_allowed(const SSL_HANDSHAKE *hs,
                                  Span<const uint8_t> protocol) {
  if (hs->config->alpn_client_proto_list.empty()) {
    return false;
  }

  if (hs->ssl->ctx->allow_unknown_alpn_protos) {
    return true;
  }

  // Check that the protocol name is one of the ones we advertised.
  return ssl_alpn_list_contains_protocol(hs->config->alpn_client_proto_list,
                                         protocol);
}

bool ssl_alpn_list_contains_protocol(Span<const uint8_t> list,
                                     Span<const uint8_t> protocol) {
  CBS cbs = list, candidate;
  while (CBS_len(&cbs) > 0) {
    if (!CBS_get_u8_length_prefixed(&cbs, &candidate)) {
      return false;
    }

    if (candidate == protocol) {
      return true;
    }
  }

  return false;
}

bool ssl_negotiate_alpn(SSL_HANDSHAKE *hs, uint8_t *out_alert,
                        const SSL_CLIENT_HELLO *client_hello) {
  SSL *const ssl = hs->ssl;
  CBS contents;
  if (ssl->ctx->alpn_select_cb == nullptr ||
      !ssl_client_hello_get_extension(
          client_hello, &contents,
          TLSEXT_TYPE_application_layer_protocol_negotiation)) {
    if (SSL_is_quic(ssl)) {
      // ALPN is required when QUIC is used.
      OPENSSL_PUT_ERROR(SSL, SSL_R_NO_APPLICATION_PROTOCOL);
      *out_alert = SSL_AD_NO_APPLICATION_PROTOCOL;
      return false;
    }
    // Ignore ALPN if not configured or no extension was supplied.
    return true;
  }

  // ALPN takes precedence over NPN.
  hs->next_proto_neg_seen = false;

  CBS protocol_name_list;
  if (!CBS_get_u16_length_prefixed(&contents, &protocol_name_list) ||  //
      CBS_len(&contents) != 0 ||                                       //
      !ssl_is_valid_alpn_list(protocol_name_list)) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_PARSE_TLSEXT);
    *out_alert = SSL_AD_DECODE_ERROR;
    return false;
  }

  // |protocol_name_list| fits in |unsigned| because TLS extensions use 16-bit
  // lengths.
  const uint8_t *selected;
  uint8_t selected_len;
  int ret = ssl->ctx->alpn_select_cb(
      ssl, &selected, &selected_len, CBS_data(&protocol_name_list),
      static_cast<unsigned>(CBS_len(&protocol_name_list)),
      ssl->ctx->alpn_select_cb_arg);
  // ALPN is required when QUIC is used.
  if (SSL_is_quic(ssl) &&
      (ret == SSL_TLSEXT_ERR_NOACK || ret == SSL_TLSEXT_ERR_ALERT_WARNING)) {
    ret = SSL_TLSEXT_ERR_ALERT_FATAL;
  }
  switch (ret) {
    case SSL_TLSEXT_ERR_OK:
      if (selected_len == 0) {
        OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_ALPN_PROTOCOL);
        *out_alert = SSL_AD_INTERNAL_ERROR;
        return false;
      }
      if (!ssl->s3->alpn_selected.CopyFrom(Span(selected, selected_len))) {
        *out_alert = SSL_AD_INTERNAL_ERROR;
        return false;
      }
      break;
    case SSL_TLSEXT_ERR_NOACK:
    case SSL_TLSEXT_ERR_ALERT_WARNING:
      break;
    case SSL_TLSEXT_ERR_ALERT_FATAL:
      *out_alert = SSL_AD_NO_APPLICATION_PROTOCOL;
      OPENSSL_PUT_ERROR(SSL, SSL_R_NO_APPLICATION_PROTOCOL);
      return false;
    default:
      // Invalid return value.
      *out_alert = SSL_AD_INTERNAL_ERROR;
      OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
      return false;
  }

  return true;
}

static bool ext_alpn_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
  SSL *const ssl = hs->ssl;
  if (ssl->s3->alpn_selected.empty()) {
    return true;
  }

  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.data(),
                     ssl->s3->alpn_selected.size()) ||
      !CBB_flush(out)) {
    return false;
  }

  return true;
}


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

static bool ext_channel_id_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
                                           CBB *out_compressible,
                                           ssl_client_hello_type_t type) {
  const SSL *const ssl = hs->ssl;
  if (!hs->config->channel_id_private || SSL_is_dtls(ssl) ||
      // Don't offer Channel ID in ClientHelloOuter. ClientHelloOuter handshakes
      // are not authenticated for the name that can learn the Channel ID.
      //
      // We could alternatively offer the extension but sign with a random key.
      // For other extensions, we try to align |ssl_client_hello_outer| and
      // |ssl_client_hello_unencrypted|, to improve the effectiveness of ECH
      // GREASE. However, Channel ID is deprecated and unlikely to be used with
      // ECH, so do the simplest thing.
      type == ssl_client_hello_outer) {
    return true;
  }

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

  return true;
}

static bool ext_channel_id_parse_serverhello(SSL_HANDSHAKE *hs,
                                             uint8_t *out_alert,
                                             CBS *contents) {
  if (contents == nullptr) {
    return true;
  }

  assert(!SSL_is_dtls(hs->ssl));
  assert(hs->config->channel_id_private);

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

  hs->channel_id_negotiated = true;
  return true;
}

static bool ext_channel_id_parse_clienthello(SSL_HANDSHAKE *hs,
                                             uint8_t *out_alert,
                                             CBS *contents) {
  SSL *const ssl = hs->ssl;
  if (contents == nullptr || !hs->config->channel_id_enabled ||
      SSL_is_dtls(ssl)) {
    return true;
  }

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

  hs->channel_id_negotiated = true;
  return true;
}

static bool ext_channel_id_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
  if (!hs->channel_id_negotiated) {
    return true;
  }

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

  return true;
}


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

static bool ext_srtp_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
                                     CBB *out_compressible,
                                     ssl_client_hello_type_t type) {
  const SSL *const ssl = hs->ssl;
  const STACK_OF(SRTP_PROTECTION_PROFILE) *profiles =
      SSL_get_srtp_profiles(ssl);
  if (profiles == nullptr ||                            //
      sk_SRTP_PROTECTION_PROFILE_num(profiles) == 0 ||  //
      !SSL_is_dtls(ssl)) {
    return true;
  }

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

  for (const SRTP_PROTECTION_PROFILE *profile : profiles) {
    if (!CBB_add_u16(&profile_ids, profile->id)) {
      return false;
    }
  }

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

  return true;
}

static bool ext_srtp_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
                                       CBS *contents) {
  SSL *const ssl = hs->ssl;
  if (contents == nullptr) {
    return true;
  }

  // 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
  assert(SSL_is_dtls(ssl));
  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 false;
  }

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

  // Check to see if the server gave us something we support and offered.
  for (const SRTP_PROTECTION_PROFILE *profile : SSL_get_srtp_profiles(ssl)) {
    if (profile->id == profile_id) {
      ssl->s3->srtp_profile = profile;
      return true;
    }
  }

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

static bool ext_srtp_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
                                       CBS *contents) {
  SSL *const ssl = hs->ssl;
  // DTLS-SRTP is only defined for DTLS.
  if (contents == nullptr || !SSL_is_dtls(ssl)) {
    return true;
  }

  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 false;
  }
  // 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.
  for (const SRTP_PROTECTION_PROFILE *server_profile : server_profiles) {
    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 false;
      }

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

  return true;
}

static bool ext_srtp_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
  SSL *const ssl = hs->ssl;
  if (ssl->s3->srtp_profile == nullptr) {
    return true;
  }

  assert(SSL_is_dtls(ssl));
  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->s3->srtp_profile->id) ||
      !CBB_add_u8(&contents, 0 /* empty MKI */) || !CBB_flush(out)) {
    return false;
  }

  return true;
}


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

static bool ext_ec_point_add_extension(const SSL_HANDSHAKE *hs, CBB *out) {
  CBB contents, formats;
  if (!CBB_add_u16(out, TLSEXT_TYPE_ec_point_formats) ||
      !CBB_add_u16_length_prefixed(out, &contents) ||
      !CBB_add_u8_length_prefixed(&contents, &formats) ||
      !CBB_add_u8(&formats, TLSEXT_ECPOINTFORMAT_uncompressed) ||
      !CBB_flush(out)) {
    return false;
  }

  return true;
}

static bool ext_ec_point_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
                                         CBB *out_compressible,
                                         ssl_client_hello_type_t type) {
  // The point format extension is unnecessary in TLS 1.3.
  if (hs->min_version >= TLS1_3_VERSION || type == ssl_client_hello_inner) {
    return true;
  }

  return ext_ec_point_add_extension(hs, out);
}

static bool ext_ec_point_parse_serverhello(SSL_HANDSHAKE *hs,
                                           uint8_t *out_alert, CBS *contents) {
  if (contents == nullptr) {
    return true;
  }

  if (ssl_protocol_version(hs->ssl) >= TLS1_3_VERSION) {
    return false;
  }

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

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

  return true;
}

static bool ext_ec_point_parse_clienthello(SSL_HANDSHAKE *hs,
                                           uint8_t *out_alert, CBS *contents) {
  if (ssl_protocol_version(hs->ssl) >= TLS1_3_VERSION) {
    return true;
  }

  return ext_ec_point_parse_serverhello(hs, out_alert, contents);
}

static bool ext_ec_point_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
  SSL *const ssl = hs->ssl;
  if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) {
    return true;
  }

  const uint32_t alg_k = hs->new_cipher->algorithm_mkey;
  const uint32_t alg_a = hs->new_cipher->algorithm_auth;
  const bool using_ecc = (alg_k & SSL_kECDHE) || (alg_a & SSL_aECDSA);

  if (!using_ecc) {
    return true;
  }

  return ext_ec_point_add_extension(hs, out);
}


// Pre Shared Key
//
// https://tools.ietf.org/html/rfc8446#section-4.2.11

bool ssl_setup_pre_shared_keys(SSL_HANDSHAKE *hs) {
  const SSL *const ssl = hs->ssl;
  if (hs->max_version < TLS1_3_VERSION) {
    return true;
  }

  if (SSL_SESSION *session = ssl->session.get();
      session != nullptr &&
      ssl_session_get_type(session) == SSLSessionType::kPreSharedKey &&
      !hs->pre_shared_keys.Push(UpRef(session))) {
    return false;
  }

  const uint16_t epsk_protocol =
      SSL_is_dtls(ssl) ? DTLS1_3_VERSION : TLS1_3_VERSION;
#if defined(TLS1_4_VERSION)
#error "More imported PSKs may be needed when TLS 1.4 exists"
#endif
  for (const auto &cred : hs->config->cert->credentials) {
    if (cred->type != SSLCredentialType::kPreSharedKey) {
      continue;
    }
    // We need SHA-256 and SHA-384 variants to cover supported cipher suites.
    for (const EVP_MD *md : {EVP_sha256(), EVP_sha384()}) {
      std::optional<SSLImportedPSK> psk =
          tls13_derive_imported_psk(hs, cred.get(), epsk_protocol, md);
      if (!psk || !hs->pre_shared_keys.Push(*std::move(psk))) {
        return false;
      }
    }
  }

  return true;
}

static bool should_offer_psk(const SSL_HANDSHAKE *hs,
                             ssl_client_hello_type_t type) {
  // TODO(https://crbug.com/boringssl/275): Should we synthesize a placeholder
  // PSK, at least when we offer early data? Otherwise ClientHelloOuter will
  // contain an early_data extension without a pre_shared_key extension and
  // potentially break the recovery flow.
  return hs->max_version >= TLS1_3_VERSION && !hs->pre_shared_keys.empty() &&
         type != ssl_client_hello_outer;
}

static size_t ext_pre_shared_key_clienthello_length(
    const SSL_HANDSHAKE *hs, ssl_client_hello_type_t type) {
  if (!should_offer_psk(hs, type)) {
    return 0;
  }

  // extension value, extension length, identities length, binders length.
  size_t ret = 2 + 2 + 2 + 2;
  for (const auto &psk : hs->pre_shared_keys) {
    // identity
    ret += 2 + ssl_pre_shared_key_identity(psk).size();
    // obfuscated_ticket_age
    ret += 4;
    // binder
    ret += 1 + EVP_MD_size(ssl_pre_shared_key_hash(psk));
  }
  return ret;
}

// ext_pre_shared_key_add_clienthello writes a pre_shared_key extension to
// |out_extensions| and flushes |out_client_hello|, invalidating
// |out_extensions|. |out_extensions| must be a child of |out_client_hello|.
//
// This function differs from other |CBB| functions because it needs to
// accommodate PSK binders. It must write the PSK extension, flush the |CBB| to
// write out a length prefix, and then finally sample the whole ClientHello.
static bool ext_pre_shared_key_add_clienthello(const SSL_HANDSHAKE *hs,
                                               CBB *out_client_hello,
                                               CBB *out_extensions,
                                               size_t *out_psk_len,
                                               ssl_client_hello_type_t type) {
  const SSL *const ssl = hs->ssl;
  if (!should_offer_psk(hs, type)) {
    *out_psk_len = 0;
    // Discard empty extensions blocks.
    if (CBB_len(out_extensions) == 0) {
      CBB_discard_child(out_client_hello);
    }
    return CBB_flush(out_client_hello);
  }

  const size_t len_before = CBB_len(out_extensions);
  CBB contents, identities, identity, binders, binder;
  if (!CBB_add_u16(out_extensions, TLSEXT_TYPE_pre_shared_key) ||
      !CBB_add_u16_length_prefixed(out_extensions, &contents) ||
      !CBB_add_u16_length_prefixed(&contents, &identities)) {
    return false;
  }

  // Fill in the PSK identities.
  for (const auto &psk : hs->pre_shared_keys) {
    if (const auto *imported = std::get_if<SSLImportedPSK>(&psk);
        imported != nullptr) {
      if (!CBB_add_u16_length_prefixed(&identities, &identity) ||
          !CBB_add_bytes(&identity, imported->imported_identity.data(),
                         imported->imported_identity.size()) ||
          !CBB_add_u32(&identities, 0 /* obfuscated_ticket_age */)) {
        return false;
      }
    } else {
      const SSL_SESSION *session = std::get<UniquePtr<SSL_SESSION>>(psk).get();
      // At most one PSK will be a session.
      assert(session == ssl->session.get());
      OPENSSL_timeval now = ssl_ctx_get_current_time(ssl->ctx.get());
      uint32_t ticket_age = 1000 * (now.tv_sec - session->time);
      uint32_t obfuscated_ticket_age = ticket_age + session->ticket_age_add;
      if (!CBB_add_u16_length_prefixed(&identities, &identity) ||
          !CBB_add_bytes(&identity, session->ticket.data(),
                         session->ticket.size()) ||
          !CBB_add_u32(&identities, obfuscated_ticket_age)) {
        return false;
      }
    }
  }

  // Fill in placeholder zero binders of the appropriate length. They will be
  // computed and filled in later after length prefixes are computed.
  if (!CBB_add_u16_length_prefixed(&contents, &binders)) {
    return false;
  }
  for (const auto &psk : hs->pre_shared_keys) {
    size_t binder_len = EVP_MD_size(ssl_pre_shared_key_hash(psk));
    if (!CBB_add_u8_length_prefixed(&binders, &binder) ||
        !CBB_add_zeros(&binder, binder_len)) {
      return false;
    }
  }
  if (!CBB_flush(&binders)) {
    return false;
  }
  const size_t binders_len = CBB_len(&binders);

  // Finish the PSK extension and save the length.
  if (!CBB_flush(out_extensions)) {
    return false;
  }
  *out_psk_len = CBB_len(out_extensions) - len_before;

  // Fill in |out_extensions|'s length prefix.
  if (!CBB_flush(out_client_hello)) {
    return false;
  }

  // Fill in binders.
  const auto client_hello = CBBAsSpan(out_client_hello);
  auto remaining_binders_out = client_hello.last(binders_len);
  const auto &transcript =
      type == ssl_client_hello_inner ? hs->inner_transcript : hs->transcript;
  for (const auto &psk : hs->pre_shared_keys) {
    // Skip length prefix.
    remaining_binders_out = remaining_binders_out.subspan(1);
    size_t one_binder_len;
    if (!tls13_psk_binder(hs, remaining_binders_out, &one_binder_len, psk,
                          transcript, client_hello,
                          2 /* length */ + binders_len)) {
      return false;
    }
    remaining_binders_out = remaining_binders_out.subspan(one_binder_len);
  }
  assert(remaining_binders_out.empty());
  return true;
}

const SSLPreSharedKey *ssl_ext_pre_shared_key_parse_serverhello(
    SSL_HANDSHAKE *hs, uint8_t *out_alert, CBS *contents) {
  uint16_t selected_identity;
  if (!CBS_get_u16(contents, &selected_identity) ||  //
      CBS_len(contents) != 0) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
    *out_alert = SSL_AD_DECODE_ERROR;
    return nullptr;
  }

  if (selected_identity >= hs->pre_shared_keys.size()) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_PSK_IDENTITY_NOT_FOUND);
    *out_alert = SSL_AD_UNKNOWN_PSK_IDENTITY;
    return nullptr;
  }

  return &hs->pre_shared_keys[selected_identity];
}

std::optional<SSLOfferedPSK> SSLOfferedPSKs::Next() {
  if (CBS_len(&identities) == 0) {
    return std::nullopt;
  }
  SSLOfferedPSK psk;
  if (!CBS_get_u16_length_prefixed(&identities, &psk.identity) ||
      CBS_len(&psk.identity) == 0 ||
      !CBS_get_u32(&identities, &psk.obfuscated_ticket_age) ||
      !CBS_get_u8_length_prefixed(&binders, &psk.binder) ||
      CBS_len(&psk.binder) == 0) {
    // After a successful parse, this should never happen.
    return std::nullopt;
  }
  return psk;
}

std::optional<SSLOfferedPSKs> ssl_ext_pre_shared_key_parse_clienthello(
    SSL_HANDSHAKE *hs, uint8_t *out_alert, const SSL_CLIENT_HELLO *client_hello,
    CBS *contents) {
  // Verify that the pre_shared_key extension is the last extension in
  // ClientHello.
  if (CBS_data(contents) + CBS_len(contents) !=
      client_hello->extensions + client_hello->extensions_len) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_PRE_SHARED_KEY_MUST_BE_LAST);
    *out_alert = SSL_AD_ILLEGAL_PARAMETER;
    return std::nullopt;
  }

  SSLOfferedPSKs psks;
  if (!CBS_get_u16_length_prefixed(contents, &psks.identities) ||
      !CBS_get_u16_length_prefixed(contents, &psks.binders) ||
      CBS_len(&psks.identities) == 0 ||  //
      CBS_len(&psks.binders) == 0 ||     //
      CBS_len(contents) != 0) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
    *out_alert = SSL_AD_DECODE_ERROR;
    return std::nullopt;
  }

  // Check the syntax of the extension.
  SSLOfferedPSKs copy = psks;
  while (CBS_len(&copy.identities) != 0 && CBS_len(&copy.binders) != 0) {
    if (!copy.Next()) {
      OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
      *out_alert = SSL_AD_DECODE_ERROR;
      return std::nullopt;
    }
  }

  // We should have run out of identities and binders at the same time.
  if (CBS_len(&copy.identities) != 0 ||
      CBS_len(&copy.binders) != 0) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_PSK_IDENTITY_BINDER_COUNT_MISMATCH);
    *out_alert = SSL_AD_ILLEGAL_PARAMETER;
    return std::nullopt;
  }

  return psks;
}

bool ssl_verify_psk_binder(SSL_HANDSHAKE *hs, uint8_t *out_alert,
                           const SSLPreSharedKey &psk,
                           const SSL_CLIENT_HELLO &client_hello) {
  CBS pre_shared_key;
  if (!ssl_client_hello_get_extension(&client_hello, &pre_shared_key,
                                      TLSEXT_TYPE_pre_shared_key)) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_EXTENSION);
    *out_alert = SSL_AD_MISSING_EXTENSION;
    return false;
  }

  std::optional<SSLOfferedPSKs> offered_psks =
      ssl_ext_pre_shared_key_parse_clienthello(hs, out_alert, &client_hello,
                                               &pre_shared_key);
  if (!offered_psks) {
    return false;
  }
  const size_t binders_len =
      2 /* length prefix */ + CBS_len(&offered_psks->binders);

  Span<const uint8_t> identity = ssl_pre_shared_key_identity(psk);
  for (uint16_t index = 0; true; index++) {
    std::optional<SSLOfferedPSK> offered_psk = offered_psks->Next();
    if (!offered_psk) {
      OPENSSL_PUT_ERROR(SSL, SSL_R_PSK_IDENTITY_NOT_FOUND);
      *out_alert = SSL_AD_ILLEGAL_PARAMETER;
      return false;
    }

    if (offered_psk->identity != identity) {
      continue;
    }

    hs->selected_psk_index = index;
    uint8_t verify_data[EVP_MAX_MD_SIZE];
    size_t verify_data_len;
    if (!tls13_psk_binder(
            hs, verify_data, &verify_data_len, psk, hs->transcript,
            Span(client_hello.client_hello, client_hello.client_hello_len),
            binders_len)) {
      *out_alert = SSL_AD_INTERNAL_ERROR;
      return false;
    }

    bool binder_ok = CBS_len(&offered_psk->binder) == verify_data_len &&
                     CRYPTO_memcmp(CBS_data(&offered_psk->binder), verify_data,
                                   verify_data_len) == 0;
    if (CRYPTO_fuzzer_mode_enabled()) {
      binder_ok = true;
    }
    if (!binder_ok) {
      OPENSSL_PUT_ERROR(SSL, SSL_R_DIGEST_CHECK_FAILED);
      *out_alert = SSL_AD_DECRYPT_ERROR;
      return false;
    }
    return true;
  }
}

bool ssl_ext_pre_shared_key_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
  if (!hs->selected_psk_index.has_value()) {
    return true;
  }

  CBB contents;
  if (!CBB_add_u16(out, TLSEXT_TYPE_pre_shared_key) ||
      !CBB_add_u16_length_prefixed(out, &contents) ||
      !CBB_add_u16(&contents, *hs->selected_psk_index) ||  //
      !CBB_flush(out)) {
    return false;
  }

  return true;
}


// Pre-Shared Key Exchange Modes
//
// https://tools.ietf.org/html/rfc8446#section-4.2.9

static bool ext_psk_key_exchange_modes_add_clienthello(
    const SSL_HANDSHAKE *hs, CBB *out, CBB *out_compressible,
    ssl_client_hello_type_t type) {
  if (hs->max_version < TLS1_3_VERSION) {
    return true;
  }
  // We do not support resumption with PAKEs, so do not offer any PSK key
  // exchange modes, to signal the server not to send a ticket.
  if (hs->pake_prover != nullptr) {
    return true;
  }

  CBB contents, ke_modes;
  if (!CBB_add_u16(out_compressible, TLSEXT_TYPE_psk_key_exchange_modes) ||
      !CBB_add_u16_length_prefixed(out_compressible, &contents) ||
      !CBB_add_u8_length_prefixed(&contents, &ke_modes) ||
      !CBB_add_u8(&ke_modes, SSL_PSK_DHE_KE)) {
    return false;
  }

  return CBB_flush(out_compressible);
}

static bool ext_psk_key_exchange_modes_parse_clienthello(SSL_HANDSHAKE *hs,
                                                         uint8_t *out_alert,
                                                         CBS *contents) {
  if (contents == nullptr) {
    return true;
  }

  CBS ke_modes;
  if (!CBS_get_u8_length_prefixed(contents, &ke_modes) ||  //
      CBS_len(&ke_modes) == 0 ||                           //
      CBS_len(contents) != 0) {
    *out_alert = SSL_AD_DECODE_ERROR;
    return false;
  }

  // We only support tickets with PSK_DHE_KE.
  hs->accept_psk_mode = OPENSSL_memchr(CBS_data(&ke_modes), SSL_PSK_DHE_KE,
                                       CBS_len(&ke_modes)) != nullptr;

  return true;
}


// Early Data Indication
//
// https://tools.ietf.org/html/rfc8446#section-4.2.10

static bool ext_early_data_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
                                           CBB *out_compressible,
                                           ssl_client_hello_type_t type) {
  const SSL *const ssl = hs->ssl;
  // The second ClientHello never offers early data, and we must have already
  // filled in |early_data_reason| by this point.
  if (ssl->s3->used_hello_retry_request) {
    assert(ssl->s3->early_data_reason != ssl_early_data_unknown);
    return true;
  }

  if (!hs->early_data_offered) {
    return true;
  }

  // If offering ECH, the extension only applies to ClientHelloInner, but we
  // send the extension in both ClientHellos. This ensures that, if the server
  // handshakes with ClientHelloOuter, it can skip past early data. See
  // RFC 9849, section 6.1.
  if (!CBB_add_u16(out_compressible, TLSEXT_TYPE_early_data) ||  //
      !CBB_add_u16(out_compressible, 0) ||                       //
      !CBB_flush(out_compressible)) {
    return false;
  }

  return true;
}

static bool ext_early_data_parse_serverhello(SSL_HANDSHAKE *hs,
                                             uint8_t *out_alert,
                                             CBS *contents) {
  SSL *const ssl = hs->ssl;
  if (contents == nullptr) {
    if (hs->early_data_offered && !ssl->s3->used_hello_retry_request) {
      ssl->s3->early_data_reason = ssl->s3->session_reused
                                       ? ssl_early_data_peer_declined
                                       : ssl_early_data_session_not_resumed;
    } else {
      // We already filled in |early_data_reason| when declining to offer 0-RTT
      // or handling the implicit HelloRetryRequest reject.
      assert(ssl->s3->early_data_reason != ssl_early_data_unknown);
    }
    return true;
  }

  // If we received an HRR, the second ClientHello never offers early data, so
  // the extensions logic will automatically reject early data extensions as
  // unsolicited. This covered by the ServerAcceptsEarlyDataOnHRR test.
  assert(!ssl->s3->used_hello_retry_request);

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

  if (!ssl->s3->session_reused) {
    *out_alert = SSL_AD_UNSUPPORTED_EXTENSION;
    OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION);
    return false;
  }

  ssl->s3->early_data_reason = ssl_early_data_accepted;
  ssl->s3->early_data_accepted = true;
  return true;
}

static bool ext_early_data_parse_clienthello(SSL_HANDSHAKE *hs,
                                             uint8_t *out_alert,
                                             CBS *contents) {
  SSL *const ssl = hs->ssl;
  if (contents == nullptr || ssl_protocol_version(ssl) < TLS1_3_VERSION) {
    return true;
  }

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

  hs->early_data_offered = true;
  return true;
}

static bool ext_early_data_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
  if (!hs->ssl->s3->early_data_accepted) {
    return true;
  }

  if (!CBB_add_u16(out, TLSEXT_TYPE_early_data) ||  //
      !CBB_add_u16(out, 0) ||                       //
      !CBB_flush(out)) {
    return false;
  }

  return true;
}


// Key Share
//
// https://tools.ietf.org/html/rfc8446#section-4.2.8

bool ssl_setup_key_shares(SSL_HANDSHAKE *hs, uint16_t override_group_id) {
  SSL *const ssl = hs->ssl;
  hs->key_shares.clear();
  hs->key_share_bytes.Reset();

  // If offering a PAKE, do not set up key shares. We do not currently support
  // clients offering both PAKE and non-PAKE modes, including resumption.
  if (hs->max_version < TLS1_3_VERSION || hs->pake_prover) {
    return true;
  }

  const Span<const uint16_t> supported_group_list =
      hs->config->supported_group_list;
  if (supported_group_list.empty()) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_NO_GROUPS_SPECIFIED);
    return false;
  }

  std::optional<Span<const uint16_t>> selected_key_shares;

  // This is used for HelloRetryRequest, where we have already been given the
  // correct group to use.
  if (override_group_id != 0) {
    assert(std::find(supported_group_list.begin(), supported_group_list.end(),
                     override_group_id) != supported_group_list.end());
    selected_key_shares.emplace(&override_group_id, 1u);
  }

  // First try to predict the most preferred (by our preference order) group
  // that was hinted by the server.
  const auto &server_hint_list = ssl->config->server_supported_groups_hint;
  if (!selected_key_shares.has_value() && !server_hint_list.empty()) {
    for (const uint16_t &supported_group : supported_group_list) {
      if (std::find(server_hint_list.begin(), server_hint_list.end(),
                    supported_group) != server_hint_list.end()) {
        selected_key_shares.emplace(&supported_group, 1u);
        break;
      }
    }
  }

  // Otherwise, try to use explicitly configured key shares from the caller.
  if (!selected_key_shares.has_value() &&
      ssl->config->client_key_share_selections.has_value()) {
    selected_key_shares.emplace(*ssl->config->client_key_share_selections);
  }

  // Run the default selection if we don't have anything better.
  InplaceVector<uint16_t, 2> default_key_shares;
  if (!selected_key_shares.has_value()) {
    // By default, predict the most preferred group.
    if (!default_key_shares.TryPushBack(supported_group_list[0])) {
      return false;
    }
    // We'll try to include one post-quantum and one classical initial key
    // share.
    for (size_t i = 1; i < supported_group_list.size(); i++) {
      if (is_post_quantum_group(default_key_shares[0]) ==
          is_post_quantum_group(supported_group_list[i])) {
        continue;
      }
      if (!default_key_shares.TryPushBack(supported_group_list[i])) {
        return false;
      }
      assert(default_key_shares[1] != default_key_shares[0]);
      break;
    }
    selected_key_shares.emplace(default_key_shares);
  }

  assert(selected_key_shares.has_value());

  bssl::ScopedCBB cbb;
  if (!CBB_init(cbb.get(), 64)) {
    return false;
  }

  if (override_group_id == 0 && ssl->ctx->grease_enabled) {
    // Add a fake group. See RFC 8701.
    if (!CBB_add_u16(cbb.get(), ssl_get_grease_value(hs, ssl_grease_group)) ||
        !CBB_add_u16(cbb.get(), 1 /* length */) ||
        !CBB_add_u8(cbb.get(), 0 /* one byte key share */)) {
      return false;
    }
  }

  CBB key_exchange;
  for (const uint16_t group_id : *selected_key_shares) {
    UniquePtr<SSLKeyShare> key_share = SSLKeyShare::Create(group_id);
    if (key_share == nullptr ||                                    //
        !CBB_add_u16(cbb.get(), group_id) ||                       //
        !CBB_add_u16_length_prefixed(cbb.get(), &key_exchange) ||  //
        !key_share->Generate(&key_exchange) ||                     //
        !hs->key_shares.TryPushBack(std::move(key_share))) {
      return false;
    }
  }

  return CBBFinishArray(cbb.get(), &hs->key_share_bytes);
}

static bool ext_key_share_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
                                          CBB *out_compressible,
                                          ssl_client_hello_type_t type) {
  // If offering a PAKE, do not set up key shares. We do not currently support
  // clients offering both PAKE and non-PAKE modes, including resumption.
  if (hs->max_version < TLS1_3_VERSION || hs->pake_prover) {
    return true;
  }

  // The caller may explicitly configure empty key shares to request a
  // HelloRetryRequest.
  assert(!hs->key_share_bytes.empty() ||
         (hs->config->client_key_share_selections.has_value() &&
          hs->config->client_key_share_selections->empty()));

  CBB contents, kse_bytes;
  if (!CBB_add_u16(out_compressible, TLSEXT_TYPE_key_share) ||
      !CBB_add_u16_length_prefixed(out_compressible, &contents) ||
      !CBB_add_u16_length_prefixed(&contents, &kse_bytes) ||
      !CBB_add_bytes(&kse_bytes, hs->key_share_bytes.data(),
                     hs->key_share_bytes.size()) ||
      !CBB_flush(out_compressible)) {
    return false;
  }

  return true;
}

bool ssl_ext_key_share_parse_serverhello(SSL_HANDSHAKE *hs,
                                         Array<uint8_t> *out_secret,
                                         uint8_t *out_alert, CBS *contents) {
  // If we did not offer key shares, the extension should have been rejected
  // as unsolicited.
  assert(!hs->key_shares.empty());

  CBS ciphertext;
  uint16_t group_id;
  if (!CBS_get_u16(contents, &group_id) ||
      !CBS_get_u16_length_prefixed(contents, &ciphertext) ||
      CBS_len(contents) != 0) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
    *out_alert = SSL_AD_DECODE_ERROR;
    return false;
  }

  const auto key_share_it =
      std::find_if(hs->key_shares.begin(), hs->key_shares.end(),
                   [group_id](const auto &key_share) {
                     return key_share->GroupID() == group_id;
                   });
  if (key_share_it == hs->key_shares.end()) {
    *out_alert = SSL_AD_ILLEGAL_PARAMETER;
    OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CURVE);
    return false;
  }
  if (!(*key_share_it)->Decap(out_secret, out_alert, ciphertext)) {
    *out_alert = SSL_AD_INTERNAL_ERROR;
    return false;
  }

  hs->new_session->group_id = group_id;
  hs->key_shares.clear();
  return true;
}

bool ssl_ext_key_share_parse_clienthello(SSL_HANDSHAKE *hs, bool *out_found,
                                         Span<const uint8_t> *out_peer_key,
                                         uint8_t *out_alert,
                                         const SSL_CLIENT_HELLO *client_hello) {
  // We only support connections that include an ECDHE key exchange, or use a
  // PAKE.
  CBS contents;
  if (!ssl_client_hello_get_extension(client_hello, &contents,
                                      TLSEXT_TYPE_key_share)) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_KEY_SHARE);
    *out_alert = SSL_AD_MISSING_EXTENSION;
    return false;
  }

  CBS key_shares;
  if (!CBS_get_u16_length_prefixed(&contents, &key_shares) ||
      CBS_len(&contents) != 0) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
    return false;
  }

  // Find the corresponding key share.
  const uint16_t group_id = hs->new_session->group_id;
  CBS peer_key;
  CBS_init(&peer_key, nullptr, 0);
  while (CBS_len(&key_shares) > 0) {
    uint16_t id;
    CBS peer_key_tmp;
    if (!CBS_get_u16(&key_shares, &id) ||
        !CBS_get_u16_length_prefixed(&key_shares, &peer_key_tmp) ||
        CBS_len(&peer_key_tmp) == 0) {
      OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
      return false;
    }

    if (id == group_id) {
      if (CBS_len(&peer_key) != 0) {
        OPENSSL_PUT_ERROR(SSL, SSL_R_DUPLICATE_KEY_SHARE);
        *out_alert = SSL_AD_ILLEGAL_PARAMETER;
        return false;
      }

      peer_key = peer_key_tmp;
      // Continue parsing the structure to keep peers honest.
    }
  }

  if (out_peer_key != nullptr) {
    *out_peer_key = peer_key;
  }
  *out_found = CBS_len(&peer_key) != 0;
  return true;
}

bool ssl_ext_pake_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
  if (hs->pake_share_bytes.empty()) {
    return true;
  }

  CBB pake_ext, pake_msg;
  if (!CBB_add_u16(out, TLSEXT_TYPE_pake) ||
      !CBB_add_u16_length_prefixed(out, &pake_ext) ||
      !CBB_add_u16(&pake_ext, SSL_PAKE_SPAKE2PLUSV1) ||
      !CBB_add_u16_length_prefixed(&pake_ext, &pake_msg) ||
      !CBB_add_bytes(&pake_msg, hs->pake_share_bytes.data(),
                     hs->pake_share_bytes.size()) ||
      !CBB_flush(out)) {
    return false;
  }
  return true;
}

bool ssl_ext_key_share_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
  if (hs->pake_verifier) {
    // We don't add the key share extension if a PAKE is offered.
    return true;
  }

  CBB entry, ciphertext;
  if (!CBB_add_u16(out, TLSEXT_TYPE_key_share) ||
      !CBB_add_u16_length_prefixed(out, &entry) ||
      !CBB_add_u16(&entry, hs->new_session->group_id) ||
      !CBB_add_u16_length_prefixed(&entry, &ciphertext) ||
      !CBB_add_bytes(&ciphertext, hs->key_share_ciphertext.data(),
                     hs->key_share_ciphertext.size()) ||
      !CBB_flush(out)) {
    return false;
  }
  return true;
}


// Supported Versions
//
// https://tools.ietf.org/html/rfc8446#section-4.2.1

static bool ext_supported_versions_add_clienthello(
    const SSL_HANDSHAKE *hs, CBB *out, CBB *out_compressible,
    ssl_client_hello_type_t type) {
  const SSL *const ssl = hs->ssl;
  if (hs->max_version <= TLS1_2_VERSION) {
    return true;
  }

  // supported_versions is compressible in ECH if ClientHelloOuter already
  // requires TLS 1.3. Otherwise the extensions differ in the older versions.
  if (hs->min_version >= TLS1_3_VERSION) {
    out = out_compressible;
  }

  CBB contents, versions;
  if (!CBB_add_u16(out, TLSEXT_TYPE_supported_versions) ||
      !CBB_add_u16_length_prefixed(out, &contents) ||
      !CBB_add_u8_length_prefixed(&contents, &versions)) {
    return false;
  }

  // Add a fake version. See RFC 8701.
  if (ssl->ctx->grease_enabled &&
      !CBB_add_u16(&versions, ssl_get_grease_value(hs, ssl_grease_version))) {
    return false;
  }

  // Encrypted ClientHellos requires TLS 1.3 or later.
  uint16_t extra_min_version =
      type == ssl_client_hello_inner ? TLS1_3_VERSION : 0;
  if (!ssl_add_supported_versions(hs, &versions, extra_min_version) ||
      !CBB_flush(out)) {
    return false;
  }

  return true;
}


// Cookie
//
// https://tools.ietf.org/html/rfc8446#section-4.2.2

static bool ext_cookie_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
                                       CBB *out_compressible,
                                       ssl_client_hello_type_t type) {
  if (hs->cookie.empty()) {
    return true;
  }

  CBB contents, cookie;
  if (!CBB_add_u16(out_compressible, TLSEXT_TYPE_cookie) ||
      !CBB_add_u16_length_prefixed(out_compressible, &contents) ||
      !CBB_add_u16_length_prefixed(&contents, &cookie) ||
      !CBB_add_bytes(&cookie, hs->cookie.data(), hs->cookie.size()) ||
      !CBB_flush(out_compressible)) {
    return false;
  }

  return true;
}


// Supported Groups
//
// https://tools.ietf.org/html/rfc4492#section-5.1.1
// https://tools.ietf.org/html/rfc8446#section-4.2.7

static bool ext_supported_groups_add_clienthello(const SSL_HANDSHAKE *hs,
                                                 CBB *out,
                                                 CBB *out_compressible,
                                                 ssl_client_hello_type_t type) {
  const SSL *const ssl = hs->ssl;
  // In PAKE mode, supported_groups and key_share are not used.
  if (hs->pake_prover != nullptr) {
    return true;
  }

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

  // Add a fake group. See RFC 8701.
  if (ssl->ctx->grease_enabled &&
      !CBB_add_u16(&groups_bytes, ssl_get_grease_value(hs, ssl_grease_group))) {
    return false;
  }

  for (uint16_t group : hs->config->supported_group_list) {
    if (is_post_quantum_group(group) && hs->max_version < TLS1_3_VERSION) {
      continue;
    }
    if (!CBB_add_u16(&groups_bytes, group)) {
      return false;
    }
  }

  return CBB_flush(out_compressible);
}

static bool ext_supported_groups_parse_serverhello(SSL_HANDSHAKE *hs,
                                                   uint8_t *out_alert,
                                                   CBS *contents) {
  // This extension is not expected to be echoed by servers in TLS 1.2, but some
  // BigIP servers send it nonetheless, so do not enforce this.
  return true;
}

static bool parse_u16_array(const CBS *cbs, Array<uint16_t> *out) {
  CBS copy = *cbs;
  if ((CBS_len(&copy) & 1) != 0) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
    return false;
  }

  Array<uint16_t> ret;
  if (!ret.InitForOverwrite(CBS_len(&copy) / 2)) {
    return false;
  }
  for (size_t i = 0; i < ret.size(); i++) {
    if (!CBS_get_u16(&copy, &ret[i])) {
      OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
      return false;
    }
  }

  assert(CBS_len(&copy) == 0);
  *out = std::move(ret);
  return true;
}

static bool ext_supported_groups_parse_clienthello(SSL_HANDSHAKE *hs,
                                                   uint8_t *out_alert,
                                                   CBS *contents) {
  if (contents == nullptr) {
    return true;
  }

  CBS supported_group_list;
  if (!CBS_get_u16_length_prefixed(contents, &supported_group_list) ||  //
      CBS_len(&supported_group_list) == 0 ||                            //
      CBS_len(contents) != 0 ||                                         //
      !parse_u16_array(&supported_group_list, &hs->peer_supported_group_list)) {
    return false;
  }

  return true;
}


// Certificate Authorities.
//
// https://tools.ietf.org/html/rfc8446#section-4.2.4

static bool ext_certificate_authorities_add_clienthello(
    const SSL_HANDSHAKE *hs, CBB *out, CBB *out_compressible,
    ssl_client_hello_type_t type) {
  // TODO(crbug.com/398275713): What should this send in ClientHelloOuter?
  if (ssl_has_CA_names(hs->config)) {
    CBB ca_contents;
    if (!CBB_add_u16(out_compressible,
                     TLSEXT_TYPE_certificate_authorities) ||             //
        !CBB_add_u16_length_prefixed(out_compressible, &ca_contents) ||  //
        !ssl_add_CA_names(hs, &ca_contents) ||                           //
        !CBB_flush(out_compressible)) {
      return false;
    }
  }
  return true;
}

static bool ext_certificate_authorities_parse_clienthello(SSL_HANDSHAKE *hs,
                                                          uint8_t *out_alert,
                                                          CBS *contents) {
  if (contents == nullptr) {
    return true;
  }

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

  hs->ca_names = SSL_parse_CA_list(hs->ssl, out_alert, contents);
  if (!hs->ca_names || sk_CRYPTO_BUFFER_num(hs->ca_names.get()) == 0 ||
      CBS_len(contents) != 0) {
    return false;
  }

  return true;
}


// Trust Anchor Identifiers
//
// https://datatracker.ietf.org/doc/draft-ietf-tls-trust-anchor-ids/

bool ssl_is_valid_trust_anchor_list(Span<const uint8_t> in) {
  CBS ids = in;
  while (CBS_len(&ids) > 0) {
    CBS id;
    if (!CBS_get_u8_length_prefixed(&ids, &id) ||  //
        CBS_len(&id) == 0) {
      return false;
    }
  }
  return true;
}

static bool ext_trust_anchors_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
                                              CBB *out_compressible,
                                              ssl_client_hello_type_t type) {
  if (!hs->config->requested_trust_anchors.has_value()) {
    return true;
  }
  // TODO(crbug.com/398275713): What should this send in ClientHelloOuter?
  CBB contents, list;
  if (!CBB_add_u16(out_compressible, TLSEXT_TYPE_trust_anchors) ||  //
      !CBB_add_u16_length_prefixed(out_compressible, &contents) ||  //
      !CBB_add_u16_length_prefixed(&contents, &list) ||             //
      !CBB_add_bytes(&list, hs->config->requested_trust_anchors->data(),
                     hs->config->requested_trust_anchors->size()) ||
      !CBB_flush(out_compressible)) {
    return false;
  }
  return true;
}

static bool ext_trust_anchors_parse_clienthello(SSL_HANDSHAKE *hs,
                                                uint8_t *out_alert,
                                                CBS *contents) {
  if (contents == nullptr || ssl_protocol_version(hs->ssl) < TLS1_3_VERSION) {
    return true;
  }

  CBS child;
  if (!CBS_get_u16_length_prefixed(contents, &child) ||
      !ssl_is_valid_trust_anchor_list(child) ||  //
      CBS_len(contents) != 0) {
    *out_alert = SSL_AD_DECODE_ERROR;
    OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
    return false;
  }

  hs->peer_requested_trust_anchors.emplace();
  if (!hs->peer_requested_trust_anchors->CopyFrom(child)) {
    *out_alert = SSL_AD_INTERNAL_ERROR;
    return false;
  }
  return true;
}

static bool ext_trust_anchors_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
  SSL *const ssl = hs->ssl;
  if (ssl_protocol_version(ssl) < TLS1_3_VERSION) {
    return true;
  }

  const size_t old_len = CBB_len(out);
  CBB contents, list, child;
  if (!CBB_add_u16(out, TLSEXT_TYPE_trust_anchors) ||
      !CBB_add_u16_length_prefixed(out, &contents) ||
      !CBB_add_u16_length_prefixed(&contents, &list)) {
    return false;
  }
  for (const auto &cred : hs->config->cert->credentials) {
    if (!cred->trust_anchor_id.empty()) {
      uint16_t unused_sigalg;
      if (!ssl_check_tls13_credential_ignoring_issuer(
              hs, kAllCertTypes, cred.get(), &unused_sigalg)) {
        ERR_clear_error();
        continue;
      }
      if (!CBB_add_u8_length_prefixed(&list, &child) ||
          !CBB_add_bytes(&child, cred->trust_anchor_id.data(),
                         cred->trust_anchor_id.size()) ||
          !CBB_flush(&list)) {
        return false;
      }
    }
  }

  bool empty = CBB_len(&list) == 0;
  if (!CBB_flush(out)) {
    return false;
  }

  // Don't send the extension if it would have been empty.
  if (empty) {
    CBB_discard(out, CBB_len(out) - old_len);
  }
  return true;
}

static bool ext_trust_anchors_parse_serverhello(SSL_HANDSHAKE *hs,
                                                uint8_t *out_alert,
                                                CBS *contents) {
  if (contents == nullptr) {
    return true;
  }

  if (ssl_protocol_version(hs->ssl) < TLS1_3_VERSION) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION);
    *out_alert = SSL_AD_UNSUPPORTED_EXTENSION;
    return false;
  }

  CBS child;
  if (!CBS_get_u16_length_prefixed(contents, &child) ||
      // The list of available trust anchors may not be empty.
      CBS_len(&child) == 0 ||                    //
      !ssl_is_valid_trust_anchor_list(child) ||  //
      CBS_len(contents) != 0) {
    *out_alert = SSL_AD_DECODE_ERROR;
    OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
    return false;
  }

  if (!hs->peer_available_trust_anchors.CopyFrom(child)) {
    *out_alert = SSL_AD_INTERNAL_ERROR;
    return false;
  }
  return true;
}

// QUIC Transport Parameters

static bool ext_quic_transport_params_add_clienthello_impl(
    const SSL_HANDSHAKE *hs, CBB *out, bool use_legacy_codepoint) {
  if (hs->config->quic_transport_params.empty() && !SSL_is_quic(hs->ssl)) {
    return true;
  }
  if (hs->config->quic_transport_params.empty() || !SSL_is_quic(hs->ssl)) {
    // QUIC Transport Parameters must be sent over QUIC, and they must not be
    // sent over non-QUIC transports. If transport params are set, then
    // SSL(_CTX)_set_quic_method must also be called.
    OPENSSL_PUT_ERROR(SSL, SSL_R_QUIC_TRANSPORT_PARAMETERS_MISCONFIGURED);
    return false;
  }
  assert(hs->min_version > TLS1_2_VERSION);
  if (use_legacy_codepoint != hs->config->quic_use_legacy_codepoint) {
    // Do nothing, we'll send the other codepoint.
    return true;
  }

  uint16_t extension_type = TLSEXT_TYPE_quic_transport_parameters;
  if (hs->config->quic_use_legacy_codepoint) {
    extension_type = TLSEXT_TYPE_quic_transport_parameters_legacy;
  }

  CBB contents;
  if (!CBB_add_u16(out, extension_type) ||
      !CBB_add_u16_length_prefixed(out, &contents) ||
      !CBB_add_bytes(&contents, hs->config->quic_transport_params.data(),
                     hs->config->quic_transport_params.size()) ||
      !CBB_flush(out)) {
    return false;
  }
  return true;
}

static bool ext_quic_transport_params_add_clienthello(
    const SSL_HANDSHAKE *hs, CBB *out, CBB *out_compressible,
    ssl_client_hello_type_t type) {
  return ext_quic_transport_params_add_clienthello_impl(
      hs, out_compressible, /*use_legacy_codepoint=*/false);
}

static bool ext_quic_transport_params_add_clienthello_legacy(
    const SSL_HANDSHAKE *hs, CBB *out, CBB *out_compressible,
    ssl_client_hello_type_t type) {
  return ext_quic_transport_params_add_clienthello_impl(
      hs, out_compressible, /*use_legacy_codepoint=*/true);
}

static bool ext_quic_transport_params_parse_serverhello_impl(
    SSL_HANDSHAKE *hs, uint8_t *out_alert, CBS *contents,
    bool used_legacy_codepoint) {
  SSL *const ssl = hs->ssl;
  if (contents == nullptr) {
    if (used_legacy_codepoint != hs->config->quic_use_legacy_codepoint) {
      // Silently ignore because we expect the other QUIC codepoint.
      return true;
    }
    if (!SSL_is_quic(ssl)) {
      return true;
    }
    *out_alert = SSL_AD_MISSING_EXTENSION;
    return false;
  }
  // The extensions parser will check for unsolicited extensions before
  // calling the callback.
  assert(SSL_is_quic(ssl));
  assert(ssl_protocol_version(ssl) == TLS1_3_VERSION);
  assert(used_legacy_codepoint == hs->config->quic_use_legacy_codepoint);
  return ssl->s3->peer_quic_transport_params.CopyFrom(*contents);
}

static bool ext_quic_transport_params_parse_serverhello(SSL_HANDSHAKE *hs,
                                                        uint8_t *out_alert,
                                                        CBS *contents) {
  return ext_quic_transport_params_parse_serverhello_impl(
      hs, out_alert, contents, /*used_legacy_codepoint=*/false);
}

static bool ext_quic_transport_params_parse_serverhello_legacy(
    SSL_HANDSHAKE *hs, uint8_t *out_alert, CBS *contents) {
  return ext_quic_transport_params_parse_serverhello_impl(
      hs, out_alert, contents, /*used_legacy_codepoint=*/true);
}

static bool ext_quic_transport_params_parse_clienthello_impl(
    SSL_HANDSHAKE *hs, uint8_t *out_alert, CBS *contents,
    bool used_legacy_codepoint) {
  SSL *const ssl = hs->ssl;
  if (!contents) {
    if (!SSL_is_quic(ssl)) {
      if (hs->config->quic_transport_params.empty()) {
        return true;
      }
      // QUIC transport parameters must not be set if |ssl| is not configured
      // for QUIC.
      OPENSSL_PUT_ERROR(SSL, SSL_R_QUIC_TRANSPORT_PARAMETERS_MISCONFIGURED);
      *out_alert = SSL_AD_INTERNAL_ERROR;
      return false;
    }
    if (used_legacy_codepoint != hs->config->quic_use_legacy_codepoint) {
      // Silently ignore because we expect the other QUIC codepoint.
      return true;
    }
    *out_alert = SSL_AD_MISSING_EXTENSION;
    return false;
  }
  if (!SSL_is_quic(ssl)) {
    if (used_legacy_codepoint) {
      // Ignore the legacy private-use codepoint because that could be sent
      // to mean something else than QUIC transport parameters.
      return true;
    }
    // Fail if we received the codepoint registered with IANA for QUIC
    // because that is not allowed outside of QUIC.
    *out_alert = SSL_AD_UNSUPPORTED_EXTENSION;
    return false;
  }
  assert(ssl_protocol_version(ssl) == TLS1_3_VERSION);
  if (used_legacy_codepoint != hs->config->quic_use_legacy_codepoint) {
    // Silently ignore because we expect the other QUIC codepoint.
    return true;
  }
  return ssl->s3->peer_quic_transport_params.CopyFrom(*contents);
}

static bool ext_quic_transport_params_parse_clienthello(SSL_HANDSHAKE *hs,
                                                        uint8_t *out_alert,
                                                        CBS *contents) {
  return ext_quic_transport_params_parse_clienthello_impl(
      hs, out_alert, contents, /*used_legacy_codepoint=*/false);
}

static bool ext_quic_transport_params_parse_clienthello_legacy(
    SSL_HANDSHAKE *hs, uint8_t *out_alert, CBS *contents) {
  return ext_quic_transport_params_parse_clienthello_impl(
      hs, out_alert, contents, /*used_legacy_codepoint=*/true);
}

static bool ext_quic_transport_params_add_serverhello_impl(
    SSL_HANDSHAKE *hs, CBB *out, bool use_legacy_codepoint) {
  if (!SSL_is_quic(hs->ssl) && use_legacy_codepoint) {
    // Ignore the legacy private-use codepoint because that could be sent
    // to mean something else than QUIC transport parameters.
    return true;
  }
  assert(SSL_is_quic(hs->ssl));
  if (hs->config->quic_transport_params.empty()) {
    // Transport parameters must be set when using QUIC.
    OPENSSL_PUT_ERROR(SSL, SSL_R_QUIC_TRANSPORT_PARAMETERS_MISCONFIGURED);
    return false;
  }
  if (use_legacy_codepoint != hs->config->quic_use_legacy_codepoint) {
    // Do nothing, we'll send the other codepoint.
    return true;
  }

  uint16_t extension_type = TLSEXT_TYPE_quic_transport_parameters;
  if (hs->config->quic_use_legacy_codepoint) {
    extension_type = TLSEXT_TYPE_quic_transport_parameters_legacy;
  }

  CBB contents;
  if (!CBB_add_u16(out, extension_type) ||
      !CBB_add_u16_length_prefixed(out, &contents) ||
      !CBB_add_bytes(&contents, hs->config->quic_transport_params.data(),
                     hs->config->quic_transport_params.size()) ||
      !CBB_flush(out)) {
    return false;
  }

  return true;
}

static bool ext_quic_transport_params_add_serverhello(SSL_HANDSHAKE *hs,
                                                      CBB *out) {
  return ext_quic_transport_params_add_serverhello_impl(
      hs, out, /*use_legacy_codepoint=*/false);
}

static bool ext_quic_transport_params_add_serverhello_legacy(SSL_HANDSHAKE *hs,
                                                             CBB *out) {
  return ext_quic_transport_params_add_serverhello_impl(
      hs, out, /*use_legacy_codepoint=*/true);
}

// Delegated credentials.
//
// https://www.rfc-editor.org/rfc/rfc9345.html

static bool ext_delegated_credential_add_clienthello(
    const SSL_HANDSHAKE *hs, CBB *out, CBB *out_compressible,
    ssl_client_hello_type_t type) {
  return true;
}

static bool ext_delegated_credential_parse_clienthello(SSL_HANDSHAKE *hs,
                                                       uint8_t *out_alert,
                                                       CBS *contents) {
  if (contents == nullptr || ssl_protocol_version(hs->ssl) < TLS1_3_VERSION) {
    // Don't use delegated credentials unless we're negotiating TLS 1.3 or
    // higher.
    return true;
  }

  // The contents of the extension are the signature algorithms the client will
  // accept for a delegated credential.
  CBS sigalg_list;
  if (!CBS_get_u16_length_prefixed(contents, &sigalg_list) ||  //
      CBS_len(&sigalg_list) == 0 ||                            //
      CBS_len(contents) != 0 ||                                //
      !parse_u16_array(&sigalg_list, &hs->peer_delegated_credential_sigalgs)) {
    return false;
  }

  return true;
}

// Certificate compression

static bool cert_compression_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
                                             CBB *out_compressible,
                                             ssl_client_hello_type_t type) {
  bool first = true;
  CBB contents, algs;

  for (const auto &alg : hs->ssl->ctx->cert_compression_algs) {
    if (alg.decompress == nullptr) {
      continue;
    }

    if (first &&
        (!CBB_add_u16(out_compressible, TLSEXT_TYPE_cert_compression) ||
         !CBB_add_u16_length_prefixed(out_compressible, &contents) ||
         !CBB_add_u8_length_prefixed(&contents, &algs))) {
      return false;
    }
    first = false;
    if (!CBB_add_u16(&algs, alg.alg_id)) {
      return false;
    }
  }

  return first || CBB_flush(out_compressible);
}

static bool cert_compression_parse_serverhello(SSL_HANDSHAKE *hs,
                                               uint8_t *out_alert,
                                               CBS *contents) {
  if (contents == nullptr) {
    return true;
  }

  // The server may not echo this extension. Any server to client negotiation is
  // advertised in the CertificateRequest message.
  return false;
}

static bool cert_compression_parse_clienthello(SSL_HANDSHAKE *hs,
                                               uint8_t *out_alert,
                                               CBS *contents) {
  if (contents == nullptr) {
    return true;
  }

  const SSL_CTX *ctx = hs->ssl->ctx.get();
  const size_t num_algs = ctx->cert_compression_algs.size();

  CBS alg_ids;
  if (!CBS_get_u8_length_prefixed(contents, &alg_ids) ||  //
      CBS_len(contents) != 0 ||                           //
      CBS_len(&alg_ids) == 0 ||                           //
      CBS_len(&alg_ids) % 2 == 1) {
    return false;
  }

  const size_t num_given_alg_ids = CBS_len(&alg_ids) / 2;
  Array<uint16_t> given_alg_ids;
  if (!given_alg_ids.InitForOverwrite(num_given_alg_ids)) {
    return false;
  }

  size_t best_index = num_algs;
  size_t given_alg_idx = 0;

  while (CBS_len(&alg_ids) > 0) {
    uint16_t alg_id;
    if (!CBS_get_u16(&alg_ids, &alg_id)) {
      return false;
    }

    given_alg_ids[given_alg_idx++] = alg_id;

    for (size_t i = 0; i < num_algs; i++) {
      const auto &alg = ctx->cert_compression_algs[i];
      if (alg.alg_id == alg_id && alg.compress != nullptr) {
        if (i < best_index) {
          best_index = i;
        }
        break;
      }
    }
  }

  std::sort(given_alg_ids.begin(), given_alg_ids.end());
  for (size_t i = 1; i < num_given_alg_ids; i++) {
    if (given_alg_ids[i - 1] == given_alg_ids[i]) {
      return false;
    }
  }

  if (best_index < num_algs &&
      ssl_protocol_version(hs->ssl) >= TLS1_3_VERSION) {
    hs->cert_compression_negotiated = true;
    hs->cert_compression_alg_id = ctx->cert_compression_algs[best_index].alg_id;
  }

  return true;
}

static bool cert_compression_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
  return true;
}

// PAKEs
//
// See
// https://chris-wood.github.io/draft-bmw-tls-pake13/draft-bmw-tls-pake13.html

bool ssl_setup_pake_shares(SSL_HANDSHAKE *hs) {
  hs->pake_share_bytes.Reset();
  if (hs->max_version < TLS1_3_VERSION) {
    return true;
  }

  const auto &creds = hs->config->cert->credentials;
  if (std::none_of(creds.begin(), creds.end(), [](const auto &cred) {
        return cred->type == SSLCredentialType::kSPAKE2PlusV1Client;
      })) {
    // If there were no configured PAKE credentials, proceed without filling
    // in the PAKE extension.
    return true;
  }

  // We currently do not support multiple PAKE credentials, or a mix of PAKE and
  // non-PAKE credentials.
  if (creds.size() != 1u) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_CREDENTIAL_LIST);
    return false;
  }
  SSLCredential *cred = creds[0].get();
  assert(cred->type == SSLCredentialType::kSPAKE2PlusV1Client);

  hs->pake_prover = MakeUnique<spake2plus::Prover>();
  uint8_t prover_share[spake2plus::kShareSize];
  if (hs->pake_prover == nullptr ||
      !hs->pake_prover->Init(cred->pake_context, cred->client_identity,
                             cred->server_identity, cred->password_verifier_w0,
                             cred->password_verifier_w1) ||
      !hs->pake_prover->GenerateShare(prover_share)) {
    return false;
  }

  hs->credential = UpRef(cred);

  bssl::ScopedCBB cbb;
  CBB shares, client_identity, server_identity, pake_message;
  if (!CBB_init(cbb.get(), 64) ||
      !CBB_add_u16_length_prefixed(cbb.get(), &client_identity) ||
      !CBB_add_bytes(&client_identity, cred->client_identity.data(),
                     cred->client_identity.size()) ||
      !CBB_add_u16_length_prefixed(cbb.get(), &server_identity) ||
      !CBB_add_bytes(&server_identity, cred->server_identity.data(),
                     cred->server_identity.size()) ||
      !CBB_add_u16_length_prefixed(cbb.get(), &shares) ||
      !CBB_add_u16(&shares, SSL_PAKE_SPAKE2PLUSV1) ||
      !CBB_add_u16_length_prefixed(&shares, &pake_message) ||
      !CBB_add_bytes(&pake_message, prover_share, sizeof(prover_share))) {
    return false;
  }

  return CBBFinishArray(cbb.get(), &hs->pake_share_bytes);
}

static bool ext_pake_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
                                     CBB *out_compressible,
                                     ssl_client_hello_type_t type) {
  if (hs->pake_share_bytes.empty()) {
    return true;
  }

  CBB pake_share_bytes;
  if (!CBB_add_u16(out_compressible, TLSEXT_TYPE_pake) ||
      !CBB_add_u16_length_prefixed(out_compressible, &pake_share_bytes) ||
      !CBB_add_bytes(&pake_share_bytes, hs->pake_share_bytes.data(),
                     hs->pake_share_bytes.size()) ||
      !CBB_flush(out_compressible)) {
    return false;
  }

  return true;
}

bool ssl_ext_pake_parse_serverhello(SSL_HANDSHAKE *hs,
                                    Array<uint8_t> *out_secret,
                                    uint8_t *out_alert, CBS *contents) {
  *out_alert = SSL_AD_DECODE_ERROR;

  if (!hs->pake_prover) {
    // If we did not offer a PAKE, the extension should have been rejected as
    // unsolicited.
    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
    *out_alert = SSL_AD_INTERNAL_ERROR;
    return false;
  }

  CBS pake_msg;
  uint16_t named_pake;
  if (!CBS_get_u16(contents, &named_pake) ||
      !CBS_get_u16_length_prefixed(contents, &pake_msg) ||
      CBS_len(contents) != 0 ||  //
      named_pake != SSL_PAKE_SPAKE2PLUSV1) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
    return false;
  }

  // Check that the server's PAKE share consists of the right number of
  // bytes for a PAKE share and a key confirmation message.
  if (CBS_len(&pake_msg) != spake2plus::kShareSize + spake2plus::kConfirmSize) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
    *out_alert = SSL_AD_ILLEGAL_PARAMETER;
    return false;
  }
  Span<const uint8_t> pake_msg_span = pake_msg;

  // Releasing the result of |ComputeConfirmation| lets the client confirm one
  // PAKE guess. If all failures are used up, no more guesses are allowed.
  if (!hs->credential->HasPAKEAttempts()) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_PAKE_EXHAUSTED);
    *out_alert = SSL_AD_INTERNAL_ERROR;
    return false;
  }

  uint8_t prover_confirm[spake2plus::kConfirmSize];
  uint8_t prover_secret[spake2plus::kSecretSize];
  if (!hs->pake_prover->ComputeConfirmation(
          prover_confirm, prover_secret,
          pake_msg_span.first<spake2plus::kShareSize>(),
          pake_msg_span.subspan(spake2plus::kShareSize))) {
    // Record a failure before releasing the answer to the client.
    hs->credential->ClaimPAKEAttempt();
    OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
    *out_alert = SSL_AD_ILLEGAL_PARAMETER;
    return false;
  }

  Array<uint8_t> secret;
  if (!secret.CopyFrom(prover_secret)) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
    *out_alert = SSL_AD_INTERNAL_ERROR;
    return false;
  }

  *out_secret = std::move(secret);
  return true;
}

static bool ext_pake_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
                                       CBS *contents) {
  if (contents == nullptr) {
    return true;
  }

  // struct {
  //     opaque    client_identity<0..2^16-1>;
  //     opaque    server_identity<0..2^16-1>;
  //     PAKEShare client_shares<0..2^16-1>;
  // } PAKEClientHello;
  //
  // struct {
  //     NamedPAKE   named_pake;
  //     opaque      pake_message<1..2^16-1>;
  // } PAKEShare;

  *out_alert = SSL_AD_DECODE_ERROR;
  CBS client_identity, server_identity, shares;
  if (!CBS_get_u16_length_prefixed(contents, &client_identity) ||
      !CBS_get_u16_length_prefixed(contents, &server_identity) ||
      !CBS_get_u16_length_prefixed(contents, &shares) ||
      CBS_len(contents) != 0) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
    return false;
  }

  uint16_t last_named_pake = 0;
  for (size_t i = 0; CBS_len(&shares) > 0; i++) {
    uint16_t pake_id;
    CBS message;
    if (!CBS_get_u16(&shares, &pake_id) ||
        !CBS_get_u16_length_prefixed(&shares, &message)) {
      OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
      return false;
    }

    // PAKEs must be sent in strictly monotonic order.
    if (i > 0 && last_named_pake >= pake_id) {
      OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
      return false;
    }
    last_named_pake = pake_id;

    // We only support one PAKE.
    if (pake_id != SSL_PAKE_SPAKE2PLUSV1) {
      continue;
    }

    // Save the PAKE share for the handshake logic to pick up later.
    // TODO(crbug.com/391393404): It would be nice if the callback did not have
    // to copy this.
    hs->pake_share = MakeUnique<SSLPAKEShare>();
    if (hs->pake_share == nullptr ||
        !hs->pake_share->client_identity.CopyFrom(client_identity) ||
        !hs->pake_share->server_identity.CopyFrom(server_identity) ||
        !hs->pake_share->pake_message.CopyFrom(message)) {
      OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
      return false;
    }
    hs->pake_share->named_pake = pake_id;
  }

  return true;
}


// Application-level Protocol Settings
//
// https://tools.ietf.org/html/draft-vvv-tls-alps-01

bool ssl_get_local_application_settings(const SSL_HANDSHAKE *hs,
                                        Span<const uint8_t> *out_settings,
                                        Span<const uint8_t> protocol) {
  for (const ALPSConfig &config : hs->config->alps_configs) {
    if (protocol == config.protocol) {
      *out_settings = config.settings;
      return true;
    }
  }
  return false;
}

static bool ext_alps_add_clienthello_impl(const SSL_HANDSHAKE *hs, CBB *out,
                                          CBB *out_compressible,
                                          ssl_client_hello_type_t type,
                                          bool use_new_codepoint) {
  const SSL *const ssl = hs->ssl;
  if (  // ALPS requires TLS 1.3.
      hs->max_version < TLS1_3_VERSION ||
      // Do not offer ALPS without ALPN.
      hs->config->alpn_client_proto_list.empty() ||
      // Do not offer ALPS if not configured.
      hs->config->alps_configs.empty() ||
      // Do not offer ALPS on renegotiation handshakes.
      ssl->s3->initial_handshake_complete) {
    return true;
  }

  if (use_new_codepoint != hs->config->alps_use_new_codepoint) {
    // Do nothing, we'll send the other codepoint.
    return true;
  }

  uint16_t extension_type = TLSEXT_TYPE_application_settings_old;
  if (hs->config->alps_use_new_codepoint) {
    extension_type = TLSEXT_TYPE_application_settings;
  }

  CBB contents, proto_list, proto;
  if (!CBB_add_u16(out_compressible, extension_type) ||
      !CBB_add_u16_length_prefixed(out_compressible, &contents) ||
      !CBB_add_u16_length_prefixed(&contents, &proto_list)) {
    return false;
  }

  for (const ALPSConfig &config : hs->config->alps_configs) {
    if (!CBB_add_u8_length_prefixed(&proto_list, &proto) ||
        !CBB_add_bytes(&proto, config.protocol.data(),
                       config.protocol.size())) {
      return false;
    }
  }

  return CBB_flush(out_compressible);
}

static bool ext_alps_add_clienthello(const SSL_HANDSHAKE *hs, CBB *out,
                                     CBB *out_compressible,
                                     ssl_client_hello_type_t type) {
  return ext_alps_add_clienthello_impl(hs, out, out_compressible, type,
                                       /*use_new_codepoint=*/true);
}

static bool ext_alps_add_clienthello_old(const SSL_HANDSHAKE *hs, CBB *out,
                                         CBB *out_compressible,
                                         ssl_client_hello_type_t type) {
  return ext_alps_add_clienthello_impl(hs, out, out_compressible, type,
                                       /*use_new_codepoint=*/false);
}

static bool ext_alps_parse_serverhello_impl(SSL_HANDSHAKE *hs,
                                            uint8_t *out_alert, CBS *contents,
                                            bool use_new_codepoint) {
  SSL *const ssl = hs->ssl;
  if (contents == nullptr) {
    return true;
  }

  assert(!ssl->s3->initial_handshake_complete);
  assert(!hs->config->alpn_client_proto_list.empty());
  assert(!hs->config->alps_configs.empty());
  assert(use_new_codepoint == hs->config->alps_use_new_codepoint);

  // ALPS requires TLS 1.3.
  if (ssl_protocol_version(ssl) < TLS1_3_VERSION) {
    *out_alert = SSL_AD_UNSUPPORTED_EXTENSION;
    OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION);
    return false;
  }

  // Note extension callbacks may run in any order, so we defer checking
  // consistency with ALPN to |ssl_check_serverhello_tlsext|.
  if (!hs->new_session->peer_application_settings.CopyFrom(*contents)) {
    *out_alert = SSL_AD_INTERNAL_ERROR;
    return false;
  }

  hs->new_session->has_application_settings = true;
  return true;
}

static bool ext_alps_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
                                       CBS *contents) {
  return ext_alps_parse_serverhello_impl(hs, out_alert, contents,
                                         /*use_new_codepoint=*/true);
}

static bool ext_alps_parse_serverhello_old(SSL_HANDSHAKE *hs,
                                           uint8_t *out_alert, CBS *contents) {
  return ext_alps_parse_serverhello_impl(hs, out_alert, contents,
                                         /*use_new_codepoint=*/false);
}

static bool ext_alps_add_serverhello_impl(SSL_HANDSHAKE *hs, CBB *out,
                                          bool use_new_codepoint) {
  SSL *const ssl = hs->ssl;
  // If early data is accepted, we omit the ALPS extension. It is implicitly
  // carried over from the previous connection.
  if (hs->new_session == nullptr ||
      !hs->new_session->has_application_settings ||
      ssl->s3->early_data_accepted) {
    return true;
  }

  if (use_new_codepoint != hs->config->alps_use_new_codepoint) {
    // Do nothing, we'll send the other codepoint.
    return true;
  }

  uint16_t extension_type = TLSEXT_TYPE_application_settings_old;
  if (hs->config->alps_use_new_codepoint) {
    extension_type = TLSEXT_TYPE_application_settings;
  }

  CBB contents;
  if (!CBB_add_u16(out, extension_type) ||
      !CBB_add_u16_length_prefixed(out, &contents) ||
      !CBB_add_bytes(&contents,
                     hs->new_session->local_application_settings.data(),
                     hs->new_session->local_application_settings.size()) ||
      !CBB_flush(out)) {
    return false;
  }

  return true;
}

static bool ext_alps_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
  return ext_alps_add_serverhello_impl(hs, out, /*use_new_codepoint=*/true);
}

static bool ext_alps_add_serverhello_old(SSL_HANDSHAKE *hs, CBB *out) {
  return ext_alps_add_serverhello_impl(hs, out, /*use_new_codepoint=*/false);
}

bool ssl_negotiate_alps(SSL_HANDSHAKE *hs, uint8_t *out_alert,
                        const SSL_CLIENT_HELLO *client_hello) {
  SSL *const ssl = hs->ssl;
  if (ssl->s3->alpn_selected.empty()) {
    return true;
  }

  // If we negotiate ALPN over TLS 1.3, try to negotiate ALPS.
  CBS alps_contents;
  Span<const uint8_t> settings;
  uint16_t extension_type = TLSEXT_TYPE_application_settings_old;
  if (hs->config->alps_use_new_codepoint) {
    extension_type = TLSEXT_TYPE_application_settings;
  }
  if (ssl_protocol_version(ssl) >= TLS1_3_VERSION &&
      ssl_get_local_application_settings(hs, &settings,
                                         ssl->s3->alpn_selected) &&
      ssl_client_hello_get_extension(client_hello, &alps_contents,
                                     extension_type)) {
    // Check if the client supports ALPS with the selected ALPN.
    bool found = false;
    CBS alps_list;
    if (!CBS_get_u16_length_prefixed(&alps_contents, &alps_list) ||  //
        CBS_len(&alps_contents) != 0 ||                              //
        CBS_len(&alps_list) == 0) {
      OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
      *out_alert = SSL_AD_DECODE_ERROR;
      return false;
    }
    while (CBS_len(&alps_list) > 0) {
      CBS protocol_name;
      if (!CBS_get_u8_length_prefixed(&alps_list, &protocol_name) ||
          // Empty protocol names are forbidden.
          CBS_len(&protocol_name) == 0) {
        OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
        *out_alert = SSL_AD_DECODE_ERROR;
        return false;
      }
      if (protocol_name == Span(ssl->s3->alpn_selected)) {
        found = true;
      }
    }

    // Negotiate ALPS if both client also supports ALPS for this protocol.
    if (found) {
      hs->new_session->has_application_settings = true;
      if (!hs->new_session->local_application_settings.CopyFrom(settings)) {
        *out_alert = SSL_AD_INTERNAL_ERROR;
        return false;
      }
    }
  }

  return true;
}

// Client certificate type & Server certificate type
//
// https://www.rfc-editor.org/rfc/rfc7250.html#section-3

// parse_clienthello_cert_types_list returns a span containing the cert type
// values from a client_certificate_type or server_certificate_type ClientHello
// extension. Returns std::nullopt on error, or returns a nonempty span
// containing the values. This rejects the invalid empty list and list
// containing only the default X.509. This does not filter out unrecognized
// values. We don't check for duplicates here, even though a list containing
// duplicates should be considered invalid, to avoid quadratic behavior.
static std::optional<Span<const uint8_t>> parse_clienthello_cert_types_list(
    uint8_t *out_alert, CBS *contents) {
  CBS cert_types;
  if (!CBS_get_u8_length_prefixed(contents, &cert_types) ||
      CBS_len(contents) != 0) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
    *out_alert = SSL_AD_ILLEGAL_PARAMETER;
    return std::nullopt;
  }
  Span<const uint8_t> cert_types_list(cert_types);
  // The client must omit the extension if the only type would be the default,
  // X.509.
  if (cert_types_list.empty() ||
      (cert_types_list.size() == 1 && cert_types_list[0] == kDefaultCertType)) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
    *out_alert = SSL_AD_ILLEGAL_PARAMETER;
    return std::nullopt;
  }
  return cert_types_list;
}

void ssl_setup_client_certificate_type(SSL_HANDSHAKE *hs) {
  assert(!hs->ssl->server);
  hs->offered_client_cert_types.clear();
  InplaceVector<uint8_t, kNumCertTypes> available_cert_types;
  if (!hs->ssl->config->available_client_cert_types.empty()) {
    available_cert_types.CopyFrom(hs->ssl->config->available_client_cert_types);
  } else {
    // Compute the available cert types based on configured SSL_CREDENTIALs.
    const auto append_if_not_present = [&](uint8_t cert_type) {
      if (std::find(available_cert_types.begin(), available_cert_types.end(),
                    cert_type) == available_cert_types.end()) {
        available_cert_types.PushBack(cert_type);
      }
    };
    for (const auto &credential : hs->config->cert->credentials) {
      if (std::optional<uint8_t> cert_type =
              ssl_credential_type_to_cert_type(credential->type);
          cert_type.has_value()) {
        append_if_not_present(*cert_type);
      }
    }
  }
  if (available_cert_types.empty() ||
      // Omit extension if the only type would be the default, X.509.
      (available_cert_types.size() == 1 &&
       available_cert_types[0] == kDefaultCertType)) {
    return;
  }
  hs->offered_client_cert_types = std::move(available_cert_types);
}

bool ssl_negotiate_client_certificate_type(
    SSL_HANDSHAKE *hs, uint8_t *out_alert,
    const SSL_CLIENT_HELLO *client_hello) {
  assert(hs->ssl->server);
  assert(!hs->config->accepted_peer_cert_types.empty());
  CBS contents;
  Span<const uint8_t> peer_available_client_cert_types;
  if (ssl_client_hello_get_extension(client_hello, &contents,
                                     TLSEXT_TYPE_client_cert_type)) {
    std::optional<Span<const uint8_t>> client_hello_client_cert_types =
        parse_clienthello_cert_types_list(out_alert, &contents);
    if (!client_hello_client_cert_types.has_value()) {
      return false;
    }
    peer_available_client_cert_types = *client_hello_client_cert_types;
  }
  if (!hs->cert_request) {
    return true;
  }
  // If the client didn't send the extension, assume the client supports X.509
  // only by default.
  if (peer_available_client_cert_types.empty()) {
    peer_available_client_cert_types =
        Span<const uint8_t>(&kDefaultCertType, 1u);
  }
  for (const uint8_t cert_type : hs->config->accepted_peer_cert_types) {
    if (std::find(peer_available_client_cert_types.begin(),
                  peer_available_client_cert_types.end(),
                  cert_type) == peer_available_client_cert_types.end()) {
      continue;
    }
    hs->peer_cert_type = cert_type;
    return true;
  }
  OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_CERTIFICATE);
  *out_alert = SSL_AD_UNSUPPORTED_CERTIFICATE;
  return false;
}

static bool ext_client_cert_type_add_clienthello(const SSL_HANDSHAKE *hs,
                                                 CBB *out,
                                                 CBB *out_compressible,
                                                 ssl_client_hello_type_t type) {
  if (hs->offered_client_cert_types.empty()) {
    return true;
  }
  CBB contents, client_cert_types;
  if (!CBB_add_u16(out, TLSEXT_TYPE_client_cert_type) ||
      !CBB_add_u16_length_prefixed(out, &contents) ||
      !CBB_add_u8_length_prefixed(&contents, &client_cert_types) ||
      !CBB_add_bytes(&client_cert_types, hs->offered_client_cert_types.data(),
                     hs->offered_client_cert_types.size()) ||
      !CBB_flush(out)) {
    return false;
  }
  return true;
}

static bool ext_client_cert_type_parse_serverhello(SSL_HANDSHAKE *hs,
                                                   uint8_t *out_alert,
                                                   CBS *contents) {
  if (contents == nullptr) {
    return true;
  }
  uint8_t cert_type;
  if (!CBS_get_u8(contents, &cert_type) || CBS_len(contents) != 0) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
    *out_alert = SSL_AD_DECODE_ERROR;
    return false;
  }
  // Reject if the server picked a cert type that we didn't offer in the
  // ClientHello.
  if (std::find(hs->offered_client_cert_types.begin(),
                hs->offered_client_cert_types.end(),
                cert_type) == hs->offered_client_cert_types.end()) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_CERTIFICATE);
    *out_alert = SSL_AD_UNSUPPORTED_CERTIFICATE;
    return false;
  }
  hs->client_cert_type = cert_type;
  return true;
}

static bool ext_client_cert_type_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
  // Only send client_certificate_type if we plan to send a CertificateRequest.
  if (!hs->cert_request) {
    return true;
  }
  CBB contents;
  if (!CBB_add_u16(out, TLSEXT_TYPE_client_cert_type) ||
      !CBB_add_u16_length_prefixed(out, &contents) ||
      !CBB_add_u8(&contents, hs->peer_cert_type) ||  //
      !CBB_flush(out)) {
    return false;
  }
  return true;
}

std::optional<Span<const uint8_t>> ssl_get_allowed_server_cert_types(
    const SSL_HANDSHAKE *hs, const SSL_CLIENT_HELLO *client_hello,
    uint8_t *out_alert) {
  assert(hs->ssl->server);
  std::optional<Span<const uint8_t>> clienthello_server_cert_types;
  CBS server_cert_types_ext;
  if (ssl_client_hello_get_extension(client_hello, &server_cert_types_ext,
                                     TLSEXT_TYPE_server_cert_type)) {
    clienthello_server_cert_types =
        parse_clienthello_cert_types_list(out_alert, &server_cert_types_ext);
    if (!clienthello_server_cert_types.has_value()) {
      OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_PARSING_EXTENSION);
      return std::nullopt;
    }
  }
  // Allow X.509 certificates by default.
  return clienthello_server_cert_types.value_or(Span(&kDefaultCertType, 1u));
}

static bool ext_server_cert_type_add_clienthello(const SSL_HANDSHAKE *hs,
                                                 CBB *out,
                                                 CBB *out_compressible,
                                                 ssl_client_hello_type_t type) {
  assert(!hs->config->accepted_peer_cert_types.empty());
  // Omit extension if the only type would be the default, X.509.
  if (hs->config->accepted_peer_cert_types.size() == 1 &&
      hs->config->accepted_peer_cert_types[0] == kDefaultCertType) {
    return true;
  }
  CBB contents, server_cert_types;
  if (!CBB_add_u16(out, TLSEXT_TYPE_server_cert_type) ||
      !CBB_add_u16_length_prefixed(out, &contents) ||
      !CBB_add_u8_length_prefixed(&contents, &server_cert_types) ||
      !CBB_add_bytes(&server_cert_types,
                     hs->config->accepted_peer_cert_types.data(),
                     hs->config->accepted_peer_cert_types.size()) ||
      !CBB_flush(out)) {
    return false;
  }
  return true;
}

static bool ext_server_cert_type_parse_serverhello(SSL_HANDSHAKE *hs,
                                                   uint8_t *out_alert,
                                                   CBS *contents) {
  assert(!hs->config->accepted_peer_cert_types.empty());
  // Absence of an extension from the server implies the default, X.509.
  uint8_t cert_type = kDefaultCertType;
  if (contents != nullptr &&
      (!CBS_get_u8(contents, &cert_type) || CBS_len(contents) != 0)) {
    return false;
  }
  // Check that the server's chosen type is among the types we accept.
  if (std::find(hs->config->accepted_peer_cert_types.begin(),
                hs->config->accepted_peer_cert_types.end(),
                cert_type) == hs->config->accepted_peer_cert_types.end()) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_CERTIFICATE);
    *out_alert = SSL_AD_UNSUPPORTED_CERTIFICATE;
    return false;
  }
  hs->peer_cert_type = cert_type;
  return true;
}

static bool ext_server_cert_type_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
  if (hs->credential == nullptr) {
    return true;
  }
  const auto cert_type = ssl_credential_type_to_cert_type(hs->credential->type);
  if (!cert_type.has_value()) {
    return true;
  }
  CBB contents;
  if (!CBB_add_u16(out, TLSEXT_TYPE_server_cert_type) ||
      !CBB_add_u16_length_prefixed(out, &contents) ||
      !CBB_add_u8(&contents, *cert_type) ||  //
      !CBB_flush(out)) {
    return false;
  }
  return true;
}

// kExtensions contains all the supported extensions.
static const struct tls_extension kExtensions[] = {
    {
        TLSEXT_TYPE_server_name,
        ext_sni_add_clienthello,
        ext_sni_parse_serverhello,
        ext_sni_parse_clienthello,
        ext_sni_add_serverhello,
    },
    {
        TLSEXT_TYPE_encrypted_client_hello,
        ext_ech_add_clienthello,
        ext_ech_parse_serverhello,
        ext_ech_parse_clienthello,
        ext_ech_add_serverhello,
    },
    {
        TLSEXT_TYPE_extended_master_secret,
        ext_ems_add_clienthello,
        ext_ems_parse_serverhello,
        ext_ems_parse_clienthello,
        ext_ems_add_serverhello,
    },
    {
        TLSEXT_TYPE_renegotiate,
        ext_ri_add_clienthello,
        ext_ri_parse_serverhello,
        ext_ri_parse_clienthello,
        ext_ri_add_serverhello,
    },
    {
        TLSEXT_TYPE_supported_groups,
        ext_supported_groups_add_clienthello,
        ext_supported_groups_parse_serverhello,
        ext_supported_groups_parse_clienthello,
        dont_add_serverhello,
    },
    {
        TLSEXT_TYPE_ec_point_formats,
        ext_ec_point_add_clienthello,
        ext_ec_point_parse_serverhello,
        ext_ec_point_parse_clienthello,
        ext_ec_point_add_serverhello,
    },
    {
        TLSEXT_TYPE_session_ticket,
        ext_ticket_add_clienthello,
        ext_ticket_parse_serverhello,
        // Ticket extension client parsing is handled in ssl_session.c
        ignore_parse_clienthello,
        ext_ticket_add_serverhello,
    },
    {
        TLSEXT_TYPE_application_layer_protocol_negotiation,
        ext_alpn_add_clienthello,
        ext_alpn_parse_serverhello,
        // ALPN is negotiated late in |ssl_negotiate_alpn|.
        ignore_parse_clienthello,
        ext_alpn_add_serverhello,
    },
    {
        TLSEXT_TYPE_status_request,
        ext_ocsp_add_clienthello,
        ext_ocsp_parse_serverhello,
        ext_ocsp_parse_clienthello,
        ext_ocsp_add_serverhello,
    },
    {
        TLSEXT_TYPE_signature_algorithms,
        ext_sigalgs_add_clienthello,
        forbid_parse_serverhello,
        ext_sigalgs_parse_clienthello,
        dont_add_serverhello,
    },
    {
        TLSEXT_TYPE_next_proto_neg,
        ext_npn_add_clienthello,
        ext_npn_parse_serverhello,
        ext_npn_parse_clienthello,
        ext_npn_add_serverhello,
    },
    {
        TLSEXT_TYPE_certificate_timestamp,
        ext_sct_add_clienthello,
        ext_sct_parse_serverhello,
        ext_sct_parse_clienthello,
        ext_sct_add_serverhello,
    },
    {
        TLSEXT_TYPE_channel_id,
        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_add_clienthello,
        ext_srtp_parse_serverhello,
        ext_srtp_parse_clienthello,
        ext_srtp_add_serverhello,
    },
    {
        TLSEXT_TYPE_key_share,
        ext_key_share_add_clienthello,
        forbid_parse_serverhello,
        ignore_parse_clienthello,
        dont_add_serverhello,
    },
    {
        TLSEXT_TYPE_psk_key_exchange_modes,
        ext_psk_key_exchange_modes_add_clienthello,
        forbid_parse_serverhello,
        ext_psk_key_exchange_modes_parse_clienthello,
        dont_add_serverhello,
    },
    {
        TLSEXT_TYPE_early_data,
        ext_early_data_add_clienthello,
        ext_early_data_parse_serverhello,
        ext_early_data_parse_clienthello,
        ext_early_data_add_serverhello,
    },
    {
        TLSEXT_TYPE_supported_versions,
        ext_supported_versions_add_clienthello,
        forbid_parse_serverhello,
        ignore_parse_clienthello,
        dont_add_serverhello,
    },
    {
        TLSEXT_TYPE_cookie,
        ext_cookie_add_clienthello,
        forbid_parse_serverhello,
        ignore_parse_clienthello,
        dont_add_serverhello,
    },
    {
        TLSEXT_TYPE_quic_transport_parameters,
        ext_quic_transport_params_add_clienthello,
        ext_quic_transport_params_parse_serverhello,
        ext_quic_transport_params_parse_clienthello,
        ext_quic_transport_params_add_serverhello,
    },
    {
        TLSEXT_TYPE_quic_transport_parameters_legacy,
        ext_quic_transport_params_add_clienthello_legacy,
        ext_quic_transport_params_parse_serverhello_legacy,
        ext_quic_transport_params_parse_clienthello_legacy,
        ext_quic_transport_params_add_serverhello_legacy,
    },
    {
        TLSEXT_TYPE_cert_compression,
        cert_compression_add_clienthello,
        cert_compression_parse_serverhello,
        cert_compression_parse_clienthello,
        cert_compression_add_serverhello,
    },
    {
        TLSEXT_TYPE_delegated_credential,
        ext_delegated_credential_add_clienthello,
        forbid_parse_serverhello,
        ext_delegated_credential_parse_clienthello,
        dont_add_serverhello,
    },
    {
        TLSEXT_TYPE_application_settings,
        ext_alps_add_clienthello,
        ext_alps_parse_serverhello,
        // ALPS is negotiated late in |ssl_negotiate_alpn|.
        ignore_parse_clienthello,
        ext_alps_add_serverhello,
    },
    {
        TLSEXT_TYPE_application_settings_old,
        ext_alps_add_clienthello_old,
        ext_alps_parse_serverhello_old,
        // ALPS is negotiated late in |ssl_negotiate_alpn|.
        ignore_parse_clienthello,
        ext_alps_add_serverhello_old,
    },
    {
        TLSEXT_TYPE_certificate_authorities,
        ext_certificate_authorities_add_clienthello,
        forbid_parse_serverhello,
        ext_certificate_authorities_parse_clienthello,
        dont_add_serverhello,
    },
    {
        TLSEXT_TYPE_pake,
        ext_pake_add_clienthello,
        // This extension is unencrypted and so adding and parsing it from the
        // ServerHello is handled elsewhere.
        forbid_parse_serverhello,
        ext_pake_parse_clienthello,
        dont_add_serverhello,
    },
    {
        TLSEXT_TYPE_trust_anchors,
        ext_trust_anchors_add_clienthello,
        ext_trust_anchors_parse_serverhello,
        ext_trust_anchors_parse_clienthello,
        ext_trust_anchors_add_serverhello,
    },
    {
        TLSEXT_TYPE_client_cert_type,
        ext_client_cert_type_add_clienthello,
        ext_client_cert_type_parse_serverhello,
        // client_certificate_type is negotiated late in
        // `ssl_negotiate_client_cert_type`.
        ignore_parse_clienthello,
        ext_client_cert_type_add_serverhello,
    },
    {
        TLSEXT_TYPE_server_cert_type,
        ext_server_cert_type_add_clienthello,
        ext_server_cert_type_parse_serverhello,
        // The server_certificate_type list from the client is parsed later,
        // during credential selection.
        ignore_parse_clienthello,
        ext_server_cert_type_add_serverhello,
    },
};

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

static_assert(kNumExtensions <=
                  sizeof(((SSL_HANDSHAKE *)nullptr)->extensions.sent) * 8,
              "too many extensions for sent bitset");
static_assert(kNumExtensions <=
                  sizeof(((SSL_HANDSHAKE *)nullptr)->extensions.received) * 8,
              "too many extensions for received bitset");

bool ssl_setup_extension_permutation(SSL_HANDSHAKE *hs) {
  if (!hs->config->permute_extensions) {
    return true;
  }

  static_assert(kNumExtensions <= UINT8_MAX,
                "extensions_permutation type is too small");
  uint32_t seeds[kNumExtensions - 1];
  Array<uint8_t> permutation;
  if (!RAND_bytes(reinterpret_cast<uint8_t *>(seeds), sizeof(seeds)) ||
      !permutation.InitForOverwrite(kNumExtensions)) {
    return false;
  }
  for (size_t i = 0; i < kNumExtensions; i++) {
    permutation[i] = i;
  }
  for (size_t i = kNumExtensions - 1; i > 0; i--) {
    // Set element |i| to a randomly-selected element 0 <= j <= i.
    std::swap(permutation[i], permutation[seeds[i - 1] % (i + 1)]);
  }
  hs->extension_permutation = std::move(permutation);
  return true;
}

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

static bool add_padding_extension(CBB *cbb, uint16_t ext, size_t len) {
  CBB child;
  if (!CBB_add_u16(cbb, ext) ||  //
      !CBB_add_u16_length_prefixed(cbb, &child) ||
      !CBB_add_zeros(&child, len)) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
    return false;
  }
  return CBB_flush(cbb);
}

static bool ssl_add_clienthello_tlsext_inner(SSL_HANDSHAKE *hs, CBB *out,
                                             CBB *out_encoded) {
  // When writing ClientHelloInner, we construct the real and encoded
  // ClientHellos concurrently, to handle compression. Uncompressed extensions
  // are written to |extensions| and copied to |extensions_encoded|. Compressed
  // extensions are buffered in |compressed| and written to the end. (ECH can
  // only compress contiguous extensions.)
  SSL *const ssl = hs->ssl;
  bssl::ScopedCBB compressed, outer_extensions;
  CBB extensions, extensions_encoded;
  if (!CBB_add_u16_length_prefixed(out, &extensions) ||
      !CBB_add_u16_length_prefixed(out_encoded, &extensions_encoded) ||
      !CBB_init(compressed.get(), 64) ||
      !CBB_init(outer_extensions.get(), 64)) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
    return false;
  }

  hs->inner_extensions_sent = 0;

  if (ssl->ctx->grease_enabled) {
    // Add a fake empty extension. See RFC 8701. This always matches
    // |ssl_add_clienthello_tlsext|, so compress it.
    uint16_t grease_ext = ssl_get_grease_value(hs, ssl_grease_extension1);
    if (!add_padding_extension(compressed.get(), grease_ext, 0) ||
        !CBB_add_u16(outer_extensions.get(), grease_ext)) {
      return false;
    }
  }

  for (size_t unpermuted = 0; unpermuted < kNumExtensions; unpermuted++) {
    size_t i = hs->extension_permutation.empty()
                   ? unpermuted
                   : hs->extension_permutation[unpermuted];
    const size_t len_before = CBB_len(&extensions);
    const size_t len_compressed_before = CBB_len(compressed.get());
    if (!kExtensions[i].add_clienthello(hs, &extensions, compressed.get(),
                                        ssl_client_hello_inner)) {
      OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_ADDING_EXTENSION);
      ERR_add_error_dataf("extension %u", (unsigned)kExtensions[i].value);
      return false;
    }

    const size_t bytes_written = CBB_len(&extensions) - len_before;
    const size_t bytes_written_compressed =
        CBB_len(compressed.get()) - len_compressed_before;
    // The callback may write to at most one output.
    assert(bytes_written == 0 || bytes_written_compressed == 0);
    if (bytes_written != 0 || bytes_written_compressed != 0) {
      hs->inner_extensions_sent |= (1u << i);
    }
    // If compressed, update the running ech_outer_extensions extension.
    if (bytes_written_compressed != 0 &&
        !CBB_add_u16(outer_extensions.get(), kExtensions[i].value)) {
      return false;
    }
  }

  if (ssl->ctx->grease_enabled) {
    // Add a fake non-empty extension. See RFC 8701. This always matches
    // |ssl_add_clienthello_tlsext|, so compress it.
    uint16_t grease_ext = ssl_get_grease_value(hs, ssl_grease_extension2);
    if (!add_padding_extension(compressed.get(), grease_ext, 1) ||
        !CBB_add_u16(outer_extensions.get(), grease_ext)) {
      return false;
    }
  }

  // Uncompressed extensions are encoded as-is.
  if (!CBB_add_bytes(&extensions_encoded, CBB_data(&extensions),
                     CBB_len(&extensions))) {
    return false;
  }

  // Flush all the compressed extensions.
  if (CBB_len(compressed.get()) != 0) {
    CBB extension, child;
    // Copy them as-is in the real ClientHelloInner.
    if (!CBB_add_bytes(&extensions, CBB_data(compressed.get()),
                       CBB_len(compressed.get())) ||
        // Replace with ech_outer_extensions in the encoded form.
        !CBB_add_u16(&extensions_encoded, TLSEXT_TYPE_ech_outer_extensions) ||
        !CBB_add_u16_length_prefixed(&extensions_encoded, &extension) ||
        !CBB_add_u8_length_prefixed(&extension, &child) ||
        !CBB_add_bytes(&child, CBB_data(outer_extensions.get()),
                       CBB_len(outer_extensions.get())) ||
        !CBB_flush(&extensions_encoded)) {
      return false;
    }
  }

  // The PSK extension must be last. It is never compressed.
  size_t psk_len;
  if (!ext_pre_shared_key_add_clienthello(hs, out, &extensions, &psk_len,
                                          ssl_client_hello_inner)) {
    return false;
  }

  // Copy the PSK extension to EncodedClientHelloInner.
  auto psk = CBBAsSpan(out).last(psk_len);
  if (!CBB_add_bytes(&extensions_encoded, psk.data(), psk.size()) ||
      !CBB_flush(out_encoded)) {
    return false;
  }

  return true;
}

bool ssl_add_clienthello_tlsext(SSL_HANDSHAKE *hs, CBB *out, CBB *out_encoded,
                                ssl_client_hello_type_t type) {
  // |out| must contain the start of a ClientHello, which means it must begin
  // with a TLS or DTLS version.
  assert(CBB_len(out) != 0 && (CBB_data(out)[0] == SSL3_VERSION_MAJOR ||
                               CBB_data(out)[0] == DTLS1_VERSION_MAJOR));

  if (type == ssl_client_hello_inner) {
    return ssl_add_clienthello_tlsext_inner(hs, out, out_encoded);
  }

  // Sample the length of the ClientHello thus far, including the message
  // header.
  size_t msg_len = SSL3_HM_HEADER_LENGTH + CBB_len(out);
  assert(out_encoded == nullptr);  // Only ClientHelloInner needs two outputs.
  SSL *const ssl = hs->ssl;
  CBB extensions;
  if (!CBB_add_u16_length_prefixed(out, &extensions)) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
    return false;
  }

  // Note we may send multiple ClientHellos for DTLS HelloVerifyRequest and TLS
  // 1.3 HelloRetryRequest. For the latter, the extensions may change, so it is
  // important to reset this value.
  hs->extensions.sent = 0;

  // Add a fake empty extension. See RFC 8701.
  if (ssl->ctx->grease_enabled &&
      !add_padding_extension(
          &extensions, ssl_get_grease_value(hs, ssl_grease_extension1), 0)) {
    return false;
  }

  bool last_was_empty = false;
  for (size_t unpermuted = 0; unpermuted < kNumExtensions; unpermuted++) {
    size_t i = hs->extension_permutation.empty()
                   ? unpermuted
                   : hs->extension_permutation[unpermuted];
    const size_t len_before = CBB_len(&extensions);
    if (!kExtensions[i].add_clienthello(hs, &extensions, &extensions, type)) {
      OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_ADDING_EXTENSION);
      ERR_add_error_dataf("extension %u", (unsigned)kExtensions[i].value);
      return false;
    }

    const size_t bytes_written = CBB_len(&extensions) - len_before;
    if (bytes_written != 0) {
      hs->extensions.sent |= (1u << i);
    }
    // If the difference in lengths is only four bytes then the extension had
    // an empty body.
    last_was_empty = (bytes_written == 4);
  }

  if (ssl->ctx->grease_enabled) {
    // Add a fake non-empty extension. See RFC 8701.
    if (!add_padding_extension(
            &extensions, ssl_get_grease_value(hs, ssl_grease_extension2), 1)) {
      return false;
    }
    last_was_empty = false;
  }

  // In cleartext ClientHellos, we add the padding extension to work around
  // bugs. We also apply this padding to ClientHelloOuter, to keep the wire
  // images aligned.
  size_t psk_len = ext_pre_shared_key_clienthello_length(hs, type);
  if (!SSL_is_dtls(ssl) && !SSL_is_quic(ssl) &&
      !ssl->s3->used_hello_retry_request) {
    msg_len += 2 /* length prefix */ + CBB_len(&extensions) + psk_len;
    // The length of the padding extension, excluding the four-byte extension
    // header.
    size_t padding_len = 0;

    // 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.
    if (last_was_empty && psk_len == 0) {
      padding_len = 1;
      // The addition of the padding extension may push us into the F5 bug.
      msg_len += 4 + padding_len;
    }

    // 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 (save for any PSK extension).
    if (msg_len > 0xff && msg_len < 0x200) {
      // If our calculations already included a padding extension, remove that
      // factor because we're about to change its length.
      if (padding_len != 0) {
        msg_len -= 4 + padding_len;
      }
      padding_len = 0x200 - msg_len;
      // Extensions take at least four bytes to encode. WebSphere Application
      // Server 7.0 is intolerant to the last extension being zero-length, so
      // always include at least one byte of data if including the extension.
      // See https://crbug.com/363583.
      if (padding_len >= 4 + 1) {
        padding_len -= 4;
      } else {
        padding_len = 1;
      }
    }

    if (padding_len != 0 &&
        !add_padding_extension(&extensions, TLSEXT_TYPE_padding, padding_len)) {
      return false;
    }
  }

  // The PSK extension must be last, including after the padding.
  size_t psk_len_actual;
  if (!ext_pre_shared_key_add_clienthello(hs, out, &extensions, &psk_len_actual,
                                          type)) {
    return false;
  }
  assert(psk_len_actual == psk_len);
  return true;
}

bool ssl_add_serverhello_tlsext(SSL_HANDSHAKE *hs, CBB *out) {
  SSL *const ssl = hs->ssl;
  CBB extensions;
  if (!CBB_add_u16_length_prefixed(out, &extensions)) {
    goto err;
  }

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

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

  // Discard empty extensions blocks before TLS 1.3.
  if (ssl_protocol_version(ssl) < TLS1_3_VERSION &&  //
      CBB_len(&extensions) == 0) {
    CBB_discard_child(out);
  }

  return CBB_flush(out);

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

static bool ssl_scan_clienthello_tlsext(SSL_HANDSHAKE *hs,
                                        const SSL_CLIENT_HELLO *client_hello,
                                        int *out_alert) {
  hs->extensions.received = 0;
  CBS extensions;
  CBS_init(&extensions, client_hello->extensions, client_hello->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)) {
      *out_alert = SSL_AD_DECODE_ERROR;
      return false;
    }

    unsigned ext_index;
    const struct tls_extension *const ext =
        tls_extension_find(&ext_index, type);
    if (ext == nullptr) {
      continue;
    }

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

  for (size_t i = 0; i < kNumExtensions; i++) {
    if (hs->extensions.received & (1u << i)) {
      continue;
    }

    CBS *contents = nullptr, fake_contents;
    static const uint8_t kFakeRenegotiateExtension[] = {0};
    if (kExtensions[i].value == TLSEXT_TYPE_renegotiate &&
        ssl_client_cipher_list_contains_cipher(
            client_hello, SSL_CIPHER_EMPTY_RENEGOTIATION_INFO_SCSV)) {
      // The renegotiation SCSV was received so pretend that we received a
      // renegotiation extension.
      CBS_init(&fake_contents, kFakeRenegotiateExtension,
               sizeof(kFakeRenegotiateExtension));
      contents = &fake_contents;
      hs->extensions.received |= (1u << i);
    }

    // Extension wasn't observed so call the callback with a NULL
    // parameter.
    uint8_t alert = SSL_AD_DECODE_ERROR;
    if (!kExtensions[i].parse_clienthello(hs, &alert, contents)) {
      OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_EXTENSION);
      ERR_add_error_dataf("extension %u", (unsigned)kExtensions[i].value);
      *out_alert = alert;
      return false;
    }
  }

  return true;
}

bool ssl_parse_clienthello_tlsext(SSL_HANDSHAKE *hs,
                                  const SSL_CLIENT_HELLO *client_hello) {
  SSL *const ssl = hs->ssl;
  int alert = SSL_AD_DECODE_ERROR;
  if (!ssl_scan_clienthello_tlsext(hs, client_hello, &alert)) {
    ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
    return false;
  }

  if (!ssl_check_clienthello_tlsext(hs)) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_TLSEXT);
    return false;
  }

  return true;
}

static bool ssl_scan_serverhello_tlsext(SSL_HANDSHAKE *hs, const CBS *cbs,
                                        int *out_alert) {
  CBS extensions = *cbs;
  if (!tls1_check_duplicate_extensions(&extensions)) {
    *out_alert = SSL_AD_DECODE_ERROR;
    return false;
  }

  uint32_t received = 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 false;
    }

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

    if (ext == nullptr) {
      OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION);
      ERR_add_error_dataf("extension %u", (unsigned)type);
      *out_alert = SSL_AD_UNSUPPORTED_EXTENSION;
      return false;
    }

    static_assert(kNumExtensions <= sizeof(hs->extensions.sent) * 8,
                  "too many bits");

    if (!(hs->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_UNSUPPORTED_EXTENSION;
      return false;
    }

    received |= (1u << ext_index);

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

  for (size_t 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(hs, &alert, nullptr)) {
        OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_EXTENSION);
        ERR_add_error_dataf("extension %u", (unsigned)kExtensions[i].value);
        *out_alert = alert;
        return false;
      }
    }
  }

  return true;
}

static bool ssl_check_clienthello_tlsext(SSL_HANDSHAKE *hs) {
  SSL *const ssl = hs->ssl;
  int ret = SSL_TLSEXT_ERR_NOACK;
  int al = SSL_AD_UNRECOGNIZED_NAME;
  if (ssl->ctx->servername_callback != nullptr) {
    ret = ssl->ctx->servername_callback(ssl, &al, ssl->ctx->servername_arg);
  } else if (ssl->session_ctx->servername_callback != nullptr) {
    ret = ssl->session_ctx->servername_callback(
        ssl, &al, ssl->session_ctx->servername_arg);
  }

  switch (ret) {
    case SSL_TLSEXT_ERR_ALERT_FATAL:
      ssl_send_alert(ssl, SSL3_AL_FATAL, al);
      return false;

    case SSL_TLSEXT_ERR_NOACK:
      hs->should_ack_sni = false;
      return true;

    default:
      hs->should_ack_sni = ssl->s3->hostname != nullptr;
      return true;
  }
}

static bool ssl_check_serverhello_tlsext(SSL_HANDSHAKE *hs) {
  SSL *const ssl = hs->ssl;
  // ALPS and ALPN have a dependency between each other, so we defer checking
  // consistency to after the callbacks run.
  if (hs->new_session != nullptr && hs->new_session->has_application_settings) {
    // ALPN must be negotiated.
    if (ssl->s3->alpn_selected.empty()) {
      OPENSSL_PUT_ERROR(SSL, SSL_R_NEGOTIATED_ALPS_WITHOUT_ALPN);
      ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
      return false;
    }

    // The negotiated protocol must be one of the ones we advertised for ALPS.
    Span<const uint8_t> settings;
    if (!ssl_get_local_application_settings(hs, &settings,
                                            ssl->s3->alpn_selected)) {
      OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_ALPN_PROTOCOL);
      ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
      return false;
    }

    if (!hs->new_session->local_application_settings.CopyFrom(settings)) {
      ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
      return false;
    }
  }

  return true;
}

bool ssl_parse_serverhello_tlsext(SSL_HANDSHAKE *hs, const CBS *cbs) {
  SSL *const ssl = hs->ssl;
  int alert = SSL_AD_DECODE_ERROR;
  if (!ssl_scan_serverhello_tlsext(hs, cbs, &alert)) {
    ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
    return false;
  }

  if (!ssl_check_serverhello_tlsext(hs)) {
    return false;
  }

  return true;
}

static enum ssl_ticket_aead_result_t decrypt_ticket_with_cipher_ctx(
    Array<uint8_t> *out, EVP_CIPHER_CTX *cipher_ctx, HMAC_CTX *hmac_ctx,
    Span<const uint8_t> ticket) {
  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.size() < SSL_TICKET_KEY_NAME_LEN + iv_len + 1 + mac_len) {
    // The ticket must be large enough for key name, IV, data, and MAC.
    return ssl_ticket_aead_ignore_ticket;
  }
  // Split the ticket into the ticket and the MAC.
  auto ticket_mac = ticket.last(mac_len);
  ticket = ticket.first(ticket.size() - mac_len);
  HMAC_Update(hmac_ctx, ticket.data(), ticket.size());
  HMAC_Final(hmac_ctx, mac, nullptr);
  assert(mac_len == ticket_mac.size());
  bool mac_ok = CRYPTO_memcmp(mac, ticket_mac.data(), mac_len) == 0;
  if (CRYPTO_fuzzer_mode_enabled()) {
    mac_ok = true;
  }
  if (!mac_ok) {
    return ssl_ticket_aead_ignore_ticket;
  }

  // Decrypt the session data.
  auto ciphertext = ticket.subspan(SSL_TICKET_KEY_NAME_LEN + iv_len);
  Array<uint8_t> plaintext;
  if (CRYPTO_fuzzer_mode_enabled()) {
    if (!plaintext.CopyFrom(ciphertext)) {
      return ssl_ticket_aead_error;
    }
  } else {
    if (ciphertext.size() >= INT_MAX) {
      return ssl_ticket_aead_ignore_ticket;
    }
    if (!plaintext.InitForOverwrite(ciphertext.size())) {
      return ssl_ticket_aead_error;
    }
    size_t len1, len2;
    if (!EVP_DecryptUpdate_ex(cipher_ctx, plaintext.data(), &len1,
                              plaintext.size(), ciphertext.data(),
                              (int)ciphertext.size()) ||
        !EVP_DecryptFinal_ex2(cipher_ctx, plaintext.data() + len1, &len2,
                              plaintext.size() - len1)) {
      ERR_clear_error();
      return ssl_ticket_aead_ignore_ticket;
    }
    plaintext.Shrink(len1 + len2);
  }

  *out = std::move(plaintext);
  return ssl_ticket_aead_success;
}

static enum ssl_ticket_aead_result_t ssl_decrypt_ticket_with_cb(
    SSL_HANDSHAKE *hs, Array<uint8_t> *out, bool *out_renew_ticket,
    Span<const uint8_t> ticket) {
  assert(ticket.size() >= SSL_TICKET_KEY_NAME_LEN + EVP_MAX_IV_LENGTH);
  ScopedEVP_CIPHER_CTX cipher_ctx;
  ScopedHMAC_CTX hmac_ctx;
  auto name = ticket.first<SSL_TICKET_KEY_NAME_LEN>();
  // The actual IV is shorter, but the length is determined by the callback's
  // chosen cipher. Instead we pass in |EVP_MAX_IV_LENGTH| worth of IV to ensure
  // the callback has enough.
  auto iv = ticket.subspan<SSL_TICKET_KEY_NAME_LEN, EVP_MAX_IV_LENGTH>();
  int cb_ret = hs->ssl->session_ctx->ticket_key_cb(
      hs->ssl, const_cast<uint8_t *>(name.data()),
      const_cast<uint8_t *>(iv.data()), cipher_ctx.get(), hmac_ctx.get(),
      0 /* decrypt */);
  if (cb_ret < 0) {
    return ssl_ticket_aead_error;
  } else if (cb_ret == 0) {
    return ssl_ticket_aead_ignore_ticket;
  } else if (cb_ret == 2) {
    *out_renew_ticket = true;
  } else {
    assert(cb_ret == 1);
  }
  return decrypt_ticket_with_cipher_ctx(out, cipher_ctx.get(), hmac_ctx.get(),
                                        ticket);
}

static enum ssl_ticket_aead_result_t ssl_decrypt_ticket_with_ticket_keys(
    SSL_HANDSHAKE *hs, Array<uint8_t> *out, Span<const uint8_t> ticket) {
  assert(ticket.size() >= SSL_TICKET_KEY_NAME_LEN + EVP_MAX_IV_LENGTH);
  SSL_CTX *ctx = hs->ssl->session_ctx.get();

  // Rotate the ticket key if necessary.
  if (!ssl_ctx_rotate_ticket_encryption_key(ctx)) {
    return ssl_ticket_aead_error;
  }

  const EVP_CIPHER *cipher = EVP_aes_128_cbc();
  auto name = ticket.first<SSL_TICKET_KEY_NAME_LEN>();
  auto iv =
      ticket.subspan(SSL_TICKET_KEY_NAME_LEN, EVP_CIPHER_iv_length(cipher));

  // Pick the matching ticket key and decrypt.
  ScopedEVP_CIPHER_CTX cipher_ctx;
  ScopedHMAC_CTX hmac_ctx;
  {
    MutexReadLock lock(&ctx->lock);
    const TicketKey *key;
    if (ctx->ticket_key_current && name == ctx->ticket_key_current->name) {
      key = ctx->ticket_key_current.get();
    } else if (ctx->ticket_key_prev && name == ctx->ticket_key_prev->name) {
      key = ctx->ticket_key_prev.get();
    } else {
      return ssl_ticket_aead_ignore_ticket;
    }
    if (!HMAC_Init_ex(hmac_ctx.get(), key->hmac_key, sizeof(key->hmac_key),
                      tlsext_tick_md(), nullptr) ||
        !EVP_DecryptInit_ex(cipher_ctx.get(), cipher, nullptr, key->aes_key,
                            iv.data())) {
      return ssl_ticket_aead_error;
    }
  }
  return decrypt_ticket_with_cipher_ctx(out, cipher_ctx.get(), hmac_ctx.get(),
                                        ticket);
}

static enum ssl_ticket_aead_result_t ssl_decrypt_ticket_with_method(
    SSL_HANDSHAKE *hs, Array<uint8_t> *out, bool *out_renew_ticket,
    Span<const uint8_t> ticket) {
  Array<uint8_t> plaintext;
  if (!plaintext.InitForOverwrite(ticket.size())) {
    return ssl_ticket_aead_error;
  }

  size_t plaintext_len;
  const enum ssl_ticket_aead_result_t result =
      hs->ssl->session_ctx->ticket_aead_method->open(
          hs->ssl, plaintext.data(), &plaintext_len, ticket.size(),
          ticket.data(), ticket.size());
  if (result != ssl_ticket_aead_success) {
    return result;
  }

  plaintext.Shrink(plaintext_len);
  *out = std::move(plaintext);
  return ssl_ticket_aead_success;
}

enum ssl_ticket_aead_result_t ssl_process_ticket(
    SSL_HANDSHAKE *hs, UniquePtr<SSL_SESSION> *out_session,
    bool *out_renew_ticket, Span<const uint8_t> ticket,
    Span<const uint8_t> session_id, bool save_ticket) {
  SSL *const ssl = hs->ssl;
  *out_renew_ticket = false;
  out_session->reset();

  if ((SSL_get_options(hs->ssl) & SSL_OP_NO_TICKET) ||
      session_id.size() > SSL_MAX_SSL_SESSION_ID_LENGTH) {
    return ssl_ticket_aead_ignore_ticket;
  }

  // Tickets in TLS 1.3 are tied into pre-shared keys (PSKs), unlike in TLS 1.2
  // where that concept doesn't exist. The |decrypted_psk| and |ignore_psk|
  // hints only apply to PSKs. We check the version to determine which this is.
  const bool is_psk = ssl_protocol_version(ssl) >= TLS1_3_VERSION;

  Array<uint8_t> plaintext;
  enum ssl_ticket_aead_result_t result;
  SSL_HANDSHAKE_HINTS *const hints = hs->hints.get();
  if (is_psk && hints && !hs->hints_requested &&
      !hints->decrypted_psk.empty()) {
    result = plaintext.CopyFrom(hints->decrypted_psk) ? ssl_ticket_aead_success
                                                      : ssl_ticket_aead_error;
  } else if (is_psk && hints && !hs->hints_requested && hints->ignore_psk) {
    result = ssl_ticket_aead_ignore_ticket;
  } else if (!is_psk && hints && !hs->hints_requested &&
             !hints->decrypted_ticket.empty()) {
    if (plaintext.CopyFrom(hints->decrypted_ticket)) {
      result = ssl_ticket_aead_success;
      *out_renew_ticket = hints->renew_ticket;
    } else {
      result = ssl_ticket_aead_error;
    }
  } else if (!is_psk && hints && !hs->hints_requested && hints->ignore_ticket) {
    result = ssl_ticket_aead_ignore_ticket;
  } else if (ssl->session_ctx->ticket_aead_method != nullptr) {
    result = ssl_decrypt_ticket_with_method(hs, &plaintext, out_renew_ticket,
                                            ticket);
  } else {
    // Ensure there is room for the key name and the largest IV |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.size() < SSL_TICKET_KEY_NAME_LEN + EVP_MAX_IV_LENGTH) {
      result = ssl_ticket_aead_ignore_ticket;
    } else if (ssl->session_ctx->ticket_key_cb != nullptr) {
      result =
          ssl_decrypt_ticket_with_cb(hs, &plaintext, out_renew_ticket, ticket);
    } else {
      result = ssl_decrypt_ticket_with_ticket_keys(hs, &plaintext, ticket);
    }
  }

  if (hints && hs->hints_requested) {
    if (result == ssl_ticket_aead_ignore_ticket) {
      if (is_psk) {
        hints->ignore_psk = true;
      } else {
        hints->ignore_ticket = true;
      }
    } else if (result == ssl_ticket_aead_success) {
      if (is_psk) {
        if (!hints->decrypted_psk.CopyFrom(plaintext)) {
          return ssl_ticket_aead_error;
        }
      } else {
        if (!hints->decrypted_ticket.CopyFrom(plaintext)) {
          return ssl_ticket_aead_error;
        }
        hints->renew_ticket = *out_renew_ticket;
      }
    }
  }

  if (result != ssl_ticket_aead_success) {
    return result;
  }

  // Decode the session.
  UniquePtr<SSL_SESSION> session(SSL_SESSION_from_bytes(
      plaintext.data(), plaintext.size(), ssl->ctx.get()));
  if (!session) {
    ERR_clear_error();  // Don't leave an error on the queue.
    return ssl_ticket_aead_ignore_ticket;
  }

  if (save_ticket && !session->ticket.CopyFrom(ticket)) {
    return ssl_ticket_aead_error;
  }

  // Envoy's tests expect the session to have a session ID that matches the
  // placeholder used by the client. It's unclear whether this is a good idea,
  // but we maintain it for now.
  session->session_id.ResizeForOverwrite(SHA256_DIGEST_LENGTH);
  SHA256(ticket.data(), ticket.size(), session->session_id.data());

  *out_session = std::move(session);
  return ssl_ticket_aead_success;
}

bool tls1_parse_peer_sigalgs(SSL_HANDSHAKE *hs, const CBS *in_sigalgs) {
  // Extension ignored for inappropriate versions
  if (ssl_protocol_version(hs->ssl) < TLS1_2_VERSION) {
    return true;
  }

  // In all contexts, the signature algorithms list may not be empty. (It may be
  // omitted by clients in TLS 1.2, but then the entire extension is omitted.)
  return CBS_len(in_sigalgs) != 0 &&
         parse_u16_array(in_sigalgs, &hs->peer_sigalgs);
}

bool tls1_get_legacy_signature_algorithm(uint16_t *out, const EVP_PKEY *pkey) {
  switch (EVP_PKEY_id(pkey)) {
    case EVP_PKEY_RSA:
      *out = SSL_SIGN_RSA_PKCS1_MD5_SHA1;
      return true;
    case EVP_PKEY_EC:
      *out = SSL_SIGN_ECDSA_SHA1;
      return true;
    default:
      return false;
  }
}

bool tls1_choose_signature_algorithm(SSL_HANDSHAKE *hs,
                                     const SSLCredential *cred, uint16_t *out) {
  SSL *const ssl = hs->ssl;
  if (!cred->UsesPrivateKey()) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE);
    return false;
  }

  // Before TLS 1.2, the signature algorithm isn't negotiated as part of the
  // handshake.
  uint16_t version = ssl_protocol_version(ssl);
  if (version < TLS1_2_VERSION) {
    if (!tls1_get_legacy_signature_algorithm(out, cred->pubkey.get())) {
      OPENSSL_PUT_ERROR(SSL, SSL_R_NO_COMMON_SIGNATURE_ALGORITHMS);
      return false;
    }
    return true;
  }

  Span<const uint16_t> peer_sigalgs;
  if (cred->type == SSLCredentialType::kDelegated) {
    peer_sigalgs = hs->peer_delegated_credential_sigalgs;
  } else {
    peer_sigalgs = hs->peer_sigalgs;
    if (peer_sigalgs.empty() && version == TLS1_2_VERSION) {
      // If the client didn't specify any signature_algorithms extension, it is
      // interpreted as SHA-1. See
      // http://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
      static const uint16_t kTLS12Default[] = {SSL_SIGN_RSA_PKCS1_SHA1,
                                               SSL_SIGN_ECDSA_SHA1};
      peer_sigalgs = kTLS12Default;
    }
  }

  Span<const uint16_t> sigalgs =
      cred->sigalgs.empty() ? Span<const uint16_t>(kSignSignatureAlgorithms)
                            : Span<const uint16_t>(cred->sigalgs);
  for (uint16_t sigalg : sigalgs) {
    if (!ssl_pkey_supports_algorithm(ssl, cred->pubkey.get(), sigalg,
                                     /*is_verify=*/false)) {
      continue;
    }

    if (std::find(peer_sigalgs.begin(), peer_sigalgs.end(), sigalg) !=
        peer_sigalgs.end()) {
      *out = sigalg;
      return true;
    }
  }

  OPENSSL_PUT_ERROR(SSL, SSL_R_NO_COMMON_SIGNATURE_ALGORITHMS);
  return false;
}

bool tls1_verify_channel_id(SSL_HANDSHAKE *hs, const SSLMessage &msg) {
  SSL *const ssl = hs->ssl;
  // A Channel ID handshake message is structured to contain multiple
  // extensions, but the only one that can be present is Channel ID.
  uint16_t extension_type;
  CBS channel_id = msg.body, extension;
  if (!CBS_get_u16(&channel_id, &extension_type) ||             //
      !CBS_get_u16_length_prefixed(&channel_id, &extension) ||  //
      CBS_len(&channel_id) != 0 ||                              //
      extension_type != TLSEXT_TYPE_channel_id ||               //
      CBS_len(&extension) != TLSEXT_CHANNEL_ID_SIZE) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
    ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
    return false;
  }

  const EC_GROUP *p256 = EC_group_p256();
  UniquePtr<ECDSA_SIG> sig(ECDSA_SIG_new());
  UniquePtr<BIGNUM> x(BN_new()), y(BN_new());
  if (!sig || !x || !y) {
    return false;
  }

  const uint8_t *p = CBS_data(&extension);
  if (BN_bin2bn(p + 0, 32, x.get()) == nullptr ||
      BN_bin2bn(p + 32, 32, y.get()) == nullptr ||
      BN_bin2bn(p + 64, 32, sig->r) == nullptr ||
      BN_bin2bn(p + 96, 32, sig->s) == nullptr) {
    return false;
  }

  UniquePtr<EC_KEY> key(EC_KEY_new());
  UniquePtr<EC_POINT> point(EC_POINT_new(p256));
  if (!key || !point ||
      !EC_POINT_set_affine_coordinates_GFp(p256, point.get(), x.get(), y.get(),
                                           nullptr) ||
      !EC_KEY_set_group(key.get(), p256) ||
      !EC_KEY_set_public_key(key.get(), point.get())) {
    return false;
  }

  uint8_t digest[EVP_MAX_MD_SIZE];
  size_t digest_len;
  if (!tls1_channel_id_hash(hs, digest, &digest_len)) {
    return false;
  }

  bool sig_ok = ECDSA_do_verify(digest, digest_len, sig.get(), key.get());
  if (CRYPTO_fuzzer_mode_enabled()) {
    sig_ok = true;
    ERR_clear_error();
  }
  if (!sig_ok) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_CHANNEL_ID_SIGNATURE_INVALID);
    ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR);
    return false;
  }

  OPENSSL_memcpy(ssl->s3->channel_id, p, 64);
  ssl->s3->channel_id_valid = true;
  return true;
}

bool tls1_write_channel_id(SSL_HANDSHAKE *hs, CBB *cbb) {
  uint8_t digest[EVP_MAX_MD_SIZE];
  size_t digest_len;
  if (!tls1_channel_id_hash(hs, digest, &digest_len)) {
    return false;
  }

  EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(hs->config->channel_id_private.get());
  if (ec_key == nullptr) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
    return false;
  }

  UniquePtr<BIGNUM> x(BN_new()), y(BN_new());
  if (!x || !y ||
      !EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(ec_key),
                                           EC_KEY_get0_public_key(ec_key),
                                           x.get(), y.get(), nullptr)) {
    return false;
  }

  UniquePtr<ECDSA_SIG> sig(ECDSA_do_sign(digest, digest_len, ec_key));
  if (!sig) {
    return false;
  }

  CBB child;
  if (!CBB_add_u16(cbb, TLSEXT_TYPE_channel_id) ||  //
      !CBB_add_u16_length_prefixed(cbb, &child) ||  //
      !BN_bn2cbb_padded(&child, 32, x.get()) ||     //
      !BN_bn2cbb_padded(&child, 32, y.get()) ||     //
      !BN_bn2cbb_padded(&child, 32, sig->r) ||      //
      !BN_bn2cbb_padded(&child, 32, sig->s) ||      //
      !CBB_flush(cbb)) {
    return false;
  }

  return true;
}

bool tls1_channel_id_hash(SSL_HANDSHAKE *hs, uint8_t *out, size_t *out_len) {
  SSL *const ssl = hs->ssl;
  if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) {
    Array<uint8_t> msg;
    if (!tls13_get_cert_verify_signature_input(hs, &msg,
                                               ssl_cert_verify_channel_id)) {
      return false;
    }
    SHA256(msg.data(), msg.size(), out);
    *out_len = SHA256_DIGEST_LENGTH;
    return true;
  }

  SHA256_CTX ctx;

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

  if (ssl->session != nullptr) {
    static const char kResumptionMagic[] = "Resumption";
    SHA256_Update(&ctx, kResumptionMagic, sizeof(kResumptionMagic));
    if (ssl->session->original_handshake_hash.empty()) {
      OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
      return false;
    }
    SHA256_Update(&ctx, ssl->session->original_handshake_hash.data(),
                  ssl->session->original_handshake_hash.size());
  }

  uint8_t hs_hash[EVP_MAX_MD_SIZE];
  size_t hs_hash_len;
  if (!hs->transcript.GetHash(hs_hash, &hs_hash_len)) {
    return false;
  }
  SHA256_Update(&ctx, hs_hash, (size_t)hs_hash_len);
  SHA256_Final(out, &ctx);
  *out_len = SHA256_DIGEST_LENGTH;
  return true;
}

bool tls1_record_handshake_hashes_for_channel_id(SSL_HANDSHAKE *hs) {
  SSL *const ssl = hs->ssl;
  // 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->session != nullptr) {
    return false;
  }

  size_t digest_len;
  hs->new_session->original_handshake_hash.ResizeForOverwrite(
      hs->transcript.DigestLen());
  if (!hs->transcript.GetHash(hs->new_session->original_handshake_hash.data(),
                              &digest_len)) {
    return false;
  }
  assert(digest_len == hs->new_session->original_handshake_hash.size());
  return true;
}

bool ssl_is_sct_list_valid(const CBS *contents) {
  // Shallow parse the SCT list for sanity. By the RFC
  // (https://tools.ietf.org/html/rfc6962#section-3.3) neither the list nor any
  // of the SCTs may be empty.
  CBS copy = *contents;
  CBS sct_list;
  if (!CBS_get_u16_length_prefixed(&copy, &sct_list) || CBS_len(&copy) != 0 ||
      CBS_len(&sct_list) == 0) {
    return false;
  }

  while (CBS_len(&sct_list) > 0) {
    CBS sct;
    if (!CBS_get_u16_length_prefixed(&sct_list, &sct) || CBS_len(&sct) == 0) {
      return false;
    }
  }

  return true;
}

BSSL_NAMESPACE_END

using namespace bssl;

int SSL_parse_client_hello(const SSL *ssl, SSL_CLIENT_HELLO *out,
                           const uint8_t *in, size_t len) {
  CBS cbs = Span(in, len);
  if (!ssl_parse_client_hello_with_trailing_data(ssl, &cbs, out)) {
    return 0;
  }
  if (CBS_len(&cbs) != 0) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED);
    return 0;
  }
  return 1;
}

int SSL_early_callback_ctx_extension_get(const SSL_CLIENT_HELLO *client_hello,
                                         uint16_t extension_type,
                                         const uint8_t **out_data,
                                         size_t *out_len) {
  CBS cbs;
  if (!ssl_client_hello_get_extension(client_hello, &cbs, extension_type)) {
    return 0;
  }

  *out_data = CBS_data(&cbs);
  *out_len = CBS_len(&cbs);
  return 1;
}
