// 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 <algorithm>
#include <utility>

#include <openssl/bytestring.h>
#include <openssl/digest.h>
#include <openssl/err.h>
#include <openssl/mem.h>
#include <openssl/sha2.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) {
  SSLImpl *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) {
  SSLImpl *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),
      // If offering PAKE, we won't send key_share extensions and we should
      // reject key_share from the peer. Otherwise, it is valid to have sent an
      // empty key_share extension, and expect the HelloRetryRequest to contain
      // a key_share.
      key_share(TLSEXT_TYPE_key_share, !hs->pake_prover),
      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) {
    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 (std::find_if(hs->key_shares.begin(), hs->key_shares.end(),
                     [group_id](const auto &hs_key_share) {
                       return hs_key_share->GroupID() == group_id;
                     }) != hs->key_shares.end()) {
      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;
  }

  // Per RFC 8446 section 4.1.4, skip any PSKs whose hash does not match the
  // selected cipher. This avoids performing the transcript hash transformation
  // for multiple hashes.
  const EVP_MD *cipher_md = SSL_CIPHER_get_handshake_digest(cipher);
  hs->pre_shared_keys.EraseIf([=](const SSLPreSharedKey &psk) {
    return ssl_pre_shared_key_hash(psk) != cipher_md;
  });

  // 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 bool check_session(const SSL_HANDSHAKE *hs, uint8_t *out_alert,
                          const SSL_SESSION *session) {
  const SSLImpl *const ssl = hs->ssl;
  if (session->ssl_version != ssl->s3->version) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_OLD_SESSION_VERSION_NOT_RETURNED);
    *out_alert = SSL_AD_ILLEGAL_PARAMETER;
    return false;
  }

  if (session->cipher->algorithm_prf != hs->new_cipher->algorithm_prf) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_OLD_SESSION_PRF_HASH_MISMATCH);
    *out_alert = SSL_AD_ILLEGAL_PARAMETER;
    return false;
  }

  if (!ssl_session_is_context_valid(hs, session)) {
    // This is actually a client application bug.
    OPENSSL_PUT_ERROR(SSL, SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT);
    *out_alert = SSL_AD_ILLEGAL_PARAMETER;
    return false;
  }
  return true;
}

static bool check_imported_psk(const SSL_HANDSHAKE *hs, uint8_t *out_alert,
                               const SSLImportedPSK &imported) {
  const SSLImpl *const ssl = hs->ssl;
  const EVP_MD *md =
      ssl_get_handshake_digest(ssl_protocol_version(ssl), hs->new_cipher);
  if (imported.md != md || imported.protocol != ssl->s3->version) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_PSK_FOR_CONNECTION);
    *out_alert = SSL_AD_ILLEGAL_PARAMETER;
    return false;
  }
  return true;
}

static bool using_certificate(const SSL_HANDSHAKE *hs) {
  const SSLImpl *const ssl = hs->ssl;
  // Resumption is not a certificate-based handshake.
  if (ssl->s3->session_reused) {
    return false;
  }
  // Non-private-key credentials imply a non-certificate handshake (PSK, etc.).
  if (hs->credential != nullptr && !hs->credential->UsesPrivateKey()) {
    return false;
  }
  return true;
}

static enum ssl_hs_wait_t do_read_server_hello(SSL_HANDSHAKE *hs) {
  SSLImpl *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, pre-shared keys are only offered in ClientHelloInner.
  const bool pre_shared_key_allowed =
      !hs->pre_shared_keys.empty() && ssl->s3->ech_status != ssl_ech_rejected;
  SSLExtension key_share(TLSEXT_TYPE_key_share, !hs->key_shares.empty()),
      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.

