/*
 *  Copyright 2008 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "rtc_base/openssl_adapter.h"

#include <errno.h>
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/ssl.h>

#include <cstdint>
#include <string>
#include <utility>
#include <vector>

#include "absl/strings/string_view.h"
#include "api/task_queue/pending_task_safety_flag.h"
#include "rtc_base/async_socket.h"
#include "rtc_base/openssl_session_cache.h"
#include "rtc_base/socket.h"
#include "rtc_base/socket_address.h"
#include "rtc_base/ssl_adapter.h"
#include "rtc_base/ssl_certificate.h"
#include "rtc_base/ssl_identity.h"
#include "rtc_base/ssl_stream_adapter.h"
#include "rtc_base/strings/string_builder.h"
#ifdef OPENSSL_IS_BORINGSSL
#include <openssl/base.h>
#include <openssl/pool.h>

#include "rtc_base/boringssl_certificate.h"
#endif
#include <openssl/x509.h>
#include <string.h>
#include <time.h>

#include <memory>

// Use CRYPTO_BUFFER APIs if available and we have no dependency on X509
// objects.
#if defined(OPENSSL_IS_BORINGSSL) && \
    defined(WEBRTC_EXCLUDE_BUILT_IN_SSL_ROOT_CERTS)
#define WEBRTC_USE_CRYPTO_BUFFER_CALLBACK
#endif

#include "absl/memory/memory.h"
#include "api/units/time_delta.h"
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"
#include "rtc_base/numerics/safe_conversions.h"
#ifdef OPENSSL_IS_BORINGSSL
#include "rtc_base/boringssl_identity.h"
#else
#include "rtc_base/openssl_identity.h"
#endif
#include "rtc_base/openssl_utility.h"
#include "rtc_base/strings/str_join.h"
#include "rtc_base/thread.h"

//////////////////////////////////////////////////////////////////////
// SocketBIO
//////////////////////////////////////////////////////////////////////

static int socket_write(BIO* h, const char* buf, int num);
static int socket_read(BIO* h, char* buf, int size);
static int socket_puts(BIO* h, const char* str);
static long socket_ctrl(BIO* h, int cmd, long arg1, void* arg2);  // NOLINT
static int socket_new(BIO* h);
static int socket_free(BIO* data);

static BIO_METHOD* BIO_socket_method() {
  static BIO_METHOD* methods = [] {
    BIO_METHOD* methods = BIO_meth_new(BIO_TYPE_BIO, "socket");
    BIO_meth_set_write(methods, socket_write);
    BIO_meth_set_read(methods, socket_read);
    BIO_meth_set_puts(methods, socket_puts);
    BIO_meth_set_ctrl(methods, socket_ctrl);
    BIO_meth_set_create(methods, socket_new);
    BIO_meth_set_destroy(methods, socket_free);
    return methods;
  }();
  return methods;
}

static BIO* BIO_new_socket(rtc::Socket* socket) {
  BIO* ret = BIO_new(BIO_socket_method());
  if (ret == nullptr) {
    return nullptr;
  }
  BIO_set_data(ret, socket);
  return ret;
}

static int socket_new(BIO* b) {
  BIO_set_shutdown(b, 0);
  BIO_set_init(b, 1);
  BIO_set_data(b, 0);
  return 1;
}

static int socket_free(BIO* b) {
  if (b == nullptr)
    return 0;
  return 1;
}

static int socket_read(BIO* b, char* out, int outl) {
  if (!out)
    return -1;
  rtc::Socket* socket = static_cast<rtc::Socket*>(BIO_get_data(b));
  BIO_clear_retry_flags(b);
  int result = socket->Recv(out, outl, nullptr);
  if (result > 0) {
    return result;
  } else if (socket->IsBlocking()) {
    BIO_set_retry_read(b);
  }
  return -1;
}

static int socket_write(BIO* b, const char* in, int inl) {
  if (!in)
    return -1;
  rtc::Socket* socket = static_cast<rtc::Socket*>(BIO_get_data(b));
  BIO_clear_retry_flags(b);
  int result = socket->Send(in, inl);
  if (result > 0) {
    return result;
  } else if (socket->IsBlocking()) {
    BIO_set_retry_write(b);
  }
  return -1;
}

static int socket_puts(BIO* b, const char* str) {
  return socket_write(b, str, webrtc::checked_cast<int>(strlen(str)));
}

static long socket_ctrl(BIO* b, int cmd, long num, void* ptr) {  // NOLINT
  switch (cmd) {
    case BIO_CTRL_RESET:
      return 0;
    case BIO_CTRL_EOF: {
      rtc::Socket* socket = static_cast<rtc::Socket*>(ptr);
      // 1 means socket closed.
      return (socket->GetState() == rtc::Socket::CS_CLOSED) ? 1 : 0;
    }
    case BIO_CTRL_WPENDING:
    case BIO_CTRL_PENDING:
      return 0;
    case BIO_CTRL_FLUSH:
      return 1;
    default:
      return 0;
  }
}

static void LogSslError() {
  // Walk down the error stack to find the SSL error.
  uint32_t error_code;
  const char* file;
  int line;
  do {
    error_code = ERR_get_error_line(&file, &line);
    if (ERR_GET_LIB(error_code) == ERR_LIB_SSL) {
      RTC_LOG(LS_ERROR) << "ERR_LIB_SSL: " << error_code << ", " << file << ":"
                        << line;
      break;
    }
  } while (error_code != 0);
}

/////////////////////////////////////////////////////////////////////////////
// OpenSSLAdapter
/////////////////////////////////////////////////////////////////////////////

namespace rtc {

using ::webrtc::TimeDelta;

bool OpenSSLAdapter::InitializeSSL() {
  // TODO: https://issues.webrtc.org/issues/339300437 - remove once
  // BoringSSL no longer requires this after
  // https://bugs.chromium.org/p/boringssl/issues/detail?id=35
  // In OpenSSL it is supposed to be a no-op as of 1.1:
  // https://www.openssl.org/docs/man1.1.1/man3/OPENSSL_init_ssl.html
  return OPENSSL_init_ssl(0, nullptr);
}

bool OpenSSLAdapter::CleanupSSL() {
  return true;
}

OpenSSLAdapter::OpenSSLAdapter(Socket* socket,
                               OpenSSLSessionCache* ssl_session_cache,
                               SSLCertificateVerifier* ssl_cert_verifier)
    : SSLAdapter(socket),
      ssl_session_cache_(ssl_session_cache),
      ssl_cert_verifier_(ssl_cert_verifier),
      state_(SSL_NONE),
      role_(SSL_CLIENT),
      ssl_read_needs_write_(false),
      ssl_write_needs_read_(false),
      ssl_(nullptr),
      ssl_ctx_(nullptr),
      ssl_mode_(SSL_MODE_TLS),
      ignore_bad_cert_(false),
      custom_cert_verifier_status_(false) {
  // If a factory is used, take a reference on the factory's SSL_CTX.
  // Otherwise, we'll create our own later.
  // Either way, we'll release our reference via SSL_CTX_free() in Cleanup().
  if (ssl_session_cache_ != nullptr) {
    ssl_ctx_ = ssl_session_cache_->GetSSLContext();
    RTC_DCHECK(ssl_ctx_);
    // Note: if using OpenSSL, requires version 1.1.0 or later.
    SSL_CTX_up_ref(ssl_ctx_);
  }
}

OpenSSLAdapter::~OpenSSLAdapter() {
  Cleanup();
}

void OpenSSLAdapter::SetIgnoreBadCert(bool ignore) {
  ignore_bad_cert_ = ignore;
}

void OpenSSLAdapter::SetAlpnProtocols(const std::vector<std::string>& protos) {
  alpn_protocols_ = protos;
}

void OpenSSLAdapter::SetEllipticCurves(const std::vector<std::string>& curves) {
  elliptic_curves_ = curves;
}

void OpenSSLAdapter::SetMode(SSLMode mode) {
  RTC_DCHECK(!ssl_ctx_);
  RTC_DCHECK(state_ == SSL_NONE);
  ssl_mode_ = mode;
}

void OpenSSLAdapter::SetCertVerifier(
    SSLCertificateVerifier* ssl_cert_verifier) {
  RTC_DCHECK(!ssl_ctx_);
  ssl_cert_verifier_ = ssl_cert_verifier;
}

void OpenSSLAdapter::SetIdentity(std::unique_ptr<SSLIdentity> identity) {
  RTC_DCHECK(!identity_);
#ifdef OPENSSL_IS_BORINGSSL
  identity_ =
      absl::WrapUnique(static_cast<BoringSSLIdentity*>(identity.release()));
#else
  identity_ =
      absl::WrapUnique(static_cast<OpenSSLIdentity*>(identity.release()));
#endif
}

void OpenSSLAdapter::SetRole(SSLRole role) {
  role_ = role;
}

int OpenSSLAdapter::StartSSL(absl::string_view hostname) {
  if (state_ != SSL_NONE)
    return -1;

  ssl_host_name_.assign(hostname.data(), hostname.size());

  if (GetSocket()->GetState() != Socket::CS_CONNECTED) {
    state_ = SSL_WAIT;
    return 0;
  }

  state_ = SSL_CONNECTING;
  if (int err = BeginSSL()) {
    Error("BeginSSL", err, false);
    return err;
  }

  return 0;
}

int OpenSSLAdapter::BeginSSL() {
  RTC_LOG(LS_INFO) << "OpenSSLAdapter::BeginSSL: " << ssl_host_name_;
  RTC_DCHECK(state_ == SSL_CONNECTING);

  // Cleanup action to deal with on error cleanup a bit cleaner.
  EarlyExitCatcher early_exit_catcher(*this);

  // First set up the context. We should either have a factory, with its own
  // pre-existing context, or be running standalone, in which case we will
  // need to create one, and specify `false` to disable session caching.
  if (ssl_session_cache_ == nullptr) {
    RTC_DCHECK(!ssl_ctx_);
    ssl_ctx_ = CreateContext(ssl_mode_, /* enable_cache= */ false);
  }

  if (!ssl_ctx_) {
    return -1;
  }

  if (identity_ && !identity_->ConfigureIdentity(ssl_ctx_)) {
    return -1;
  }

  std::unique_ptr<BIO, decltype(&::BIO_free)> bio{BIO_new_socket(GetSocket()),
                                                  ::BIO_free};
  if (!bio) {
    return -1;
  }

  ssl_ = SSL_new(ssl_ctx_);
  if (!ssl_) {
    return -1;
  }

  SSL_set_app_data(ssl_, this);

  // SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER allows different buffers to be passed
  // into SSL_write when a record could only be partially transmitted (and thus
  // requires another call to SSL_write to finish transmission). This allows us
  // to copy the data into our own buffer when this occurs, since the original
  // buffer can't safely be accessed after control exits Send.
  // TODO(deadbeef): Do we want SSL_MODE_ENABLE_PARTIAL_WRITE? It doesn't
  // appear Send handles partial writes properly, though maybe we never notice
  // since we never send more than 16KB at once..
  SSL_set_mode(ssl_, SSL_MODE_ENABLE_PARTIAL_WRITE |
                         SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);

  // Enable SNI, if a hostname is supplied.
  if (!ssl_host_name_.empty()) {
    SSL_set_tlsext_host_name(ssl_, ssl_host_name_.c_str());

    // Enable session caching, if configured and a hostname is supplied.
    if (ssl_session_cache_ != nullptr) {
      SSL_SESSION* cached = ssl_session_cache_->LookupSession(ssl_host_name_);
      if (cached) {
        if (SSL_set_session(ssl_, cached) == 0) {
          RTC_LOG(LS_WARNING) << "Failed to apply SSL session from cache";
          return -1;
        }

        RTC_LOG(LS_INFO) << "Attempting to resume SSL session to "
                         << ssl_host_name_;
      }
    }
  }

