// Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
// Copyright (c) 2002, Oracle and/or its affiliates. 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 <utility>

#include <openssl/rand.h>

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


BSSL_NAMESPACE_BEGIN

SSL_HANDSHAKE::SSL_HANDSHAKE(SSL *ssl_arg)
    : ssl(ssl_arg),
      transcript(SSL_is_dtls(ssl_arg)),
      inner_transcript(SSL_is_dtls(ssl_arg)),
      ech_is_inner(false),
      ech_authenticated_reject(false),
      scts_requested(false),
      handshake_finalized(false),
      accept_psk_mode(false),
      cert_request(false),
      certificate_status_expected(false),
      ocsp_stapling_requested(false),
      should_ack_sni(false),
      in_false_start(false),
      in_early_data(false),
      early_data_offered(false),
      can_early_read(false),
      can_early_write(false),
      is_early_version(false),
      next_proto_neg_seen(false),
      ticket_expected(false),
      extended_master_secret(false),
      pending_private_key_op(false),
      handback(false),
      hints_requested(false),
      cert_compression_negotiated(false),
      apply_jdk11_workaround(false),
      can_release_private_key(false),
      channel_id_negotiated(false),
      received_hello_verify_request(false),
      matched_peer_trust_anchor(false),
      peer_matched_trust_anchor(false) {
  assert(ssl);

  // Draw entropy for all GREASE values at once. This avoids calling
  // |RAND_bytes| repeatedly and makes the values consistent within a
  // connection. The latter is so the second ClientHello matches after
  // HelloRetryRequest and so supported_groups and key_shares are consistent.
  RAND_bytes(grease_seed, sizeof(grease_seed));
}

SSL_HANDSHAKE::~SSL_HANDSHAKE() {
  ssl->ctx->x509_method->hs_flush_cached_ca_names(this);
}

bool SSL_HANDSHAKE::GetClientHello(SSLMessage *out_msg,
                                   SSL_CLIENT_HELLO *out_client_hello) {
  if (!ech_client_hello_buf.empty()) {
    // If the backing buffer is non-empty, the ClientHelloInner has been set.
    out_msg->is_v2_hello = false;
    out_msg->type = SSL3_MT_CLIENT_HELLO;
    out_msg->raw = CBS(ech_client_hello_buf);
    size_t header_len =
        SSL_is_dtls(ssl) ? DTLS1_HM_HEADER_LENGTH : SSL3_HM_HEADER_LENGTH;
    out_msg->body = CBS(Span(ech_client_hello_buf).subspan(header_len));
  } else if (!ssl->method->get_message(ssl, out_msg)) {
    // The message has already been read, so this cannot fail.
    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
    return false;
  }

  if (!SSL_parse_client_hello(ssl, out_client_hello, CBS_data(&out_msg->body),
                              CBS_len(&out_msg->body))) {
    ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
    return false;
  }
  return true;
}

UniquePtr<SSL_HANDSHAKE> ssl_handshake_new(SSL *ssl) {
  UniquePtr<SSL_HANDSHAKE> hs = MakeUnique<SSL_HANDSHAKE>(ssl);
  if (!hs || !hs->transcript.Init()) {
    return nullptr;
  }
  hs->config = ssl->config.get();
  if (!hs->config) {
    assert(hs->config);
    return nullptr;
  }
  return hs;
}

bool ssl_check_message_type(SSL *ssl, const SSLMessage &msg, int type) {
  if (msg.type != type) {
    ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
    OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE);
    ERR_add_error_dataf("got type %d, wanted type %d", msg.type, type);
    return false;
  }

  return true;
}

bool ssl_add_message_cbb(SSL *ssl, CBB *cbb) {
  Array<uint8_t> msg;
  if (!ssl->method->finish_message(ssl, cbb, &msg) ||
      !ssl->method->add_message(ssl, std::move(msg))) {
    return false;
  }

  return true;
}

