chromium/third_party/webrtc/rtc_base/openssl_adapter.cc

/*
 *  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"
#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"
#include "system_wrappers/include/field_trial.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* BIO_new_socket(rtc::Socket* socket) {}

static int socket_new(BIO* b) {}

static int socket_free(BIO* b) {}

static int socket_read(BIO* b, char* out, int outl) {}

static int socket_write(BIO* b, const char* in, int inl) {}

static int socket_puts(BIO* b, const char* str) {}

static long socket_ctrl(BIO* b, int cmd, long num, void* ptr) {}

static void LogSslError() {}

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

namespace rtc {

TimeDelta;

bool OpenSSLAdapter::InitializeSSL() {}

bool OpenSSLAdapter::CleanupSSL() {}

OpenSSLAdapter::OpenSSLAdapter(Socket* socket,
                               OpenSSLSessionCache* ssl_session_cache,
                               SSLCertificateVerifier* ssl_cert_verifier)
    :{}

OpenSSLAdapter::~OpenSSLAdapter() {}

void OpenSSLAdapter::SetIgnoreBadCert(bool ignore) {}

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

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

void OpenSSLAdapter::SetMode(SSLMode mode) {}

void OpenSSLAdapter::SetCertVerifier(
    SSLCertificateVerifier* ssl_cert_verifier) {}

void OpenSSLAdapter::SetIdentity(std::unique_ptr<SSLIdentity> identity) {}

void OpenSSLAdapter::SetRole(SSLRole role) {}

int OpenSSLAdapter::StartSSL(absl::string_view hostname) {}

int OpenSSLAdapter::BeginSSL() {}

int OpenSSLAdapter::ContinueSSL() {}

void OpenSSLAdapter::Error(absl::string_view context, int err, bool signal) {}

void OpenSSLAdapter::Cleanup() {}

int OpenSSLAdapter::DoSslWrite(const void* pv, size_t cb, int* error) {}

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

int OpenSSLAdapter::Send(const void* pv, size_t cb) {}

int OpenSSLAdapter::SendTo(const void* pv,
                           size_t cb,
                           const SocketAddress& addr) {}

int OpenSSLAdapter::Recv(void* pv, size_t cb, int64_t* timestamp) {}

int OpenSSLAdapter::RecvFrom(void* pv,
                             size_t cb,
                             SocketAddress* paddr,
                             int64_t* timestamp) {}

int OpenSSLAdapter::Close() {}

Socket::ConnState OpenSSLAdapter::GetState() const {}

bool OpenSSLAdapter::IsResumedSession() {}

void OpenSSLAdapter::OnTimeout() {}

void OpenSSLAdapter::OnConnectEvent(Socket* socket) {}

void OpenSSLAdapter::OnReadEvent(Socket* socket) {}

void OpenSSLAdapter::OnWriteEvent(Socket* socket) {}

void OpenSSLAdapter::OnCloseEvent(Socket* socket, int err) {}

bool OpenSSLAdapter::SSLPostConnectionCheck(SSL* ssl, absl::string_view host) {}

void OpenSSLAdapter::SSLInfoCallback(const SSL* s, int where, int value) {}

#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) {}

int OpenSSLAdapter::SSLVerifyInternal(int previous_status,
                                      SSL* ssl,
                                      X509_STORE_CTX* store) {}
#endif  // !defined(WEBRTC_USE_CRYPTO_BUFFER_CALLBACK)

int OpenSSLAdapter::NewSSLSessionCallback(SSL* ssl, SSL_SESSION* session) {}

SSL_CTX* OpenSSLAdapter::CreateContext(SSLMode mode,
                                       bool enable_cache,
                                       bool permute_extension) {}

std::string TransformAlpnProtocols(
    const std::vector<std::string>& alpn_protocols) {}

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

OpenSSLAdapterFactory::OpenSSLAdapterFactory() = default;

OpenSSLAdapterFactory::~OpenSSLAdapterFactory() = default;

void OpenSSLAdapterFactory::SetMode(SSLMode mode) {}

void OpenSSLAdapterFactory::SetCertVerifier(
    SSLCertificateVerifier* ssl_cert_verifier) {}

void OpenSSLAdapterFactory::SetIdentity(std::unique_ptr<SSLIdentity> identity) {}

void OpenSSLAdapterFactory::SetRole(SSLRole role) {}

void OpenSSLAdapterFactory::SetIgnoreBadCert(bool ignore) {}

OpenSSLAdapter* OpenSSLAdapterFactory::CreateAdapter(Socket* socket,
                                                     bool permute_extension) {}

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

void OpenSSLAdapter::EarlyExitCatcher::disable() {}

OpenSSLAdapter::EarlyExitCatcher::~EarlyExitCatcher() {}

}  // namespace rtc