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

#include <openssl/ssl.h>

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

#include <utility>

#include <openssl/bytestring.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/hkdf.h>
#include <openssl/mem.h>
#include <openssl/pool.h>
#include <openssl/stack.h>
#include <openssl/x509.h>

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


BSSL_NAMESPACE_BEGIN

// kMaxKeyUpdates is the number of consecutive KeyUpdates that will be
// processed. Without this limit an attacker could force unbounded processing
// without being able to return application data.
static const uint8_t kMaxKeyUpdates = 32;

const uint8_t kHelloRetryRequest[SSL3_RANDOM_SIZE] = {
    0xcf, 0x21, 0xad, 0x74, 0xe5, 0x9a, 0x61, 0x11, 0xbe, 0x1d, 0x8c,
    0x02, 0x1e, 0x65, 0xb8, 0x91, 0xc2, 0xa2, 0x11, 0x16, 0x7a, 0xbb,
    0x8c, 0x5e, 0x07, 0x9e, 0x09, 0xe2, 0xc8, 0xa8, 0x33, 0x9c,
};

// See RFC 8446, section 4.1.3.
const uint8_t kTLS12DowngradeRandom[8] = {0x44, 0x4f, 0x57, 0x4e,
                                          0x47, 0x52, 0x44, 0x00};
const uint8_t kTLS13DowngradeRandom[8] = {0x44, 0x4f, 0x57, 0x4e,
                                          0x47, 0x52, 0x44, 0x01};

// This is a non-standard randomly-generated value.
const uint8_t kJDK11DowngradeRandom[8] = {0xed, 0xbf, 0xb4, 0xa8,
                                          0xc2, 0x47, 0x10, 0xff};

bool tls13_get_cert_verify_signature_input(
    SSL_HANDSHAKE *hs, Array<uint8_t> *out,
    enum ssl_cert_verify_context_t cert_verify_context) {
  ScopedCBB cbb;
  if (!CBB_init(cbb.get(), 64 + 33 + 1 + 2 * EVP_MAX_MD_SIZE)) {
    return false;
  }

  for (size_t i = 0; i < 64; i++) {
    if (!CBB_add_u8(cbb.get(), 0x20)) {
      return false;
    }
  }

  Span<const char> context;
  if (cert_verify_context == ssl_cert_verify_server) {
    static const char kContext[] = "TLS 1.3, server CertificateVerify";
    context = kContext;
  } else if (cert_verify_context == ssl_cert_verify_client) {
    static const char kContext[] = "TLS 1.3, client CertificateVerify";
    context = kContext;
  } else if (cert_verify_context == ssl_cert_verify_channel_id) {
    static const char kContext[] = "TLS 1.3, Channel ID";
    context = kContext;
  } else {
    return false;
  }

  // Note `context` includes the NUL byte separator.
  if (!CBB_add_bytes(cbb.get(),
                     reinterpret_cast<const uint8_t *>(context.data()),
                     context.size())) {
    return false;
  }

  uint8_t context_hash[EVP_MAX_MD_SIZE];
  size_t context_hash_len;
  if (!hs->transcript.GetHash(context_hash, &context_hash_len) ||
      !CBB_add_bytes(cbb.get(), context_hash, context_hash_len) ||
      !CBBFinishArray(cbb.get(), out)) {
    return false;
  }

  return true;
}

