/*
 *  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 <string>
#include <utility>
#include <vector>

#include "absl/functional/any_invocable.h"
#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "api/field_trials_view.h"
#include "api/sequence_checker.h"
#include "api/task_queue/pending_task_safety_flag.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/thread.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[] = {
    {"SRTP_AES128_CM_SHA1_80", kSrtpAes128CmSha1_80},
    {"SRTP_AES128_CM_SHA1_32", kSrtpAes128CmSha1_32},
    {"SRTP_AEAD_AES_128_GCM", kSrtpAeadAes128Gcm},
    {"SRTP_AEAD_AES_256_GCM", 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) {
  if (field_trials == nullptr) {
    return kForceDtls13Off;
  }
#ifdef DTLS1_3_VERSION
  if (field_trials->IsEnabled("WebRTC-ForceDtls13")) {
    RTC_LOG(LS_WARNING) << "WebRTC-ForceDtls13 Enabled";
    return kForceDtls13Enabled;
  }
  if (field_trials->Lookup("WebRTC-ForceDtls13") == "Only") {
    RTC_LOG(LS_WARNING) << "WebRTC-ForceDtls13 Only";
    return kForceDtls13Only;
  }
  RTC_LOG(LS_WARNING) << "WebRTC-ForceDtls13 Disabled";
#endif
  return kForceDtls13Off;
}

}  // namespace

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

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

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

static 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.

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

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

static 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(
      MakeArrayView(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;
}

static 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(
      MakeArrayView(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;
}

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

static 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: {
      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;
  }
}

/////////////////////////////////////////////////////////////////////////////
// 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_(Thread::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,
    ArrayView<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;
}

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) {
    // TODO (jonaso, webrtc:367395350): Switch to upcoming
    // DTLSv1_set_timeout_duration.
    DTLSv1_set_initial_timeout_duration(ssl_, dtls_handshake_timeout_ms_);
  }
#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(ArrayView<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.size() == 0) {
    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);
  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(ArrayView<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.size() == 0) {
    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);

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

    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) {
            ContinueSSL();
          }
        } else {
          RTC_DCHECK_NOTREACHED();
        }
        // 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;
    }
  }

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

  return 0;
}

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) << ")";
  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(0, 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
    {static_cast<uint16_t>(TLS1_3_CK_AES_128_GCM_SHA256 & 0xffff),
     "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
    {static_cast<uint16_t>(TLS1_3_CK_CHACHA20_POLY1305_SHA256 & 0xffff),
     "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
