Add support for changing the TLS elliptic curve set.
This CL is almost identical to http://chromium-review.googlesource.com/c/611150 Bug: webrtc:8213 Change-Id: I21a8a0041a73b3171ed66b687dc47a579d45fe19 Reviewed-on: https://chromium-review.googlesource.com/653205 Commit-Queue: Diogo Real <diogor@google.com> Reviewed-by: Peter Thatcher <pthatcher@webrtc.org> Reviewed-by: Emad Omara <emadomara@webrtc.org> Reviewed-by: Zeke Chin <tkchin@webrtc.org> Reviewed-by: Sami Kalliomäki <sakal@webrtc.org> Cr-Commit-Position: refs/heads/master@{#19755}
This commit is contained in:
@ -195,12 +195,15 @@ class PeerConnectionInterface : public rtc::RefCountInterface {
|
|||||||
std::string hostname;
|
std::string hostname;
|
||||||
// List of protocols to be used in the TLS ALPN extension.
|
// List of protocols to be used in the TLS ALPN extension.
|
||||||
std::vector<std::string> tls_alpn_protocols;
|
std::vector<std::string> tls_alpn_protocols;
|
||||||
|
// List of elliptic curves to be used in the TLS elliptic curves extension.
|
||||||
|
std::vector<std::string> tls_elliptic_curves;
|
||||||
|
|
||||||
bool operator==(const IceServer& o) const {
|
bool operator==(const IceServer& o) const {
|
||||||
return uri == o.uri && urls == o.urls && username == o.username &&
|
return uri == o.uri && urls == o.urls && username == o.username &&
|
||||||
password == o.password && tls_cert_policy == o.tls_cert_policy &&
|
password == o.password && tls_cert_policy == o.tls_cert_policy &&
|
||||||
hostname == o.hostname &&
|
hostname == o.hostname &&
|
||||||
tls_alpn_protocols == o.tls_alpn_protocols;
|
tls_alpn_protocols == o.tls_alpn_protocols &&
|
||||||
|
tls_elliptic_curves == o.tls_elliptic_curves;
|
||||||
}
|
}
|
||||||
bool operator!=(const IceServer& o) const { return !(*this == o); }
|
bool operator!=(const IceServer& o) const { return !(*this == o); }
|
||||||
};
|
};
|
||||||
|
|||||||
@ -159,6 +159,7 @@ AsyncPacketSocket* BasicPacketSocketFactory::CreateClientTcpSocket(
|
|||||||
}
|
}
|
||||||
|
|
||||||
ssl_adapter->SetAlpnProtocols(tcp_options.tls_alpn_protocols);
|
ssl_adapter->SetAlpnProtocols(tcp_options.tls_alpn_protocols);
|
||||||
|
ssl_adapter->SetEllipticCurves(tcp_options.tls_elliptic_curves);
|
||||||
|
|
||||||
socket = ssl_adapter;
|
socket = ssl_adapter;
|
||||||
|
|
||||||
|
|||||||
@ -20,6 +20,7 @@ namespace rtc {
|
|||||||
struct PacketSocketTcpOptions {
|
struct PacketSocketTcpOptions {
|
||||||
int opts;
|
int opts;
|
||||||
std::vector<std::string> tls_alpn_protocols;
|
std::vector<std::string> tls_alpn_protocols;
|
||||||
|
std::vector<std::string> tls_elliptic_curves;
|
||||||
};
|
};
|
||||||
|
|
||||||
class AsyncPacketSocket;
|
class AsyncPacketSocket;
|
||||||
|
|||||||
@ -536,7 +536,7 @@ class PortTest : public testing::Test, public sigslot::has_slots<> {
|
|||||||
return TurnPort::Create(
|
return TurnPort::Create(
|
||||||
&main_, socket_factory, MakeNetwork(addr), 0, 0, username_, password_,
|
&main_, socket_factory, MakeNetwork(addr), 0, 0, username_, password_,
|
||||||
ProtocolAddress(server_addr, int_proto), kRelayCredentials, 0,
|
ProtocolAddress(server_addr, int_proto), kRelayCredentials, 0,
|
||||||
std::string(), std::vector<std::string>());
|
std::string(), std::vector<std::string>(), std::vector<std::string>());
|
||||||
}
|
}
|
||||||
RelayPort* CreateGturnPort(const SocketAddress& addr,
|
RelayPort* CreateGturnPort(const SocketAddress& addr,
|
||||||
ProtocolType int_proto, ProtocolType ext_proto) {
|
ProtocolType int_proto, ProtocolType ext_proto) {
|
||||||
|
|||||||
@ -192,6 +192,7 @@ struct RelayServerConfig {
|
|||||||
int priority = 0;
|
int priority = 0;
|
||||||
TlsCertPolicy tls_cert_policy = TlsCertPolicy::TLS_CERT_POLICY_SECURE;
|
TlsCertPolicy tls_cert_policy = TlsCertPolicy::TLS_CERT_POLICY_SECURE;
|
||||||
std::vector<std::string> tls_alpn_protocols;
|
std::vector<std::string> tls_alpn_protocols;
|
||||||
|
std::vector<std::string> tls_elliptic_curves;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PortAllocatorSession : public sigslot::has_slots<> {
|
class PortAllocatorSession : public sigslot::has_slots<> {
|
||||||
|
|||||||
@ -222,7 +222,8 @@ TurnPort::TurnPort(rtc::Thread* thread,
|
|||||||
const RelayCredentials& credentials,
|
const RelayCredentials& credentials,
|
||||||
int server_priority,
|
int server_priority,
|
||||||
const std::string& origin,
|
const std::string& origin,
|
||||||
const std::vector<std::string>& tls_alpn_protocols)
|
const std::vector<std::string>& tls_alpn_protocols,
|
||||||
|
const std::vector<std::string>& tls_elliptic_curves)
|
||||||
: Port(thread,
|
: Port(thread,
|
||||||
RELAY_PORT_TYPE,
|
RELAY_PORT_TYPE,
|
||||||
factory,
|
factory,
|
||||||
@ -233,6 +234,7 @@ TurnPort::TurnPort(rtc::Thread* thread,
|
|||||||
password),
|
password),
|
||||||
server_address_(server_address),
|
server_address_(server_address),
|
||||||
tls_alpn_protocols_(tls_alpn_protocols),
|
tls_alpn_protocols_(tls_alpn_protocols),
|
||||||
|
tls_elliptic_curves_(tls_elliptic_curves),
|
||||||
credentials_(credentials),
|
credentials_(credentials),
|
||||||
socket_(NULL),
|
socket_(NULL),
|
||||||
resolver_(NULL),
|
resolver_(NULL),
|
||||||
@ -341,6 +343,7 @@ bool TurnPort::CreateTurnClientSocket() {
|
|||||||
rtc::PacketSocketTcpOptions tcp_options;
|
rtc::PacketSocketTcpOptions tcp_options;
|
||||||
tcp_options.opts = opts;
|
tcp_options.opts = opts;
|
||||||
tcp_options.tls_alpn_protocols = tls_alpn_protocols_;
|
tcp_options.tls_alpn_protocols = tls_alpn_protocols_;
|
||||||
|
tcp_options.tls_elliptic_curves = tls_elliptic_curves_;
|
||||||
socket_ = socket_factory()->CreateClientTcpSocket(
|
socket_ = socket_factory()->CreateClientTcpSocket(
|
||||||
rtc::SocketAddress(Network()->GetBestIP(), 0), server_address_.address,
|
rtc::SocketAddress(Network()->GetBestIP(), 0), server_address_.address,
|
||||||
proxy(), user_agent(), tcp_options);
|
proxy(), user_agent(), tcp_options);
|
||||||
|
|||||||
@ -70,10 +70,11 @@ class TurnPort : public Port {
|
|||||||
const RelayCredentials& credentials,
|
const RelayCredentials& credentials,
|
||||||
int server_priority,
|
int server_priority,
|
||||||
const std::string& origin,
|
const std::string& origin,
|
||||||
const std::vector<std::string>& tls_alpn_protocols) {
|
const std::vector<std::string>& tls_alpn_protocols,
|
||||||
|
const std::vector<std::string>& tls_elliptic_curves) {
|
||||||
return new TurnPort(thread, factory, network, min_port, max_port, username,
|
return new TurnPort(thread, factory, network, min_port, max_port, username,
|
||||||
password, server_address, credentials, server_priority,
|
password, server_address, credentials, server_priority,
|
||||||
origin, tls_alpn_protocols);
|
origin, tls_alpn_protocols, tls_elliptic_curves);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~TurnPort();
|
virtual ~TurnPort();
|
||||||
@ -100,6 +101,10 @@ class TurnPort : public Port {
|
|||||||
return tls_alpn_protocols_;
|
return tls_alpn_protocols_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual std::vector<std::string> GetTlsEllipticCurves() const {
|
||||||
|
return tls_elliptic_curves_;
|
||||||
|
}
|
||||||
|
|
||||||
virtual void PrepareAddress();
|
virtual void PrepareAddress();
|
||||||
virtual Connection* CreateConnection(
|
virtual Connection* CreateConnection(
|
||||||
const Candidate& c, PortInterface::CandidateOrigin origin);
|
const Candidate& c, PortInterface::CandidateOrigin origin);
|
||||||
@ -192,7 +197,8 @@ class TurnPort : public Port {
|
|||||||
const RelayCredentials& credentials,
|
const RelayCredentials& credentials,
|
||||||
int server_priority,
|
int server_priority,
|
||||||
const std::string& origin,
|
const std::string& origin,
|
||||||
const std::vector<std::string>& alpn_protocols);
|
const std::vector<std::string>& tls_alpn_protocols,
|
||||||
|
const std::vector<std::string>& tls_elliptic_curves);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum {
|
enum {
|
||||||
@ -273,6 +279,7 @@ class TurnPort : public Port {
|
|||||||
ProtocolAddress server_address_;
|
ProtocolAddress server_address_;
|
||||||
TlsCertPolicy tls_cert_policy_ = TlsCertPolicy::TLS_CERT_POLICY_SECURE;
|
TlsCertPolicy tls_cert_policy_ = TlsCertPolicy::TLS_CERT_POLICY_SECURE;
|
||||||
std::vector<std::string> tls_alpn_protocols_;
|
std::vector<std::string> tls_alpn_protocols_;
|
||||||
|
std::vector<std::string> tls_elliptic_curves_;
|
||||||
RelayCredentials credentials_;
|
RelayCredentials credentials_;
|
||||||
AttemptedServerSet attempted_server_addresses_;
|
AttemptedServerSet attempted_server_addresses_;
|
||||||
|
|
||||||
|
|||||||
@ -263,7 +263,8 @@ class TurnPortTest : public testing::Test,
|
|||||||
RelayCredentials credentials(username, password);
|
RelayCredentials credentials(username, password);
|
||||||
turn_port_.reset(TurnPort::Create(
|
turn_port_.reset(TurnPort::Create(
|
||||||
&main_, &socket_factory_, network, 0, 0, kIceUfrag1, kIcePwd1,
|
&main_, &socket_factory_, network, 0, 0, kIceUfrag1, kIcePwd1,
|
||||||
server_address, credentials, 0, origin, std::vector<std::string>()));
|
server_address, credentials, 0, origin, std::vector<std::string>(),
|
||||||
|
std::vector<std::string>()));
|
||||||
// This TURN port will be the controlling.
|
// This TURN port will be the controlling.
|
||||||
turn_port_->SetIceRole(ICEROLE_CONTROLLING);
|
turn_port_->SetIceRole(ICEROLE_CONTROLLING);
|
||||||
ConnectSignals();
|
ConnectSignals();
|
||||||
|
|||||||
@ -1445,7 +1445,7 @@ void AllocationSequence::CreateTurnPort(const RelayServerConfig& config) {
|
|||||||
session_->allocator()->min_port(), session_->allocator()->max_port(),
|
session_->allocator()->min_port(), session_->allocator()->max_port(),
|
||||||
session_->username(), session_->password(), *relay_port,
|
session_->username(), session_->password(), *relay_port,
|
||||||
config.credentials, config.priority, session_->allocator()->origin(),
|
config.credentials, config.priority, session_->allocator()->origin(),
|
||||||
config.tls_alpn_protocols);
|
config.tls_alpn_protocols, config.tls_elliptic_curves);
|
||||||
}
|
}
|
||||||
RTC_DCHECK(port != NULL);
|
RTC_DCHECK(port != NULL);
|
||||||
port->SetTlsCertPolicy(config.tls_cert_policy);
|
port->SetTlsCertPolicy(config.tls_cert_policy);
|
||||||
|
|||||||
@ -258,6 +258,7 @@ static RTCErrorType ParseIceServerUrl(
|
|||||||
cricket::TlsCertPolicy::TLS_CERT_POLICY_INSECURE_NO_CHECK;
|
cricket::TlsCertPolicy::TLS_CERT_POLICY_INSECURE_NO_CHECK;
|
||||||
}
|
}
|
||||||
config.tls_alpn_protocols = server.tls_alpn_protocols;
|
config.tls_alpn_protocols = server.tls_alpn_protocols;
|
||||||
|
config.tls_elliptic_curves = server.tls_elliptic_curves;
|
||||||
|
|
||||||
turn_servers->push_back(config);
|
turn_servers->push_back(config);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -31,6 +31,7 @@
|
|||||||
#include "webrtc/rtc_base/openssl.h"
|
#include "webrtc/rtc_base/openssl.h"
|
||||||
#include "webrtc/rtc_base/safe_conversions.h"
|
#include "webrtc/rtc_base/safe_conversions.h"
|
||||||
#include "webrtc/rtc_base/sslroots.h"
|
#include "webrtc/rtc_base/sslroots.h"
|
||||||
|
#include "webrtc/rtc_base/stringencode.h"
|
||||||
#include "webrtc/rtc_base/stringutils.h"
|
#include "webrtc/rtc_base/stringutils.h"
|
||||||
#include "webrtc/rtc_base/thread.h"
|
#include "webrtc/rtc_base/thread.h"
|
||||||
|
|
||||||
@ -311,6 +312,10 @@ void OpenSSLAdapter::SetAlpnProtocols(const std::vector<std::string>& protos) {
|
|||||||
alpn_protocols_ = protos;
|
alpn_protocols_ = protos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OpenSSLAdapter::SetEllipticCurves(const std::vector<std::string>& curves) {
|
||||||
|
elliptic_curves_ = curves;
|
||||||
|
}
|
||||||
|
|
||||||
void OpenSSLAdapter::SetMode(SSLMode mode) {
|
void OpenSSLAdapter::SetMode(SSLMode mode) {
|
||||||
RTC_DCHECK(!ssl_ctx_);
|
RTC_DCHECK(!ssl_ctx_);
|
||||||
RTC_DCHECK(state_ == SSL_NONE);
|
RTC_DCHECK(state_ == SSL_NONE);
|
||||||
@ -445,6 +450,10 @@ int OpenSSLAdapter::BeginSSL() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!elliptic_curves_.empty()) {
|
||||||
|
SSL_set1_curves_list(ssl_, rtc::join(elliptic_curves_, ':').c_str());
|
||||||
|
}
|
||||||
|
|
||||||
// Now that the initial config is done, transfer ownership of |bio| to the
|
// Now that the initial config is done, transfer ownership of |bio| to the
|
||||||
// SSL object. If ContinueSSL() fails, the bio will be freed in Cleanup().
|
// SSL object. If ContinueSSL() fails, the bio will be freed in Cleanup().
|
||||||
SSL_set_bio(ssl_, bio, bio);
|
SSL_set_bio(ssl_, bio, bio);
|
||||||
|
|||||||
@ -40,6 +40,7 @@ class OpenSSLAdapter : public SSLAdapter, public MessageHandler {
|
|||||||
|
|
||||||
void SetIgnoreBadCert(bool ignore) override;
|
void SetIgnoreBadCert(bool ignore) override;
|
||||||
void SetAlpnProtocols(const std::vector<std::string>& protos) override;
|
void SetAlpnProtocols(const std::vector<std::string>& protos) override;
|
||||||
|
void SetEllipticCurves(const std::vector<std::string>& curves) override;
|
||||||
|
|
||||||
void SetMode(SSLMode mode) override;
|
void SetMode(SSLMode mode) override;
|
||||||
void SetIdentity(SSLIdentity* identity) override;
|
void SetIdentity(SSLIdentity* identity) override;
|
||||||
@ -136,6 +137,8 @@ class OpenSSLAdapter : public SSLAdapter, public MessageHandler {
|
|||||||
bool ignore_bad_cert_;
|
bool ignore_bad_cert_;
|
||||||
// List of protocols to be used in the TLS ALPN extension.
|
// List of protocols to be used in the TLS ALPN extension.
|
||||||
std::vector<std::string> alpn_protocols_;
|
std::vector<std::string> alpn_protocols_;
|
||||||
|
// List of elliptic curves to be used in the TLS elliptic curves extension.
|
||||||
|
std::vector<std::string> elliptic_curves_;
|
||||||
|
|
||||||
bool custom_verification_succeeded_;
|
bool custom_verification_succeeded_;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -48,7 +48,9 @@ class SSLAdapter : public AsyncSocketAdapter {
|
|||||||
// TODO(juberti): Remove the opportunistic encryption mechanism in
|
// TODO(juberti): Remove the opportunistic encryption mechanism in
|
||||||
// BasicPacketSocketFactory that uses this function.
|
// BasicPacketSocketFactory that uses this function.
|
||||||
virtual void SetIgnoreBadCert(bool ignore) = 0;
|
virtual void SetIgnoreBadCert(bool ignore) = 0;
|
||||||
|
|
||||||
virtual void SetAlpnProtocols(const std::vector<std::string>& protos) = 0;
|
virtual void SetAlpnProtocols(const std::vector<std::string>& protos) = 0;
|
||||||
|
virtual void SetEllipticCurves(const std::vector<std::string>& curves) = 0;
|
||||||
|
|
||||||
// Do DTLS or TLS (default is TLS, if unspecified)
|
// Do DTLS or TLS (default is TLS, if unspecified)
|
||||||
virtual void SetMode(SSLMode mode) = 0;
|
virtual void SetMode(SSLMode mode) = 0;
|
||||||
|
|||||||
@ -64,6 +64,10 @@ class SSLAdapterTestDummyClient : public sigslot::has_slots<> {
|
|||||||
ssl_adapter_->SetAlpnProtocols(protos);
|
ssl_adapter_->SetAlpnProtocols(protos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetEllipticCurves(const std::vector<std::string>& curves) {
|
||||||
|
ssl_adapter_->SetEllipticCurves(curves);
|
||||||
|
}
|
||||||
|
|
||||||
rtc::SocketAddress GetAddress() const {
|
rtc::SocketAddress GetAddress() const {
|
||||||
return ssl_adapter_->GetLocalAddress();
|
return ssl_adapter_->GetLocalAddress();
|
||||||
}
|
}
|
||||||
@ -290,6 +294,10 @@ class SSLAdapterTestBase : public testing::Test,
|
|||||||
client_->SetAlpnProtocols(protos);
|
client_->SetAlpnProtocols(protos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetEllipticCurves(const std::vector<std::string>& curves) {
|
||||||
|
client_->SetEllipticCurves(curves);
|
||||||
|
}
|
||||||
|
|
||||||
void TestHandshake(bool expect_success) {
|
void TestHandshake(bool expect_success) {
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
@ -450,6 +458,14 @@ TEST_F(SSLAdapterTestTLS_ECDSA, TestTLSALPN) {
|
|||||||
TestTransfer("Hello, world!");
|
TestTransfer("Hello, world!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test transfer with TLS Elliptic curves set to "X25519:P-256:P-384:P-521"
|
||||||
|
TEST_F(SSLAdapterTestTLS_ECDSA, TestTLSEllipticCurves) {
|
||||||
|
std::vector<std::string> elliptic_curves{"X25519", "P-256", "P-384", "P-521"};
|
||||||
|
SetEllipticCurves(elliptic_curves);
|
||||||
|
TestHandshake(true);
|
||||||
|
TestTransfer("Hello, world!");
|
||||||
|
}
|
||||||
|
|
||||||
// Basic tests: DTLS
|
// Basic tests: DTLS
|
||||||
|
|
||||||
// Test that handshake works, using RSA
|
// Test that handshake works, using RSA
|
||||||
|
|||||||
@ -645,6 +645,28 @@ bool tokenize_first(const std::string& source,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string join(const std::vector<std::string>& source, char delimiter) {
|
||||||
|
if (source.size() == 0) {
|
||||||
|
return std::string();
|
||||||
|
}
|
||||||
|
// Find length of the string to be returned to pre-allocate memory.
|
||||||
|
size_t source_string_length = 0;
|
||||||
|
for (size_t i = 0; i < source.size(); ++i) {
|
||||||
|
source_string_length += source[i].length();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build the joined string.
|
||||||
|
std::string joined_string;
|
||||||
|
joined_string.reserve(source_string_length + source.size() - 1);
|
||||||
|
for (size_t i = 0; i < source.size(); ++i) {
|
||||||
|
if (i != 0) {
|
||||||
|
joined_string += delimiter;
|
||||||
|
}
|
||||||
|
joined_string += source[i];
|
||||||
|
}
|
||||||
|
return joined_string;
|
||||||
|
}
|
||||||
|
|
||||||
size_t split(const std::string& source, char delimiter,
|
size_t split(const std::string& source, char delimiter,
|
||||||
std::vector<std::string>* fields) {
|
std::vector<std::string>* fields) {
|
||||||
RTC_DCHECK(fields);
|
RTC_DCHECK(fields);
|
||||||
|
|||||||
@ -136,6 +136,10 @@ inline std::string s_url_decode(const std::string& source) {
|
|||||||
return s_transform(source, url_decode);
|
return s_transform(source, url_decode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Joins the source vector of strings into a single string, with each
|
||||||
|
// field in source being separated by delimiter. No trailing delimiter is added.
|
||||||
|
std::string join(const std::vector<std::string>& source, char delimiter);
|
||||||
|
|
||||||
// Splits the source string into multiple fields separated by delimiter,
|
// Splits the source string into multiple fields separated by delimiter,
|
||||||
// with duplicates of delimiter creating empty fields.
|
// with duplicates of delimiter creating empty fields.
|
||||||
size_t split(const std::string& source, char delimiter,
|
size_t split(const std::string& source, char delimiter,
|
||||||
|
|||||||
@ -113,6 +113,10 @@ public class PeerConnection {
|
|||||||
// List of protocols to be used in the TLS ALPN extension.
|
// List of protocols to be used in the TLS ALPN extension.
|
||||||
public final List<String> tlsAlpnProtocols;
|
public final List<String> tlsAlpnProtocols;
|
||||||
|
|
||||||
|
// List of elliptic curves to be used in the TLS elliptic curves extension.
|
||||||
|
// Only curve names supported by OpenSSL should be used (eg. "P-256","X25519").
|
||||||
|
public final List<String> tlsEllipticCurves;
|
||||||
|
|
||||||
/** Convenience constructor for STUN servers. */
|
/** Convenience constructor for STUN servers. */
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public IceServer(String uri) {
|
public IceServer(String uri) {
|
||||||
@ -132,22 +136,23 @@ public class PeerConnection {
|
|||||||
@Deprecated
|
@Deprecated
|
||||||
public IceServer(String uri, String username, String password, TlsCertPolicy tlsCertPolicy,
|
public IceServer(String uri, String username, String password, TlsCertPolicy tlsCertPolicy,
|
||||||
String hostname) {
|
String hostname) {
|
||||||
this(uri, username, password, tlsCertPolicy, hostname, null);
|
this(uri, username, password, tlsCertPolicy, hostname, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private IceServer(String uri, String username, String password, TlsCertPolicy tlsCertPolicy,
|
private IceServer(String uri, String username, String password, TlsCertPolicy tlsCertPolicy,
|
||||||
String hostname, List<String> tlsAlpnProtocols) {
|
String hostname, List<String> tlsAlpnProtocols, List<String> tlsEllipticCurves) {
|
||||||
this.uri = uri;
|
this.uri = uri;
|
||||||
this.username = username;
|
this.username = username;
|
||||||
this.password = password;
|
this.password = password;
|
||||||
this.tlsCertPolicy = tlsCertPolicy;
|
this.tlsCertPolicy = tlsCertPolicy;
|
||||||
this.hostname = hostname;
|
this.hostname = hostname;
|
||||||
this.tlsAlpnProtocols = tlsAlpnProtocols;
|
this.tlsAlpnProtocols = tlsAlpnProtocols;
|
||||||
|
this.tlsEllipticCurves = tlsEllipticCurves;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return uri + " [" + username + ":" + password + "] [" + tlsCertPolicy + "] [" + hostname
|
return uri + " [" + username + ":" + password + "] [" + tlsCertPolicy + "] [" + hostname
|
||||||
+ "] [" + tlsAlpnProtocols + "]";
|
+ "] [" + tlsAlpnProtocols + "] [" + tlsEllipticCurves + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Builder builder(String uri) {
|
public static Builder builder(String uri) {
|
||||||
@ -161,6 +166,7 @@ public class PeerConnection {
|
|||||||
private TlsCertPolicy tlsCertPolicy = TlsCertPolicy.TLS_CERT_POLICY_SECURE;
|
private TlsCertPolicy tlsCertPolicy = TlsCertPolicy.TLS_CERT_POLICY_SECURE;
|
||||||
private String hostname = "";
|
private String hostname = "";
|
||||||
private List<String> tlsAlpnProtocols;
|
private List<String> tlsAlpnProtocols;
|
||||||
|
private List<String> tlsEllipticCurves;
|
||||||
|
|
||||||
private Builder(String uri) {
|
private Builder(String uri) {
|
||||||
this.uri = uri;
|
this.uri = uri;
|
||||||
@ -191,8 +197,14 @@ public class PeerConnection {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Builder setTlsEllipticCurves(List<String> tlsEllipticCurves) {
|
||||||
|
this.tlsEllipticCurves = tlsEllipticCurves;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public IceServer createIceServer() {
|
public IceServer createIceServer() {
|
||||||
return new IceServer(uri, username, password, tlsCertPolicy, hostname, tlsAlpnProtocols);
|
return new IceServer(
|
||||||
|
uri, username, password, tlsCertPolicy, hostname, tlsAlpnProtocols, tlsEllipticCurves);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -364,6 +364,8 @@ void JavaToNativeIceServers(JNIEnv* jni,
|
|||||||
GetFieldID(jni, j_ice_server_class, "hostname", "Ljava/lang/String;");
|
GetFieldID(jni, j_ice_server_class, "hostname", "Ljava/lang/String;");
|
||||||
jfieldID j_ice_server_tls_alpn_protocols_id = GetFieldID(
|
jfieldID j_ice_server_tls_alpn_protocols_id = GetFieldID(
|
||||||
jni, j_ice_server_class, "tlsAlpnProtocols", "Ljava/util/List;");
|
jni, j_ice_server_class, "tlsAlpnProtocols", "Ljava/util/List;");
|
||||||
|
jfieldID j_ice_server_tls_elliptic_curves_id = GetFieldID(
|
||||||
|
jni, j_ice_server_class, "tlsEllipticCurves", "Ljava/util/List;");
|
||||||
jstring uri = reinterpret_cast<jstring>(
|
jstring uri = reinterpret_cast<jstring>(
|
||||||
GetObjectField(jni, j_ice_server, j_ice_server_uri_id));
|
GetObjectField(jni, j_ice_server, j_ice_server_uri_id));
|
||||||
jstring username = reinterpret_cast<jstring>(
|
jstring username = reinterpret_cast<jstring>(
|
||||||
@ -376,6 +378,8 @@ void JavaToNativeIceServers(JNIEnv* jni,
|
|||||||
GetObjectField(jni, j_ice_server, j_ice_server_hostname_id));
|
GetObjectField(jni, j_ice_server, j_ice_server_hostname_id));
|
||||||
jobject tls_alpn_protocols = GetNullableObjectField(
|
jobject tls_alpn_protocols = GetNullableObjectField(
|
||||||
jni, j_ice_server, j_ice_server_tls_alpn_protocols_id);
|
jni, j_ice_server, j_ice_server_tls_alpn_protocols_id);
|
||||||
|
jobject tls_elliptic_curves = GetNullableObjectField(
|
||||||
|
jni, j_ice_server, j_ice_server_tls_elliptic_curves_id);
|
||||||
PeerConnectionInterface::IceServer server;
|
PeerConnectionInterface::IceServer server;
|
||||||
server.uri = JavaToStdString(jni, uri);
|
server.uri = JavaToStdString(jni, uri);
|
||||||
server.username = JavaToStdString(jni, username);
|
server.username = JavaToStdString(jni, username);
|
||||||
@ -383,6 +387,8 @@ void JavaToNativeIceServers(JNIEnv* jni,
|
|||||||
server.tls_cert_policy = tls_cert_policy;
|
server.tls_cert_policy = tls_cert_policy;
|
||||||
server.hostname = JavaToStdString(jni, hostname);
|
server.hostname = JavaToStdString(jni, hostname);
|
||||||
server.tls_alpn_protocols = JavaToStdVectorStrings(jni, tls_alpn_protocols);
|
server.tls_alpn_protocols = JavaToStdVectorStrings(jni, tls_alpn_protocols);
|
||||||
|
server.tls_elliptic_curves =
|
||||||
|
JavaToStdVectorStrings(jni, tls_elliptic_curves);
|
||||||
ice_servers->push_back(server);
|
ice_servers->push_back(server);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,6 +20,7 @@
|
|||||||
@synthesize tlsCertPolicy = _tlsCertPolicy;
|
@synthesize tlsCertPolicy = _tlsCertPolicy;
|
||||||
@synthesize hostname = _hostname;
|
@synthesize hostname = _hostname;
|
||||||
@synthesize tlsAlpnProtocols = _tlsAlpnProtocols;
|
@synthesize tlsAlpnProtocols = _tlsAlpnProtocols;
|
||||||
|
@synthesize tlsEllipticCurves = _tlsEllipticCurves;
|
||||||
|
|
||||||
- (instancetype)initWithURLStrings:(NSArray<NSString *> *)urlStrings {
|
- (instancetype)initWithURLStrings:(NSArray<NSString *> *)urlStrings {
|
||||||
return [self initWithURLStrings:urlStrings
|
return [self initWithURLStrings:urlStrings
|
||||||
@ -57,7 +58,7 @@
|
|||||||
credential:credential
|
credential:credential
|
||||||
tlsCertPolicy:tlsCertPolicy
|
tlsCertPolicy:tlsCertPolicy
|
||||||
hostname:hostname
|
hostname:hostname
|
||||||
tlsAlpnProtocols:[NSMutableArray new]];
|
tlsAlpnProtocols:[NSArray array]];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (instancetype)initWithURLStrings:(NSArray<NSString *> *)urlStrings
|
- (instancetype)initWithURLStrings:(NSArray<NSString *> *)urlStrings
|
||||||
@ -66,6 +67,22 @@
|
|||||||
tlsCertPolicy:(RTCTlsCertPolicy)tlsCertPolicy
|
tlsCertPolicy:(RTCTlsCertPolicy)tlsCertPolicy
|
||||||
hostname:(NSString *)hostname
|
hostname:(NSString *)hostname
|
||||||
tlsAlpnProtocols:(NSArray<NSString *> *)tlsAlpnProtocols {
|
tlsAlpnProtocols:(NSArray<NSString *> *)tlsAlpnProtocols {
|
||||||
|
return [self initWithURLStrings:urlStrings
|
||||||
|
username:username
|
||||||
|
credential:credential
|
||||||
|
tlsCertPolicy:tlsCertPolicy
|
||||||
|
hostname:hostname
|
||||||
|
tlsAlpnProtocols:tlsAlpnProtocols
|
||||||
|
tlsEllipticCurves:[NSArray array]];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (instancetype)initWithURLStrings:(NSArray<NSString *> *)urlStrings
|
||||||
|
username:(NSString *)username
|
||||||
|
credential:(NSString *)credential
|
||||||
|
tlsCertPolicy:(RTCTlsCertPolicy)tlsCertPolicy
|
||||||
|
hostname:(NSString *)hostname
|
||||||
|
tlsAlpnProtocols:(NSArray<NSString *> *)tlsAlpnProtocols
|
||||||
|
tlsEllipticCurves:(NSArray<NSString *> *)tlsEllipticCurves {
|
||||||
NSParameterAssert(urlStrings.count);
|
NSParameterAssert(urlStrings.count);
|
||||||
if (self = [super init]) {
|
if (self = [super init]) {
|
||||||
_urlStrings = [[NSArray alloc] initWithArray:urlStrings copyItems:YES];
|
_urlStrings = [[NSArray alloc] initWithArray:urlStrings copyItems:YES];
|
||||||
@ -74,18 +91,20 @@
|
|||||||
_tlsCertPolicy = tlsCertPolicy;
|
_tlsCertPolicy = tlsCertPolicy;
|
||||||
_hostname = [hostname copy];
|
_hostname = [hostname copy];
|
||||||
_tlsAlpnProtocols = [[NSArray alloc] initWithArray:tlsAlpnProtocols copyItems:YES];
|
_tlsAlpnProtocols = [[NSArray alloc] initWithArray:tlsAlpnProtocols copyItems:YES];
|
||||||
|
_tlsEllipticCurves = [[NSArray alloc] initWithArray:tlsEllipticCurves copyItems:YES];
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSString *)description {
|
- (NSString *)description {
|
||||||
return [NSString stringWithFormat:@"RTCIceServer:\n%@\n%@\n%@\n%@\n%@\n%@",
|
return [NSString stringWithFormat:@"RTCIceServer:\n%@\n%@\n%@\n%@\n%@\n%@\n%@",
|
||||||
_urlStrings,
|
_urlStrings,
|
||||||
_username,
|
_username,
|
||||||
_credential,
|
_credential,
|
||||||
[self stringForTlsCertPolicy:_tlsCertPolicy],
|
[self stringForTlsCertPolicy:_tlsCertPolicy],
|
||||||
_hostname,
|
_hostname,
|
||||||
_tlsAlpnProtocols];
|
_tlsAlpnProtocols,
|
||||||
|
_tlsEllipticCurves];
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - Private
|
#pragma mark - Private
|
||||||
@ -110,6 +129,10 @@
|
|||||||
iceServer.tls_alpn_protocols.push_back(proto.stdString);
|
iceServer.tls_alpn_protocols.push_back(proto.stdString);
|
||||||
}];
|
}];
|
||||||
|
|
||||||
|
[_tlsEllipticCurves enumerateObjectsUsingBlock:^(NSString *curve, NSUInteger idx, BOOL *stop) {
|
||||||
|
iceServer.tls_elliptic_curves.push_back(curve.stdString);
|
||||||
|
}];
|
||||||
|
|
||||||
[_urlStrings enumerateObjectsUsingBlock:^(NSString *url,
|
[_urlStrings enumerateObjectsUsingBlock:^(NSString *url,
|
||||||
NSUInteger idx,
|
NSUInteger idx,
|
||||||
BOOL *stop) {
|
BOOL *stop) {
|
||||||
@ -144,6 +167,11 @@
|
|||||||
for (auto const &proto : nativeServer.tls_alpn_protocols) {
|
for (auto const &proto : nativeServer.tls_alpn_protocols) {
|
||||||
[tlsAlpnProtocols addObject:[NSString stringForStdString:proto]];
|
[tlsAlpnProtocols addObject:[NSString stringForStdString:proto]];
|
||||||
}
|
}
|
||||||
|
NSMutableArray *tlsEllipticCurves =
|
||||||
|
[NSMutableArray arrayWithCapacity:nativeServer.tls_elliptic_curves.size()];
|
||||||
|
for (auto const &curve : nativeServer.tls_elliptic_curves) {
|
||||||
|
[tlsEllipticCurves addObject:[NSString stringForStdString:curve]];
|
||||||
|
}
|
||||||
RTCTlsCertPolicy tlsCertPolicy;
|
RTCTlsCertPolicy tlsCertPolicy;
|
||||||
|
|
||||||
switch (nativeServer.tls_cert_policy) {
|
switch (nativeServer.tls_cert_policy) {
|
||||||
@ -160,7 +188,8 @@
|
|||||||
credential:credential
|
credential:credential
|
||||||
tlsCertPolicy:tlsCertPolicy
|
tlsCertPolicy:tlsCertPolicy
|
||||||
hostname:hostname
|
hostname:hostname
|
||||||
tlsAlpnProtocols:tlsAlpnProtocols];
|
tlsAlpnProtocols:tlsAlpnProtocols
|
||||||
|
tlsEllipticCurves:tlsEllipticCurves];
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -46,6 +46,12 @@ RTC_EXPORT
|
|||||||
/** List of protocols to be used in the TLS ALPN extension. */
|
/** List of protocols to be used in the TLS ALPN extension. */
|
||||||
@property(nonatomic, readonly) NSArray<NSString *> *tlsAlpnProtocols;
|
@property(nonatomic, readonly) NSArray<NSString *> *tlsAlpnProtocols;
|
||||||
|
|
||||||
|
/**
|
||||||
|
List elliptic curves to be used in the TLS elliptic curves extension.
|
||||||
|
Only curve names supported by OpenSSL should be used (eg. "P-256","X25519").
|
||||||
|
*/
|
||||||
|
@property(nonatomic, readonly) NSArray<NSString *> *tlsEllipticCurves;
|
||||||
|
|
||||||
- (nonnull instancetype)init NS_UNAVAILABLE;
|
- (nonnull instancetype)init NS_UNAVAILABLE;
|
||||||
|
|
||||||
/** Convenience initializer for a server with no authentication (e.g. STUN). */
|
/** Convenience initializer for a server with no authentication (e.g. STUN). */
|
||||||
@ -87,7 +93,20 @@ RTC_EXPORT
|
|||||||
credential:(nullable NSString *)credential
|
credential:(nullable NSString *)credential
|
||||||
tlsCertPolicy:(RTCTlsCertPolicy)tlsCertPolicy
|
tlsCertPolicy:(RTCTlsCertPolicy)tlsCertPolicy
|
||||||
hostname:(nullable NSString *)hostname
|
hostname:(nullable NSString *)hostname
|
||||||
tlsAlpnProtocols:(NSArray<NSString *> *)tlsAlpnProtocols
|
tlsAlpnProtocols:(NSArray<NSString *> *)tlsAlpnProtocols;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize an RTCIceServer with its associated URLs, optional username,
|
||||||
|
* optional credential, TLS cert policy, hostname, ALPN protocols and
|
||||||
|
* elliptic curves.
|
||||||
|
*/
|
||||||
|
- (instancetype)initWithURLStrings:(NSArray<NSString *> *)urlStrings
|
||||||
|
username:(nullable NSString *)username
|
||||||
|
credential:(nullable NSString *)credential
|
||||||
|
tlsCertPolicy:(RTCTlsCertPolicy)tlsCertPolicy
|
||||||
|
hostname:(nullable NSString *)hostname
|
||||||
|
tlsAlpnProtocols:(nullable NSArray<NSString *> *)tlsAlpnProtocols
|
||||||
|
tlsEllipticCurves:(nullable NSArray<NSString *> *)tlsEllipticCurves
|
||||||
NS_DESIGNATED_INITIALIZER;
|
NS_DESIGNATED_INITIALIZER;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@ -92,6 +92,24 @@
|
|||||||
EXPECT_EQ(2u, iceStruct.tls_alpn_protocols.size());
|
EXPECT_EQ(2u, iceStruct.tls_alpn_protocols.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)testTlsEllipticCurves {
|
||||||
|
RTCIceServer *server = [[RTCIceServer alloc] initWithURLStrings:@[ @"turn1:turn1.example.net" ]
|
||||||
|
username:@"username"
|
||||||
|
credential:@"credential"
|
||||||
|
tlsCertPolicy:RTCTlsCertPolicySecure
|
||||||
|
hostname:@"hostname"
|
||||||
|
tlsAlpnProtocols:@[ @"proto1", @"proto2" ]
|
||||||
|
tlsEllipticCurves:@[ @"curve1", @"curve2" ]];
|
||||||
|
webrtc::PeerConnectionInterface::IceServer iceStruct = server.nativeServer;
|
||||||
|
EXPECT_EQ(1u, iceStruct.urls.size());
|
||||||
|
EXPECT_EQ("turn1:turn1.example.net", iceStruct.urls.front());
|
||||||
|
EXPECT_EQ("username", iceStruct.username);
|
||||||
|
EXPECT_EQ("credential", iceStruct.password);
|
||||||
|
EXPECT_EQ("hostname", iceStruct.hostname);
|
||||||
|
EXPECT_EQ(2u, iceStruct.tls_alpn_protocols.size());
|
||||||
|
EXPECT_EQ(2u, iceStruct.tls_elliptic_curves.size());
|
||||||
|
}
|
||||||
|
|
||||||
- (void)testInitFromNativeServer {
|
- (void)testInitFromNativeServer {
|
||||||
webrtc::PeerConnectionInterface::IceServer nativeServer;
|
webrtc::PeerConnectionInterface::IceServer nativeServer;
|
||||||
nativeServer.username = "username";
|
nativeServer.username = "username";
|
||||||
@ -100,6 +118,8 @@
|
|||||||
nativeServer.hostname = "hostname";
|
nativeServer.hostname = "hostname";
|
||||||
nativeServer.tls_alpn_protocols.push_back("proto1");
|
nativeServer.tls_alpn_protocols.push_back("proto1");
|
||||||
nativeServer.tls_alpn_protocols.push_back("proto2");
|
nativeServer.tls_alpn_protocols.push_back("proto2");
|
||||||
|
nativeServer.tls_elliptic_curves.push_back("curve1");
|
||||||
|
nativeServer.tls_elliptic_curves.push_back("curve2");
|
||||||
|
|
||||||
RTCIceServer *iceServer =
|
RTCIceServer *iceServer =
|
||||||
[[RTCIceServer alloc] initWithNativeServer:nativeServer];
|
[[RTCIceServer alloc] initWithNativeServer:nativeServer];
|
||||||
@ -110,6 +130,7 @@
|
|||||||
EXPECT_EQ("password", [NSString stdStringForString:iceServer.credential]);
|
EXPECT_EQ("password", [NSString stdStringForString:iceServer.credential]);
|
||||||
EXPECT_EQ("hostname", [NSString stdStringForString:iceServer.hostname]);
|
EXPECT_EQ("hostname", [NSString stdStringForString:iceServer.hostname]);
|
||||||
EXPECT_EQ(2u, iceServer.tlsAlpnProtocols.count);
|
EXPECT_EQ(2u, iceServer.tlsAlpnProtocols.count);
|
||||||
|
EXPECT_EQ(2u, iceServer.tlsEllipticCurves.count);
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
Reference in New Issue
Block a user