// 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.

#include <openssl/ssl.h>

#include <assert.h>

#include <openssl/asn1.h>
#include <openssl/bytestring.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/stack.h>
#include <openssl/x509.h>

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


BSSL_NAMESPACE_BEGIN

// check_ssl_x509_method asserts that `ssl` has the X509-based method
// installed. Calling an X509-based method on an `ssl` with a different method
// will likely misbehave and possibly crash or leak memory.
static void check_ssl_x509_method(const SSL *ssl) {
  assert(ssl == nullptr || ssl->ctx->x509_method == &ssl_crypto_x509_method);
}

// check_ssl_ctx_x509_method acts like `check_ssl_x509_method`, but for an
// `SSL_CTX`.
static void check_ssl_ctx_x509_method(const SSLContext *ctx) {
  assert(ctx == nullptr || ctx->x509_method == &ssl_crypto_x509_method);
}

// x509_to_buffer returns a `CRYPTO_BUFFER` that contains the serialised
// contents of `x509`.
static UniquePtr<CRYPTO_BUFFER> x509_to_buffer(X509 *x509) {
  uint8_t *buf = nullptr;
  int cert_len = i2d_X509(x509, &buf);
  if (cert_len <= 0) {
    return nullptr;
  }

  UniquePtr<CRYPTO_BUFFER> buffer(CRYPTO_BUFFER_new(buf, cert_len, nullptr));
  OPENSSL_free(buf);

  return buffer;
}

static void ssl_crypto_x509_cert_flush_cached_leaf(CERT *cert) {
  X509_free(cert->x509_leaf);
  cert->x509_leaf = nullptr;
}

static void ssl_crypto_x509_cert_flush_cached_chain(CERT *cert) {
  sk_X509_pop_free(cert->x509_chain, X509_free);
  cert->x509_chain = nullptr;
}

// ssl_cert_set1_chain sets elements 1.. of `cert->chain` to the serialised
// forms of elements of `chain`. It returns one on success or zero on error, in
// which case no change to `cert->chain` is made. It preserves the existing
// leaf from `cert->chain`, if any.
static bool ssl_cert_set1_chain(CERT *cert, STACK_OF(X509) *chain) {
  cert->legacy_credential->ClearIntermediateCerts();
  for (X509 *x509 : chain) {
    UniquePtr<CRYPTO_BUFFER> buffer = x509_to_buffer(x509);
    if (!buffer ||
        !cert->legacy_credential->AppendIntermediateCert(std::move(buffer))) {
      return false;
    }
  }

  ssl_crypto_x509_cert_flush_cached_chain(cert);
  return true;
}

static bool ssl_crypto_x509_check_client_CA_list(
    STACK_OF(CRYPTO_BUFFER) *names) {
  for (const CRYPTO_BUFFER *buffer : names) {
    const uint8_t *inp = CRYPTO_BUFFER_data(buffer);
    UniquePtr<X509_NAME> name(
        d2i_X509_NAME(nullptr, &inp, CRYPTO_BUFFER_len(buffer)));
    if (name == nullptr ||
        inp != CRYPTO_BUFFER_data(buffer) + CRYPTO_BUFFER_len(buffer)) {
      return false;
    }
  }

  return true;
}

static void ssl_crypto_x509_cert_clear(CERT *cert) {
  ssl_crypto_x509_cert_flush_cached_leaf(cert);
  ssl_crypto_x509_cert_flush_cached_chain(cert);

  X509_free(cert->x509_stash);
  cert->x509_stash = nullptr;
}

static void ssl_crypto_x509_cert_free(CERT *cert) {
  ssl_crypto_x509_cert_clear(cert);
  X509_STORE_free(cert->verify_store);
}

static void ssl_crypto_x509_cert_dup(CERT *new_cert, const CERT *cert) {
  if (cert->verify_store != nullptr) {
    X509_STORE_up_ref(cert->verify_store);
    new_cert->verify_store = cert->verify_store;
  }
}

static bool ssl_crypto_x509_session_cache_objects(SSL_SESSION *sess) {
  bssl::UniquePtr<STACK_OF(X509)> chain, chain_without_leaf;
  if (sk_CRYPTO_BUFFER_num(sess->certs.get()) > 0) {
    chain.reset(sk_X509_new_null());
    if (!chain) {
      return false;
    }
    if (sess->is_server) {
      // chain_without_leaf is only needed for server sessions. See
      // `SSL_get_peer_cert_chain`.
      chain_without_leaf.reset(sk_X509_new_null());
      if (!chain_without_leaf) {
        return false;
      }
    }
  }

  bssl::UniquePtr<X509> leaf;
  for (CRYPTO_BUFFER *cert : sess->certs.get()) {
    UniquePtr<X509> x509(X509_parse_from_buffer(cert));
    if (!x509) {
      OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
      return false;
    }
    if (leaf == nullptr) {
      leaf = UpRef(x509);
    } else if (chain_without_leaf &&
               !PushToStack(chain_without_leaf.get(), UpRef(x509))) {
      return false;
    }
    if (!PushToStack(chain.get(), std::move(x509))) {
      return false;
    }
  }

  sk_X509_pop_free(sess->x509_chain, X509_free);
  sess->x509_chain = chain.release();

  sk_X509_pop_free(sess->x509_chain_without_leaf, X509_free);
  sess->x509_chain_without_leaf = chain_without_leaf.release();

  X509_free(sess->x509_peer);
  sess->x509_peer = leaf.release();
  return true;
}

