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

#ifndef OPENSSL_HEADER_SSL_INTERNAL_H
#define OPENSSL_HEADER_SSL_INTERNAL_H

#include <openssl/base.h>

#include <stdlib.h>

#include <algorithm>
#include <atomic>
#include <bitset>
#include <cstdint>
#include <initializer_list>
#include <limits>
#include <new>
#include <optional>
#include <string_view>
#include <type_traits>
#include <utility>
#include <variant>

#include <openssl/aead.h>
#include <openssl/curve25519.h>
#include <openssl/err.h>
#include <openssl/hpke.h>
#include <openssl/mem.h>
#include <openssl/span.h>
#include <openssl/ssl.h>
#include <openssl/stack.h>

#include "../crypto/err/internal.h"
#include "../crypto/internal.h"
#include "../crypto/lhash/internal.h"
#include "../crypto/mem_internal.h"
#include "../crypto/spake2plus/internal.h"

#if defined(OPENSSL_WINDOWS)
// Windows defines struct timeval in winsock2.h.
#include <winsock2.h>
#else
#include <sys/time.h>
#endif


DECLARE_OPAQUE_STRUCT(ssl_credential_st, SSLCredential)
DECLARE_OPAQUE_STRUCT(ssl_ctx_st, SSLContext)
DECLARE_OPAQUE_STRUCT(ssl_st, SSLImpl)
DECLARE_OPAQUE_STRUCT(ssl_ech_keys_st, SSLECHKeys)

BSSL_NAMESPACE_BEGIN

struct SSL_CONFIG;
struct SSL_HANDSHAKE;
struct SSL_PROTOCOL_METHOD;
struct SSL_X509_METHOD;

// C++ utilities.

// An MRUQueue maintains a queue of up to `N` objects of type `T`. If the queue
// is at capacity, adding to the queue pops the least recently added element.
template <typename T, size_t N>
class MRUQueue {
 public:
  static constexpr bool kAllowUniquePtr = true;

  MRUQueue() = default;

  // If we ever need to make this type movable, we could. (The defaults almost
  // work except we need `start_` to be reset when moved-from.)
  MRUQueue(const MRUQueue &other) = delete;
  MRUQueue &operator=(const MRUQueue &other) = delete;

  bool empty() const { return size() == 0; }
  size_t size() const { return storage_.size(); }

  T &operator[](size_t i) {
    BSSL_CHECK(i < size());
    return storage_[(start_ + i) % N];
  }
  const T &operator[](size_t i) const {
    return (*const_cast<MRUQueue *>(this))[i];
  }

  void Clear() {
    storage_.clear();
    start_ = 0;
  }

  void PushBack(T t) {
    if (storage_.size() < N) {
      assert(start_ == 0);
      storage_.PushBack(std::move(t));
    } else {
      (*this)[0] = std::move(t);
      start_ = (start_ + 1) % N;
    }
  }

 private:
  InplaceVector<T, N> storage_;
  PackedSize<N> start_ = 0;
};

// GetAllNames helps to implement `*_get_all_*_names` style functions. It
// writes at most `max_out` string pointers to `out` and returns the number that
// it would have liked to have written. The strings written consist of
// `fixed_names_len` strings from `fixed_names` followed by `objects_len`
// strings taken by projecting `objects` through `name`.
template <typename T, typename Name, size_t S1, size_t S2>
inline size_t GetAllNames(const char **out, size_t max_out,
                          Span<const char *const, S1> fixed_names,
                          Name(T::*name), Span<const T, S2> objects) {
  auto span = Span(out, max_out);
  for (size_t i = 0; !span.empty() && i < fixed_names.size(); i++) {
    span[0] = fixed_names[i];
    span = span.subspan(1);
  }
  span = span.first(std::min(span.size(), objects.size()));
  for (size_t i = 0; i < span.size(); i++) {
    span[i] = objects[i].*name;
  }
  return fixed_names.size() + objects.size();
}


// Protocol versions.
//
// Due to DTLS's historical wire version differences, we maintain two notions of
// version.
//
// The "version" or "wire version" is the actual 16-bit value that appears on
// the wire. It uniquely identifies a version and is also used at API
// boundaries. The set of supported versions differs between TLS and DTLS. Wire
// versions are opaque values and may not be compared numerically.
//
// The "protocol version" identifies the high-level handshake variant being
// used. DTLS versions map to the corresponding TLS versions. Protocol versions
// are sequential and may be compared numerically.

// ssl_protocol_version_from_wire sets `*out` to the protocol version
// corresponding to wire version `version` and returns true. If `version` is not
// a valid TLS or DTLS version, it returns false.
//
// Note this simultaneously handles both DTLS and TLS. Use one of the
// higher-level functions below for most operations.
bool ssl_protocol_version_from_wire(uint16_t *out, uint16_t version);

// ssl_get_version_range sets `*out_min_version` and `*out_max_version` to the
// minimum and maximum enabled protocol versions, respectively.
bool ssl_get_version_range(const SSL_HANDSHAKE *hs, uint16_t *out_min_version,
                           uint16_t *out_max_version);

// ssl_supports_version returns whether `hs` supports `version`.
bool ssl_supports_version(const SSL_HANDSHAKE *hs, uint16_t version);

// ssl_method_supports_version returns whether `method` supports `version`.
bool ssl_method_supports_version(const SSL_PROTOCOL_METHOD *method,
                                 uint16_t version);

// ssl_add_supported_versions writes the supported versions of `hs` to `cbb`, in
// decreasing preference order. The version list is filtered to those whose
// protocol version is at least `extra_min_version`.
bool ssl_add_supported_versions(const SSL_HANDSHAKE *hs, CBB *cbb,
                                uint16_t extra_min_version);

// ssl_negotiate_version negotiates a common version based on `hs`'s preferences
// and the peer preference list in `peer_versions`. On success, it returns true
// and sets `*out_version` to the selected version. Otherwise, it returns false
// and sets `*out_alert` to an alert to send.
bool ssl_negotiate_version(SSL_HANDSHAKE *hs, uint8_t *out_alert,
                           uint16_t *out_version, const CBS *peer_versions);

// ssl_has_final_version returns whether `ssl` has determined the final version.
// This may be used to distinguish the predictive 0-RTT version from the final
// one.
bool ssl_has_final_version(const SSLImpl *ssl);

// ssl_protocol_version returns `ssl`'s protocol version. It is an error to
// call this function before the version is determined.
uint16_t ssl_protocol_version(const SSLImpl *ssl);

// Cipher suites.

BSSL_NAMESPACE_END

struct ssl_cipher_st {
  // name is the OpenSSL name for the cipher.
  const char *name;
  // standard_name is the IETF name for the cipher.
  const char *standard_name;
  // protocol_id is the cipher's two-byte protocol ID.
  uint16_t protocol_id;

  // algorithm_* determine the cipher suite. See constants below for the values.
  uint32_t algorithm_mkey;
  uint32_t algorithm_auth;
  uint32_t algorithm_enc;
  uint32_t algorithm_mac;
  uint32_t algorithm_prf;
};

BSSL_NAMESPACE_BEGIN

// Bits for `algorithm_mkey` (key exchange algorithm).
#define SSL_kRSA 0x00000001u
#define SSL_kECDHE 0x00000002u
// SSL_kPSK is only set for plain PSK, not ECDHE_PSK.
#define SSL_kPSK 0x00000004u
#define SSL_kGENERIC 0x00000008u

// Bits for `algorithm_auth` (server authentication).
#define SSL_aRSA_SIGN 0x00000001u
#define SSL_aRSA_DECRYPT 0x00000002u
#define SSL_aECDSA 0x00000004u
// SSL_aPSK is set for both PSK and ECDHE_PSK.
#define SSL_aPSK 0x00000008u
#define SSL_aGENERIC 0x00000010u

#define SSL_aCERT (SSL_aRSA_SIGN | SSL_aRSA_DECRYPT | SSL_aECDSA)

// Bits for `algorithm_enc` (symmetric encryption).
#define SSL_3DES 0x00000001u
#define SSL_AES128 0x00000002u
#define SSL_AES256 0x00000004u
#define SSL_AES128GCM 0x00000008u
#define SSL_AES256GCM 0x00000010u
#define SSL_CHACHA20POLY1305 0x00000020u

#define SSL_AES (SSL_AES128 | SSL_AES256 | SSL_AES128GCM | SSL_AES256GCM)

// Bits for `algorithm_mac` (symmetric authentication).
#define SSL_SHA1 0x00000001u
#define SSL_SHA256 0x00000002u
// SSL_AEAD is set for all AEADs.
#define SSL_AEAD 0x00000004u

// Bits for `algorithm_prf` (handshake digest).
#define SSL_HANDSHAKE_MAC_DEFAULT 0x1
#define SSL_HANDSHAKE_MAC_SHA256 0x2
#define SSL_HANDSHAKE_MAC_SHA384 0x4

// SSL_MAX_MD_SIZE is size of the largest hash function used in TLS, SHA-384.
#define SSL_MAX_MD_SIZE 48

// An SSLCipherPreferenceList contains a list of SSL_CIPHERs with equal-
// preference groups. For TLS clients, the groups are moot because the server
// picks the cipher and groups cannot be expressed on the wire. However, for
// servers, the equal-preference groups allow the client's preferences to be
// partially respected. (This only has an effect with
// SSL_OP_CIPHER_SERVER_PREFERENCE).
//
// The equal-preference groups are expressed by grouping SSL_CIPHERs together.
// All elements of a group have the same priority: no ordering is expressed
// within a group.
//
// The values in `ciphers` are in one-to-one correspondence with
// `in_group_flags`. (That is, sk_SSL_CIPHER_num(ciphers) is the number of
// bytes in `in_group_flags`.) The bytes in `in_group_flags` are either 1, to
// indicate that the corresponding SSL_CIPHER is not the last element of a
// group, or 0 to indicate that it is.
//
// For example, if `in_group_flags` contains all zeros then that indicates a
// traditional, fully-ordered preference. Every SSL_CIPHER is the last element
// of the group (i.e. they are all in a one-element group).
//
// For a more complex example, consider:
//   ciphers:        A  B  C  D  E  F
//   in_group_flags: 1  1  0  0  1  0
//
// That would express the following, order:
//
//    A         E
//    B -> D -> F
//    C
struct SSLCipherPreferenceList {
  static constexpr bool kAllowUniquePtr = true;

  SSLCipherPreferenceList() = default;
  ~SSLCipherPreferenceList();

  bool Init(UniquePtr<STACK_OF(SSL_CIPHER)> ciphers,
            Span<const bool> in_group_flags);
  bool Init(const SSLCipherPreferenceList &);

  void Remove(const SSL_CIPHER *cipher);

  UniquePtr<STACK_OF(SSL_CIPHER)> ciphers;
  bool *in_group_flags = nullptr;
};

// AllCiphers returns an array of all supported ciphers, sorted by id.
Span<const SSL_CIPHER> AllCiphers();

// ssl_cipher_get_evp_aead sets `*out_aead` to point to the correct EVP_AEAD
// object for `cipher` protocol version `version`. It sets `*out_mac_secret_len`
// and `*out_fixed_iv_len` to the MAC key length and fixed IV length,
// respectively. The MAC key length is zero except for legacy block and stream
// ciphers. It returns true on success and false on error.
bool ssl_cipher_get_evp_aead(const EVP_AEAD **out_aead,
                             size_t *out_mac_secret_len,
                             size_t *out_fixed_iv_len, const SSL_CIPHER *cipher,
                             uint16_t version);

// ssl_get_handshake_digest returns the `EVP_MD` corresponding to `version` and
// `cipher`.
const EVP_MD *ssl_get_handshake_digest(uint16_t version,
                                       const SSL_CIPHER *cipher);

// ssl_create_cipher_list evaluates `rule_str`. It sets `*out_cipher_list` to a
// newly-allocated `SSLCipherPreferenceList` containing the result. It returns
// true on success and false on failure. If `strict` is true, nonsense will be
// rejected. If false, nonsense will be silently ignored. An empty result is
// considered an error regardless of `strict`. `has_aes_hw` indicates if the
// list should be ordered based on having support for AES in hardware or not.
bool ssl_create_cipher_list(UniquePtr<SSLCipherPreferenceList> *out_cipher_list,
                            const bool has_aes_hw, const char *rule_str,
                            bool strict);

// ssl_cipher_auth_mask_for_key returns the mask of cipher `algorithm_auth`
// values suitable for use with `key` in TLS 1.2 and below. `sign_ok` indicates
// whether `key` may be used for signing.
uint32_t ssl_cipher_auth_mask_for_key(const EVP_PKEY *key, bool sign_ok);

// ssl_cipher_uses_certificate_auth returns whether `cipher` authenticates the
// server and, optionally, the client with a certificate.
bool ssl_cipher_uses_certificate_auth(const SSL_CIPHER *cipher);

// ssl_cipher_requires_server_key_exchange returns whether `cipher` requires a
// ServerKeyExchange message.
//
// This function may return false while still allowing `cipher` an optional
// ServerKeyExchange. This is the case for plain PSK ciphers.
bool ssl_cipher_requires_server_key_exchange(const SSL_CIPHER *cipher);

// ssl_cipher_get_record_split_len, for TLS 1.0 CBC mode ciphers, returns the
// length of an encrypted 1-byte record, for use in record-splitting. Otherwise
// it returns zero.
size_t ssl_cipher_get_record_split_len(const SSL_CIPHER *cipher);

// ssl_choose_tls13_cipher returns an `SSL_CIPHER` corresponding with the best
// available from `cipher_suites` compatible with `version` and `policy`. It
// returns NULL if there isn't a compatible cipher. `has_aes_hw` indicates if
// the choice should be made as if support for AES in hardware is available.
const SSL_CIPHER *ssl_choose_tls13_cipher(CBS cipher_suites, bool has_aes_hw,
                                          uint16_t version,
                                          enum ssl_compliance_policy_t policy);

// ssl_tls13_cipher_meets_policy returns true if `cipher_id` is acceptable given
// `policy`.
bool ssl_tls13_cipher_meets_policy(uint16_t cipher_id,
                                   enum ssl_compliance_policy_t policy);

// ssl_cipher_is_deprecated returns true if `cipher` is deprecated.
OPENSSL_EXPORT bool ssl_cipher_is_deprecated(const SSL_CIPHER *cipher);


// Transcript layer.

// SSLTranscript maintains the handshake transcript as a combination of a
// buffer and running hash.
class SSLTranscript {
 public:
  explicit SSLTranscript(bool is_dtls);
  ~SSLTranscript();

  SSLTranscript(SSLTranscript &&other) = default;
  SSLTranscript &operator=(SSLTranscript &&other) = default;

  // Init initializes the handshake transcript. If called on an existing
  // transcript, it resets the transcript and hash. It returns true on success
  // and false on failure.
  bool Init();

  // InitHash initializes the handshake hash based on the PRF and contents of
  // the handshake transcript. Subsequent calls to `Update` will update the
  // rolling hash. It returns one on success and zero on failure. It is an error
  // to call this function after the handshake buffer is released. This may be
  // called multiple times to change the hash function.
  bool InitHash(uint16_t version, const SSL_CIPHER *cipher);

  // UpdateForHelloRetryRequest resets the rolling hash with the
  // HelloRetryRequest construction. It returns true on success and false on
  // failure. It is an error to call this function before the handshake buffer
  // is released.
  bool UpdateForHelloRetryRequest();

  // CopyToHashContext initializes `ctx` with `digest` and the data thus far in
  // the transcript. It returns true on success and false on failure. If the
  // handshake buffer is still present, `digest` may be any supported digest.
  // Otherwise, `digest` must match the transcript hash.
  bool CopyToHashContext(EVP_MD_CTX *ctx, const EVP_MD *digest) const;

  Span<const uint8_t> buffer() const {
    return Span(reinterpret_cast<const uint8_t *>(buffer_->data),
                buffer_->length);
  }

  // FreeBuffer releases the handshake buffer. Subsequent calls to
  // `Update` will not update the handshake buffer.
  void FreeBuffer();

  // DigestLen returns the length of the PRF hash.
  size_t DigestLen() const;

  // Digest returns the PRF hash. For TLS 1.1 and below, this is
  // `EVP_md5_sha1`.
  const EVP_MD *Digest() const;

  // Update adds `in` to the handshake buffer and handshake hash, whichever is
  // enabled. It returns true on success and false on failure.
  bool Update(Span<const uint8_t> in);

  // GetHash writes the handshake hash to `out` which must have room for at
  // least `DigestLen` bytes. On success, it returns true and sets `*out_len` to
  // the number of bytes written. Otherwise, it returns false.
  bool GetHash(uint8_t *out, size_t *out_len) const;

  // GetFinishedMAC computes the MAC for the Finished message into the bytes
  // pointed by `out` and writes the number of bytes to `*out_len`. `out` must
  // have room for `EVP_MAX_MD_SIZE` bytes. It returns true on success and false
  // on failure.
  bool GetFinishedMAC(uint8_t *out, size_t *out_len, const SSL_SESSION *session,
                      bool from_server) const;

 private:
  // HashBuffer initializes `ctx` to use `digest` and writes the contents of
  // `buffer_` to `ctx`. If this SSLTranscript is for DTLS 1.3, the appropriate
  // bytes in `buffer_` will be skipped when hashing the buffer.
  bool HashBuffer(EVP_MD_CTX *ctx, const EVP_MD *digest) const;

  // AddToBufferOrHash directly adds the contents of `in` to `buffer_` and/or
  // `hash_`.
  bool AddToBufferOrHash(Span<const uint8_t> in);

  // buffer_, if non-null, contains the handshake transcript.
  UniquePtr<BUF_MEM> buffer_;
  // hash, if initialized with an `EVP_MD`, maintains the handshake hash.
  ScopedEVP_MD_CTX hash_;
  // is_dtls_ indicates whether this is a transcript for a DTLS connection.
  bool is_dtls_ : 1;
  // version_ contains the version for the connection (if known).
  uint16_t version_ = 0;
};

// tls1_prf computes the PRF function for `ssl`. It fills `out`, using `secret`
// as the secret and `label` as the label. `seed1` and `seed2` are concatenated
// to form the seed parameter. It returns true on success and false on failure.
bool tls1_prf(const EVP_MD *digest, Span<uint8_t> out,
              Span<const uint8_t> secret, std::string_view label,
              Span<const uint8_t> seed1, Span<const uint8_t> seed2);


// Encryption layer.

// SSLAEADContext contains information about an AEAD that is being used to
// encrypt an SSL connection.
class SSLAEADContext {
 public:
  explicit SSLAEADContext(const SSL_CIPHER *cipher);
  ~SSLAEADContext();
  static constexpr bool kAllowUniquePtr = true;

  SSLAEADContext(const SSLAEADContext &&) = delete;
  SSLAEADContext &operator=(const SSLAEADContext &&) = delete;

  // CreateNullCipher creates an `SSLAEADContext` for the null cipher.
  static UniquePtr<SSLAEADContext> CreateNullCipher();

  // Create creates an `SSLAEADContext` using the supplied key material. It
  // returns nullptr on error. Only one of `Open` or `Seal` may be used with the
  // resulting object, depending on `direction`. `version` is the wire version.
  static UniquePtr<SSLAEADContext> Create(enum evp_aead_direction_t direction,
                                          uint16_t version,
                                          const SSL_CIPHER *cipher,
                                          Span<const uint8_t> enc_key,
                                          Span<const uint8_t> mac_key,
                                          Span<const uint8_t> fixed_iv);

  // CreatePlaceholderForQUIC creates a placeholder `SSLAEADContext` for the
  // given cipher. The resulting object can be queried for various properties
  // but cannot encrypt or decrypt data.
  static UniquePtr<SSLAEADContext> CreatePlaceholderForQUIC(
      const SSL_CIPHER *cipher);

  const SSL_CIPHER *cipher() const { return cipher_; }

  // is_null_cipher returns true if this is the null cipher.
  bool is_null_cipher() const { return !cipher_; }

  // ExplicitNonceLen returns the length of the explicit nonce.
  size_t ExplicitNonceLen() const;

  // MaxOverhead returns the maximum overhead of calling `Seal`.
  size_t MaxOverhead() const;

  // MaxSealInputLen returns the maximum length for `Seal` that can fit in
  // `max_out` output bytes, or zero if no input may fit.
  size_t MaxSealInputLen(size_t max_out) const;

  // SuffixLen calculates the suffix length written by `SealScatter` and writes
  // it to `*out_suffix_len`. It returns true on success and false on error.
  // `in_len` and `extra_in_len` should equal the argument of the same names
  // passed to `SealScatter`.
  bool SuffixLen(size_t *out_suffix_len, size_t in_len,
                 size_t extra_in_len) const;

  // CiphertextLen calculates the total ciphertext length written by
  // `SealScatter` and writes it to `*out_len`. It returns true on success and
  // false on error. `in_len` and `extra_in_len` should equal the argument of
  // the same names passed to `SealScatter`.
  bool CiphertextLen(size_t *out_len, size_t in_len, size_t extra_in_len) const;

  // Open authenticates and decrypts `in` in-place. On success, it sets `*out`
  // to the plaintext in `in` and returns true.  Otherwise, it returns
  // false. The output will always be `ExplicitNonceLen` bytes ahead of `in`.
  bool Open(Span<uint8_t> *out, uint8_t type, uint16_t record_version,
            uint64_t seqnum, Span<const uint8_t> header, Span<uint8_t> in);

  // Seal encrypts and authenticates `in_len` bytes from `in` and writes the
  // result to `out`. It returns true on success and false on error.
  //
  // If `in` and `out` alias then `out` + `ExplicitNonceLen` must be == `in`.
  bool Seal(uint8_t *out, size_t *out_len, size_t max_out, uint8_t type,
            uint16_t record_version, uint64_t seqnum,
            Span<const uint8_t> header, const uint8_t *in, size_t in_len);

  // SealScatter encrypts and authenticates `in_len` bytes from `in` and splits
  // the result between `out_prefix`, `out` and `out_suffix`. It returns one on
  // success and zero on error.
  //
  // On successful return, exactly `ExplicitNonceLen` bytes are written to
  // `out_prefix`, `in_len` bytes to `out`, and `SuffixLen` bytes to
  // `out_suffix`.
  //
  // `extra_in` may point to an additional plaintext buffer. If present,
  // `extra_in_len` additional bytes are encrypted and authenticated, and the
  // ciphertext is written to the beginning of `out_suffix`. `SuffixLen` should
  // be used to size `out_suffix` accordingly.
  //
  // If `in` and `out` alias then `out` must be == `in`. Other arguments may not
  // alias anything.
  bool SealScatter(uint8_t *out_prefix, uint8_t *out, uint8_t *out_suffix,
                   uint8_t type, uint16_t record_version, uint64_t seqnum,
                   Span<const uint8_t> header, const uint8_t *in, size_t in_len,
                   const uint8_t *extra_in, size_t extra_in_len);

  bool GetIV(const uint8_t **out_iv, size_t *out_iv_len) const;

 private:
  // GetAdditionalData returns the additional data, writing into `storage` if
  // necessary.
  Span<const uint8_t> GetAdditionalData(uint8_t storage[13], uint8_t type,
                                        uint16_t record_version,
                                        uint64_t seqnum, size_t plaintext_len,
                                        Span<const uint8_t> header);

  const SSL_CIPHER *cipher_;
  ScopedEVP_AEAD_CTX ctx_;
  // fixed_nonce_ contains any bytes of the nonce that are fixed for all
  // records.
  InplaceVector<uint8_t, 12> fixed_nonce_;
  uint8_t variable_nonce_len_ = 0;
  // variable_nonce_included_in_record_ is true if the variable nonce
  // for a record is included as a prefix before the ciphertext.
  bool variable_nonce_included_in_record_ : 1;
  // random_variable_nonce_ is true if the variable nonce is
  // randomly generated, rather than derived from the sequence
  // number.
  bool random_variable_nonce_ : 1;
  // xor_fixed_nonce_ is true if the fixed nonce should be XOR'd into the
  // variable nonce rather than prepended.
  bool xor_fixed_nonce_ : 1;
  // omit_length_in_ad_ is true if the length should be omitted in the
  // AEAD's ad parameter.
  bool omit_length_in_ad_ : 1;
  // ad_is_header_ is true if the AEAD's ad parameter is the record header.
  bool ad_is_header_ : 1;
};