  // If the server specified no alternative authentication mode, it is using
  // certificate authentication. Check that this is acceptable.
  if (!pake_share.present && !pre_shared_key.present &&
      !ssl_accepts_server_certificate_auth(hs)) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_EXTENSION);
    ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_MISSING_EXTENSION);
    return ssl_hs_error;
  }
  // 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 implies 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));

  // Determine the PSK used.
  const EVP_MD *cipher_md =
      ssl_get_handshake_digest(ssl_protocol_version(ssl), hs->new_cipher);
  Span<const uint8_t> psk_secret = Span(kZeroes, EVP_MD_size(cipher_md));
  alert = SSL_AD_DECODE_ERROR;
  if (pre_shared_key.present) {
    const SSLPreSharedKey *psk = ssl_ext_pre_shared_key_parse_serverhello(
        hs, &alert, &pre_shared_key.data);
    if (psk == nullptr) {
      ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
      return ssl_hs_error;
    }

    if (const auto *imported = std::get_if<SSLImportedPSK>(psk);
        imported != nullptr) {
      if (!check_imported_psk(hs, &alert, *imported)) {
        ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
        return ssl_hs_error;
      }

      psk_secret = imported->ipskx;
      hs->credential = UpRef(imported->credential);
      if (!ssl_get_new_session(hs)) {
        ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
        return ssl_hs_error;
      }
    } else {
      const SSL_SESSION *session = std::get<UniquePtr<SSL_SESSION>>(*psk).get();
      assert(session == ssl->session.get());
      if (!check_session(hs, &alert, session)) {
        ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
        return ssl_hs_error;
      }

      psk_secret = session->secret;
      ssl->s3->session_reused = true;
      // Only authentication information carries over in TLS 1.3.
      hs->new_session = SSL_SESSION_dup(session, 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, nullptr);

      // 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;
  hs->can_release_private_key = !using_certificate(hs);
  assert(!using_certificate(hs) || ssl_accepts_server_certificate_auth(hs));

  // Set up the key schedule and incorporate the PSK into the running secret.
  if (!tls13_init_key_schedule(hs, psk_secret)) {
    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) {
  SSLImpl *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) {
  SSLImpl *const ssl = hs->ssl;
  // CertificateRequest may only be sent in certificate-based handshakes.
  if (!using_certificate(hs)) {
    if (ssl->s3->session_reused && 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;
  }

  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 || sk_CRYPTO_BUFFER_num(hs->ca_names.get()) == 0 ||
        CBS_len(&ca.data) != 0) {
      OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_PARSING_EXTENSION);
      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) {
  SSLImpl *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) {
  SSLImpl *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) {
  SSLImpl *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) {
  SSLImpl *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) {
  SSLImpl *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 SSLCredential *cred,
                             uint16_t *out_sigalg) {
  bool cert_type_ok = false;
  if (hs->client_cert_type == TLSEXT_cert_type_x509) {
    cert_type_ok = cred->type == SSLCredentialType::kX509;
  } else if (hs->client_cert_type == TLSEXT_cert_type_rpk) {
    cert_type_ok = cred->type == SSLCredentialType::kRawPublicKey;
  }
  if (!cert_type_ok) {
    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) {
  SSLImpl *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<SSLCredential *> creds;
  if (!ssl_get_full_credential_list(hs, &creds)) {
    return ssl_hs_error;
  }

  // Select the credential, if any, to use.
  bool may_proceed_anonymously = true;
  for (SSLCredential *cred : creds) {
    if (!cred->UsesPrivateKey()) {
      // Non-certificate credentials (e.g. PSKs) do not participate in deciding
      // whether to error or proceed anonymously.
      continue;
    }

    ERR_clear_error();
    may_proceed_anonymously = false;
    uint16_t sigalg;
    if (check_credential(hs, cred, &sigalg)) {
      hs->credential = UpRef(cred);
      hs->signature_algorithm = sigalg;
      break;
    }
  }

  // Fail the connection if no credentials matched, but only if the caller
  // configured at least one certificate credential. If there were no
  // candidates, proceed anonymously.
  if (!may_proceed_anonymously && 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) {
  SSLImpl *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(SSLImpl *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 != nullptr &&
      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(SSLImpl *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);
  SSLExtension flags(TLSEXT_TYPE_tls_flags);
  uint8_t alert = SSL_AD_DECODE_ERROR;
  if (!ssl_parse_extensions(&extensions, &alert, {&early_data, &flags},
                            /*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;
    }
  }

  if (flags.present) {
    SSLFlags parsed;
    if (!ssl_parse_flags_extension_request(&flags.data, &parsed, &alert)) {
      ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
      return nullptr;
    }
    if (parsed & kSSLFlagResumptionAcrossNames) {
      session->is_resumable_across_names = true;
    }
  }

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