static bool ssl_crypto_x509_session_dup(SSL_SESSION *new_session,
                                        const SSL_SESSION *session) {
  new_session->x509_peer = UpRef(session->x509_peer).release();
  if (session->x509_chain != nullptr) {
    new_session->x509_chain = X509_chain_up_ref(session->x509_chain);
    if (new_session->x509_chain == nullptr) {
      return false;
    }
  }
  if (session->x509_chain_without_leaf != nullptr) {
    new_session->x509_chain_without_leaf =
        X509_chain_up_ref(session->x509_chain_without_leaf);
    if (new_session->x509_chain_without_leaf == nullptr) {
      return false;
    }
  }

  return true;
}

static void ssl_crypto_x509_session_clear(SSL_SESSION *session) {
  X509_free(session->x509_peer);
  session->x509_peer = nullptr;
  sk_X509_pop_free(session->x509_chain, X509_free);
  session->x509_chain = nullptr;
  sk_X509_pop_free(session->x509_chain_without_leaf, X509_free);
  session->x509_chain_without_leaf = nullptr;
}

static bool ssl_crypto_x509_session_verify_cert_chain(SSL_SESSION *session,
                                                      SSL_HANDSHAKE *hs,
                                                      uint8_t *out_alert) {
  if (session->peer_cert_type != TLSEXT_cert_type_x509) {
    return false;
  }
  *out_alert = SSL_AD_INTERNAL_ERROR;
  STACK_OF(X509) *const cert_chain = session->x509_chain;
  if (cert_chain == nullptr || sk_X509_num(cert_chain) == 0) {
    return false;
  }

  SSL *const ssl = hs->ssl;
  SSLContext *ssl_ctx = ssl->ctx.get();
  X509_STORE *verify_store = ssl_ctx->cert_store;
  if (hs->config->cert->verify_store != nullptr) {
    verify_store = hs->config->cert->verify_store;
  }

  X509 *leaf = sk_X509_value(cert_chain, 0);
  const char *name;
  size_t name_len;
  SSL_get0_ech_name_override(ssl, &name, &name_len);
  UniquePtr<X509_STORE_CTX> ctx(X509_STORE_CTX_new());
  if (!ctx ||                                                             //
      !X509_STORE_CTX_init(ctx.get(), verify_store, leaf, cert_chain) ||  //
      !X509_STORE_CTX_set_ex_data(
          ctx.get(), SSL_get_ex_data_X509_STORE_CTX_idx(), ssl) ||  //
      // We need to inherit the verify parameters. These can be determined by
      // the context: if its a server it will verify SSL client certificates or
      // vice versa.
      !X509_STORE_CTX_set_default(
          ctx.get(),
          ssl->server ? "ssl_client" : "ssl_server") ||  //
      // Anything non-default in "param" should overwrite anything in the ctx.
      !X509_VERIFY_PARAM_set1(X509_STORE_CTX_get0_param(ctx.get()),
                              hs->config->param) ||  //
      // ClientHelloOuter connections use a different name.
      (name_len != 0 &&  //
       !X509_VERIFY_PARAM_set1_host(X509_STORE_CTX_get0_param(ctx.get()), name,
                                    name_len))) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_X509_LIB);
    return false;
  }

  if (hs->config->verify_callback) {
    X509_STORE_CTX_set_verify_cb(ctx.get(), hs->config->verify_callback);
  }

  int verify_ret;
  if (ssl_ctx->app_verify_callback != nullptr) {
    verify_ret =
        ssl_ctx->app_verify_callback(ctx.get(), ssl_ctx->app_verify_arg);
  } else {
    verify_ret = X509_verify_cert(ctx.get());
  }

  session->verify_result = X509_STORE_CTX_get_error(ctx.get());

  // If `SSL_VERIFY_NONE`, the error is non-fatal, but we keep the result.
  if (verify_ret <= 0 && hs->config->verify_mode != SSL_VERIFY_NONE) {
    *out_alert = SSL_alert_from_verify_result(session->verify_result);
    return false;
  }

  ERR_clear_error();
  return true;
}

static void ssl_crypto_x509_hs_flush_cached_ca_names(SSL_HANDSHAKE *hs) {
  sk_X509_NAME_pop_free(hs->cached_x509_ca_names, X509_NAME_free);
  hs->cached_x509_ca_names = nullptr;
}

static bool ssl_crypto_x509_ssl_new(SSL_HANDSHAKE *hs) {
  hs->config->param = X509_VERIFY_PARAM_new();
  if (hs->config->param == nullptr) {
    return false;
  }
  X509_VERIFY_PARAM_inherit(hs->config->param, hs->ssl->ctx->param);
  return true;
}

static void ssl_crypto_x509_ssl_flush_cached_client_CA(SSL_CONFIG *cfg) {
  sk_X509_NAME_pop_free(cfg->cached_x509_client_CA, X509_NAME_free);
  cfg->cached_x509_client_CA = nullptr;
}

static void ssl_crypto_x509_ssl_config_free(SSL_CONFIG *cfg) {
  sk_X509_NAME_pop_free(cfg->cached_x509_client_CA, X509_NAME_free);
  cfg->cached_x509_client_CA = nullptr;
  X509_VERIFY_PARAM_free(cfg->param);
}

