// Copyright 2016 The BoringSSL Authors
//
// 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 <string.h>

#include <utility>

#include <openssl/bytestring.h>
#include <openssl/digest.h>
#include <openssl/err.h>
#include <openssl/mem.h>
#include <openssl/sha.h>
#include <openssl/stack.h>

#include "../crypto/internal.h"
#include "internal.h"


BSSL_NAMESPACE_BEGIN

enum client_hs_state_t {
  state_read_hello_retry_request = 0,
  state_send_second_client_hello,
  state_read_server_hello,
  state_read_encrypted_extensions,
  state_read_certificate_request,
  state_read_server_certificate,
  state_read_server_certificate_verify,
  state_server_certificate_reverify,
  state_read_server_finished,
  state_send_end_of_early_data,
  state_send_client_encrypted_extensions,
  state_send_client_certificate,
  state_send_client_certificate_verify,
  state_complete_second_flight,
  state_done,
};

static const uint8_t kZeroes[EVP_MAX_MD_SIZE] = {0};

// end_of_early_data closes the early data stream for |hs| and switches the
// encryption level to |level|. It returns true on success and false on error.
static bool close_early_data(SSL_HANDSHAKE *hs, ssl_encryption_level_t level) {
  SSL *const ssl = hs->ssl;
  assert(hs->in_early_data);

  // Note |can_early_write| may already be false if |SSL_write| exceeded the
  // early data write limit.
  hs->can_early_write = false;

  // 0-RTT write states on the client differ between TLS 1.3, DTLS 1.3, and
  // QUIC. TLS 1.3 has one write encryption level at a time. 0-RTT write keys
  // overwrite the null cipher and defer handshake write keys. While a
  // HelloRetryRequest can cause us to rewind back to the null cipher, sequence
  // numbers have no effect, so we can install a "new" null cipher.
  //
  // In QUIC and DTLS 1.3, 0-RTT write state cannot override or defer the normal
  // write state. The two ClientHello sequence numbers must align, and handshake
  // write keys must be installed early to ACK the EncryptedExtensions.
  //
  // TODO(crbug.com/381113363): We do not support 0-RTT in DTLS 1.3 and, in
  // QUIC, the caller handles 0-RTT data, so we can skip installing 0-RTT keys
  // and act as if there is one write level. Now that we're implementing
  // DTLS 1.3, switch the abstraction to the DTLS/QUIC model where handshake
  // keys write keys are installed immediately, but the TLS record layer
  // internally waits to activate that epoch until the 0-RTT channel is closed.
  if (!SSL_is_quic(ssl)) {
    if (level == ssl_encryption_initial) {
      bssl::UniquePtr<SSLAEADContext> null_ctx =
          SSLAEADContext::CreateNullCipher();
      if (!null_ctx ||  //
          !ssl->method->set_write_state(ssl, ssl_encryption_initial,
                                        std::move(null_ctx),
                                        /*traffic_secret=*/{})) {
        return false;
      }
    } else {
      assert(level == ssl_encryption_handshake);
      if (!tls13_set_traffic_key(ssl, ssl_encryption_handshake, evp_aead_seal,
                                 hs->new_session.get(),
                                 hs->client_handshake_secret)) {
        return false;
      }
    }
  } else {
    assert(ssl->s3->quic_write_level == level);
  }

  return true;
}

static bool parse_server_hello_tls13(const SSL_HANDSHAKE *hs,
                                     ParsedServerHello *out, uint8_t *out_alert,
                                     const SSLMessage &msg) {
  if (!ssl_parse_server_hello(out, out_alert, msg)) {
    return false;
  }
  uint16_t expected_version =
      SSL_is_dtls(hs->ssl) ? DTLS1_2_VERSION : TLS1_2_VERSION;
  // DTLS 1.3 disables "compatibility mode" (RFC 8446, appendix D.4). When
  // disabled, servers MUST NOT echo the legacy_session_id (RFC 9147, section
  // 5). The client could have sent a session ID indicating its willingness to
  // resume a DTLS 1.2 session, so just checking that the session IDs match is
  // incorrect.
  Span<const uint8_t> expected_session_id =
      SSL_is_dtls(hs->ssl) ? Span<const uint8_t>() : Span(hs->session_id);

  // RFC 8446 fixes some legacy values. Check them.
  if (out->legacy_version != expected_version ||  //
      out->compression_method != 0 ||
      Span<const uint8_t>(out->session_id) != expected_session_id ||
      CBS_len(&out->extensions) == 0) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
    *out_alert = SSL_AD_DECODE_ERROR;
    return false;
  }
  return true;
}

static bool is_hello_retry_request(const ParsedServerHello &server_hello) {
  return Span<const uint8_t>(server_hello.random) == kHelloRetryRequest;
}

static bool check_ech_confirmation(const SSL_HANDSHAKE *hs, bool *out_accepted,
                                   uint8_t *out_alert,
                                   const ParsedServerHello &server_hello) {
  const bool is_hrr = is_hello_retry_request(server_hello);
  size_t offset;
  if (is_hrr) {
    // We check for an unsolicited extension when parsing all of them.
    SSLExtension ech(TLSEXT_TYPE_encrypted_client_hello);
    if (!ssl_parse_extensions(&server_hello.extensions, out_alert, {&ech},
                              /*ignore_unknown=*/true)) {
      return false;
    }
    if (!ech.present) {
      *out_accepted = false;
      return true;
    }
    if (CBS_len(&ech.data) != ECH_CONFIRMATION_SIGNAL_LEN) {
      OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
      *out_alert = SSL_AD_DECODE_ERROR;
      return false;
    }
    offset = CBS_data(&ech.data) - CBS_data(&server_hello.raw);
  } else {
    offset = ssl_ech_confirmation_signal_hello_offset(hs->ssl);
  }

  if (!hs->selected_ech_config) {
    *out_accepted = false;
    return true;
  }

  uint8_t expected[ECH_CONFIRMATION_SIGNAL_LEN];
  if (!ssl_ech_accept_confirmation(hs, expected, hs->inner_client_random,
                                   hs->inner_transcript, is_hrr,
                                   server_hello.raw, offset)) {
    *out_alert = SSL_AD_INTERNAL_ERROR;
    return false;
  }

  *out_accepted = CRYPTO_memcmp(CBS_data(&server_hello.raw) + offset, expected,
                                sizeof(expected)) == 0;
  return true;
}

