Add SSLConfig object to IceServer.

This is a rollforward of https://webrtc-review.googlesource.com/c/src/+/96020,
with the addition of setting the old tlsCertPolicy, tlsAlpnProtocols and
tlsEllipticCurves in the RTCIceServer initializer, for backwards compatibility.

Bug: webrtc:9662
Change-Id: I28706ed4ff5abe3f7f913f105779f0e5412aeac5
Reviewed-on: https://webrtc-review.googlesource.com/98762
Commit-Queue: Diogo Real <diogor@google.com>
Reviewed-by: Sami Kalliomäki <sakal@webrtc.org>
Reviewed-by: Kári Helgason <kthelgason@webrtc.org>
Reviewed-by: Steve Anton <steveanton@webrtc.org>
Reviewed-by: Qingsi Wang <qingsi@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#24696}
This commit is contained in:
Diogo Real
2018-09-11 16:00:22 -07:00
committed by Commit Bot
parent e0c8b230e7
commit 4f085434b9
31 changed files with 1093 additions and 183 deletions

View File

@ -157,12 +157,7 @@ AsyncPacketSocket* BasicPacketSocketFactory::CreateClientTcpSocket(
return NULL;
}
if (tlsOpts & PacketSocketFactory::OPT_TLS_INSECURE) {
ssl_adapter->SetIgnoreBadCert(true);
}
ssl_adapter->SetAlpnProtocols(tcp_options.tls_alpn_protocols);
ssl_adapter->SetEllipticCurves(tcp_options.tls_elliptic_curves);
ssl_adapter->SetSSLConfig(tcp_options.ssl_config);
ssl_adapter->SetCertVerifier(tcp_options.tls_cert_verifier);
socket = ssl_adapter;

View File