static bool ssl_crypto_x509_ssl_auto_chain_if_needed(SSL_HANDSHAKE *hs) {
  // Only build a chain if the feature isn't disabled, the legacy credential
  // exists but has no intermediates configured.
  SSL *ssl = hs->ssl;
  SSLCredential *cred = hs->config->cert->legacy_credential.get();
  if ((ssl->mode & SSL_MODE_NO_AUTO_CHAIN) || !cred->IsComplete() ||
      sk_CRYPTO_BUFFER_num(cred->chain.get()) != 1) {
    return true;
  }

  UniquePtr<X509> leaf(
      X509_parse_from_buffer(sk_CRYPTO_BUFFER_value(cred->chain.get(), 0)));
  if (!leaf) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_X509_LIB);
    return false;
  }

  UniquePtr<X509_STORE_CTX> ctx(X509_STORE_CTX_new());
  if (!ctx || !X509_STORE_CTX_init(ctx.get(), ssl->ctx->cert_store, leaf.get(),
                                   nullptr)) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_X509_LIB);
    return false;
  }

  // Attempt to build a chain, ignoring the result.
  X509_verify_cert(ctx.get());
  ERR_clear_error();

  // Remove the leaf from the generated chain.
  UniquePtr<STACK_OF(X509)> chain(X509_STORE_CTX_get1_chain(ctx.get()));
  if (!chain) {
    return false;
  }
  X509_free(sk_X509_shift(chain.get()));

  return SSL_set1_chain(ssl, chain.get());
}

static void ssl_crypto_x509_ssl_ctx_flush_cached_client_CA(SSLContext *ctx) {
  sk_X509_NAME_pop_free(ctx->cached_x509_client_CA, X509_NAME_free);
  ctx->cached_x509_client_CA = nullptr;
}

static bool ssl_crypto_x509_ssl_ctx_new(SSLContext *ctx) {
  ctx->cert_store = X509_STORE_new();
  ctx->param = X509_VERIFY_PARAM_new();
  return (ctx->cert_store != nullptr && ctx->param != nullptr);
}

static void ssl_crypto_x509_ssl_ctx_free(SSLContext *ctx) {
  ssl_crypto_x509_ssl_ctx_flush_cached_client_CA(ctx);
  X509_VERIFY_PARAM_free(ctx->param);
  X509_STORE_free(ctx->cert_store);
}

const SSL_X509_METHOD ssl_crypto_x509_method = {
    ssl_crypto_x509_check_client_CA_list,
    ssl_crypto_x509_cert_clear,
    ssl_crypto_x509_cert_free,
    ssl_crypto_x509_cert_dup,
    ssl_crypto_x509_cert_flush_cached_chain,
    ssl_crypto_x509_cert_flush_cached_leaf,
    ssl_crypto_x509_session_cache_objects,
    ssl_crypto_x509_session_dup,
    ssl_crypto_x509_session_clear,
    ssl_crypto_x509_session_verify_cert_chain,
    ssl_crypto_x509_hs_flush_cached_ca_names,
    ssl_crypto_x509_ssl_new,
    ssl_crypto_x509_ssl_config_free,
    ssl_crypto_x509_ssl_flush_cached_client_CA,
    ssl_crypto_x509_ssl_auto_chain_if_needed,
    ssl_crypto_x509_ssl_ctx_new,
    ssl_crypto_x509_ssl_ctx_free,
    ssl_crypto_x509_ssl_ctx_flush_cached_client_CA,
};

BSSL_NAMESPACE_END

using namespace bssl;

X509 *SSL_get_peer_certificate(const SSL *ssl) {
  check_ssl_x509_method(ssl);
  if (ssl == nullptr) {
    return nullptr;
  }
  SSL_SESSION *session = SSL_get_session(ssl);
  if (session == nullptr || session->x509_peer == nullptr) {
    return nullptr;
  }
  X509_up_ref(session->x509_peer);
  return session->x509_peer;
}

STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *ssl) {
  check_ssl_x509_method(ssl);
  if (ssl == nullptr) {
    return nullptr;
  }
  SSL_SESSION *session = SSL_get_session(ssl);
  if (session == nullptr) {
    return nullptr;
  }

  // OpenSSL historically didn't include the leaf certificate in the returned
  // certificate chain, but only for servers.
  return ssl->server ? session->x509_chain_without_leaf : session->x509_chain;
}

STACK_OF(X509) *SSL_get_peer_full_cert_chain(const SSL *ssl) {
  check_ssl_x509_method(ssl);
  SSL_SESSION *session = SSL_get_session(ssl);
  if (session == nullptr) {
    return nullptr;
  }

  return session->x509_chain;
}

int SSL_CTX_set_purpose(SSL_CTX *ctx, int purpose) {
  auto *ctx_impl = FromOpaque(ctx);
  check_ssl_ctx_x509_method(ctx_impl);
  return X509_VERIFY_PARAM_set_purpose(ctx_impl->param, purpose);
}

int SSL_set_purpose(SSL *ssl, int purpose) {
  check_ssl_x509_method(ssl);
  if (!ssl->config) {
    return 0;
  }
  return X509_VERIFY_PARAM_set_purpose(ssl->config->param, purpose);
}

int SSL_CTX_set_trust(SSL_CTX *ctx, int trust) {
  auto *ctx_impl = FromOpaque(ctx);
  check_ssl_ctx_x509_method(ctx_impl);
  return X509_VERIFY_PARAM_set_trust(ctx_impl->param, trust);
}

int SSL_set_trust(SSL *ssl, int trust) {
  check_ssl_x509_method(ssl);
  if (!ssl->config) {
    return 0;
  }
  return X509_VERIFY_PARAM_set_trust(ssl->config->param, trust);
}