static enum ssl_hs_wait_t do_read_hello_retry_request(SSL_HANDSHAKE *hs) {
  SSL *const ssl = hs->ssl;
  assert(ssl->s3->version != 0);
  SSLMessage msg;
  if (!ssl->method->get_message(ssl, &msg)) {
    return ssl_hs_read_message;
  }

  // Queue up a ChangeCipherSpec for whenever we next send something. This
  // will be before the second ClientHello. If we offered early data, this was
  // already done.
  if (!hs->early_data_offered &&  //
      !ssl->method->add_change_cipher_spec(ssl)) {
    return ssl_hs_error;
  }

  ParsedServerHello server_hello;
  uint8_t alert = SSL_AD_DECODE_ERROR;
  if (!parse_server_hello_tls13(hs, &server_hello, &alert, msg)) {
    ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
    return ssl_hs_error;
  }

  // The cipher suite must be one we offered. We currently offer all supported
  // TLS 1.3 ciphers unless policy controls limited it. So we check the version
  // and that it's ok per policy.
  const SSL_CIPHER *cipher = SSL_get_cipher_by_value(server_hello.cipher_suite);
  if (cipher == nullptr ||
      SSL_CIPHER_get_min_version(cipher) > ssl_protocol_version(ssl) ||
      SSL_CIPHER_get_max_version(cipher) < ssl_protocol_version(ssl) ||
      !ssl_tls13_cipher_meets_policy(SSL_CIPHER_get_protocol_id(cipher),
                                     ssl->config->compliance_policy)) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CIPHER_RETURNED);
    ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
    return ssl_hs_error;
  }

  hs->new_cipher = cipher;

  const bool is_hrr = is_hello_retry_request(server_hello);
  if (!hs->transcript.InitHash(ssl_protocol_version(ssl), hs->new_cipher) ||
      (is_hrr && !hs->transcript.UpdateForHelloRetryRequest())) {
    return ssl_hs_error;
  }
  if (hs->selected_ech_config) {
    if (!hs->inner_transcript.InitHash(ssl_protocol_version(ssl),
                                       hs->new_cipher) ||
        (is_hrr && !hs->inner_transcript.UpdateForHelloRetryRequest())) {
      return ssl_hs_error;
    }
  }

  // Determine which ClientHello the server is responding to. Run
  // |check_ech_confirmation| unconditionally, so we validate the extension
  // contents.
  bool ech_accepted;
  if (!check_ech_confirmation(hs, &ech_accepted, &alert, server_hello)) {
    ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
    return ssl_hs_error;
  }
  if (hs->selected_ech_config) {
    ssl->s3->ech_status = ech_accepted ? ssl_ech_accepted : ssl_ech_rejected;
  }

  if (!is_hrr) {
    hs->tls13_state = state_read_server_hello;
    return ssl_hs_ok;
  }

  // The ECH extension, if present, was already parsed by
  // |check_ech_confirmation|.
  SSLExtension cookie(TLSEXT_TYPE_cookie),
      key_share(TLSEXT_TYPE_key_share, !hs->key_share_bytes.empty()),
      supported_versions(TLSEXT_TYPE_supported_versions),
      ech_unused(TLSEXT_TYPE_encrypted_client_hello,
                 hs->selected_ech_config || hs->config->ech_grease_enabled);
  if (!ssl_parse_extensions(
          &server_hello.extensions, &alert,
          {&cookie, &key_share, &supported_versions, &ech_unused},
          /*ignore_unknown=*/false)) {
    ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
    return ssl_hs_error;
  }

  if (!cookie.present && !key_share.present) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_EMPTY_HELLO_RETRY_REQUEST);
    ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
    return ssl_hs_error;
  }
  if (cookie.present) {
    CBS cookie_value;
    if (!CBS_get_u16_length_prefixed(&cookie.data, &cookie_value) ||  //
        CBS_len(&cookie_value) == 0 ||                                //
        CBS_len(&cookie.data) != 0) {
      OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
      ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
      return ssl_hs_error;
    }

    if (!hs->cookie.CopyFrom(cookie_value)) {
      return ssl_hs_error;
    }
  }

  if (key_share.present) {
    // If offering PAKE, we won't send key_share extensions, in which case we
    // would have rejected key_share from the peer.
    assert(!hs->pake_prover);

    uint16_t group_id;
    if (!CBS_get_u16(&key_share.data, &group_id) ||
        CBS_len(&key_share.data) != 0) {
      OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
      ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
      return ssl_hs_error;
    }

    // The group must be supported.
    if (!tls1_check_group_id(hs, group_id)) {
      ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
      OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CURVE);
      return ssl_hs_error;
    }

    // Check that the HelloRetryRequest does not request a key share that was
    // provided in the initial ClientHello.
    if (hs->key_shares[0]->GroupID() == group_id ||
        (hs->key_shares[1] && hs->key_shares[1]->GroupID() == group_id)) {
      ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
      OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CURVE);
      return ssl_hs_error;
    }

    if (!ssl_setup_key_shares(hs, group_id)) {
      return ssl_hs_error;
    }
  }

  // Although we now know whether ClientHelloInner was used, we currently
  // maintain both transcripts up to ServerHello. We could swap transcripts
  // early, but then ClientHello construction and |check_ech_confirmation|
  // become more complex.
  if (!ssl_hash_message(hs, msg)) {
    return ssl_hs_error;
  }
  if (ssl->s3->ech_status == ssl_ech_accepted &&
      !hs->inner_transcript.Update(msg.raw)) {
    return ssl_hs_error;
  }

  // HelloRetryRequest should be the end of the flight.
  if (ssl->method->has_unprocessed_handshake_data(ssl)) {
    ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
    OPENSSL_PUT_ERROR(SSL, SSL_R_EXCESS_HANDSHAKE_DATA);
    return ssl_hs_error;
  }

  ssl->method->next_message(ssl);
  ssl->s3->used_hello_retry_request = true;
  hs->tls13_state = state_send_second_client_hello;
  // 0-RTT is rejected if we receive a HelloRetryRequest.
  if (hs->in_early_data) {
    ssl->s3->early_data_reason = ssl_early_data_hello_retry_request;
    if (!close_early_data(hs, ssl_encryption_initial)) {
      return ssl_hs_error;
    }
    return ssl_hs_early_data_rejected;
  }
  return ssl_hs_ok;
}