#ifdef OPENSSL_IS_BORINGSSL
  // Set a couple common TLS extensions; even though we don't use them yet.
  SSL_enable_ocsp_stapling(ssl_);
  SSL_enable_signed_cert_timestamps(ssl_);
#endif

  if (!alpn_protocols_.empty()) {
    std::string tls_alpn_string = TransformAlpnProtocols(alpn_protocols_);
    if (!tls_alpn_string.empty()) {
      SSL_set_alpn_protos(
          ssl_, reinterpret_cast<const unsigned char*>(tls_alpn_string.data()),
          webrtc::dchecked_cast<unsigned>(tls_alpn_string.size()));
    }
  }

  if (!elliptic_curves_.empty()) {
    SSL_set1_curves_list(ssl_, webrtc::StrJoin(elliptic_curves_, ":").c_str());
  }

  // Now that the initial config is done, transfer ownership of `bio` to the
  // SSL object. If ContinueSSL() fails, the bio will be freed in Cleanup().
  SSL_set_bio(ssl_, bio.get(), bio.get());
  bio.release();

  // Do the connect.
  int err = ContinueSSL();
  if (err != 0) {
    return err;
  }
  early_exit_catcher.disable();
  return 0;
}

int OpenSSLAdapter::ContinueSSL() {
  RTC_DCHECK(state_ == SSL_CONNECTING);

  // Clear the DTLS timer
  timer_.reset();

  int code = (role_ == SSL_CLIENT) ? SSL_connect(ssl_) : SSL_accept(ssl_);
  switch (SSL_get_error(ssl_, code)) {
    case SSL_ERROR_NONE:
      if (!SSLPostConnectionCheck(ssl_, ssl_host_name_)) {
        RTC_LOG(LS_ERROR) << "TLS post connection check failed";
        // make sure we close the socket
        Cleanup();
        // The connect failed so return -1 to shut down the socket
        return -1;
      }

      state_ = SSL_CONNECTED;
      AsyncSocketAdapter::OnConnectEvent(this);
      // TODO(benwright): Refactor this code path.
      // Don't let ourselves go away during the callbacks
      // PRefPtr<OpenSSLAdapter> lock(this);
      // RTC_LOG(LS_INFO) << " -- onStreamReadable";
      // AsyncSocketAdapter::OnReadEvent(this);
      // RTC_LOG(LS_INFO) << " -- onStreamWriteable";
      // AsyncSocketAdapter::OnWriteEvent(this);
      break;

    case SSL_ERROR_WANT_READ:
      RTC_LOG(LS_VERBOSE) << " -- error want read";
      struct timeval timeout;
      if (DTLSv1_get_timeout(ssl_, &timeout)) {
        TimeDelta delay = TimeDelta::Seconds(timeout.tv_sec) +
                          TimeDelta::Micros(timeout.tv_usec);
        Thread::Current()->PostDelayedTask(
            SafeTask(timer_.flag(), [this] { OnTimeout(); }), delay);
      }
      break;

    case SSL_ERROR_WANT_WRITE:
      break;

    case SSL_ERROR_ZERO_RETURN:
    default:
      RTC_LOG(LS_WARNING) << "ContinueSSL -- error " << code;
      return (code != 0) ? code : -1;
  }

  return 0;
}