int SSL_CTX_set1_param(SSL_CTX *ctx, const X509_VERIFY_PARAM *param) {
  auto *ctx_impl = FromOpaque(ctx);
  check_ssl_ctx_x509_method(ctx_impl);
  return X509_VERIFY_PARAM_set1(ctx_impl->param, param);
}

int SSL_set1_param(SSL *ssl, const X509_VERIFY_PARAM *param) {
  check_ssl_x509_method(ssl);
  if (!ssl->config) {
    return 0;
  }
  return X509_VERIFY_PARAM_set1(ssl->config->param, param);
}

X509_VERIFY_PARAM *SSL_CTX_get0_param(SSL_CTX *ctx) {
  auto *ctx_impl = FromOpaque(ctx);
  check_ssl_ctx_x509_method(ctx_impl);
  return ctx_impl->param;
}

X509_VERIFY_PARAM *SSL_get0_param(SSL *ssl) {
  check_ssl_x509_method(ssl);
  if (!ssl->config) {
    assert(ssl->config);
    return nullptr;
  }
  return ssl->config->param;
}

int SSL_get_verify_depth(const SSL *ssl) {
  check_ssl_x509_method(ssl);
  if (!ssl->config) {
    assert(ssl->config);
    return 0;
  }
  return X509_VERIFY_PARAM_get_depth(ssl->config->param);
}

int (*SSL_get_verify_callback(const SSL *ssl))(int, X509_STORE_CTX *) {
  check_ssl_x509_method(ssl);
  if (!ssl->config) {
    assert(ssl->config);
    return nullptr;
  }
  return ssl->config->verify_callback;
}

int SSL_CTX_get_verify_mode(const SSL_CTX *ctx) {
  auto *ctx_impl = FromOpaque(ctx);
  check_ssl_ctx_x509_method(ctx_impl);
  return ctx_impl->verify_mode;
}

int SSL_CTX_get_verify_depth(const SSL_CTX *ctx) {
  auto *ctx_impl = FromOpaque(ctx);
  check_ssl_ctx_x509_method(ctx_impl);
  return X509_VERIFY_PARAM_get_depth(ctx_impl->param);
}

int (*SSL_CTX_get_verify_callback(const SSL_CTX *ctx))(
    int ok, X509_STORE_CTX *store_ctx) {
  auto *ctx_impl = FromOpaque(ctx);
  check_ssl_ctx_x509_method(ctx_impl);
  return ctx_impl->default_verify_callback;
}

void SSL_set_verify(SSL *ssl, int mode,
                    int (*callback)(int ok, X509_STORE_CTX *store_ctx)) {
  check_ssl_x509_method(ssl);
  if (!ssl->config) {
    return;
  }
  ssl->config->verify_mode = mode;
  if (callback != nullptr) {
    ssl->config->verify_callback = callback;
  }
}

void SSL_set_verify_depth(SSL *ssl, int depth) {
  check_ssl_x509_method(ssl);
  if (!ssl->config) {
    return;
  }
  X509_VERIFY_PARAM_set_depth(ssl->config->param, depth);
}

void SSL_CTX_set_cert_verify_callback(
    SSL_CTX *ctx, int (*cb)(X509_STORE_CTX *store_ctx, void *arg), void *arg) {
  auto *ctx_impl = FromOpaque(ctx);
  check_ssl_ctx_x509_method(ctx_impl);
  ctx_impl->app_verify_callback = cb;
  ctx_impl->app_verify_arg = arg;
}

void SSL_CTX_set_verify(SSL_CTX *ctx, int mode,
                        int (*cb)(int, X509_STORE_CTX *)) {
  auto *ctx_impl = FromOpaque(ctx);
  check_ssl_ctx_x509_method(ctx_impl);
  ctx_impl->verify_mode = mode;
  ctx_impl->default_verify_callback = cb;
}

void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth) {
  auto *ctx_impl = FromOpaque(ctx);
  check_ssl_ctx_x509_method(ctx_impl);
  X509_VERIFY_PARAM_set_depth(ctx_impl->param, depth);
}

int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx) {
  auto *ctx_impl = FromOpaque(ctx);
  check_ssl_ctx_x509_method(ctx_impl);
  return X509_STORE_set_default_paths(ctx_impl->cert_store);
}

int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *ca_file,
                                  const char *ca_dir) {
  auto *ctx_impl = FromOpaque(ctx);
  check_ssl_ctx_x509_method(ctx_impl);
  return X509_STORE_load_locations(ctx_impl->cert_store, ca_file, ca_dir);
}

long SSL_get_verify_result(const SSL *ssl) {
  check_ssl_x509_method(ssl);
  SSL_SESSION *session = SSL_get_session(ssl);
  if (session == nullptr) {
    return X509_V_ERR_INVALID_CALL;
  }
  return session->verify_result;
}

X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *ctx) {
  auto *ctx_impl = FromOpaque(ctx);
  check_ssl_ctx_x509_method(ctx_impl);
  return ctx_impl->cert_store;
}

void SSL_CTX_set_cert_store(SSL_CTX *ctx, X509_STORE *store) {
  auto *ctx_impl = FromOpaque(ctx);
  check_ssl_ctx_x509_method(ctx_impl);
  X509_STORE_free(ctx_impl->cert_store);
  ctx_impl->cert_store = store;
}

static int ssl_use_certificate(CERT *cert, X509 *x) {
  if (x == nullptr) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER);
    return 0;
  }

  UniquePtr<CRYPTO_BUFFER> buffer = x509_to_buffer(x);
  if (!buffer) {
    return 0;
  }

  return ssl_set_cert(cert, std::move(buffer));
}