static enum ssl_hs_wait_t do_send_second_client_hello(SSL_HANDSHAKE *hs) {
  // Build the second ClientHelloInner, if applicable. The second ClientHello
  // uses an empty string for |enc|.
  if (hs->ssl->s3->ech_status == ssl_ech_accepted &&
      !ssl_encrypt_client_hello(hs, {})) {
    return ssl_hs_error;
  }

  if (!ssl_add_client_hello(hs)) {
    return ssl_hs_error;
  }

  ssl_done_writing_client_hello(hs);
  hs->tls13_state = state_read_server_hello;
  return ssl_hs_flush;
}

static enum ssl_hs_wait_t do_read_server_hello(SSL_HANDSHAKE *hs) {
  SSL *const ssl = hs->ssl;
  SSLMessage msg;
  if (!ssl->method->get_message(ssl, &msg)) {
    return ssl_hs_read_message;
  }
  ParsedServerHello server_hello;
  uint8_t alert = SSL_AD_DECODE_ERROR;
  if (!parse_server_hello_tls13(hs, &server_hello, &alert, msg)) {
    ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
    return ssl_hs_error;
  }

  // Forbid a second HelloRetryRequest.
  if (is_hello_retry_request(server_hello)) {
    ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
    OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE);
    return ssl_hs_error;
  }

  // Check the cipher suite, in case this is after HelloRetryRequest.
  if (SSL_CIPHER_get_protocol_id(hs->new_cipher) != server_hello.cipher_suite) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CIPHER_RETURNED);
    ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
    return ssl_hs_error;
  }

  if (ssl->s3->ech_status == ssl_ech_accepted) {
    if (ssl->s3->used_hello_retry_request) {
      // HelloRetryRequest and ServerHello must accept ECH consistently.
      bool ech_accepted;
      if (!check_ech_confirmation(hs, &ech_accepted, &alert, server_hello)) {
        ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
        return ssl_hs_error;
      }
      if (!ech_accepted) {
        OPENSSL_PUT_ERROR(SSL, SSL_R_INCONSISTENT_ECH_NEGOTIATION);
        ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
        return ssl_hs_error;
      }
    }

    hs->transcript = std::move(hs->inner_transcript);
    hs->extensions.sent = hs->inner_extensions_sent;
    // Report the inner random value through |SSL_get_client_random|.
    OPENSSL_memcpy(ssl->s3->client_random, hs->inner_client_random,
                   SSL3_RANDOM_SIZE);
  }

  OPENSSL_memcpy(ssl->s3->server_random, CBS_data(&server_hello.random),
                 SSL3_RANDOM_SIZE);

  // When offering ECH, |ssl->session| is only offered in ClientHelloInner.
  const bool pre_shared_key_allowed =
      ssl->session != nullptr &&
      ssl_session_get_type(ssl->session.get()) ==
          SSLSessionType::kPreSharedKey &&
      ssl->s3->ech_status != ssl_ech_rejected;
  SSLExtension key_share(TLSEXT_TYPE_key_share, hs->key_shares[0] != nullptr),
      pake_share(TLSEXT_TYPE_pake, hs->pake_prover != nullptr),
      pre_shared_key(TLSEXT_TYPE_pre_shared_key, pre_shared_key_allowed),
      supported_versions(TLSEXT_TYPE_supported_versions);
  if (!ssl_parse_extensions(
          &server_hello.extensions, &alert,
          {&key_share, &pre_shared_key, &supported_versions, &pake_share},
          /*ignore_unknown=*/false)) {
    ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
    return ssl_hs_error;
  }

  // Recheck supported_versions, in case this is after HelloRetryRequest.
  uint16_t version;
  if (!supported_versions.present ||                       //
      !CBS_get_u16(&supported_versions.data, &version) ||  //
      CBS_len(&supported_versions.data) != 0 ||            //
      version != ssl->s3->version) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_SECOND_SERVERHELLO_VERSION_MISMATCH);
    ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
    return ssl_hs_error;
  }

  // The combination of ServerHello extensions determines the kind of handshake
  // that the server selected. Check for invalid combinations.

  // pake replaces key_share and may not be used with pre_shared_key.
  if (pake_share.present && (key_share.present || pre_shared_key.present)) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION);
    ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_EXTENSION);
    return ssl_hs_error;
  }
  // In PAKE mode, we require a PAKE handshake and do not support resumption.
  if (hs->pake_prover != nullptr && !pake_share.present) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_EXTENSION);
    ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_MISSING_EXTENSION);
    return ssl_hs_error;
  }
  // In non-PAKE modes, we require per-connection forward secrecy and do not
  // support psk_ke.
  if (hs->pake_prover == nullptr && !key_share.present) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_KEY_SHARE);
    ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_MISSING_EXTENSION);
    return ssl_hs_error;
  }
  // The above imples only one of three handshake forms will be allowed. The
  // checks for unsolicited extensions ensure the server did not select
  // something we cannot respond to.
  assert(
      // Full handshake
      (key_share.present && !pake_share.present && !pre_shared_key.present) ||
      // PSK/resumption handshake
      (key_share.present && !pake_share.present && pre_shared_key.present) ||
      // PAKE handshake
      (!key_share.present && pake_share.present && !pre_shared_key.present));

  alert = SSL_AD_DECODE_ERROR;
  if (pre_shared_key.present) {
    if (!ssl_ext_pre_shared_key_parse_serverhello(hs, &alert,
                                                  &pre_shared_key.data)) {
      ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
      return ssl_hs_error;
    }

    if (ssl->session->ssl_version != ssl->s3->version) {
      OPENSSL_PUT_ERROR(SSL, SSL_R_OLD_SESSION_VERSION_NOT_RETURNED);
      ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
      return ssl_hs_error;
    }

    if (ssl->session->cipher->algorithm_prf != hs->new_cipher->algorithm_prf) {
      OPENSSL_PUT_ERROR(SSL, SSL_R_OLD_SESSION_PRF_HASH_MISMATCH);
      ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
      return ssl_hs_error;
    }

    if (!ssl_session_is_context_valid(hs, ssl->session.get())) {
      // This is actually a client application bug.
      OPENSSL_PUT_ERROR(SSL,
                        SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT);
      ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
      return ssl_hs_error;
    }

    ssl->s3->session_reused = true;
    hs->can_release_private_key = true;
    // Only authentication information carries over in TLS 1.3.
    hs->new_session =
        SSL_SESSION_dup(ssl->session.get(), SSL_SESSION_DUP_AUTH_ONLY);
    if (!hs->new_session) {
      ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
      return ssl_hs_error;
    }
    ssl_set_session(ssl, NULL);

    // Resumption incorporates fresh key material, so refresh the timeout.
    ssl_session_renew_timeout(ssl, hs->new_session.get(),
                              ssl->session_ctx->session_psk_dhe_timeout);
  } else if (!ssl_get_new_session(hs)) {
    ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
    return ssl_hs_error;
  }

  hs->new_session->cipher = hs->new_cipher;

  // Set up the key schedule and incorporate the PSK into the running secret.
  size_t hash_len = EVP_MD_size(
      ssl_get_handshake_digest(ssl_protocol_version(ssl), hs->new_cipher));
  if (!tls13_init_key_schedule(hs, ssl->s3->session_reused
                                       ? Span(hs->new_session->secret)
                                       : Span(kZeroes, hash_len))) {
    return ssl_hs_error;
  }

  // Resolve ECDHE or PAKE and incorporate it into the secret.
  Array<uint8_t> shared_secret;
  alert = SSL_AD_DECODE_ERROR;
  if (key_share.present) {
    if (!ssl_ext_key_share_parse_serverhello(hs, &shared_secret, &alert,
                                             &key_share.data)) {
      ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
      return ssl_hs_error;
    }
  } else if (pake_share.present) {
    if (!ssl_ext_pake_parse_serverhello(hs, &shared_secret, &alert,
                                        &pake_share.data)) {
      ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
      return ssl_hs_error;
    }
  } else {
    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
    ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
    return ssl_hs_error;
  }

  if (!tls13_advance_key_schedule(hs, shared_secret) ||  //
      !ssl_hash_message(hs, msg) ||                      //
      !tls13_derive_handshake_secrets(hs)) {
    return ssl_hs_error;
  }

  // If currently sending early data over TCP, we defer installing client
  // traffic keys to when the early data stream is closed. See
  // |close_early_data|. Note if the server has already rejected 0-RTT via
  // HelloRetryRequest, |in_early_data| is already false.
  if (!hs->in_early_data || SSL_is_quic(ssl)) {
    if (!tls13_set_traffic_key(ssl, ssl_encryption_handshake, evp_aead_seal,
                               hs->new_session.get(),
                               hs->client_handshake_secret)) {
      return ssl_hs_error;
    }
  }

  if (!tls13_set_traffic_key(ssl, ssl_encryption_handshake, evp_aead_open,
                             hs->new_session.get(),
                             hs->server_handshake_secret)) {
    return ssl_hs_error;
  }

  ssl->method->next_message(ssl);
  hs->tls13_state = state_read_encrypted_extensions;
  return ssl_hs_ok;
}

