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

#include <openssl/ssl.h>

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

#include <utility>

#include <openssl/bn.h>
#include <openssl/bytestring.h>
#include <openssl/ec.h>
#include <openssl/ec_key.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/mem.h>
#include <openssl/pool.h>
#include <openssl/sha2.h>
#include <openssl/x509.h>

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


BSSL_NAMESPACE_BEGIN

CERT::CERT(const SSL_X509_METHOD *x509_method_arg)
    : legacy_credential(MakeUnique<SSLCredential>(SSLCredentialType::kX509)),
      x509_method(x509_method_arg) {}

CERT::~CERT() { x509_method->cert_free(this); }

UniquePtr<CERT> ssl_cert_dup(CERT *cert) {
  UniquePtr<CERT> ret = MakeUnique<CERT>(cert->x509_method);
  if (!ret) {
    return nullptr;
  }

  // TODO(crbug.com/boringssl/431): This should just be `CopyFrom`.
  for (const auto &cred : cert->credentials) {
    if (!ret->credentials.Push(UpRef(cred))) {
      return nullptr;
    }
  }

  // `legacy_credential` is mutable, so it must be copied. We cannot simply
  // bump the reference count.
  ret->legacy_credential = cert->legacy_credential->Dup();
  if (ret->legacy_credential == nullptr ||
      !ret->available_trust_anchors.CopyFrom(cert->available_trust_anchors)) {
    return nullptr;
  }

  ret->cert_cb = cert->cert_cb;
  ret->cert_cb_arg = cert->cert_cb_arg;

  ret->x509_method->cert_dup(ret.get(), cert);

  ret->sid_ctx = cert->sid_ctx;
  return ret;
}

static void ssl_cert_set_cert_cb(CERT *cert, int (*cb)(SSL *ssl, void *arg),
                                 void *arg) {
  cert->cert_cb = cb;
  cert->cert_cb_arg = arg;
}

static int cert_set_chain_and_key(
    CERT *cert, CRYPTO_BUFFER *const *certs, size_t num_certs,
    EVP_PKEY *privkey, const SSL_PRIVATE_KEY_METHOD *privkey_method) {
  if (num_certs == 0 ||  //
      (privkey == nullptr && privkey_method == nullptr)) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER);
    return 0;
  }

  if (privkey != nullptr && privkey_method != nullptr) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_CANNOT_HAVE_BOTH_PRIVKEY_AND_METHOD);
    return 0;
  }

  cert->legacy_credential->ClearCertAndKey();
  if (!SSL_CREDENTIAL_set1_cert_chain(cert->legacy_credential.get(), certs,
                                      num_certs)) {
    return 0;
  }

  cert->x509_method->cert_flush_cached_leaf(cert);
  cert->x509_method->cert_flush_cached_chain(cert);

  return privkey != nullptr
             ? SSL_CREDENTIAL_set1_private_key(cert->legacy_credential.get(),
                                               privkey)
             : SSL_CREDENTIAL_set_private_key_method(
                   cert->legacy_credential.get(), privkey_method);
}