void OpenSSLAdapter::Error(absl::string_view context, int err, bool signal) {
  RTC_LOG(LS_WARNING) << "OpenSSLAdapter::Error(" << context << ", " << err
                      << ")";
  state_ = SSL_ERROR;
  SetError(err);
  if (signal) {
    AsyncSocketAdapter::OnCloseEvent(this, err);
  }
}

void OpenSSLAdapter::Cleanup() {
  RTC_LOG(LS_INFO) << "OpenSSLAdapter::Cleanup";

  state_ = SSL_NONE;
  ssl_read_needs_write_ = false;
  ssl_write_needs_read_ = false;
  custom_cert_verifier_status_ = false;
  pending_data_.Clear();

  if (ssl_) {
    SSL_free(ssl_);
    ssl_ = nullptr;
  }

  if (ssl_ctx_) {
    SSL_CTX_free(ssl_ctx_);
    ssl_ctx_ = nullptr;
  }
  identity_.reset();

  // Clear the DTLS timer
  timer_.reset();
}

int OpenSSLAdapter::DoSslWrite(const void* pv, size_t cb, int* error) {
  // If we have pending data (that was previously only partially written by
  // SSL_write), we shouldn't be attempting to write anything else.
  RTC_DCHECK(pending_data_.empty() || pv == pending_data_.data());
  RTC_DCHECK(error != nullptr);

  ssl_write_needs_read_ = false;
  int ret = SSL_write(ssl_, pv, webrtc::checked_cast<int>(cb));
  *error = SSL_get_error(ssl_, ret);
  switch (*error) {
    case SSL_ERROR_NONE:
      // Success!
      return ret;
    case SSL_ERROR_WANT_READ:
      RTC_LOG(LS_INFO) << " -- error want read";
      ssl_write_needs_read_ = true;
      SetError(EWOULDBLOCK);
      break;
    case SSL_ERROR_WANT_WRITE:
      RTC_LOG(LS_INFO) << " -- error want write";
      SetError(EWOULDBLOCK);
      break;
    case SSL_ERROR_ZERO_RETURN:
      SetError(EWOULDBLOCK);
      // do we need to signal closure?
      break;
    case SSL_ERROR_SSL:
      LogSslError();
      Error("SSL_write", ret ? ret : -1, false);
      break;
    default:
      Error("SSL_write", ret ? ret : -1, false);
      break;
  }

  return SOCKET_ERROR;
}