bool tls13_process_certificate(SSL_HANDSHAKE *hs, const SSLMessage &msg,
                               bool allow_anonymous) {
  SSLImpl *const ssl = hs->ssl;
  CBS body = msg.body;
  bssl::UniquePtr<CRYPTO_BUFFER> decompressed;

  if (msg.type == SSL3_MT_COMPRESSED_CERTIFICATE) {
    CBS compressed;
    uint16_t alg_id;
    uint32_t uncompressed_len;

    if (!CBS_get_u16(&body, &alg_id) ||
        !CBS_get_u24(&body, &uncompressed_len) ||
        !CBS_get_u24_length_prefixed(&body, &compressed) ||
        CBS_len(&body) != 0) {
      ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
      OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
      return false;
    }

    if (uncompressed_len > ssl->max_cert_list) {
      ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
      OPENSSL_PUT_ERROR(SSL, SSL_R_UNCOMPRESSED_CERT_TOO_LARGE);
      ERR_add_error_dataf("requested=%u",
                          static_cast<unsigned>(uncompressed_len));
      return false;
    }

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

    if (decompress == nullptr) {
      ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
      OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CERT_COMPRESSION_ALG);
      ERR_add_error_dataf("alg=%d", static_cast<int>(alg_id));
      return false;
    }

    CRYPTO_BUFFER *decompressed_ptr = nullptr;
    if (!decompress(ssl, &decompressed_ptr, uncompressed_len,
                    CBS_data(&compressed), CBS_len(&compressed))) {
      ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
      OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_DECOMPRESSION_FAILED);
      ERR_add_error_dataf("alg=%d", static_cast<int>(alg_id));
      return false;
    }
    decompressed.reset(decompressed_ptr);

    if (CRYPTO_BUFFER_len(decompressed_ptr) != uncompressed_len) {
      ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
      OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_DECOMPRESSION_FAILED);
      ERR_add_error_dataf(
          "alg=%d got=%u expected=%u", static_cast<int>(alg_id),
          static_cast<unsigned>(CRYPTO_BUFFER_len(decompressed_ptr)),
          static_cast<unsigned>(uncompressed_len));
      return false;
    }

    CBS_init(&body, CRYPTO_BUFFER_data(decompressed_ptr),
             CRYPTO_BUFFER_len(decompressed_ptr));
  } else {
    assert(msg.type == SSL3_MT_CERTIFICATE);
  }

  CBS context, certificate_list;
  if (!CBS_get_u8_length_prefixed(&body, &context) ||            //
      CBS_len(&context) != 0 ||                                  //
      !CBS_get_u24_length_prefixed(&body, &certificate_list) ||  //
      CBS_len(&body) != 0) {
    ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
    OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
    return false;
  }

  // Only used for X.509 certificates.
  UniquePtr<STACK_OF(CRYPTO_BUFFER)> certs(sk_CRYPTO_BUFFER_new_null());
  if (!certs) {
    ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
    return false;
  }

  const bool retain_sha256 =
      ssl->server && hs->config->retain_only_sha256_of_client_certs;
  UniquePtr<EVP_PKEY> pkey;
  while (CBS_len(&certificate_list) > 0) {
    CBS certificate;  // For an RPK, this is the subjectPublicKeyInfo.
    CBS extensions;
    if (!CBS_get_u24_length_prefixed(&certificate_list, &certificate) ||
        !CBS_get_u16_length_prefixed(&certificate_list, &extensions) ||
        CBS_len(&certificate) == 0) {
      ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
      OPENSSL_PUT_ERROR(SSL, hs->peer_cert_type == TLSEXT_cert_type_rpk
                                 ? SSL_R_INVALID_RAW_PUBLIC_KEY
                                 : SSL_R_CERT_LENGTH_MISMATCH);
      return false;
    }
    const bool is_first_entry = pkey == nullptr;
    if (is_first_entry) {
      if (hs->peer_cert_type == TLSEXT_cert_type_rpk) {
        // Only one CertificateEntry is allowed for RawPublicKey cert type.
        if (CBS_len(&certificate_list) != 0) {
          ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
          OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_RAW_PUBLIC_KEY);
          return false;
        }
        pkey = ssl_parse_peer_subject_public_key_info(certificate);
      } else {
        assert(hs->peer_cert_type == TLSEXT_cert_type_x509);
        bool is_leaf_cert = sk_CRYPTO_BUFFER_num(certs.get()) == 0;
        if (is_leaf_cert) {
          pkey = ssl_cert_parse_pubkey(&certificate);
        }
      }

      if (!pkey) {
        ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
        OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
        return false;
      }
      // TLS 1.3 always uses certificate keys for signing thus the correct
      // keyUsage is enforced. (RPKs have no keyUsage to enforce.)
      if (hs->peer_cert_type == TLSEXT_cert_type_x509 &&
          !ssl_cert_check_key_usage(&certificate,
                                    key_usage_digital_signature)) {
        ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
        return false;
      }

      if (retain_sha256) {
        // Retain the hash of the leaf certificate or RPK if requested.
        SHA256(CBS_data(&certificate), CBS_len(&certificate),
               hs->new_session->peer_sha256);
      }
    }

    if (hs->peer_cert_type == TLSEXT_cert_type_x509) {
      UniquePtr<CRYPTO_BUFFER> buf(
          CRYPTO_BUFFER_new_from_CBS(&certificate, ssl->ctx->pool.get()));
      if (!buf ||  //
          !PushToStack(certs.get(), std::move(buf))) {
        ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
        return false;
      }
    }

    // Extensions are not supported with RPKs.
    const bool cert_extensions_allowed =
        hs->peer_cert_type == TLSEXT_cert_type_x509;

    // Parse out the extensions.
    SSLExtension status_request(TLSEXT_TYPE_status_request,
                                cert_extensions_allowed && !ssl->server &&
                                    hs->config->ocsp_stapling_enabled);
    SSLExtension sct(TLSEXT_TYPE_certificate_timestamp,
                     cert_extensions_allowed && !ssl->server &&
                         hs->config->signed_cert_timestamps_enabled);
    SSLExtension trust_anchors(
        TLSEXT_TYPE_trust_anchors,
        cert_extensions_allowed && !ssl->server && is_first_entry &&
            hs->config->requested_trust_anchors.has_value());
    uint8_t alert = SSL_AD_DECODE_ERROR;
    if (!ssl_parse_extensions(&extensions, &alert,
                              {&status_request, &sct, &trust_anchors},
                              /*ignore_unknown=*/false)) {
      ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
      return false;
    }

    // All Certificate extensions are parsed, but only the leaf extensions are
    // stored.
    if (status_request.present) {
      uint8_t status_type;
      CBS ocsp_response;
      if (!CBS_get_u8(&status_request.data, &status_type) ||
          status_type != TLSEXT_STATUSTYPE_ocsp ||
          !CBS_get_u24_length_prefixed(&status_request.data, &ocsp_response) ||
          CBS_len(&ocsp_response) == 0 || CBS_len(&status_request.data) != 0) {
        OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
        ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
        return false;
      }

      if (sk_CRYPTO_BUFFER_num(certs.get()) == 1) {
        hs->new_session->ocsp_response.reset(
            CRYPTO_BUFFER_new_from_CBS(&ocsp_response, ssl->ctx->pool.get()));
        if (hs->new_session->ocsp_response == nullptr) {
          ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
          return false;
        }
      }
    }

    if (sct.present) {
      if (!ssl_is_sct_list_valid(&sct.data)) {
        OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_PARSING_EXTENSION);
        ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
        return false;
      }

      if (sk_CRYPTO_BUFFER_num(certs.get()) == 1) {
        hs->new_session->signed_cert_timestamp_list.reset(
            CRYPTO_BUFFER_new_from_CBS(&sct.data, ssl->ctx->pool.get()));
        if (hs->new_session->signed_cert_timestamp_list == nullptr) {
          ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
          return false;
        }
      }
    }

    if (trust_anchors.present) {
      if (CBS_len(&trust_anchors.data) != 0) {
        OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_PARSING_EXTENSION);
        ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
        return false;
      }
      hs->peer_matched_trust_anchor = true;
    }
  }

  if (pkey != nullptr) {
    hs->new_session->peer_cert_type = hs->peer_cert_type;
    hs->peer_pubkey = std::move(pkey);
    if (hs->peer_cert_type == TLSEXT_cert_type_rpk) {
      hs->new_session->peer_raw_public_key = UpRef(hs->peer_pubkey);
    } else {
      assert(hs->peer_cert_type == TLSEXT_cert_type_x509);
      hs->new_session->certs = std::move(certs);
    }
  }

  if (!ssl->ctx->x509_method->session_cache_objects(hs->new_session.get())) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
    ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
    return false;
  }

  if (!ssl_session_has_peer_cred(hs->new_session.get())) {
    if (!allow_anonymous) {
      OPENSSL_PUT_ERROR(SSL, SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE);
      ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_CERTIFICATE_REQUIRED);
      return false;
    }

    // OpenSSL returns X509_V_OK when no certificates are requested. This is
    // classed by them as a bug, but it's assumed by at least NGINX.
    hs->new_session->verify_result = X509_V_OK;

    // No certificate, so nothing more to do.
    return true;
  }

  hs->new_session->peer_sha256_valid = retain_sha256;
  return true;
}