// DTLS replay bitmap.

// DTLSReplayBitmap maintains a sliding window of sequence numbers to detect
// replayed packets.
class DTLSReplayBitmap {
 public:
  // ShouldDiscard returns true if `seq_num` has been seen in
  // `bitmap` or is stale. Otherwise it returns false.
  bool ShouldDiscard(uint64_t seqnum) const;

  // Record updates the bitmap to record receipt of sequence number
  // `seq_num`. It slides the window forward if needed. It is an error to call
  // this function on a stale sequence number.
  void Record(uint64_t seqnum);

  uint64_t max_seq_num() const { return max_seq_num_; }

 private:
  // map is a bitset of sequence numbers that have been seen. Bit i corresponds
  // to `max_seq_num_ - i`.
  std::bitset<256> map_;
  // max_seq_num_ is the largest sequence number seen so far as a 64-bit
  // integer, or zero if none have been seen.
  uint64_t max_seq_num_ = 0;
};

// reconstruct_seqnum takes the low order bits of a record sequence number from
// the wire and reconstructs the full sequence number. It does so using the
// algorithm described in section 4.2.2 of RFC 9147, where `wire_seq` is the
// low bits of the sequence number as seen on the wire, `seq_mask` is a bitmask
// of 8 or 16 1 bits corresponding to the length of the sequence number on the
// wire, and `max_valid_seqnum` is the largest sequence number of a record
// successfully deprotected in this epoch. This function returns the sequence
// number that is numerically closest to one plus `max_valid_seqnum` that when
// bitwise and-ed with `seq_mask` equals `wire_seq`.
//
// `max_valid_seqnum` must be most 2^48-1, in which case the output will also be
// at most 2^48-1.
uint64_t reconstruct_seqnum(uint16_t wire_seq, uint64_t seq_mask,
                            uint64_t max_valid_seqnum);


// Record layer.

class DTLSRecordNumber {
 public:
  static constexpr uint64_t kMaxSequence = (uint64_t{1} << 48) - 1;

  DTLSRecordNumber() = default;
  DTLSRecordNumber(uint16_t epoch, uint64_t sequence) {
    BSSL_CHECK(sequence <= kMaxSequence);
    combined_ = (uint64_t{epoch} << 48) | sequence;
  }

  static DTLSRecordNumber FromCombined(uint64_t combined) {
    return DTLSRecordNumber(combined);
  }

  bool operator==(DTLSRecordNumber r) const {
    return combined() == r.combined();
  }
  bool operator!=(DTLSRecordNumber r) const { return !((*this) == r); }
  bool operator<(DTLSRecordNumber r) const { return combined() < r.combined(); }

  uint64_t combined() const { return combined_; }
  uint16_t epoch() const { return combined_ >> 48; }
  uint64_t sequence() const { return combined_ & kMaxSequence; }

  bool HasNext() const { return sequence() < kMaxSequence; }
  DTLSRecordNumber Next() const {
    BSSL_CHECK(HasNext());
    // This will not overflow into the epoch.
    return DTLSRecordNumber::FromCombined(combined_ + 1);
  }

 private:
  explicit DTLSRecordNumber(uint64_t combined) : combined_(combined) {}

  uint64_t combined_ = 0;
};

class RecordNumberEncrypter {
 public:
  static constexpr bool kAllowUniquePtr = true;
  static constexpr size_t kMaxKeySize = 32;

  // Create returns a DTLS 1.3 record number encrypter for `traffic_secret`, or
  // nullptr on error.
  static UniquePtr<RecordNumberEncrypter> Create(
      const SSL_CIPHER *cipher, Span<const uint8_t> traffic_secret);

  virtual ~RecordNumberEncrypter() = default;
  virtual size_t KeySize() = 0;
  virtual bool SetKey(Span<const uint8_t> key) = 0;
  virtual bool GenerateMask(Span<uint8_t> out, Span<const uint8_t> sample) = 0;
};

struct DTLSReadEpoch {
  static constexpr bool kAllowUniquePtr = true;

  // TODO(davidben): This could be made slightly more compact if `bitmap` stored
  // a DTLSRecordNumber.
  uint16_t epoch = 0;
  UniquePtr<SSLAEADContext> aead;
  UniquePtr<RecordNumberEncrypter> rn_encrypter;
  DTLSReplayBitmap bitmap;
  InplaceVector<uint8_t, SSL_MAX_MD_SIZE> traffic_secret;
};

struct DTLSWriteEpoch {
  static constexpr bool kAllowUniquePtr = true;

  uint16_t epoch() const { return next_record.epoch(); }

  DTLSRecordNumber next_record;
  UniquePtr<SSLAEADContext> aead;
  UniquePtr<RecordNumberEncrypter> rn_encrypter;
  InplaceVector<uint8_t, SSL_MAX_MD_SIZE> traffic_secret;
};

// ssl_record_prefix_len returns the length of the prefix before the ciphertext
// of a record for `ssl`.
//
// TODO(davidben): Expose this as part of public API once the high-level
// buffer-free APIs are available.
size_t ssl_record_prefix_len(const SSLImpl *ssl);

enum ssl_open_record_t {
  ssl_open_record_success,
  ssl_open_record_discard,
  ssl_open_record_partial,
  ssl_open_record_close_notify,
  ssl_open_record_error,
};

// tls_open_record decrypts a record from `in` in-place.
//
// If the input did not contain a complete record, it returns
// `ssl_open_record_partial`. It sets `*out_consumed` to the total number of
// bytes necessary. It is guaranteed that a successful call to `tls_open_record`
// will consume at least that many bytes.
//
// Otherwise, it sets `*out_consumed` to the number of bytes of input
// consumed. Note that input may be consumed on all return codes if a record was
// decrypted.
//
// On success, it returns `ssl_open_record_success`. It sets `*out_type` to the
// record type and `*out` to the record body in `in`. Note that `*out` may be
// empty.
//
// If a record was successfully processed but should be discarded, it returns
// `ssl_open_record_discard`.
//
// If a record was successfully processed but is a close_notify, it returns
// `ssl_open_record_close_notify`.
//
// On failure or fatal alert, it returns `ssl_open_record_error` and sets
// `*out_alert` to an alert to emit, or zero if no alert should be emitted.
enum ssl_open_record_t tls_open_record(SSLImpl *ssl, uint8_t *out_type,
                                       Span<uint8_t> *out, size_t *out_consumed,
                                       uint8_t *out_alert, Span<uint8_t> in);

// dtls_open_record implements `tls_open_record` for DTLS. It only returns
// `ssl_open_record_partial` if `in` was empty and sets `*out_consumed` to
// zero. The caller should read one packet and try again. On success,
// `*out_number` is set to the record number of the record.
enum ssl_open_record_t dtls_open_record(SSLImpl *ssl, uint8_t *out_type,
                                        DTLSRecordNumber *out_number,
                                        Span<uint8_t> *out,
                                        size_t *out_consumed,
                                        uint8_t *out_alert, Span<uint8_t> in);

// ssl_needs_record_splitting returns one if `ssl`'s current outgoing cipher
// state needs record-splitting and zero otherwise.
bool ssl_needs_record_splitting(const SSLImpl *ssl);

// tls_seal_record seals a new record of type `type` and body `in` and writes it
// to `out`. At most `max_out` bytes will be written. It returns true on success
// and false on error. If enabled, `tls_seal_record` implements TLS 1.0 CBC
// 1/n-1 record splitting and may write two records concatenated.
//
// For a large record, the bulk of the ciphertext will begin
// `tls_seal_align_prefix_len` bytes into out. Aligning `out` appropriately may
// improve performance. It writes at most `in_len` + `SSL_max_seal_overhead`
// bytes to `out`.
//
// `in` and `out` may not alias.
bool tls_seal_record(SSLImpl *ssl, uint8_t *out, size_t *out_len,
                     size_t max_out, uint8_t type, const uint8_t *in,
                     size_t in_len);

// dtls_record_header_write_len returns the length of the record header that
// will be written at `epoch`.
size_t dtls_record_header_write_len(const SSLImpl *ssl, uint16_t epoch);

// dtls_max_seal_overhead returns the maximum overhead, in bytes, of sealing a
// record.
size_t dtls_max_seal_overhead(const SSLImpl *ssl, uint16_t epoch);

// dtls_seal_prefix_len returns the number of bytes of prefix to reserve in
// front of the plaintext when sealing a record in-place.
size_t dtls_seal_prefix_len(const SSLImpl *ssl, uint16_t epoch);

// dtls_seal_max_input_len returns the maximum number of input bytes that can
// fit in a record of up to `max_out` bytes, or zero if none may fit.
size_t dtls_seal_max_input_len(const SSLImpl *ssl, uint16_t epoch,
                               size_t max_out);

// dtls_get_read_epoch and dtls_get_write_epoch return the epoch corresponding
// to `epoch` or nullptr if there is none.
DTLSReadEpoch *dtls_get_read_epoch(const SSLImpl *ssl, uint16_t epoch);
DTLSWriteEpoch *dtls_get_write_epoch(const SSLImpl *ssl, uint16_t epoch);

// dtls_seal_record implements `tls_seal_record` for DTLS. `epoch` selects which
// epoch's cipher state to use. Unlike `tls_seal_record`, `in` and `out` may
// alias but, if they do, `in` must be exactly `dtls_seal_prefix_len` bytes
// ahead of `out`. On success, `*out_number` is set to the record number of the
// record.
bool dtls_seal_record(SSLImpl *ssl, DTLSRecordNumber *out_number, uint8_t *out,
                      size_t *out_len, size_t max_out, uint8_t type,
                      const uint8_t *in, size_t in_len, uint16_t epoch);

// ssl_process_alert processes `in` as an alert and updates `ssl`'s shutdown
// state. It returns one of `ssl_open_record_discard`, `ssl_open_record_error`,
// `ssl_open_record_close_notify`, or `ssl_open_record_fatal_alert` as
// appropriate.
enum ssl_open_record_t ssl_process_alert(SSLImpl *ssl, uint8_t *out_alert,
                                         Span<const uint8_t> in);


// Private key operations.

// ssl_private_key_* perform the corresponding operation on
// `SSL_PRIVATE_KEY_METHOD`. If there is a custom private key configured, they
// call the corresponding function or `complete` depending on whether there is a
// pending operation. Otherwise, they implement the operation with
// `EVP_PKEY`.

enum ssl_private_key_result_t ssl_private_key_sign(
    SSL_HANDSHAKE *hs, uint8_t *out, size_t *out_len, size_t max_out,
    uint16_t sigalg, Span<const uint8_t> in);

enum ssl_private_key_result_t ssl_private_key_decrypt(SSL_HANDSHAKE *hs,
                                                      uint8_t *out,
                                                      size_t *out_len,
                                                      size_t max_out,
                                                      Span<const uint8_t> in);

// ssl_parse_peer_subject_public_key_info decodes a SubjectPublicKeyInfo
// representing the peer TLS key. It returns a newly-allocated `EVP_PKEY` or
// nullptr on error.
UniquePtr<EVP_PKEY> ssl_parse_peer_subject_public_key_info(
    Span<const uint8_t> spki);

// ssl_pkey_supports_algorithm returns whether `pkey` may be used to sign
// `sigalg`.
bool ssl_pkey_supports_algorithm(const SSLImpl *ssl, EVP_PKEY *pkey,
                                 uint16_t sigalg, bool is_verify);

// ssl_public_key_verify verifies that the `signature` is valid for the public
// key `pkey` and input `in`, using the signature algorithm `sigalg`.
bool ssl_public_key_verify(SSLImpl *ssl, Span<const uint8_t> signature,
                           uint16_t sigalg, EVP_PKEY *pkey,
                           Span<const uint8_t> in);


// Key shares.

// SSLKeyShare abstracts over KEM-like constructions, for use with TLS 1.2 ECDHE
// cipher suites and the TLS 1.3 key_share extension.
//
// TODO(davidben): This class is named SSLKeyShare after the TLS 1.3 key_share
// extension, but it really implements a KEM abstraction. Additionally, we use
// the same type for Encap, which is a one-off, stateless operation, as Generate
// and Decap. Slightly tidier would be for Generate to return a new SSLKEMKey
// (or we introduce EVP_KEM and EVP_KEM_KEY), with a Decap method, and for Encap
// to be static function.
class SSLKeyShare {
 public:
  virtual ~SSLKeyShare() {}
  static constexpr bool kAllowUniquePtr = true;

  // Create returns a SSLKeyShare instance for use with group `group_id` or
  // nullptr on error.
  static UniquePtr<SSLKeyShare> Create(uint16_t group_id);

  // GroupID returns the group ID.
  virtual uint16_t GroupID() const = 0;

  // Generate generates a keypair and writes the public key to `out_public_key`.
  // It returns true on success and false on error.
  virtual bool Generate(CBB *out_public_key) = 0;

  // Encap generates an ephemeral, symmetric secret and encapsulates it with
  // `peer_key`. On success, it returns true, writes the encapsulated secret to
  // `out_ciphertext`, and sets `*out_secret` to the shared secret. On failure,
  // it returns false and sets `*out_alert` to an alert to send to the peer.
  virtual bool Encap(CBB *out_ciphertext, Array<uint8_t> *out_secret,
                     uint8_t *out_alert, Span<const uint8_t> peer_key) = 0;

  // Decap decapsulates the symmetric secret in `ciphertext`. On success, it
  // returns true and sets `*out_secret` to the shared secret. On failure, it
  // returns false and sets `*out_alert` to an alert to send to the peer.
  virtual bool Decap(Array<uint8_t> *out_secret, uint8_t *out_alert,
                     Span<const uint8_t> ciphertext) = 0;

  // SerializePrivateKey writes the private key to `out`, returning true if
  // successful and false otherwise. It should be called after `Generate`.
  virtual bool SerializePrivateKey(CBB *out) { return false; }

  // DeserializePrivateKey initializes the state of the key exchange from `in`,
  // returning true if successful and false otherwise.
  virtual bool DeserializePrivateKey(CBS *in) { return false; }
};

struct NamedGroup {
  int nid;
  uint16_t group_id;
  const char name[32], alias[32];
};

// NamedGroups returns all supported groups.
Span<const NamedGroup> NamedGroups();

// kNumNamedGroups is the number of supported groups.
constexpr size_t kNumNamedGroups = 7u;

// DefaultSupportedGroupIds returns the list of IDs for the default groups that
// are supported when the caller hasn't explicitly configured supported groups.
Span<const uint16_t> DefaultSupportedGroupIds();

// ssl_nid_to_group_id looks up the group corresponding to `nid`. On success, it
// sets `*out_group_id` to the group ID and returns true. Otherwise, it returns
// false.
bool ssl_nid_to_group_id(uint16_t *out_group_id, int nid);

// ssl_name_to_group_id looks up the group corresponding to the `name` string of
// length `len`. On success, it sets `*out_group_id` to the group ID and returns
// true. Otherwise, it returns false.
bool ssl_name_to_group_id(uint16_t *out_group_id, const char *name, size_t len);

// ssl_group_id_to_nid returns the NID corresponding to `group_id` or
// `NID_undef` if unknown.
int ssl_group_id_to_nid(uint16_t group_id);


// Handshake messages.

struct SSLMessage {
  bool is_v2_hello;
  uint8_t type;
  CBS body;
  // raw is the entire serialized handshake message, including the TLS or DTLS
  // message header.
  CBS raw;
};

// SSL_MAX_HANDSHAKE_FLIGHT is the number of messages, including
// ChangeCipherSpec, in the longest handshake flight. Currently this is the
// client's second leg in a full handshake when client certificates, NPN, and
// Channel ID, are all enabled.
#define SSL_MAX_HANDSHAKE_FLIGHT 7

extern const uint8_t kHelloRetryRequest[SSL3_RANDOM_SIZE];
extern const uint8_t kTLS12DowngradeRandom[8];
extern const uint8_t kTLS13DowngradeRandom[8];
extern const uint8_t kJDK11DowngradeRandom[8];

// ssl_max_handshake_message_len returns the maximum number of bytes permitted
// in a handshake message for `ssl`.
size_t ssl_max_handshake_message_len(const SSLImpl *ssl);

// tls_can_accept_handshake_data returns whether `ssl` is able to accept more
// data into handshake buffer.
bool tls_can_accept_handshake_data(const SSLImpl *ssl, uint8_t *out_alert);

// tls_has_unprocessed_handshake_data returns whether there is buffered
// handshake data that has not been consumed by `get_message`.
bool tls_has_unprocessed_handshake_data(const SSLImpl *ssl);

// tls_append_handshake_data appends `data` to the handshake buffer. It returns
// true on success and false on allocation failure.
bool tls_append_handshake_data(SSLImpl *ssl, Span<const uint8_t> data);

// dtls_has_unprocessed_handshake_data behaves like
// `tls_has_unprocessed_handshake_data` for DTLS.
bool dtls_has_unprocessed_handshake_data(const SSLImpl *ssl);

// tls_flush_pending_hs_data flushes any handshake plaintext data.
bool tls_flush_pending_hs_data(SSLImpl *ssl);

// dtls_clear_outgoing_messages releases all buffered outgoing messages.
void dtls_clear_outgoing_messages(SSLImpl *ssl);

// dtls_clear_unused_write_epochs releases any write epochs that are no longer
// needed.
void dtls_clear_unused_write_epochs(SSLImpl *ssl);


// Callbacks.

// ssl_do_info_callback calls `ssl`'s info callback, if set.
void ssl_do_info_callback(const SSLImpl *ssl, int type, int value);

// ssl_do_msg_callback calls `ssl`'s message callback, if set.
void ssl_do_msg_callback(const SSLImpl *ssl, int is_write, int content_type,
                         Span<const uint8_t> in);


// Transport buffers.

class SSLBuffer {
 public:
  SSLBuffer() {}
  ~SSLBuffer() { Clear(); }

  SSLBuffer(const SSLBuffer &) = delete;
  SSLBuffer &operator=(const SSLBuffer &) = delete;

  uint8_t *data() { return buf_ + offset_; }
  size_t size() const { return size_; }
  bool empty() const { return size_ == 0; }
  size_t cap() const { return cap_; }

  Span<uint8_t> span() { return Span(data(), size()); }

  Span<uint8_t> remaining() { return Span(data() + size(), cap() - size()); }

  // Clear releases the buffer.
  void Clear();

  // EnsureCap ensures the buffer has capacity at least `new_cap`, aligned such
  // that data written after `header_len` is aligned to a
  // `SSL3_ALIGN_PAYLOAD`-byte boundary. It returns true on success and false
  // on error.
  bool EnsureCap(size_t header_len, size_t new_cap);

  // DidWrite extends the buffer by `len`. The caller must have filled in to
  // this point.
  void DidWrite(size_t len);

  // Consume consumes `len` bytes from the front of the buffer.  The memory
  // consumed will remain valid until the next call to `DiscardConsumed` or
  // `Clear`.
  void Consume(size_t len);

  // DiscardConsumed discards the consumed bytes from the buffer. If the buffer
  // is now empty, it releases memory used by it.
  void DiscardConsumed();

 private:
  // buf_ is the memory allocated for this buffer.
  uint8_t *buf_ = nullptr;
  // offset_ is the offset into `buf_` which the buffer contents start at.
  uint16_t offset_ = 0;
  // size_ is the size of the buffer contents from `buf_` + `offset_`.
  uint16_t size_ = 0;
  // cap_ is how much memory beyond `buf_` + `offset_` is available.
  uint16_t cap_ = 0;
  // inline_buf_ is a static buffer for short reads.
  uint8_t inline_buf_[SSL3_RT_HEADER_LENGTH];
};

// ssl_read_buffer_extend_to extends the read buffer to the desired length. For
// TLS, it reads to the end of the buffer until the buffer is `len` bytes
// long. For DTLS, it reads a new packet and ignores `len`. It returns one on
// success, zero on EOF, and a negative number on error.
//
// It is an error to call `ssl_read_buffer_extend_to` in DTLS when the buffer is
// non-empty.
int ssl_read_buffer_extend_to(SSLImpl *ssl, size_t len);

// ssl_handle_open_record handles the result of passing `ssl->s3->read_buffer`
// to a record-processing function. If `ret` is a success or if the caller
// should retry, it returns one and sets `*out_retry`. Otherwise, it returns <=
// 0.
int ssl_handle_open_record(SSLImpl *ssl, bool *out_retry, ssl_open_record_t ret,
                           size_t consumed, uint8_t alert);

// ssl_write_buffer_flush flushes the write buffer to the transport. It returns
// one on success and <= 0 on error. For DTLS, whether or not the write
// succeeds, the write buffer will be cleared.
int ssl_write_buffer_flush(SSLImpl *ssl);


// Certificate functions.

// ssl_parse_cert_chain parses a certificate list from `cbs` in the format used
// by a TLS Certificate message. On success, it advances `cbs` and returns
// true. Otherwise, it returns false and sets `*out_alert` to an alert to send
// to the peer.
//
// If the list is non-empty then `*out_chain` and `*out_pubkey` will be set to
// the certificate chain and the leaf certificate's public key
// respectively. Otherwise, both will be set to nullptr.
//
// If the list is non-empty and `out_leaf_sha256` is non-NULL, it writes the
// SHA-256 hash of the leaf to `out_leaf_sha256`.
bool ssl_parse_cert_chain(uint8_t *out_alert,
                          UniquePtr<STACK_OF(CRYPTO_BUFFER)> *out_chain,
                          UniquePtr<EVP_PKEY> *out_pubkey,
                          uint8_t *out_leaf_sha256, CBS *cbs,
                          CRYPTO_BUFFER_POOL *pool);

// ssl_parse_rpk_cert parses a RawPublicKey certificate from `cbs` in the format
// used by a TLS 1.2 Certificate message (RFC 7250). On success, it advances
// `cbs` and returns true, and sets `*out_raw_public_key` to the parsed key, and
// sets `*out_pubkey` to the same key by incrementing the reference count, and
// if `out_rpk_sha256` is non-NULL, it writes the SHA-256 hash of the RPK to
// `out_rpk_sha256`. Otherwise, it returns false and sets `*out_alert` to an
// alert to send to the peer.
bool ssl_parse_rpk_cert(uint8_t *out_alert,
                        UniquePtr<EVP_PKEY> *out_raw_public_key,
                        UniquePtr<EVP_PKEY> *out_pubkey,
                        uint8_t *out_rpk_sha256, CBS *cbs);

enum ssl_key_usage_t {
  key_usage_digital_signature = 0,
  key_usage_encipherment = 2,
};

// ssl_cert_check_key_usage parses the DER-encoded, X.509 certificate in `in`
// and returns true if doesn't specify a key usage or, if it does, if it
// includes `bit`. Otherwise it pushes to the error queue and returns false.
bool ssl_cert_check_key_usage(const CBS *in, enum ssl_key_usage_t bit);

// ssl_cert_extract_issuer parses the DER-encoded, X.509 certificate in `in`
// and extracts the issuer. On success it returns true and the DER encoded
// issuer is in `out_dn`, otherwise it returns false.
bool ssl_cert_extract_issuer(const CBS *in, CBS *out_dn);

// ssl_cert_matches_issuer parses the DER-encoded, X.509 certificate in `in`
// and returns true if its issuer is an exact match for the DER encoded
// distinguished name in `dn`
bool ssl_cert_matches_issuer(const CBS *in, const CBS *dn);

// ssl_cert_parse_pubkey extracts the public key from the DER-encoded, X.509
// certificate in `in`. It returns an allocated `EVP_PKEY` or else returns
// nullptr and pushes to the error queue.
UniquePtr<EVP_PKEY> ssl_cert_parse_pubkey(const CBS *in);