size_t ssl_max_handshake_message_len(const SSL *ssl) {
  // kMaxMessageLen is the default maximum message size for handshakes which do
  // not accept peer certificate chains.
  static const size_t kMaxMessageLen = 16384;

  if (SSL_in_init(ssl)) {
    SSL_CONFIG *config = ssl->config.get();  // SSL_in_init() implies not NULL.
    if ((!ssl->server || (config->verify_mode & SSL_VERIFY_PEER)) &&
        kMaxMessageLen < ssl->max_cert_list) {
      return ssl->max_cert_list;
    }
    return kMaxMessageLen;
  }

  if (ssl_protocol_version(ssl) < TLS1_3_VERSION) {
    // In TLS 1.2 and below, the largest acceptable post-handshake message is
    // a HelloRequest.
    return 0;
  }

  if (ssl->server) {
    // The largest acceptable post-handshake message for a server is a
    // KeyUpdate. We will never initiate post-handshake auth.
    return 1;
  }

  // Clients must accept NewSessionTicket, so allow the default size.
  return kMaxMessageLen;
}

bool ssl_hash_message(SSL_HANDSHAKE *hs, const SSLMessage &msg) {
  // V2ClientHello messages are pre-hashed.
  if (msg.is_v2_hello) {
    return true;
  }

  return hs->transcript.Update(msg.raw);
}

bool ssl_parse_extensions(const CBS *cbs, uint8_t *out_alert,
                          std::initializer_list<SSLExtension *> extensions,
                          bool ignore_unknown) {
  // Reset everything.
  for (SSLExtension *ext : extensions) {
    ext->present = false;
    CBS_init(&ext->data, nullptr, 0);
    if (!ext->allowed) {
      assert(!ignore_unknown);
    }
  }

  CBS copy = *cbs;
  while (CBS_len(&copy) != 0) {
    uint16_t type;
    CBS data;
    if (!CBS_get_u16(&copy, &type) ||
        !CBS_get_u16_length_prefixed(&copy, &data)) {
      OPENSSL_PUT_ERROR(SSL, SSL_R_PARSE_TLSEXT);
      *out_alert = SSL_AD_DECODE_ERROR;
      return false;
    }

    SSLExtension *found = nullptr;
    for (SSLExtension *ext : extensions) {
      if (type == ext->type && ext->allowed) {
        found = ext;
        break;
      }
    }

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

    // Duplicate ext_types are forbidden.
    if (found->present) {
      OPENSSL_PUT_ERROR(SSL, SSL_R_DUPLICATE_EXTENSION);
      *out_alert = SSL_AD_ILLEGAL_PARAMETER;
      return false;
    }

    found->present = true;
    found->data = data;
  }

  return true;
}

enum ssl_verify_result_t ssl_verify_peer_cert(SSL_HANDSHAKE *hs) {
  SSL *const ssl = hs->ssl;
  const SSL_SESSION *prev_session = ssl->s3->established_session.get();
  if (prev_session != NULL) {
    // If renegotiating, the server must not change the server certificate. See
    // https://mitls.org/pages/attacks/3SHAKE. We never resume on renegotiation,
    // so this check is sufficient to ensure the reported peer certificate never
    // changes on renegotiation.
    assert(!ssl->server);
    if (sk_CRYPTO_BUFFER_num(prev_session->certs.get()) !=
        sk_CRYPTO_BUFFER_num(hs->new_session->certs.get())) {
      OPENSSL_PUT_ERROR(SSL, SSL_R_SERVER_CERT_CHANGED);
      ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
      return ssl_verify_invalid;
    }

    for (size_t i = 0; i < sk_CRYPTO_BUFFER_num(hs->new_session->certs.get());
         i++) {
      const CRYPTO_BUFFER *old_cert =
          sk_CRYPTO_BUFFER_value(prev_session->certs.get(), i);
      const CRYPTO_BUFFER *new_cert =
          sk_CRYPTO_BUFFER_value(hs->new_session->certs.get(), i);
      if (Span(CRYPTO_BUFFER_data(old_cert), CRYPTO_BUFFER_len(old_cert)) !=
          Span(CRYPTO_BUFFER_data(new_cert), CRYPTO_BUFFER_len(new_cert))) {
        OPENSSL_PUT_ERROR(SSL, SSL_R_SERVER_CERT_CHANGED);
        ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
        return ssl_verify_invalid;
      }
    }

    // The certificate is identical, so we may skip re-verifying the
    // certificate. Since we only authenticated the previous one, copy other
    // authentication from the established session and ignore what was newly
    // received.
    hs->new_session->ocsp_response = UpRef(prev_session->ocsp_response);
    hs->new_session->signed_cert_timestamp_list =
        UpRef(prev_session->signed_cert_timestamp_list);
    hs->new_session->verify_result = prev_session->verify_result;
    return ssl_verify_ok;
  }

