/* Copyright (c) 2016, Google Inc.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */

#include <openssl/ssl.h>

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

#include <utility>

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

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


namespace bssl {

// 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,
};

// This value was selected by truncating the SHA-256 hash of "Draft TLS 1.3
// Downgrade" to 8 bytes:
//
//   echo -n 'Draft TLS 1.3 Downgrade' | sha256sum | head -c 16
const uint8_t kDraftDowngradeRandom[8] = {0x95, 0xb9, 0x9f, 0x87,
                                          0x22, 0xfe, 0x9b, 0x64};


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)) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
    return false;
  }

  for (size_t i = 0; i < 64; i++) {
    if (!CBB_add_u8(cbb.get(), 0x20)) {
      OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
      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 {
    OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
    return false;
  }

  // Note |context| includes the NUL byte separator.
  if (!CBB_add_bytes(cbb.get(),
                     reinterpret_cast<const uint8_t *>(context.data()),
                     context.size())) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
    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)) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
    return false;
  }

  return true;
}

int tls13_process_certificate(SSL_HANDSHAKE *hs, const SSLMessage &msg,
                              int allow_anonymous) {
  SSL *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 0;
    }

    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 0;
    }

    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 0;
    }

    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 0;
    }
    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 0;
    }

    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 0;
  }

  UniquePtr<STACK_OF(CRYPTO_BUFFER)> certs(sk_CRYPTO_BUFFER_new_null());
  if (!certs) {
    ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
    OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
    return 0;
  }

  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, 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, SSL_R_CERT_LENGTH_MISMATCH);
      return 0;
    }

    if (sk_CRYPTO_BUFFER_num(certs.get()) == 0) {
      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 0;
      }
      // TLS 1.3 always uses certificate keys for signing thus the correct
      // keyUsage is enforced.
      if (!ssl_cert_check_digital_signature_key_usage(&certificate)) {
        ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
        return 0;
      }

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

    UniquePtr<CRYPTO_BUFFER> buf(
        CRYPTO_BUFFER_new_from_CBS(&certificate, ssl->ctx->pool));
    if (!buf ||
        !PushToStack(certs.get(), std::move(buf))) {
      ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
      OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
      return 0;
    }

    // Parse out the extensions.
    bool have_status_request = false, have_sct = false;
    CBS status_request, sct;
    const SSL_EXTENSION_TYPE ext_types[] = {
        {TLSEXT_TYPE_status_request, &have_status_request, &status_request},
        {TLSEXT_TYPE_certificate_timestamp, &have_sct, &sct},
    };

    uint8_t alert = SSL_AD_DECODE_ERROR;
    if (!ssl_parse_extensions(&extensions, &alert, ext_types,
                              OPENSSL_ARRAY_SIZE(ext_types),
                              0 /* reject unknown */)) {
      ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
      return 0;
    }

    // All Certificate extensions are parsed, but only the leaf extensions are
    // stored.
    if (have_status_request) {
      if (ssl->server || !hs->config->ocsp_stapling_enabled) {
        OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION);
        ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_EXTENSION);
        return 0;
      }

      uint8_t status_type;
      CBS ocsp_response;
      if (!CBS_get_u8(&status_request, &status_type) ||
          status_type != TLSEXT_STATUSTYPE_ocsp ||
          !CBS_get_u24_length_prefixed(&status_request, &ocsp_response) ||
          CBS_len(&ocsp_response) == 0 ||
          CBS_len(&status_request) != 0) {
        ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
        return 0;
      }

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

    if (have_sct) {
      if (ssl->server || !hs->config->signed_cert_timestamps_enabled) {
        OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION);
        ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_EXTENSION);
        return 0;
      }

      if (!ssl_is_sct_list_valid(&sct)) {
        OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_PARSING_EXTENSION);
        ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
        return 0;
      }

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

  // Store a null certificate list rather than an empty one if the peer didn't
  // send certificates.
  if (sk_CRYPTO_BUFFER_num(certs.get()) == 0) {
    certs.reset();
  }

  hs->peer_pubkey = std::move(pkey);
  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 0;
  }

  if (sk_CRYPTO_BUFFER_num(hs->new_session->certs.get()) == 0) {
    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 0;
    }

    // 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 1;
  }

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

int tls13_process_certificate_verify(SSL_HANDSHAKE *hs, const SSLMessage &msg) {
  SSL *const ssl = hs->ssl;
  if (hs->peer_pubkey == NULL) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
    return 0;
  }

  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 0;
  }

  uint8_t alert = SSL_AD_DECODE_ERROR;
  if (!tls12_check_peer_sigalg(ssl, &alert, signature_algorithm)) {
    ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
    return 0;
  }
  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 0;
  }

  bool sig_ok = ssl_public_key_verify(ssl, signature, signature_algorithm,
                                      hs->peer_pubkey.get(), input);
#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
  sig_ok = true;
  ERR_clear_error();
#endif
  if (!sig_ok) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SIGNATURE);
    ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR);
    return 0;
  }

  return 1;
}