bool tls13_process_certificate_verify(SSL_HANDSHAKE *hs,
                                      const SSLMessage &msg) {
  SSLImpl *const ssl = hs->ssl;
  if (hs->peer_pubkey == nullptr) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
    return false;
  }

  CBS body = msg.body, signature;
  uint16_t signature_algorithm;
  if (!CBS_get_u16(&body, &signature_algorithm) ||        //
      !CBS_get_u16_length_prefixed(&body, &signature) ||  //
      CBS_len(&body) != 0) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
    ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
    return false;
  }

  uint8_t alert = SSL_AD_DECODE_ERROR;
  if (!tls12_check_peer_sigalg(hs, &alert, signature_algorithm,
                               hs->peer_pubkey.get())) {
    ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
    return false;
  }
  hs->new_session->peer_signature_algorithm = signature_algorithm;

  Array<uint8_t> input;
  if (!tls13_get_cert_verify_signature_input(
          hs, &input,
          ssl->server ? ssl_cert_verify_client : ssl_cert_verify_server)) {
    ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
    return false;
  }

  if (!ssl_public_key_verify(ssl, signature, signature_algorithm,
                             hs->peer_pubkey.get(), input)) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SIGNATURE);
    ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR);
    return false;
  }

  return true;
}

bool tls13_process_finished(SSL_HANDSHAKE *hs, const SSLMessage &msg,
                            bool use_saved_value) {
  SSLImpl *const ssl = hs->ssl;
  uint8_t verify_data_buf[EVP_MAX_MD_SIZE];
  Span<const uint8_t> verify_data;
  if (use_saved_value) {
    assert(ssl->server);
    verify_data = hs->expected_client_finished;
  } else {
    size_t len;
    if (!tls13_finished_mac(hs, verify_data_buf, &len, !ssl->server)) {
      return false;
    }
    verify_data = Span(verify_data_buf, len);
  }

  bool finished_ok =
      CBS_mem_equal(&msg.body, verify_data.data(), verify_data.size());
  if (CRYPTO_fuzzer_mode_enabled()) {
    finished_ok = true;
  }
  if (!finished_ok) {
    ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR);
    OPENSSL_PUT_ERROR(SSL, SSL_R_DIGEST_CHECK_FAILED);
    return false;
  }

  return true;
}