// SSL_parse_CA_list parses a CA list from `cbs` in the format used by a TLS
// CertificateRequest message and Certificate Authorities extension. On success,
// it returns a newly-allocated `CRYPTO_BUFFER` list and advances
// `cbs`. Otherwise, it returns nullptr and sets `*out_alert` to an alert to
// send to the peer.
UniquePtr<STACK_OF(CRYPTO_BUFFER)> SSL_parse_CA_list(SSLImpl *ssl,
                                                     uint8_t *out_alert,
                                                     CBS *cbs);

// ssl_has_client_CAs returns whether there are configured CAs.
bool ssl_has_client_CAs(const SSL_CONFIG *cfg);

// ssl_add_client_CA_list adds the configured CA list to `cbb` in the format
// used by a TLS CertificateRequest message. It returns true on success and
// false on error.
bool ssl_add_client_CA_list(const SSL_HANDSHAKE *hs, CBB *cbb);

// ssl_has_CA_names returns whether there are configured CA names.
bool ssl_has_CA_names(const SSL_CONFIG *cfg);

// ssl_add_CA_names adds the configured CA_names list to `cbb` in the format
// used by a TLS Certificate Authorities extension. It returns true on success
// and false on error.
bool ssl_add_CA_names(const SSL_HANDSHAKE *hs, CBB *cbb);

// ssl_check_leaf_certificate returns one if `pkey` and `leaf` are suitable as
// a server's leaf certificate for `hs`. Otherwise, it returns zero and pushes
// an error on the error queue.
bool ssl_check_leaf_certificate(SSL_HANDSHAKE *hs, EVP_PKEY *pkey,
                                const CRYPTO_BUFFER *leaf);


// TLS 1.3 key derivation.

// tls13_init_key_schedule initializes the handshake hash and key derivation
// state, and incorporates the PSK. The cipher suite and PRF hash must have been
// selected at this point. It returns true on success and false on error.
bool tls13_init_key_schedule(SSL_HANDSHAKE *hs, Span<const uint8_t> psk);

// tls13_init_early_key_schedule initializes the handshake hash and key
// derivation state from `session` for use with 0-RTT. It returns one on success
// and zero on error.
bool tls13_init_early_key_schedule(SSL_HANDSHAKE *hs,
                                   const SSL_SESSION *session);

// tls13_advance_key_schedule incorporates `in` into the key schedule with
// HKDF-Extract. It returns true on success and false on error.
bool tls13_advance_key_schedule(SSL_HANDSHAKE *hs, Span<const uint8_t> in);

// tls13_set_traffic_key sets the read or write traffic keys to
// `traffic_secret`. The version and cipher suite are determined from `session`.
// It returns true on success and false on error.
bool tls13_set_traffic_key(SSLImpl *ssl, enum ssl_encryption_level_t level,
                           enum evp_aead_direction_t direction,
                           const SSL_SESSION *session,
                           Span<const uint8_t> traffic_secret);

// tls13_derive_early_secret derives the early traffic secret. It returns true
// on success and false on error.
bool tls13_derive_early_secret(SSL_HANDSHAKE *hs);

// tls13_derive_handshake_secrets derives the handshake traffic secret. It
// returns true on success and false on error.
bool tls13_derive_handshake_secrets(SSL_HANDSHAKE *hs);

// tls13_rotate_traffic_key derives the next read or write traffic secret. It
// returns true on success and false on error.
bool tls13_rotate_traffic_key(SSLImpl *ssl,
                              enum evp_aead_direction_t direction);

// tls13_derive_application_secrets derives the initial application data traffic
// and exporter secrets based on the handshake transcripts and `master_secret`.
// It returns true on success and false on error.
bool tls13_derive_application_secrets(SSL_HANDSHAKE *hs);

// tls13_derive_resumption_secret derives the `resumption_secret`.
bool tls13_derive_resumption_secret(SSL_HANDSHAKE *hs);

// tls13_export_keying_material provides an exporter interface to use the
// `exporter_secret`.
bool tls13_export_keying_material(const SSLImpl *ssl, Span<uint8_t> out,
                                  Span<const uint8_t> secret,
                                  std::string_view label,
                                  Span<const uint8_t> context);

// tls13_finished_mac calculates the MAC of the handshake transcript to verify
// the integrity of the Finished message, and stores the result in `out` and
// length in `out_len`. `is_server` is true if this is for the Server Finished
// and false for the Client Finished.
bool tls13_finished_mac(SSL_HANDSHAKE *hs, uint8_t *out, size_t *out_len,
                        bool is_server);

// tls13_derive_session_psk calculates the PSK for this session based on the
// resumption master secret and `nonce`. It returns true on success, and false
// on failure.
bool tls13_derive_session_psk(SSL_SESSION *session, Span<const uint8_t> nonce,
                              bool is_dtls);

struct SSLImportedPSK {
  static constexpr bool kAllowUniquePtr = true;
  UniquePtr<SSLCredential> credential;
  Array<uint8_t> imported_identity;
  InplaceVector<uint8_t, SSL_MAX_MD_SIZE> ipskx;
  uint16_t protocol = 0;
  const EVP_MD *md = nullptr;
};

// tls13_derive_imported_psk computes the imported PSK value for `cred`, which
// must be an PSK credential, for use with a target KDF of HKDF with `hkdf_md`.
// `protocol` should be the wire version (i.e. `TLS1_3_VERSION` or
// `DTLS1_3_VERSION`) of the target protocol. It returns the imported PSK on
// success and std::nullopt on error.
std::optional<SSLImportedPSK> tls13_derive_imported_psk(const SSL_HANDSHAKE *hs,
                                                        SSLCredential *cred,
                                                        uint16_t protocol,
                                                        const EVP_MD *hkdf_md);

// tls13_compare_imported_psk_identity returns whether `id` is equal to `cred`'s
// imported identity for the specified target protocol and target KDF. This
// allows matching against PSK identities without deriving imported PSK keys.
bool tls13_compare_imported_psk_identity(Span<const uint8_t> id,
                                         const SSLCredential *cred,
                                         uint16_t protocol,
                                         const EVP_MD *hkdf_md);

using SSLPreSharedKey = std::variant<SSLImportedPSK, UniquePtr<SSL_SESSION>>;
BORINGSSL_MAKE_DELETER(SSLPreSharedKey, Delete)

// ssl_pre_shared_key_hash return's `psk`'s hash.
const EVP_MD *ssl_pre_shared_key_hash(const SSLPreSharedKey &psk);

// ssl_pre_shared_key_identity return's `psk`'s identity.
Span<const uint8_t> ssl_pre_shared_key_identity(const SSLPreSharedKey &psk);

// ssl_pre_shared_key_secret return's `psk`'s secret.
Span<const uint8_t> ssl_pre_shared_key_secret(const SSLPreSharedKey &psk);

// tls13_psk_binder calculates the PSK binder value for `psk` over `transcript`
// and `client_hello`. On success, it writes the result to `out`, sets
// `*out_len` to the length, and returns true. Otherwise, it returns false.
// `binders_len` must be the length of the binders field, covering all binders
// and the overall length prefix, in `client_hello`.
bool tls13_psk_binder(const SSL_HANDSHAKE *hs, Span<uint8_t> out,
                      size_t *out_len, const SSLPreSharedKey &psk,
                      const SSLTranscript &transcript,
                      Span<const uint8_t> client_hello, size_t binders_len);


// Encrypted ClientHello.

struct ECHConfig {
  static constexpr bool kAllowUniquePtr = true;
  // raw contains the serialized ECHConfig.
  Array<uint8_t> raw;
  // The following fields alias into `raw`.
  Span<const uint8_t> public_key;
  Span<const uint8_t> public_name;
  Span<const uint8_t> cipher_suites;
  uint16_t kem_id = 0;
  uint8_t maximum_name_length = 0;
  uint8_t config_id = 0;
};

class ECHServerConfig {
 public:
  static constexpr bool kAllowUniquePtr = true;
  ECHServerConfig() = default;
  ECHServerConfig(const ECHServerConfig &other) = delete;
  ECHServerConfig &operator=(ECHServerConfig &&) = delete;

  // Init parses `ech_config` as an ECHConfig and saves a copy of `key`.
  // It returns true on success and false on error.
  bool Init(Span<const uint8_t> ech_config, const EVP_HPKE_KEY *key,
            bool is_retry_config);

  // SetupContext sets up `ctx` for a new connection, given the specified
  // HPKE ciphersuite and encapsulated KEM key. It returns true on success and
  // false on error. This function may only be called on an initialized object.
  bool SetupContext(EVP_HPKE_CTX *ctx, uint16_t kdf_id, uint16_t aead_id,
                    Span<const uint8_t> enc) const;

  const ECHConfig &ech_config() const { return ech_config_; }
  bool is_retry_config() const { return is_retry_config_; }

 private:
  ECHConfig ech_config_;
  ScopedEVP_HPKE_KEY key_;
  bool is_retry_config_ = false;
};

class SSLECHKeys : public ssl_ech_keys_st, public bssl::RefCounted<SSLECHKeys> {
 public:
  SSLECHKeys() : RefCounted(CheckSubClass()) {}

  Vector<UniquePtr<ECHServerConfig>> configs;

 private:
  friend RefCounted;
  ~SSLECHKeys() = default;
};

enum ssl_client_hello_type_t {
  ssl_client_hello_unencrypted,
  ssl_client_hello_inner,
  ssl_client_hello_outer,
};

// ECH_CLIENT_* are types for the ClientHello encrypted_client_hello extension.
#define ECH_CLIENT_OUTER 0
#define ECH_CLIENT_INNER 1

// ssl_decode_client_hello_inner recovers the full ClientHelloInner from the
// EncodedClientHelloInner `encoded_client_hello_inner` by replacing its
// outer_extensions extension with the referenced extensions from the
// ClientHelloOuter `client_hello_outer`. If successful, it writes the recovered
// ClientHelloInner to `out_client_hello_inner`. It returns true on success and
// false on failure.
//
// This function is exported for fuzzing.
OPENSSL_EXPORT bool ssl_decode_client_hello_inner(
    SSLImpl *ssl, uint8_t *out_alert, Array<uint8_t> *out_client_hello_inner,
    Span<const uint8_t> encoded_client_hello_inner,
    const SSL_CLIENT_HELLO *client_hello_outer);

// ssl_client_hello_decrypt attempts to decrypt and decode the `payload`. It
// writes the result to `*out`. `payload` must point into `client_hello_outer`.
// It returns true on success and false on error. On error, it sets
// `*out_is_decrypt_error` to whether the failure was due to a bad ciphertext.
bool ssl_client_hello_decrypt(SSL_HANDSHAKE *hs, uint8_t *out_alert,
                              bool *out_is_decrypt_error, Array<uint8_t> *out,
                              const SSL_CLIENT_HELLO *client_hello_outer,
                              Span<const uint8_t> payload);

#define ECH_CONFIRMATION_SIGNAL_LEN 8

// ssl_ech_confirmation_signal_hello_offset returns the offset of the ECH
// confirmation signal in a ServerHello message, including the handshake header.
size_t ssl_ech_confirmation_signal_hello_offset(const SSLImpl *ssl);

// ssl_ech_accept_confirmation computes the server's ECH acceptance signal,
// writing it to `out`. The transcript portion is the concatenation of
// `transcript` with `msg`. The `ECH_CONFIRMATION_SIGNAL_LEN` bytes from
// `offset` in `msg` are replaced with zeros before hashing. This function
// returns true on success, and false on failure.
bool ssl_ech_accept_confirmation(
    const SSL_HANDSHAKE *hs, Span<uint8_t, ECH_CONFIRMATION_SIGNAL_LEN> out,
    Span<const uint8_t, SSL3_RANDOM_SIZE> client_random,
    const SSLTranscript &transcript, bool is_hrr, Span<const uint8_t> msg,
    size_t offset);

// ssl_is_valid_ech_public_name returns true if `public_name` is a valid ECH
// public name and false otherwise. It is exported for testing.
bool ssl_is_valid_ech_public_name(Span<const uint8_t> public_name);

// ssl_is_valid_ech_config_list returns true if `ech_config_list` is a valid
// ECHConfigList structure and false otherwise.
bool ssl_is_valid_ech_config_list(Span<const uint8_t> ech_config_list);

// ssl_select_ech_config selects an ECHConfig and associated parameters to offer
// on the client and updates `hs`. It returns true on success, whether an
// ECHConfig was found or not, and false on internal error. On success, the
// encapsulated key is written to `out_enc` and `*out_enc_len` is set to the
// number of bytes written. If the function did not select an ECHConfig, the
// encapsulated key is the empty string.
bool ssl_select_ech_config(SSL_HANDSHAKE *hs, Span<uint8_t> out_enc,
                           size_t *out_enc_len);

// ssl_ech_extension_body_length returns the length of the body of a ClientHello
// ECH extension that encrypts `in_len` bytes with `aead` and an 'enc' value of
// length `enc_len`. The result does not include the four-byte extension header.
size_t ssl_ech_extension_body_length(const EVP_HPKE_AEAD *aead, size_t enc_len,
                                     size_t in_len);

// ssl_encrypt_client_hello constructs a new ClientHelloInner, adds it to the
// inner transcript, and encrypts for inclusion in the ClientHelloOuter. `enc`
// is the encapsulated key to include in the extension. It returns true on
// success and false on error. If not offering ECH, `enc` is ignored and the
// function will compute a GREASE ECH extension if necessary, and otherwise
// return success while doing nothing.
//
// Encrypting the ClientHelloInner incorporates all extensions in the
// ClientHelloOuter, so all other state necessary for `ssl_add_client_hello`
// must already be computed.
bool ssl_encrypt_client_hello(SSL_HANDSHAKE *hs, Span<const uint8_t> enc);


// Credentials.

enum class SSLCredentialType {
  kX509,
  kDelegated,
  kSPAKE2PlusV1Client,
  kSPAKE2PlusV1Server,
  kPreSharedKey,
  kRawPublicKey,
};

struct SSLTrustAnchorRange {
  Array<uint8_t> base;
  uint64_t min = 0;
  uint64_t max = 0;

  bool Contains(Span<const uint8_t> id) const;
};

class SSLCredential : public ssl_credential_st,
                      public RefCounted<SSLCredential> {
 public:
  explicit SSLCredential(SSLCredentialType type);
  SSLCredential(const SSLCredential &) = delete;
  SSLCredential &operator=(const SSLCredential &) = delete;

  // Dup returns a copy of the credential, or nullptr on error. The `ex_data`
  // values are not copied. This is only used on the legacy credential, whose
  // `ex_data` is inaccessible.
  UniquePtr<SSLCredential> Dup() const;

  // ClearCertAndKey erases any certificate and private key on the credential.
  void ClearCertAndKey();

  // UsesX509 returns true if the credential type uses an X.509 certificate.
  bool UsesX509() const;

  // UsesPrivateKey returns true if the credential type uses an asymmetric
  // private and public keypair.
  bool UsesPrivateKey() const;

  // IsComplete returns whether all required fields in the credential have been
  // filled in.
  bool IsComplete() const;

  // SetLeafCert sets the leaf certificate to `leaf`, leaving the remaining
  // certificates unmodified. It returns true on success and false on error. If
  // `discard_key_on_mismatch` is true and the private key is inconsistent with
  // the new leaf certificate, it is silently discarded.
  bool SetLeafCert(UniquePtr<CRYPTO_BUFFER> leaf, bool discard_key_on_mismatch);

  // ClearIntermediateCerts clears intermediate certificates in the certificate
  // chain, while preserving the leaf.
  void ClearIntermediateCerts();

  // AppendIntermediateCert appends `cert` to the certificate chain. If there is
  // no leaf certificate configured, it leaves a placeholder null in `chain`. It
  // returns one on success and zero on error.
  bool AppendIntermediateCert(UniquePtr<CRYPTO_BUFFER> cert);

  // ChainContainsIssuer returns true if `dn` is a byte for byte match with the
  // issuer of any certificate in `chain`, false otherwise.
  bool ChainContainsIssuer(Span<const uint8_t> dn) const;

  // type is the credential type and determines which other fields apply.
  SSLCredentialType type;

  // pubkey is the cached public key of the credential. Unlike `privkey`, it is
  // always present and is extracted from the certificate, delegated credential,
  // etc.
  UniquePtr<EVP_PKEY> pubkey;

  // privkey is the private key of the credential. It may be omitted in favor of
  // `key_method`.
  UniquePtr<EVP_PKEY> privkey;

  // key_method, if non-null, is a set of callbacks to call for private key
  // operations.
  const SSL_PRIVATE_KEY_METHOD *key_method = nullptr;

  // sigalgs, if non-empty, is the set of signature algorithms supported by the
  // private key in decreasing order of preference. If empty, the default list
  // is used.
  //
  // In delegated credentials, this field is not configurable and is instead
  // computed from the dc_cert_verify_algorithm field.
  Array<uint16_t> sigalgs;

  // chain contains the certificate chain, with the leaf at the beginning. The
  // first element of `chain` may be nullptr to indicate that the leaf
  // certificate has not yet been set.
  //   If `chain` != nullptr -> len(chain) >= 1
  //   If `chain[0]` == nullptr -> len(chain) >= 2.
  //   `chain[1..]` != nullptr
  UniquePtr<STACK_OF(CRYPTO_BUFFER)> chain;

  // dc is the DelegatedCredential structure, if this is a delegated credential.
  UniquePtr<CRYPTO_BUFFER> dc;

  // dc_algorithm is the signature scheme of the signature over the delegated
  // credential itself, made by the end-entity certificate's public key.
  uint16_t dc_algorithm = 0;

  // Signed certificate timestamp list to be sent to the client, if requested
  UniquePtr<CRYPTO_BUFFER> signed_cert_timestamp_list;

  // OCSP response to be sent to the client, if requested.
  UniquePtr<CRYPTO_BUFFER> ocsp_response;

  // SPAKE2+-specific information.
  Array<uint8_t> pake_context;
  Array<uint8_t> client_identity;
  Array<uint8_t> server_identity;
  Array<uint8_t> password_verifier_w0;
  Array<uint8_t> password_verifier_w1;  // server-only
  Array<uint8_t> registration_record;   // client-only
  mutable std::atomic<uint32_t> pake_limit;

  // External-PSK-specific information. epskx is the HKDF-Extract-ed value, from
  // Section 5.1 of RFC 9258.
  Array<uint8_t> epskx;
  Array<uint8_t> epsk_id;
  const EVP_MD *epsk_md = nullptr;
  Array<uint8_t> epsk_context;

  // Checks whether there are still permitted PAKE attempts remaining, without
  // changing the counter.
  bool HasPAKEAttempts() const;

  // Atomically decrement `pake_limit`. Return true if successful and false if
  // `pake_limit` is already zero.
  bool ClaimPAKEAttempt() const;

  // Atomically increment `pake_limit`. This must be paired with a
  // `ClaimPAKEAttempt` call.
  void RestorePAKEAttempt() const;

  // trust_anchor_id, if non-empty, is the trust anchor ID for the root of the
  // chain in `chain`.
  Array<uint8_t> trust_anchor_id;

  // trust_anchor_group_inclusions describes trust anchor groups that also match
  // this credential.
  Vector<SSLTrustAnchorRange> trust_anchor_group_inclusions;

  CRYPTO_EX_DATA ex_data;

  // must_match_issuer is a flag indicating that this credential should be
  // considered only when it matches a peer request for a particular issuer via
  // a negotiation mechanism (such as the certificate_authorities extension).
  // This also implies that chain is a certificate path ending in a certificate
  // issued by the certificate with that trust anchor identifier.
  bool must_match_issuer = false;

 private:
  friend RefCounted;
  ~SSLCredential();
};

// ssl_get_full_credential_list computes `hs`'s full credential list, including
// the legacy credential. On success, it writes it to `*out` and returns true.
// Otherwise, it returns false. The credential list may be empty, in which case
// this function will successfully output an empty array.
//
// This function should be called at most once during the handshake and is
// intended to be used for certificate-based credentials. It runs the
// auto-chaining logic as part of finishing the legacy credential. Other uses of
// the credential list (e.g. PAKE credentials) should iterate over
// `hs->config->cert->credentials`.
//
// The pointers in the result are only valid until `hs` is next mutated.
bool ssl_get_full_credential_list(SSL_HANDSHAKE *hs,
                                  Array<SSLCredential *> *out);

// ssl_credential_matches_requested_issuers returns true if `cred` is a
// usable match for any requested issuers in `hs`, and false with an error
// otherwise.
bool ssl_credential_matches_requested_issuers(SSL_HANDSHAKE *hs,
                                              const SSLCredential *cred);

// ssl_check_tls13_credential_ignoring_issuer returns true if `cred` is usable
// as the certificate in a TLS 1.3 handshake, ignoring the issuer check.
// `allowed_cert_types` is a nonempty set of cert types (`TLSEXT_cert_type_*`
// values) that are usable; `cred` must match one of these types.
// `out_sigalg` will be set to a matching signature algorithm if true is
// returned.
bool ssl_check_tls13_credential_ignoring_issuer(
    SSL_HANDSHAKE *hs, Span<const uint8_t> allowed_cert_types,
    const SSLCredential *cred, uint16_t *out_sigalg);


// Client certificate type & Server certificate type.

inline constexpr uint8_t kAllCertTypes[] = {
    TLSEXT_cert_type_x509,
    TLSEXT_cert_type_rpk,
};
inline constexpr size_t kNumCertTypes = std::size(kAllCertTypes);
inline constexpr uint8_t kDefaultCertType = TLSEXT_cert_type_x509;

// ssl_credential_type_to_cert_type returns the certificate type value
// (`TLSEXT_cert_type_*` value) corresponding to `cred_type`, or else
// std::nullopt.
std::optional<uint8_t> ssl_credential_type_to_cert_type(
    SSLCredentialType cred_type);

// ssl_setup_client_certificate_type computes the client cert types to offer, as
// a client, and saves them in `hs`. The values are used later when checking
// that the server responded with a valid value.
void ssl_setup_client_certificate_type(SSL_HANDSHAKE *hs);

// ssl_negotiate_client_certificate_type, for a server, negotiates the
// client_certificate_type extension, if applicable. It updates
// `hs->peer_cert_type` appropriately and returns true if negotiation was
// successful or not necessary (i.e. if we are not requesting a cert from the
// client), or it returns false and sets `*out_alert` to an alert on error.
bool ssl_negotiate_client_certificate_type(
    SSL_HANDSHAKE *hs, uint8_t *out_alert,
    const SSL_CLIENT_HELLO *client_hello);

// ssl_get_allowed_server_cert_types, for a server, returns the cert types that
// may be used based on the server_certificate_type extension in the
// ClientHello. It returns a nonempty list of allowable certificate types. By
// default, if the client did not send the extension, X.509 certificates are
// allowed. The returned cert types may include unrecognized values. Returns
// nullopt and sets `out_alert` on failure.
std::optional<Span<const uint8_t>> ssl_get_allowed_server_cert_types(
    const SSL_HANDSHAKE *hs, const SSL_CLIENT_HELLO *client_hello,
    uint8_t *out_alert);


// Handshake functions.

enum ssl_hs_wait_t {
  ssl_hs_error,
  ssl_hs_ok,
  ssl_hs_read_server_hello,
  ssl_hs_read_message,
  ssl_hs_flush,
  ssl_hs_certificate_selection_pending,
  ssl_hs_handoff,
  ssl_hs_handback,
  ssl_hs_x509_lookup,
  ssl_hs_private_key_operation,
  ssl_hs_pending_session,
  ssl_hs_pending_ticket,
  ssl_hs_early_return,
  ssl_hs_early_data_rejected,
  ssl_hs_read_end_of_early_data,
  ssl_hs_read_change_cipher_spec,
  ssl_hs_certificate_verify,
  ssl_hs_hints_ready,
};

enum ssl_grease_index_t {
  ssl_grease_cipher = 0,
  ssl_grease_group,
  ssl_grease_extension1,
  ssl_grease_extension2,
  ssl_grease_version,
  ssl_grease_ticket_extension,
  ssl_grease_ech_config_id,
  ssl_grease_signature_algorithm,
  ssl_grease_last_index = ssl_grease_signature_algorithm,
};