static enum ssl_hs_wait_t do_read_encrypted_extensions(SSL_HANDSHAKE *hs) {
  SSL *const ssl = hs->ssl;
  SSLMessage msg;
  if (!ssl->method->get_message(ssl, &msg)) {
    return ssl_hs_read_message;
  }
  if (!ssl_check_message_type(ssl, msg, SSL3_MT_ENCRYPTED_EXTENSIONS)) {
    return ssl_hs_error;
  }

  CBS body = msg.body, extensions;
  if (!CBS_get_u16_length_prefixed(&body, &extensions) ||  //
      CBS_len(&body) != 0) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
    ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
    return ssl_hs_error;
  }

  if (!ssl_parse_serverhello_tlsext(hs, &extensions)) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_PARSE_TLSEXT);
    return ssl_hs_error;
  }

  if (ssl->s3->early_data_accepted) {
    // The extension parser checks the server resumed the session.
    assert(ssl->s3->session_reused);
    // If offering ECH, the server may not accept early data with
    // ClientHelloOuter. We do not offer sessions with ClientHelloOuter, so this
    // this should be implied by checking |session_reused|.
    assert(ssl->s3->ech_status != ssl_ech_rejected);

    if (hs->early_session->cipher != hs->new_session->cipher) {
      OPENSSL_PUT_ERROR(SSL, SSL_R_CIPHER_MISMATCH_ON_EARLY_DATA);
      ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
      return ssl_hs_error;
    }
    if (Span(hs->early_session->early_alpn) != ssl->s3->alpn_selected) {
      OPENSSL_PUT_ERROR(SSL, SSL_R_ALPN_MISMATCH_ON_EARLY_DATA);
      ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
      return ssl_hs_error;
    }
    // Channel ID is incompatible with 0-RTT. The ALPS extension should be
    // negotiated implicitly.
    if (hs->channel_id_negotiated ||
        hs->new_session->has_application_settings) {
      OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION_ON_EARLY_DATA);
      ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
      return ssl_hs_error;
    }
    hs->new_session->has_application_settings =
        hs->early_session->has_application_settings;
    if (!hs->new_session->local_application_settings.CopyFrom(
            hs->early_session->local_application_settings) ||
        !hs->new_session->peer_application_settings.CopyFrom(
            hs->early_session->peer_application_settings)) {
      ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
      return ssl_hs_error;
    }
  }

  // Store the negotiated ALPN in the session.
  if (!hs->new_session->early_alpn.CopyFrom(ssl->s3->alpn_selected)) {
    ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
    return ssl_hs_error;
  }

  if (!ssl_hash_message(hs, msg)) {
    return ssl_hs_error;
  }

  ssl->method->next_message(ssl);
  hs->tls13_state = state_read_certificate_request;
  if (hs->in_early_data && !ssl->s3->early_data_accepted) {
    if (!close_early_data(hs, ssl_encryption_handshake)) {
      return ssl_hs_error;
    }
    return ssl_hs_early_data_rejected;
  }
  return ssl_hs_ok;
}