bool ssl_set_cert(CERT *cert, UniquePtr<CRYPTO_BUFFER> buffer) {
  // Don't fail for a cert/key mismatch, just free the current private key.
  // (When switching to a different keypair, the caller should switch the
  // certificate, then the key.)
  if (!cert->legacy_credential->SetLeafCert(std::move(buffer),
                                            /*discard_key_on_mismatch=*/true)) {
    return false;
  }

  cert->x509_method->cert_flush_cached_leaf(cert);
  return true;
}

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) {
  out_chain->reset();
  out_pubkey->reset();

  CBS certificate_list;
  if (!CBS_get_u24_length_prefixed(cbs, &certificate_list)) {
    *out_alert = SSL_AD_DECODE_ERROR;
    OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
    return false;
  }

  if (CBS_len(&certificate_list) == 0) {
    return true;
  }

  UniquePtr<STACK_OF(CRYPTO_BUFFER)> chain(sk_CRYPTO_BUFFER_new_null());
  if (!chain) {
    *out_alert = SSL_AD_INTERNAL_ERROR;
    return false;
  }

  UniquePtr<EVP_PKEY> pubkey;
  while (CBS_len(&certificate_list) > 0) {
    CBS certificate;
    if (!CBS_get_u24_length_prefixed(&certificate_list, &certificate) ||
        CBS_len(&certificate) == 0) {
      *out_alert = SSL_AD_DECODE_ERROR;
      OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_LENGTH_MISMATCH);
      return false;
    }

    if (sk_CRYPTO_BUFFER_num(chain.get()) == 0) {
      pubkey = ssl_cert_parse_pubkey(&certificate);
      if (!pubkey) {
        *out_alert = SSL_AD_DECODE_ERROR;
        return false;
      }

      // Retain the hash of the leaf certificate if requested.
      if (out_leaf_sha256 != nullptr) {
        SHA256(CBS_data(&certificate), CBS_len(&certificate), out_leaf_sha256);
      }
    }

    UniquePtr<CRYPTO_BUFFER> buf(
        CRYPTO_BUFFER_new_from_CBS(&certificate, pool));
    if (!buf ||  //
        !PushToStack(chain.get(), std::move(buf))) {
      *out_alert = SSL_AD_INTERNAL_ERROR;
      return false;
    }
  }

  *out_chain = std::move(chain);
  *out_pubkey = std::move(pubkey);
  return true;
}

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) {
  out_raw_public_key->reset();
  out_pubkey->reset();
  CBS spki;
  if (!CBS_get_u24_length_prefixed(cbs, &spki) ||  //
      CBS_len(cbs) != 0) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_RAW_PUBLIC_KEY);
    *out_alert = SSL_AD_DECODE_ERROR;
    return false;
  }
  // The TLS 1.2 Certificate format for Raw Public Keys in RFC 7250 does not
  // permit the peer to decline to send a Certificate, which is possible to do
  // with X.509 Certificates, but we allow a client to do this by sending an
  // empty RPK SPKI.
  if (CBS_len(&spki) == 0) {
    return true;
  }
  *out_raw_public_key = ssl_parse_peer_subject_public_key_info(spki);
  if (*out_raw_public_key == nullptr) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_RAW_PUBLIC_KEY);
    *out_alert = SSL_AD_DECODE_ERROR;
    return false;
  }
  // Retain the hash of the leaf certificate if requested.
  if (out_rpk_sha256 != nullptr) {
    SHA256(CBS_data(&spki), CBS_len(&spki), out_rpk_sha256);
  }
  *out_pubkey = UpRef(*out_raw_public_key);
  return true;
}

// ssl_cert_skip_to_spki parses a DER-encoded, X.509 certificate from `in` and
// positions `*out_tbs_cert` to cover the TBSCertificate, starting at the
// subjectPublicKeyInfo.
static bool ssl_cert_skip_to_spki(const CBS *in, CBS *out_tbs_cert) {
  /* From RFC 5280, section 4.1
   *    Certificate  ::=  SEQUENCE  {
   *      tbsCertificate       TBSCertificate,
   *      signatureAlgorithm   AlgorithmIdentifier,
   *      signatureValue       BIT STRING  }

   * TBSCertificate  ::=  SEQUENCE  {
   *      version         [0]  EXPLICIT Version DEFAULT v1,
   *      serialNumber         CertificateSerialNumber,
   *      signature            AlgorithmIdentifier,
   *      issuer               Name,
   *      validity             Validity,
   *      subject              Name,
   *      subjectPublicKeyInfo SubjectPublicKeyInfo,
   *      ... } */
  CBS buf = *in;

  CBS toplevel;
  if (!CBS_get_asn1(&buf, &toplevel, CBS_ASN1_SEQUENCE) ||          //
      CBS_len(&buf) != 0 ||                                         //
      !CBS_get_asn1(&toplevel, out_tbs_cert, CBS_ASN1_SEQUENCE) ||  //
      // version
      !CBS_get_optional_asn1(
          out_tbs_cert, nullptr, nullptr,
          CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0) ||  //

      // serialNumber
      !CBS_get_asn1(out_tbs_cert, nullptr, CBS_ASN1_INTEGER) ||
      // signature algorithm
      !CBS_get_asn1(out_tbs_cert, nullptr, CBS_ASN1_SEQUENCE) ||
      // issuer
      !CBS_get_asn1(out_tbs_cert, nullptr, CBS_ASN1_SEQUENCE) ||
      // validity
      !CBS_get_asn1(out_tbs_cert, nullptr, CBS_ASN1_SEQUENCE) ||
      // subject
      !CBS_get_asn1(out_tbs_cert, nullptr, CBS_ASN1_SEQUENCE)) {
    return false;
  }

  return true;
}