@ -14,8 +14,10 @@
#include <string>
#include <vector>
#include "absl/types/optional.h"
#include "rtc_base/constructormagic.h"
#include "rtc_base/proxyinfo.h"
#include "rtc_base/ssladapter.h"
#include "rtc_base/sslcertificate.h"
namespace rtc {
@ -26,11 +28,12 @@ struct PacketSocketTcpOptions {
~PacketSocketTcpOptions();
int opts = 0;
std::vector<std::string> tls_alpn_protocols;
std::vector<std::string> tls_elliptic_curves;
// An optional custom SSL certificate verifier that an API user can provide to
// inject their own certificate verification logic.
SSLCertificateVerifier* tls_cert_verifier = nullptr;
// SSL configuration options.
rtc::SSLConfig ssl_config;
};
class AsyncPacketSocket;

View File

@ -537,8 +537,7 @@ class PortTest : public testing::Test, public sigslot::has_slots<> {
return TurnPort::Create(
&main_, socket_factory, MakeNetwork(addr), 0, 0, username_, password_,
ProtocolAddress(server_addr, int_proto), kRelayCredentials, 0,
std::string(), std::vector<std::string>(), std::vector<std::string>(),
nullptr, nullptr);
std::string(), nullptr, rtc::SSLConfig(), nullptr);
}
RelayPort* CreateGturnPort(const SocketAddress& addr,
ProtocolType int_proto,

View File

@ -20,6 +20,7 @@
#include "p2p/base/portinterface.h"
#include "rtc_base/helpers.h"
#include "rtc_base/proxyinfo.h"
#include "rtc_base/ssladapter.h"
#include "rtc_base/sslcertificate.h"
#include "rtc_base/third_party/sigslot/sigslot.h"
#include "rtc_base/thread.h"
@ -118,17 +119,6 @@ enum : uint32_t {
CF_ALL = 0x7,
};
// TLS certificate policy.
enum class TlsCertPolicy {
// For TLS based protocols, ensure the connection is secure by not
// circumventing certificate validation.
TLS_CERT_POLICY_SECURE,
// For TLS based protocols, disregard security completely by skipping
// certificate validation. This is insecure and should never be used unless
// security is irrelevant in that particular context.
TLS_CERT_POLICY_INSECURE_NO_CHECK,
};
// TODO(deadbeef): Rename to TurnCredentials (and username to ufrag).
struct RelayCredentials {
RelayCredentials() {}
@ -144,6 +134,17 @@ struct RelayCredentials {
std::string password;
};
// TLS certificate policy.
enum class TlsCertPolicy {
// For TLS based protocols, ensure the connection is secure by not
// circumventing certificate validation.
TLS_CERT_POLICY_SECURE,
// For TLS based protocols, disregard security completely by skipping
// certificate validation. This is insecure and should never be used unless
// security is irrelevant in that particular context.
TLS_CERT_POLICY_INSECURE_NO_CHECK,
};
typedef std::vector<ProtocolAddress> PortList;
// TODO(deadbeef): Rename to TurnServerConfig.
struct RelayServerConfig {
@ -180,6 +181,7 @@ struct RelayServerConfig {
TlsCertPolicy tls_cert_policy = TlsCertPolicy::TLS_CERT_POLICY_SECURE;
std::vector<std::string> tls_alpn_protocols;
std::vector<std::string> tls_elliptic_curves;
rtc::SSLConfig ssl_config;
rtc::SSLCertificateVerifier* tls_cert_verifier = nullptr;
};

View File

@ -110,7 +110,12 @@ class TestTurnServer : public TurnAuthInterface {
adapter->SetRole(rtc::SSL_SERVER);
adapter->SetIdentity(
rtc::SSLIdentity::Generate(common_name, rtc::KeyParams()));
adapter->SetIgnoreBadCert(ignore_bad_cert);
rtc::SSLConfig ssl_config;
if (ignore_bad_cert) {
ssl_config.tls_cert_policy =
rtc::TlsCertPolicy::TLS_CERT_POLICY_INSECURE_NO_CHECK;
}
adapter->SetSSLConfig(ssl_config);
socket = adapter;
}
socket->Bind(int_addr);

View File

@ -244,8 +244,47 @@ TurnPort::TurnPort(rtc::Thread* thread,
username,
password),
server_address_(server_address),
tls_alpn_protocols_(tls_alpn_protocols),
tls_elliptic_curves_(tls_elliptic_curves),
tls_cert_verifier_(tls_cert_verifier),
credentials_(credentials),
socket_(NULL),
resolver_(NULL),
error_(0),
request_manager_(thread),
next_channel_number_(TURN_CHANNEL_NUMBER_START),
state_(STATE_CONNECTING),
server_priority_(server_priority),
allocate_mismatch_retries_(0),
turn_customizer_(customizer) {
ssl_config_.tls_alpn_protocols = tls_alpn_protocols;
ssl_config_.tls_elliptic_curves = tls_elliptic_curves;
request_manager_.SignalSendPacket.connect(this, &TurnPort::OnSendStunPacket);
request_manager_.set_origin(origin);
}
TurnPort::TurnPort(rtc::Thread* thread,
rtc::PacketSocketFactory* factory,
rtc::Network* network,
uint16_t min_port,
uint16_t max_port,
const std::string& username,
const std::string& password,
const ProtocolAddress& server_address,
const RelayCredentials& credentials,
int server_priority,
const std::string& origin,
webrtc::TurnCustomizer* customizer,
const rtc::SSLConfig& ssl_config,
rtc::SSLCertificateVerifier* tls_cert_verifier)
: Port(thread,
RELAY_PORT_TYPE,
factory,
network,
min_port,
max_port,
username,
password),
server_address_(server_address),
ssl_config_(ssl_config),
tls_cert_verifier_(tls_cert_verifier),
credentials_(credentials),
socket_(NULL),
@ -289,20 +328,20 @@ ProtocolType TurnPort::GetProtocol() const {
return server_address_.proto;
}
TlsCertPolicy TurnPort::GetTlsCertPolicy() const {
return tls_cert_policy_;
}
void TurnPort::SetTlsCertPolicy(TlsCertPolicy tls_cert_policy) {
tls_cert_policy_ = tls_cert_policy;
switch (tls_cert_policy) {
case TlsCertPolicy::TLS_CERT_POLICY_SECURE:
ssl_config_.tls_cert_policy = rtc::TlsCertPolicy::TLS_CERT_POLICY_SECURE;
break;
case TlsCertPolicy::TLS_CERT_POLICY_INSECURE_NO_CHECK:
ssl_config_.tls_cert_policy =
rtc::TlsCertPolicy::TLS_CERT_POLICY_INSECURE_NO_CHECK;
break;
}
}
std::vector<std::string> TurnPort::GetTlsAlpnProtocols() const {
return tls_alpn_protocols_;
}
std::vector<std::string> TurnPort::GetTlsEllipticCurves() const {
return tls_elliptic_curves_;
const rtc::SSLConfig& TurnPort::GetSslConfig() const {
return ssl_config_;
}
void TurnPort::PrepareAddress() {
@ -362,8 +401,8 @@ bool TurnPort::CreateTurnClientSocket() {
// Apply server address TLS and insecure bits to options.
if (server_address_.proto == PROTO_TLS) {
if (tls_cert_policy_ ==
TlsCertPolicy::TLS_CERT_POLICY_INSECURE_NO_CHECK) {
if (ssl_config_.tls_cert_policy ==
rtc::TlsCertPolicy::TLS_CERT_POLICY_INSECURE_NO_CHECK) {
opts |= rtc::PacketSocketFactory::OPT_TLS_INSECURE;
} else {
opts |= rtc::PacketSocketFactory::OPT_TLS;
@ -372,9 +411,8 @@ bool TurnPort::CreateTurnClientSocket() {
rtc::PacketSocketTcpOptions tcp_options;
tcp_options.opts = opts;
tcp_options.tls_alpn_protocols = tls_alpn_protocols_;
tcp_options.tls_elliptic_curves = tls_elliptic_curves_;
tcp_options.tls_cert_verifier = tls_cert_verifier_;
tcp_options.ssl_config = ssl_config_;
socket_ = socket_factory()->CreateClientTcpSocket(
rtc::SocketAddress(Network()->GetBestIP(), 0), server_address_.address,
proxy(), user_agent(), tcp_options);

View File

@ -22,6 +22,7 @@
#include "p2p/client/basicportallocator.h"
#include "rtc_base/asyncinvoker.h"
#include "rtc_base/asyncpacketsocket.h"
#include "rtc_base/ssladapter.h"
#include "rtc_base/sslcertificate.h"
namespace rtc {
@ -66,6 +67,7 @@ class TurnPort : public Port {
customizer);
}
// Deprecated. TODO(diogor, webrtc:9673): Remove this constructor.
// Create a TURN port that will use a new socket, bound to |network| and
// using a port in the range between |min_port| and |max_port|.
static TurnPort* Create(
@ -84,10 +86,34 @@ class TurnPort : public Port {
const std::vector<std::string>& tls_elliptic_curves,
webrtc::TurnCustomizer* customizer,
rtc::SSLCertificateVerifier* tls_cert_verifier = nullptr) {
rtc::SSLConfig ssl_config;
ssl_config.tls_alpn_protocols = tls_alpn_protocols;
ssl_config.tls_elliptic_curves = tls_elliptic_curves;
return new TurnPort(thread, factory, network, min_port, max_port, username,
password, server_address, credentials, server_priority,
origin, tls_alpn_protocols, tls_elliptic_curves,
customizer, tls_cert_verifier);
origin, customizer, ssl_config, tls_cert_verifier);
}
// Create a TURN port that will use a new socket, bound to |network| and
// using a port in the range between |min_port| and |max_port|.
static TurnPort* Create(
rtc::Thread* thread,
rtc::PacketSocketFactory* factory,
rtc::Network* network,
uint16_t min_port,
uint16_t max_port,
const std::string& username, // ice username.
const std::string& password, // ice password.
const ProtocolAddress& server_address,
const RelayCredentials& credentials,
int server_priority,
const std::string& origin,
webrtc::TurnCustomizer* customizer,
const rtc::SSLConfig& ssl_config,
rtc::SSLCertificateVerifier* tls_cert_verifier = nullptr) {
return new TurnPort(thread, factory, network, min_port, max_port, username,
password, server_address, credentials, server_priority,
origin, customizer, ssl_config, tls_cert_verifier);
}
~TurnPort() override;
@ -104,11 +130,11 @@ class TurnPort : public Port {
ProtocolType GetProtocol() const override;
virtual TlsCertPolicy GetTlsCertPolicy() const;
// Deprecated. SSLConfig should be used instead.
// TODO(diogor, webrtc:9673): Remove this.
virtual void SetTlsCertPolicy(TlsCertPolicy tls_cert_policy);
virtual std::vector<std::string> GetTlsAlpnProtocols() const;
virtual std::vector<std::string> GetTlsEllipticCurves() const;
virtual const rtc::SSLConfig& GetSslConfig() const;
// Release a TURN allocation by sending a refresh with lifetime 0.
// Sets state to STATE_RECEIVEONLY.
@ -220,6 +246,21 @@ class TurnPort : public Port {
webrtc::TurnCustomizer* customizer,
rtc::SSLCertificateVerifier* tls_cert_verifier = nullptr);
TurnPort(rtc::Thread* thread,
rtc::PacketSocketFactory* factory,
rtc::Network* network,
uint16_t min_port,
uint16_t max_port,
const std::string& username,
const std::string& password,
const ProtocolAddress& server_address,
const RelayCredentials& credentials,
int server_priority,
const std::string& origin,
webrtc::TurnCustomizer* customizer,
const rtc::SSLConfig& ssl_config,
rtc::SSLCertificateVerifier* tls_cert_verifier = nullptr);
// NOTE: This method needs to be accessible for StacPort
// return true if entry was created (i.e channel_number consumed).
bool CreateOrRefreshEntry(const rtc::SocketAddress& addr,
@ -304,9 +345,7 @@ class TurnPort : public Port {
size_t size, bool payload);
ProtocolAddress server_address_;
TlsCertPolicy tls_cert_policy_ = TlsCertPolicy::TLS_CERT_POLICY_SECURE;
std::vector<std::string> tls_alpn_protocols_;
std::vector<std::string> tls_elliptic_curves_;
rtc::SSLConfig ssl_config_;
rtc::SSLCertificateVerifier* tls_cert_verifier_;
RelayCredentials credentials_;
AttemptedServerSet attempted_server_addresses_;

View File

@ -270,21 +270,16 @@ class TurnPortTest : public testing::Test,
const ProtocolAddress& server_address,
const std::string& origin) {
RelayCredentials credentials(username, password);
turn_port_.reset(TurnPort::Create(
&main_, &socket_factory_, network, 0, 0, kIceUfrag1, kIcePwd1,
server_address, credentials, 0, origin, std::vector<std::string>(),
std::vector<std::string>(), turn_customizer_.get()));
rtc::SSLConfig ssl_config;
ssl_config.tls_cert_policy =
rtc::TlsCertPolicy::TLS_CERT_POLICY_INSECURE_NO_CHECK;
turn_port_.reset(TurnPort::Create(&main_, &socket_factory_, network, 0, 0,
kIceUfrag1, kIcePwd1, server_address,
credentials, 0, origin,
turn_customizer_.get(), ssl_config));
// This TURN port will be the controlling.
turn_port_->SetIceRole(ICEROLE_CONTROLLING);
ConnectSignals();
if (server_address.proto == cricket::PROTO_TLS) {
// The test TURN server has a self-signed certificate so will not pass
// the normal client validation. Instruct the client to ignore certificate
// errors for testing only.
turn_port_->SetTlsCertPolicy(
TlsCertPolicy::TLS_CERT_POLICY_INSECURE_NO_CHECK);
}
}
void CreateSharedTurnPort(const std::string& username,

View File

@ -26,20 +26,29 @@ std::unique_ptr<Port> TurnPortFactory::Create(
args.username, args.password, *args.server_address,
args.config->credentials, args.config->priority, args.origin,
args.turn_customizer);
port->SetTlsCertPolicy(args.config->tls_cert_policy);
return std::unique_ptr<Port>(port);
}
std::unique_ptr<Port> TurnPortFactory::Create(const CreateRelayPortArgs& args,
int min_port,
int max_port) {
rtc::SSLConfig ssl_config = args.config->ssl_config;
if (!args.config->tls_alpn_protocols.empty()) {
ssl_config.tls_alpn_protocols = args.config->tls_alpn_protocols;
}
if (!args.config->tls_elliptic_curves.empty()) {
ssl_config.tls_elliptic_curves = args.config->tls_elliptic_curves;
}
if (args.config->tls_cert_policy ==
TlsCertPolicy::TLS_CERT_POLICY_INSECURE_NO_CHECK) {
ssl_config.tls_cert_policy =
rtc::TlsCertPolicy::TLS_CERT_POLICY_INSECURE_NO_CHECK;
}
TurnPort* port = TurnPort::Create(
args.network_thread, args.socket_factory, args.network, min_port,
max_port, args.username, args.password, *args.server_address,
args.config->credentials, args.config->priority, args.origin,
args.config->tls_alpn_protocols, args.config->tls_elliptic_curves,
args.turn_customizer, args.config->tls_cert_verifier);
port->SetTlsCertPolicy(args.config->tls_cert_policy);
args.turn_customizer, ssl_config, args.config->tls_cert_verifier);
return std::unique_ptr<Port>(port);
}