///////////////////////////////////////////////////////////////////////////////
// Socket Implementation
///////////////////////////////////////////////////////////////////////////////

int OpenSSLAdapter::Send(const void* pv, size_t cb) {
  switch (state_) {
    case SSL_NONE:
      return AsyncSocketAdapter::Send(pv, cb);
    case SSL_WAIT:
    case SSL_CONNECTING:
      SetError(ENOTCONN);
      return SOCKET_ERROR;
    case SSL_CONNECTED:
      break;
    case SSL_ERROR:
    default:
      return SOCKET_ERROR;
  }

  int ret;
  int error;

  if (!pending_data_.empty()) {
    ret = DoSslWrite(pending_data_.data(), pending_data_.size(), &error);
    if (ret != static_cast<int>(pending_data_.size())) {
      // We couldn't finish sending the pending data, so we definitely can't
      // send any more data. Return with an EWOULDBLOCK error.
      SetError(EWOULDBLOCK);
      return SOCKET_ERROR;
    }
    // We completed sending the data previously passed into SSL_write! Now
    // we're allowed to send more data.
    pending_data_.Clear();
  }

  // OpenSSL will return an error if we try to write zero bytes
  if (cb == 0) {
    return 0;
  }

  ret = DoSslWrite(pv, cb, &error);

  // If SSL_write fails with SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE, this
  // means the underlying socket is blocked on reading or (more typically)
  // writing. When this happens, OpenSSL requires that the next call to
  // SSL_write uses the same arguments (though, with
  // SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER, the actual buffer pointer may be
  // different).
  //
  // However, after Send exits, we will have lost access to data the user of
  // this class is trying to send, and there's no guarantee that the user of
  // this class will call Send with the same arguements when it fails. So, we
  // buffer the data ourselves. When we know the underlying socket is writable
  // again from OnWriteEvent (or if Send is called again before that happens),
  // we'll retry sending this buffered data.
  if (error == SSL_ERROR_WANT_READ || error == SSL_ERROR_WANT_WRITE) {
    // Shouldn't be able to get to this point if we already have pending data.
    RTC_DCHECK(pending_data_.empty());
    RTC_LOG(LS_WARNING)
        << "SSL_write couldn't write to the underlying socket; buffering data.";
    pending_data_.SetData(static_cast<const uint8_t*>(pv), cb);
    // Since we're taking responsibility for sending this data, return its full
    // size. The user of this class can consider it sent.
    return webrtc::dchecked_cast<int>(cb);
  }
  return ret;
}