int SSL_use_certificate(SSL *ssl, X509 *x) {
  check_ssl_x509_method(ssl);
  if (!ssl->config) {
    return 0;
  }
  return ssl_use_certificate(ssl->config->cert.get(), x);
}

int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x) {
  auto *ctx_impl = FromOpaque(ctx);
  check_ssl_ctx_x509_method(ctx_impl);
  return ssl_use_certificate(ctx_impl->cert.get(), x);
}

// ssl_cert_cache_leaf_cert sets `cert->x509_leaf`, if currently NULL, from the
// first element of `cert->chain`.
static int ssl_cert_cache_leaf_cert(CERT *cert) {
  assert(cert->x509_method);

  const SSLCredential *cred = cert->legacy_credential.get();
  if (cert->x509_leaf != nullptr || cred->chain == nullptr) {
    return 1;
  }

  CRYPTO_BUFFER *leaf = sk_CRYPTO_BUFFER_value(cred->chain.get(), 0);
  if (!leaf) {
    return 1;
  }

  cert->x509_leaf = X509_parse_from_buffer(leaf);
  return cert->x509_leaf != nullptr;
}

static X509 *ssl_cert_get0_leaf(CERT *cert) {
  if (cert->x509_leaf == nullptr &&  //
      !ssl_cert_cache_leaf_cert(cert)) {
    return nullptr;
  }

  return cert->x509_leaf;
}

X509 *SSL_get_certificate(const SSL *ssl) {
  check_ssl_x509_method(ssl);
  if (!ssl->config) {
    assert(ssl->config);
    return nullptr;
  }
  return ssl_cert_get0_leaf(ssl->config->cert.get());
}

X509 *SSL_CTX_get0_certificate(const SSL_CTX *ctx) {
  auto *ctx_impl = FromOpaque(ctx);
  check_ssl_ctx_x509_method(ctx_impl);
  MutexWriteLock lock(&ctx_impl->lock);
  return ssl_cert_get0_leaf(ctx_impl->cert.get());
}

static int ssl_cert_add1_chain_cert(CERT *cert, X509 *x509) {
  assert(cert->x509_method);

  UniquePtr<CRYPTO_BUFFER> buffer = x509_to_buffer(x509);
  if (!buffer ||
      !cert->legacy_credential->AppendIntermediateCert(std::move(buffer))) {
    return 0;
  }

  ssl_crypto_x509_cert_flush_cached_chain(cert);
  return 1;
}

static int ssl_cert_add0_chain_cert(CERT *cert, X509 *x509) {
  if (!ssl_cert_add1_chain_cert(cert, x509)) {
    return 0;
  }

  X509_free(cert->x509_stash);
  cert->x509_stash = x509;
  return 1;
}

int SSL_CTX_set0_chain(SSL_CTX *ctx, STACK_OF(X509) *chain) {
  auto *ctx_impl = FromOpaque(ctx);
  check_ssl_ctx_x509_method(ctx_impl);
  if (!ssl_cert_set1_chain(ctx_impl->cert.get(), chain)) {
    return 0;
  }
  sk_X509_pop_free(chain, X509_free);
  return 1;
}

int SSL_CTX_set1_chain(SSL_CTX *ctx, STACK_OF(X509) *chain) {
  auto *ctx_impl = FromOpaque(ctx);
  check_ssl_ctx_x509_method(ctx_impl);
  return ssl_cert_set1_chain(ctx_impl->cert.get(), chain);
}

int SSL_set0_chain(SSL *ssl, STACK_OF(X509) *chain) {
  check_ssl_x509_method(ssl);
  if (!ssl->config) {
    return 0;
  }
  if (!ssl_cert_set1_chain(ssl->config->cert.get(), chain)) {
    return 0;
  }
  sk_X509_pop_free(chain, X509_free);
  return 1;
}

int SSL_set1_chain(SSL *ssl, STACK_OF(X509) *chain) {
  check_ssl_x509_method(ssl);
  if (!ssl->config) {
    return 0;
  }
  return ssl_cert_set1_chain(ssl->config->cert.get(), chain);
}

int SSL_CTX_add0_chain_cert(SSL_CTX *ctx, X509 *x509) {
  auto *ctx_impl = FromOpaque(ctx);
  check_ssl_ctx_x509_method(ctx_impl);
  return ssl_cert_add0_chain_cert(ctx_impl->cert.get(), x509);
}

int SSL_CTX_add1_chain_cert(SSL_CTX *ctx, X509 *x509) {
  auto *ctx_impl = FromOpaque(ctx);
  check_ssl_ctx_x509_method(ctx_impl);
  return ssl_cert_add1_chain_cert(ctx_impl->cert.get(), x509);
}

int SSL_CTX_add_extra_chain_cert(SSL_CTX *ctx, X509 *x509) {
  auto *ctx_impl = FromOpaque(ctx);
  check_ssl_ctx_x509_method(ctx_impl);
  return SSL_CTX_add0_chain_cert(ctx, x509);
}

int SSL_add0_chain_cert(SSL *ssl, X509 *x509) {
  check_ssl_x509_method(ssl);
  if (!ssl->config) {
    return 0;
  }
  return ssl_cert_add0_chain_cert(ssl->config->cert.get(), x509);
}

int SSL_add1_chain_cert(SSL *ssl, X509 *x509) {
  check_ssl_x509_method(ssl);
  if (!ssl->config) {
    return 0;
  }
  return ssl_cert_add1_chain_cert(ssl->config->cert.get(), x509);
}