  uint8_t alert = SSL_AD_CERTIFICATE_UNKNOWN;
  enum ssl_verify_result_t ret;
  if (hs->config->custom_verify_callback != nullptr) {
    ret = hs->config->custom_verify_callback(ssl, &alert);
    switch (ret) {
      case ssl_verify_ok:
        hs->new_session->verify_result = X509_V_OK;
        break;
      case ssl_verify_invalid:
        // If |SSL_VERIFY_NONE|, the error is non-fatal, but we keep the result.
        if (hs->config->verify_mode == SSL_VERIFY_NONE) {
          ERR_clear_error();
          ret = ssl_verify_ok;
        }
        hs->new_session->verify_result = X509_V_ERR_APPLICATION_VERIFICATION;
        break;
      case ssl_verify_retry:
        break;
    }
  } else {
    ret = ssl->ctx->x509_method->session_verify_cert_chain(
              hs->new_session.get(), hs, &alert)
              ? ssl_verify_ok
              : ssl_verify_invalid;
  }

  if (ret == ssl_verify_invalid) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_CERTIFICATE_VERIFY_FAILED);
    ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
  }

  // Emulate OpenSSL's client OCSP callback. OpenSSL verifies certificates
  // before it receives the OCSP, so it needs a second callback for OCSP.
  if (ret == ssl_verify_ok && !ssl->server &&
      hs->config->ocsp_stapling_enabled &&
      ssl->ctx->legacy_ocsp_callback != nullptr) {
    int cb_ret =
        ssl->ctx->legacy_ocsp_callback(ssl, ssl->ctx->legacy_ocsp_callback_arg);
    if (cb_ret <= 0) {
      OPENSSL_PUT_ERROR(SSL, SSL_R_OCSP_CB_ERROR);
      ssl_send_alert(ssl, SSL3_AL_FATAL,
                     cb_ret == 0 ? SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE
                                 : SSL_AD_INTERNAL_ERROR);
      ret = ssl_verify_invalid;
    }
  }

  return ret;
}

// Verifies a stored certificate when resuming a session. A few things are
// different from verify_peer_cert:
// 1. We can't be renegotiating if we're resuming a session.
// 2. The session is immutable, so we don't support verify_mode ==
// SSL_VERIFY_NONE
// 3. We don't call the OCSP callback.
// 4. We only support custom verify callbacks.
enum ssl_verify_result_t ssl_reverify_peer_cert(SSL_HANDSHAKE *hs,
                                                bool send_alert) {
  SSL *const ssl = hs->ssl;
  assert(ssl->s3->established_session == nullptr);
  assert(hs->config->verify_mode != SSL_VERIFY_NONE);

  uint8_t alert = SSL_AD_CERTIFICATE_UNKNOWN;
  enum ssl_verify_result_t ret = ssl_verify_invalid;
  if (hs->config->custom_verify_callback != nullptr) {
    ret = hs->config->custom_verify_callback(ssl, &alert);
  }

  if (ret == ssl_verify_invalid) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_CERTIFICATE_VERIFY_FAILED);
    if (send_alert) {
      ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
    }
  }

  return ret;
}