enum tls12_server_hs_state_t {
  state12_start_accept = 0,
  state12_read_client_hello,
  state12_read_client_hello_after_ech,
  state12_cert_callback,
  state12_tls13,
  state12_select_parameters,
  state12_send_server_hello,
  state12_send_server_certificate,
  state12_send_server_key_exchange,
  state12_send_server_hello_done,
  state12_read_client_certificate,
  state12_verify_client_certificate,
  state12_read_client_key_exchange,
  state12_read_client_certificate_verify,
  state12_read_change_cipher_spec,
  state12_process_change_cipher_spec,
  state12_read_next_proto,
  state12_read_channel_id,
  state12_read_client_finished,
  state12_send_server_finished,
  state12_finish_server_handshake,
  state12_done,
};

enum tls13_server_hs_state_t {
  state13_select_parameters = 0,
  state13_select_session,
  state13_send_hello_retry_request,
  state13_read_second_client_hello,
  state13_send_server_hello,
  state13_send_server_certificate_verify,
  state13_send_server_finished,
  state13_send_half_rtt_ticket,
  state13_read_second_client_flight,
  state13_process_end_of_early_data,
  state13_read_client_encrypted_extensions,
  state13_read_client_certificate,
  state13_read_client_certificate_verify,
  state13_read_channel_id,
  state13_read_client_finished,
  state13_send_new_session_ticket,
  state13_done,
};

// handback_t lists the points in the state machine where a handback can occur.
// These are the different points at which key material is no longer needed.
enum handback_t {
  handback_after_session_resumption = 0,
  handback_after_ecdhe = 1,
  handback_after_handshake = 2,
  handback_tls13 = 3,
  handback_max_value = handback_tls13,
};

// SSL_HANDSHAKE_HINTS contains handshake hints for a connection. See
// `SSL_request_handshake_hints` and related functions.
struct SSL_HANDSHAKE_HINTS {
  static constexpr bool kAllowUniquePtr = true;

  Array<uint8_t> server_random_tls12;
  Array<uint8_t> server_random_tls13;

  uint16_t key_share_group_id = 0;
  Array<uint8_t> key_share_ciphertext;
  Array<uint8_t> key_share_secret;

  uint16_t signature_algorithm = 0;
  Array<uint8_t> signature_input;
  Array<uint8_t> signature_spki;
  Array<uint8_t> signature;

  Array<uint8_t> decrypted_psk;
  bool ignore_psk = false;

  uint16_t cert_compression_alg_id = 0;
  Array<uint8_t> cert_compression_input;
  Array<uint8_t> cert_compression_output;

  uint16_t ecdhe_group_id = 0;
  Array<uint8_t> ecdhe_public_key;
  Array<uint8_t> ecdhe_private_key;

  Array<uint8_t> decrypted_ticket;
  bool renew_ticket = false;
  bool ignore_ticket = false;
};

struct SSLPAKEShare {
  static constexpr bool kAllowUniquePtr = true;
  uint16_t named_pake;
  Array<uint8_t> client_identity;
  Array<uint8_t> server_identity;
  Array<uint8_t> pake_message;
};

struct SSL_HANDSHAKE {
  explicit SSL_HANDSHAKE(SSLImpl *ssl);
  ~SSL_HANDSHAKE();
  static constexpr bool kAllowUniquePtr = true;

  // ssl is a non-owning pointer to the parent `SSL` object.
  SSLImpl *ssl;

  // config is a non-owning pointer to the handshake configuration.
  SSL_CONFIG *config;

  // wait contains the operation the handshake is currently blocking on or
  // `ssl_hs_ok` if none.
  enum ssl_hs_wait_t wait = ssl_hs_ok;

  // state is the internal state for the TLS 1.2 and below handshake. Its
  // values depend on `do_handshake` but the starting state is always zero.
  int state = 0;

  // tls13_state is the internal state for the TLS 1.3 handshake. Its values
  // depend on `do_handshake` but the starting state is always zero.
  int tls13_state = 0;

  // min_version is the minimum accepted protocol version, taking account both
  // `SSL_OP_NO_*` and `SSL_CTX_set_min_proto_version` APIs.
  uint16_t min_version = 0;

  // max_version is the maximum accepted protocol version, taking account both
  // `SSL_OP_NO_*` and `SSL_CTX_set_max_proto_version` APIs.
  uint16_t max_version = 0;

  InplaceVector<uint8_t, SSL_MAX_MD_SIZE> secret;
  InplaceVector<uint8_t, SSL_MAX_MD_SIZE> early_traffic_secret;
  InplaceVector<uint8_t, SSL_MAX_MD_SIZE> client_handshake_secret;
  InplaceVector<uint8_t, SSL_MAX_MD_SIZE> server_handshake_secret;
  InplaceVector<uint8_t, SSL_MAX_MD_SIZE> client_traffic_secret_0;
  InplaceVector<uint8_t, SSL_MAX_MD_SIZE> server_traffic_secret_0;
  InplaceVector<uint8_t, SSL_MAX_MD_SIZE> expected_client_finished;

  // GetClientHello, on the server, returns either the normal ClientHello
  // message or the ClientHelloInner if it has been serialized to
  // `ech_client_hello_buf`. This function should only be called when the
  // current message is a ClientHello. It returns true on success and false on
  // error.
  //
  // Note that fields of the returned `out_msg` and `out_client_hello` point
  // into a handshake-owned buffer, so their lifetimes should not exceed this
  // SSL_HANDSHAKE.
  bool GetClientHello(SSLMessage *out_msg, SSL_CLIENT_HELLO *out_client_hello);

  union {
    // sent is a bitset where the bits correspond to elements of kExtensions
    // in extensions.cc. Each bit is set if that extension was sent in a
    // ClientHello. It's not used by servers.
    uint32_t sent = 0;
    // received is a bitset, like `sent`, but is used by servers to record
    // which extensions were received from a client.
    uint32_t received;
  } extensions;

  // inner_extensions_sent, on clients that offer ECH, is `extensions.sent` for
  // the ClientHelloInner.
  uint32_t inner_extensions_sent = 0;

  // early_data_written is the amount of early data that has been written by the
  // record layer.
  uint32_t early_data_written = 0;

  // error, if `wait` is `ssl_hs_error`, is the error the handshake failed on.
  UniquePtr<ERR_SAVE_STATE> error;

  // key_shares are the current key exchange instances, in preference order. Any
  // members of this vector must be non-null.
  InplaceVector<UniquePtr<SSLKeyShare>, kNumNamedGroups> key_shares;

  // pre_shared_keys are the pre-shared keys to be offered by the client.
  Vector<SSLPreSharedKey> pre_shared_keys;

  // pre_shared_key is the selected pre-shared key on the server.
  UniquePtr<SSLPreSharedKey> pre_shared_key;

  // selected_psk_index is the index of the selected pre-shared key on the
  // server.
  std::optional<uint16_t> selected_psk_index;

  // transcript is the current handshake transcript.
  SSLTranscript transcript;

  // inner_transcript, on the client, is the handshake transcript for the
  // ClientHelloInner handshake. It is moved to `transcript` if the server
  // accepts ECH.
  SSLTranscript inner_transcript;

  // inner_client_random is the ClientHello random value used with
  // ClientHelloInner.
  uint8_t inner_client_random[SSL3_RANDOM_SIZE] = {0};

  // cookie is the value of the cookie in HelloRetryRequest, or empty if none
  // was received.
  Array<uint8_t> cookie;

  // dtls_cookie is the value of the cookie in DTLS HelloVerifyRequest. If
  // empty, either none was received or HelloVerifyRequest contained an empty
  // cookie. Check the received_hello_verify_request field to distinguish an
  // empty cookie from no HelloVerifyRequest message being received.
  Array<uint8_t> dtls_cookie;

  // ech_client_outer contains the outer ECH extension to send in the
  // ClientHello, excluding the header and type byte.
  Array<uint8_t> ech_client_outer;

  // ech_retry_configs, on the client, contains the retry configs from the
  // server as a serialized ECHConfigList.
  Array<uint8_t> ech_retry_configs;

  // ech_client_hello_buf, on the server, contains the bytes of the
  // reconstructed ClientHelloInner message.
  Array<uint8_t> ech_client_hello_buf;

  // key_share_bytes is the key_share extension that the client should send.
  Array<uint8_t> key_share_bytes;

  // key_share_ciphertext, for servers, is encapsulated shared secret to be sent
  // to the client in the TLS 1.3 key_share extension.
  Array<uint8_t> key_share_ciphertext;

  // peer_sigalgs are the signature algorithms that the peer supports. These are
  // taken from the contents of the signature algorithms extension for a server
  // or from the CertificateRequest for a client.
  Array<uint16_t> peer_sigalgs;

  // peer_supported_group_list contains the supported group IDs advertised by
  // the peer. This is only set on the server's end. The server does not
  // advertise this extension to the client.
  Array<uint16_t> peer_supported_group_list;

  // peer_delegated_credential_sigalgs are the signature algorithms the peer
  // supports with delegated credentials, or empty if the peer does not support
  // delegated credentials.
  Array<uint16_t> peer_delegated_credential_sigalgs;

  // peer_key is the peer's ECDH key for a TLS 1.2 client.
  Array<uint8_t> peer_key;

  // extension_permutation is the permutation to apply to ClientHello
  // extensions. It maps indices into the `kExtensions` table into other
  // indices.
  Array<uint8_t> extension_permutation;

  // cert_compression_alg_id, for a server, contains the negotiated certificate
  // compression algorithm for this client. It is only valid if
  // `cert_compression_negotiated` is true.
  uint16_t cert_compression_alg_id;

  // ech_hpke_ctx is the HPKE context used in ECH. On the server, it is
  // initialized if `ech_status` is `ssl_ech_accepted`. On the client, it is
  // initialized if `selected_ech_config` is not nullptr.
  ScopedEVP_HPKE_CTX ech_hpke_ctx;

  // server_params, in a TLS 1.2 server, stores the ServerKeyExchange
  // parameters. It has client and server randoms prepended for signing
  // convenience.
  Array<uint8_t> server_params;

  // peer_psk_identity_hint, on the client, is the psk_identity_hint sent by the
  // server when using a TLS 1.2 PSK key exchange.
  UniquePtr<char> peer_psk_identity_hint;

  // ca_names contains the list of CAs received via the Certificate Authorities
  // extension in our peer's CertificateRequest or ClientHello message
  UniquePtr<STACK_OF(CRYPTO_BUFFER)> ca_names;

  // peer_requested_trust_anchors, if not nullopt, contains the trust anchor IDs
  // (possibly none) the peer requested in ClientHello or CertificateRequest. If
  // nullopt, the peer did not send the extension.
  std::optional<Array<uint8_t>> peer_requested_trust_anchors;

  // peer_available_trust_anchors, if not empty, is the list of trust anchor IDs
  // the peer reported as available in EncryptedExtensions. This is only sent by
  // servers to clients.
  Array<uint8_t> peer_available_trust_anchors;

  // cached_x509_ca_names contains a cache of parsed versions of the elements of
  // `ca_names`. This pointer is left non-owning so only
  // `ssl_crypto_x509_method` needs to link against crypto/x509.
  STACK_OF(X509_NAME) *cached_x509_ca_names = nullptr;

  // certificate_types, on the client, contains the set of certificate types
  // received in a CertificateRequest message.
  Array<uint8_t> certificate_types;

  // credential is the credential we are using for the handshake.
  UniquePtr<SSLCredential> credential;

  // peer_pubkey is the public key parsed from the peer's leaf certificate.
  UniquePtr<EVP_PKEY> peer_pubkey;

  // new_session is the new mutable session being established by the current
  // handshake. It should not be cached.
  UniquePtr<SSL_SESSION> new_session;

  // early_session is the session corresponding to the current 0-RTT state on
  // the client if `in_early_data` is true.
  UniquePtr<SSL_SESSION> early_session;

  // ssl_ech_keys, for servers, is the set of ECH keys to use with this
  // handshake. This is copied from `SSL_CTX` to ensure consistent behavior as
  // `SSL_CTX` rotates keys.
  UniquePtr<SSLECHKeys> ech_keys;

  // selected_ech_config, for clients, is the ECHConfig the client uses to offer
  // ECH, or nullptr if ECH is not being offered. If non-NULL, `ech_hpke_ctx`
  // will be initialized.
  UniquePtr<ECHConfig> selected_ech_config;

  // new_cipher is the cipher being negotiated in this handshake.
  const SSL_CIPHER *new_cipher = nullptr;

  // key_block is the record-layer key block for TLS 1.2 and earlier.
  Array<uint8_t> key_block;

  // pending_hints, if non-null, contains the pending hints to filled as the
  // predicted handshake progresses. If non-null, only the first round-trip of
  // the handshake will complete, after which the `pending_hints` structure can
  // be serialized.
  UniquePtr<SSL_HANDSHAKE_HINTS> pending_hints;

  // provided_hints, if non-null, contains hints configured by the caller
  // and will influence the (real or predicted) handshake on match.
  UniquePtr<SSL_HANDSHAKE_HINTS> provided_hints;

  // ech_is_inner, on the server, indicates whether the ClientHello contained an
  // inner ECH extension.
  bool ech_is_inner : 1;

  // ech_authenticated_reject, on the client, indicates whether an ECH rejection
  // handshake has been authenticated.
  bool ech_authenticated_reject : 1;

  // scts_requested is true if the SCT extension is in the ClientHello.
  bool scts_requested : 1;

  // handshake_finalized is true once the handshake has completed, at which
  // point accessors should use the established state.
  bool handshake_finalized : 1;

  // accept_psk_mode stores whether the client's PSK mode is compatible with our
  // preferences.
  bool accept_psk_mode : 1;

  // cert_request is true if a client certificate was requested.
  bool cert_request : 1;

  // certificate_status_expected is true if OCSP stapling was negotiated and the
  // server is expected to send a CertificateStatus message. (This is used on
  // both the client and server sides.)
  bool certificate_status_expected : 1;

  // ocsp_stapling_requested is true if a client requested OCSP stapling.
  bool ocsp_stapling_requested : 1;

  // should_ack_sni is used by a server and indicates that the SNI extension
  // should be echoed in the ServerHello.
  bool should_ack_sni : 1;

  // in_false_start is true if there is a pending client handshake in False
  // Start. The client may write data at this point.
  bool in_false_start : 1;

  // in_early_data is true if there is a pending handshake that has progressed
  // enough to send and receive early data.
  bool in_early_data : 1;

  // early_data_offered is true if the client sent the early_data extension.
  bool early_data_offered : 1;

  // can_early_read is true if application data may be read at this point in the
  // handshake.
  bool can_early_read : 1;

  // can_early_write is true if application data may be written at this point in
  // the handshake.
  bool can_early_write : 1;

  // is_early_version is true if the protocol version configured is not
  // necessarily the final version and is just the predicted 0-RTT version.
  bool is_early_version : 1;

  // next_proto_neg_seen is one of NPN was negotiated.
  bool next_proto_neg_seen : 1;

  // ticket_expected is true if a TLS 1.2 NewSessionTicket message is to be sent
  // or received.
  bool ticket_expected : 1;

  // extended_master_secret is true if the extended master secret extension is
  // negotiated in this handshake.
  bool extended_master_secret : 1;

  // pending_private_key_op is true if there is a pending private key operation
  // in progress.
  bool pending_private_key_op : 1;

  // handback indicates that a server should pause the handshake after
  // finishing operations that require private key material, in such a way that
  // `SSL_get_error` returns `SSL_ERROR_HANDBACK`.  It is set by
  // `SSL_apply_handoff`.
  bool handback : 1;

  // cert_compression_negotiated is true iff `cert_compression_alg_id` is valid.
  bool cert_compression_negotiated : 1;

  // apply_jdk11_workaround is true if the peer is probably a JDK 11 client
  // which implemented TLS 1.3 incorrectly.
  bool apply_jdk11_workaround : 1;

  // can_release_private_key is true if the private key will no longer be used
  // in this handshake.
  bool can_release_private_key : 1;

  // channel_id_negotiated is true if Channel ID should be used in this
  // handshake.
  bool channel_id_negotiated : 1;

  // received_hello_verify_request is true if we received a HelloVerifyRequest
  // message from the server.
  bool received_hello_verify_request : 1;

  // matched_peer_trust_anchor indicates that we have matched a trust anchor
  // the peer requested in the trust anchors extension.
  bool matched_peer_trust_anchor : 1;

  // peer_matched_trust_anchor is true if the peer indicated a match with one of
  // our requested trust anchors.
  bool peer_matched_trust_anchor : 1;

  // client_version is the value sent or received in the ClientHello version.
  uint16_t client_version = 0;

  // early_data_read is the amount of early data that has been read by the
  // record layer.
  uint16_t early_data_read = 0;

  // signature_algorithm is the signature algorithm to be used in signing with
  // the selected credential, or zero if not applicable or not yet selected.
  uint16_t signature_algorithm = 0;

  // ech_config_id is the ECH config sent by the client.
  uint8_t ech_config_id = 0;

  // session_id is the session ID in the ClientHello.
  InplaceVector<uint8_t, SSL_MAX_SSL_SESSION_ID_LENGTH> session_id;

  // grease_seed is the entropy for GREASE values.
  uint8_t grease_seed[ssl_grease_last_index + 1] = {0};

  // pake_share is the PAKE message received over the wire, if any.
  UniquePtr<SSLPAKEShare> pake_share;

  // pake_share_bytes are the bytes of the PAKEShare to send, if any.
  Array<uint8_t> pake_share_bytes;

  // pake_prover is the PAKE context for a client.
  UniquePtr<spake2plus::Prover> pake_prover;

  // pake_verifier is the PAKE context for a server.
  UniquePtr<spake2plus::Verifier> pake_verifier;

  // offered_client_cert_types, for a client, is a list of client certificate
  // types (`TLSEXT_cert_type_*` values) that were sent in the
  // client_certificate_type extension in the ClientHello.
  InplaceVector<uint8_t, kNumCertTypes> offered_client_cert_types;

  // peer_cert_type, is the cert type expected from the peer in this handshake,
  // negotiated based on server_certificate_type extensions (for a client) or
  // client_certificate_type extensions (for a server), or set to X.509
  // certificates by default (if the peer didn't send the extension).
  // This is not used in resumption.
  uint8_t peer_cert_type = kDefaultCertType;

  // client_cert_type, for a client, is the cert type for this side of the
  // handshake to present to the peer (server) in a Certificate message,
  // negotiated based on client_certificate_type extensions.
  // This is not used in resumption.
  uint8_t client_cert_type = kDefaultCertType;

  // client_requested_server_cert_padding_size, for a server, is the number of
  // bytes that the client requested we send, or nullopt if the client did not
  // request any padding.
  std::optional<uint16_t> client_requested_server_padding_size;
};

// kMaxTickets is the maximum number of tickets to send immediately after the
// handshake. We use a one-byte ticket nonce, and there is no point in sending
// so many tickets.
constexpr size_t kMaxTickets = 16;

UniquePtr<SSL_HANDSHAKE> ssl_handshake_new(SSLImpl *ssl);

// ssl_check_message_type checks if `msg` has type `type`. If so it returns
// one. Otherwise, it sends an alert and returns zero.
bool ssl_check_message_type(SSLImpl *ssl, const SSLMessage &msg, int type);

// ssl_run_handshake runs the TLS handshake. It returns one on success and <= 0
// on error. It sets `out_early_return` to one if we've completed the handshake
// early.
int ssl_run_handshake(SSL_HANDSHAKE *hs, bool *out_early_return);

// The following are implementations of `do_handshake` for the client and
// server.
enum ssl_hs_wait_t ssl_client_handshake(SSL_HANDSHAKE *hs);
enum ssl_hs_wait_t ssl_server_handshake(SSL_HANDSHAKE *hs);
enum ssl_hs_wait_t tls13_client_handshake(SSL_HANDSHAKE *hs);
enum ssl_hs_wait_t tls13_server_handshake(SSL_HANDSHAKE *hs);

// The following functions return human-readable representations of the TLS
// handshake states for debugging.
const char *ssl_client_handshake_state(SSL_HANDSHAKE *hs);
const char *ssl_server_handshake_state(SSL_HANDSHAKE *hs);
const char *tls13_client_handshake_state(SSL_HANDSHAKE *hs);
const char *tls13_server_handshake_state(SSL_HANDSHAKE *hs);

// tls13_add_key_update queues a KeyUpdate message on `ssl`. `request_type` must
// be one of `SSL_KEY_UPDATE_REQUESTED` or `SSL_KEY_UPDATE_NOT_REQUESTED`.
bool tls13_add_key_update(SSLImpl *ssl, int request_type);

// tls13_post_handshake processes a post-handshake message. It returns true on
// success and false on failure.
bool tls13_post_handshake(SSLImpl *ssl, const SSLMessage &msg);

bool tls13_process_certificate(SSL_HANDSHAKE *hs, const SSLMessage &msg,
                               bool allow_anonymous);
bool tls13_process_certificate_verify(SSL_HANDSHAKE *hs, const SSLMessage &msg);

// tls13_process_finished processes `msg` as a Finished message from the
// peer. If `use_saved_value` is true, the verify_data is compared against
// `hs->expected_client_finished` rather than computed fresh.
bool tls13_process_finished(SSL_HANDSHAKE *hs, const SSLMessage &msg,
                            bool use_saved_value);

bool tls13_add_certificate(SSL_HANDSHAKE *hs);

// tls13_add_certificate_verify adds a TLS 1.3 CertificateVerify message to the
// handshake. If it returns `ssl_private_key_retry`, it should be called again
// to retry when the signing operation is completed.
enum ssl_private_key_result_t tls13_add_certificate_verify(SSL_HANDSHAKE *hs);

bool tls13_add_finished(SSL_HANDSHAKE *hs);
bool tls13_process_new_session_ticket(SSLImpl *ssl, const SSLMessage &msg);
UniquePtr<SSL_SESSION> tls13_create_session_with_ticket(SSLImpl *ssl,
                                                        CBS *body);

// ssl_setup_extension_permutation computes a ClientHello extension permutation
// for `hs`, if applicable. It returns true on success and false on error.
bool ssl_setup_extension_permutation(SSL_HANDSHAKE *hs);

// ssl_setup_pre_shared_keys computes the offered client PSKs and saves them in
// `hs`. It returns true on success and false on failure.
bool ssl_setup_pre_shared_keys(SSL_HANDSHAKE *hs);

// ssl_setup_key_shares computes client key shares and saves them in `hs`. It
// returns true on success and false on failure. In order of precedence:
//
// - If `override_group_id` is non-zero, it offers a single key share of the
//   specified group.
//
// - If a group can be predicted on the basis of a server hint set via
//   `SSL_set1_server_supported_groups_hint`, a single key share of that group
//   is sent.
//
// - If any number of key shares (including zero) were previously specified by
//   the caller via `SSL_set1_client_key_shares`, those are used.
//
// - Otherwise, it selects the first supported group and may select a second if
//   at most one of the two is a post-quantum group.
//
// GREASE will be included if enabled, when `override_group_id` is zero.
bool ssl_setup_key_shares(SSL_HANDSHAKE *hs, uint16_t override_group_id);

// ssl_setup_pake_shares computes the client PAKE shares and saves them in `hs`.
// It returns true on success and false on failure.
bool ssl_setup_pake_shares(SSL_HANDSHAKE *hs);

bool ssl_ext_key_share_parse_serverhello(SSL_HANDSHAKE *hs,
                                         Array<uint8_t> *out_secret,
                                         uint8_t *out_alert, CBS *contents);
bool ssl_ext_key_share_parse_clienthello(SSL_HANDSHAKE *hs, bool *out_found,
                                         Span<const uint8_t> *out_peer_key,
                                         uint8_t *out_alert,
                                         const SSL_CLIENT_HELLO *client_hello);
bool ssl_ext_pake_add_serverhello(SSL_HANDSHAKE *hs, CBB *out);
bool ssl_ext_key_share_add_serverhello(SSL_HANDSHAKE *hs, CBB *out);

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