int OpenSSLAdapter::SendTo(const void* pv,
                           size_t cb,
                           const SocketAddress& addr) {
  if (GetSocket()->GetState() == Socket::CS_CONNECTED &&
      addr == GetSocket()->GetRemoteAddress()) {
    return Send(pv, cb);
  }

  SetError(ENOTCONN);
  return SOCKET_ERROR;
}

int OpenSSLAdapter::Recv(void* pv, size_t cb, int64_t* timestamp) {
  switch (state_) {
    case SSL_NONE:
      return AsyncSocketAdapter::Recv(pv, cb, timestamp);
    case SSL_WAIT:
    case SSL_CONNECTING:
      SetError(ENOTCONN);
      return SOCKET_ERROR;
    case SSL_CONNECTED:
      break;
    case SSL_ERROR:
    default:
      return SOCKET_ERROR;
  }

  // Don't trust OpenSSL with zero byte reads
  if (cb == 0) {
    return 0;
  }

  ssl_read_needs_write_ = false;
  int code = SSL_read(ssl_, pv, webrtc::checked_cast<int>(cb));
  int error = SSL_get_error(ssl_, code);

  switch (error) {
    case SSL_ERROR_NONE:
      return code;
    case SSL_ERROR_WANT_READ:
      SetError(EWOULDBLOCK);
      break;
    case SSL_ERROR_WANT_WRITE:
      ssl_read_needs_write_ = true;
      SetError(EWOULDBLOCK);
      break;
    case SSL_ERROR_ZERO_RETURN:
      SetError(EWOULDBLOCK);
      // do we need to signal closure?
      break;
    case SSL_ERROR_SSL:
      LogSslError();
      Error("SSL_read", (code ? code : -1), false);
      break;
    default:
      Error("SSL_read", (code ? code : -1), false);
      break;
  }
  return SOCKET_ERROR;
}

int OpenSSLAdapter::RecvFrom(void* pv,
                             size_t cb,
                             SocketAddress* paddr,
                             int64_t* timestamp) {
  if (GetSocket()->GetState() == Socket::CS_CONNECTED) {
    int ret = Recv(pv, cb, timestamp);
    *paddr = GetRemoteAddress();
    return ret;
  }

  SetError(ENOTCONN);
  return SOCKET_ERROR;
}

int OpenSSLAdapter::Close() {
  Cleanup();
  state_ = SSL_NONE;
  return AsyncSocketAdapter::Close();
}

Socket::ConnState OpenSSLAdapter::GetState() const {
  ConnState state = GetSocket()->GetState();
  if ((state == CS_CONNECTED) &&
      ((state_ == SSL_WAIT) || (state_ == SSL_CONNECTING))) {
    state = CS_CONNECTING;
  }
  return state;
}

bool OpenSSLAdapter::IsResumedSession() {
  return (ssl_ && SSL_session_reused(ssl_) == 1);
}

void OpenSSLAdapter::OnTimeout() {
  RTC_LOG(LS_INFO) << "DTLS timeout expired";
  DTLSv1_handle_timeout(ssl_);
  ContinueSSL();
}

void OpenSSLAdapter::OnConnectEvent(Socket* socket) {
  RTC_LOG(LS_INFO) << "OpenSSLAdapter::OnConnectEvent";
  if (state_ != SSL_WAIT) {
    RTC_DCHECK(state_ == SSL_NONE);
    AsyncSocketAdapter::OnConnectEvent(socket);
    return;
  }

  state_ = SSL_CONNECTING;
  if (int err = BeginSSL()) {
    AsyncSocketAdapter::OnCloseEvent(socket, err);
  }
}

void OpenSSLAdapter::OnReadEvent(Socket* socket) {
  if (state_ == SSL_NONE) {
    AsyncSocketAdapter::OnReadEvent(socket);
    return;
  }

  if (state_ == SSL_CONNECTING) {
    if (int err = ContinueSSL()) {
      Error("ContinueSSL", err);
    }
    return;
  }

  if (state_ != SSL_CONNECTED) {
    return;
  }

  // Don't let ourselves go away during the callbacks
  // PRefPtr<OpenSSLAdapter> lock(this); // TODO(benwright): fix this
  if (ssl_write_needs_read_) {
    AsyncSocketAdapter::OnWriteEvent(socket);
  }

  AsyncSocketAdapter::OnReadEvent(socket);
}

void OpenSSLAdapter::OnWriteEvent(Socket* socket) {
  if (state_ == SSL_NONE) {
    AsyncSocketAdapter::OnWriteEvent(socket);
    return;
  }

  if (state_ == SSL_CONNECTING) {
    if (int err = ContinueSSL()) {
      Error("ContinueSSL", err);
    }
    return;
  }

  if (state_ != SSL_CONNECTED) {
    return;
  }

  // Don't let ourselves go away during the callbacks
  // PRefPtr<OpenSSLAdapter> lock(this); // TODO(benwright): fix this

  if (ssl_read_needs_write_) {
    AsyncSocketAdapter::OnReadEvent(socket);
  }

  // If a previous SSL_write failed due to the underlying socket being blocked,
  // this will attempt finishing the write operation.
  if (!pending_data_.empty()) {
    int error;
    if (DoSslWrite(pending_data_.data(), pending_data_.size(), &error) ==
        static_cast<int>(pending_data_.size())) {
      pending_data_.Clear();
    }
  }

  AsyncSocketAdapter::OnWriteEvent(socket);
}

