Skip to content

Commit

Permalink
This changeset adds dependency injection support for SSL Root Certs.
Browse files Browse the repository at this point in the history
This extends the API surface so that
custom certificates can be provided by an API user in both the standalone and
factory creation paths for the OpenSSLAdapter. Prior to this change the SSL
roots were hardcoded in a header file and directly included into
openssladapter.cc. This forces the 100 kilobytes of certificates to always be
compiled into the library. This is undesirable in certain linking cases where
these certificates can be shared from another binary that already has an
equivalent set of trusted roots hard coded into the binary.

Support for removing the hard coded SSL roots has also been added through a new
build flag. By default the hard coded SSL roots will be included and will be
used if no other trusted root certificates are provided.

The main goal of this CL is to reduce total binary size requirements of WebRTC
by about 100kb in certain applications where adding these certificates is
redundant.

Change-Id: Ifd36d92b5cb32d1b3098a61ddfc244d76df8f30f

Bug: chromium:526260
Change-Id: Ifd36d92b5cb32d1b3098a61ddfc244d76df8f30f
Reviewed-on: https://webrtc-review.googlesource.com/64841
Commit-Queue: Benjamin Wright <[email protected]>
Reviewed-by: Karl Wiberg <[email protected]>
Reviewed-by: Taylor Brandstetter <[email protected]>
Cr-Commit-Position: refs/heads/master@{#23180}
  • Loading branch information
benjwright authored and Commit Bot committed May 9, 2018
1 parent 7c682e0 commit d6f86e8
Show file tree
Hide file tree
Showing 31 changed files with 1,272 additions and 715 deletions.
2 changes: 2 additions & 0 deletions api/peerconnectioninterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@
#include "rtc_base/rtccertificate.h"
#include "rtc_base/rtccertificategenerator.h"
#include "rtc_base/socketaddress.h"
#include "rtc_base/sslcertificate.h"
#include "rtc_base/sslstreamadapter.h"

namespace rtc {
Expand Down Expand Up @@ -1190,6 +1191,7 @@ struct PeerConnectionDependencies final {
// Optional dependencies
std::unique_ptr<cricket::PortAllocator> allocator;
std::unique_ptr<rtc::RTCCertificateGeneratorInterface> cert_generator;
std::unique_ptr<rtc::SSLCertificateVerifier> tls_cert_verifier;
};

// PeerConnectionFactoryInterface is the factory interface used for creating
Expand Down
1 change: 1 addition & 0 deletions p2p/base/basicpacketsocketfactory.cc
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ AsyncPacketSocket* BasicPacketSocketFactory::CreateClientTcpSocket(

ssl_adapter->SetAlpnProtocols(tcp_options.tls_alpn_protocols);
ssl_adapter->SetEllipticCurves(tcp_options.tls_elliptic_curves);
ssl_adapter->SetCertVerifier(tcp_options.tls_cert_verifier);

socket = ssl_adapter;

Expand Down
4 changes: 4 additions & 0 deletions p2p/base/packetsocketfactory.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

#include "rtc_base/constructormagic.h"
#include "rtc_base/proxyinfo.h"
#include "rtc_base/sslcertificate.h"

namespace rtc {

Expand All @@ -27,6 +28,9 @@ struct 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;
};

class AsyncPacketSocket;
Expand Down
10 changes: 5 additions & 5 deletions p2p/base/port_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -544,7 +544,7 @@ class PortTest : public testing::Test, public sigslot::has_slots<> {
&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, nullptr);
}
RelayPort* CreateGturnPort(const SocketAddress& addr,
ProtocolType int_proto, ProtocolType ext_proto) {
Expand Down Expand Up @@ -1486,7 +1486,7 @@ TEST_F(PortTest, TestTcpNoDelay) {
}

TEST_F(PortTest, TestDelayedBindingUdp) {
FakeAsyncPacketSocket *socket = new FakeAsyncPacketSocket();
FakeAsyncPacketSocket* socket = new FakeAsyncPacketSocket();
FakePacketSocketFactory socket_factory;

socket_factory.set_next_udp_socket(socket);
Expand All @@ -1502,7 +1502,7 @@ TEST_F(PortTest, TestDelayedBindingUdp) {
}

TEST_F(PortTest, TestDelayedBindingTcp) {
FakeAsyncPacketSocket *socket = new FakeAsyncPacketSocket();
FakeAsyncPacketSocket* socket = new FakeAsyncPacketSocket();
FakePacketSocketFactory socket_factory;

socket_factory.set_next_server_tcp_socket(socket);
Expand All @@ -1525,7 +1525,7 @@ void PortTest::TestCrossFamilyPorts(int type) {
SocketAddress("2001:db8::1", 0),
SocketAddress("2001:db8::2", 0)};
for (int i = 0; i < 4; i++) {
FakeAsyncPacketSocket *socket = new FakeAsyncPacketSocket();
FakeAsyncPacketSocket* socket = new FakeAsyncPacketSocket();
if (type == SOCK_DGRAM) {
factory.set_next_udp_socket(socket);
ports[i].reset(CreateUdpPort(addresses[i], &factory));
Expand Down Expand Up @@ -1595,7 +1595,7 @@ TEST_F(PortTest, TestUdpV6CrossTypePorts) {
SocketAddress("fe80::2", 0),
SocketAddress("::1", 0)};
for (int i = 0; i < 4; i++) {
FakeAsyncPacketSocket *socket = new FakeAsyncPacketSocket();
FakeAsyncPacketSocket* socket = new FakeAsyncPacketSocket();
factory.set_next_udp_socket(socket);
ports[i].reset(CreateUdpPort(addresses[i], &factory));
socket->set_state(AsyncPacketSocket::STATE_BINDING);
Expand Down
2 changes: 2 additions & 0 deletions p2p/base/portallocator.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "rtc_base/helpers.h"
#include "rtc_base/proxyinfo.h"
#include "rtc_base/sigslot.h"
#include "rtc_base/sslcertificate.h"
#include "rtc_base/thread.h"
#include "rtc_base/thread_checker.h"

Expand Down Expand Up @@ -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::SSLCertificateVerifier* tls_cert_verifier = nullptr;
};

class PortAllocatorSession : public sigslot::has_slots<> {
Expand Down
14 changes: 9 additions & 5 deletions p2p/base/testturnserver.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,11 @@ class TestTurnServer : public TurnAuthInterface {
TestTurnServer(rtc::Thread* thread,
const rtc::SocketAddress& int_addr,
const rtc::SocketAddress& udp_ext_addr,
ProtocolType int_protocol = PROTO_UDP)
ProtocolType int_protocol = PROTO_UDP,
bool ignore_bad_cert = true,
const std::string& common_name = "test turn server")
: server_(thread), thread_(thread) {
AddInternalSocket(int_addr, int_protocol);
AddInternalSocket(int_addr, int_protocol, ignore_bad_cert, common_name);
server_.SetExternalSocketFactory(new rtc::BasicPacketSocketFactory(thread),
udp_ext_addr);
server_.set_realm(kTestRealm);
Expand All @@ -78,7 +80,9 @@ class TestTurnServer : public TurnAuthInterface {
}

void AddInternalSocket(const rtc::SocketAddress& int_addr,
ProtocolType proto) {
ProtocolType proto,
bool ignore_bad_cert = true,
const std::string& common_name = "test turn server") {
if (proto == cricket::PROTO_UDP) {
server_.AddInternalSocket(
rtc::AsyncUDPSocket::Create(thread_->socketserver(), int_addr),
Expand All @@ -96,8 +100,8 @@ class TestTurnServer : public TurnAuthInterface {
rtc::SSLAdapter* adapter = rtc::SSLAdapter::Create(socket);
adapter->SetRole(rtc::SSL_SERVER);
adapter->SetIdentity(
rtc::SSLIdentity::Generate("test turn server", rtc::KeyParams()));
adapter->SetIgnoreBadCert(true);
rtc::SSLIdentity::Generate(common_name, rtc::KeyParams()));
adapter->SetIgnoreBadCert(ignore_bad_cert);
socket = adapter;
}
socket->Bind(int_addr);
Expand Down
13 changes: 6 additions & 7 deletions p2p/base/turnport.cc
Original file line number Diff line number Diff line change
Expand Up @@ -199,13 +199,9 @@ TurnPort::TurnPort(rtc::Thread* thread,
int server_priority,
const std::string& origin,
webrtc::TurnCustomizer* customizer)
: Port(thread,
RELAY_PORT_TYPE,
factory,
network,
username,
password),
: Port(thread, RELAY_PORT_TYPE, factory, network, username, password),
server_address_(server_address),
tls_cert_verifier_(nullptr),
credentials_(credentials),
socket_(socket),
resolver_(NULL),
Expand Down Expand Up @@ -233,7 +229,8 @@ TurnPort::TurnPort(rtc::Thread* thread,
const std::string& origin,
const std::vector<std::string>& tls_alpn_protocols,
const std::vector<std::string>& tls_elliptic_curves,
webrtc::TurnCustomizer* customizer)
webrtc::TurnCustomizer* customizer,
rtc::SSLCertificateVerifier* tls_cert_verifier)
: Port(thread,
RELAY_PORT_TYPE,
factory,
Expand All @@ -245,6 +242,7 @@ TurnPort::TurnPort(rtc::Thread* thread,
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),
Expand Down Expand Up @@ -374,6 +372,7 @@ bool TurnPort::CreateTurnClientSocket() {
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_;
socket_ = socket_factory()->CreateClientTcpSocket(
rtc::SocketAddress(Network()->GetBestIP(), 0), server_address_.address,
proxy(), user_agent(), tcp_options);
Expand Down
37 changes: 21 additions & 16 deletions p2p/base/turnport.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "p2p/client/basicportallocator.h"
#include "rtc_base/asyncinvoker.h"
#include "rtc_base/asyncpacketsocket.h"
#include "rtc_base/sslcertificate.h"

namespace rtc {
class AsyncResolver;
Expand Down Expand Up @@ -67,24 +68,26 @@ class TurnPort : public Port {

// 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,
const std::vector<std::string>& tls_alpn_protocols,
const std::vector<std::string>& tls_elliptic_curves,
webrtc::TurnCustomizer* customizer) {
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,
const std::vector<std::string>& tls_alpn_protocols,
const std::vector<std::string>& tls_elliptic_curves,
webrtc::TurnCustomizer* customizer,
rtc::SSLCertificateVerifier* tls_cert_verifier = nullptr) {
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);
customizer, tls_cert_verifier);
}

~TurnPort() override;
Expand Down Expand Up @@ -214,7 +217,8 @@ class TurnPort : public Port {
const std::string& origin,
const std::vector<std::string>& tls_alpn_protocols,
const std::vector<std::string>& tls_elliptic_curves,
webrtc::TurnCustomizer* customizer);
webrtc::TurnCustomizer* customizer,
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).
Expand Down Expand Up @@ -303,6 +307,7 @@ class TurnPort : public Port {
TlsCertPolicy tls_cert_policy_ = TlsCertPolicy::TLS_CERT_POLICY_SECURE;
std::vector<std::string> tls_alpn_protocols_;
std::vector<std::string> tls_elliptic_curves_;
rtc::SSLCertificateVerifier* tls_cert_verifier_;
RelayCredentials credentials_;
AttemptedServerSet attempted_server_addresses_;

Expand Down
20 changes: 5 additions & 15 deletions p2p/client/turnportfactory.cc
Original file line number Diff line number Diff line change
Expand Up @@ -43,22 +43,12 @@ std::unique_ptr<Port> TurnPortFactory::Create(
const CreateRelayPortArgs& args,
int min_port,
int max_port) {

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.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);
return std::unique_ptr<Port>(port);
}
Expand Down
7 changes: 7 additions & 0 deletions pc/peerconnection.cc
Original file line number Diff line number Diff line change
Expand Up @@ -904,8 +904,10 @@ bool PeerConnection::Initialize(
"PeerConnectionObserver";
return false;
}

observer_ = dependencies.observer;
port_allocator_ = std::move(dependencies.allocator);
tls_cert_verifier_ = std::move(dependencies.tls_cert_verifier);

// The port allocator lives on the network thread and should be initialized
// there.
Expand Down Expand Up @@ -4674,6 +4676,11 @@ bool PeerConnection::InitializePortAllocator_n(
ConvertIceTransportTypeToCandidateFilter(configuration.type));
port_allocator_->set_max_ipv6_networks(configuration.max_ipv6_networks);

if (tls_cert_verifier_ != nullptr) {
for (auto& turn_server : turn_servers) {
turn_server.tls_cert_verifier = tls_cert_verifier_.get();
}
}
// Call this last since it may create pooled allocator sessions using the
// properties set above.
port_allocator_->SetConfiguration(
Expand Down
1 change: 1 addition & 0 deletions pc/peerconnection.h
Original file line number Diff line number Diff line change
Expand Up @@ -906,6 +906,7 @@ class PeerConnection : public PeerConnectionInternal,
PeerConnectionInterface::RTCConfiguration configuration_;

std::unique_ptr<cricket::PortAllocator> port_allocator_;
std::unique_ptr<rtc::SSLCertificateVerifier> tls_cert_verifier_;
int port_allocator_flags_ = 0;

// One PeerConnection has only one RTCP CNAME.
Expand Down
Loading

0 comments on commit d6f86e8

Please sign in to comment.