bool tls13_add_certificate(SSL_HANDSHAKE *hs) {
  SSLImpl *const ssl = hs->ssl;
  const SSLCredential *cred = hs->credential.get();

  ScopedCBB cbb;
  CBB *body, body_storage, certificate_list;

  if (hs->cert_compression_negotiated) {
    if (!CBB_init(cbb.get(), 1024)) {
      return false;
    }
    body = cbb.get();
  } else {
    body = &body_storage;
    if (!ssl->method->init_message(ssl, cbb.get(), body, SSL3_MT_CERTIFICATE)) {
      return false;
    }
  }

  if (  // The request context is always empty in the handshake.
      !CBB_add_u8(body, 0) ||
      !CBB_add_u24_length_prefixed(body, &certificate_list)) {
    return false;
  }

  if (cred == nullptr) {
    return ssl_add_message_cbb(ssl, cbb.get());
  }

  CBB leaf, extensions;
  if (!CBB_add_u24_length_prefixed(&certificate_list, &leaf)) {
    return false;
  }
  if (cred->type == SSLCredentialType::kRawPublicKey) {
    // Write the CertificateEntry format for a RawPublicKey (RFC 8446, section
    // 4.4.2).
    if (!EVP_marshal_public_key(&leaf, cred->pubkey.get())) {
      return false;
    }
  } else {
    assert(cred->UsesX509());
    CRYPTO_BUFFER *leaf_buf = sk_CRYPTO_BUFFER_value(cred->chain.get(), 0);
    if (!CBB_add_bytes(&leaf, CRYPTO_BUFFER_data(leaf_buf),
                       CRYPTO_BUFFER_len(leaf_buf))) {
      return false;
    }
  }
  if (!CBB_add_u16_length_prefixed(&certificate_list, &extensions)) {
    return false;
  }

  if (hs->scts_requested && cred->signed_cert_timestamp_list != nullptr) {
    CBB contents;
    if (!CBB_add_u16(&extensions, TLSEXT_TYPE_certificate_timestamp) ||
        !CBB_add_u16_length_prefixed(&extensions, &contents) ||
        !CBB_add_bytes(
            &contents,
            CRYPTO_BUFFER_data(cred->signed_cert_timestamp_list.get()),
            CRYPTO_BUFFER_len(cred->signed_cert_timestamp_list.get())) ||
        !CBB_flush(&extensions)) {
      return false;
    }
  }

  if (hs->ocsp_stapling_requested && cred->ocsp_response != nullptr) {
    CBB contents, ocsp_response;
    if (!CBB_add_u16(&extensions, TLSEXT_TYPE_status_request) ||
        !CBB_add_u16_length_prefixed(&extensions, &contents) ||
        !CBB_add_u8(&contents, TLSEXT_STATUSTYPE_ocsp) ||
        !CBB_add_u24_length_prefixed(&contents, &ocsp_response) ||
        !CBB_add_bytes(&ocsp_response,
                       CRYPTO_BUFFER_data(cred->ocsp_response.get()),
                       CRYPTO_BUFFER_len(cred->ocsp_response.get())) ||
        !CBB_flush(&extensions)) {
      return false;
    }
  }

  if (cred->type == SSLCredentialType::kDelegated) {
    CBB child;
    if (!CBB_add_u16(&extensions, TLSEXT_TYPE_delegated_credential) ||
        !CBB_add_u16_length_prefixed(&extensions, &child) ||
        !CBB_add_bytes(&child, CRYPTO_BUFFER_data(cred->dc.get()),
                       CRYPTO_BUFFER_len(cred->dc.get())) ||
        !CBB_flush(&extensions)) {
      return false;
    }
  }

  if (hs->matched_peer_trust_anchor) {
    // Let the peer know we matched a requested trust anchor.
    CBB empty_contents;
    if (!CBB_add_u16(&extensions, TLSEXT_TYPE_trust_anchors) ||        //
        !CBB_add_u16_length_prefixed(&extensions, &empty_contents) ||  //
        !CBB_flush(&extensions)) {
      return false;
    }
  }

  for (size_t i = 1; i < sk_CRYPTO_BUFFER_num(cred->chain.get()); i++) {
    CRYPTO_BUFFER *cert_buf = sk_CRYPTO_BUFFER_value(cred->chain.get(), i);
    CBB child;
    if (!CBB_add_u24_length_prefixed(&certificate_list, &child) ||
        !CBB_add_bytes(&child, CRYPTO_BUFFER_data(cert_buf),
                       CRYPTO_BUFFER_len(cert_buf)) ||
        !CBB_add_u16(&certificate_list, 0 /* no extensions */)) {
      return false;
    }
  }

  if (!hs->cert_compression_negotiated) {
    return ssl_add_message_cbb(ssl, cbb.get());
  }

  Array<uint8_t> msg;
  if (!CBBFinishArray(cbb.get(), &msg)) {
    return false;
  }

  const CertCompressionAlg *alg = nullptr;
  for (const auto &candidate : ssl->ctx->cert_compression_algs) {
    if (candidate.alg_id == hs->cert_compression_alg_id) {
      alg = &candidate;
      break;
    }
  }

  if (alg == nullptr || alg->compress == nullptr) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
    return false;
  }

  CBB compressed;
  body = &body_storage;
  if (!ssl->method->init_message(ssl, cbb.get(), body,
                                 SSL3_MT_COMPRESSED_CERTIFICATE) ||
      !CBB_add_u16(body, hs->cert_compression_alg_id) ||
      msg.size() > (1u << 24) - 1 ||  //
      !CBB_add_u24(body, static_cast<uint32_t>(msg.size())) ||
      !CBB_add_u24_length_prefixed(body, &compressed)) {
    return false;
  }

  if (hs->provided_hints != nullptr &&
      hs->provided_hints->cert_compression_alg_id ==
          hs->cert_compression_alg_id &&
      hs->provided_hints->cert_compression_input == Span(msg) &&
      !hs->provided_hints->cert_compression_output.empty()) {
    if (!CBB_add_bytes(&compressed,
                       hs->provided_hints->cert_compression_output.data(),
                       hs->provided_hints->cert_compression_output.size())) {
      return false;
    }
  } else {
    if (!alg->compress(ssl, &compressed, msg.data(), msg.size())) {
      OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
      return false;
    }
  }
  if (hs->pending_hints != nullptr) {
    hs->pending_hints->cert_compression_alg_id = hs->cert_compression_alg_id;
    if (!hs->pending_hints->cert_compression_input.CopyFrom(msg) ||
        !hs->pending_hints->cert_compression_output.CopyFrom(
            CBBAsSpan(&compressed))) {
      return false;
    }
  }

  if (!ssl_add_message_cbb(ssl, cbb.get())) {
    return false;
  }

  return true;
}