void OpenSSLAdapter::OnCloseEvent(Socket* socket, int err) {
  RTC_LOG(LS_INFO) << "OpenSSLAdapter::OnCloseEvent(" << err << ")";
  AsyncSocketAdapter::OnCloseEvent(socket, err);
}

bool OpenSSLAdapter::SSLPostConnectionCheck(SSL* ssl, absl::string_view host) {
  bool is_valid_cert_name =
      openssl::VerifyPeerCertMatchesHost(ssl, host) &&
      (SSL_get_verify_result(ssl) == X509_V_OK || custom_cert_verifier_status_);

  if (!is_valid_cert_name && ignore_bad_cert_) {
    RTC_DLOG(LS_WARNING) << "Other TLS post connection checks failed. "
                            "ignore_bad_cert_ set to true. Overriding name "
                            "verification failure!";
    is_valid_cert_name = true;
  }
  return is_valid_cert_name;
}

void OpenSSLAdapter::SSLInfoCallback(const SSL* ssl, int where, int ret) {
  switch (where) {
    case SSL_CB_LOOP:
    case SSL_CB_READ:
    case SSL_CB_WRITE:
      return;
    default:
      break;
  }
  char buf[1024];
  webrtc::SimpleStringBuilder ss(buf);
  ss << SSL_state_string_long(ssl);
  if (ret == 0) {
    RTC_LOG(LS_ERROR) << "Error during " << ss.str() << "\n";
    return;
  }
  // See SSL_alert_type_string_long.
  int severity_class = where >> 8;
  switch (severity_class) {
    case SSL3_AL_WARNING:
    case SSL3_AL_FATAL:
      ss << " " << SSL_alert_type_string_long(ret);
      ss << " " << SSL_alert_desc_string_long(ret);
      RTC_LOG(LS_WARNING) << ss.str();
      break;
    default:
      RTC_LOG(LS_INFO) << ss.str();
      break;
  }
}

#ifdef WEBRTC_USE_CRYPTO_BUFFER_CALLBACK
// static
enum ssl_verify_result_t OpenSSLAdapter::SSLVerifyCallback(SSL* ssl,
                                                           uint8_t* out_alert) {
  // Get our stream pointer from the SSL context.
  OpenSSLAdapter* stream =
      reinterpret_cast<OpenSSLAdapter*>(SSL_get_app_data(ssl));

  ssl_verify_result_t ret = stream->SSLVerifyInternal(ssl, out_alert);

  // Should only be used for debugging and development.
  if (ret != ssl_verify_ok && stream->ignore_bad_cert_) {
    RTC_DLOG(LS_WARNING) << "Ignoring cert error while verifying cert chain";
    return ssl_verify_ok;
  }

  return ret;
}

enum ssl_verify_result_t OpenSSLAdapter::SSLVerifyInternal(SSL* ssl,
                                                           uint8_t* out_alert) {
  if (ssl_cert_verifier_ == nullptr) {
    RTC_LOG(LS_WARNING) << "Built-in trusted root certificates disabled but no "
                           "SSL verify callback provided.";
    return ssl_verify_invalid;
  }

  RTC_LOG(LS_INFO) << "Invoking SSL Verify Callback.";
  const STACK_OF(CRYPTO_BUFFER)* chain = SSL_get0_peer_certificates(ssl);
  if (sk_CRYPTO_BUFFER_num(chain) == 0) {
    RTC_LOG(LS_ERROR) << "Peer certificate chain empty?";
    return ssl_verify_invalid;
  }

  BoringSSLCertificate cert(bssl::UpRef(sk_CRYPTO_BUFFER_value(chain, 0)));
  if (!ssl_cert_verifier_->Verify(cert)) {
    RTC_LOG(LS_WARNING) << "Failed to verify certificate using custom callback";
    return ssl_verify_invalid;
  }

  custom_cert_verifier_status_ = true;
  RTC_LOG(LS_INFO) << "Validated certificate using custom callback";
  return ssl_verify_ok;
}
#else  // WEBRTC_USE_CRYPTO_BUFFER_CALLBACK
int OpenSSLAdapter::SSLVerifyCallback(int status, X509_STORE_CTX* store) {
  // Get our stream pointer from the store
  SSL* ssl = reinterpret_cast<SSL*>(
      X509_STORE_CTX_get_ex_data(store, SSL_get_ex_data_X509_STORE_CTX_idx()));

  OpenSSLAdapter* stream =
      reinterpret_cast<OpenSSLAdapter*>(SSL_get_app_data(ssl));
  // Update status with the custom verifier.
  // Status is unchanged if verification fails.
  status = stream->SSLVerifyInternal(status, ssl, store);

  // Should only be used for debugging and development.
  if (!status && stream->ignore_bad_cert_) {
    RTC_DLOG(LS_WARNING) << "Ignoring cert error while verifying cert chain";
    return 1;
  }

  return status;
}