struct SSLOfferedPSK {
  CBS identity, binder;
  uint32_t obfuscated_ticket_age;
};

struct SSLOfferedPSKs {
  CBS identities, binders;
  std::optional<SSLOfferedPSK> Next();
};

const SSLPreSharedKey *ssl_ext_pre_shared_key_parse_serverhello(
    SSL_HANDSHAKE *hs, uint8_t *out_alert, CBS *contents);
std::optional<SSLOfferedPSKs> ssl_ext_pre_shared_key_parse_clienthello(
    SSL_HANDSHAKE *hs, uint8_t *out_alert, const SSL_CLIENT_HELLO *client_hello,
    CBS *contents);

// ssl_verify_psk_binder verifies `client_hello` has a valid binder for `psk`.
// The binder is computed with `client_hello` and `hs`'s transcript, which
// should not have `client_hello` in it. On success, it returns true. Otherwise,
// it returns false and sets `*out_alert` to an alert to send.
//
// This function additionally saves the index where `psk` was found in `hs`. It
// must be called before `ssl_ext_pre_shared_key_add_serverhello`.
bool ssl_verify_psk_binder(SSL_HANDSHAKE *hs, uint8_t *out_alert,
                           const SSLPreSharedKey &psk,
                           const SSL_CLIENT_HELLO &client_hello);

bool ssl_ext_pre_shared_key_add_serverhello(SSL_HANDSHAKE *hs, CBB *out);


// ssl_is_sct_list_valid does a shallow parse of the SCT list in `contents` and
// returns whether it's valid.
bool ssl_is_sct_list_valid(const CBS *contents);

// ssl_write_client_hello_without_extensions writes a ClientHello to `out`,
// up to the extensions field. `type` determines the type of ClientHello to
// write. If `omit_session_id` is true, the session ID is empty.
bool ssl_write_client_hello_without_extensions(const SSL_HANDSHAKE *hs,
                                               CBB *cbb,
                                               ssl_client_hello_type_t type,
                                               bool empty_session_id);

// ssl_add_client_hello constructs a ClientHello and adds it to the outgoing
// flight. It returns true on success and false on error.
bool ssl_add_client_hello(SSL_HANDSHAKE *hs);

struct ParsedServerHello {
  CBS raw;
  uint16_t legacy_version = 0;
  CBS random;
  CBS session_id;
  uint16_t cipher_suite = 0;
  uint8_t compression_method = 0;
  CBS extensions;
};

// ssl_parse_server_hello parses `msg` as a ServerHello. On success, it writes
// the result to `*out` and returns true. Otherwise, it returns false and sets
// `*out_alert` to an alert to send to the peer.
bool ssl_parse_server_hello(ParsedServerHello *out, uint8_t *out_alert,
                            const SSLMessage &msg);

enum ssl_cert_verify_context_t {
  ssl_cert_verify_server,
  ssl_cert_verify_client,
  ssl_cert_verify_channel_id,
};

// tls13_get_cert_verify_signature_input generates the message to be signed for
// TLS 1.3's CertificateVerify message. `cert_verify_context` determines the
// type of signature. It sets `*out` to a newly allocated buffer containing the
// result. This function returns true on success and false on failure.
bool tls13_get_cert_verify_signature_input(
    SSL_HANDSHAKE *hs, Array<uint8_t> *out,
    enum ssl_cert_verify_context_t cert_verify_context);

// ssl_is_valid_alpn_list returns whether `in` is a valid ALPN protocol list.
bool ssl_is_valid_alpn_list(Span<const uint8_t> in);

// ssl_is_alpn_protocol_allowed returns whether `protocol` is a valid server
// selection for `hs->ssl`'s client preferences.
bool ssl_is_alpn_protocol_allowed(const SSL_HANDSHAKE *hs,
                                  Span<const uint8_t> protocol);

// ssl_alpn_list_contains_protocol returns whether `list`, a serialized ALPN
// protocol list, contains `protocol`.
bool ssl_alpn_list_contains_protocol(Span<const uint8_t> list,
                                     Span<const uint8_t> protocol);

// ssl_negotiate_alpn negotiates the ALPN extension, if applicable. It returns
// true on successful negotiation or if nothing was negotiated. It returns false
// and sets `*out_alert` to an alert on error.
bool ssl_negotiate_alpn(SSL_HANDSHAKE *hs, uint8_t *out_alert,
                        const SSL_CLIENT_HELLO *client_hello);

// ssl_get_local_application_settings looks up the configured ALPS value for
// `protocol`. If found, it sets `*out_settings` to the value and returns true.
// Otherwise, it returns false.
bool ssl_get_local_application_settings(const SSL_HANDSHAKE *hs,
                                        Span<const uint8_t> *out_settings,
                                        Span<const uint8_t> protocol);

// ssl_negotiate_alps negotiates the ALPS extension, if applicable. It returns
// true on successful negotiation or if nothing was negotiated. It returns false
// and sets `*out_alert` to an alert on error.
bool ssl_negotiate_alps(SSL_HANDSHAKE *hs, uint8_t *out_alert,
                        const SSL_CLIENT_HELLO *client_hello);

// ssl_is_valid_trust_anchor_list returns whether `in` is a valid trust anchor
// identifiers list.
bool ssl_is_valid_trust_anchor_list(Span<const uint8_t> in);

struct SSLExtension {
  SSLExtension(uint16_t type_arg, bool allowed_arg = true)
      : type(type_arg), allowed(allowed_arg), present(false) {
    CBS_init(&data, nullptr, 0);
  }

  uint16_t type;
  bool allowed;
  bool present;
  CBS data;
};

// ssl_parse_extensions parses a TLS extensions block out of `cbs` and advances
// it. It writes the parsed extensions to pointers in `extensions`. On success,
// it fills in the `present` and `data` fields and returns true. Otherwise, it
// sets `*out_alert` to an alert to send and returns false. Unknown extensions
// are rejected unless `ignore_unknown` is true.
bool ssl_parse_extensions(const CBS *cbs, uint8_t *out_alert,
                          std::initializer_list<SSLExtension *> extensions,
                          bool ignore_unknown);

// ssl_verify_peer_cert verifies the peer certificate for `hs`.
enum ssl_verify_result_t ssl_verify_peer_cert(SSL_HANDSHAKE *hs);
// ssl_reverify_peer_cert verifies the peer certificate for `hs` when resuming a
// session.
enum ssl_verify_result_t ssl_reverify_peer_cert(SSL_HANDSHAKE *hs,
                                                bool send_alert);

enum ssl_hs_wait_t ssl_get_finished(SSL_HANDSHAKE *hs);

// ssl_send_finished adds a Finished message to the current flight of messages.
// It returns true on success and false on error.
bool ssl_send_finished(SSL_HANDSHAKE *hs);

// ssl_send_tls12_certificate adds a TLS 1.2 Certificate message to the current
// flight of messages. It returns true on success and false on error.
bool ssl_send_tls12_certificate(SSL_HANDSHAKE *hs);

// ssl_handshake_session returns the `SSL_SESSION` corresponding to the current
// handshake. Note, in TLS 1.2 resumptions, this session is immutable.
const SSL_SESSION *ssl_handshake_session(const SSL_HANDSHAKE *hs);

// ssl_done_writing_client_hello is called after the last ClientHello is written
// by `hs`. It releases some memory that is no longer needed.
void ssl_done_writing_client_hello(SSL_HANDSHAKE *hs);

// ssl_accepts_server_certificate_auth returns whether `hs`, which must be a
// client, accepts certificate-based authentication. If it returns false, the
// client should not send certificate-related extensions, and should not accept
// server responses that result in a certificate-based flow.
bool ssl_accepts_server_certificate_auth(const SSL_HANDSHAKE *hs);


// Flags.

// SSLFlags is a bitmask of flags that can be encoded with the TLS flags
// extension, draft-ietf-tls-tlsflags-14. For now, our in-memory representation
// matches the wire representation, and we only support flags up to 32. If
// higher values are needed, we can increase the size of the bitmask, or only
// store the flags we implement in the bitmask.
using SSLFlags = uint32_t;
inline constexpr SSLFlags kSSLFlagResumptionAcrossNames = 1 << 8;

// ssl_add_flags_extension encodes a tls_flags extension (including the header)
// containing the flags in `flags`. It returns true on success and false on
// error. If `flags` is zero (no flags set), it returns true without adding
// anything to `cbb`.
bool ssl_add_flags_extension(CBB *cbb, SSLFlags flags);

// ssl_parse_flags_extension_request parses tls_flags extension value (excluding
// the header) from `cbs`, for a request message (ClientHello,
// CertificateRequest, or NewSessionTicket). Unrecognized flags will be ignored.
//
// On success, it sets `*out` to the parsed flags and returns true. On error, it
// sets `*out_alert` to a TLS alert and returns false.
bool ssl_parse_flags_extension_request(const CBS *cbs, SSLFlags *out,
                                       uint8_t *out_alert);

// ssl_parse_flags_extension_response parses tls_flags extension value
// (excluding the header) from `cbs`, for a response message (HelloRetryRequest,
// ServerHello, EncryptedExtensions, or Certificate). Only the flags in
// `allowed_flags` may be present.
//
// On success, it sets `*out` to the parsed flags and returns true. On error, it
// sets `*out_alert` to a TLS alert and returns false.
bool ssl_parse_flags_extension_response(const CBS *cbs, SSLFlags *out,
                                        uint8_t *out_alert,
                                        SSLFlags allowed_flags);


// SSLKEYLOGFILE functions.

// ssl_log_secret logs `secret` with label `label`, if logging is enabled for
// `ssl`. It returns true on success and false on failure.
bool ssl_log_secret(const SSLImpl *ssl, const char *label,
                    Span<const uint8_t> secret);


// ClientHello functions.

bool ssl_parse_client_hello_with_trailing_data(const SSLImpl *ssl, CBS *cbs,
                                               SSL_CLIENT_HELLO *out);

bool ssl_client_hello_get_extension(const SSL_CLIENT_HELLO *client_hello,
                                    CBS *out, uint16_t extension_type);

bool ssl_client_cipher_list_contains_cipher(
    const SSL_CLIENT_HELLO *client_hello, uint16_t id);


// GREASE.

// ssl_get_grease_value returns a GREASE value for `hs`. For a given
// connection, the values for each index will be deterministic. This allows the
// same ClientHello be sent twice for a HelloRetryRequest or the same group be
// advertised in both supported_groups and key_shares.
uint16_t ssl_get_grease_value(const SSL_HANDSHAKE *hs,
                              enum ssl_grease_index_t index);


// Signature algorithms.

// tls1_parse_peer_sigalgs parses `sigalgs` as the list of peer signature
// algorithms and saves them on `hs`. It returns true on success and false on
// error.
bool tls1_parse_peer_sigalgs(SSL_HANDSHAKE *hs, const CBS *sigalgs);

// tls1_get_legacy_signature_algorithm sets `*out` to the signature algorithm
// that should be used with `pkey` in TLS 1.1 and earlier. It returns true on
// success and false if `pkey` may not be used at those versions.
bool tls1_get_legacy_signature_algorithm(uint16_t *out, const EVP_PKEY *pkey);

// tls1_choose_signature_algorithm sets `*out` to a signature algorithm for use
// with `cred` based on the peer's preferences and the algorithms supported. It
// returns true on success and false on error.
bool tls1_choose_signature_algorithm(SSL_HANDSHAKE *hs,
                                     const SSLCredential *cred, uint16_t *out);

// tls12_add_verify_sigalgs adds the signature algorithms acceptable for the
// peer signature to `out`. It returns true on success and false on error.
bool tls12_add_verify_sigalgs(const SSL_HANDSHAKE *hs, CBB *out);

// tls12_check_peer_sigalg checks if `sigalg` is acceptable for the peer
// signature from `pkey`. It returns true on success and false on error, setting
// `*out_alert` to an alert to send.
bool tls12_check_peer_sigalg(const SSL_HANDSHAKE *hs, uint8_t *out_alert,
                             uint16_t sigalg, EVP_PKEY *pkey);


// Underdocumented functions.
//
// Functions below here haven't been touched up and may be underdocumented.

#define TLSEXT_CHANNEL_ID_SIZE 128

// From RFC 4492, used in encoding the curve type in ECParameters
#define NAMED_CURVE_TYPE 3

struct CERT {
  static constexpr bool kAllowUniquePtr = true;

  explicit CERT(const SSL_X509_METHOD *x509_method);
  ~CERT();

  bool is_valid() const { return legacy_credential != nullptr; }

  // credentials is the list of credentials to select between. Elements of this
  // array immutable.
  Vector<UniquePtr<SSLCredential>> credentials;

  // legacy_credential is the credential configured by the legacy
  // non-credential-based APIs. If IsComplete() returns true, it is appended to
  // the list of credentials.
  UniquePtr<SSLCredential> legacy_credential;

  // available_trust_anchors, if not empty, overrides the default list of
  // available trust anchors to send in EncryptedExtensions.
  Array<uint8_t> available_trust_anchors;

  // x509_method contains pointers to functions that might deal with `X509`
  // compatibility, or might be a no-op, depending on the application.
  const SSL_X509_METHOD *x509_method = nullptr;

  // x509_chain may contain a parsed copy of `chain[1..]` from the legacy
  // credential. This is only used as a cache in order to implement “get0”
  // functions that return a non-owning pointer to the certificate chain.
  STACK_OF(X509) *x509_chain = nullptr;

  // x509_leaf may contain a parsed copy of the first element of `chain` from
  // the legacy credential. This is only used as a cache in order to implement
  // “get0” functions that return a non-owning pointer to the certificate chain.
  X509 *x509_leaf = nullptr;

  // x509_stash contains the last `X509` object append to the legacy
  // credential's chain. This is a workaround for some third-party code that
  // continue to use an `X509` object even after passing ownership with an
  // “add0” function.
  X509 *x509_stash = nullptr;

  // Certificate setup callback: if set is called whenever a
  // certificate may be required (client or server). the callback
  // can then examine any appropriate parameters and setup any
  // certificates required. This allows advanced applications
  // to select certificates on the fly: for example based on
  // supported signature algorithms or curves.
  int (*cert_cb)(SSL *ssl, void *arg) = nullptr;
  void *cert_cb_arg = nullptr;

  // Optional X509_STORE for certificate validation. If NULL the parent SSL_CTX
  // store is used instead.
  X509_STORE *verify_store = nullptr;

  // sid_ctx partitions the session space within a shared session cache or
  // ticket key. Only sessions with a matching value will be accepted.
  InplaceVector<uint8_t, SSL_MAX_SID_CTX_LENGTH> sid_ctx;
};

// `SSL_PROTOCOL_METHOD` abstracts between TLS and DTLS.
struct SSL_PROTOCOL_METHOD {
  bool is_dtls;
  bool (*ssl_new)(SSLImpl *ssl);
  void (*ssl_free)(SSLImpl *ssl);
  // get_message sets `*out` to the current handshake message and returns true
  // if one has been received. It returns false if more input is needed.
  bool (*get_message)(const SSLImpl *ssl, SSLMessage *out);
  // next_message is called to release the current handshake message.
  void (*next_message)(SSLImpl *ssl);
  // has_unprocessed_handshake_data returns whether there is buffered
  // handshake data that has not been consumed by `get_message`.
  bool (*has_unprocessed_handshake_data)(const SSLImpl *ssl);
  // Use the `ssl_open_handshake` wrapper.
  ssl_open_record_t (*open_handshake)(SSLImpl *ssl, size_t *out_consumed,
                                      uint8_t *out_alert, Span<uint8_t> in);
  // Use the `ssl_open_change_cipher_spec` wrapper.
  ssl_open_record_t (*open_change_cipher_spec)(SSLImpl *ssl,
                                               size_t *out_consumed,
                                               uint8_t *out_alert,
                                               Span<uint8_t> in);
  // Use the `ssl_open_app_data` wrapper.
  ssl_open_record_t (*open_app_data)(SSLImpl *ssl, Span<uint8_t> *out,
                                     size_t *out_consumed, uint8_t *out_alert,
                                     Span<uint8_t> in);
  // write_app_data encrypts and writes `in` as application data. On success, it
  // returns one and sets `*out_bytes_written` to the number of bytes of `in`
  // written. Otherwise, it returns <= 0 and sets `*out_needs_handshake` to
  // whether the operation failed because the caller needs to drive the
  // handshake.
  int (*write_app_data)(SSLImpl *ssl, bool *out_needs_handshake,
                        size_t *out_bytes_written, Span<const uint8_t> in);
  int (*dispatch_alert)(SSLImpl *ssl);
  // init_message begins a new handshake message of type `type`. `cbb` is the
  // root CBB to be passed into `finish_message`. `*body` is set to a child CBB
  // the caller should write to. It returns true on success and false on error.
  bool (*init_message)(const SSLImpl *ssl, CBB *cbb, CBB *body, uint8_t type);
  // finish_message finishes a handshake message. It sets `*out_msg` to the
  // serialized message. It returns true on success and false on error.
  bool (*finish_message)(const SSLImpl *ssl, CBB *cbb, Array<uint8_t> *out_msg);
  // add_message adds a handshake message to the pending flight. It returns
  // true on success and false on error.
  bool (*add_message)(SSLImpl *ssl, Array<uint8_t> msg);
  // add_change_cipher_spec adds a ChangeCipherSpec record to the pending
  // flight. It returns true on success and false on error.
  bool (*add_change_cipher_spec)(SSLImpl *ssl);
  // finish_flight marks the pending flight as finished and ready to send.
  // `flush` must be called to write it.
  void (*finish_flight)(SSLImpl *ssl);
  // schedule_ack schedules a DTLS 1.3 ACK to be sent, without an ACK delay.
  // `flush` must be called to write it.
  void (*schedule_ack)(SSLImpl *ssl);
  // flush writes any scheduled data to the transport. It returns one on success
  // and <= 0 on error.
  int (*flush)(SSLImpl *ssl);
  // on_handshake_complete is called when the handshake is complete.
  void (*on_handshake_complete)(SSLImpl *ssl);
  // set_read_state sets `ssl`'s read cipher state and level to `aead_ctx` and
  // `level`. In QUIC, `aead_ctx` is a placeholder object. In TLS 1.3,
  // `traffic_secret` is the original traffic secret. This function returns true
  // on success and false on error.
  //
  // TODO(crbug.com/371998381): Take the traffic secrets as input and let the
  // function create the SSLAEADContext.
  bool (*set_read_state)(SSLImpl *ssl, ssl_encryption_level_t level,
                         UniquePtr<SSLAEADContext> aead_ctx,
                         Span<const uint8_t> traffic_secret);
  // set_write_state sets `ssl`'s write cipher state and level to `aead_ctx` and
  // `level`. In QUIC, `aead_ctx` is a placeholder object In TLS 1.3,
  // `traffic_secret` is the original traffic secret. This function returns true
  // on success and false on error.
  //
  // TODO(crbug.com/371998381): Take the traffic secrets as input and let the
  // function create the SSLAEADContext.
  bool (*set_write_state)(SSLImpl *ssl, ssl_encryption_level_t level,
                          UniquePtr<SSLAEADContext> aead_ctx,
                          Span<const uint8_t> traffic_secret);
};

// The following wrappers call `open_*` but handle `read_shutdown` correctly.

// ssl_open_handshake processes a record from `in` for reading a handshake
// message.
ssl_open_record_t ssl_open_handshake(SSLImpl *ssl, size_t *out_consumed,
                                     uint8_t *out_alert, Span<uint8_t> in);

// ssl_open_change_cipher_spec processes a record from `in` for reading a
// ChangeCipherSpec.
ssl_open_record_t ssl_open_change_cipher_spec(SSLImpl *ssl,
                                              size_t *out_consumed,
                                              uint8_t *out_alert,
                                              Span<uint8_t> in);

// ssl_open_app_data processes a record from `in` for reading application data.
// On success, it returns `ssl_open_record_success` and sets `*out` to the
// input. If it encounters a post-handshake message, it returns
// `ssl_open_record_discard`. The caller should then retry, after processing any
// messages received with `get_message`.
ssl_open_record_t ssl_open_app_data(SSLImpl *ssl, Span<uint8_t> *out,
                                    size_t *out_consumed, uint8_t *out_alert,
                                    Span<uint8_t> in);

struct SSL_X509_METHOD {
  // check_CA_list returns one if `names` is a good list of X.509 distinguished
  // names and zero otherwise. This is used to ensure that we can reject
  // unparsable values at handshake time when using crypto/x509.
  bool (*check_CA_list)(STACK_OF(CRYPTO_BUFFER) *names);

  // cert_clear frees and NULLs all X509 certificate-related state.
  void (*cert_clear)(CERT *cert);
  // cert_free frees all X509-related state.
  void (*cert_free)(CERT *cert);
  // cert_flush_cached_chain drops any cached `X509`-based certificate chain
  // from `cert`.
  // cert_dup duplicates any needed fields from `cert` to `new_cert`.
  void (*cert_dup)(CERT *new_cert, const CERT *cert);
  void (*cert_flush_cached_chain)(CERT *cert);
  // cert_flush_cached_chain drops any cached `X509`-based leaf certificate
  // from `cert`.
  void (*cert_flush_cached_leaf)(CERT *cert);

  // session_cache_objects fills out `sess->x509_peer` and `sess->x509_chain`
  // from `sess->certs` and erases `sess->x509_chain_without_leaf`. It returns
  // true on success or false on error.
  bool (*session_cache_objects)(SSL_SESSION *session);
  // session_dup duplicates any needed fields from `session` to `new_session`.
  // It returns true on success or false on error.
  bool (*session_dup)(SSL_SESSION *new_session, const SSL_SESSION *session);
  // session_clear frees any X509-related state from `session`.
  void (*session_clear)(SSL_SESSION *session);
  // session_verify_cert_chain verifies the certificate chain in `session`,
  // sets `session->verify_result` and returns true on success or false on
  // error.
  bool (*session_verify_cert_chain)(SSL_SESSION *session, SSL_HANDSHAKE *ssl,
                                    uint8_t *out_alert);

  // hs_flush_cached_ca_names drops any cached `X509_NAME`s from `hs`.
  void (*hs_flush_cached_ca_names)(SSL_HANDSHAKE *hs);
  // ssl_new does any necessary initialisation of `hs`. It returns true on
  // success or false on error.
  bool (*ssl_new)(SSL_HANDSHAKE *hs);
  // ssl_free frees anything created by `ssl_new`.
  void (*ssl_config_free)(SSL_CONFIG *cfg);
  // ssl_flush_cached_client_CA drops any cached `X509_NAME`s from `ssl`.
  void (*ssl_flush_cached_client_CA)(SSL_CONFIG *cfg);
  // ssl_auto_chain_if_needed runs the deprecated auto-chaining logic if
  // necessary. On success, it updates `ssl`'s certificate configuration as
  // needed and returns true. Otherwise, it returns false.
  bool (*ssl_auto_chain_if_needed)(SSL_HANDSHAKE *hs);
  // ssl_ctx_new does any necessary initialisation of `ctx`. It returns true on
  // success or false on error.
  bool (*ssl_ctx_new)(SSLContext *ctx);
  // ssl_ctx_free frees anything created by `ssl_ctx_new`.
  void (*ssl_ctx_free)(SSLContext *ctx);
  // ssl_ctx_flush_cached_client_CA drops any cached `X509_NAME`s from `ctx`.
  void (*ssl_ctx_flush_cached_client_CA)(SSLContext *ssl);
};

// ssl_crypto_x509_method provides the `SSL_X509_METHOD` functions using
// crypto/x509.
extern const SSL_X509_METHOD ssl_crypto_x509_method;

// ssl_noop_x509_method provides the `SSL_X509_METHOD` functions that avoid
// crypto/x509.
extern const SSL_X509_METHOD ssl_noop_x509_method;

struct TicketKey {
  static constexpr bool kAllowUniquePtr = true;