enum ssl_private_key_result_t tls13_add_certificate_verify(SSL_HANDSHAKE *hs) {
  SSLImpl *const ssl = hs->ssl;
  assert(hs->signature_algorithm != 0);
  ScopedCBB cbb;
  CBB body;
  if (!ssl->method->init_message(ssl, cbb.get(), &body,
                                 SSL3_MT_CERTIFICATE_VERIFY) ||
      !CBB_add_u16(&body, hs->signature_algorithm)) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
    return ssl_private_key_failure;
  }

  CBB child;
  const size_t max_sig_len = EVP_PKEY_size(hs->credential->pubkey.get());
  uint8_t *sig;
  size_t sig_len;
  if (!CBB_add_u16_length_prefixed(&body, &child) ||
      !CBB_reserve(&child, &sig, max_sig_len)) {
    ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
    return ssl_private_key_failure;
  }

  Array<uint8_t> msg;
  if (!tls13_get_cert_verify_signature_input(
          hs, &msg,
          ssl->server ? ssl_cert_verify_server : ssl_cert_verify_client)) {
    ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
    return ssl_private_key_failure;
  }

  enum ssl_private_key_result_t sign_result = ssl_private_key_sign(
      hs, sig, &sig_len, max_sig_len, hs->signature_algorithm, msg);
  if (sign_result != ssl_private_key_success) {
    return sign_result;
  }

  if (!CBB_did_write(&child, sig_len) ||  //
      !ssl_add_message_cbb(ssl, cbb.get())) {
    return ssl_private_key_failure;
  }

  return ssl_private_key_success;
}