int OpenSSLAdapter::SSLVerifyInternal(int previous_status,
                                      SSL* ssl,
                                      X509_STORE_CTX* store) {
#if !defined(NDEBUG)
  if (!previous_status) {
    char data[256];
    X509* cert = X509_STORE_CTX_get_current_cert(store);
    int depth = X509_STORE_CTX_get_error_depth(store);
    int err = X509_STORE_CTX_get_error(store);

    RTC_DLOG(LS_INFO) << "Error with certificate at depth: " << depth;
    X509_NAME_oneline(X509_get_issuer_name(cert), data, sizeof(data));
    RTC_DLOG(LS_INFO) << "  issuer  = " << data;
    X509_NAME_oneline(X509_get_subject_name(cert), data, sizeof(data));
    RTC_DLOG(LS_INFO) << "  subject = " << data;
    RTC_DLOG(LS_INFO) << "  err     = " << err << ":"
                      << X509_verify_cert_error_string(err);
  }
#endif
  // `ssl_cert_verifier_` is used to override errors; if there is no error
  // there is no reason to call it.
  if (previous_status || ssl_cert_verifier_ == nullptr) {
    return previous_status;
  }

  RTC_LOG(LS_INFO) << "Invoking SSL Verify Callback.";
#ifdef OPENSSL_IS_BORINGSSL
  // Convert X509 to CRYPTO_BUFFER.
  uint8_t* data = nullptr;
  int length = i2d_X509(X509_STORE_CTX_get_current_cert(store), &data);
  if (length < 0) {
    RTC_LOG(LS_ERROR) << "Failed to encode X509.";
    return previous_status;
  }
  bssl::UniquePtr<uint8_t> owned_data(data);
  bssl::UniquePtr<CRYPTO_BUFFER> crypto_buffer(
      CRYPTO_BUFFER_new(data, length, openssl::GetBufferPool()));
  if (!crypto_buffer) {
    RTC_LOG(LS_ERROR) << "Failed to allocate CRYPTO_BUFFER.";
    return previous_status;
  }
  const BoringSSLCertificate cert(std::move(crypto_buffer));
#else
  const OpenSSLCertificate cert(X509_STORE_CTX_get_current_cert(store));
#endif
  if (!ssl_cert_verifier_->Verify(cert)) {
    RTC_LOG(LS_INFO) << "Failed to verify certificate using custom callback";
    return previous_status;
  }

  custom_cert_verifier_status_ = true;
  RTC_LOG(LS_INFO) << "Validated certificate using custom callback";
  return 1;
}
#endif  // !defined(WEBRTC_USE_CRYPTO_BUFFER_CALLBACK)

int OpenSSLAdapter::NewSSLSessionCallback(SSL* ssl, SSL_SESSION* session) {
  OpenSSLAdapter* stream =
      reinterpret_cast<OpenSSLAdapter*>(SSL_get_app_data(ssl));
  RTC_DCHECK(stream->ssl_session_cache_);
  RTC_LOG(LS_INFO) << "Caching SSL session for " << stream->ssl_host_name_;
  stream->ssl_session_cache_->AddSession(stream->ssl_host_name_, session);
  return 1;  // We've taken ownership of the session; OpenSSL shouldn't free it.
}

SSL_CTX* OpenSSLAdapter::CreateContext(SSLMode mode, bool enable_cache) {
#ifdef WEBRTC_USE_CRYPTO_BUFFER_CALLBACK
  // If X509 objects aren't used, we can use these methods to avoid
  // linking the sizable crypto/x509 code.
  SSL_CTX* ctx = SSL_CTX_new(mode == SSL_MODE_DTLS ? DTLS_with_buffers_method()
                                                   : TLS_with_buffers_method());
#else
  SSL_CTX* ctx =
      SSL_CTX_new(mode == SSL_MODE_DTLS ? DTLS_method() : TLS_method());
#endif
  if (ctx == nullptr) {
    unsigned long error = ERR_get_error();  // NOLINT: type used by OpenSSL.
    RTC_LOG(LS_WARNING) << "SSL_CTX creation failed: " << '"'
                        << ERR_reason_error_string(error)
                        << "\" "
                           "(error="
                        << error << ')';
    return nullptr;
  }

#ifndef WEBRTC_EXCLUDE_BUILT_IN_SSL_ROOT_CERTS
  if (!openssl::LoadBuiltinSSLRootCertificates(ctx)) {
    RTC_LOG(LS_ERROR) << "SSL_CTX creation failed: Failed to load any trusted "
                         "ssl root certificates.";
    SSL_CTX_free(ctx);
    return nullptr;
  }
#endif  // WEBRTC_EXCLUDE_BUILT_IN_SSL_ROOT_CERTS

#if !defined(NDEBUG)
  SSL_CTX_set_info_callback(ctx, SSLInfoCallback);
#endif

#ifdef OPENSSL_IS_BORINGSSL
  SSL_CTX_set0_buffer_pool(ctx, openssl::GetBufferPool());
#endif

#ifdef WEBRTC_USE_CRYPTO_BUFFER_CALLBACK
  SSL_CTX_set_custom_verify(ctx, SSL_VERIFY_PEER, SSLVerifyCallback);
#else
  SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, SSLVerifyCallback);
  // Verify certificate chains up to a depth of 4. This is not
  // needed for DTLS-SRTP which uses self-signed certificates
  // (so the depth is 0) but is required to support TURN/TLS.
  SSL_CTX_set_verify_depth(ctx, 4);