bool ssl_cert_extract_issuer(const CBS *in, CBS *out_dn) {
  CBS buf = *in;

  CBS toplevel;
  CBS cert;
  if (!CBS_get_asn1(&buf, &toplevel, CBS_ASN1_SEQUENCE) ||   //
      CBS_len(&buf) != 0 ||                                  //
      !CBS_get_asn1(&toplevel, &cert, CBS_ASN1_SEQUENCE) ||  //
      // version
      !CBS_get_optional_asn1(
          &cert, nullptr, nullptr,
          CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0) ||  //
      // serialNumber
      !CBS_get_asn1(&cert, nullptr, CBS_ASN1_INTEGER) ||  //
      // signature algorithm
      !CBS_get_asn1(&cert, nullptr, CBS_ASN1_SEQUENCE) ||  //
      // issuer
      !CBS_get_asn1_element(&cert, out_dn, CBS_ASN1_SEQUENCE)) {
    return false;
  }
  return true;
}

bool ssl_cert_matches_issuer(const CBS *in, const CBS *dn) {
  CBS issuer;

  if (!ssl_cert_extract_issuer(in, &issuer)) {
    return false;
  }
  return CBS_mem_equal(&issuer, CBS_data(dn), CBS_len(dn));
}

UniquePtr<EVP_PKEY> ssl_cert_parse_pubkey(const CBS *in) {
  CBS buf = *in, tbs_cert, spki;
  if (!ssl_cert_skip_to_spki(&buf, &tbs_cert) ||
      !CBS_get_asn1_element(&tbs_cert, &spki, CBS_ASN1_SEQUENCE)) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_CANNOT_PARSE_LEAF_CERT);
    return nullptr;
  }

  return ssl_parse_peer_subject_public_key_info(spki);
}

bool ssl_compare_public_and_private_key(const EVP_PKEY *pubkey,
                                        const EVP_PKEY *privkey) {
  if (EVP_PKEY_is_opaque(privkey)) {
    // We cannot check an opaque private key and have to trust that it
    // matches.
    return true;
  }

  if (EVP_PKEY_eq(pubkey, privkey) != 1) {
    if (EVP_PKEY_id(pubkey) != EVP_PKEY_id(privkey)) {
      OPENSSL_PUT_ERROR(X509, X509_R_KEY_TYPE_MISMATCH);
    } else {
      OPENSSL_PUT_ERROR(X509, X509_R_KEY_VALUES_MISMATCH);
    }
    return false;
  }

  return true;
}

bool ssl_cert_check_key_usage(const CBS *in, enum ssl_key_usage_t bit) {
  CBS buf = *in;

  CBS tbs_cert, outer_extensions;
  int has_extensions;
  if (!ssl_cert_skip_to_spki(&buf, &tbs_cert) ||
      // subjectPublicKeyInfo
      !CBS_get_asn1(&tbs_cert, nullptr, CBS_ASN1_SEQUENCE) ||
      // issuerUniqueID
      !CBS_get_optional_asn1(&tbs_cert, nullptr, nullptr,
                             CBS_ASN1_CONTEXT_SPECIFIC | 1) ||
      // subjectUniqueID
      !CBS_get_optional_asn1(&tbs_cert, nullptr, nullptr,
                             CBS_ASN1_CONTEXT_SPECIFIC | 2) ||
      !CBS_get_optional_asn1(
          &tbs_cert, &outer_extensions, &has_extensions,
          CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 3)) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_CANNOT_PARSE_LEAF_CERT);
    return false;
  }

  if (!has_extensions) {
    return true;
  }

  CBS extensions;
  if (!CBS_get_asn1(&outer_extensions, &extensions, CBS_ASN1_SEQUENCE)) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_CANNOT_PARSE_LEAF_CERT);
    return false;
  }

  while (CBS_len(&extensions) > 0) {
    CBS extension, oid, contents;
    if (!CBS_get_asn1(&extensions, &extension, CBS_ASN1_SEQUENCE) ||
        !CBS_get_asn1(&extension, &oid, CBS_ASN1_OBJECT) ||
        (CBS_peek_asn1_tag(&extension, CBS_ASN1_BOOLEAN) &&
         !CBS_get_asn1(&extension, nullptr, CBS_ASN1_BOOLEAN)) ||
        !CBS_get_asn1(&extension, &contents, CBS_ASN1_OCTETSTRING) ||
        CBS_len(&extension) != 0) {
      OPENSSL_PUT_ERROR(SSL, SSL_R_CANNOT_PARSE_LEAF_CERT);
      return false;
    }

    static const uint8_t kKeyUsageOID[3] = {0x55, 0x1d, 0x0f};
    if (CBS_len(&oid) != sizeof(kKeyUsageOID) ||
        OPENSSL_memcmp(CBS_data(&oid), kKeyUsageOID, sizeof(kKeyUsageOID)) !=
            0) {
      continue;
    }

    CBS bit_string;
    if (!CBS_get_asn1(&contents, &bit_string, CBS_ASN1_BITSTRING) ||
        CBS_len(&contents) != 0) {
      OPENSSL_PUT_ERROR(SSL, SSL_R_CANNOT_PARSE_LEAF_CERT);
      return false;
    }

    // This is the KeyUsage extension. See
    // https://tools.ietf.org/html/rfc5280#section-4.2.1.3
    if (!CBS_is_valid_asn1_bitstring(&bit_string)) {
      OPENSSL_PUT_ERROR(SSL, SSL_R_CANNOT_PARSE_LEAF_CERT);
      return false;
    }

    if (!CBS_asn1_bitstring_has_bit(&bit_string, bit)) {
      OPENSSL_PUT_ERROR(SSL, SSL_R_KEY_USAGE_BIT_INCORRECT);
      return false;
    }

    return true;
  }

  // No KeyUsage extension found.
  return true;
}

