DTLS 1.3 - patch 4

This patchs adds a field trial for enabling DTLS1.3, WebRTC-ForceDtls13
- "Enabled" set max version to DTLS1.3
- "Only" set min & max version to DTLS1.3

Wireup a FieldTrialsView so that this does not
use the global string.

Also convert the WebRTC-DisableTlsSessionTicketKillswitch
from global string to FieldTrialsView.

BUG=webrtc:383141571

Change-Id: Ia775efc1dcbffd01bfddb6030490438cb8de89d7
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/372261
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Jonas Oreland <jonaso@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#43616}
This commit is contained in:
Jonas Oreland 2024-12-19 15:15:50 +01:00 committed by WebRTC LUCI CQ
parent b3e94fd0df
commit 12574a315f
11 changed files with 72 additions and 13 deletions

View File

@ -83,6 +83,9 @@ ACTIVE_FIELD_TRIALS: FrozenSet[FieldTrial] = frozenset([
FieldTrial('WebRTC-EncoderDataDumpDirectory',
296242528,
date(2024, 4, 1)),
FieldTrial('WebRTC-ForceDtls13',
383141571,
date(2024,9,1)),
FieldTrial('WebRTC-FrameCadenceAdapter-UseVideoFrameTimestamp',
42226256,
date(2024, 10, 1)),

View File

@ -395,6 +395,10 @@ class RTC_EXPORT IceTransportInternal : public rtc::PacketTransportInternal {
dictionary_writer_synced_callback_list_.RemoveReceivers(tag);
}
virtual const webrtc::FieldTrialsView* field_trials() const {
return nullptr;
}
protected:
void SendGatheringStateEvent() {
gathering_state_callback_list_.Send(this);

View File

@ -199,7 +199,8 @@ P2PTransportChannel::P2PTransportChannel(
STRONG_AND_STABLE_WRITABLE_CONNECTION_PING_INTERVAL,
true /* presume_writable_when_fully_relayed */,
REGATHER_ON_FAILED_NETWORKS_INTERVAL,
RECEIVING_SWITCHING_DELAY) {
RECEIVING_SWITCHING_DELAY),
field_trials_(field_trials) {
TRACE_EVENT0("webrtc", "P2PTransportChannel::P2PTransportChannel");
RTC_DCHECK(allocator_ != nullptr);
// Validate IceConfig even for mostly built-in constant default values in case

View File

@ -248,6 +248,10 @@ class RTC_EXPORT P2PTransportChannel : public IceTransportInternal,
return stun_dict_writer_;
}
const webrtc::FieldTrialsView* field_trials() const override {
return field_trials_;
}
private:
P2PTransportChannel(
absl::string_view transport_name,
@ -503,6 +507,8 @@ class RTC_EXPORT P2PTransportChannel : public IceTransportInternal,
// Parsed field trials.
IceFieldTrials ice_field_trials_;
// Unparsed field trials.
const webrtc::FieldTrialsView* field_trials_;
// A dictionary of attributes that will be reflected to peer.
StunDictionaryWriter stun_dict_writer_;

View File

@ -363,7 +363,8 @@ bool DtlsTransport::SetupDtls() {
dtls_ = rtc::SSLStreamAdapter::Create(
std::move(downward),
[this](rtc::SSLHandshakeError error) { OnDtlsHandshakeError(error); });
[this](rtc::SSLHandshakeError error) { OnDtlsHandshakeError(error); },
ice_transport_->field_trials());
if (!dtls_) {
RTC_LOG(LS_ERROR) << ToString() << ": Failed to create DTLS adapter.";
return false;

View File

@ -1606,10 +1606,10 @@ rtc_library("ssl_adapter") {
":threading",
":timeutils",
"../api:array_view",
"../api:field_trials_view",
"../api:sequence_checker",
"../api/task_queue:pending_task_safety_flag",
"../api/units:time_delta",
"../system_wrappers:field_trial",
"system:rtc_export",
"task_utils:repeating_task",
"//third_party/abseil-cpp/absl/functional:any_invocable",

View File

@ -63,7 +63,6 @@
#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

View File

@ -58,7 +58,6 @@
#include "rtc_base/string_encode.h"
#include "rtc_base/thread.h"
#include "rtc_base/time_utils.h"
#include "system_wrappers/include/field_trial.h"
#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
#error "webrtc requires at least OpenSSL version 1.1.0, to support DTLS-SRTP"
@ -140,6 +139,28 @@ uint16_t GetMaxVersion(SSLMode ssl_mode, SSLProtocolVersion version) {
}
}
constexpr int kForceDtls13Off = 0;
#ifdef DTLS1_3_VERSION
constexpr int kForceDtls13Enabled = 1;
constexpr int kForceDtls13Only = 2;
#endif
int GetForceDtls13(const webrtc::FieldTrialsView* field_trials) {
if (field_trials == nullptr) {
return kForceDtls13Off;
}
#ifdef DTLS1_3_VERSION
auto mode = field_trials->Lookup("WebRTC-ForceDtls13");
RTC_LOG(LS_WARNING) << "WebRTC-ForceDtls13: " << mode;
if (mode == "Enabled") {
return kForceDtls13Enabled;
} else if (mode == "Only") {
return kForceDtls13Only;
}
#endif
return kForceDtls13Off;
}
} // namespace
//////////////////////////////////////////////////////////////////////
@ -264,7 +285,8 @@ static long stream_ctrl(BIO* b, int cmd, long num, void* ptr) {
OpenSSLStreamAdapter::OpenSSLStreamAdapter(
std::unique_ptr<StreamInterface> stream,
absl::AnyInvocable<void(SSLHandshakeError)> handshake_error)
absl::AnyInvocable<void(SSLHandshakeError)> handshake_error,
const webrtc::FieldTrialsView* field_trials)
: stream_(std::move(stream)),
handshake_error_(std::move(handshake_error)),
owner_(rtc::Thread::Current()),
@ -276,8 +298,12 @@ OpenSSLStreamAdapter::OpenSSLStreamAdapter(
ssl_ctx_(nullptr),
ssl_mode_(SSL_MODE_DTLS),
ssl_max_version_(SSL_PROTOCOL_DTLS_12),
disable_handshake_ticket_(!webrtc::field_trial::IsDisabled(
"WebRTC-DisableTlsSessionTicketKillswitch")) {
disable_handshake_ticket_(
(field_trials == nullptr)
? true
: !field_trials->IsDisabled(
"WebRTC-DisableTlsSessionTicketKillswitch")),
force_dtls_13_(GetForceDtls13(field_trials)) {
stream_->SetEventCallback(
[this](int events, int err) { OnEvent(events, err); });
}
@ -988,6 +1014,15 @@ SSL_CTX* OpenSSLStreamAdapter::SetupSSLContext() {
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);

View File

@ -31,6 +31,7 @@
#else
#include "rtc_base/openssl_identity.h"
#endif
#include "api/field_trials_view.h"
#include "api/task_queue/pending_task_safety_flag.h"
#include "rtc_base/ssl_identity.h"
#include "rtc_base/ssl_stream_adapter.h"
@ -70,7 +71,8 @@ class OpenSSLStreamAdapter final : public SSLStreamAdapter {
public:
OpenSSLStreamAdapter(
std::unique_ptr<StreamInterface> stream,
absl::AnyInvocable<void(SSLHandshakeError)> handshake_error);
absl::AnyInvocable<void(SSLHandshakeError)> handshake_error,
const webrtc::FieldTrialsView* field_trials = nullptr);
~OpenSSLStreamAdapter() override;
void SetIdentity(std::unique_ptr<SSLIdentity> identity) override;
@ -244,6 +246,11 @@ class OpenSSLStreamAdapter final : public SSLStreamAdapter {
// Rollout killswitch for disabling session tickets.
const bool disable_handshake_ticket_;
// 0 == Disabled
// 1 == Max
// 2 == Enabled (both min and max)
const int force_dtls_13_ = 0;
};
/////////////////////////////////////////////////////////////////////////////

View File

@ -82,9 +82,10 @@ bool IsGcmCryptoSuite(int crypto_suite) {
std::unique_ptr<SSLStreamAdapter> SSLStreamAdapter::Create(
std::unique_ptr<StreamInterface> stream,
absl::AnyInvocable<void(SSLHandshakeError)> handshake_error) {
return std::make_unique<OpenSSLStreamAdapter>(std::move(stream),
std::move(handshake_error));
absl::AnyInvocable<void(SSLHandshakeError)> handshake_error,
const webrtc::FieldTrialsView* field_trials) {
return std::make_unique<OpenSSLStreamAdapter>(
std::move(stream), std::move(handshake_error), field_trials);
}
bool SSLStreamAdapter::IsBoringSsl() {

View File

@ -22,6 +22,7 @@
#include "absl/functional/any_invocable.h"
#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "api/field_trials_view.h"
#include "rtc_base/buffer.h"
#include "rtc_base/ssl_certificate.h"
#include "rtc_base/ssl_identity.h"
@ -123,7 +124,8 @@ class SSLStreamAdapter : public StreamInterface {
// Caller is responsible for freeing the returned object.
static std::unique_ptr<SSLStreamAdapter> Create(
std::unique_ptr<StreamInterface> stream,
absl::AnyInvocable<void(SSLHandshakeError)> handshake_error = nullptr);
absl::AnyInvocable<void(SSLHandshakeError)> handshake_error = nullptr,
const webrtc::FieldTrialsView* field_trials = nullptr);
SSLStreamAdapter() = default;
~SSLStreamAdapter() override = default;