#endif
  // Use defaults, but disable HMAC-SHA256 and HMAC-SHA384 ciphers
  // (note that SHA256 and SHA384 only select legacy CBC ciphers).
  // Additionally disable HMAC-SHA1 ciphers in ECDSA. These are the remaining
  // CBC-mode ECDSA ciphers. Finally, disable 3DES.
  SSL_CTX_set_cipher_list(
      ctx, "ALL:!SHA256:!SHA384:!aPSK:!ECDSA+SHA1:!ADH:!LOW:!EXP:!MD5:!3DES");

  if (enable_cache) {
    SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_CLIENT);
    SSL_CTX_sess_set_new_cb(ctx, &OpenSSLAdapter::NewSSLSessionCallback);
  }

#ifdef OPENSSL_IS_BORINGSSL
  SSL_CTX_set_permute_extensions(ctx, true);
#endif
  return ctx;
}

std::string TransformAlpnProtocols(
    const std::vector<std::string>& alpn_protocols) {
  // Transforms the alpn_protocols list to the format expected by
  // Open/BoringSSL. This requires joining the protocols into a single string
  // and prepending a character with the size of the protocol string before
  // each protocol.
  std::string transformed_alpn;
  for (const std::string& proto : alpn_protocols) {
    if (proto.size() == 0 || proto.size() > 0xFF) {
      RTC_LOG(LS_ERROR) << "OpenSSLAdapter::Error("
                           "TransformAlpnProtocols received proto with size "
                        << proto.size() << ")";
      return "";
    }
    transformed_alpn += static_cast<char>(proto.size());
    transformed_alpn += proto;
    RTC_LOG(LS_VERBOSE) << "TransformAlpnProtocols: Adding proto: " << proto;
  }
  return transformed_alpn;
}

//////////////////////////////////////////////////////////////////////
// OpenSSLAdapterFactory
//////////////////////////////////////////////////////////////////////

OpenSSLAdapterFactory::OpenSSLAdapterFactory() = default;

OpenSSLAdapterFactory::~OpenSSLAdapterFactory() = default;

void OpenSSLAdapterFactory::SetMode(SSLMode mode) {
  RTC_DCHECK(!ssl_session_cache_);
  ssl_mode_ = mode;
}

void OpenSSLAdapterFactory::SetCertVerifier(
    SSLCertificateVerifier* ssl_cert_verifier) {
  RTC_DCHECK(!ssl_session_cache_);
  ssl_cert_verifier_ = ssl_cert_verifier;
}

void OpenSSLAdapterFactory::SetIdentity(std::unique_ptr<SSLIdentity> identity) {
  RTC_DCHECK(!ssl_session_cache_);
  identity_ = std::move(identity);
}

void OpenSSLAdapterFactory::SetRole(SSLRole role) {
  RTC_DCHECK(!ssl_session_cache_);
  ssl_role_ = role;
}

void OpenSSLAdapterFactory::SetIgnoreBadCert(bool ignore) {
  RTC_DCHECK(!ssl_session_cache_);
  ignore_bad_cert_ = ignore;
}

OpenSSLAdapter* OpenSSLAdapterFactory::CreateAdapter(Socket* socket) {
  if (ssl_session_cache_ == nullptr) {
    SSL_CTX* ssl_ctx = OpenSSLAdapter::CreateContext(ssl_mode_, true);
    if (ssl_ctx == nullptr) {
      return nullptr;
    }
    // The OpenSSLSessionCache will upref the ssl_ctx.
    ssl_session_cache_ =
        std::make_unique<OpenSSLSessionCache>(ssl_mode_, ssl_ctx);
    SSL_CTX_free(ssl_ctx);
  }
  OpenSSLAdapter* ssl_adapter =
      new OpenSSLAdapter(socket, ssl_session_cache_.get(), ssl_cert_verifier_);
  ssl_adapter->SetRole(ssl_role_);
  ssl_adapter->SetIgnoreBadCert(ignore_bad_cert_);
  if (identity_) {
    ssl_adapter->SetIdentity(identity_->Clone());
  }
  return ssl_adapter;
}

OpenSSLAdapter::EarlyExitCatcher::EarlyExitCatcher(OpenSSLAdapter& adapter_ptr)
    : adapter_ptr_(adapter_ptr) {}

void OpenSSLAdapter::EarlyExitCatcher::disable() {
  disabled_ = true;
}

OpenSSLAdapter::EarlyExitCatcher::~EarlyExitCatcher() {
  if (!disabled_) {
    adapter_ptr_.Cleanup();
  }
}

}  // namespace rtc