UniquePtr<STACK_OF(CRYPTO_BUFFER)> SSL_parse_CA_list(SSLImpl *ssl,
                                                     uint8_t *out_alert,
                                                     CBS *cbs) {
  CRYPTO_BUFFER_POOL *const pool = ssl->ctx->pool.get();

  UniquePtr<STACK_OF(CRYPTO_BUFFER)> ret(sk_CRYPTO_BUFFER_new_null());
  if (!ret) {
    *out_alert = SSL_AD_INTERNAL_ERROR;
    return nullptr;
  }

  CBS child;
  if (!CBS_get_u16_length_prefixed(cbs, &child)) {
    *out_alert = SSL_AD_DECODE_ERROR;
    OPENSSL_PUT_ERROR(SSL, SSL_R_LENGTH_MISMATCH);
    return nullptr;
  }

  while (CBS_len(&child) > 0) {
    CBS distinguished_name;
    if (!CBS_get_u16_length_prefixed(&child, &distinguished_name)) {
      *out_alert = SSL_AD_DECODE_ERROR;
      OPENSSL_PUT_ERROR(SSL, SSL_R_CA_DN_TOO_LONG);
      return nullptr;
    }

    UniquePtr<CRYPTO_BUFFER> buffer(
        CRYPTO_BUFFER_new_from_CBS(&distinguished_name, pool));
    if (!buffer ||  //
        !PushToStack(ret.get(), std::move(buffer))) {
      *out_alert = SSL_AD_INTERNAL_ERROR;
      return nullptr;
    }
  }

  if (!ssl->ctx->x509_method->check_CA_list(ret.get())) {
    *out_alert = SSL_AD_DECODE_ERROR;
    OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
    return nullptr;
  }

  return ret;
}

static bool CA_names_non_empty(const STACK_OF(CRYPTO_BUFFER) *config_names,
                               const STACK_OF(CRYPTO_BUFFER) *ctx_names) {
  if (config_names != nullptr) {
    return sk_CRYPTO_BUFFER_num(config_names) > 0;
  }
  if (ctx_names != nullptr) {
    return sk_CRYPTO_BUFFER_num(ctx_names) > 0;
  }
  return false;
}


static bool marshal_CA_names(const STACK_OF(CRYPTO_BUFFER) *config_names,
                             const STACK_OF(CRYPTO_BUFFER) *ctx_names,
                             CBB *cbb) {
  const STACK_OF(CRYPTO_BUFFER) *names =
      config_names == nullptr ? ctx_names : config_names;
  CBB child, name_cbb;

  if (!CBB_add_u16_length_prefixed(cbb, &child)) {
    return false;
  }

  if (names == nullptr) {
    return CBB_flush(cbb);
  }

  for (const CRYPTO_BUFFER *name : names) {
    if (!CBB_add_u16_length_prefixed(&child, &name_cbb) ||
        !CBB_add_bytes(&name_cbb, CRYPTO_BUFFER_data(name),
                       CRYPTO_BUFFER_len(name))) {
      return false;
    }
  }

  return CBB_flush(cbb);
}

bool ssl_has_client_CAs(const SSL_CONFIG *cfg) {
  return CA_names_non_empty(cfg->client_CA.get(),
                            cfg->ssl->ctx->client_CA.get());
}

