#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>
#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"
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);
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() { … }
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) { … }
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
enum ssl_verify_result_t OpenSSLAdapter::SSLVerifyCallback(SSL* ssl,
uint8_t* out_alert) {
OpenSSLAdapter* stream =
reinterpret_cast<OpenSSLAdapter*>(SSL_get_app_data(ssl));
ssl_verify_result_t ret = stream->SSLVerifyInternal(ssl, out_alert);
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
int OpenSSLAdapter::SSLVerifyCallback(int status, X509_STORE_CTX* store) { … }
int OpenSSLAdapter::SSLVerifyInternal(int previous_status,
SSL* ssl,
X509_STORE_CTX* store) { … }
#endif
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() = 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() { … }
}