static uint16_t grease_index_to_value(const SSL_HANDSHAKE *hs,
                                      enum ssl_grease_index_t index) {
  // This generates a random value of the form 0xωaωa, for all 0 ≤ ω < 16.
  uint16_t ret = hs->grease_seed[index];
  ret = (ret & 0xf0) | 0x0a;
  ret |= ret << 8;
  return ret;
}

uint16_t ssl_get_grease_value(const SSL_HANDSHAKE *hs,
                              enum ssl_grease_index_t index) {
  uint16_t ret = grease_index_to_value(hs, index);
  if (index == ssl_grease_extension2 &&
      ret == grease_index_to_value(hs, ssl_grease_extension1)) {
    // The two fake extensions must not have the same value. GREASE values are
    // of the form 0x1a1a, 0x2a2a, 0x3a3a, etc., so XOR to generate a different
    // one.
    ret ^= 0x1010;
  }
  return ret;
}

enum ssl_hs_wait_t ssl_get_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)) {
    return ssl_hs_error;
  }

  // Snapshot the finished hash before incorporating the new message.
  uint8_t finished[EVP_MAX_MD_SIZE];
  size_t finished_len;
  if (!hs->transcript.GetFinishedMAC(finished, &finished_len,
                                     ssl_handshake_session(hs), !ssl->server) ||
      !ssl_hash_message(hs, msg)) {
    return ssl_hs_error;
  }

  int finished_ok = CBS_mem_equal(&msg.body, finished, finished_len);
#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
  finished_ok = 1;
#endif
  if (!finished_ok) {
    ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR);
    OPENSSL_PUT_ERROR(SSL, SSL_R_DIGEST_CHECK_FAILED);
    return ssl_hs_error;
  }

  // Copy the Finished so we can use it for renegotiation checks.
  if (finished_len > ssl->s3->previous_client_finished.capacity() ||
      finished_len > ssl->s3->previous_server_finished.capacity()) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
    return ssl_hs_error;
  }

  if (ssl->server) {
    ssl->s3->previous_client_finished.CopyFrom(Span(finished, finished_len));
  } else {
    ssl->s3->previous_server_finished.CopyFrom(Span(finished, finished_len));
  }

  // The Finished message should be the end of a 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);
  return ssl_hs_ok;
}

bool ssl_send_finished(SSL_HANDSHAKE *hs) {
  SSL *const ssl = hs->ssl;
  const SSL_SESSION *session = ssl_handshake_session(hs);

  uint8_t finished_buf[EVP_MAX_MD_SIZE];
  size_t finished_len;
  if (!hs->transcript.GetFinishedMAC(finished_buf, &finished_len, session,
                                     ssl->server)) {
    return false;
  }
  auto finished = Span(finished_buf, finished_len);

  // Log the master secret, if logging is enabled.
  if (!ssl_log_secret(ssl, "CLIENT_RANDOM", session->secret)) {
    return false;
  }

  // Copy the Finished so we can use it for renegotiation checks.
  bool ok = ssl->server
                ? ssl->s3->previous_server_finished.TryCopyFrom(finished)
                : ssl->s3->previous_client_finished.TryCopyFrom(finished);
  if (!ok) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
    return ssl_hs_error;
  }

  ScopedCBB cbb;
  CBB body;
  if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_FINISHED) ||
      !CBB_add_bytes(&body, finished.data(), finished.size()) ||
      !ssl_add_message_cbb(ssl, cbb.get())) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
    return false;
  }

  return true;
}