int SSL_CTX_clear_chain_certs(SSL_CTX *ctx) {
  auto *ctx_impl = FromOpaque(ctx);
  check_ssl_ctx_x509_method(ctx_impl);
  return SSL_CTX_set0_chain(ctx, nullptr);
}

int SSL_CTX_clear_extra_chain_certs(SSL_CTX *ctx) {
  auto *ctx_impl = FromOpaque(ctx);
  check_ssl_ctx_x509_method(ctx_impl);
  return SSL_CTX_clear_chain_certs(ctx);
}

int SSL_clear_chain_certs(SSL *ssl) {
  check_ssl_x509_method(ssl);
  return SSL_set0_chain(ssl, nullptr);
}

// ssl_cert_cache_chain_certs fills in `cert->x509_chain` from elements 1.. of
// `cert->chain`.
static int ssl_cert_cache_chain_certs(CERT *cert) {
  assert(cert->x509_method);

  const SSLCredential *cred = cert->legacy_credential.get();
  if (cert->x509_chain != nullptr || cred->chain == nullptr ||
      sk_CRYPTO_BUFFER_num(cred->chain.get()) < 2) {
    return 1;
  }

  UniquePtr<STACK_OF(X509)> chain(sk_X509_new_null());
  if (!chain) {
    return 0;
  }

  for (size_t i = 1; i < sk_CRYPTO_BUFFER_num(cred->chain.get()); i++) {
    CRYPTO_BUFFER *buffer = sk_CRYPTO_BUFFER_value(cred->chain.get(), i);
    UniquePtr<X509> x509(X509_parse_from_buffer(buffer));
    if (!x509 ||  //
        !PushToStack(chain.get(), std::move(x509))) {
      return 0;
    }
  }

  cert->x509_chain = chain.release();
  return 1;
}

int SSL_CTX_get0_chain_certs(const SSL_CTX *ctx, STACK_OF(X509) **out_chain) {
  auto *ctx_impl = FromOpaque(ctx);
  check_ssl_ctx_x509_method(ctx_impl);
  MutexWriteLock lock(&ctx_impl->lock);
  if (!ssl_cert_cache_chain_certs(ctx_impl->cert.get())) {
    *out_chain = nullptr;
    return 0;
  }

  *out_chain = ctx_impl->cert->x509_chain;
  return 1;
}

int SSL_CTX_get_extra_chain_certs(const SSL_CTX *ctx,
                                  STACK_OF(X509) **out_chain) {
  return SSL_CTX_get0_chain_certs(ctx, out_chain);
}

int SSL_get0_chain_certs(const SSL *ssl, STACK_OF(X509) **out_chain) {
  check_ssl_x509_method(ssl);
  if (!ssl->config) {
    assert(ssl->config);
    return 0;
  }
  if (!ssl_cert_cache_chain_certs(ssl->config->cert.get())) {
    *out_chain = nullptr;
    return 0;
  }

  *out_chain = ssl->config->cert->x509_chain;
  return 1;
}

SSL_SESSION *d2i_SSL_SESSION_bio(BIO *bio, SSL_SESSION **out) {
  uint8_t *data;
  size_t len;
  if (!BIO_read_asn1(bio, &data, &len, 1024 * 1024)) {
    return nullptr;
  }
  bssl::UniquePtr<uint8_t> free_data(data);
  const uint8_t *ptr = data;
  return d2i_SSL_SESSION(out, &ptr, static_cast<long>(len));
}

int i2d_SSL_SESSION_bio(BIO *bio, const SSL_SESSION *session) {
  uint8_t *data;
  size_t len;
  if (!SSL_SESSION_to_bytes(session, &data, &len)) {
    return 0;
  }
  bssl::UniquePtr<uint8_t> free_data(data);
  return BIO_write_all(bio, data, len);
}

IMPLEMENT_PEM_rw(SSL_SESSION, SSL_SESSION, PEM_STRING_SSL_SESSION, SSL_SESSION)

SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **out, const uint8_t **inp, long len) {
  return bssl::D2IFromCBS(out, inp, len, [](CBS *cbs) {
    return SSL_SESSION_parse(cbs, &ssl_crypto_x509_method,
                             nullptr /* no buffer pool */);
  });
}

STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *list) {
  return sk_X509_NAME_deep_copy(list, X509_NAME_dup, X509_NAME_free);
}

static void set_client_CA_list(UniquePtr<STACK_OF(CRYPTO_BUFFER)> *ca_list,
                               const STACK_OF(X509_NAME) *name_list,
                               CRYPTO_BUFFER_POOL *pool) {
  UniquePtr<STACK_OF(CRYPTO_BUFFER)> buffers(sk_CRYPTO_BUFFER_new_null());
  if (!buffers) {
    return;
  }

  for (X509_NAME *name : name_list) {
    uint8_t *outp = nullptr;
    int len = i2d_X509_NAME(name, &outp);
    if (len < 0) {
      return;
    }

    UniquePtr<CRYPTO_BUFFER> buffer(CRYPTO_BUFFER_new(outp, len, pool));
    OPENSSL_free(outp);
    if (!buffer || !PushToStack(buffers.get(), std::move(buffer))) {
      return;
    }
  }

  *ca_list = std::move(buffers);
}