bool ssl_has_CA_names(const SSL_CONFIG *cfg) {
  return CA_names_non_empty(cfg->CA_names.get(), cfg->ssl->ctx->CA_names.get());
}

bool ssl_add_client_CA_list(const SSL_HANDSHAKE *hs, CBB *cbb) {
  return marshal_CA_names(hs->config->client_CA.get(),
                          hs->ssl->ctx->client_CA.get(), cbb);
}

bool ssl_add_CA_names(const SSL_HANDSHAKE *hs, CBB *cbb) {
  return marshal_CA_names(hs->config->CA_names.get(),
                          hs->ssl->ctx->CA_names.get(), cbb);
}

bool ssl_check_leaf_certificate(SSL_HANDSHAKE *hs, EVP_PKEY *pkey,
                                const CRYPTO_BUFFER *leaf) {
  assert(ssl_protocol_version(hs->ssl) < TLS1_3_VERSION);

  // Check the certificate's type matches the cipher. This does not check key
  // usage restrictions, which are handled separately.
  //
  // TODO(davidben): Put the key type and key usage checks in one place.
  if (!(hs->new_cipher->algorithm_auth &
        ssl_cipher_auth_mask_for_key(pkey, /*sign_ok=*/true))) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CERTIFICATE_TYPE);
    return false;
  }

  if (EVP_PKEY_id(pkey) == EVP_PKEY_EC) {
    // Check the key's group and point format are acceptable.
    uint16_t group_id;
    if (!ssl_nid_to_group_id(&group_id, EVP_PKEY_get_ec_curve_nid(pkey)) ||
        !tls1_check_group_id(hs, group_id) ||
        EVP_PKEY_get_ec_point_conv_form(pkey) !=
            POINT_CONVERSION_UNCOMPRESSED) {
      OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ECC_CERT);
      return false;
    }
  }

  return true;
}

BSSL_NAMESPACE_END

using namespace bssl;

int SSL_set_chain_and_key(SSL *ssl, CRYPTO_BUFFER *const *certs,
                          size_t num_certs, EVP_PKEY *privkey,
                          const SSL_PRIVATE_KEY_METHOD *privkey_method) {
  auto *ssl_impl = FromOpaque(ssl);
  if (!ssl_impl->config) {
    return 0;
  }
  return cert_set_chain_and_key(ssl_impl->config->cert.get(), certs, num_certs,
                                privkey, privkey_method);
}

int SSL_CTX_set_chain_and_key(SSL_CTX *ctx, CRYPTO_BUFFER *const *certs,
                              size_t num_certs, EVP_PKEY *privkey,
                              const SSL_PRIVATE_KEY_METHOD *privkey_method) {
  return cert_set_chain_and_key(FromOpaque(ctx)->cert.get(), certs, num_certs,
                                privkey, privkey_method);
}

void SSL_certs_clear(SSL *ssl) {
  auto *ssl_impl = FromOpaque(ssl);
  if (!ssl_impl->config) {
    return;
  }

  CERT *cert = ssl_impl->config->cert.get();
  cert->x509_method->cert_clear(cert);
  cert->credentials.clear();
  cert->legacy_credential->ClearCertAndKey();
}

const STACK_OF(CRYPTO_BUFFER) *SSL_CTX_get0_chain(const SSL_CTX *ctx) {
  return FromOpaque(ctx)->cert->legacy_credential->chain.get();
}

const STACK_OF(CRYPTO_BUFFER) *SSL_get0_chain(const SSL *ssl) {
  const auto *ssl_impl = FromOpaque(ssl);
  if (!ssl_impl->config) {
    return nullptr;
  }
  return ssl_impl->config->cert->legacy_credential->chain.get();
}

int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, size_t der_len,
                                 const uint8_t *der) {
  UniquePtr<CRYPTO_BUFFER> buffer(CRYPTO_BUFFER_new(der, der_len, nullptr));
  if (!buffer) {
    return 0;
  }

  return ssl_set_cert(FromOpaque(ctx)->cert.get(), std::move(buffer));
}

int SSL_use_certificate_ASN1(SSL *ssl, const uint8_t *der, size_t der_len) {
  auto *ssl_impl = FromOpaque(ssl);
  UniquePtr<CRYPTO_BUFFER> buffer(CRYPTO_BUFFER_new(der, der_len, nullptr));
  if (!buffer || !ssl_impl->config) {
    return 0;
  }

  return ssl_set_cert(ssl_impl->config->cert.get(), std::move(buffer));
}