bool tls13_add_finished(SSL_HANDSHAKE *hs) {
  SSLImpl *const ssl = hs->ssl;
  size_t verify_data_len;
  uint8_t verify_data[EVP_MAX_MD_SIZE];

  if (!tls13_finished_mac(hs, verify_data, &verify_data_len, ssl->server)) {
    ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
    OPENSSL_PUT_ERROR(SSL, SSL_R_DIGEST_CHECK_FAILED);
    return false;
  }

  ScopedCBB cbb;
  CBB body;
  if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_FINISHED) ||
      !CBB_add_bytes(&body, verify_data, verify_data_len) ||
      !ssl_add_message_cbb(ssl, cbb.get())) {
    return false;
  }

  return true;
}

bool tls13_add_key_update(SSLImpl *ssl, int request_type) {
  if (ssl->s3->key_update_pending) {
    return true;
  }

  // We do not support multiple parallel outgoing flights. If there is an
  // outgoing flight pending, queue the KeyUpdate for later.
  if (SSL_is_dtls(ssl) && !ssl->d1->outgoing_messages.empty()) {
    ssl->d1->queued_key_update = request_type == SSL_KEY_UPDATE_REQUESTED
                                     ? QueuedKeyUpdate::kUpdateRequested
                                     : QueuedKeyUpdate::kUpdateNotRequested;
    return true;
  }

  ScopedCBB cbb;
  CBB body_cbb;
  if (!ssl->method->init_message(ssl, cbb.get(), &body_cbb,
                                 SSL3_MT_KEY_UPDATE) ||
      !CBB_add_u8(&body_cbb, request_type) ||
      !ssl_add_message_cbb(ssl, cbb.get())) {
    return false;
  }

  // In DTLS, the actual key update is deferred until KeyUpdate is ACKed.
  if (!SSL_is_dtls(ssl) && !tls13_rotate_traffic_key(ssl, evp_aead_seal)) {
    return false;
  }

  // Suppress KeyUpdate acknowledgments until this change is written to the
  // wire. This prevents us from accumulating write obligations when read and
  // write progress at different rates. See RFC 8446, section 4.6.3.
  ssl->s3->key_update_pending = true;
  ssl->method->finish_flight(ssl);
  return true;
}