void SSL_set_client_CA_list(SSL *ssl, STACK_OF(X509_NAME) *name_list) {
  check_ssl_x509_method(ssl);
  if (!ssl->config) {
    return;
  }
  ssl->ctx->x509_method->ssl_flush_cached_client_CA(ssl->config.get());
  set_client_CA_list(&ssl->config->client_CA, name_list, ssl->ctx->pool.get());
  sk_X509_NAME_pop_free(name_list, X509_NAME_free);
}

void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list) {
  auto *ctx_impl = FromOpaque(ctx);
  check_ssl_ctx_x509_method(ctx_impl);
  ctx_impl->x509_method->ssl_ctx_flush_cached_client_CA(ctx_impl);
  set_client_CA_list(&ctx_impl->client_CA, name_list, ctx_impl->pool.get());
  sk_X509_NAME_pop_free(name_list, X509_NAME_free);
}

static STACK_OF(X509_NAME) *buffer_names_to_x509(
    const STACK_OF(CRYPTO_BUFFER) *names, STACK_OF(X509_NAME) **cached) {
  if (names == nullptr) {
    return nullptr;
  }

  if (*cached != nullptr) {
    return *cached;
  }

  UniquePtr<STACK_OF(X509_NAME)> new_cache(sk_X509_NAME_new_null());
  if (!new_cache) {
    return nullptr;
  }

  for (const CRYPTO_BUFFER *buffer : names) {
    const uint8_t *inp = CRYPTO_BUFFER_data(buffer);
    UniquePtr<X509_NAME> name(
        d2i_X509_NAME(nullptr, &inp, CRYPTO_BUFFER_len(buffer)));
    if (!name ||
        inp != CRYPTO_BUFFER_data(buffer) + CRYPTO_BUFFER_len(buffer) ||
        !PushToStack(new_cache.get(), std::move(name))) {
      return nullptr;
    }
  }

  *cached = new_cache.release();
  return *cached;
}

STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *ssl) {
  check_ssl_x509_method(ssl);
  if (!ssl->config) {
    assert(ssl->config);
    return nullptr;
  }
  // For historical reasons, this function is used both to query configuration
  // state on a server as well as handshake state on a client. However, whether
  // `ssl` is a client or server is not known until explicitly configured with
  // `SSL_set_connect_state`. If `do_handshake` is NULL, `ssl` is in an
  // indeterminate mode and `ssl->server` is unset.
  if (ssl->do_handshake != nullptr && !ssl->server) {
    if (ssl->s3->hs != nullptr) {
      return buffer_names_to_x509(ssl->s3->hs->ca_names.get(),
                                  &ssl->s3->hs->cached_x509_ca_names);
    }

    return nullptr;
  }

  if (ssl->config->client_CA != nullptr) {
    return buffer_names_to_x509(
        ssl->config->client_CA.get(),
        (STACK_OF(X509_NAME) **)&ssl->config->cached_x509_client_CA);
  }
  return SSL_CTX_get_client_CA_list(ssl->ctx.get());
}

STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *ctx) {
  auto *ctx_impl = FromOpaque(ctx);
  check_ssl_ctx_x509_method(ctx_impl);
  // This is a logically const operation that may be called on multiple threads,
  // so it needs to lock around updating `cached_x509_client_CA`.
  MutexWriteLock lock(&ctx_impl->lock);
  return buffer_names_to_x509(
      ctx_impl->client_CA.get(),
      const_cast<STACK_OF(X509_NAME) **>(&ctx_impl->cached_x509_client_CA));
}

static int add_client_CA(UniquePtr<STACK_OF(CRYPTO_BUFFER)> *names, X509 *x509,
                         CRYPTO_BUFFER_POOL *pool) {
  if (x509 == nullptr) {
    return 0;
  }

  uint8_t *outp = nullptr;
  int len = i2d_X509_NAME(X509_get_subject_name(x509), &outp);
  if (len < 0) {
    return 0;
  }

  UniquePtr<CRYPTO_BUFFER> buffer(CRYPTO_BUFFER_new(outp, len, pool));
  OPENSSL_free(outp);
  if (!buffer) {
    return 0;
  }

  int alloced = 0;
  if (*names == nullptr) {
    names->reset(sk_CRYPTO_BUFFER_new_null());
    alloced = 1;

    if (*names == nullptr) {
      return 0;
    }
  }

  if (!PushToStack(names->get(), std::move(buffer))) {
    if (alloced) {
      names->reset();
    }
    return 0;
  }

  return 1;
}

int SSL_add_client_CA(SSL *ssl, X509 *x509) {
  check_ssl_x509_method(ssl);
  if (!ssl->config) {
    return 0;
  }
  if (!add_client_CA(&ssl->config->client_CA, x509, ssl->ctx->pool.get())) {
    return 0;
  }

  ssl_crypto_x509_ssl_flush_cached_client_CA(ssl->config.get());
  return 1;
}

int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x509) {
  auto *ctx_impl = FromOpaque(ctx);
  check_ssl_ctx_x509_method(ctx_impl);
  if (!add_client_CA(&ctx_impl->client_CA, x509, ctx_impl->pool.get())) {
    return 0;
  }

  ssl_crypto_x509_ssl_ctx_flush_cached_client_CA(ctx_impl);
  return 1;
}