  uint8_t name[SSL_TICKET_KEY_NAME_LEN] = {0};
  uint8_t hmac_key[16] = {0};
  uint8_t aes_key[16] = {0};
  // next_rotation_tv_sec is the time (in seconds from the epoch) when the
  // current key should be superseded by a new key, or the time when a previous
  // key should be dropped. If zero, then the key should not be automatically
  // rotated.
  uint64_t next_rotation_tv_sec = 0;
};

struct CertCompressionAlg {
  static constexpr bool kAllowUniquePtr = true;

  ssl_cert_compression_func_t compress = nullptr;
  ssl_cert_decompression_func_t decompress = nullptr;
  uint16_t alg_id = 0;
};

DEFINE_LHASH_OF(SSL_SESSION)

// An ssl_shutdown_t describes the shutdown state of one end of the connection,
// whether it is alive or has been shutdown via close_notify or fatal alert.
enum ssl_shutdown_t {
  ssl_shutdown_none = 0,
  ssl_shutdown_close_notify = 1,
  ssl_shutdown_error = 2,
};

enum ssl_ech_status_t {
  // ssl_ech_none indicates ECH was not offered, or we have not gotten far
  // enough in the handshake to determine the status.
  ssl_ech_none,
  // ssl_ech_accepted indicates the server accepted ECH.
  ssl_ech_accepted,
  // ssl_ech_rejected indicates the server was offered ECH but rejected it.
  ssl_ech_rejected,
};

struct SSL3_STATE {
  static constexpr bool kAllowUniquePtr = true;

  SSL3_STATE();
  ~SSL3_STATE();

  uint64_t read_sequence = 0;
  uint64_t write_sequence = 0;

  uint8_t server_random[SSL3_RANDOM_SIZE] = {0};
  uint8_t client_random[SSL3_RANDOM_SIZE] = {0};

  // read_buffer holds data from the transport to be processed.
  SSLBuffer read_buffer;
  // write_buffer holds data to be written to the transport.
  SSLBuffer write_buffer;

  // pending_app_data is the unconsumed application data. It points into
  // `read_buffer`.
  Span<uint8_t> pending_app_data;

  // unreported_bytes_written is the number of bytes successfully written to the
  // transport, but not yet reported to the caller. The next `SSL_write` will
  // skip this many bytes from the input. This is used if
  // `SSL_MODE_ENABLE_PARTIAL_WRITE` is disabled, in which case `SSL_write` only
  // reports bytes written when the full caller input is written.
  size_t unreported_bytes_written = 0;

  // pending_write, if `has_pending_write` is true, is the caller-supplied data
  // corresponding to the current pending write. This is used to check the
  // caller retried with a compatible buffer.
  Span<const uint8_t> pending_write;

  // pending_write_type, if `has_pending_write` is true, is the record type
  // for the current pending write.
  //
  // TODO(davidben): Remove this when alerts are moved out of this write path.
  uint8_t pending_write_type = 0;

  // read_shutdown is the shutdown state for the read half of the connection.
  enum ssl_shutdown_t read_shutdown = ssl_shutdown_none;

  // write_shutdown is the shutdown state for the write half of the connection.
  enum ssl_shutdown_t write_shutdown = ssl_shutdown_none;

  // read_error, if `read_shutdown` is `ssl_shutdown_error`, is the error for
  // the receive half of the connection.
  UniquePtr<ERR_SAVE_STATE> read_error;

  int total_renegotiations = 0;

  // This holds a variable that indicates what we were doing when a 0 or -1 is
  // returned.  This is needed for non-blocking IO so we know what request
  // needs re-doing when in SSL_accept or SSL_connect
  int rwstate = SSL_ERROR_NONE;

  enum ssl_encryption_level_t quic_read_level = ssl_encryption_initial;
  enum ssl_encryption_level_t quic_write_level = ssl_encryption_initial;

  // version is the protocol version, or zero if the version has not yet been
  // set. In clients offering 0-RTT, this version will initially be set to the
  // early version, then switched to the final version. To distinguish these
  // cases, use `ssl_has_final_version`.
  uint16_t version = 0;

  // early_data_skipped is the amount of early data that has been skipped by the
  // record layer.
  uint16_t early_data_skipped = 0;

  // empty_record_count is the number of consecutive empty records received.
  uint8_t empty_record_count = 0;

  // warning_alert_count is the number of consecutive warning alerts
  // received.
  uint8_t warning_alert_count = 0;

  // key_update_count is the number of consecutive KeyUpdates received.
  uint8_t key_update_count = 0;

  // ech_status indicates whether ECH was accepted by the server.
  ssl_ech_status_t ech_status = ssl_ech_none;

  // skip_early_data instructs the record layer to skip unexpected early data
  // messages when 0RTT is rejected.
  bool skip_early_data : 1;

  // v2_hello_done is true if the peer's V2ClientHello, if any, has been handled
  // and future messages should use the record layer.
  bool v2_hello_done : 1;

  // is_v2_hello is true if the current handshake message was derived from a
  // V2ClientHello rather than received from the peer directly.
  bool is_v2_hello : 1;

  // has_message is true if the current handshake message has been returned
  // at least once by `get_message` and false otherwise.
  bool has_message : 1;

  // initial_handshake_complete is true if the initial handshake has
  // completed.
  bool initial_handshake_complete : 1;

  // session_reused indicates whether a session was resumed.
  bool session_reused : 1;

  bool send_connection_binding : 1;

  // channel_id_valid is true if, on the server, the client has negotiated a
  // Channel ID and the `channel_id` field is filled in.
  bool channel_id_valid : 1;

  // key_update_pending is true if we are in the process of sending a KeyUpdate
  // message. As a DoS mitigation (and a requirement in DTLS), we never send
  // more than one KeyUpdate at once. In DTLS, this tracks whether there is an
  // unACKed KeyUpdate.
  bool key_update_pending : 1;

  // early_data_accepted is true if early data was accepted by the server.
  bool early_data_accepted : 1;

  // alert_dispatch is true there is an alert in `send_alert` to be sent.
  bool alert_dispatch : 1;

  // renegotiate_pending is whether the read half of the channel is blocked on a
  // HelloRequest.
  bool renegotiate_pending : 1;

  // used_hello_retry_request is whether the handshake used a TLS 1.3
  // HelloRetryRequest message.
  bool used_hello_retry_request : 1;

  // server_sent_requested_padding is true iff a client requested padding
  // through the server padding extension, and the server sent back the
  // requested amount of padding.
  bool server_sent_requested_padding : 1;

  // hs_buf is the buffer of handshake data to process.
  UniquePtr<BUF_MEM> hs_buf;

  // pending_hs_data contains the pending handshake data that has not yet
  // been encrypted to `pending_flight`. This allows packing the handshake into
  // fewer records.
  UniquePtr<BUF_MEM> pending_hs_data;

  // pending_flight is the pending outgoing flight. This is used to flush each
  // handshake flight in a single write. `write_buffer` must be written out
  // before this data.
  UniquePtr<BUF_MEM> pending_flight;

  // pending_flight_offset is the number of bytes of `pending_flight` which have
  // been successfully written.
  uint32_t pending_flight_offset = 0;

  // ticket_age_skew is the difference, in seconds, between the client-sent
  // ticket age and the server-computed value in TLS 1.3 server connections
  // which resumed a session.
  int32_t ticket_age_skew = 0;

  // ssl_early_data_reason stores details on why 0-RTT was accepted or rejected.
  enum ssl_early_data_reason_t early_data_reason = ssl_early_data_unknown;

  // aead_read_ctx is the current read cipher state.
  UniquePtr<SSLAEADContext> aead_read_ctx;

  // aead_write_ctx is the current write cipher state.
  UniquePtr<SSLAEADContext> aead_write_ctx;

  // hs is the handshake state for the current handshake or NULL if there isn't
  // one.
  UniquePtr<SSL_HANDSHAKE> hs;

  InplaceVector<uint8_t, SSL_MAX_MD_SIZE> write_traffic_secret;
  InplaceVector<uint8_t, SSL_MAX_MD_SIZE> read_traffic_secret;
  InplaceVector<uint8_t, SSL_MAX_MD_SIZE> exporter_secret;

  // Connection binding to prevent renegotiation attacks
  InplaceVector<uint8_t, 12> previous_client_finished;
  InplaceVector<uint8_t, 12> previous_server_finished;

  uint8_t send_alert[2] = {0};

  // established_session is the session established by the connection. This
  // session is only filled upon the completion of the handshake and is
  // immutable.
  UniquePtr<SSL_SESSION> established_session;

  // Next protocol negotiation. For the client, this is the protocol that we
  // sent in NextProtocol and is set when handling ServerHello extensions.
  //
  // For a server, this is the client's selected_protocol from NextProtocol and
  // is set when handling the NextProtocol message, before the Finished
  // message.
  Array<uint8_t> next_proto_negotiated;

  // ALPN information
  // (we are in the process of transitioning from NPN to ALPN.)

  // In a server these point to the selected ALPN protocol after the
  // ClientHello has been processed. In a client these contain the protocol
  // that the server selected once the ServerHello has been processed.
  Array<uint8_t> alpn_selected;

  // hostname, on the server, is the value of the SNI extension.
  UniquePtr<char> hostname;

  // For a server:
  //     If `channel_id_valid` is true, then this contains the
  //     verified Channel ID from the client: a P256 point, (x,y), where
  //     each are big-endian values.
  uint8_t channel_id[64] = {0};

  // Contains the QUIC transport params received by the peer.
  Array<uint8_t> peer_quic_transport_params;

  // srtp_profile is the selected SRTP protection profile for
  // DTLS-SRTP.
  const SRTP_PROTECTION_PROFILE *srtp_profile = nullptr;
};

// lengths of messages
#define DTLS1_RT_MAX_HEADER_LENGTH 13

// DTLS_PLAINTEXT_RECORD_HEADER_LENGTH is the length of the DTLS record header
// for plaintext records (in DTLS 1.3) or DTLS versions <= 1.2.
#define DTLS_PLAINTEXT_RECORD_HEADER_LENGTH 13

// DTLS1_3_RECORD_HEADER_LENGTH is the length of the DTLS 1.3 record header
// sent by BoringSSL for encrypted records. Note that received encrypted DTLS
// 1.3 records might have a different length header.
#define DTLS1_3_RECORD_HEADER_WRITE_LENGTH 5

static_assert(DTLS1_RT_MAX_HEADER_LENGTH >= DTLS_PLAINTEXT_RECORD_HEADER_LENGTH,
              "DTLS1_RT_MAX_HEADER_LENGTH must not be smaller than defined "
              "record header lengths");
static_assert(DTLS1_RT_MAX_HEADER_LENGTH >= DTLS1_3_RECORD_HEADER_WRITE_LENGTH,
              "DTLS1_RT_MAX_HEADER_LENGTH must not be smaller than defined "
              "record header lengths");

#define DTLS1_HM_HEADER_LENGTH 12

// A DTLSMessageBitmap maintains a list of bits which may be marked to indicate
// a portion of a message was received or ACKed.
class DTLSMessageBitmap {
 public:
  // A Range represents a range of bits from `start`, inclusive, to `end`,
  // exclusive.
  struct Range {
    size_t start = 0;
    size_t end = 0;

    bool empty() const { return start == end; }
    size_t size() const { return end - start; }
    bool operator==(const Range &r) const {
      return start == r.start && end == r.end;
    }
    bool operator!=(const Range &r) const { return !(*this == r); }
  };

  // Init initializes the structure with `num_bits` unmarked bits, from zero
  // to `num_bits - 1`.
  bool Init(size_t num_bits);

  // MarkRange marks the bits from `start`, inclusive, to `end`, exclusive.
  void MarkRange(size_t start, size_t end);

  // NextUnmarkedRange returns the next range of unmarked bits, starting from
  // `start`, inclusive. If all bits after `start` are marked, it returns an
  // empty range.
  Range NextUnmarkedRange(size_t start) const;

  // IsComplete returns whether every bit in the bitmask has been marked.
  bool IsComplete() const { return bytes_.empty(); }

 private:
  // bytes_ contains the unmarked bits. We maintain an invariant: if `bytes_` is
  // not empty, some bit is unset.
  Array<uint8_t> bytes_;
  // first_unmarked_byte_ is the index of first byte in `bytes_` that is not
  // 0xff. This is maintained to amortize checking if the message is complete.
  size_t first_unmarked_byte_ = 0;
};

struct hm_header_st {
  uint8_t type;
  uint32_t msg_len;
  uint16_t seq;
  uint32_t frag_off;
  uint32_t frag_len;
};

// An DTLSIncomingMessage is an incoming DTLS message, possibly not yet
// assembled.
struct DTLSIncomingMessage {
  static constexpr bool kAllowUniquePtr = true;

  Span<uint8_t> msg() { return Span(data).subspan(DTLS1_HM_HEADER_LENGTH); }
  Span<const uint8_t> msg() const {
    return Span(data).subspan(DTLS1_HM_HEADER_LENGTH);
  }
  size_t msg_len() const { return msg().size(); }

  // type is the type of the message.
  uint8_t type = 0;
  // seq is the sequence number of this message.
  uint16_t seq = 0;
  // data contains the message, including the message header of length
  // `DTLS1_HM_HEADER_LENGTH`.
  Array<uint8_t> data;
  // reassembly tracks which parts of the message have been received.
  DTLSMessageBitmap reassembly;
};

struct DTLSOutgoingMessage {
  size_t msg_len() const {
    assert(!is_ccs);
    assert(data.size() >= DTLS1_HM_HEADER_LENGTH);
    return data.size() - DTLS1_HM_HEADER_LENGTH;
  }

  bool IsFullyAcked() const {
    // ACKs only exist in DTLS 1.3, which does not send ChangeCipherSpec.
    return !is_ccs && acked.IsComplete();
  }

  Array<uint8_t> data;
  uint16_t epoch = 0;
  bool is_ccs = false;
  // acked tracks which bits of the message have been ACKed by the peer. If
  // `msg_len` is zero, it tracks one bit for whether the header has been
  // received.
  DTLSMessageBitmap acked;
};

struct OPENSSL_timeval {
  uint64_t tv_sec;
  uint32_t tv_usec;
};

struct DTLSTimer {
 public:
  static constexpr uint64_t kNever = UINT64_MAX;

  // StartMicroseconds schedules the timer to expire the specified number of
  // microseconds from `now`.
  void StartMicroseconds(OPENSSL_timeval now, uint64_t microseconds);

  // Stop disables the timer.
  void Stop();

  // IsExpired returns true if the timer was set and is expired at time `now`.
  bool IsExpired(OPENSSL_timeval now) const;

  // IsSet returns true if the timer is scheduled or expired, and false if it is
  // stopped.
  bool IsSet() const;

  void UpdateDuration(uint64_t microseconds) { duration_ = microseconds; }

  // MicrosecondsRemaining returns the time remaining, in microseconds, at
  // `now`, or `kNever` if the timer is unset.
  uint64_t MicrosecondsRemaining(OPENSSL_timeval now) const;

 private:
  uint64_t start_time_;
  uint64_t duration_ = kNever;  // If set to kNever then this timer is unset.
};

// DTLS_MAX_EXTRA_WRITE_EPOCHS is the maximum number of additional write epochs
// that DTLS may need to retain.
//
// The maximum is, as a DTLS 1.3 server, immediately after sending Finished. At
// this point, the current epoch is the application write keys (epoch 3), but we
// may have ServerHello (epoch 0) and EncryptedExtensions (epoch 1) to
// retransmit. KeyUpdate does not increase this count. If the server were to
// initiate KeyUpdate from this state, it would not apply the new epoch until
// the client's ACKs have caught up. At that point, epochs 0 and 1 can be
// discarded.
#define DTLS_MAX_EXTRA_WRITE_EPOCHS 2

// DTLS_MAX_ACK_BUFFER is the maximum number of records worth of data we'll keep
// track of with DTLS 1.3 ACKs. When we exceed this value, information about
// stale records will be dropped. This will not break the connection but may
// cause ACKs to perform worse and retransmit unnecessary information.
#define DTLS_MAX_ACK_BUFFER 32

// A DTLSSentRecord records information about a record we sent. Each record
// covers all bytes from `first_msg_start` (inclusive) of `first_msg` to
// `last_msg_end` (exclusive) of `last_msg`. Messages are referenced by index
// into `outgoing_messages`. `last_msg_end` may be `outgoing_messages.size()` if
// `last_msg_end` is zero.
//
// When the message is empty, `first_msg_start` and `last_msg_end` are
// maintained as if there is a single bit in the message representing the
// header. See `acked` in DTLSOutgoingMessage.
struct DTLSSentRecord {
  DTLSRecordNumber number;
  PackedSize<SSL_MAX_HANDSHAKE_FLIGHT> first_msg = 0;
  PackedSize<SSL_MAX_HANDSHAKE_FLIGHT> last_msg = 0;
  uint32_t first_msg_start = 0;
  uint32_t last_msg_end = 0;
};

enum class QueuedKeyUpdate {
  kNone,
  kUpdateNotRequested,
  kUpdateRequested,
};

// DTLS_PREV_READ_EPOCH_EXPIRE_SECONDS is how long to retain the previous read
// epoch in DTLS 1.3. This value is set based on the following:
//
// - Section 4.2.1 of RFC 9147 recommends retaining past read epochs for the
//   default TCP MSL. This accommodates packet reordering with KeyUpdate.
//
// - Section 5.8.1 of RFC 9147 requires being capable of ACKing the client's
//   final flight for at least twice the default MSL. That requires retaining
//   epoch 2 after the handshake.
//
// - Section 4 of RFC 9293 defines the MSL to be two minutes.
#define DTLS_PREV_READ_EPOCH_EXPIRE_SECONDS (4 * 60)

struct DTLSPrevReadEpoch {
  static constexpr bool kAllowUniquePtr = true;
  DTLSReadEpoch epoch;
  // expire is the expiration time of the read epoch, expressed as a POSIX
  // timestamp in seconds.
  uint64_t expire;
};

struct DTLS1_STATE {
  static constexpr bool kAllowUniquePtr = true;

  DTLS1_STATE();
  ~DTLS1_STATE();

  bool Init();

  // has_change_cipher_spec is true if we have received a ChangeCipherSpec from
  // the peer in this epoch.
  bool has_change_cipher_spec : 1;

  // outgoing_messages_complete is true if `outgoing_messages` has been
  // completed by an attempt to flush it. Future calls to `add_message` and
  // `add_change_cipher_spec` will start a new flight.
  bool outgoing_messages_complete : 1;

  // flight_has_reply is true if the current outgoing flight is complete and has
  // processed at least one message. This is used to detect whether we or the
  // peer sent the final flight.
  bool flight_has_reply : 1;

  // handshake_write_overflow and handshake_read_overflow are true if
  // handshake_write_seq and handshake_read_seq, respectively have overflowed.
  bool handshake_write_overflow : 1;
  bool handshake_read_overflow : 1;

  // sending_flight and sending_ack are true if we are in the process of sending
  // a handshake flight and ACK, respectively.
  bool sending_flight : 1;
  bool sending_ack : 1;
  // pending_flush is whether we have a pending flush on the transport.
  bool pending_flush : 1;

  // queued_key_update, if not kNone, indicates we've queued a KeyUpdate message
  // to send after the current flight is ACKed.
  QueuedKeyUpdate queued_key_update : 2;

  uint16_t handshake_write_seq = 0;
  uint16_t handshake_read_seq = 0;

  // read_epoch is the current read epoch.
  DTLSReadEpoch read_epoch;

  // next_read_epoch is the next read epoch in DTLS 1.3. It will become
  // current once a record is received from it.
  UniquePtr<DTLSReadEpoch> next_read_epoch;

  // prev_read_epoch is the previous read epoch in DTLS 1.3.
  UniquePtr<DTLSPrevReadEpoch> prev_read_epoch;

  // write_epoch is the current DTLS write epoch. Non-retransmit records will
  // generally use this epoch.
  // TODO(crbug.com/381113363): 0-RTT will be the exception, when implemented.
  DTLSWriteEpoch write_epoch;

  // extra_write_epochs is the collection available write epochs.
  InplaceVector<UniquePtr<DTLSWriteEpoch>, DTLS_MAX_EXTRA_WRITE_EPOCHS>
      extra_write_epochs;

  // incoming_messages is a ring buffer of incoming handshake messages that have
  // yet to be processed. The front of the ring buffer is message number
  // `handshake_read_seq`, at position `handshake_read_seq` %
  // `SSL_MAX_HANDSHAKE_FLIGHT`.
  UniquePtr<DTLSIncomingMessage> incoming_messages[SSL_MAX_HANDSHAKE_FLIGHT];

  // outgoing_messages is the queue of outgoing messages from the last handshake
  // flight.
  InplaceVector<DTLSOutgoingMessage, SSL_MAX_HANDSHAKE_FLIGHT>
      outgoing_messages;

  // sent_records is a queue of records we sent, for processing ACKs. To save
  // memory in the steady state, the structure is stored on the heap and dropped
  // when empty.
  UniquePtr<MRUQueue<DTLSSentRecord, DTLS_MAX_ACK_BUFFER>> sent_records;

  // records_to_ack is a queue of received records that we should ACK. This is
  // not stored on the heap because, in the steady state, DTLS 1.3 does not
  // necessarily empty this list. (We probably could drop records from here once
  // they are sufficiently old.)
  MRUQueue<DTLSRecordNumber, DTLS_MAX_ACK_BUFFER> records_to_ack;

  // outgoing_written is the number of outgoing messages that have been
  // written.
  uint8_t outgoing_written = 0;
  // outgoing_offset is the number of bytes of the next outgoing message have
  // been written.
  uint32_t outgoing_offset = 0;

  unsigned mtu = 0;  // max DTLS packet size

  // num_timeouts is the number of times the retransmit timer has fired since
  // the last time it was reset.
  unsigned num_timeouts = 0;

  // retransmit_timer tracks when to schedule the next DTLS retransmit if we do
  // not hear from the peer.
  DTLSTimer retransmit_timer;

  // ack_timer tracks when to send an ACK.
  DTLSTimer ack_timer;

  // timeout_duration_ms is the timeout duration in milliseconds.
  uint32_t timeout_duration_ms = 0;
};

// An ALPSConfig is a pair of ALPN protocol and settings value to use with ALPS.
struct ALPSConfig {
  Array<uint8_t> protocol;
  Array<uint8_t> settings;
};

// SSL_CONFIG contains configuration bits that can be shed after the handshake
// completes.  Objects of this type are not shared; they are unique to a
// particular `SSL`.
//
// See SSL_shed_handshake_config() for more about the conditions under which
// configuration can be shed.
struct SSL_CONFIG {
  static constexpr bool kAllowUniquePtr = true;

  explicit SSL_CONFIG(SSLImpl *ssl_arg);
  ~SSL_CONFIG();

  // ssl is a non-owning pointer to the parent `SSL` object.
  SSLImpl *const ssl = nullptr;

  // conf_max_version is the maximum acceptable version configured by
  // `SSL_set_max_proto_version`. Note this version is not normalized in DTLS
  // and is further constrained by `SSL_OP_NO_*`.
  uint16_t conf_max_version = 0;

  // conf_min_version is the minimum acceptable version configured by
  // `SSL_set_min_proto_version`. Note this version is not normalized in DTLS
  // and is further constrained by `SSL_OP_NO_*`.
  uint16_t conf_min_version = 0;

  X509_VERIFY_PARAM *param = nullptr;

  // crypto
  UniquePtr<SSLCipherPreferenceList> cipher_list;

  // This is used to hold the local certificate used (i.e. the server
  // certificate for a server or the client certificate for a client).
  UniquePtr<CERT> cert;

  int (*verify_callback)(int ok,
                         X509_STORE_CTX *ctx) =
      nullptr;  // fail if callback returns 0

  enum ssl_verify_result_t (*custom_verify_callback)(
      SSL *ssl, uint8_t *out_alert) = nullptr;
  // Server-only: psk_identity_hint is the identity hint to send in
  // PSK-based key exchanges.
  UniquePtr<char> psk_identity_hint;