static enum ssl_hs_wait_t do_read_certificate_request(SSL_HANDSHAKE *hs) {
  SSL *const ssl = hs->ssl;
  // CertificateRequest may only be sent in non-resumption handshakes.
  if (ssl->s3->session_reused) {
    if (ssl->ctx->reverify_on_resume && !ssl->s3->early_data_accepted) {
      hs->tls13_state = state_server_certificate_reverify;
      return ssl_hs_ok;
    }
    hs->tls13_state = state_read_server_finished;
    return ssl_hs_ok;
  }

  if (hs->pake_prover) {
    hs->tls13_state = state_read_server_finished;
    return ssl_hs_ok;
  }

  SSLMessage msg;
  if (!ssl->method->get_message(ssl, &msg)) {
    return ssl_hs_read_message;
  }

  // CertificateRequest is optional.
  if (msg.type != SSL3_MT_CERTIFICATE_REQUEST) {
    hs->tls13_state = state_read_server_certificate;
    return ssl_hs_ok;
  }

  SSLExtension sigalgs(TLSEXT_TYPE_signature_algorithms),
      ca(TLSEXT_TYPE_certificate_authorities);
  CBS body = msg.body, context, extensions, supported_signature_algorithms;
  uint8_t alert = SSL_AD_DECODE_ERROR;
  if (!CBS_get_u8_length_prefixed(&body, &context) ||
      // The request context is always empty during the handshake.
      CBS_len(&context) != 0 ||
      !CBS_get_u16_length_prefixed(&body, &extensions) ||  //
      CBS_len(&body) != 0 ||
      !ssl_parse_extensions(&extensions, &alert, {&sigalgs, &ca},
                            /*ignore_unknown=*/true) ||
      !sigalgs.present ||
      !CBS_get_u16_length_prefixed(&sigalgs.data,
                                   &supported_signature_algorithms) ||
      !tls1_parse_peer_sigalgs(hs, &supported_signature_algorithms)) {
    ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
    OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
    return ssl_hs_error;
  }

  if (ca.present) {
    hs->ca_names = SSL_parse_CA_list(ssl, &alert, &ca.data);
    if (!hs->ca_names) {
      ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
      return ssl_hs_error;
    }
  } else {
    hs->ca_names.reset(sk_CRYPTO_BUFFER_new_null());
    if (!hs->ca_names) {
      ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
      return ssl_hs_error;
    }
  }

  hs->cert_request = true;
  ssl->ctx->x509_method->hs_flush_cached_ca_names(hs);

  if (!ssl_hash_message(hs, msg)) {
    return ssl_hs_error;
  }

  ssl->method->next_message(ssl);
  hs->tls13_state = state_read_server_certificate;
  return ssl_hs_ok;
}

static enum ssl_hs_wait_t do_read_server_certificate(SSL_HANDSHAKE *hs) {
  SSL *const ssl = hs->ssl;
  SSLMessage msg;
  if (!ssl->method->get_message(ssl, &msg)) {
    return ssl_hs_read_message;
  }

  if (msg.type != SSL3_MT_COMPRESSED_CERTIFICATE &&
      !ssl_check_message_type(ssl, msg, SSL3_MT_CERTIFICATE)) {
    return ssl_hs_error;
  }