bool ssl_send_tls12_certificate(SSL_HANDSHAKE *hs) {
  ScopedCBB cbb;
  CBB body, certs, cert;
  if (!hs->ssl->method->init_message(hs->ssl, cbb.get(), &body,
                                     SSL3_MT_CERTIFICATE) ||
      !CBB_add_u24_length_prefixed(&body, &certs)) {
    return false;
  }

  if (hs->credential != nullptr) {
    assert(hs->credential->type == SSLCredentialType::kX509);
    STACK_OF(CRYPTO_BUFFER) *chain = hs->credential->chain.get();
    for (size_t i = 0; i < sk_CRYPTO_BUFFER_num(chain); i++) {
      CRYPTO_BUFFER *buffer = sk_CRYPTO_BUFFER_value(chain, i);
      if (!CBB_add_u24_length_prefixed(&certs, &cert) ||
          !CBB_add_bytes(&cert, CRYPTO_BUFFER_data(buffer),
                         CRYPTO_BUFFER_len(buffer))) {
        return false;
      }
    }
  }

  return ssl_add_message_cbb(hs->ssl, cbb.get());
}

const SSL_SESSION *ssl_handshake_session(const SSL_HANDSHAKE *hs) {
  if (hs->new_session) {
    return hs->new_session.get();
  }
  return hs->ssl->session.get();
}