void SSL_CTX_set_cert_cb(SSL_CTX *ctx, int (*cb)(SSL *ssl, void *arg),
                         void *arg) {
  ssl_cert_set_cert_cb(FromOpaque(ctx)->cert.get(), cb, arg);
}

void SSL_set_cert_cb(SSL *ssl, int (*cb)(SSL *ssl, void *arg), void *arg) {
  auto *ssl_impl = FromOpaque(ssl);
  if (!ssl_impl->config) {
    return;
  }
  ssl_cert_set_cert_cb(ssl_impl->config->cert.get(), cb, arg);
}

const STACK_OF(CRYPTO_BUFFER) *SSL_get0_peer_certificates(const SSL *ssl) {
  SSL_SESSION *session = SSL_get_session(ssl);
  if (session == nullptr) {
    return nullptr;
  }

  return session->certs.get();
}

const STACK_OF(CRYPTO_BUFFER) *SSL_get0_server_requested_CAs(const SSL *ssl) {
  const auto *ssl_impl = FromOpaque(ssl);
  if (ssl_impl->s3->hs == nullptr) {
    return nullptr;
  }
  return ssl_impl->s3->hs->ca_names.get();
}

int SSL_CTX_set_signed_cert_timestamp_list(SSL_CTX *ctx, const uint8_t *list,
                                           size_t list_len) {
  UniquePtr<CRYPTO_BUFFER> buf(CRYPTO_BUFFER_new(list, list_len, nullptr));
  return buf != nullptr &&
         SSL_CREDENTIAL_set1_signed_cert_timestamp_list(
             FromOpaque(ctx)->cert->legacy_credential.get(), buf.get());
}

int SSL_set_signed_cert_timestamp_list(SSL *ssl, const uint8_t *list,
                                       size_t list_len) {
  auto *ssl_impl = FromOpaque(ssl);
  if (!ssl_impl->config) {
    return 0;
  }
  UniquePtr<CRYPTO_BUFFER> buf(CRYPTO_BUFFER_new(list, list_len, nullptr));
  return buf != nullptr &&
         SSL_CREDENTIAL_set1_signed_cert_timestamp_list(
             ssl_impl->config->cert->legacy_credential.get(), buf.get());
}

int SSL_CTX_set_ocsp_response(SSL_CTX *ctx, const uint8_t *response,
                              size_t response_len) {
  UniquePtr<CRYPTO_BUFFER> buf(
      CRYPTO_BUFFER_new(response, response_len, nullptr));
  return buf != nullptr &&
         SSL_CREDENTIAL_set1_ocsp_response(
             FromOpaque(ctx)->cert->legacy_credential.get(), buf.get());
}

int SSL_set_ocsp_response(SSL *ssl, const uint8_t *response,
                          size_t response_len) {
  auto *ssl_impl = FromOpaque(ssl);
  if (!ssl_impl->config) {
    return 0;
  }
  UniquePtr<CRYPTO_BUFFER> buf(
      CRYPTO_BUFFER_new(response, response_len, nullptr));
  return buf != nullptr &&
         SSL_CREDENTIAL_set1_ocsp_response(
             ssl_impl->config->cert->legacy_credential.get(), buf.get());
}

void SSL_CTX_set0_client_CAs(SSL_CTX *ctx, STACK_OF(CRYPTO_BUFFER) *name_list) {
  auto *ctx_impl = FromOpaque(ctx);
  ctx_impl->x509_method->ssl_ctx_flush_cached_client_CA(ctx_impl);
  ctx_impl->client_CA.reset(name_list);
}

void SSL_set0_client_CAs(SSL *ssl, STACK_OF(CRYPTO_BUFFER) *name_list) {
  auto *ssl_impl = FromOpaque(ssl);
  if (!ssl_impl->config) {
    // `SSL_set0_client_CAs` is expected to take ownership of `name_list`.
    sk_CRYPTO_BUFFER_pop_free(name_list, CRYPTO_BUFFER_free);
    return;
  }
  ssl_impl->ctx->x509_method->ssl_flush_cached_client_CA(
      ssl_impl->config.get());
  ssl_impl->config->client_CA.reset(name_list);
}

void SSL_set0_CA_names(SSL *ssl, STACK_OF(CRYPTO_BUFFER) *name_list) {
  auto *ssl_impl = FromOpaque(ssl);
  if (!ssl_impl->config) {
    return;
  }
  ssl_impl->config->CA_names.reset(name_list);
}