  if (!tls13_process_certificate(hs, msg, false /* certificate required */) ||
      !ssl_hash_message(hs, msg)) {
    return ssl_hs_error;
  }

  ssl->method->next_message(ssl);
  hs->tls13_state = state_read_server_certificate_verify;
  return ssl_hs_ok;
}

static enum ssl_hs_wait_t do_read_server_certificate_verify(SSL_HANDSHAKE *hs) {
  SSL *const ssl = hs->ssl;
  SSLMessage msg;
  if (!ssl->method->get_message(ssl, &msg)) {
    return ssl_hs_read_message;
  }
  switch (ssl_verify_peer_cert(hs)) {
    case ssl_verify_ok:
      break;
    case ssl_verify_invalid:
      return ssl_hs_error;
    case ssl_verify_retry:
      hs->tls13_state = state_read_server_certificate_verify;
      return ssl_hs_certificate_verify;
  }

  if (!ssl_check_message_type(ssl, msg, SSL3_MT_CERTIFICATE_VERIFY) ||
      !tls13_process_certificate_verify(hs, msg) ||
      !ssl_hash_message(hs, msg)) {
    return ssl_hs_error;
  }

  ssl->method->next_message(ssl);
  hs->tls13_state = state_read_server_finished;
  return ssl_hs_ok;
}

static enum ssl_hs_wait_t do_server_certificate_reverify(SSL_HANDSHAKE *hs) {
  switch (ssl_reverify_peer_cert(hs, /*send_alert=*/true)) {
    case ssl_verify_ok:
      break;
    case ssl_verify_invalid:
      return ssl_hs_error;
    case ssl_verify_retry:
      hs->tls13_state = state_server_certificate_reverify;
      return ssl_hs_certificate_verify;
  }
  hs->tls13_state = state_read_server_finished;
  return ssl_hs_ok;
}

static enum ssl_hs_wait_t do_read_server_finished(SSL_HANDSHAKE *hs) {
  SSL *const ssl = hs->ssl;
  SSLMessage msg;
  if (!ssl->method->get_message(ssl, &msg)) {
    return ssl_hs_read_message;
  }
  if (!ssl_check_message_type(ssl, msg, SSL3_MT_FINISHED) ||
      !tls13_process_finished(hs, msg, false /* don't use saved value */) ||
      !ssl_hash_message(hs, msg) ||
      // Update the secret to the master secret and derive traffic keys.
      !tls13_advance_key_schedule(hs,
                                  Span(kZeroes, hs->transcript.DigestLen())) ||
      !tls13_derive_application_secrets(hs)) {
    return ssl_hs_error;
  }

  // Finished should be the end of the flight.
  if (ssl->method->has_unprocessed_handshake_data(ssl)) {
    ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
    OPENSSL_PUT_ERROR(SSL, SSL_R_EXCESS_HANDSHAKE_DATA);
    return ssl_hs_error;
  }

  ssl->method->next_message(ssl);
  hs->tls13_state = state_send_end_of_early_data;
  return ssl_hs_ok;
}

static enum ssl_hs_wait_t do_send_end_of_early_data(SSL_HANDSHAKE *hs) {
  SSL *const ssl = hs->ssl;

  if (ssl->s3->early_data_accepted) {
    // DTLS and QUIC omit the EndOfEarlyData message. See RFC 9001, section 8.3,
    // and RFC 9147, section 5.6.
    if (!SSL_is_quic(ssl) && !SSL_is_dtls(ssl)) {
      ScopedCBB cbb;
      CBB body;
      if (!ssl->method->init_message(ssl, cbb.get(), &body,
                                     SSL3_MT_END_OF_EARLY_DATA) ||
          !ssl_add_message_cbb(ssl, cbb.get())) {
        return ssl_hs_error;
      }
    }

    if (!close_early_data(hs, ssl_encryption_handshake)) {
      return ssl_hs_error;
    }
  }

  hs->tls13_state = state_send_client_encrypted_extensions;
  return ssl_hs_ok;
}

static enum ssl_hs_wait_t do_send_client_encrypted_extensions(
    SSL_HANDSHAKE *hs) {
  SSL *const ssl = hs->ssl;
  // For now, only one extension uses client EncryptedExtensions. This function
  // may be generalized if others use it in the future.
  if (hs->new_session->has_application_settings &&
      !ssl->s3->early_data_accepted) {
    ScopedCBB cbb;
    CBB body, extensions, extension;
    uint16_t extension_type = TLSEXT_TYPE_application_settings_old;
    if (hs->config->alps_use_new_codepoint) {
      extension_type = TLSEXT_TYPE_application_settings;
    }
    if (!ssl->method->init_message(ssl, cbb.get(), &body,
                                   SSL3_MT_ENCRYPTED_EXTENSIONS) ||
        !CBB_add_u16_length_prefixed(&body, &extensions) ||
        !CBB_add_u16(&extensions, extension_type) ||
        !CBB_add_u16_length_prefixed(&extensions, &extension) ||
        !CBB_add_bytes(&extension,
                       hs->new_session->local_application_settings.data(),
                       hs->new_session->local_application_settings.size()) ||
        !ssl_add_message_cbb(ssl, cbb.get())) {
      return ssl_hs_error;
    }
  }

  hs->tls13_state = state_send_client_certificate;
  return ssl_hs_ok;
}