  unsigned (*psk_client_callback)(SSL *ssl, const char *hint, char *identity,
                                  unsigned max_identity_len, uint8_t *psk,
                                  unsigned max_psk_len) = nullptr;
  unsigned (*psk_server_callback)(SSL *ssl, const char *identity, uint8_t *psk,
                                  unsigned max_psk_len) = nullptr;

  // for server side, keep the list of CA_dn we can use
  UniquePtr<STACK_OF(CRYPTO_BUFFER)> client_CA;

  // cached_x509_client_CA is a cache of parsed versions of the elements of
  // `client_CA`.
  STACK_OF(X509_NAME) *cached_x509_client_CA = nullptr;

  // For client side, keep the list of CA distinguished names we can use
  // for the Certificate Authorities extension.
  // TODO(bbe) having this separate from the client side (above) is mildly
  // silly, but OpenSSL has *_client_CA API's for this exposed, and for the
  // moment we are not crossing those streams.
  UniquePtr<STACK_OF(CRYPTO_BUFFER)> CA_names;

  // Trust anchor IDs to be requested in the trust_anchors extension.
  std::optional<Array<uint8_t>> requested_trust_anchors;

  // Our list of supported groups. If this list is modified, for a client,
  // `client_key_share_selections` must be reset if the key shares are no longer
  // a valid subsequence of the supported group list.
  Array<uint16_t> supported_group_list;

  // Contains flags corresponding to `supported_group_list`, which are
  // SSL_GROUP_FLAG_* values ORed together.
  Array<uint32_t> supported_group_list_flags;

  // For a client, this may contain a subsequence of the group IDs in
  // `suppported_group_list`, which gives the groups for which key shares should
  // be sent in the client's key_share extension. This is non-nullopt iff
  // `SSL_set1_client_key_shares` was successfully called to configure key
  // shares. If non-nullopt, these groups are in the same order as they appear
  // in `supported_group_list`, and may not contain duplicates.
  std::optional<InplaceVector<uint16_t, kNumNamedGroups>>
      client_key_share_selections;

  // For a client, this contains a list of groups believed to be supported by
  // the server, in server preference order.
  Array<uint16_t> server_supported_groups_hint;

  // channel_id_private is the client's Channel ID private key, or null if
  // Channel ID should not be offered on this connection.
  UniquePtr<EVP_PKEY> channel_id_private;

  // For a client, this contains the list of supported protocols in wire
  // format.
  Array<uint8_t> alpn_client_proto_list;

  // alps_configs contains the list of supported protocols to use with ALPS,
  // along with their corresponding ALPS values.
  Vector<ALPSConfig> alps_configs;

  // Contains the QUIC transport params that this endpoint will send.
  Array<uint8_t> quic_transport_params;

  // Contains the context used to decide whether to accept early data in QUIC.
  Array<uint8_t> quic_early_data_context;

  // verify_sigalgs, if not empty, is the set of signature algorithms
  // accepted from the peer in decreasing order of preference.
  Array<uint16_t> verify_sigalgs;

  // srtp_profiles is the list of configured SRTP protection profiles for
  // DTLS-SRTP.
  UniquePtr<STACK_OF(SRTP_PROTECTION_PROFILE)> srtp_profiles;

  // client_ech_config_list, if not empty, is a serialized ECHConfigList
  // structure for the client to use when negotiating ECH.
  Array<uint8_t> client_ech_config_list;

  // compliance_policy limits the set of ciphers that can be selected when
  // negotiating a TLS 1.3 connection.
  enum ssl_compliance_policy_t compliance_policy = ssl_compliance_policy_none;

  // server_padding_request, if set by the client, indicates that the client
  // will ask the server to include additional padding in the
  // EncryptedExtensions message of a TLS 1.3 connection.
  std::optional<uint16_t> server_padding_request;

  // verify_mode is a bitmask of `SSL_VERIFY_*` values.
  uint8_t verify_mode = SSL_VERIFY_NONE;

  // accepted_peer_cert_types contains a list of `TLSEXT_cert_type_*` values in
  // preference order indicating the types of certificates to accept from the
  // peer. This list should always be non-empty. If the caller did not configure
  // a valid list, only X.509 certificates are accepted by default.
  InplaceVector<uint8_t, kNumCertTypes> accepted_peer_cert_types;

  // available_client_cert_types, if not empty, contains a list of
  // `TLSEXT_cert_type_*` values in preference order indicating the types of
  // client certificates that the caller, as a client, explicitly configured and
  // wishes to advertise, instead of the automatically inferred client cert
  // types from the configured credential list.
  InplaceVector<uint8_t, kNumCertTypes> available_client_cert_types;

  // ech_grease_enabled controls whether ECH GREASE may be sent in the
  // ClientHello.
  bool ech_grease_enabled : 1;

  // Enable signed certificate time stamps. Currently client only.
  bool signed_cert_timestamps_enabled : 1;

  // ocsp_stapling_enabled is only used by client connections and indicates
  // whether OCSP stapling will be requested.
  bool ocsp_stapling_enabled : 1;

  // channel_id_enabled is copied from the `SSL_CTX`. For a server, it means
  // that we'll accept Channel IDs from clients. It is ignored on the client.
  bool channel_id_enabled : 1;

  // retain_only_sha256_of_client_certs is true if we should compute the SHA256
  // hash of the peer's certificate and then discard it to save memory and
  // session space. Only effective on the server side.
  bool retain_only_sha256_of_client_certs : 1;

  // handoff indicates that a server should stop after receiving the
  // ClientHello and pause the handshake in such a way that `SSL_get_error`
  // returns `SSL_ERROR_HANDOFF`. This is copied in `SSL_new` from the `SSL_CTX`
  // element of the same name and may be cleared if the handoff is declined.
  bool handoff : 1;

  // shed_handshake_config indicates that the handshake config (this object!)
  // should be freed after the handshake completes.
  bool shed_handshake_config : 1;

  // jdk11_workaround is whether to disable TLS 1.3 for JDK 11 clients, as a
  // workaround for https://bugs.openjdk.java.net/browse/JDK-8211806.
  bool jdk11_workaround : 1;

  // QUIC drafts up to and including 32 used a different TLS extension
  // codepoint to convey QUIC's transport parameters.
  bool quic_use_legacy_codepoint : 1;

  // permute_extensions is whether to permute extensions when sending messages.
  bool permute_extensions : 1;

  // aes_hw_override if set indicates we should override checking for aes
  // hardware support, and use the value in aes_hw_override_value instead.
  bool aes_hw_override : 1;

  // aes_hw_override_value is used for testing to indicate the support or lack
  // of support for AES hw. The value is only considered if `aes_hw_override` is
  // true.
  bool aes_hw_override_value : 1;

  // alps_use_new_codepoint if set indicates we use new ALPS extension codepoint
  // to negotiate and convey application settings.
  bool alps_use_new_codepoint : 1;

  // server_padding_enabled is true iff the server is willing to send additional
  // padding to clients that request it through the server padding extension.
  bool server_padding_enabled : 1;
};

// From RFC 8446, used in determining PSK modes.
#define SSL_PSK_DHE_KE 0x1

// kMaxEarlyDataAccepted is the advertised number of plaintext bytes of early
// data that will be accepted. This value should be slightly below
// kMaxEarlyDataSkipped in tls_record.c, which is measured in ciphertext.
static const size_t kMaxEarlyDataAccepted = 14336;

UniquePtr<CERT> ssl_cert_dup(CERT *cert);
bool ssl_set_cert(CERT *cert, UniquePtr<CRYPTO_BUFFER> buffer);
bool ssl_is_key_type_supported(int key_type);
// ssl_compare_public_and_private_key returns true if `pubkey` is the public
// counterpart to `privkey`. Otherwise it returns false and pushes a helpful
// message on the error queue.
bool ssl_compare_public_and_private_key(const EVP_PKEY *pubkey,
                                        const EVP_PKEY *privkey);
bool ssl_get_new_session(SSL_HANDSHAKE *hs);

// ssl_encrypt_ticket encrypt a ticket for `session` and writes the result to
// `out`. It returns true on success and false on error. If, on success, nothing
// was written to `out`, the caller should skip sending a ticket.
bool ssl_encrypt_ticket(SSL_HANDSHAKE *hs, CBB *out,
                        const SSL_SESSION *session);

bool ssl_ctx_rotate_ticket_encryption_key(SSLContext *ctx);

// ssl_session_new returns a newly-allocated blank `SSL_SESSION` or nullptr on
// error.
UniquePtr<SSL_SESSION> ssl_session_new(const SSL_X509_METHOD *x509_method);

// ssl_hash_session_id returns a hash of `session_id`, suitable for a hash table
// keyed on session IDs.
uint32_t ssl_hash_session_id(Span<const uint8_t> session_id);

// SSL_SESSION_parse parses an `SSL_SESSION` from `cbs` and advances `cbs` over
// the parsed data.
OPENSSL_EXPORT UniquePtr<SSL_SESSION> SSL_SESSION_parse(
    CBS *cbs, const SSL_X509_METHOD *x509_method, CRYPTO_BUFFER_POOL *pool);

// ssl_session_serialize writes `in` to `cbb` as if it were serialising a
// session for Session-ID resumption. It returns true on success and false on
// error.
OPENSSL_EXPORT bool ssl_session_serialize(const SSL_SESSION *in, CBB *cbb);

enum class SSLSessionType {
  // The session is not resumable.
  kNotResumable,
  // The session uses a TLS 1.2 session ID.
  kID,
  // The session uses a TLS 1.2 ticket.
  kTicket,
  // The session uses a TLS 1.3 pre-shared key.
  kPreSharedKey,
};

// ssl_session_get_type returns the type of `session`.
SSLSessionType ssl_session_get_type(const SSL_SESSION *session);

// ssl_session_is_context_valid returns whether `session`'s session ID context
// matches the one set on `hs`.
bool ssl_session_is_context_valid(const SSL_HANDSHAKE *hs,
                                  const SSL_SESSION *session);

// ssl_session_is_time_valid returns true if `session` is still valid and false
// if it has expired.
bool ssl_session_is_time_valid(const SSLImpl *ssl, const SSL_SESSION *session);

// ssl_session_is_resumable returns whether `session` is resumable for `hs`.
bool ssl_session_is_resumable(const SSL_HANDSHAKE *hs,
                              const SSL_SESSION *session);

// ssl_session_protocol_version returns the protocol version associated with
// `session`. Note that despite the name, this is not the same as
// `SSL_SESSION_get_protocol_version`. The latter is based on upstream's name.
uint16_t ssl_session_protocol_version(const SSL_SESSION *session);

// ssl_session_get_digest returns the digest used in `session`.
const EVP_MD *ssl_session_get_digest(const SSL_SESSION *session);

// ssl_session_has_peer_cred returns whether `session` contains the peer's
// (non-PSK) credentials (either X.509 cert chain or raw public key, depending
// on the peer's certificate type) or a valid SHA-256 hash thereof.
bool ssl_session_has_peer_cred(const SSL_SESSION *session);

void ssl_set_session(SSLImpl *ssl, SSL_SESSION *session);

// ssl_get_prev_session looks up the previous session based on `client_hello`.
// On success, it sets `*out_session` to the session or nullptr if none was
// found. If the session could not be looked up synchronously, it returns
// `ssl_hs_pending_session` and should be called again. If a ticket could not be
// decrypted immediately it returns `ssl_hs_pending_ticket` and should also
// be called again. Otherwise, it returns `ssl_hs_error`.
enum ssl_hs_wait_t ssl_get_prev_session(SSL_HANDSHAKE *hs,
                                        UniquePtr<SSL_SESSION> *out_session,
                                        bool *out_tickets_supported,
                                        bool *out_renew_ticket,
                                        const SSL_CLIENT_HELLO *client_hello);

// The following flags determine which parts of the session are duplicated.
#define SSL_SESSION_DUP_AUTH_ONLY 0x0
#define SSL_SESSION_INCLUDE_TICKET 0x1
#define SSL_SESSION_INCLUDE_NONAUTH 0x2
#define SSL_SESSION_DUP_ALL \
  (SSL_SESSION_INCLUDE_TICKET | SSL_SESSION_INCLUDE_NONAUTH)

// SSL_SESSION_dup returns a newly-allocated `SSL_SESSION` with a copy of the
// fields in `session` or nullptr on error. The new session is non-resumable and
// must be explicitly marked resumable once it has been filled in.
OPENSSL_EXPORT UniquePtr<SSL_SESSION> SSL_SESSION_dup(
    const SSL_SESSION *session, int dup_flags);

// ssl_session_rebase_time updates `session`'s start time to the current time,
// adjusting the timeout so the expiration time is unchanged.
void ssl_session_rebase_time(SSLImpl *ssl, SSL_SESSION *session);

// ssl_session_renew_timeout calls `ssl_session_rebase_time` and renews
// `session`'s timeout to `timeout` (measured from the current time). The
// renewal is clamped to the session's auth_timeout.
void ssl_session_renew_timeout(SSLImpl *ssl, SSL_SESSION *session,
                               uint32_t timeout);

void ssl_update_cache(SSLImpl *ssl);

void ssl_send_alert(SSLImpl *ssl, int level, int desc);
int ssl_send_alert_impl(SSLImpl *ssl, int level, int desc);
bool tls_get_message(const SSLImpl *ssl, SSLMessage *out);
ssl_open_record_t tls_open_handshake(SSLImpl *ssl, size_t *out_consumed,
                                     uint8_t *out_alert, Span<uint8_t> in);
void tls_next_message(SSLImpl *ssl);

int tls_dispatch_alert(SSLImpl *ssl);
ssl_open_record_t tls_open_app_data(SSLImpl *ssl, Span<uint8_t> *out,
                                    size_t *out_consumed, uint8_t *out_alert,
                                    Span<uint8_t> in);
ssl_open_record_t tls_open_change_cipher_spec(SSLImpl *ssl,
                                              size_t *out_consumed,
                                              uint8_t *out_alert,
                                              Span<uint8_t> in);
int tls_write_app_data(SSLImpl *ssl, bool *out_needs_handshake,
                       size_t *out_bytes_written, Span<const uint8_t> in);

bool tls_new(SSLImpl *ssl);
void tls_free(SSLImpl *ssl);

bool tls_init_message(const SSLImpl *ssl, CBB *cbb, CBB *body, uint8_t type);
bool tls_finish_message(const SSLImpl *ssl, CBB *cbb, Array<uint8_t> *out_msg);
bool tls_add_message(SSLImpl *ssl, Array<uint8_t> msg);
bool tls_add_change_cipher_spec(SSLImpl *ssl);
int tls_flush(SSLImpl *ssl);

bool dtls1_init_message(const SSLImpl *ssl, CBB *cbb, CBB *body, uint8_t type);
bool dtls1_finish_message(const SSLImpl *ssl, CBB *cbb,
                          Array<uint8_t> *out_msg);
bool dtls1_add_message(SSLImpl *ssl, Array<uint8_t> msg);
bool dtls1_add_change_cipher_spec(SSLImpl *ssl);
void dtls1_finish_flight(SSLImpl *ssl);
void dtls1_schedule_ack(SSLImpl *ssl);
int dtls1_flush(SSLImpl *ssl);

// ssl_add_message_cbb finishes the handshake message in `cbb` and adds it to
// the pending flight. It returns true on success and false on error.
bool ssl_add_message_cbb(SSLImpl *ssl, CBB *cbb);

// ssl_hash_message incorporates `msg` into the handshake hash. It returns true
// on success and false on allocation failure.
bool ssl_hash_message(SSL_HANDSHAKE *hs, const SSLMessage &msg);

ssl_open_record_t dtls1_process_ack(SSLImpl *ssl, uint8_t *out_alert,
                                    DTLSRecordNumber ack_record_number,
                                    Span<const uint8_t> data);
ssl_open_record_t dtls1_open_app_data(SSLImpl *ssl, Span<uint8_t> *out,
                                      size_t *out_consumed, uint8_t *out_alert,
                                      Span<uint8_t> in);
ssl_open_record_t dtls1_open_change_cipher_spec(SSLImpl *ssl,
                                                size_t *out_consumed,
                                                uint8_t *out_alert,
                                                Span<uint8_t> in);

int dtls1_write_app_data(SSLImpl *ssl, bool *out_needs_handshake,
                         size_t *out_bytes_written, Span<const uint8_t> in);

// dtls1_write_record sends a record. It returns one on success and <= 0 on
// error.
int dtls1_write_record(SSLImpl *ssl, int type, Span<const uint8_t> in,
                       uint16_t epoch);

bool dtls1_parse_fragment(CBS *cbs, struct hm_header_st *out_hdr,
                          CBS *out_body);

// DTLS1_MTU_TIMEOUTS is the maximum number of retransmit timeouts to expire
// before starting to decrease the MTU.
#define DTLS1_MTU_TIMEOUTS 2

// DTLS1_MAX_TIMEOUTS is the maximum number of retransmit timeouts to expire
// before failing the DTLS handshake.
#define DTLS1_MAX_TIMEOUTS 12

void dtls1_stop_timer(SSLImpl *ssl);

unsigned int dtls1_min_mtu();

bool dtls1_new(SSLImpl *ssl);
void dtls1_free(SSLImpl *ssl);

bool dtls1_process_handshake_fragments(SSLImpl *ssl, uint8_t *out_alert,
                                       DTLSRecordNumber record_number,
                                       Span<const uint8_t> record);
bool dtls1_get_message(const SSLImpl *ssl, SSLMessage *out);
ssl_open_record_t dtls1_open_handshake(SSLImpl *ssl, size_t *out_consumed,
                                       uint8_t *out_alert, Span<uint8_t> in);
void dtls1_next_message(SSLImpl *ssl);
int dtls1_dispatch_alert(SSLImpl *ssl);

// tls1_configure_aead configures either the read or write direction AEAD (as
// determined by `direction`) using the keys generated by the TLS KDF. The
// `key_block_cache` argument is used to store the generated key block, if
// empty. Otherwise it's assumed that the key block is already contained within
// it. It returns true on success or false on error.
bool tls1_configure_aead(SSLImpl *ssl, evp_aead_direction_t direction,
                         Array<uint8_t> *key_block_cache,
                         const SSL_SESSION *session,
                         Span<const uint8_t> iv_override);

bool tls1_change_cipher_state(SSL_HANDSHAKE *hs,
                              evp_aead_direction_t direction);

// tls1_generate_master_secret computes the master secret from `premaster` and
// writes it to `out`. `out` must have size `SSL3_MASTER_SECRET_SIZE`.
bool tls1_generate_master_secret(SSL_HANDSHAKE *hs, Span<uint8_t> out,
                                 Span<const uint8_t> premaster);

// tls1_check_group_id returns whether `group_id` is consistent with locally-
// configured group preferences.
bool tls1_check_group_id(const SSL_HANDSHAKE *ssl, uint16_t group_id);

// tls1_get_shared_group sets `*out_group_id` to the first preferred shared
// group between client and server preferences and returns true. If none may be
// found, it returns false.
bool tls1_get_shared_group(SSL_HANDSHAKE *hs, uint16_t *out_group_id);

// ssl_add_clienthello_tlsext writes ClientHello extensions to `out` for `type`.
// It returns true on success and false on failure. `out` must currently contain
// a ClientHello message, not including the message and record header. (Its
// contents will be used to compute padding and PSK binders.)
//
// If `type` is `ssl_client_hello_inner`, this function also writes the
// compressed extensions to `out_encoded`. Otherwise, `out_encoded` should be
// nullptr.
bool ssl_add_clienthello_tlsext(SSL_HANDSHAKE *hs, CBB *out, CBB *out_encoded,
                                ssl_client_hello_type_t type);

bool ssl_add_serverhello_tlsext(SSL_HANDSHAKE *hs, CBB *out);
bool ssl_parse_clienthello_tlsext(SSL_HANDSHAKE *hs,
                                  const SSL_CLIENT_HELLO *client_hello);
bool ssl_parse_serverhello_tlsext(SSL_HANDSHAKE *hs, const CBS *extensions);

#define tlsext_tick_md EVP_sha256

// ssl_process_ticket processes a session ticket from the client. It returns
// one of:
//   `ssl_ticket_aead_success`: `*out_session` is set to the parsed session and
//       `*out_renew_ticket` is set to whether the ticket should be renewed.
//   `ssl_ticket_aead_ignore_ticket`: `*out_renew_ticket` is set to whether a
//       fresh ticket should be sent, but the given ticket cannot be used.
//   `ssl_ticket_aead_retry`: the ticket could not be immediately decrypted.
//       Retry later.
//   `ssl_ticket_aead_error`: an error occurred that is fatal to the connection.
//
// If `save_ticket` is true, `*out_session` will have a copy of the ticket saved
// in its `ticket` field.
enum ssl_ticket_aead_result_t ssl_process_ticket(
    SSL_HANDSHAKE *hs, UniquePtr<SSL_SESSION> *out_session,
    bool *out_renew_ticket, Span<const uint8_t> ticket,
    Span<const uint8_t> session_id, bool save_ticket);

// tls1_verify_channel_id processes `msg` as a Channel ID message, and verifies
// the signature. If the key is valid, it saves the Channel ID and returns true.
// Otherwise, it returns false.
bool tls1_verify_channel_id(SSL_HANDSHAKE *hs, const SSLMessage &msg);

// tls1_write_channel_id generates a Channel ID message and puts the output in
// `cbb`. `ssl->channel_id_private` must already be set before calling.  This
// function returns true on success and false on error.
bool tls1_write_channel_id(SSL_HANDSHAKE *hs, CBB *cbb);

// tls1_channel_id_hash computes the hash to be signed by Channel ID and writes
// it to `out`, which must contain at least `EVP_MAX_MD_SIZE` bytes. It returns
// true on success and false on failure.
bool tls1_channel_id_hash(SSL_HANDSHAKE *hs, uint8_t *out, size_t *out_len);

// tls1_record_handshake_hashes_for_channel_id records the current handshake
// hashes in `hs->new_session` so that Channel ID resumptions can sign that
// data.
bool tls1_record_handshake_hashes_for_channel_id(SSL_HANDSHAKE *hs);

// ssl_can_write returns whether `ssl` is allowed to write.
bool ssl_can_write(const SSLImpl *ssl);

// ssl_can_read returns whether `ssl` is allowed to read.
bool ssl_can_read(const SSLImpl *ssl);

OPENSSL_timeval ssl_ctx_get_current_time(const SSLContext *ctx);

// ssl_reset_error_state resets state for `SSL_get_error`.
void ssl_reset_error_state(SSLImpl *ssl);

// ssl_set_read_error sets `ssl`'s read half into an error state, saving the
// current state of the error queue.
void ssl_set_read_error(SSLImpl *ssl);

BSSL_NAMESPACE_END


// Opaque C types.
//
// The following types are exported to C code as public typedefs, so they must
// be defined outside of the namespace.
//
// TODO(crbug.com/500444613): Move these to the bssl namespace.

// ssl_method_st backs the public `SSL_METHOD` type. It is a compatibility
// structure to support the legacy version-locked methods.
struct ssl_method_st {
  // version, if non-zero, is the only protocol version acceptable to an
  // SSL_CTX initialized from this method.
  uint16_t version;
  // method is the underlying SSL_PROTOCOL_METHOD that initializes the
  // SSL_CTX.
  const bssl::SSL_PROTOCOL_METHOD *method;
  // x509_method contains pointers to functions that might deal with `X509`
  // compatibility, or might be a no-op, depending on the application.
  const bssl::SSL_X509_METHOD *x509_method;
};

BSSL_NAMESPACE_BEGIN
class SSLContext : public ssl_ctx_st, public RefCounted<SSLContext> {
 public:
  explicit SSLContext(const SSL_METHOD *ssl_method);
  SSLContext(const SSLContext &) = delete;
  SSLContext &operator=(const SSLContext &) = delete;

  const SSL_PROTOCOL_METHOD *method = nullptr;
  const SSL_X509_METHOD *x509_method = nullptr;

  // lock is used to protect various operations on this object.
  mutable Mutex lock;

  // conf_max_version is the maximum acceptable protocol version configured by
  // `SSL_CTX_set_max_proto_version`. Note this version is normalized in DTLS
  // and is further constrained by `SSL_OP_NO_*`.
  uint16_t conf_max_version = 0;

