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}
diff --git a/webrtc/sdk/objc/Framework/Classes/PeerConnection/RTCIceServer.mm b/webrtc/sdk/objc/Framework/Classes/PeerConnection/RTCIceServer.mm
index a28e237..eeb1177 100644
--- a/webrtc/sdk/objc/Framework/Classes/PeerConnection/RTCIceServer.mm
+++ b/webrtc/sdk/objc/Framework/Classes/PeerConnection/RTCIceServer.mm
@@ -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;
 }
 
diff --git a/webrtc/sdk/objc/Framework/Headers/WebRTC/RTCIceServer.h b/webrtc/sdk/objc/Framework/Headers/WebRTC/RTCIceServer.h
index e9baa8f..727da8a 100644
--- a/webrtc/sdk/objc/Framework/Headers/WebRTC/RTCIceServer.h
+++ b/webrtc/sdk/objc/Framework/Headers/WebRTC/RTCIceServer.h
@@ -46,6 +46,12 @@
 /** 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 @@
                         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
diff --git a/webrtc/sdk/objc/Framework/UnitTests/RTCIceServerTest.mm b/webrtc/sdk/objc/Framework/UnitTests/RTCIceServerTest.mm
index 9d42c07..669ede6 100644
--- a/webrtc/sdk/objc/Framework/UnitTests/RTCIceServerTest.mm
+++ b/webrtc/sdk/objc/Framework/UnitTests/RTCIceServerTest.mm
@@ -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