static bool check_credential(SSL_HANDSHAKE *hs, const SSL_CREDENTIAL *cred,
                             uint16_t *out_sigalg) {
  if (cred->type != SSLCredentialType::kX509) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE);
    return false;
  }

  // All currently supported credentials require a signature.
  if (!tls1_choose_signature_algorithm(hs, cred, out_sigalg)) {
    return false;
  }
  // Use this credential if it either matches a requested issuer,
  // or does not require issuer matching.
  return ssl_credential_matches_requested_issuers(hs, cred);
}

static enum ssl_hs_wait_t do_send_client_certificate(SSL_HANDSHAKE *hs) {
  SSL *const ssl = hs->ssl;

  // The peer didn't request a certificate.
  if (!hs->cert_request) {
    hs->tls13_state = state_complete_second_flight;
    return ssl_hs_ok;
  }

  if (ssl->s3->ech_status == ssl_ech_rejected) {
    // Do not send client certificates on ECH reject. We have not authenticated
    // the server for the name that can learn the certificate.
    SSL_certs_clear(ssl);
  } else if (hs->config->cert->cert_cb != nullptr) {
    // Call cert_cb to update the certificate.
    int rv = hs->config->cert->cert_cb(ssl, hs->config->cert->cert_cb_arg);
    if (rv == 0) {
      ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
      OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_CB_ERROR);
      return ssl_hs_error;
    }
    if (rv < 0) {
      hs->tls13_state = state_send_client_certificate;
      return ssl_hs_x509_lookup;
    }
  }

  Array<SSL_CREDENTIAL *> creds;
  if (!ssl_get_full_credential_list(hs, &creds)) {
    return ssl_hs_error;
  }

  if (!creds.empty()) {
    // Select the credential to use.
    for (SSL_CREDENTIAL *cred : creds) {
      ERR_clear_error();
      uint16_t sigalg;
      if (check_credential(hs, cred, &sigalg)) {
        hs->credential = UpRef(cred);
        hs->signature_algorithm = sigalg;
        break;
      }
    }
    if (hs->credential == nullptr) {
      // The error from the last attempt is in the error queue.
      assert(ERR_peek_error() != 0);
      ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
      return ssl_hs_error;
    }
  }

  if (!tls13_add_certificate(hs)) {
    return ssl_hs_error;
  }

  hs->tls13_state = state_send_client_certificate_verify;
  return ssl_hs_ok;
}

static enum ssl_hs_wait_t do_send_client_certificate_verify(SSL_HANDSHAKE *hs) {
  // Don't send CertificateVerify if there is no certificate.
  if (hs->credential == nullptr) {
    hs->tls13_state = state_complete_second_flight;
    return ssl_hs_ok;
  }

  switch (tls13_add_certificate_verify(hs)) {
    case ssl_private_key_success:
      hs->tls13_state = state_complete_second_flight;
      return ssl_hs_ok;

    case ssl_private_key_retry:
      hs->tls13_state = state_send_client_certificate_verify;
      return ssl_hs_private_key_operation;

    case ssl_private_key_failure:
      return ssl_hs_error;
  }

  assert(0);
  return ssl_hs_error;
}

static enum ssl_hs_wait_t do_complete_second_flight(SSL_HANDSHAKE *hs) {
  SSL *const ssl = hs->ssl;
  hs->can_release_private_key = true;

  // Send a Channel ID assertion if necessary.
  if (hs->channel_id_negotiated) {
    ScopedCBB cbb;
    CBB body;
    if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_CHANNEL_ID) ||
        !tls1_write_channel_id(hs, &body) ||
        !ssl_add_message_cbb(ssl, cbb.get())) {
      return ssl_hs_error;
    }
  }

  // Send a Finished message.
  if (!tls13_add_finished(hs)) {
    return ssl_hs_error;
  }

  // Derive the final keys and enable them.
  if (!tls13_set_traffic_key(ssl, ssl_encryption_application, evp_aead_seal,
                             hs->new_session.get(),
                             hs->client_traffic_secret_0) ||
      !tls13_set_traffic_key(ssl, ssl_encryption_application, evp_aead_open,
                             hs->new_session.get(),
                             hs->server_traffic_secret_0) ||
      !tls13_derive_resumption_secret(hs)) {
    return ssl_hs_error;
  }

  hs->tls13_state = state_done;
  return ssl_hs_flush;
}

enum ssl_hs_wait_t tls13_client_handshake(SSL_HANDSHAKE *hs) {
  while (hs->tls13_state != state_done) {
    enum ssl_hs_wait_t ret = ssl_hs_error;
    enum client_hs_state_t state =
        static_cast<enum client_hs_state_t>(hs->tls13_state);
    switch (state) {
      case state_read_hello_retry_request:
        ret = do_read_hello_retry_request(hs);
        break;
      case state_send_second_client_hello:
        ret = do_send_second_client_hello(hs);
        break;
      case state_read_server_hello:
        ret = do_read_server_hello(hs);
        break;
      case state_read_encrypted_extensions:
        ret = do_read_encrypted_extensions(hs);
        break;
      case state_read_certificate_request:
        ret = do_read_certificate_request(hs);
        break;
      case state_read_server_certificate:
        ret = do_read_server_certificate(hs);
        break;
      case state_read_server_certificate_verify:
        ret = do_read_server_certificate_verify(hs);
        break;
      case state_server_certificate_reverify:
        ret = do_server_certificate_reverify(hs);
        break;
      case state_read_server_finished:
        ret = do_read_server_finished(hs);
        break;
      case state_send_end_of_early_data:
        ret = do_send_end_of_early_data(hs);
        break;
      case state_send_client_certificate:
        ret = do_send_client_certificate(hs);
        break;
      case state_send_client_encrypted_extensions:
        ret = do_send_client_encrypted_extensions(hs);
        break;
      case state_send_client_certificate_verify:
        ret = do_send_client_certificate_verify(hs);
        break;
      case state_complete_second_flight:
        ret = do_complete_second_flight(hs);
        break;
      case state_done:
        ret = ssl_hs_ok;
        break;
    }

    if (hs->tls13_state != state) {
      ssl_do_info_callback(hs->ssl, SSL_CB_CONNECT_LOOP, 1);
    }

    if (ret != ssl_hs_ok) {
      return ret;
    }
  }

