/*
 *  Copyright 2004 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_stream_adapter.h"

#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/ssl.h>
#include <openssl/stack.h>
#include <openssl/tls1.h>

#include <cstddef>
#include <cstdint>
#include <cstring>
#include <memory>
#include <optional>
#include <span>
#include <string>
#include <utility>
#include <vector>

#include "absl/functional/any_invocable.h"
#include "absl/strings/str_format.h"
#include "absl/strings/string_view.h"
#include "api/field_trials_view.h"
#include "api/sequence_checker.h"
#include "api/task_queue/pending_task_safety_flag.h"
#include "api/task_queue/task_queue_base.h"
#include "api/units/time_delta.h"
#include "rtc_base/buffer.h"
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"
#include "rtc_base/numerics/safe_conversions.h"
#include "rtc_base/openssl_adapter.h"
#include "rtc_base/openssl_digest.h"
#include "rtc_base/openssl_utility.h"
#include "rtc_base/ssl_certificate.h"
#include "rtc_base/ssl_identity.h"
#include "rtc_base/ssl_stream_adapter.h"
#include "rtc_base/stream.h"
#include "rtc_base/string_encode.h"
#include "rtc_base/task_utils/repeating_task.h"
#include "rtc_base/time_utils.h"

#ifdef OPENSSL_IS_BORINGSSL
#include <openssl/digest.h>
#include <openssl/dtls1.h>
#include <openssl/pool.h>
#include <openssl/ssl.h>

#include "rtc_base/boringssl_certificate.h"
#include "rtc_base/boringssl_identity.h"
#include "rtc_base/openssl.h"
#else
#include "rtc_base/openssl_identity.h"
#endif

#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
#error "webrtc requires at least OpenSSL version 1.1.0, to support DTLS-SRTP"
#endif

namespace {
// Value specified in RFC 5764.
constexpr absl::string_view kDtlsSrtpExporterLabel = "EXTRACTOR-dtls_srtp";
}  // namespace

namespace webrtc {
namespace {
// SRTP cipher suite table. `internal_name` is used to construct a
// colon-separated profile strings which is needed by
// SSL_CTX_set_tlsext_use_srtp().
struct SrtpCipherMapEntry {
  const char* internal_name;
  const int id;
};

// This isn't elegant, but it's better than an external reference
constexpr SrtpCipherMapEntry kSrtpCipherMap[] = {
    {.internal_name = "SRTP_AES128_CM_SHA1_80", .id = kSrtpAes128CmSha1_80},
    {.internal_name = "SRTP_AES128_CM_SHA1_32", .id = kSrtpAes128CmSha1_32},
    {.internal_name = "SRTP_AEAD_AES_128_GCM", .id = kSrtpAeadAes128Gcm},
    {.internal_name = "SRTP_AEAD_AES_256_GCM", .id = kSrtpAeadAes256Gcm}};

#ifdef OPENSSL_IS_BORINGSSL
// Enabled by EnableTimeCallbackForTesting. Should never be set in production
// code.
bool g_use_time_callback_for_testing = false;
// Not used in production code. Actual time should be relative to Jan 1, 1970.
void TimeCallbackForTesting(const SSL* ssl, struct timeval* out_clock) {
  int64_t time = TimeNanos();
  out_clock->tv_sec = time / kNumNanosecsPerSec;
  out_clock->tv_usec = (time % kNumNanosecsPerSec) / kNumNanosecsPerMicrosec;
}
#endif

uint16_t GetMaxVersion(SSLMode ssl_mode, SSLProtocolVersion version) {
  switch (ssl_mode) {
    case SSL_MODE_TLS:
      switch (version) {
        default:
        case SSL_PROTOCOL_NOT_GIVEN:
        case SSL_PROTOCOL_TLS_10:
        case SSL_PROTOCOL_TLS_11:
        case SSL_PROTOCOL_TLS_12:
          return TLS1_2_VERSION;
        case SSL_PROTOCOL_TLS_13:
#ifdef TLS1_3_VERSION
          return TLS1_3_VERSION;
#else
          return TLS1_2_VERSION;
#endif
      }
    case SSL_MODE_DTLS:
      switch (version) {
        default:
        case SSL_PROTOCOL_NOT_GIVEN:
        case SSL_PROTOCOL_DTLS_10:
        case SSL_PROTOCOL_DTLS_12:
          return DTLS1_2_VERSION;
        case SSL_PROTOCOL_DTLS_13:
#ifdef DTLS1_3_VERSION
          return DTLS1_3_VERSION;
#else
          return DTLS1_2_VERSION;
#endif
      }
  }
}

constexpr int kForceDtls13Off = 0;
#ifdef DTLS1_3_VERSION
constexpr int kForceDtls13Enabled = 1;
constexpr int kForceDtls13Only = 2;
#endif

int GetForceDtls13(const FieldTrialsView* field_trials) {
#ifdef DTLS1_3_VERSION
  if (field_trials) {
#if defined(WEBRTC_CHROMIUM_BUILD)
    if (field_trials->IsDisabled("WebRTC-ForceDtls13")) {
      RTC_LOG(LS_WARNING) << "WebRTC-ForceDtls13 Disabled";
      return kForceDtls13Off;
    }
#else
    if (field_trials->IsEnabled("WebRTC-ForceDtls13")) {
      RTC_LOG(LS_WARNING) << "WebRTC-ForceDtls13 Enabled";
      return kForceDtls13Enabled;
    }
#endif  // defined(WEBRTC_CHROMIUM_BUILD)
    if (field_trials->Lookup("WebRTC-ForceDtls13") == "Only") {
      RTC_LOG(LS_WARNING) << "WebRTC-ForceDtls13 Only";
      return kForceDtls13Only;
    }
  }
  // Default behavior:
#if defined(WEBRTC_CHROMIUM_BUILD)
  RTC_LOG(LS_WARNING) << "WebRTC-ForceDtls13 Enabled";
  return kForceDtls13Enabled;
#else
  RTC_LOG(LS_WARNING) << "WebRTC-ForceDtls13 Disabled";
  return kForceDtls13Off;
#endif  // defined(WEBRTC_CHROMIUM_BUILD)

#else
  return kForceDtls13Off;
#endif  // DTLS1_3_VERSION
}

#ifdef OPENSSL_IS_BORINGSSL
std::string GetOpenSslError() {
  std::string error;
  int64_t error_id;
  const char* error_file;
  int error_line;
  while ((error_id = ERR_get_error_line(&error_file, &error_line)) != 0) {
    char buf[ERR_ERROR_STRING_BUF_LEN];
    ERR_error_string_n(error_id, buf, sizeof(buf));
    absl::StrAppendFormat(&error, "\nOpenSSL error (file: %s, line: %d): %s",
                          error_file, error_line, buf);
  }
  return error;
}
#endif

//////////////////////////////////////////////////////////////////////
// StreamBIO
//////////////////////////////////////////////////////////////////////

int stream_write(BIO* h, const char* buf, int num);
int stream_read(BIO* h, char* buf, int size);
int stream_puts(BIO* h, const char* str);
long stream_ctrl(BIO* h, int cmd, long arg1, void* arg2);
int stream_new(BIO* h);
int stream_free(BIO* data);

BIO_METHOD* BIO_stream_method() {
  static BIO_METHOD* method = [] {
    BIO_METHOD* method = BIO_meth_new(BIO_TYPE_BIO, "stream");
    BIO_meth_set_write(method, stream_write);
    BIO_meth_set_read(method, stream_read);
    BIO_meth_set_puts(method, stream_puts);
    BIO_meth_set_ctrl(method, stream_ctrl);
    BIO_meth_set_create(method, stream_new);
    BIO_meth_set_destroy(method, stream_free);
    return method;
  }();
  return method;
}

BIO* BIO_new_stream(StreamInterface* stream) {
  BIO* ret = BIO_new(BIO_stream_method());
  if (ret == nullptr) {
    return nullptr;
  }
  BIO_set_data(ret, stream);
  return ret;
}

// bio methods return 1 (or at least non-zero) on success and 0 on failure.

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

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

int stream_read(BIO* b, char* out, int outl) {
  if (!out) {
    return -1;
  }
  StreamInterface* stream = static_cast<StreamInterface*>(BIO_get_data(b));
  BIO_clear_retry_flags(b);
  size_t read;
  int error;
  StreamResult result = stream->Read(
      std::span(reinterpret_cast<uint8_t*>(out), outl), read, error);
  if (result == SR_SUCCESS) {
    return checked_cast<int>(read);
  } else if (result == SR_BLOCK) {
    BIO_set_retry_read(b);
  }
  return -1;
}

int stream_write(BIO* b, const char* in, int inl) {
  if (!in) {
    return -1;
  }
  StreamInterface* stream = static_cast<StreamInterface*>(BIO_get_data(b));
  BIO_clear_retry_flags(b);
  size_t written;
  int error;
  StreamResult result = stream->Write(
      std::span(reinterpret_cast<const uint8_t*>(in), inl), written, error);
  if (result == SR_SUCCESS) {
    return checked_cast<int>(written);
  } else if (result == SR_BLOCK) {
    BIO_set_retry_write(b);
  }
  return -1;
}

int stream_puts(BIO* b, const char* str) {
  return stream_write(b, str, checked_cast<int>(strlen(str)));
}

long stream_ctrl(BIO* b, int cmd, long num, void* ptr) {
  switch (cmd) {
    case BIO_CTRL_RESET:
      return 0;
    case BIO_CTRL_EOF: {
      StreamInterface* stream = static_cast<StreamInterface*>(ptr);
      // 1 means end-of-stream.
      return (stream->GetState() == SS_CLOSED) ? 1 : 0;
    }
    case BIO_CTRL_WPENDING:
    case BIO_CTRL_PENDING:
      return 0;
    case BIO_CTRL_FLUSH: {
      // Flush signals the end of a flight of handshake packets.
      StreamInterface* stream = static_cast<StreamInterface*>(BIO_get_data(b));
      RTC_DCHECK(stream);
      if (stream->Flush()) {
        RTC_LOG(LS_WARNING) << "Failed to flush stream";
        return 0;
      }
      return 1;
    }
    case BIO_CTRL_DGRAM_QUERY_MTU:
      // openssl defaults to mtu=256 unless we return something here.
      // The handshake doesn't actually need to send packets above 1k,
      // so this seems like a sensible value that should work in most cases.
      // Webrtc uses the same value for video packets.
      RTC_DCHECK_NOTREACHED()
          << "We should be using SSL_set_mtu instead of this!";
      return 1200;
    default:
      return 0;
  }
}

}  // namespace

/////////////////////////////////////////////////////////////////////////////
// OpenSSLStreamAdapter
/////////////////////////////////////////////////////////////////////////////

OpenSSLStreamAdapter::OpenSSLStreamAdapter(
    std::unique_ptr<StreamInterface> stream,
    absl::AnyInvocable<void(SSLHandshakeError)> handshake_error,
    const FieldTrialsView* field_trials)
    : stream_(std::move(stream)),
      handshake_error_(std::move(handshake_error)),
      owner_(TaskQueueBase::Current()),
      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_DTLS),
      ssl_max_version_(SSL_PROTOCOL_DTLS_12),
      force_dtls_13_(GetForceDtls13(field_trials)),
      disable_ssl_group_ids_(field_trials && field_trials->IsEnabled(
                                                 "WebRTC-DisableSslGroupIds")) {
  stream_->SetEventCallback(
      [this](int events, int err) { OnEvent(events, err); });
}

OpenSSLStreamAdapter::~OpenSSLStreamAdapter() {
  timeout_task_.Stop();
  Cleanup(0);
}

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

SSLIdentity* OpenSSLStreamAdapter::GetIdentityForTesting() const {
  return identity_.get();
}

void OpenSSLStreamAdapter::SetServerRole(SSLRole role) {
  role_ = role;
}

SSLPeerCertificateDigestError OpenSSLStreamAdapter::SetPeerCertificateDigest(
    absl::string_view digest_alg,
    std::span<const uint8_t> digest_val) {
  RTC_DCHECK(!peer_certificate_verified_);
  RTC_DCHECK(!HasPeerCertificateDigest());
  size_t expected_len;

  if (!OpenSSLDigest::GetDigestSize(digest_alg, &expected_len)) {
    RTC_LOG(LS_WARNING) << "Unknown digest algorithm: " << digest_alg;
    return SSLPeerCertificateDigestError::UNKNOWN_ALGORITHM;
  }
  if (expected_len != digest_val.size()) {
    return SSLPeerCertificateDigestError::INVALID_LENGTH;
  }

  peer_certificate_digest_value_.SetData(digest_val);
  peer_certificate_digest_algorithm_ = std::string(digest_alg);

  if (!peer_cert_chain_) {
    // Normal case, where the digest is set before we obtain the certificate
    // from the handshake.
    return SSLPeerCertificateDigestError::NONE;
  }

  if (!VerifyPeerCertificate()) {
    Error("SetPeerCertificateDigest", -1, SSL_AD_BAD_CERTIFICATE, false);
    return SSLPeerCertificateDigestError::VERIFICATION_FAILED;
  }

  if (state_ == SSL_CONNECTED) {
    // Post the event asynchronously to unwind the stack. The caller
    // of ContinueSSL may be the same object listening for these
    // events and may not be prepared for reentrancy.
    PostEvent(SE_OPEN | SE_READ | SE_WRITE, 0);
  }
  return SSLPeerCertificateDigestError::NONE;
}

std::optional<absl::string_view> OpenSSLStreamAdapter::GetTlsCipherSuiteName()
    const {
  if (state_ != SSL_CONNECTED) {
    return std::nullopt;
  }

  const SSL_CIPHER* current_cipher = SSL_get_current_cipher(ssl_);
  return SSL_CIPHER_standard_name(current_cipher);
}

bool OpenSSLStreamAdapter::GetSslCipherSuite(int* cipher_suite) const {
  if (state_ != SSL_CONNECTED) {
    return false;
  }

  const SSL_CIPHER* current_cipher = SSL_get_current_cipher(ssl_);
  if (current_cipher == nullptr) {
    return false;
  }

  *cipher_suite = static_cast<uint16_t>(SSL_CIPHER_get_id(current_cipher));
  return true;
}

SSLProtocolVersion OpenSSLStreamAdapter::GetSslVersion() const {
  if (state_ != SSL_CONNECTED) {
    return SSL_PROTOCOL_NOT_GIVEN;
  }

  int ssl_version = SSL_version(ssl_);
  if (ssl_mode_ == SSL_MODE_DTLS) {
    if (ssl_version == DTLS1_VERSION) {
      return SSL_PROTOCOL_DTLS_10;
    } else if (ssl_version == DTLS1_2_VERSION) {
      return SSL_PROTOCOL_DTLS_12;
    }
#ifdef DTLS1_3_VERSION
    if (ssl_version == DTLS1_3_VERSION) {
      return SSL_PROTOCOL_DTLS_13;
    }
#endif
  } else {
    if (ssl_version == TLS1_VERSION) {
      return SSL_PROTOCOL_TLS_10;
    } else if (ssl_version == TLS1_1_VERSION) {
      return SSL_PROTOCOL_TLS_11;
    } else if (ssl_version == TLS1_2_VERSION) {
      return SSL_PROTOCOL_TLS_12;
    }
#ifdef TLS1_3_VERSION
    if (ssl_version == TLS1_3_VERSION) {
      return SSL_PROTOCOL_TLS_13;
    }
#endif
  }

  return SSL_PROTOCOL_NOT_GIVEN;
}

bool OpenSSLStreamAdapter::GetSslVersionBytes(int* version) const {
  if (state_ != SSL_CONNECTED) {
    return false;
  }
  *version = SSL_version(ssl_);
  return true;
}

uint16_t OpenSSLStreamAdapter::GetSslGroupId() const {
  if (state_ != SSL_CONNECTED) {
    return 0;
  }
#ifdef OPENSSL_IS_BORINGSSL
  return SSL_get_group_id(ssl_);
#else
  return 0;
#endif
}

bool OpenSSLStreamAdapter::ExportSrtpKeyingMaterial(
    ZeroOnFreeBuffer<uint8_t>& keying_material) {
  // Arguments are:
  // keying material/len -- a buffer to hold the keying material.
  // label               -- the exporter label.
  //                        part of the RFC defining each exporter
  //                        usage. We only use RFC 5764 for DTLS-SRTP.
  // context/context_len -- a context to bind to for this connection;
  // use_context            optional, can be null, 0 (IN). Not used by WebRTC.
  if (SSL_export_keying_material(
          ssl_, keying_material.data(), keying_material.size(),
          kDtlsSrtpExporterLabel.data(), kDtlsSrtpExporterLabel.size(), nullptr,
          0, false) != 1) {
    return false;
  }
  return true;
}

bool OpenSSLStreamAdapter::AppendSrtpKeyingMaterial(
    ZeroOnFreeBuffer<uint8_t>& key_buffer) {
  // Compute size of keying material.
  int selected_crypto_suite;
  if (!GetDtlsSrtpCryptoSuite(&selected_crypto_suite)) {
    RTC_LOG(LS_ERROR) << "No crypto suite";
    return false;
  }
  int key_len, salt_len;
  if (!GetSrtpKeyAndSaltLengths(selected_crypto_suite, &key_len, &salt_len)) {
    RTC_LOG(LS_ERROR) << "Unable to get key and salt len from crypto suite";
    return false;
  }
  int key_material_size = key_len * 2 + salt_len * 2;
  // Arguments are:
  // keying material/len -- a buffer to hold the keying material.
  // label               -- the exporter label.
  //                        part of the RFC defining each exporter
  //                        usage. We only use RFC 5764 for DTLS-SRTP.
  // context/context_len -- a context to bind to for this connection;
  // use_context            optional, can be null, 0 (IN). Not used by WebRTC.
  bool success = false;
  key_buffer.AppendData(
      key_material_size, [&](std::span<uint8_t> keying_material) -> size_t {
        int result = SSL_export_keying_material(
            ssl_, keying_material.data(), keying_material.size(),
            kDtlsSrtpExporterLabel.data(), kDtlsSrtpExporterLabel.size(),
            nullptr, 0, false);
        if (result != 0) {
          success = true;
          return keying_material.size();
        } else {
          return 0;  // Consider no data appended
        }
      });
  return success;
}

uint16_t OpenSSLStreamAdapter::GetPeerSignatureAlgorithm() const {
  if (state_ != SSL_CONNECTED) {
    return 0;
  }
#ifdef OPENSSL_IS_BORINGSSL
  return SSL_get_peer_signature_algorithm(ssl_);
#else
  return kSslSignatureAlgorithmUnknown;
#endif
}

bool OpenSSLStreamAdapter::SetDtlsSrtpCryptoSuites(
    const std::vector<int>& ciphers) {
  if (state_ != SSL_NONE) {
    return false;
  }

  std::string internal_ciphers;
  for (const int cipher : ciphers) {
    bool found = false;
    for (const auto& entry : kSrtpCipherMap) {
      if (cipher == entry.id) {
        found = true;
        if (!internal_ciphers.empty()) {
          internal_ciphers += ":";
        }
        internal_ciphers += entry.internal_name;
        break;
      }
    }

    if (!found) {
      RTC_LOG(LS_ERROR) << "Could not find cipher: " << cipher;
      return false;
    }
  }

  if (internal_ciphers.empty()) {
    return false;
  }

  srtp_ciphers_ = internal_ciphers;
  return true;
}

bool OpenSSLStreamAdapter::GetDtlsSrtpCryptoSuite(int* crypto_suite) const {
  RTC_DCHECK(state_ == SSL_CONNECTED);
  if (state_ != SSL_CONNECTED) {
    return false;
  }

  const SRTP_PROTECTION_PROFILE* srtp_profile =
      SSL_get_selected_srtp_profile(ssl_);

  if (!srtp_profile) {
    return false;
  }

  *crypto_suite = srtp_profile->id;
  RTC_DCHECK(!SrtpCryptoSuiteToName(*crypto_suite).empty());
  return true;
}

bool OpenSSLStreamAdapter::IsTlsConnected() {
  return state_ == SSL_CONNECTED;
}

int OpenSSLStreamAdapter::StartSSL() {
  // Don't allow StartSSL to be called twice.
  if (state_ != SSL_NONE) {
    return -1;
  }

  if (stream_->GetState() != SS_OPEN) {
    state_ = SSL_WAIT;
    return 0;
  }

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

  return 0;
}

void OpenSSLStreamAdapter::SetMode(SSLMode mode) {
  RTC_DCHECK(state_ == SSL_NONE);
  ssl_mode_ = mode;
}

void OpenSSLStreamAdapter::SetMaxProtocolVersion(SSLProtocolVersion version) {
  RTC_DCHECK(ssl_ctx_ == nullptr);
  ssl_max_version_ = version;
}

void OpenSSLStreamAdapter::SetInitialRetransmissionTimeout(int timeout_ms) {
  dtls_handshake_timeout_ms_ = timeout_ms;
#ifdef OPENSSL_IS_BORINGSSL
  if (ssl_ctx_ != nullptr && ssl_mode_ == SSL_MODE_DTLS) {
    DTLSv1_set_initial_timeout_duration(ssl_, dtls_handshake_timeout_ms_);
  }
#endif
}

void OpenSSLStreamAdapter::UpdateRetransmissionTimeout(int timeout_ms) {
  dtls_handshake_timeout_ms_ = timeout_ms;
#ifdef OPENSSL_IS_BORINGSSL
  if (ssl_ctx_ != nullptr && ssl_mode_ == SSL_MODE_DTLS) {
    DTLSv1_set_initial_timeout_duration(ssl_, dtls_handshake_timeout_ms_);
    // Clear the DTLS timer
    timeout_task_.Stop();
    MaybeSetTimeout();
  }
#endif
}

void OpenSSLStreamAdapter::SetMTU(int mtu) {
  dtls_mtu_ = mtu;
  if (ssl_) {
    RTC_CHECK(SSL_set_mtu(ssl_, dtls_mtu_)) << "Call to SSL_set_mtu failed.";
  }
}

//
// StreamInterface Implementation
//
StreamResult OpenSSLStreamAdapter::Write(std::span<const uint8_t> data,
                                         size_t& written,
                                         int& error) {
  RTC_DLOG(LS_VERBOSE) << "OpenSSLStreamAdapter::Write(" << data.size() << ")";

  switch (state_) {
    case SSL_NONE:
      // pass-through in clear text
      return stream_->Write(data, written, error);
    case SSL_WAIT:
    case SSL_CONNECTING:
      return SR_BLOCK;
    case SSL_CONNECTED:
      if (WaitingToVerifyPeerCertificate()) {
        return SR_BLOCK;
      }
      break;
    case SSL_ERROR:
    case SSL_CLOSED:
    default:
      error = ssl_error_code_;
      return SR_ERROR;
  }

  // OpenSSL will return an error if we try to write zero bytes
  if (data.empty()) {
    written = 0;
    return SR_SUCCESS;
  }

  ssl_write_needs_read_ = false;

  int code = SSL_write(ssl_, data.data(), checked_cast<int>(data.size()));
  int ssl_error = SSL_get_error(ssl_, code);
  MaybeSetTimeout();
  switch (ssl_error) {
    case SSL_ERROR_NONE:
      RTC_DLOG(LS_VERBOSE) << " -- success";
      RTC_DCHECK_GT(code, 0);
      RTC_DCHECK_LE(code, data.size());
      written = code;
      return SR_SUCCESS;
    case SSL_ERROR_WANT_READ:
      RTC_DLOG(LS_VERBOSE) << " -- error want read";
      ssl_write_needs_read_ = true;
      return SR_BLOCK;
    case SSL_ERROR_WANT_WRITE:
      RTC_DLOG(LS_VERBOSE) << " -- error want write";
      return SR_BLOCK;
    case SSL_ERROR_ZERO_RETURN:
    default:
      Error("SSL_write", (ssl_error ? ssl_error : -1), 0, false);
      error = ssl_error_code_;
      return SR_ERROR;
  }
  // not reached
}

StreamResult OpenSSLStreamAdapter::Read(std::span<uint8_t> data,
                                        size_t& read,
                                        int& error) {
  RTC_DLOG(LS_VERBOSE) << "OpenSSLStreamAdapter::Read(" << data.size() << ")";
  switch (state_) {
    case SSL_NONE:
      // pass-through in clear text
      return stream_->Read(data, read, error);
    case SSL_WAIT:
    case SSL_CONNECTING:
      return SR_BLOCK;
    case SSL_CONNECTED:
      if (WaitingToVerifyPeerCertificate()) {
        return SR_BLOCK;
      }
      break;
    case SSL_CLOSED:
      return SR_EOS;
    case SSL_ERROR:
    default:
      error = ssl_error_code_;
      return SR_ERROR;
  }

  // Don't trust OpenSSL with zero byte reads
  if (data.empty()) {
    read = 0;
    return SR_SUCCESS;
  }

  ssl_read_needs_write_ = false;

  const int code = SSL_read(ssl_, data.data(), checked_cast<int>(data.size()));
  const int ssl_error = SSL_get_error(ssl_, code);
  MaybeSetTimeout();

  switch (ssl_error) {
    case SSL_ERROR_NONE:
      RTC_DLOG(LS_VERBOSE) << " -- success";
      RTC_DCHECK_GT(code, 0);
      RTC_DCHECK_LE(code, data.size());
      read = code;

      if (ssl_mode_ == SSL_MODE_DTLS) {
        // Enforce atomic reads -- this is a short read
        unsigned int pending = SSL_pending(ssl_);

        if (pending) {
          RTC_DLOG(LS_INFO) << " -- short DTLS read. flushing";
          FlushInput(pending);
          error = SSE_MSG_TRUNC;
          return SR_ERROR;
        }
      }
      return SR_SUCCESS;
    case SSL_ERROR_WANT_READ:
      RTC_DLOG(LS_VERBOSE) << " -- error want read";
      return SR_BLOCK;
    case SSL_ERROR_WANT_WRITE:
      RTC_DLOG(LS_VERBOSE) << " -- error want write";
      ssl_read_needs_write_ = true;
      return SR_BLOCK;
    case SSL_ERROR_ZERO_RETURN:
      RTC_DLOG(LS_VERBOSE) << " -- remote side closed";
      Close();
      return SR_EOS;
    default:
      Error("SSL_read", (ssl_error ? ssl_error : -1), 0, false);
      error = ssl_error_code_;
      return SR_ERROR;
  }
  // not reached
}

void OpenSSLStreamAdapter::FlushInput(unsigned int left) {
  unsigned char buf[2048];

  while (left) {
    // This should always succeed
    const int toread = (sizeof(buf) < left) ? sizeof(buf) : left;
    const int code = SSL_read(ssl_, buf, toread);
    const int ssl_error = SSL_get_error(ssl_, code);
    RTC_DCHECK(ssl_error == SSL_ERROR_NONE);

    MaybeSetTimeout();

    if (ssl_error != SSL_ERROR_NONE) {
      RTC_DLOG(LS_VERBOSE) << " -- error " << code;
      Error("SSL_read", (ssl_error ? ssl_error : -1), 0, false);
      return;
    }

    RTC_DLOG(LS_VERBOSE) << " -- flushed " << code << " bytes";
    left -= code;
  }
}

void OpenSSLStreamAdapter::Close() {
  Cleanup(0);
  RTC_DCHECK(state_ == SSL_CLOSED || state_ == SSL_ERROR);
  // When we're closed at SSL layer, also close the stream level which
  // performs necessary clean up. Otherwise, a new incoming packet after
  // this could overflow the stream buffer.
  stream_->Close();
}

StreamState OpenSSLStreamAdapter::GetState() const {
  switch (state_) {
    case SSL_WAIT:
    case SSL_CONNECTING:
      return SS_OPENING;
    case SSL_CONNECTED:
      if (WaitingToVerifyPeerCertificate()) {
        return SS_OPENING;
      }
      return SS_OPEN;
    default:
      return SS_CLOSED;
  }
  // not reached
}

void OpenSSLStreamAdapter::OnEvent(int events, int err) {
  RTC_DCHECK_RUN_ON(&callback_sequence_);
  int events_to_signal = 0;
  int signal_error = 0;

  if ((events & SE_OPEN)) {
    RTC_DLOG(LS_VERBOSE) << "OpenSSLStreamAdapter::OnEvent SE_OPEN";
    if (state_ != SSL_WAIT) {
      RTC_DCHECK(state_ == SSL_NONE);
      events_to_signal |= SE_OPEN;
    } else {
      state_ = SSL_CONNECTING;
      if (int error = BeginSSL()) {
        Error("BeginSSL", error, 0, true);
        return;
      }
    }
  }

  if ((events & (SE_READ | SE_WRITE))) {
    RTC_DLOG(LS_VERBOSE) << "OpenSSLStreamAdapter::OnEvent"
                         << ((events & SE_READ) ? " SE_READ" : "")
                         << ((events & SE_WRITE) ? " SE_WRITE" : "");
    if (state_ == SSL_NONE) {
      events_to_signal |= events & (SE_READ | SE_WRITE);
    } else if (state_ == SSL_CONNECTING) {
      if (int error = ContinueSSL()) {
        Error("ContinueSSL", error, 0, true);
        return;
      }
    } else if (state_ == SSL_CONNECTED) {
      if (((events & SE_READ) && ssl_write_needs_read_) ||
          (events & SE_WRITE)) {
        RTC_DLOG(LS_VERBOSE) << " -- onStreamWriteable";
        events_to_signal |= SE_WRITE;
      }
      if (((events & SE_WRITE) && ssl_read_needs_write_) ||
          (events & SE_READ)) {
        RTC_DLOG(LS_VERBOSE) << " -- onStreamReadable";
        events_to_signal |= SE_READ;
      }
    }
  }

  if ((events & SE_CLOSE)) {
    RTC_DLOG(LS_VERBOSE) << "OpenSSLStreamAdapter::OnEvent(SE_CLOSE, " << err
                         << ")";
    Cleanup(0);
    events_to_signal |= SE_CLOSE;
    // SE_CLOSE is the only event that uses the final parameter to OnEvent().
    RTC_DCHECK(signal_error == 0);
    signal_error = err;
  }

  if (events_to_signal) {
    // Note that the adapter presents itself as the origin of the stream events,
    // since users of the adapter may not recognize the adapted object.
    FireEvent(events_to_signal, signal_error);
  }
}

void OpenSSLStreamAdapter::PostEvent(int events, int err) {
  owner_->PostTask(SafeTask(task_safety_.flag(), [this, events, err]() {
    RTC_DCHECK_RUN_ON(&callback_sequence_);
    FireEvent(events, err);
  }));
}

void OpenSSLStreamAdapter::SetTimeout(int delay_ms) {
  // We need to accept 0 delay here as well as >0 delay, because
  // DTLSv1_get_timeout seems to frequently return 0 ms.
  RTC_DCHECK_GE(delay_ms, 0);
  RTC_DCHECK(!timeout_task_.Running());

  timeout_task_ = RepeatingTaskHandle::DelayedStart(
      owner_, TimeDelta::Millis(delay_ms),
      [flag = task_safety_.flag(), this]() {
        if (flag->alive()) {
          RTC_DLOG(LS_INFO) << "DTLS timeout expired";
          timeout_task_.Stop();
          int res = DTLSv1_handle_timeout(ssl_);
          if (res > 0) {
            retransmission_count_++;
            RTC_LOG(LS_INFO) << "DTLS retransmission";
          } else if (res < 0) {
            RTC_LOG(LS_INFO) << "DTLSv1_handle_timeout() return -1";
            Error("DTLSv1_handle_timeout", res, -1, true);
            return TimeDelta::PlusInfinity();
          }
          // We check the timer even after SSL_CONNECTED,
          // but ContinueSSL() is only needed when SSL_CONNECTING
          if (state_ == SSL_CONNECTING) {
            // Note: timeout is set inside ContinueSSL()
            ContinueSSL();
          } else if (state_ == SSL_CONNECTED) {
            MaybeSetTimeout();
          } else {
            RTC_DCHECK_NOTREACHED() << "state_: " << state_;
          }
        } else {
          RTC_DCHECK_NOTREACHED() << "flag->alive() == false";
        }
        // This callback will never run again (stopped above).
        return TimeDelta::PlusInfinity();
      });
}

int OpenSSLStreamAdapter::BeginSSL() {
  RTC_DCHECK(state_ == SSL_CONNECTING);
  // The underlying stream has opened.
  RTC_DLOG(LS_INFO) << "BeginSSL with peer.";

  BIO* bio = nullptr;

  // First set up the context.
  RTC_DCHECK(ssl_ctx_ == nullptr);
  ssl_ctx_ = SetupSSLContext();
  if (!ssl_ctx_) {
    return -1;
  }

  bio = BIO_new_stream(stream_.get());
  if (!bio) {
    return -1;
  }

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

  SSL_set_app_data(ssl_, this);

  SSL_set_bio(ssl_, bio, bio);  // the SSL object owns the bio now.

  // Use SSL_set_mtu to configure MTU insted of
  // BIO_CTRL_DGRAM_QUERY_MTU
  SSL_set_options(ssl_, SSL_OP_NO_QUERY_MTU);
  SSL_set_mtu(ssl_, dtls_mtu_);

#ifdef OPENSSL_IS_BORINGSSL
  if (ssl_mode_ == SSL_MODE_DTLS) {
    DTLSv1_set_initial_timeout_duration(ssl_, dtls_handshake_timeout_ms_);
  }

  if (!disable_ssl_group_ids_) {
    if (!SSL_set1_group_ids(ssl_, ssl_cipher_groups_.data(),
                            ssl_cipher_groups_.size())) {
      RTC_LOG(LS_WARNING) << "Failed to call SSL_set1_group_ids.";
      return -1;
    }
  }
#endif

  SSL_set_mode(ssl_, SSL_MODE_ENABLE_PARTIAL_WRITE |
                         SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);

  // Do the connect
  return ContinueSSL();
}

int OpenSSLStreamAdapter::ContinueSSL() {
  RTC_DCHECK_RUN_ON(&callback_sequence_);
  RTC_DLOG(LS_VERBOSE) << "ContinueSSL";
  RTC_DCHECK_EQ(state_, SSL_CONNECTING);

  // Clear the DTLS timer
  timeout_task_.Stop();

  const int code = (role_ == SSL_CLIENT) ? SSL_connect(ssl_) : SSL_accept(ssl_);
  const int ssl_error = SSL_get_error(ssl_, code);

  switch (ssl_error) {
    case SSL_ERROR_NONE:
      RTC_DLOG(LS_INFO) << " -- success";
      // By this point, OpenSSL should have given us a certificate, or errored
      // out if one was missing.
      RTC_DCHECK(peer_cert_chain_ || !GetClientAuthEnabled());

      state_ = SSL_CONNECTED;
      if (!WaitingToVerifyPeerCertificate()) {
        // We have everything we need to start the connection, so signal
        // SE_OPEN. If we need a client certificate fingerprint and don't have
        // it yet, we'll instead signal SE_OPEN in SetPeerCertificateDigest.
        //
        // TODO(deadbeef): Post this event asynchronously to unwind the stack.
        // The caller of ContinueSSL may be the same object listening for these
        // events and may not be prepared for reentrancy.
        // PostEvent(SE_OPEN | SE_READ | SE_WRITE, 0);
        FireEvent(SE_OPEN | SE_READ | SE_WRITE, 0);
      }
      break;
    case SSL_ERROR_WANT_READ:
      RTC_DLOG(LS_INFO) << " -- error when we want to read";
      break;
    case SSL_ERROR_WANT_WRITE:
      RTC_DLOG(LS_INFO) << " -- error when we want to write";
      break;
    case SSL_ERROR_ZERO_RETURN:
    default: {
      SSLHandshakeError ssl_handshake_err = SSLHandshakeError::UNKNOWN;
      int err_code = ERR_peek_last_error();
      if (err_code != 0 && ERR_GET_REASON(err_code) == SSL_R_NO_SHARED_CIPHER) {
        ssl_handshake_err = SSLHandshakeError::INCOMPATIBLE_CIPHERSUITE;
      }
      RTC_DLOG(LS_VERBOSE) << " -- error " << code << ", " << err_code << ", "
                           << ERR_GET_REASON(err_code);
      if (handshake_error_) {
        handshake_error_(ssl_handshake_err);
      }
      return (ssl_error != 0) ? ssl_error : -1;
    }
  }

  MaybeSetTimeout();

  return 0;
}

void OpenSSLStreamAdapter::MaybeSetTimeout() {
  if (ssl_ != nullptr && !timeout_task_.Running()) {
    struct timeval timeout;
    if (DTLSv1_get_timeout(ssl_, &timeout)) {
      int delay = timeout.tv_sec * 1000 + timeout.tv_usec / 1000;
      SetTimeout(delay);
    }
  }
}

void OpenSSLStreamAdapter::Error(absl::string_view context,
                                 int err,
                                 uint8_t alert,
                                 bool signal) {
  RTC_DCHECK_RUN_ON(&callback_sequence_);
  RTC_LOG(LS_WARNING) << "OpenSSLStreamAdapter::Error(" << context << ", "
                      << err << ", " << static_cast<int>(alert) << ")";
#ifdef OPENSSL_IS_BORINGSSL
  if (err == SSL_ERROR_SSL) {
    RTC_LOG(LS_WARNING) << "GetOpenSslError: " << GetOpenSslError();
  }
#endif
  state_ = SSL_ERROR;
  ssl_error_code_ = err;
  Cleanup(alert);
  if (signal) {
    FireEvent(SE_CLOSE, err);
  }
}

void OpenSSLStreamAdapter::Cleanup(uint8_t alert) {
  RTC_DLOG(LS_INFO) << "Cleanup";

  if (state_ != SSL_ERROR) {
    state_ = SSL_CLOSED;
    ssl_error_code_ = 0;
  }

  if (ssl_) {
    int ret;
// SSL_send_fatal_alert is only available in BoringSSL.
#ifdef OPENSSL_IS_BORINGSSL
    if (alert) {
      ret = SSL_send_fatal_alert(ssl_, alert);
      if (ret < 0) {
        RTC_LOG(LS_WARNING) << "SSL_send_fatal_alert failed, error = "
                            << SSL_get_error(ssl_, ret);
      }
    } else {
#endif
      ret = SSL_shutdown(ssl_);
      if (ret < 0) {
        RTC_LOG(LS_WARNING)
            << "SSL_shutdown failed, error = " << SSL_get_error(ssl_, ret);
      }
#ifdef OPENSSL_IS_BORINGSSL
    }
#endif
    SSL_free(ssl_);
    ssl_ = nullptr;
  }
  if (ssl_ctx_) {
    SSL_CTX_free(ssl_ctx_);
    ssl_ctx_ = nullptr;
  }
  identity_.reset();
  peer_cert_chain_.reset();

  // Clear the DTLS timer
  timeout_task_.Stop();
}

SSL_CTX* OpenSSLStreamAdapter::SetupSSLContext() {
#ifdef OPENSSL_IS_BORINGSSL
  // If X509 objects aren't used, we can use these methods to avoid
  // linking the sizable crypto/x509 code, using CRYPTO_BUFFER instead.
  SSL_CTX* ctx =
      SSL_CTX_new(ssl_mode_ == SSL_MODE_DTLS ? DTLS_with_buffers_method()
                                             : TLS_with_buffers_method());
#else
  SSL_CTX* ctx =
      SSL_CTX_new(ssl_mode_ == SSL_MODE_DTLS ? DTLS_method() : TLS_method());
#endif
  if (ctx == nullptr) {
    return nullptr;
  }

  auto min_version =
      ssl_mode_ == SSL_MODE_DTLS ? DTLS1_2_VERSION : TLS1_2_VERSION;
  auto max_version = GetMaxVersion(ssl_mode_, ssl_max_version_);
#ifdef DTLS1_3_VERSION
  if (force_dtls_13_ == kForceDtls13Enabled) {
    max_version = DTLS1_3_VERSION;
  } else if (force_dtls_13_ == kForceDtls13Only) {
    min_version = DTLS1_3_VERSION;
    max_version = DTLS1_3_VERSION;
  }
#endif

  SSL_CTX_set_min_proto_version(ctx, min_version);
  SSL_CTX_set_max_proto_version(ctx, max_version);

#ifdef OPENSSL_IS_BORINGSSL
  // SSL_CTX_set_current_time_cb is only supported in BoringSSL.
  if (g_use_time_callback_for_testing) {
    SSL_CTX_set_current_time_cb(ctx, &TimeCallbackForTesting);
  }
  SSL_CTX_set0_buffer_pool(ctx, openssl::GetBufferPool());
#endif

  if (identity_ && !identity_->ConfigureIdentity(ctx)) {
    SSL_CTX_free(ctx);
    return nullptr;
  }

  // TODO(bugs.webrtc.org/339300437): Remove dependency.
  SSL_CTX_set_info_callback(ctx, OpenSSLAdapter::SSLInfoCallback);

  int mode = SSL_VERIFY_PEER;
  if (GetClientAuthEnabled()) {
    // Require a certificate from the client.
    // Note: Normally this is always true in production, but it may be disabled
    // for testing purposes (e.g. SSLAdapter unit tests).
    mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
  }

  // Configure a custom certificate verification callback to check the peer
  // certificate digest.
#ifdef OPENSSL_IS_BORINGSSL
  // Use CRYPTO_BUFFER version of the callback if building with BoringSSL.
  SSL_CTX_set_custom_verify(ctx, mode, SSLVerifyCallback);
#else
  // Note the second argument to SSL_CTX_set_verify is to override individual
  // errors in the default verification logic, which is not what we want here.
  SSL_CTX_set_verify(ctx, mode, nullptr);
  SSL_CTX_set_cert_verify_callback(ctx, SSLVerifyCallback, nullptr);
#endif

  // Select list of available ciphers. Note that !SHA256 and !SHA384 only
  // remove HMAC-SHA256 and HMAC-SHA384 cipher suites, not GCM cipher suites
  // with SHA256 or SHA384 as the handshake hash.
  // This matches the list of SSLClientSocketImpl in Chromium.
  SSL_CTX_set_cipher_list(
      ctx,
      "DEFAULT:!NULL:!aNULL:!SHA256:!SHA384:!aECDH:!AESGCM+AES256:!aPSK:!3DES");

  if (!srtp_ciphers_.empty()) {
    if (SSL_CTX_set_tlsext_use_srtp(ctx, srtp_ciphers_.c_str())) {
      SSL_CTX_free(ctx);
      return nullptr;
    }
  }

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

#if defined(OPENSSL_IS_BORINGSSL) || (OPENSSL_VERSION_NUMBER >= 0x30000000L)
  SSL_CTX_set_options(ctx, SSL_OP_NO_TICKET);
#endif

  return ctx;
}

bool OpenSSLStreamAdapter::VerifyPeerCertificate() {
  if (!HasPeerCertificateDigest() || !peer_cert_chain_ ||
      !peer_cert_chain_->GetSize()) {
    RTC_LOG(LS_WARNING) << "Missing digest or peer certificate.";
    return false;
  }

  Buffer computed_digest = Buffer::CreateWithCapacity(EVP_MAX_MD_SIZE);
  if (!peer_cert_chain_->Get(0).ComputeDigest(
          peer_certificate_digest_algorithm_, computed_digest)) {
    RTC_LOG(LS_WARNING) << "Failed to compute peer cert digest.";
    return false;
  }

  if (computed_digest != peer_certificate_digest_value_) {
    RTC_LOG(LS_WARNING)
        << "Rejected peer certificate due to mismatched digest using "
        << peer_certificate_digest_algorithm_ << ". Expected "
        << hex_encode_with_delimiter(peer_certificate_digest_value_, ':')
        << " got " << hex_encode_with_delimiter(computed_digest, ':');
    return false;
  }
  // Ignore any verification error if the digest matches, since there is no
  // value in checking the validity of a self-signed cert issued by untrusted
  // sources.
  RTC_DLOG(LS_INFO) << "Accepted peer certificate.";
  peer_certificate_verified_ = true;
  return true;
}

std::unique_ptr<SSLCertChain> OpenSSLStreamAdapter::GetPeerSSLCertChain()
    const {
  return peer_cert_chain_ ? peer_cert_chain_->Clone() : nullptr;
}

#ifdef OPENSSL_IS_BORINGSSL
enum ssl_verify_result_t OpenSSLStreamAdapter::SSLVerifyCallback(
    SSL* ssl,
    uint8_t* out_alert) {
  // Get our OpenSSLStreamAdapter from the context.
  OpenSSLStreamAdapter* stream =
      reinterpret_cast<OpenSSLStreamAdapter*>(SSL_get_app_data(ssl));
  const STACK_OF(CRYPTO_BUFFER)* chain = SSL_get0_peer_certificates(ssl);
  // Creates certificate chain.
  std::vector<std::unique_ptr<SSLCertificate>> cert_chain;
  for (CRYPTO_BUFFER* cert : chain) {
    cert_chain.emplace_back(new BoringSSLCertificate(bssl::UpRef(cert)));
  }
  stream->peer_cert_chain_.reset(new SSLCertChain(std::move(cert_chain)));

  // If the peer certificate digest isn't known yet, we'll wait to verify
  // until it's known, and for now just return a success status.
  if (stream->peer_certificate_digest_algorithm_.empty()) {
    RTC_LOG(LS_INFO) << "Waiting to verify certificate until digest is known.";
    // TODO(deadbeef): Use ssl_verify_retry?
    return ssl_verify_ok;
  }

  if (!stream->VerifyPeerCertificate()) {
    return ssl_verify_invalid;
  }

  return ssl_verify_ok;
}
#else   // OPENSSL_IS_BORINGSSL
int OpenSSLStreamAdapter::SSLVerifyCallback(X509_STORE_CTX* store, void* arg) {
  // Get our SSL structure and OpenSSLStreamAdapter from the store.
  SSL* ssl = reinterpret_cast<SSL*>(
      X509_STORE_CTX_get_ex_data(store, SSL_get_ex_data_X509_STORE_CTX_idx()));
  OpenSSLStreamAdapter* stream =
      reinterpret_cast<OpenSSLStreamAdapter*>(SSL_get_app_data(ssl));

  // Record the peer's certificate.
  X509* cert = X509_STORE_CTX_get0_cert(store);
  stream->peer_cert_chain_.reset(
      new SSLCertChain(std::make_unique<OpenSSLCertificate>(cert)));

  // If the peer certificate digest isn't known yet, we'll wait to verify
  // until it's known, and for now just return a success status.
  if (stream->peer_certificate_digest_algorithm_.empty()) {
    RTC_DLOG(LS_INFO) << "Waiting to verify certificate until digest is known.";
    return 1;
  }

  if (!stream->VerifyPeerCertificate()) {
    X509_STORE_CTX_set_error(store, X509_V_ERR_CERT_REJECTED);
    return 0;
  }

  return 1;
}
#endif  // !OPENSSL_IS_BORINGSSL

bool OpenSSLStreamAdapter::IsBoringSsl() {
#ifdef OPENSSL_IS_BORINGSSL
  return true;
#else
  return false;
#endif
}

#define CDEF(X) \
  { static_cast<uint16_t>(TLS1_CK_##X & 0xffff), "TLS_" #X }

struct cipher_list {
  uint16_t cipher;
  const char* cipher_str;
};

// TODO(torbjorng): Perhaps add more cipher suites to these lists.
static const cipher_list OK_RSA_ciphers[] = {
    CDEF(ECDHE_RSA_WITH_AES_128_CBC_SHA),
    CDEF(ECDHE_RSA_WITH_AES_256_CBC_SHA),
    CDEF(ECDHE_RSA_WITH_AES_128_GCM_SHA256),
#ifdef TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA256
    CDEF(ECDHE_RSA_WITH_AES_256_GCM_SHA256),
#endif
#ifdef TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256  // BoringSSL.
    CDEF(ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256),
#elif defined(TLS1_RFC_ECDHE_ECDSA_WITH_CHACHA20_POLY1305)  // OpenSSL.
    CDEF(ECDHE_RSA_WITH_CHACHA20_POLY1305),
#endif
};

static const cipher_list OK_ECDSA_ciphers[] = {
    CDEF(ECDHE_ECDSA_WITH_AES_128_CBC_SHA),
    CDEF(ECDHE_ECDSA_WITH_AES_256_CBC_SHA),
    CDEF(ECDHE_ECDSA_WITH_AES_128_GCM_SHA256),
#ifdef TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA256
    CDEF(ECDHE_ECDSA_WITH_AES_256_GCM_SHA256),
#endif
#ifdef TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256  // BoringSSL.
    CDEF(ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256),
#elif defined(TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305)  // OpenSSL.
    CDEF(ECDHE_ECDSA_WITH_CHACHA20_POLY1305),
#endif
};
#undef CDEF

static const cipher_list OK_DTLS13_ciphers[] = {
#ifdef TLS1_3_CK_AES_128_GCM_SHA256  // BoringSSL TLS 1.3
    {.cipher = static_cast<uint16_t>(TLS1_3_CK_AES_128_GCM_SHA256 & 0xffff),
     .cipher_str = "TLS_AES_128_GCM_SHA256"},
#endif
#ifdef TLS1_3_CK_AES_256_GCM_SHA256  // BoringSSL TLS 1.3
    {static_cast<uint16_t>(TLS1_3_CK_AES_256_GCM_SHA256 & 0xffff),
     "TLS_AES_256_GCM_SHA256"},
#endif
#ifdef TLS1_3_CK_CHACHA20_POLY1305_SHA256  // BoringSSL TLS 1.3
    {.cipher =
         static_cast<uint16_t>(TLS1_3_CK_CHACHA20_POLY1305_SHA256 & 0xffff),
     .cipher_str = "TLS_CHACHA20_POLY1305_SHA256"},
#endif
};

bool OpenSSLStreamAdapter::IsAcceptableCipher(int cipher, KeyType key_type) {
  if (key_type == KT_RSA) {
    for (const cipher_list& c : OK_RSA_ciphers) {
      if (cipher == c.cipher) {
        return true;
      }
    }
  }

  if (key_type == KT_ECDSA) {
    for (const cipher_list& c : OK_ECDSA_ciphers) {
      if (cipher == c.cipher) {
        return true;
      }
    }
  }

  for (const cipher_list& c : OK_DTLS13_ciphers) {
    if (cipher == c.cipher) {
      return true;
    }
  }

  return false;
}

bool OpenSSLStreamAdapter::IsAcceptableCipher(absl::string_view cipher,
                                              KeyType key_type) {
  if (key_type == KT_RSA) {
    for (const cipher_list& c : OK_RSA_ciphers) {
      if (cipher == c.cipher_str) {
        return true;
      }
    }
  }

  if (key_type == KT_ECDSA) {
    for (const cipher_list& c : OK_ECDSA_ciphers) {
      if (cipher == c.cipher_str) {
        return true;
      }
    }
  }

  for (const cipher_list& c : OK_DTLS13_ciphers) {
    if (cipher == c.cipher_str) {
      return true;
    }
  }

  return false;
}

void OpenSSLStreamAdapter::EnableTimeCallbackForTesting() {
#ifdef OPENSSL_IS_BORINGSSL
  g_use_time_callback_for_testing = true;
#endif
}

SSLProtocolVersion OpenSSLStreamAdapter::GetMaxSupportedDTLSProtocolVersion() {
#if defined(OPENSSL_IS_BORINGSSL) && defined(DTLS1_3_VERSION)
  return SSL_PROTOCOL_DTLS_13;
#else
  return SSL_PROTOCOL_DTLS_12;
#endif
}

bool OpenSSLStreamAdapter::SetSslGroupIds(const std::vector<uint16_t>& groups) {
  if (state_ != SSL_NONE) {
    return false;
  }
  ssl_cipher_groups_ = groups;
  return true;
}

}  // namespace webrtc