int tls13_process_finished(SSL_HANDSHAKE *hs, const SSLMessage &msg,
                           int use_saved_value) {
  SSL *const ssl = hs->ssl;
  uint8_t verify_data_buf[EVP_MAX_MD_SIZE];
  const uint8_t *verify_data;
  size_t verify_data_len;
  if (use_saved_value) {
    assert(ssl->server);
    verify_data = hs->expected_client_finished;
    verify_data_len = hs->hash_len;
  } else {
    if (!tls13_finished_mac(hs, verify_data_buf, &verify_data_len,
                            !ssl->server)) {
      return 0;
    }
    verify_data = verify_data_buf;
  }

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

  return 1;
}

int tls13_add_certificate(SSL_HANDSHAKE *hs) {
  SSL *const ssl = hs->ssl;
  CERT *const cert = hs->config->cert.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)) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
    return 0;
  }

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

  CRYPTO_BUFFER *leaf_buf = sk_CRYPTO_BUFFER_value(cert->chain.get(), 0);
  CBB leaf, extensions;
  if (!CBB_add_u24_length_prefixed(&certificate_list, &leaf) ||
      !CBB_add_bytes(&leaf, CRYPTO_BUFFER_data(leaf_buf),
                     CRYPTO_BUFFER_len(leaf_buf)) ||
      !CBB_add_u16_length_prefixed(&certificate_list, &extensions)) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
    return 0;
  }

  if (hs->scts_requested && cert->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(cert->signed_cert_timestamp_list.get()),
            CRYPTO_BUFFER_len(cert->signed_cert_timestamp_list.get())) ||
        !CBB_flush(&extensions)) {
      OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
      return 0;
    }
  }

  if (hs->ocsp_stapling_requested && cert->ocsp_response != NULL) {
    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(cert->ocsp_response.get()),
                       CRYPTO_BUFFER_len(cert->ocsp_response.get())) ||
        !CBB_flush(&extensions)) {
      OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
      return 0;
    }
  }

  for (size_t i = 1; i < sk_CRYPTO_BUFFER_num(cert->chain.get()); i++) {
    CRYPTO_BUFFER *cert_buf = sk_CRYPTO_BUFFER_value(cert->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 */)) {
      OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
      return 0;
    }
  }

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

  Array<uint8_t> msg;
  if (!CBBFinishArray(cbb.get(), &msg)) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
    return 0;
  }

  const CertCompressionAlg *alg = nullptr;
  for (CertCompressionAlg *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 0;
  }

  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) ||
      !CBB_add_u24(body, msg.size()) ||
      !CBB_add_u24_length_prefixed(body, &compressed) ||
      !alg->compress(ssl, &compressed, msg.data(), msg.size()) ||
      !ssl_add_message_cbb(ssl, cbb.get())) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
    return 0;
  }

  return 1;
}

enum ssl_private_key_result_t tls13_add_certificate_verify(SSL_HANDSHAKE *hs) {
  SSL *const ssl = hs->ssl;
  uint16_t signature_algorithm;
  if (!tls1_choose_signature_algorithm(hs, &signature_algorithm)) {
    return ssl_private_key_failure;
  }

  ScopedCBB cbb;
  CBB body;
  if (!ssl->method->init_message(ssl, cbb.get(), &body,
                                 SSL3_MT_CERTIFICATE_VERIFY) ||
      !CBB_add_u16(&body, signature_algorithm)) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
    return ssl_private_key_failure;
  }

  // Sign the digest.
  CBB child;
  const size_t max_sig_len = EVP_PKEY_size(hs->local_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, 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;
}

int tls13_add_finished(SSL_HANDSHAKE *hs) {
  SSL *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 0;
  }

  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 0;
  }

  return 1;
}

static int tls13_receive_key_update(SSL *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 0;
  }

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

  // Acknowledge the KeyUpdate
  if (key_update_request == SSL_KEY_UPDATE_REQUESTED &&
      !ssl->s3->key_update_pending) {
    ScopedCBB cbb;
    CBB body_cbb;
    if (!ssl->method->init_message(ssl, cbb.get(), &body_cbb,
                                   SSL3_MT_KEY_UPDATE) ||
        !CBB_add_u8(&body_cbb, SSL_KEY_UPDATE_NOT_REQUESTED) ||
        !ssl_add_message_cbb(ssl, cbb.get()) ||
        !tls13_rotate_traffic_key(ssl, evp_aead_seal)) {
      return 0;
    }

    // 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 draft-ietf-tls-tls13-18, section
    // 4.5.3.
    ssl->s3->key_update_pending = true;
  }

  return 1;
}

int tls13_post_handshake(SSL *ssl, const SSLMessage &msg) {
  if (msg.type == SSL3_MT_KEY_UPDATE) {
    ssl->s3->key_update_count++;
    if (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 0;
    }

    return tls13_receive_key_update(ssl, msg);
  }

  ssl->s3->key_update_count = 0;

  if (msg.type == SSL3_MT_NEW_SESSION_TICKET && !ssl->server) {
    return tls13_process_new_session_ticket(ssl, msg);
  }

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

}  // namespace bssl