static bool tls13_receive_key_update(SSLImpl *ssl, const SSLMessage &msg) {
  CBS body = msg.body;
  uint8_t key_update_request;
  if (!CBS_get_u8(&body, &key_update_request) ||              //
      CBS_len(&body) != 0 ||                                  //
      (key_update_request != SSL_KEY_UPDATE_NOT_REQUESTED &&  //
       key_update_request != SSL_KEY_UPDATE_REQUESTED)) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
    ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
    return false;
  }

  if (!tls13_rotate_traffic_key(ssl, evp_aead_open)) {
    return false;
  }

  // Acknowledge the KeyUpdate
  if (key_update_request == SSL_KEY_UPDATE_REQUESTED &&
      !tls13_add_key_update(ssl, SSL_KEY_UPDATE_NOT_REQUESTED)) {
    return false;
  }

  return true;
}

bool tls13_post_handshake(SSLImpl *ssl, const SSLMessage &msg) {
  if (msg.type == SSL3_MT_NEW_SESSION_TICKET && !ssl->server) {
    return tls13_process_new_session_ticket(ssl, msg);
  }

  if (msg.type == SSL3_MT_KEY_UPDATE) {
    ssl->s3->key_update_count++;
    if (SSL_is_quic(ssl) || ssl->s3->key_update_count > kMaxKeyUpdates) {
      OPENSSL_PUT_ERROR(SSL, SSL_R_TOO_MANY_KEY_UPDATES);
      ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
      return false;
    }

    return tls13_receive_key_update(ssl, msg);
  }

  ssl->s3->key_update_count = 0;

  ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
  OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE);
  return false;
}

BSSL_NAMESPACE_END