  return ssl_hs_ok;
}

const char *tls13_client_handshake_state(SSL_HANDSHAKE *hs) {
  enum client_hs_state_t state =
      static_cast<enum client_hs_state_t>(hs->tls13_state);
  switch (state) {
    case state_read_hello_retry_request:
      return "TLS 1.3 client read_hello_retry_request";
    case state_send_second_client_hello:
      return "TLS 1.3 client send_second_client_hello";
    case state_read_server_hello:
      return "TLS 1.3 client read_server_hello";
    case state_read_encrypted_extensions:
      return "TLS 1.3 client read_encrypted_extensions";
    case state_read_certificate_request:
      return "TLS 1.3 client read_certificate_request";
    case state_read_server_certificate:
      return "TLS 1.3 client read_server_certificate";
    case state_read_server_certificate_verify:
      return "TLS 1.3 client read_server_certificate_verify";
    case state_server_certificate_reverify:
      return "TLS 1.3 client server_certificate_reverify";
    case state_read_server_finished:
      return "TLS 1.3 client read_server_finished";
    case state_send_end_of_early_data:
      return "TLS 1.3 client send_end_of_early_data";
    case state_send_client_encrypted_extensions:
      return "TLS 1.3 client send_client_encrypted_extensions";
    case state_send_client_certificate:
      return "TLS 1.3 client send_client_certificate";
    case state_send_client_certificate_verify:
      return "TLS 1.3 client send_client_certificate_verify";
    case state_complete_second_flight:
      return "TLS 1.3 client complete_second_flight";
    case state_done:
      return "TLS 1.3 client done";
  }

  return "TLS 1.3 client unknown";
}

bool tls13_process_new_session_ticket(SSL *ssl, const SSLMessage &msg) {
  if (ssl->s3->write_shutdown != ssl_shutdown_none) {
    // Ignore tickets on shutdown. Callers tend to indiscriminately call
    // |SSL_shutdown| before destroying an |SSL|, at which point calling the new
    // session callback may be confusing.
    return true;
  }

  CBS body = msg.body;
  UniquePtr<SSL_SESSION> session = tls13_create_session_with_ticket(ssl, &body);
  if (!session) {
    return false;
  }

  if ((ssl->session_ctx->session_cache_mode & SSL_SESS_CACHE_CLIENT) &&
      ssl->session_ctx->new_session_cb != NULL &&
      ssl->session_ctx->new_session_cb(ssl, session.get())) {
    // |new_session_cb|'s return value signals that it took ownership.
    session.release();
  }

  return true;
}

UniquePtr<SSL_SESSION> tls13_create_session_with_ticket(SSL *ssl, CBS *body) {
  UniquePtr<SSL_SESSION> session = SSL_SESSION_dup(
      ssl->s3->established_session.get(), SSL_SESSION_INCLUDE_NONAUTH);
  if (!session) {
    return nullptr;
  }

  ssl_session_rebase_time(ssl, session.get());

  uint32_t server_timeout;
  CBS ticket_nonce, ticket, extensions;
  if (!CBS_get_u32(body, &server_timeout) ||
      !CBS_get_u32(body, &session->ticket_age_add) ||
      !CBS_get_u8_length_prefixed(body, &ticket_nonce) ||
      !CBS_get_u16_length_prefixed(body, &ticket) ||
      CBS_len(&ticket) == 0 ||  //
      !session->ticket.CopyFrom(ticket) ||
      !CBS_get_u16_length_prefixed(body, &extensions) ||  //
      CBS_len(body) != 0) {
    ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
    OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
    return nullptr;
  }

  // Cap the renewable lifetime by the server advertised value. This avoids
  // wasting bandwidth on 0-RTT when we know the server will reject it.
  if (session->timeout > server_timeout) {
    session->timeout = server_timeout;
  }

  if (!tls13_derive_session_psk(session.get(), ticket_nonce,
                                SSL_is_dtls(ssl))) {
    return nullptr;
  }

  SSLExtension early_data(TLSEXT_TYPE_early_data);
  uint8_t alert = SSL_AD_DECODE_ERROR;
  if (!ssl_parse_extensions(&extensions, &alert, {&early_data},
                            /*ignore_unknown=*/true)) {
    ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
    return nullptr;
  }

  if (early_data.present) {
    if (!CBS_get_u32(&early_data.data, &session->ticket_max_early_data) ||
        CBS_len(&early_data.data) != 0) {
      ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
      OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
      return nullptr;
    }

    // QUIC does not use the max_early_data_size parameter and always sets it to
    // a fixed value. See RFC 9001, section 4.6.1.
    if (SSL_is_quic(ssl) && session->ticket_max_early_data != 0xffffffff) {
      ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
      OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
      return nullptr;
    }
  }

  // Historically, OpenSSL filled in fake session IDs for ticket-based sessions.
  // Envoy's tests depend on this, although perhaps they shouldn't.
  session->session_id.ResizeForOverwrite(SHA256_DIGEST_LENGTH);
  SHA256(CBS_data(&ticket), CBS_len(&ticket), session->session_id.data());

  session->ticket_age_add_valid = true;
  session->not_resumable = false;

  return session;
}

BSSL_NAMESPACE_END
