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;
|
||||
// List of protocols to be used in the TLS ALPN extension.
|
||||
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 {
|
||||
return uri == o.uri && urls == o.urls && username == o.username &&
|
||||
password == o.password && tls_cert_policy == o.tls_cert_policy &&
|
||||
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); }
|
||||
};
|
||||
|
||||
@ -159,6 +159,7 @@ AsyncPacketSocket* BasicPacketSocketFactory::CreateClientTcpSocket(
|
||||
}
|
||||
|
||||
ssl_adapter->SetAlpnProtocols(tcp_options.tls_alpn_protocols);
|
||||
ssl_adapter->SetEllipticCurves(tcp_options.tls_elliptic_curves);
|
||||
|
||||
socket = ssl_adapter;
|
||||
|
||||
|
||||
@ -20,6 +20,7 @@ namespace rtc {
|
||||
struct PacketSocketTcpOptions {
|
||||
int opts;
|
||||
std::vector<std::string> tls_alpn_protocols;
|
||||
std::vector<std::string> tls_elliptic_curves;
|
||||
};
|
||||
|
||||
class AsyncPacketSocket;
|
||||
|
||||
@ -536,7 +536,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::string(), std::vector<std::string>(), std::vector<std::string>());
|
||||
}
|
||||
RelayPort* CreateGturnPort(const SocketAddress& addr,
|
||||
ProtocolType int_proto, ProtocolType ext_proto) {
|
||||
|
||||
@ -192,6 +192,7 @@ struct RelayServerConfig {
|
||||
int priority = 0;
|
||||
TlsCertPolicy tls_cert_policy = TlsCertPolicy::TLS_CERT_POLICY_SECURE;
|
||||
std::vector<std::string> tls_alpn_protocols;
|
||||
std::vector<std::string> tls_elliptic_curves;
|
||||
};
|
||||
|
||||
class PortAllocatorSession : public sigslot::has_slots<> {
|
||||
|
||||
@ -222,7 +222,8 @@ TurnPort::TurnPort(rtc::Thread* thread,
|
||||
const RelayCredentials& credentials,
|
||||
int server_priority,
|
||||
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,
|
||||
RELAY_PORT_TYPE,
|
||||
factory,
|
||||
@ -233,6 +234,7 @@ TurnPort::TurnPort(rtc::Thread* thread,
|
||||
password),
|
||||
server_address_(server_address),
|
||||
tls_alpn_protocols_(tls_alpn_protocols),
|
||||
tls_elliptic_curves_(tls_elliptic_curves),
|
||||
credentials_(credentials),
|
||||
socket_(NULL),
|
||||
resolver_(NULL),
|
||||
@ -341,6 +343,7 @@ 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_;
|
||||
socket_ = socket_factory()->CreateClientTcpSocket(
|
||||
rtc::SocketAddress(Network()->GetBestIP(), 0), server_address_.address,
|
||||
proxy(), user_agent(), tcp_options);
|
||||
|
||||
@ -70,10 +70,11 @@ class TurnPort : public Port {
|
||||
const RelayCredentials& credentials,
|
||||
int server_priority,
|
||||
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,
|
||||
password, server_address, credentials, server_priority,
|
||||
origin, tls_alpn_protocols);
|
||||
origin, tls_alpn_protocols, tls_elliptic_curves);
|
||||
}
|
||||
|
||||
virtual ~TurnPort();
|
||||
@ -100,6 +101,10 @@ class TurnPort : public Port {
|
||||
return tls_alpn_protocols_;
|
||||
}
|
||||
|
||||
virtual std::vector<std::string> GetTlsEllipticCurves() const {
|
||||
return tls_elliptic_curves_;
|
||||
}
|
||||
|
||||
virtual void PrepareAddress();
|
||||
virtual Connection* CreateConnection(
|
||||
const Candidate& c, PortInterface::CandidateOrigin origin);
|
||||
@ -192,7 +197,8 @@ class TurnPort : public Port {
|
||||
const RelayCredentials& credentials,
|
||||
int server_priority,
|
||||
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:
|
||||
enum {
|
||||
@ -273,6 +279,7 @@ class TurnPort : public Port {
|
||||
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_;
|
||||
RelayCredentials credentials_;
|
||||
AttemptedServerSet attempted_server_addresses_;
|
||||
|
||||
|
||||
@ -263,7 +263,8 @@ class TurnPortTest : public testing::Test,
|
||||
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>()));
|
||||
server_address, credentials, 0, origin, std::vector<std::string>(),
|
||||
std::vector<std::string>()));
|
||||
// This TURN port will be the controlling.
|
||||
turn_port_->SetIceRole(ICEROLE_CONTROLLING);
|
||||
ConnectSignals();
|
||||
|
||||
@ -1445,7 +1445,7 @@ void AllocationSequence::CreateTurnPort(const RelayServerConfig& config) {
|
||||
session_->allocator()->min_port(), session_->allocator()->max_port(),
|
||||
session_->username(), session_->password(), *relay_port,
|
||||
config.credentials, config.priority, session_->allocator()->origin(),
|
||||
config.tls_alpn_protocols);
|
||||
config.tls_alpn_protocols, config.tls_elliptic_curves);
|
||||
}
|
||||
RTC_DCHECK(port != NULL);
|
||||
port->SetTlsCertPolicy(config.tls_cert_policy);
|
||||
|
||||
@ -258,6 +258,7 @@ static RTCErrorType ParseIceServerUrl(
|
||||
cricket::TlsCertPolicy::TLS_CERT_POLICY_INSECURE_NO_CHECK;
|
||||
}
|
||||
config.tls_alpn_protocols = server.tls_alpn_protocols;
|
||||
config.tls_elliptic_curves = server.tls_elliptic_curves;
|
||||
|
||||
turn_servers->push_back(config);
|
||||
break;
|
||||
|
||||
@ -31,6 +31,7 @@
|
||||
#include "webrtc/rtc_base/openssl.h"
|
||||
#include "webrtc/rtc_base/safe_conversions.h"
|
||||
#include "webrtc/rtc_base/sslroots.h"
|
||||
#include "webrtc/rtc_base/stringencode.h"
|
||||
#include "webrtc/rtc_base/stringutils.h"
|
||||
#include "webrtc/rtc_base/thread.h"
|
||||
|
||||
@ -311,6 +312,10 @@ void OpenSSLAdapter::SetAlpnProtocols(const std::vector<std::string>& protos) {
|
||||
alpn_protocols_ = protos;
|
||||
}
|
||||
|
||||
void OpenSSLAdapter::SetEllipticCurves(const std::vector<std::string>& curves) {
|
||||
elliptic_curves_ = curves;
|
||||
}
|
||||
|
||||
void OpenSSLAdapter::SetMode(SSLMode mode) {
|
||||
RTC_DCHECK(!ssl_ctx_);
|
||||
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
|
||||
// SSL object. If ContinueSSL() fails, the bio will be freed in Cleanup().
|
||||
SSL_set_bio(ssl_, bio, bio);
|
||||
|
||||
@ -40,6 +40,7 @@ class OpenSSLAdapter : public SSLAdapter, public MessageHandler {
|
||||
|
||||
void SetIgnoreBadCert(bool ignore) 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 SetIdentity(SSLIdentity* identity) override;
|
||||
@ -136,6 +137,8 @@ class OpenSSLAdapter : public SSLAdapter, public MessageHandler {
|
||||
bool ignore_bad_cert_;
|
||||
// List of protocols to be used in the TLS ALPN extension.
|
||||
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_;
|
||||
};
|
||||
|
||||
@ -48,7 +48,9 @@ class SSLAdapter : public AsyncSocketAdapter {
|
||||
// TODO(juberti): Remove the opportunistic encryption mechanism in
|
||||
// BasicPacketSocketFactory that uses this function.
|
||||
virtual void SetIgnoreBadCert(bool ignore) = 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)
|
||||
virtual void SetMode(SSLMode mode) = 0;
|
||||
|
||||
@ -64,6 +64,10 @@ class SSLAdapterTestDummyClient : public sigslot::has_slots<> {
|
||||
ssl_adapter_->SetAlpnProtocols(protos);
|
||||
}
|
||||
|
||||
void SetEllipticCurves(const std::vector<std::string>& curves) {
|
||||
ssl_adapter_->SetEllipticCurves(curves);
|
||||
}
|
||||
|
||||
rtc::SocketAddress GetAddress() const {
|
||||
return ssl_adapter_->GetLocalAddress();
|
||||
}
|
||||
@ -290,6 +294,10 @@ class SSLAdapterTestBase : public testing::Test,
|
||||
client_->SetAlpnProtocols(protos);
|
||||
}
|
||||
|
||||
void SetEllipticCurves(const std::vector<std::string>& curves) {
|
||||
client_->SetEllipticCurves(curves);
|
||||
}
|
||||
|
||||
void TestHandshake(bool expect_success) {
|
||||
int rv;
|
||||
|
||||
@ -450,6 +458,14 @@ TEST_F(SSLAdapterTestTLS_ECDSA, TestTLSALPN) {
|
||||
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
|
||||
|
||||
// Test that handshake works, using RSA
|
||||
|
||||
@ -645,6 +645,28 @@ bool tokenize_first(const std::string& source,
|
||||
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,
|
||||
std::vector<std::string>* fields) {
|
||||
RTC_DCHECK(fields);
|
||||
|
||||
@ -136,6 +136,10 @@ inline std::string s_url_decode(const std::string& source) {
|
||||
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,
|
||||
// with duplicates of delimiter creating empty fields.
|
||||
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.
|
||||
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. */
|
||||
@Deprecated
|
||||
public IceServer(String uri) {
|
||||
@ -132,22 +136,23 @@ public class PeerConnection {
|
||||
@Deprecated
|
||||
public IceServer(String uri, String username, String password, TlsCertPolicy tlsCertPolicy,
|
||||
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,
|
||||
String hostname, List<String> tlsAlpnProtocols) {
|
||||
String hostname, List<String> tlsAlpnProtocols, List<String> tlsEllipticCurves) {
|
||||
this.uri = uri;
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
this.tlsCertPolicy = tlsCertPolicy;
|
||||
this.hostname = hostname;
|
||||
this.tlsAlpnProtocols = tlsAlpnProtocols;
|
||||
this.tlsEllipticCurves = tlsEllipticCurves;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return uri + " [" + username + ":" + password + "] [" + tlsCertPolicy + "] [" + hostname
|
||||
+ "] [" + tlsAlpnProtocols + "]";
|
||||
+ "] [" + tlsAlpnProtocols + "] [" + tlsEllipticCurves + "]";
|
||||
}
|
||||
|
||||
public static Builder builder(String uri) {
|
||||
@ -161,6 +166,7 @@ public class PeerConnection {
|
||||
private TlsCertPolicy tlsCertPolicy = TlsCertPolicy.TLS_CERT_POLICY_SECURE;
|
||||
private String hostname = "";
|
||||
private List<String> tlsAlpnProtocols;
|
||||
private List<String> tlsEllipticCurves;
|
||||
|
||||
private Builder(String uri) {
|
||||
this.uri = uri;
|
||||
@ -191,8 +197,14 @@ public class PeerConnection {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setTlsEllipticCurves(List<String> tlsEllipticCurves) {
|
||||
this.tlsEllipticCurves = tlsEllipticCurves;
|
||||
return this;
|
||||
}
|
||||
|
||||
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;");
|
||||
jfieldID j_ice_server_tls_alpn_protocols_id = GetFieldID(
|
||||
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>(
|
||||
GetObjectField(jni, j_ice_server, j_ice_server_uri_id));
|
||||
jstring username = reinterpret_cast<jstring>(
|
||||
@ -376,6 +378,8 @@ void JavaToNativeIceServers(JNIEnv* jni,
|
||||
GetObjectField(jni, j_ice_server, j_ice_server_hostname_id));
|
||||
jobject tls_alpn_protocols = GetNullableObjectField(
|
||||
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;
|
||||
server.uri = JavaToStdString(jni, uri);
|
||||
server.username = JavaToStdString(jni, username);
|
||||
@ -383,6 +387,8 @@ void JavaToNativeIceServers(JNIEnv* jni,
|
||||
server.tls_cert_policy = tls_cert_policy;
|
||||
server.hostname = JavaToStdString(jni, hostname);
|
||||
server.tls_alpn_protocols = JavaToStdVectorStrings(jni, tls_alpn_protocols);
|
||||
server.tls_elliptic_curves =
|
||||
JavaToStdVectorStrings(jni, tls_elliptic_curves);
|
||||
ice_servers->push_back(server);
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,6 +20,7 @@
|
||||
@synthesize tlsCertPolicy = _tlsCertPolicy;
|
||||
@synthesize hostname = _hostname;
|
||||
@synthesize tlsAlpnProtocols = _tlsAlpnProtocols;
|
||||
@synthesize tlsEllipticCurves = _tlsEllipticCurves;
|
||||
|
||||
- (instancetype)initWithURLStrings:(NSArray<NSString *> *)urlStrings {
|
||||
return [self initWithURLStrings:urlStrings
|
||||
@ -57,7 +58,7 @@
|
||||
credential:credential
|
||||
tlsCertPolicy:tlsCertPolicy
|
||||
hostname:hostname
|
||||
tlsAlpnProtocols:[NSMutableArray new]];
|
||||
tlsAlpnProtocols:[NSArray array]];
|
||||
}
|
||||
|
||||
- (instancetype)initWithURLStrings:(NSArray<NSString *> *)urlStrings
|
||||
@ -66,6 +67,22 @@
|
||||
tlsCertPolicy:(RTCTlsCertPolicy)tlsCertPolicy
|
||||
hostname:(NSString *)hostname
|
||||
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);
|
||||
if (self = [super init]) {
|
||||
_urlStrings = [[NSArray alloc] initWithArray:urlStrings copyItems:YES];
|
||||
@ -74,18 +91,20 @@
|
||||
_tlsCertPolicy = tlsCertPolicy;
|
||||
_hostname = [hostname copy];
|
||||
_tlsAlpnProtocols = [[NSArray alloc] initWithArray:tlsAlpnProtocols copyItems:YES];
|
||||
_tlsEllipticCurves = [[NSArray alloc] initWithArray:tlsEllipticCurves copyItems:YES];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSString *)description {
|
||||
return [NSString stringWithFormat:@"RTCIceServer:\n%@\n%@\n%@\n%@\n%@\n%@",
|
||||
return [NSString stringWithFormat:@"RTCIceServer:\n%@\n%@\n%@\n%@\n%@\n%@\n%@",
|
||||
_urlStrings,
|
||||
_username,
|
||||
_credential,
|
||||
[self stringForTlsCertPolicy:_tlsCertPolicy],
|
||||
_hostname,
|
||||
_tlsAlpnProtocols];
|
||||
_tlsAlpnProtocols,
|
||||
_tlsEllipticCurves];
|
||||
}
|
||||
|
||||
#pragma mark - Private
|
||||
@ -110,6 +129,10 @@
|
||||
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,
|
||||
NSUInteger idx,
|
||||
BOOL *stop) {
|
||||
@ -144,6 +167,11 @@
|
||||
for (auto const &proto : nativeServer.tls_alpn_protocols) {
|
||||
[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;
|
||||
|
||||
switch (nativeServer.tls_cert_policy) {
|
||||
@ -160,7 +188,8 @@
|
||||
credential:credential
|
||||
tlsCertPolicy:tlsCertPolicy
|
||||
hostname:hostname
|
||||
tlsAlpnProtocols:tlsAlpnProtocols];
|
||||
tlsAlpnProtocols:tlsAlpnProtocols
|
||||
tlsEllipticCurves:tlsEllipticCurves];
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
@ -46,6 +46,12 @@ RTC_EXPORT
|
||||
/** List of protocols to be used in the TLS ALPN extension. */
|
||||
@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;
|
||||
|
||||
/** Convenience initializer for a server with no authentication (e.g. STUN). */
|
||||
@ -87,7 +93,20 @@ RTC_EXPORT
|
||||
credential:(nullable NSString *)credential
|
||||
tlsCertPolicy:(RTCTlsCertPolicy)tlsCertPolicy
|
||||
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;
|
||||
|
||||
@end
|
||||
|
||||
@ -92,6 +92,24 @@
|
||||
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 {
|
||||
webrtc::PeerConnectionInterface::IceServer nativeServer;
|
||||
nativeServer.username = "username";
|
||||
@ -100,6 +118,8 @@
|
||||
nativeServer.hostname = "hostname";
|
||||
nativeServer.tls_alpn_protocols.push_back("proto1");
|
||||
nativeServer.tls_alpn_protocols.push_back("proto2");
|
||||
nativeServer.tls_elliptic_curves.push_back("curve1");
|
||||
nativeServer.tls_elliptic_curves.push_back("curve2");
|
||||
|
||||
RTCIceServer *iceServer =
|
||||
[[RTCIceServer alloc] initWithNativeServer:nativeServer];
|
||||
@ -110,6 +130,7 @@
|
||||
EXPECT_EQ("password", [NSString stdStringForString:iceServer.credential]);
|
||||
EXPECT_EQ("hostname", [NSString stdStringForString:iceServer.hostname]);
|
||||
EXPECT_EQ(2u, iceServer.tlsAlpnProtocols.count);
|
||||
EXPECT_EQ(2u, iceServer.tlsEllipticCurves.count);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user