  // conf_min_version is the minimum acceptable protocol version configured by
  // `SSL_CTX_set_min_proto_version`. Note this version is normalized in DTLS
  // and is further constrained by `SSL_OP_NO_*`.
  uint16_t conf_min_version = 0;

  // num_tickets is the number of tickets to send immediately after the TLS 1.3
  // handshake. TLS 1.3 recommends single-use tickets so, by default, issue two
  /// in case the client makes several connections before getting a renewal.
  uint8_t num_tickets = 2;

  // quic_method is the method table corresponding to the QUIC hooks.
  const SSL_QUIC_METHOD *quic_method = nullptr;

  UniquePtr<SSLCipherPreferenceList> cipher_list;

  X509_STORE *cert_store = nullptr;
  LHASH_OF(SSL_SESSION) *sessions = nullptr;
  // Most session-ids that will be cached, default is
  // SSL_SESSION_CACHE_MAX_SIZE_DEFAULT. 0 is unlimited.
  unsigned long session_cache_size = SSL_SESSION_CACHE_MAX_SIZE_DEFAULT;
  SSL_SESSION *session_cache_head = nullptr;
  SSL_SESSION *session_cache_tail = nullptr;

  // handshakes_since_cache_flush is the number of successful handshakes since
  // the last cache flush.
  int handshakes_since_cache_flush = 0;

  // This can have one of 2 values, ored together,
  // SSL_SESS_CACHE_CLIENT,
  // SSL_SESS_CACHE_SERVER,
  // Default is SSL_SESSION_CACHE_SERVER, which means only
  // SSL_accept which cache SSL_SESSIONS.
  int session_cache_mode = SSL_SESS_CACHE_SERVER;

  // session_timeout is the default lifetime for new sessions in TLS 1.2 and
  // earlier, in seconds.
  uint32_t session_timeout = SSL_DEFAULT_SESSION_TIMEOUT;

  // session_psk_dhe_timeout is the default lifetime for new sessions in TLS
  // 1.3, in seconds.
  uint32_t session_psk_dhe_timeout = SSL_DEFAULT_SESSION_PSK_DHE_TIMEOUT;

  // If this callback is not null, it will be called each time a session id is
  // added to the cache.  If this function returns 1, it means that the
  // callback will do a SSL_SESSION_free() when it has finished using it.
  // Otherwise, on 0, it means the callback has finished with it. If
  // remove_session_cb is not null, it will be called when a session-id is
  // removed from the cache.  After the call, OpenSSL will SSL_SESSION_free()
  // it.
  int (*new_session_cb)(SSL *ssl, SSL_SESSION *sess) = nullptr;
  void (*remove_session_cb)(SSL_CTX *ctx, SSL_SESSION *sess) = nullptr;
  SSL_SESSION *(*get_session_cb)(SSL *ssl, const uint8_t *data, int len,
                                 int *copy) = nullptr;

  // if defined, these override the X509_verify_cert() calls
  int (*app_verify_callback)(X509_STORE_CTX *store_ctx, void *arg) = nullptr;
  void *app_verify_arg = nullptr;

  ssl_verify_result_t (*custom_verify_callback)(SSL *ssl,
                                                uint8_t *out_alert) = nullptr;

  // Default password callback.
  pem_password_cb *default_passwd_callback = nullptr;

  // Default password callback user data.
  void *default_passwd_callback_userdata = nullptr;

  // get client cert callback
  int (*client_cert_cb)(SSL *ssl, X509 **out_x509,
                        EVP_PKEY **out_pkey) = nullptr;

  CRYPTO_EX_DATA ex_data;

  // Default values used when no per-SSL value is defined follow

  void (*info_callback)(const SSL *ssl, int type, int value) = nullptr;

  // what we put in client cert requests
  UniquePtr<STACK_OF(CRYPTO_BUFFER)> client_CA;

  // cached_x509_client_CA is a cache of parsed versions of the elements of
  // `client_CA`.
  STACK_OF(X509_NAME) *cached_x509_client_CA = nullptr;

  // What we put in client hello in the CA extension.
  UniquePtr<STACK_OF(CRYPTO_BUFFER)> CA_names;

  // What we request in the trust_anchors extension.
  std::optional<Array<uint8_t>> requested_trust_anchors;

  // Default values to use in SSL structures follow (these are copied by
  // SSL_new)

  uint32_t options = SSL_OP_ALL;
  // Disable the auto-chaining feature by default. wpa_supplicant relies on this
  // feature, but require callers opt into it.
  uint32_t mode = SSL_MODE_NO_AUTO_CHAIN;
  uint32_t max_cert_list = SSL_MAX_CERT_LIST_DEFAULT;

  UniquePtr<CERT> cert;

  // callback that allows applications to peek at protocol messages
  void (*msg_callback)(int is_write, int version, int content_type,
                       const void *buf, size_t len, SSL *ssl,
                       void *arg) = nullptr;
  void *msg_callback_arg = nullptr;

  int verify_mode = SSL_VERIFY_NONE;
  int (*default_verify_callback)(int ok, X509_STORE_CTX *ctx) =
      nullptr;  // called 'verify_callback' in the SSL

  X509_VERIFY_PARAM *param = nullptr;

  // select_certificate_cb is called before most ClientHello processing and
  // before the decision whether to resume a session is made. See
  // `ssl_select_cert_result_t` for details of the return values.
  ssl_select_cert_result_t (*select_certificate_cb)(const SSL_CLIENT_HELLO *) =
      nullptr;

  // dos_protection_cb is called once the resumption decision for a ClientHello
  // has been made. It returns one to continue the handshake or zero to
  // abort.
  int (*dos_protection_cb)(const SSL_CLIENT_HELLO *) = nullptr;

  // Controls whether to verify certificates when resuming connections. They
  // were already verified when the connection was first made, so the default is
  // false. For now, this is only respected on clients, not servers.
  bool reverify_on_resume = false;

  // Maximum amount of data to send in one fragment. actual record size can be
  // more than this due to padding and MAC overheads.
  uint16_t max_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH;

  // TLS extensions servername callback
  int (*servername_callback)(SSL *, int *, void *) = nullptr;
  void *servername_arg = nullptr;

  // RFC 4507 session ticket keys. `ticket_key_current` may be NULL before the
  // first handshake and `ticket_key_prev` may be NULL at any time.
  // Automatically generated ticket keys are rotated as needed at handshake
  // time. Hence, all access must be synchronized through `lock`.
  UniquePtr<TicketKey> ticket_key_current;
  UniquePtr<TicketKey> ticket_key_prev;

  // Callback to support customisation of ticket key setting
  int (*ticket_key_cb)(SSL *ssl, uint8_t *name, uint8_t *iv,
                       EVP_CIPHER_CTX *ectx, HMAC_CTX *hctx, int enc) = nullptr;

  // Server-only: psk_identity_hint is the default identity hint to send in
  // PSK-based key exchanges.
  UniquePtr<char> psk_identity_hint;

  unsigned (*psk_client_callback)(SSL *ssl, const char *hint, char *identity,
                                  unsigned max_identity_len, uint8_t *psk,
                                  unsigned max_psk_len) = nullptr;
  unsigned (*psk_server_callback)(SSL *ssl, const char *identity, uint8_t *psk,
                                  unsigned max_psk_len) = nullptr;


  // Next protocol negotiation information
  // (for experimental NPN extension).

  // For a server, this contains a callback function by which the set of
  // advertised protocols can be provided.
  int (*next_protos_advertised_cb)(SSL *ssl, const uint8_t **out,
                                   unsigned *out_len, void *arg) = nullptr;
  void *next_protos_advertised_cb_arg = nullptr;
  // For a client, this contains a callback function that selects the
  // next protocol from the list provided by the server.
  int (*next_proto_select_cb)(SSL *ssl, uint8_t **out, uint8_t *out_len,
                              const uint8_t *in, unsigned in_len,
                              void *arg) = nullptr;
  void *next_proto_select_cb_arg = nullptr;

  // ALPN information
  // (we are in the process of transitioning from NPN to ALPN.)

  // For a server, this contains a callback function that allows the
  // server to select the protocol for the connection.
  //   out: on successful return, this must point to the raw protocol
  //        name (without the length prefix).
  //   outlen: on successful return, this contains the length of `*out`.
  //   in: points to the client's list of supported protocols in
  //       wire-format.
  //   inlen: the length of `in`.
  int (*alpn_select_cb)(SSL *ssl, const uint8_t **out, uint8_t *out_len,
                        const uint8_t *in, unsigned in_len,
                        void *arg) = nullptr;
  void *alpn_select_cb_arg = nullptr;

  // For a client, this contains the list of supported protocols in wire
  // format.
  Array<uint8_t> alpn_client_proto_list;

  // SRTP profiles we are willing to do from RFC 5764
  UniquePtr<STACK_OF(SRTP_PROTECTION_PROFILE)> srtp_profiles;

  // Defined compression algorithms for certificates.
  Vector<CertCompressionAlg> cert_compression_algs;

  // Supported group values and flags inherited by SSL structure
  Array<uint16_t> supported_group_list;
  Array<uint32_t> supported_group_list_flags;

  // channel_id_private is the client's Channel ID private key, or null if
  // Channel ID should not be offered on this connection.
  UniquePtr<EVP_PKEY> channel_id_private;

  // ech_keys contains the server's list of ECHConfig values and associated
  // private keys. This list may be swapped out at any time, so all access must
  // be synchronized through `lock`.
  UniquePtr<SSLECHKeys> ech_keys;

  // keylog_callback, if not NULL, is the key logging callback. See
  // `SSL_CTX_set_keylog_callback`.
  void (*keylog_callback)(const SSL *ssl, const char *line) = nullptr;

  // current_time_cb, if not NULL, is the function to use to get the current
  // time. It sets `*out_clock` to the current time. The `ssl` argument is
  // always NULL. See `SSL_CTX_set_current_time_cb`.
  void (*current_time_cb)(const SSL *ssl, struct timeval *out_clock) = nullptr;

  // pool is used for all `CRYPTO_BUFFER`s in case we wish to share certificate
  // memory.
  UniquePtr<CRYPTO_BUFFER_POOL> pool;

  // ticket_aead_method contains function pointers for opening and sealing
  // session tickets.
  const SSL_TICKET_AEAD_METHOD *ticket_aead_method = nullptr;

  // legacy_ocsp_callback implements an OCSP-related callback for OpenSSL
  // compatibility.
  int (*legacy_ocsp_callback)(SSL *ssl, void *arg) = nullptr;
  void *legacy_ocsp_callback_arg = nullptr;

  // compliance_policy limits the set of ciphers that can be selected when
  // negotiating a TLS 1.3 connection.
  enum ssl_compliance_policy_t compliance_policy = ssl_compliance_policy_none;

  // verify_sigalgs, if not empty, is the set of signature algorithms
  // accepted from the peer in decreasing order of preference.
  Array<uint16_t> verify_sigalgs;

  // accepted_peer_cert_types inherited by SSL struct.
  InplaceVector<uint8_t, kNumCertTypes> accepted_peer_cert_types;

  // available_client_cert_types inherited by SSL struct.
  InplaceVector<uint8_t, kNumCertTypes> available_client_cert_types;

  // retain_only_sha256_of_client_certs is true if we should compute the SHA256
  // hash of the peer's certificate and then discard it to save memory and
  // session space. Only effective on the server side.
  bool retain_only_sha256_of_client_certs : 1;

  // quiet_shutdown is true if the connection should not send a close_notify on
  // shutdown.
  bool quiet_shutdown : 1;

  // ocsp_stapling_enabled is only used by client connections and indicates
  // whether OCSP stapling will be requested.
  bool ocsp_stapling_enabled : 1;

  // If true, a client will request certificate timestamps.
  bool signed_cert_timestamps_enabled : 1;

  // channel_id_enabled is whether Channel ID is enabled. For a server, means
  // that we'll accept Channel IDs from clients.  For a client, means that we'll
  // advertise support.
  bool channel_id_enabled : 1;

  // grease_enabled is whether GREASE (RFC 8701) is enabled.
  bool grease_enabled : 1;

  // grease_sigalgs_enabled controls whether GREASE signature algorithms may be
  // sent.
  // TODO(crbug.com/526597789): Fold into `grease_enabled` once deployed safely.
  bool grease_sigalgs_enabled : 1;

  // permute_extensions is whether to permute extensions when sending messages.
  bool permute_extensions : 1;

  // allow_unknown_alpn_protos is whether the client allows unsolicited ALPN
  // protocols from the peer.
  bool allow_unknown_alpn_protos : 1;

  // false_start_allowed_without_alpn is whether False Start (if
  // `SSL_MODE_ENABLE_FALSE_START` is enabled) is allowed without ALPN.
  bool false_start_allowed_without_alpn : 1;

  // handoff indicates that a server should stop after receiving the
  // ClientHello and pause the handshake in such a way that `SSL_get_error`
  // returns `SSL_ERROR_HANDOFF`.
  bool handoff : 1;

  // If enable_early_data is true, early data can be sent and accepted.
  bool enable_early_data : 1;

  // aes_hw_override if set indicates we should override checking for AES
  // hardware support, and use the value in aes_hw_override_value instead.
  bool aes_hw_override : 1;

  // aes_hw_override_value is used for testing to indicate the support or lack
  // of support for AES hardware. The value is only considered if
  // `aes_hw_override` is true.
  bool aes_hw_override_value : 1;

  // resumption_across_names_enabled indicates whether a TLS 1.3 server should
  // signal its sessions may be resumed across names in the server certificate.
  bool resumption_across_names_enabled : 1;

 private:
  friend RefCounted;
  ~SSLContext();
};

class SSLImpl : public ssl_st {
 public:
  static constexpr bool kAllowUniquePtr = true;

  explicit SSLImpl(SSLContext *ctx_arg);
  SSLImpl(const SSLImpl &) = delete;
  SSLImpl &operator=(const SSLImpl &) = delete;
  ~SSLImpl();

  // method is the method table corresponding to the current protocol (DTLS or
  // TLS).
  const SSL_PROTOCOL_METHOD *method = nullptr;

  // config is a container for handshake configuration.  Accesses to this field
  // should check for nullptr, since configuration may be shed after the
  // handshake completes.  (If you have the `SSL_HANDSHAKE` object at hand, use
  // that instead, and skip the null check.)
  UniquePtr<SSL_CONFIG> config;

  uint16_t max_send_fragment = 0;

  // There are 2 BIO's even though they are normally both the same. This is so
  // data can be read and written to different handlers

  UniquePtr<BIO> rbio;  // used by SSL_read
  UniquePtr<BIO> wbio;  // used by SSL_write

  // do_handshake runs the handshake. On completion, it returns `ssl_hs_ok`.
  // Otherwise, it returns a value corresponding to what operation is needed to
  // progress.
  ssl_hs_wait_t (*do_handshake)(SSL_HANDSHAKE *hs) = nullptr;

  SSL3_STATE *s3 = nullptr;   // TLS variables
  DTLS1_STATE *d1 = nullptr;  // DTLS variables

  // callback that allows applications to peek at protocol messages
  void (*msg_callback)(int write_p, int version, int content_type,
                       const void *buf, size_t len, SSL *ssl,
                       void *arg) = nullptr;
  void *msg_callback_arg = nullptr;

  // session info

  // initial_timeout_duration_ms is the default DTLS timeout duration in
  // milliseconds. It's used to initialize the timer any time it's restarted. We
  // default to RFC 9147's recommendation for real-time applications, 400ms.
  uint32_t initial_timeout_duration_ms = 400;

  // session is the configured session to be offered by the client. This session
  // is immutable.
  UniquePtr<SSL_SESSION> session;

  void (*info_callback)(const SSL *ssl, int type, int value) = nullptr;

  UniquePtr<SSLContext> ctx;

  // session_ctx is the `SSLContext` used for the session cache and related
  // settings.
  UniquePtr<SSLContext> session_ctx;

  // extra application data
  CRYPTO_EX_DATA ex_data;

  uint32_t options = 0;  // protocol behaviour
  uint32_t mode = 0;     // API behaviour
  uint32_t max_cert_list = 0;
  UniquePtr<char> hostname;

  // quic_method is the method table corresponding to the QUIC hooks.
  const SSL_QUIC_METHOD *quic_method = nullptr;

  // renegotiate_mode controls how peer renegotiation attempts are handled.
  ssl_renegotiate_mode_t renegotiate_mode = ssl_renegotiate_never;

  // server is true iff this SSL* is the server half. Note: before the SSL*
  // is initialized by either SSL_set_accept_state or SSL_set_connect_state,
  // the side is not determined. In this state, server is always false.
  bool server : 1;

  // quiet_shutdown is true if the connection should not send a close_notify on
  // shutdown.
  bool quiet_shutdown : 1;

  // If enable_early_data is true, early data can be sent and accepted.
  bool enable_early_data : 1;

  // resumption_across_names_enabled indicates whether a TLS 1.3 server should
  // signal its sessions may be resumed across names in the server certificate.
  bool resumption_across_names_enabled : 1;
};
BSSL_NAMESPACE_END

struct ssl_session_st : public bssl::RefCounted<ssl_session_st> {
  explicit ssl_session_st(const bssl::SSL_X509_METHOD *method);
  ssl_session_st(const ssl_session_st &) = delete;
  ssl_session_st &operator=(const ssl_session_st &) = delete;

  // ssl_version is the (D)TLS version that established the session.
  uint16_t ssl_version = 0;

  // group_id is the ID of the ECDH group used to establish this session or zero
  // if not applicable or unknown.
  uint16_t group_id = 0;

  // peer_signature_algorithm is the signature algorithm used to authenticate
  // the peer, or zero if not applicable or unknown.
  uint16_t peer_signature_algorithm = 0;

  // secret, in TLS 1.2 and below, is the master secret associated with the
  // session. In TLS 1.3 and up, it is the resumption PSK for sessions handed to
  // the caller, but it stores the resumption secret when stored on `SSL`
  // objects.
  bssl::InplaceVector<uint8_t, SSL_MAX_MASTER_KEY_LENGTH> secret;

  bssl::InplaceVector<uint8_t, SSL_MAX_SSL_SESSION_ID_LENGTH> session_id;

  // this is used to determine whether the session is being reused in
  // the appropriate context. It is up to the application to set this,
  // via SSL_new
  bssl::InplaceVector<uint8_t, SSL_MAX_SID_CTX_LENGTH> sid_ctx;

  bssl::UniquePtr<char> psk_identity;

  // certs contains the certificate chain from the peer, starting with the leaf
  // certificate. This must be null if `peer_raw_public_key` is non-null.
  bssl::UniquePtr<STACK_OF(CRYPTO_BUFFER)> certs;

  const bssl::SSL_X509_METHOD *x509_method = nullptr;

  // x509_peer is the peer's certificate. This must be null if
  // `peer_raw_public_key` is non-null.
  X509 *x509_peer = nullptr;

  // x509_chain is the certificate chain sent by the peer. NOTE: for historical
  // reasons, when a client (so the peer is a server), the chain includes
  // `peer`, but when a server it does not. This must be null if
  // `peer_raw_public_key` is non-null.
  STACK_OF(X509) *x509_chain = nullptr;

  // x509_chain_without_leaf is a lazily constructed copy of `x509_chain` that
  // omits the leaf certificate. This exists because OpenSSL, historically,
  // didn't include the leaf certificate in the chain for a server, but did for
  // a client. The `x509_chain` always includes it and, if an API call requires
  // a chain without, it is stored here. This must be null if
  // `peer_raw_public_key` is non-null.
  STACK_OF(X509) *x509_chain_without_leaf = nullptr;

  // verify_result is the result of certificate verification in the case of
  // non-fatal certificate errors.
  long verify_result = X509_V_ERR_INVALID_CALL;

  // timeout is the lifetime of the session in seconds, measured from `time`.
  // This is renewable up to `auth_timeout`.
  uint32_t timeout = SSL_DEFAULT_SESSION_TIMEOUT;

  // auth_timeout is the non-renewable lifetime of the session in seconds,
  // measured from `time`.
  uint32_t auth_timeout = SSL_DEFAULT_SESSION_TIMEOUT;

  // time is the time the session was issued, measured in seconds from the UNIX
  // epoch.
  uint64_t time = 0;

  const SSL_CIPHER *cipher = nullptr;

  CRYPTO_EX_DATA ex_data;  // application specific data

  // These are used to make removal of session-ids more efficient and to
  // implement a maximum cache size.
  SSL_SESSION *prev = nullptr, *next = nullptr;

  bssl::Array<uint8_t> ticket;

  bssl::UniquePtr<CRYPTO_BUFFER> signed_cert_timestamp_list;

  // The OCSP response that came with the session.
  bssl::UniquePtr<CRYPTO_BUFFER> ocsp_response;

  // peer_sha256 contains the SHA-256 hash of the peer's X.509 certificate or
  // raw public key if `peer_sha256_valid` is true. (`peer_cert_type` indicates
  // which type of credential is hashed here.)
  uint8_t peer_sha256[SHA256_DIGEST_LENGTH] = {0};

  // original_handshake_hash contains the handshake hash (either SHA-1+MD5 or
  // SHA-2, depending on TLS version) for the original, full handshake that
  // created a session. This is used by Channel IDs during resumption.
  bssl::InplaceVector<uint8_t, SSL_MAX_MD_SIZE> original_handshake_hash;

  uint32_t ticket_lifetime_hint = 0;  // Session lifetime hint in seconds

  uint32_t ticket_age_add = 0;

  // ticket_max_early_data is the maximum amount of data allowed to be sent as
  // early data. If zero, 0-RTT is disallowed.
  uint32_t ticket_max_early_data = 0;

  // early_alpn is the ALPN protocol from the initial handshake. This is only
  // stored for TLS 1.3 and above in order to enforce ALPN matching for 0-RTT
  // resumptions. For the current connection's ALPN protocol, see
  // `alpn_selected` on `SSL3_STATE`.
  bssl::Array<uint8_t> early_alpn;

  // local_application_settings, if `has_application_settings` is true, is the
  // local ALPS value for this connection.
  bssl::Array<uint8_t> local_application_settings;

  // peer_application_settings, if `has_application_settings` is true, is the
  // peer ALPS value for this connection.
  bssl::Array<uint8_t> peer_application_settings;

  // extended_master_secret is whether the master secret in this session was
  // generated using EMS and thus isn't vulnerable to the Triple Handshake
  // attack.
  bool extended_master_secret : 1;

  // peer_sha256_valid is whether `peer_sha256` is valid.
  bool peer_sha256_valid : 1;  // Non-zero if peer_sha256 is valid

  // not_resumable is used to indicate that session resumption is disallowed.
  bool not_resumable : 1;

  // ticket_age_add_valid is whether `ticket_age_add` is valid.
  bool ticket_age_add_valid : 1;

  // is_server is whether this session was created by a server.
  bool is_server : 1;

  // is_quic indicates whether this session was created using QUIC.
  bool is_quic : 1;

  // has_application_settings indicates whether ALPS was negotiated in this
  // session.
  bool has_application_settings : 1;

  // is_resumable_across_names indicates whether the session may be resumed for
  // any of the identities presented in the certificate.
  bool is_resumable_across_names : 1;

  // quic_early_data_context is used to determine whether early data must be
  // rejected when performing a QUIC handshake.
  bssl::Array<uint8_t> quic_early_data_context;

  // peer_cert_type is the peer's cert type (`TLSEXT_cert_type_*` value), which
  // determines the type of Certificate the peer used for this session: which of
  // `certs` xor `peer_raw_public_key` is populated for an authenticated
  // session.
  uint8_t peer_cert_type = bssl::kDefaultCertType;

  // peer_raw_public_key, if non-null, is the raw public key received from the
  // peer. This must be null if `certs` is non-null.
  bssl::UniquePtr<EVP_PKEY> peer_raw_public_key;

 private:
  friend RefCounted;
  ~ssl_session_st();
};

#endif  // OPENSSL_HEADER_SSL_INTERNAL_H
