From 36d22d82aa202bb199967e9512281e9a53db42c9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 21:33:14 +0200 Subject: Adding upstream version 115.7.0esr. Signed-off-by: Daniel Baumann --- .../p2p/base/transport_description_factory.cc | 151 +++++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 third_party/libwebrtc/p2p/base/transport_description_factory.cc (limited to 'third_party/libwebrtc/p2p/base/transport_description_factory.cc') diff --git a/third_party/libwebrtc/p2p/base/transport_description_factory.cc b/third_party/libwebrtc/p2p/base/transport_description_factory.cc new file mode 100644 index 0000000000..7eb21da166 --- /dev/null +++ b/third_party/libwebrtc/p2p/base/transport_description_factory.cc @@ -0,0 +1,151 @@ +/* + * Copyright 2012 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 "p2p/base/transport_description_factory.h" + +#include + +#include +#include + +#include "p2p/base/transport_description.h" +#include "rtc_base/logging.h" +#include "rtc_base/ssl_fingerprint.h" + +namespace cricket { + +TransportDescriptionFactory::TransportDescriptionFactory( + const webrtc::FieldTrialsView& field_trials) + : secure_(SEC_DISABLED), field_trials_(field_trials) {} + +TransportDescriptionFactory::~TransportDescriptionFactory() = default; + +std::unique_ptr TransportDescriptionFactory::CreateOffer( + const TransportOptions& options, + const TransportDescription* current_description, + IceCredentialsIterator* ice_credentials) const { + auto desc = std::make_unique(); + + // Generate the ICE credentials if we don't already have them. + if (!current_description || options.ice_restart) { + IceParameters credentials = ice_credentials->GetIceCredentials(); + desc->ice_ufrag = credentials.ufrag; + desc->ice_pwd = credentials.pwd; + } else { + desc->ice_ufrag = current_description->ice_ufrag; + desc->ice_pwd = current_description->ice_pwd; + } + desc->AddOption(ICE_OPTION_TRICKLE); + if (options.enable_ice_renomination) { + desc->AddOption(ICE_OPTION_RENOMINATION); + } + + // If we are trying to establish a secure transport, add a fingerprint. + if (secure_ == SEC_ENABLED || secure_ == SEC_REQUIRED) { + // Fail if we can't create the fingerprint. + // If we are the initiator set role to "actpass". + if (!SetSecurityInfo(desc.get(), CONNECTIONROLE_ACTPASS)) { + return NULL; + } + } + + return desc; +} + +std::unique_ptr TransportDescriptionFactory::CreateAnswer( + const TransportDescription* offer, + const TransportOptions& options, + bool require_transport_attributes, + const TransportDescription* current_description, + IceCredentialsIterator* ice_credentials) const { + // TODO(juberti): Figure out why we get NULL offers, and fix this upstream. + if (!offer) { + RTC_LOG(LS_WARNING) << "Failed to create TransportDescription answer " + "because offer is NULL"; + return NULL; + } + + auto desc = std::make_unique(); + // Generate the ICE credentials if we don't already have them or ice is + // being restarted. + if (!current_description || options.ice_restart) { + IceParameters credentials = ice_credentials->GetIceCredentials(); + desc->ice_ufrag = credentials.ufrag; + desc->ice_pwd = credentials.pwd; + } else { + desc->ice_ufrag = current_description->ice_ufrag; + desc->ice_pwd = current_description->ice_pwd; + } + desc->AddOption(ICE_OPTION_TRICKLE); + if (options.enable_ice_renomination) { + desc->AddOption(ICE_OPTION_RENOMINATION); + } + + // Negotiate security params. + if (offer && offer->identity_fingerprint.get()) { + // The offer supports DTLS, so answer with DTLS, as long as we support it. + if (secure_ == SEC_ENABLED || secure_ == SEC_REQUIRED) { + ConnectionRole role = CONNECTIONROLE_NONE; + // If the offer does not constrain the role, go with preference. + if (offer->connection_role == CONNECTIONROLE_ACTPASS) { + role = (options.prefer_passive_role) ? CONNECTIONROLE_PASSIVE + : CONNECTIONROLE_ACTIVE; + } else if (offer->connection_role == CONNECTIONROLE_ACTIVE) { + role = CONNECTIONROLE_PASSIVE; + } else if (offer->connection_role == CONNECTIONROLE_PASSIVE) { + role = CONNECTIONROLE_ACTIVE; + } else if (offer->connection_role == CONNECTIONROLE_NONE) { + // This case may be reached if a=setup is not present in the SDP. + RTC_LOG(LS_WARNING) << "Remote offer connection role is NONE, which is " + "a protocol violation"; + role = (options.prefer_passive_role) ? CONNECTIONROLE_PASSIVE + : CONNECTIONROLE_ACTIVE; + } else { + RTC_LOG(LS_ERROR) << "Remote offer connection role is " << role + << " which is a protocol violation"; + RTC_DCHECK_NOTREACHED(); + } + + if (!SetSecurityInfo(desc.get(), role)) { + return NULL; + } + } + } else if (require_transport_attributes && secure_ == SEC_REQUIRED) { + // We require DTLS, but the other side didn't offer it. Fail. + RTC_LOG(LS_WARNING) << "Failed to create TransportDescription answer " + "because of incompatible security settings"; + return NULL; + } + + return desc; +} + +bool TransportDescriptionFactory::SetSecurityInfo(TransportDescription* desc, + ConnectionRole role) const { + if (!certificate_) { + RTC_LOG(LS_ERROR) << "Cannot create identity digest with no certificate"; + return false; + } + + // This digest algorithm is used to produce the a=fingerprint lines in SDP. + // RFC 4572 Section 5 requires that those lines use the same hash function as + // the certificate's signature, which is what CreateFromCertificate does. + desc->identity_fingerprint = + rtc::SSLFingerprint::CreateFromCertificate(*certificate_); + if (!desc->identity_fingerprint) { + return false; + } + + // Assign security role. + desc->connection_role = role; + return true; +} + +} // namespace cricket -- cgit v1.2.3