/*
 *  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>
#ifdef OPENSSL_IS_BORINGSSL
#include <openssl/pool.h>
#endif
#include <openssl/rand.h>
#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 "rtc_base/checks.h"
#include "rtc_base/location.h"
#include "rtc_base/logging.h"
#include "rtc_base/numerics/safe_conversions.h"
#include "rtc_base/openssl.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/string_encode.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::AsyncSocket* 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::AsyncSocket* socket = static_cast<rtc::AsyncSocket*>(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::AsyncSocket* socket = static_cast<rtc::AsyncSocket*>(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, rtc::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::AsyncSocket* socket = static_cast<rtc::AsyncSocket*>(ptr);
      // 1 means socket closed.
      return (socket->GetState() == rtc::AsyncSocket::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 {

bool OpenSSLAdapter::InitializeSSL() {
  if (!SSL_library_init())
    return false;
#if !defined(ADDRESS_SANITIZER) || !defined(WEBRTC_MAC) || defined(WEBRTC_IOS)
  // Loading the error strings crashes mac_asan.  Omit this debugging aid there.
  SSL_load_error_strings();
#endif
  ERR_load_BIO_strings();
  OpenSSL_add_all_algorithms();
  RAND_poll();
  return true;
}

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

OpenSSLAdapter::OpenSSLAdapter(AsyncSocket* 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;
}

AsyncSocket* OpenSSLAdapter::Accept(SocketAddress* paddr) {
  RTC_DCHECK(role_ == SSL_SERVER);
  AsyncSocket* socket = SSLAdapter::Accept(paddr);
  if (!socket) {
    return nullptr;
  }

  SSLAdapter* adapter = SSLAdapter::Create(socket);
  adapter->SetIdentity(identity_->Clone());
  adapter->SetRole(rtc::SSL_SERVER);
  adapter->SetIgnoreBadCert(ignore_bad_cert_);
  adapter->StartSSL("");
  return adapter;
}

int OpenSSLAdapter::StartSSL(const char* hostname) {
  if (state_ != SSL_NONE)
    return -1;

  ssl_host_name_ = hostname;

  if (socket_->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);

  int err = 0;
  BIO* bio = nullptr;

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

  if (!ssl_ctx_) {
    err = -1;
    goto ssl_error;
  }

  if (identity_ && !identity_->ConfigureIdentity(ssl_ctx_)) {
    SSL_CTX_free(ssl_ctx_);
    err = -1;
    goto ssl_error;
  }

  bio = BIO_new_socket(socket_);
  if (!bio) {
    err = -1;
    goto ssl_error;
  }

  ssl_ = SSL_new(ssl_ctx_);
  if (!ssl_) {
    err = -1;
    goto ssl_error;
  }

  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";
          err = -1;
          goto ssl_error;
        }

        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()),
          rtc::dchecked_cast<unsigned>(tls_alpn_string.size()));
    }
  }

  if (!elliptic_curves_.empty()) {
    SSL_set1_curves_list(ssl_, rtc::join(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, bio);
  bio = nullptr;

  // Do the connect.
  err = ContinueSSL();
  if (err != 0) {
    goto ssl_error;
  }

  return err;

ssl_error:
  Cleanup();
  if (bio) {
    BIO_free(bio);
  }

  return err;
}

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

  // Clear the DTLS timer
  Thread::Current()->Clear(this, MSG_TIMEOUT);

  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)) {
        int delay = timeout.tv_sec * 1000 + timeout.tv_usec / 1000;

        Thread::Current()->PostDelayed(RTC_FROM_HERE, delay, this, MSG_TIMEOUT,
                                       0);
      }
      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(const char* 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
  Thread::Current()->Clear(this, MSG_TIMEOUT);
}

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

///////////////////////////////////////////////////////////////////////////////
// AsyncSocket 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 rtc::dchecked_cast<int>(cb);
  }
  return ret;
}

int OpenSSLAdapter::SendTo(const void* pv,
                           size_t cb,
                           const SocketAddress& addr) {
  if (socket_->GetState() == Socket::CS_CONNECTED &&
      addr == socket_->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, 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 (socket_->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 = socket_->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::OnMessage(Message* msg) {
  if (MSG_TIMEOUT == msg->message_id) {
    RTC_LOG(LS_INFO) << "DTLS timeout expired";
    DTLSv1_handle_timeout(ssl_);
    ContinueSSL();
  }
}

void OpenSSLAdapter::OnConnectEvent(AsyncSocket* 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(AsyncSocket* 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(AsyncSocket* 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(AsyncSocket* socket, int err) {
  RTC_LOG(LS_INFO) << "OpenSSLAdapter::OnCloseEvent(" << err << ")";
  AsyncSocketAdapter::OnCloseEvent(socket, err);
}

bool OpenSSLAdapter::SSLPostConnectionCheck(SSL* ssl, const std::string& 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;
}

#if !defined(NDEBUG)

// We only use this for tracing and so it is only needed in debug mode

void OpenSSLAdapter::SSLInfoCallback(const SSL* s, int where, int ret) {
  const char* str = "undefined";
  int w = where & ~SSL_ST_MASK;
  if (w & SSL_ST_CONNECT) {
    str = "SSL_connect";
  } else if (w & SSL_ST_ACCEPT) {
    str = "SSL_accept";
  }
  if (where & SSL_CB_LOOP) {
    RTC_DLOG(LS_VERBOSE) << str << ":" << SSL_state_string_long(s);
  } else if (where & SSL_CB_ALERT) {
    str = (where & SSL_CB_READ) ? "read" : "write";
    RTC_DLOG(LS_INFO) << "SSL3 alert " << str << ":"
                      << SSL_alert_type_string_long(ret) << ":"
                      << SSL_alert_desc_string_long(ret);
  } else if (where & SSL_CB_EXIT) {
    if (ret == 0) {
      RTC_DLOG(LS_INFO) << str << ":failed in " << SSL_state_string_long(s);
    } else if (ret < 0) {
      RTC_DLOG(LS_INFO) << str << ":error in " << SSL_state_string_long(s);
    }
  }
}

#endif

#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 ok, 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));
  ok = stream->SSLVerifyInternal(ok, ssl, store);

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

  return ok;
}

int OpenSSLAdapter::SSLVerifyInternal(int ok, SSL* ssl, X509_STORE_CTX* store) {
#if !defined(NDEBUG)
  if (!ok) {
    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
  if (ssl_cert_verifier_ == nullptr) {
    return ok;
  }

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

  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);
  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.
  SSL_CTX_set_cipher_list(
      ctx, "ALL:!SHA256:!SHA384:!aPSK:!ECDSA+SHA1:!ADH:!LOW:!EXP:!MD5");

  if (mode == SSL_MODE_DTLS) {
    SSL_CTX_set_read_ahead(ctx, 1);
  }

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

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

OpenSSLAdapter* OpenSSLAdapterFactory::CreateAdapter(AsyncSocket* 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);
  }
  return new OpenSSLAdapter(socket, ssl_session_cache_.get(),
                            ssl_cert_verifier_);
}

}  // namespace rtc