static int do_client_cert_cb(SSL *ssl, void *arg) {
  // Should only be called during handshake, but check to be sure.
  BSSL_CHECK(ssl->config);

  if (ssl->config->cert->legacy_credential->IsComplete() ||
      ssl->ctx->client_cert_cb == nullptr) {
    return 1;
  }

  X509 *x509 = nullptr;
  EVP_PKEY *pkey = nullptr;
  int ret = ssl->ctx->client_cert_cb(ssl, &x509, &pkey);
  if (ret < 0) {
    return -1;
  }
  UniquePtr<X509> free_x509(x509);
  UniquePtr<EVP_PKEY> free_pkey(pkey);

  if (ret != 0) {
    if (!SSL_use_certificate(ssl, x509) ||  //
        !SSL_use_PrivateKey(ssl, pkey)) {
      return 0;
    }
  }

  return 1;
}

void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx,
                                int (*cb)(SSL *ssl, X509 **out_x509,
                                          EVP_PKEY **out_pkey)) {
  auto *ctx_impl = FromOpaque(ctx);
  check_ssl_ctx_x509_method(ctx_impl);
  // Emulate the old client certificate callback with the new one.
  SSL_CTX_set_cert_cb(ctx, do_client_cert_cb, nullptr);
  ctx_impl->client_cert_cb = cb;
}

static int set_cert_store(X509_STORE **store_ptr, X509_STORE *new_store,
                          int take_ref) {
  X509_STORE_free(*store_ptr);
  *store_ptr = new_store;

  if (new_store != nullptr && take_ref) {
    X509_STORE_up_ref(new_store);
  }

  return 1;
}

int SSL_get_ex_data_X509_STORE_CTX_idx() {
  // The ex_data index to go from `X509_STORE_CTX` to `SSL` always uses the
  // reserved app_data slot. Before ex_data was introduced, app_data was used.
  // Avoid breaking any software which assumes `X509_STORE_CTX_get_app_data`
  // works.
  return 0;
}

int SSL_CTX_set0_verify_cert_store(SSL_CTX *ctx, X509_STORE *store) {
  auto *ctx_impl = FromOpaque(ctx);
  check_ssl_ctx_x509_method(ctx_impl);
  return set_cert_store(&ctx_impl->cert->verify_store, store, 0);
}

int SSL_CTX_set1_verify_cert_store(SSL_CTX *ctx, X509_STORE *store) {
  auto *ctx_impl = FromOpaque(ctx);
  check_ssl_ctx_x509_method(ctx_impl);
  return set_cert_store(&ctx_impl->cert->verify_store, store, 1);
}

int SSL_set0_verify_cert_store(SSL *ssl, X509_STORE *store) {
  check_ssl_x509_method(ssl);
  if (!ssl->config) {
    return 0;
  }
  return set_cert_store(&ssl->config->cert->verify_store, store, 0);
}

int SSL_set1_verify_cert_store(SSL *ssl, X509_STORE *store) {
  check_ssl_x509_method(ssl);
  if (!ssl->config) {
    return 0;
  }
  return set_cert_store(&ssl->config->cert->verify_store, store, 1);
}

int SSL_set1_host(SSL *ssl, const char *hostname) {
  check_ssl_x509_method(ssl);
  if (!ssl->config) {
    return 0;
  }
  return X509_VERIFY_PARAM_set1_host(ssl->config->param, hostname,
                                     strlen(hostname));
}

void SSL_set_hostflags(SSL *ssl, unsigned flags) {
  check_ssl_x509_method(ssl);
  if (!ssl->config) {
    return;
  }
  X509_VERIFY_PARAM_set_hostflags(ssl->config->param, flags);
}

int SSL_alert_from_verify_result(long result) {
  switch (result) {
    case X509_V_ERR_CERT_CHAIN_TOO_LONG:
    case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
    case X509_V_ERR_INVALID_CA:
    case X509_V_ERR_PATH_LENGTH_EXCEEDED:
    case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
    case X509_V_ERR_UNABLE_TO_GET_CRL:
    case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER:
    case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
    case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
    case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
      return SSL_AD_UNKNOWN_CA;

    case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
    case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
    case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
    case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
    case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
    case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
    case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
    case X509_V_ERR_CERT_UNTRUSTED:
    case X509_V_ERR_CERT_REJECTED:
    case X509_V_ERR_HOSTNAME_MISMATCH:
    case X509_V_ERR_EMAIL_MISMATCH:
    case X509_V_ERR_IP_ADDRESS_MISMATCH:
      return SSL_AD_BAD_CERTIFICATE;

    case X509_V_ERR_CERT_SIGNATURE_FAILURE:
    case X509_V_ERR_CRL_SIGNATURE_FAILURE:
      return SSL_AD_DECRYPT_ERROR;

    case X509_V_ERR_CERT_HAS_EXPIRED:
    case X509_V_ERR_CERT_NOT_YET_VALID:
    case X509_V_ERR_CRL_HAS_EXPIRED:
    case X509_V_ERR_CRL_NOT_YET_VALID:
      return SSL_AD_CERTIFICATE_EXPIRED;

    case X509_V_ERR_CERT_REVOKED:
      return SSL_AD_CERTIFICATE_REVOKED;

    case X509_V_ERR_UNSPECIFIED:
    case X509_V_ERR_OUT_OF_MEM:
    case X509_V_ERR_INVALID_CALL:
    case X509_V_ERR_STORE_LOOKUP:
      return SSL_AD_INTERNAL_ERROR;

    case X509_V_ERR_APPLICATION_VERIFICATION:
      return SSL_AD_HANDSHAKE_FAILURE;

    case X509_V_ERR_INVALID_PURPOSE:
      return SSL_AD_UNSUPPORTED_CERTIFICATE;

    default:
      return SSL_AD_CERTIFICATE_UNKNOWN;
  }
}