int ssl_run_handshake(SSL_HANDSHAKE *hs, bool *out_early_return) {
  SSL *const ssl = hs->ssl;
  for (;;) {
    // If a timeout during the handshake triggered a DTLS ACK or retransmit, we
    // resolve that first. E.g., if |ssl_hs_private_key_operation| is slow, the
    // ACK timer may fire.
    if (hs->wait != ssl_hs_error && SSL_is_dtls(ssl)) {
      int ret = ssl->method->flush(ssl);
      if (ret <= 0) {
        return ret;
      }
    }

    // Resolve the operation the handshake was waiting on. Each condition may
    // halt the handshake by returning, or continue executing if the handshake
    // may immediately proceed. Cases which halt the handshake can clear
    // |hs->wait| to re-enter the state machine on the next iteration, or leave
    // it set to keep the condition sticky.
    switch (hs->wait) {
      case ssl_hs_error:
        ERR_restore_state(hs->error.get());
        return -1;

      case ssl_hs_flush: {
        int ret = ssl->method->flush(ssl);
        if (ret <= 0) {
          return ret;
        }
        break;
      }

      case ssl_hs_read_server_hello:
      case ssl_hs_read_message:
      case ssl_hs_read_change_cipher_spec: {
        if (SSL_is_quic(ssl)) {
          // QUIC has no ChangeCipherSpec messages.
          assert(hs->wait != ssl_hs_read_change_cipher_spec);
          // The caller should call |SSL_provide_quic_data|. Clear |hs->wait| so
          // the handshake can check if there is sufficient data next iteration.
          ssl->s3->rwstate = SSL_ERROR_WANT_READ;
          hs->wait = ssl_hs_ok;
          return -1;
        }

        uint8_t alert = SSL_AD_DECODE_ERROR;
        size_t consumed = 0;
        ssl_open_record_t ret;
        if (hs->wait == ssl_hs_read_change_cipher_spec) {
          ret = ssl_open_change_cipher_spec(ssl, &consumed, &alert,
                                            ssl->s3->read_buffer.span());
        } else {
          ret = ssl_open_handshake(ssl, &consumed, &alert,
                                   ssl->s3->read_buffer.span());
        }
        if (ret == ssl_open_record_error &&
            hs->wait == ssl_hs_read_server_hello) {
          uint32_t err = ERR_peek_error();
          if (ERR_GET_LIB(err) == ERR_LIB_SSL &&
              ERR_GET_REASON(err) == SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE) {
            // Add a dedicated error code to the queue for a handshake_failure
            // alert in response to ClientHello. This matches NSS's client
            // behavior and gives a better error on a (probable) failure to
            // negotiate initial parameters. Note: this error code comes after
            // the original one.
            //
            // See https://crbug.com/446505.
            OPENSSL_PUT_ERROR(SSL, SSL_R_HANDSHAKE_FAILURE_ON_CLIENT_HELLO);
          }
        }
        bool retry;
        int bio_ret = ssl_handle_open_record(ssl, &retry, ret, consumed, alert);
        if (bio_ret <= 0) {
          return bio_ret;
        }
        if (retry) {
          continue;
        }
        ssl->s3->read_buffer.DiscardConsumed();
        break;
      }

      case ssl_hs_read_end_of_early_data: {
        if (ssl->s3->hs->can_early_read) {
          // While we are processing early data, the handshake returns early.
          *out_early_return = true;
          return 1;
        }
        hs->wait = ssl_hs_ok;
        break;
      }

      case ssl_hs_certificate_selection_pending:
        ssl->s3->rwstate = SSL_ERROR_PENDING_CERTIFICATE;
        hs->wait = ssl_hs_ok;
        return -1;

      case ssl_hs_handoff:
        ssl->s3->rwstate = SSL_ERROR_HANDOFF;
        hs->wait = ssl_hs_ok;
        return -1;

      case ssl_hs_handback: {
        int ret = ssl->method->flush(ssl);
        if (ret <= 0) {
          return ret;
        }
        ssl->s3->rwstate = SSL_ERROR_HANDBACK;
        hs->wait = ssl_hs_handback;
        return -1;
      }

        // The following cases are associated with callback APIs which expect to
        // be called each time the state machine runs. Thus they set |hs->wait|
        // to |ssl_hs_ok| so that, next time, we re-enter the state machine and
        // call the callback again.
      case ssl_hs_x509_lookup:
        ssl->s3->rwstate = SSL_ERROR_WANT_X509_LOOKUP;
        hs->wait = ssl_hs_ok;
        return -1;
      case ssl_hs_private_key_operation:
        ssl->s3->rwstate = SSL_ERROR_WANT_PRIVATE_KEY_OPERATION;
        hs->wait = ssl_hs_ok;
        return -1;
      case ssl_hs_pending_session:
        ssl->s3->rwstate = SSL_ERROR_PENDING_SESSION;
        hs->wait = ssl_hs_ok;
        return -1;
      case ssl_hs_pending_ticket:
        ssl->s3->rwstate = SSL_ERROR_PENDING_TICKET;
        hs->wait = ssl_hs_ok;
        return -1;
      case ssl_hs_certificate_verify:
        ssl->s3->rwstate = SSL_ERROR_WANT_CERTIFICATE_VERIFY;
        hs->wait = ssl_hs_ok;
        return -1;

      case ssl_hs_early_data_rejected:
        assert(ssl->s3->early_data_reason != ssl_early_data_unknown);
        assert(!hs->can_early_write);
        ssl->s3->rwstate = SSL_ERROR_EARLY_DATA_REJECTED;
        return -1;

      case ssl_hs_early_return:
        if (!ssl->server) {
          // On ECH reject, the handshake should never complete.
          assert(ssl->s3->ech_status != ssl_ech_rejected);
        }
        *out_early_return = true;
        hs->wait = ssl_hs_ok;
        return 1;

      case ssl_hs_hints_ready:
        ssl->s3->rwstate = SSL_ERROR_HANDSHAKE_HINTS_READY;
        return -1;

      case ssl_hs_ok:
        break;
    }

    // Run the state machine again.
    hs->wait = ssl->do_handshake(hs);
    if (hs->wait == ssl_hs_error) {
      hs->error.reset(ERR_save_state());
      return -1;
    }
    if (hs->wait == ssl_hs_ok) {
      if (!ssl->server) {
        // On ECH reject, the handshake should never complete.
        assert(ssl->s3->ech_status != ssl_ech_rejected);
      }
      // The handshake has completed.
      *out_early_return = false;
      return 1;
    }
    // If the handshake returns |ssl_hs_flush|, implicitly finish the flight.
    // This is a convenience so we do not need to manually insert this
    // throughout the handshake.
    if (hs->wait == ssl_hs_flush) {
      ssl->method->finish_flight(ssl);
    }

    // Loop to the beginning and resolve what was blocking the handshake.
  }
}

BSSL_NAMESPACE_END
