blob: a40312ffca558bcd4f50325135fab35a2233ca7c [file] [log] [blame]
deadbeef49f34fd2016-12-06 16:22:06 -08001/*
2 * Copyright 2011 The WebRTC Project Authors. All rights reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
Taylor Brandstetter6e2e7ce2017-12-19 10:26:23 -080010#include "pc/jseptransport.h"
deadbeef49f34fd2016-12-06 16:22:06 -080011
12#include <memory>
13
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020014#include "p2p/base/fakedtlstransport.h"
15#include "p2p/base/fakeicetransport.h"
16#include "rtc_base/fakesslidentity.h"
17#include "rtc_base/gunit.h"
18#include "rtc_base/network.h"
deadbeef49f34fd2016-12-06 16:22:06 -080019
Taylor Brandstetter74cefe12017-12-14 15:38:57 -080020namespace cricket {
21
deadbeef49f34fd2016-12-06 16:22:06 -080022using rtc::SocketAddress;
Steve Anton3828c062017-12-06 10:34:51 -080023using webrtc::SdpType;
deadbeef49f34fd2016-12-06 16:22:06 -080024
25static const char kIceUfrag1[] = "TESTICEUFRAG0001";
26static const char kIcePwd1[] = "TESTICEPWD00000000000001";
27
28static const char kIceUfrag2[] = "TESTICEUFRAG0002";
29static const char kIcePwd2[] = "TESTICEPWD00000000000002";
30
Taylor Brandstetter74cefe12017-12-14 15:38:57 -080031TransportDescription MakeTransportDescription(
32 const char* ufrag,
33 const char* pwd,
34 const rtc::scoped_refptr<rtc::RTCCertificate>& cert,
35 ConnectionRole role = CONNECTIONROLE_NONE) {
36 std::unique_ptr<rtc::SSLFingerprint> fingerprint;
37 if (cert) {
38 fingerprint.reset(rtc::SSLFingerprint::CreateFromCertificate(cert));
39 }
40 return TransportDescription(std::vector<std::string>(), ufrag, pwd,
41 ICEMODE_FULL, role, fingerprint.get());
42}
43
deadbeef49f34fd2016-12-06 16:22:06 -080044class JsepTransportTest : public testing::Test, public sigslot::has_slots<> {
45 public:
deadbeefd8cfa1a2017-03-27 10:33:26 -070046 JsepTransportTest() { RecreateTransport(); }
47
Taylor Brandstetter74cefe12017-12-14 15:38:57 -080048 bool SetupFakeTransports(int component) {
49 fake_ice_transports_.emplace_back(
50 new FakeIceTransport(transport_->mid(), component));
51 fake_dtls_transports_.emplace_back(
52 new FakeDtlsTransport(fake_ice_transports_.back().get()));
53 return transport_->AddChannel(fake_dtls_transports_.back().get(),
54 component);
deadbeef49f34fd2016-12-06 16:22:06 -080055 }
deadbeefd8cfa1a2017-03-27 10:33:26 -070056
Taylor Brandstetter74cefe12017-12-14 15:38:57 -080057 void DestroyChannel(int component) { transport_->RemoveChannel(component); }
deadbeef49f34fd2016-12-06 16:22:06 -080058
deadbeefd8cfa1a2017-03-27 10:33:26 -070059 void RecreateTransport() {
60 transport_.reset(new JsepTransport("test content name", nullptr));
61 }
62
Taylor Brandstetter6e2e7ce2017-12-19 10:26:23 -080063 bool IceCredentialsChanged(const std::string& old_ufrag,
64 const std::string& old_pwd,
65 const std::string& new_ufrag,
66 const std::string& new_pwd) {
67 return (old_ufrag != new_ufrag) || (old_pwd != new_pwd);
68 }
69
deadbeef49f34fd2016-12-06 16:22:06 -080070 protected:
Taylor Brandstetter74cefe12017-12-14 15:38:57 -080071 std::vector<std::unique_ptr<FakeDtlsTransport>> fake_dtls_transports_;
72 std::vector<std::unique_ptr<FakeIceTransport>> fake_ice_transports_;
deadbeef49f34fd2016-12-06 16:22:06 -080073 std::unique_ptr<JsepTransport> transport_;
74};
75
Taylor Brandstetter74cefe12017-12-14 15:38:57 -080076// This test verifies transports are created with proper ICE ufrag/password
77// after a transport description is applied.
78TEST_F(JsepTransportTest, TestIceTransportParameters) {
79 EXPECT_TRUE(SetupFakeTransports(1));
80 TransportDescription local_desc(kIceUfrag1, kIcePwd1);
Steve Anton3828c062017-12-06 10:34:51 -080081 ASSERT_TRUE(transport_->SetLocalTransportDescription(local_desc,
82 SdpType::kOffer, NULL));
Taylor Brandstetter74cefe12017-12-14 15:38:57 -080083 EXPECT_EQ(ICEMODE_FULL, fake_ice_transports_[0]->remote_ice_mode());
84 EXPECT_EQ(kIceUfrag1, fake_ice_transports_[0]->ice_ufrag());
85 EXPECT_EQ(kIcePwd1, fake_ice_transports_[0]->ice_pwd());
deadbeef49f34fd2016-12-06 16:22:06 -080086
Taylor Brandstetter74cefe12017-12-14 15:38:57 -080087 TransportDescription remote_desc(kIceUfrag2, kIcePwd2);
deadbeef49f34fd2016-12-06 16:22:06 -080088 ASSERT_TRUE(transport_->SetRemoteTransportDescription(
Steve Anton3828c062017-12-06 10:34:51 -080089 remote_desc, SdpType::kAnswer, NULL));
Taylor Brandstetter74cefe12017-12-14 15:38:57 -080090 EXPECT_EQ(ICEMODE_FULL, fake_ice_transports_[0]->remote_ice_mode());
91 EXPECT_EQ(kIceUfrag2, fake_ice_transports_[0]->remote_ice_ufrag());
92 EXPECT_EQ(kIcePwd2, fake_ice_transports_[0]->remote_ice_pwd());
93}
94
95// Similarly, test that DTLS parameters are applied after a transport
96// description is applied.
97TEST_F(JsepTransportTest, TestDtlsTransportParameters) {
98 EXPECT_TRUE(SetupFakeTransports(1));
99
100 // Create certificates.
101 rtc::scoped_refptr<rtc::RTCCertificate> local_cert =
102 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
103 rtc::SSLIdentity::Generate("local", rtc::KT_DEFAULT)));
104 rtc::scoped_refptr<rtc::RTCCertificate> remote_cert =
105 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
106 rtc::SSLIdentity::Generate("remote", rtc::KT_DEFAULT)));
107 transport_->SetLocalCertificate(local_cert);
108
109 // Apply offer/answer.
110 TransportDescription local_desc = MakeTransportDescription(
111 kIceUfrag1, kIcePwd1, local_cert, CONNECTIONROLE_ACTPASS);
112 ASSERT_TRUE(transport_->SetLocalTransportDescription(
113 local_desc, SdpType::kOffer, nullptr));
114 TransportDescription remote_desc = MakeTransportDescription(
115 kIceUfrag2, kIcePwd2, remote_cert, CONNECTIONROLE_ACTIVE);
116 ASSERT_TRUE(transport_->SetRemoteTransportDescription(
117 remote_desc, SdpType::kAnswer, nullptr));
118
119 // Verify that SSL role and remote fingerprint were set correctly based on
120 // transport descriptions.
121 rtc::SSLRole role;
Zhi Huange818b6e2018-02-22 15:26:27 -0800122 EXPECT_TRUE(fake_dtls_transports_[0]->GetDtlsRole(&role));
Taylor Brandstetter74cefe12017-12-14 15:38:57 -0800123 EXPECT_EQ(rtc::SSL_SERVER, role); // Because remote description was "active".
124 EXPECT_EQ(remote_desc.identity_fingerprint->ToString(),
125 fake_dtls_transports_[0]->dtls_fingerprint().ToString());
126}
127
128// Same as above test, but with remote transport description using
129// CONNECTIONROLE_PASSIVE, expecting SSL_CLIENT role.
130TEST_F(JsepTransportTest, TestDtlsTransportParametersWithPassiveAnswer) {
131 EXPECT_TRUE(SetupFakeTransports(1));
132
133 // Create certificates.
134 rtc::scoped_refptr<rtc::RTCCertificate> local_cert =
135 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
136 rtc::SSLIdentity::Generate("local", rtc::KT_DEFAULT)));
137 rtc::scoped_refptr<rtc::RTCCertificate> remote_cert =
138 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
139 rtc::SSLIdentity::Generate("remote", rtc::KT_DEFAULT)));
140 transport_->SetLocalCertificate(local_cert);
141
142 // Apply offer/answer.
143 TransportDescription local_desc = MakeTransportDescription(
144 kIceUfrag1, kIcePwd1, local_cert, CONNECTIONROLE_ACTPASS);
145 ASSERT_TRUE(transport_->SetLocalTransportDescription(
146 local_desc, SdpType::kOffer, nullptr));
147 TransportDescription remote_desc = MakeTransportDescription(
148 kIceUfrag2, kIcePwd2, remote_cert, CONNECTIONROLE_PASSIVE);
149 ASSERT_TRUE(transport_->SetRemoteTransportDescription(
150 remote_desc, SdpType::kAnswer, nullptr));
151
152 // Verify that SSL role and remote fingerprint were set correctly based on
153 // transport descriptions.
154 rtc::SSLRole role;
Zhi Huange818b6e2018-02-22 15:26:27 -0800155 EXPECT_TRUE(fake_dtls_transports_[0]->GetDtlsRole(&role));
Taylor Brandstetter74cefe12017-12-14 15:38:57 -0800156 EXPECT_EQ(rtc::SSL_CLIENT,
157 role); // Because remote description was "passive".
158 EXPECT_EQ(remote_desc.identity_fingerprint->ToString(),
159 fake_dtls_transports_[0]->dtls_fingerprint().ToString());
160}
161
162// Add two DtlsTransports/IceTransports and make sure parameters are applied to
163// both of them. Applicable when RTP/RTCP are not multiplexed, so they share
164// the same parameters but different connections.
165TEST_F(JsepTransportTest, TestTransportParametersAppliedToTwoComponents) {
166 EXPECT_TRUE(SetupFakeTransports(1));
167 EXPECT_TRUE(SetupFakeTransports(2));
168
169 // Create certificates.
170 rtc::scoped_refptr<rtc::RTCCertificate> local_cert =
171 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
172 rtc::SSLIdentity::Generate("local", rtc::KT_DEFAULT)));
173 rtc::scoped_refptr<rtc::RTCCertificate> remote_cert =
174 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
175 rtc::SSLIdentity::Generate("remote", rtc::KT_DEFAULT)));
176 transport_->SetLocalCertificate(local_cert);
177
178 // Apply offer/answer.
179 TransportDescription local_desc = MakeTransportDescription(
180 kIceUfrag1, kIcePwd1, local_cert, CONNECTIONROLE_ACTPASS);
181 ASSERT_TRUE(transport_->SetLocalTransportDescription(
182 local_desc, SdpType::kOffer, nullptr));
183 TransportDescription remote_desc = MakeTransportDescription(
184 kIceUfrag2, kIcePwd2, remote_cert, CONNECTIONROLE_ACTIVE);
185 ASSERT_TRUE(transport_->SetRemoteTransportDescription(
186 remote_desc, SdpType::kAnswer, nullptr));
187
188 for (int i = 0; i < 1; ++i) {
189 // Verify parameters of ICE transports.
190 EXPECT_EQ(ICEMODE_FULL, fake_ice_transports_[i]->remote_ice_mode());
191 EXPECT_EQ(kIceUfrag1, fake_ice_transports_[i]->ice_ufrag());
192 EXPECT_EQ(kIcePwd1, fake_ice_transports_[i]->ice_pwd());
193 EXPECT_EQ(kIceUfrag2, fake_ice_transports_[i]->remote_ice_ufrag());
194 EXPECT_EQ(kIcePwd2, fake_ice_transports_[i]->remote_ice_pwd());
195 // Verify parameters of DTLS transports.
196 rtc::SSLRole role;
Zhi Huange818b6e2018-02-22 15:26:27 -0800197 EXPECT_TRUE(fake_dtls_transports_[i]->GetDtlsRole(&role));
Taylor Brandstetter74cefe12017-12-14 15:38:57 -0800198 EXPECT_EQ(rtc::SSL_SERVER,
199 role); // Because remote description was "active".
200 EXPECT_EQ(remote_desc.identity_fingerprint->ToString(),
201 fake_dtls_transports_[i]->dtls_fingerprint().ToString());
202 }
deadbeef49f34fd2016-12-06 16:22:06 -0800203}
204
205// Verifies that IceCredentialsChanged returns true when either ufrag or pwd
206// changed, and false in other cases.
207TEST_F(JsepTransportTest, TestIceCredentialsChanged) {
Taylor Brandstetter74cefe12017-12-14 15:38:57 -0800208 EXPECT_TRUE(IceCredentialsChanged("u1", "p1", "u2", "p2"));
209 EXPECT_TRUE(IceCredentialsChanged("u1", "p1", "u2", "p1"));
210 EXPECT_TRUE(IceCredentialsChanged("u1", "p1", "u1", "p2"));
211 EXPECT_FALSE(IceCredentialsChanged("u1", "p1", "u1", "p1"));
deadbeef49f34fd2016-12-06 16:22:06 -0800212}
213
deadbeefd1a38b52016-12-10 13:15:33 -0800214// Tests SetNeedsIceRestartFlag and NeedsIceRestart, ensuring NeedsIceRestart
215// only starts returning "false" once an ICE restart has been initiated.
216TEST_F(JsepTransportTest, NeedsIceRestart) {
217 // Do initial offer/answer so there's something to restart.
Taylor Brandstetter74cefe12017-12-14 15:38:57 -0800218 TransportDescription local_desc(kIceUfrag1, kIcePwd1);
219 TransportDescription remote_desc(kIceUfrag1, kIcePwd1);
deadbeefd1a38b52016-12-10 13:15:33 -0800220 ASSERT_TRUE(transport_->SetLocalTransportDescription(
Steve Anton3828c062017-12-06 10:34:51 -0800221 local_desc, SdpType::kOffer, nullptr));
deadbeefd1a38b52016-12-10 13:15:33 -0800222 ASSERT_TRUE(transport_->SetRemoteTransportDescription(
Steve Anton3828c062017-12-06 10:34:51 -0800223 remote_desc, SdpType::kAnswer, nullptr));
deadbeefd1a38b52016-12-10 13:15:33 -0800224
225 // Flag initially should be false.
226 EXPECT_FALSE(transport_->NeedsIceRestart());
227
228 // After setting flag, it should be true.
229 transport_->SetNeedsIceRestartFlag();
230 EXPECT_TRUE(transport_->NeedsIceRestart());
231
232 // Doing an identical offer/answer shouldn't clear the flag.
233 ASSERT_TRUE(transport_->SetLocalTransportDescription(
Steve Anton3828c062017-12-06 10:34:51 -0800234 local_desc, SdpType::kOffer, nullptr));
deadbeefd1a38b52016-12-10 13:15:33 -0800235 ASSERT_TRUE(transport_->SetRemoteTransportDescription(
Steve Anton3828c062017-12-06 10:34:51 -0800236 remote_desc, SdpType::kAnswer, nullptr));
deadbeefd1a38b52016-12-10 13:15:33 -0800237 EXPECT_TRUE(transport_->NeedsIceRestart());
238
239 // Doing an offer/answer that restarts ICE should clear the flag.
Taylor Brandstetter74cefe12017-12-14 15:38:57 -0800240 TransportDescription ice_restart_local_desc(kIceUfrag2, kIcePwd2);
241 TransportDescription ice_restart_remote_desc(kIceUfrag2, kIcePwd2);
deadbeefd1a38b52016-12-10 13:15:33 -0800242 ASSERT_TRUE(transport_->SetLocalTransportDescription(
Steve Anton3828c062017-12-06 10:34:51 -0800243 ice_restart_local_desc, SdpType::kOffer, nullptr));
deadbeefd1a38b52016-12-10 13:15:33 -0800244 ASSERT_TRUE(transport_->SetRemoteTransportDescription(
Steve Anton3828c062017-12-06 10:34:51 -0800245 ice_restart_remote_desc, SdpType::kAnswer, nullptr));
deadbeefd1a38b52016-12-10 13:15:33 -0800246 EXPECT_FALSE(transport_->NeedsIceRestart());
247}
248
deadbeef49f34fd2016-12-06 16:22:06 -0800249TEST_F(JsepTransportTest, TestGetStats) {
Taylor Brandstetter74cefe12017-12-14 15:38:57 -0800250 EXPECT_TRUE(SetupFakeTransports(1));
251 TransportStats stats;
deadbeef49f34fd2016-12-06 16:22:06 -0800252 EXPECT_TRUE(transport_->GetStats(&stats));
zhihuangb2cdd932017-01-19 16:54:25 -0800253 // Note that this tests the behavior of a FakeIceTransport.
deadbeef49f34fd2016-12-06 16:22:06 -0800254 ASSERT_EQ(1U, stats.channel_stats.size());
255 EXPECT_EQ(1, stats.channel_stats[0].component);
256 // Set local transport description for FakeTransport before connecting.
257 TransportDescription faketransport_desc(
Taylor Brandstetter74cefe12017-12-14 15:38:57 -0800258 std::vector<std::string>(), rtc::CreateRandomString(ICE_UFRAG_LENGTH),
259 rtc::CreateRandomString(ICE_PWD_LENGTH), ICEMODE_FULL,
260 CONNECTIONROLE_NONE, nullptr);
Steve Anton3828c062017-12-06 10:34:51 -0800261 transport_->SetLocalTransportDescription(faketransport_desc, SdpType::kOffer,
262 nullptr);
deadbeef49f34fd2016-12-06 16:22:06 -0800263 EXPECT_TRUE(transport_->GetStats(&stats));
264 ASSERT_EQ(1U, stats.channel_stats.size());
265 EXPECT_EQ(1, stats.channel_stats[0].component);
266}
267
268// Tests that VerifyCertificateFingerprint only returns true when the
269// certificate matches the fingerprint.
270TEST_F(JsepTransportTest, TestVerifyCertificateFingerprint) {
271 std::string error_desc;
272 EXPECT_FALSE(
273 transport_->VerifyCertificateFingerprint(nullptr, nullptr, &error_desc));
274 rtc::KeyType key_types[] = {rtc::KT_RSA, rtc::KT_ECDSA};
275
276 for (auto& key_type : key_types) {
277 rtc::scoped_refptr<rtc::RTCCertificate> certificate =
278 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
279 rtc::SSLIdentity::Generate("testing", key_type)));
280 ASSERT_NE(nullptr, certificate);
281
282 std::string digest_algorithm;
283 ASSERT_TRUE(certificate->ssl_certificate().GetSignatureDigestAlgorithm(
284 &digest_algorithm));
285 ASSERT_FALSE(digest_algorithm.empty());
286 std::unique_ptr<rtc::SSLFingerprint> good_fingerprint(
287 rtc::SSLFingerprint::Create(digest_algorithm, certificate->identity()));
288 ASSERT_NE(nullptr, good_fingerprint);
289
290 EXPECT_TRUE(transport_->VerifyCertificateFingerprint(
291 certificate.get(), good_fingerprint.get(), &error_desc));
292 EXPECT_FALSE(transport_->VerifyCertificateFingerprint(
293 certificate.get(), nullptr, &error_desc));
294 EXPECT_FALSE(transport_->VerifyCertificateFingerprint(
295 nullptr, good_fingerprint.get(), &error_desc));
296
297 rtc::SSLFingerprint bad_fingerprint = *good_fingerprint;
298 bad_fingerprint.digest.AppendData("0", 1);
299 EXPECT_FALSE(transport_->VerifyCertificateFingerprint(
300 certificate.get(), &bad_fingerprint, &error_desc));
301 }
302}
303
deadbeefd8cfa1a2017-03-27 10:33:26 -0700304// Tests the logic of DTLS role negotiation for an initial offer/answer.
305TEST_F(JsepTransportTest, DtlsRoleNegotiation) {
Taylor Brandstetter74cefe12017-12-14 15:38:57 -0800306 // Just use the same certificate for both sides; doesn't really matter in a
307 // non end-to-end test.
deadbeefd8cfa1a2017-03-27 10:33:26 -0700308 rtc::scoped_refptr<rtc::RTCCertificate> certificate =
309 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
310 rtc::SSLIdentity::Generate("testing", rtc::KT_ECDSA)));
deadbeefd8cfa1a2017-03-27 10:33:26 -0700311
Taylor Brandstetter74cefe12017-12-14 15:38:57 -0800312 TransportDescription local_desc =
313 MakeTransportDescription(kIceUfrag1, kIcePwd1, certificate);
314 TransportDescription remote_desc =
315 MakeTransportDescription(kIceUfrag2, kIcePwd2, certificate);
deadbeef49f34fd2016-12-06 16:22:06 -0800316
317 struct NegotiateRoleParams {
Taylor Brandstetter74cefe12017-12-14 15:38:57 -0800318 ConnectionRole local_role;
319 ConnectionRole remote_role;
Steve Anton3828c062017-12-06 10:34:51 -0800320 SdpType local_type;
321 SdpType remote_type;
deadbeef49f34fd2016-12-06 16:22:06 -0800322 };
323
deadbeef49f34fd2016-12-06 16:22:06 -0800324 std::string error_desc;
325
326 // Parameters which set the SSL role to SSL_CLIENT.
327 NegotiateRoleParams valid_client_params[] = {
Taylor Brandstetter74cefe12017-12-14 15:38:57 -0800328 {CONNECTIONROLE_ACTIVE, CONNECTIONROLE_ACTPASS, SdpType::kAnswer,
329 SdpType::kOffer},
330 {CONNECTIONROLE_ACTIVE, CONNECTIONROLE_ACTPASS, SdpType::kPrAnswer,
331 SdpType::kOffer},
332 {CONNECTIONROLE_ACTPASS, CONNECTIONROLE_PASSIVE, SdpType::kOffer,
333 SdpType::kAnswer},
334 {CONNECTIONROLE_ACTPASS, CONNECTIONROLE_PASSIVE, SdpType::kOffer,
335 SdpType::kPrAnswer}};
deadbeef49f34fd2016-12-06 16:22:06 -0800336
337 for (auto& param : valid_client_params) {
deadbeefd8cfa1a2017-03-27 10:33:26 -0700338 RecreateTransport();
339 transport_->SetLocalCertificate(certificate);
340
deadbeef49f34fd2016-12-06 16:22:06 -0800341 local_desc.connection_role = param.local_role;
342 remote_desc.connection_role = param.remote_role;
343
deadbeefd8cfa1a2017-03-27 10:33:26 -0700344 // Set the offer first.
Steve Anton3828c062017-12-06 10:34:51 -0800345 if (param.local_type == SdpType::kOffer) {
deadbeefd8cfa1a2017-03-27 10:33:26 -0700346 EXPECT_TRUE(transport_->SetLocalTransportDescription(
Steve Anton3828c062017-12-06 10:34:51 -0800347 local_desc, param.local_type, nullptr));
deadbeefd8cfa1a2017-03-27 10:33:26 -0700348 EXPECT_TRUE(transport_->SetRemoteTransportDescription(
Steve Anton3828c062017-12-06 10:34:51 -0800349 remote_desc, param.remote_type, nullptr));
deadbeefd8cfa1a2017-03-27 10:33:26 -0700350 } else {
351 EXPECT_TRUE(transport_->SetRemoteTransportDescription(
Steve Anton3828c062017-12-06 10:34:51 -0800352 remote_desc, param.remote_type, nullptr));
deadbeefd8cfa1a2017-03-27 10:33:26 -0700353 EXPECT_TRUE(transport_->SetLocalTransportDescription(
Steve Anton3828c062017-12-06 10:34:51 -0800354 local_desc, param.local_type, nullptr));
deadbeefd8cfa1a2017-03-27 10:33:26 -0700355 }
356 EXPECT_EQ(rtc::SSL_CLIENT, *transport_->GetSslRole());
deadbeef49f34fd2016-12-06 16:22:06 -0800357 }
358
359 // Parameters which set the SSL role to SSL_SERVER.
360 NegotiateRoleParams valid_server_params[] = {
Taylor Brandstetter74cefe12017-12-14 15:38:57 -0800361 {CONNECTIONROLE_PASSIVE, CONNECTIONROLE_ACTPASS, SdpType::kAnswer,
362 SdpType::kOffer},
363 {CONNECTIONROLE_PASSIVE, CONNECTIONROLE_ACTPASS, SdpType::kPrAnswer,
364 SdpType::kOffer},
365 {CONNECTIONROLE_ACTPASS, CONNECTIONROLE_ACTIVE, SdpType::kOffer,
366 SdpType::kAnswer},
367 {CONNECTIONROLE_ACTPASS, CONNECTIONROLE_ACTIVE, SdpType::kOffer,
368 SdpType::kPrAnswer}};
deadbeef49f34fd2016-12-06 16:22:06 -0800369
370 for (auto& param : valid_server_params) {
deadbeefd8cfa1a2017-03-27 10:33:26 -0700371 RecreateTransport();
372 transport_->SetLocalCertificate(certificate);
373
deadbeef49f34fd2016-12-06 16:22:06 -0800374 local_desc.connection_role = param.local_role;
375 remote_desc.connection_role = param.remote_role;
376
deadbeefd8cfa1a2017-03-27 10:33:26 -0700377 // Set the offer first.
Steve Anton3828c062017-12-06 10:34:51 -0800378 if (param.local_type == SdpType::kOffer) {
deadbeefd8cfa1a2017-03-27 10:33:26 -0700379 EXPECT_TRUE(transport_->SetLocalTransportDescription(
Steve Anton3828c062017-12-06 10:34:51 -0800380 local_desc, param.local_type, nullptr));
deadbeefd8cfa1a2017-03-27 10:33:26 -0700381 EXPECT_TRUE(transport_->SetRemoteTransportDescription(
Steve Anton3828c062017-12-06 10:34:51 -0800382 remote_desc, param.remote_type, nullptr));
deadbeefd8cfa1a2017-03-27 10:33:26 -0700383 } else {
384 EXPECT_TRUE(transport_->SetRemoteTransportDescription(
Steve Anton3828c062017-12-06 10:34:51 -0800385 remote_desc, param.remote_type, nullptr));
deadbeefd8cfa1a2017-03-27 10:33:26 -0700386 EXPECT_TRUE(transport_->SetLocalTransportDescription(
Steve Anton3828c062017-12-06 10:34:51 -0800387 local_desc, param.local_type, nullptr));
deadbeefd8cfa1a2017-03-27 10:33:26 -0700388 }
389 EXPECT_EQ(rtc::SSL_SERVER, *transport_->GetSslRole());
deadbeef49f34fd2016-12-06 16:22:06 -0800390 }
391
392 // Invalid parameters due to both peers having a duplicate role.
393 NegotiateRoleParams duplicate_params[] = {
Taylor Brandstetter74cefe12017-12-14 15:38:57 -0800394 {CONNECTIONROLE_ACTIVE, CONNECTIONROLE_ACTIVE, SdpType::kAnswer,
395 SdpType::kOffer},
396 {CONNECTIONROLE_ACTPASS, CONNECTIONROLE_ACTPASS, SdpType::kAnswer,
397 SdpType::kOffer},
398 {CONNECTIONROLE_PASSIVE, CONNECTIONROLE_PASSIVE, SdpType::kAnswer,
399 SdpType::kOffer},
400 {CONNECTIONROLE_ACTIVE, CONNECTIONROLE_ACTIVE, SdpType::kPrAnswer,
401 SdpType::kOffer},
402 {CONNECTIONROLE_ACTPASS, CONNECTIONROLE_ACTPASS, SdpType::kPrAnswer,
403 SdpType::kOffer},
404 {CONNECTIONROLE_PASSIVE, CONNECTIONROLE_PASSIVE, SdpType::kPrAnswer,
405 SdpType::kOffer},
406 {CONNECTIONROLE_ACTIVE, CONNECTIONROLE_ACTIVE, SdpType::kOffer,
407 SdpType::kAnswer},
408 {CONNECTIONROLE_ACTPASS, CONNECTIONROLE_ACTPASS, SdpType::kOffer,
409 SdpType::kAnswer},
410 {CONNECTIONROLE_PASSIVE, CONNECTIONROLE_PASSIVE, SdpType::kOffer,
411 SdpType::kAnswer},
412 {CONNECTIONROLE_ACTIVE, CONNECTIONROLE_ACTIVE, SdpType::kOffer,
413 SdpType::kPrAnswer},
414 {CONNECTIONROLE_ACTPASS, CONNECTIONROLE_ACTPASS, SdpType::kOffer,
415 SdpType::kPrAnswer},
416 {CONNECTIONROLE_PASSIVE, CONNECTIONROLE_PASSIVE, SdpType::kOffer,
417 SdpType::kPrAnswer}};
deadbeef49f34fd2016-12-06 16:22:06 -0800418
419 for (auto& param : duplicate_params) {
deadbeefd8cfa1a2017-03-27 10:33:26 -0700420 RecreateTransport();
421 transport_->SetLocalCertificate(certificate);
422
deadbeef49f34fd2016-12-06 16:22:06 -0800423 local_desc.connection_role = param.local_role;
424 remote_desc.connection_role = param.remote_role;
425
deadbeefd8cfa1a2017-03-27 10:33:26 -0700426 // Set the offer first.
Steve Anton3828c062017-12-06 10:34:51 -0800427 if (param.local_type == SdpType::kOffer) {
deadbeefd8cfa1a2017-03-27 10:33:26 -0700428 EXPECT_TRUE(transport_->SetLocalTransportDescription(
Steve Anton3828c062017-12-06 10:34:51 -0800429 local_desc, param.local_type, nullptr));
deadbeefd8cfa1a2017-03-27 10:33:26 -0700430 EXPECT_FALSE(transport_->SetRemoteTransportDescription(
Steve Anton3828c062017-12-06 10:34:51 -0800431 remote_desc, param.remote_type, nullptr));
deadbeefd8cfa1a2017-03-27 10:33:26 -0700432 } else {
433 EXPECT_TRUE(transport_->SetRemoteTransportDescription(
Steve Anton3828c062017-12-06 10:34:51 -0800434 remote_desc, param.remote_type, nullptr));
deadbeefd8cfa1a2017-03-27 10:33:26 -0700435 EXPECT_FALSE(transport_->SetLocalTransportDescription(
Steve Anton3828c062017-12-06 10:34:51 -0800436 local_desc, param.local_type, nullptr));
deadbeefd8cfa1a2017-03-27 10:33:26 -0700437 }
deadbeef49f34fd2016-12-06 16:22:06 -0800438 }
439
440 // Invalid parameters due to the offerer not using ACTPASS.
441 NegotiateRoleParams offerer_without_actpass_params[] = {
Taylor Brandstetter74cefe12017-12-14 15:38:57 -0800442 {CONNECTIONROLE_ACTIVE, CONNECTIONROLE_PASSIVE, SdpType::kAnswer,
443 SdpType::kOffer},
444 {CONNECTIONROLE_PASSIVE, CONNECTIONROLE_ACTIVE, SdpType::kAnswer,
445 SdpType::kOffer},
446 {CONNECTIONROLE_ACTPASS, CONNECTIONROLE_PASSIVE, SdpType::kAnswer,
447 SdpType::kOffer},
448 {CONNECTIONROLE_ACTIVE, CONNECTIONROLE_PASSIVE, SdpType::kPrAnswer,
449 SdpType::kOffer},
450 {CONNECTIONROLE_PASSIVE, CONNECTIONROLE_ACTIVE, SdpType::kPrAnswer,
451 SdpType::kOffer},
452 {CONNECTIONROLE_ACTPASS, CONNECTIONROLE_PASSIVE, SdpType::kPrAnswer,
453 SdpType::kOffer},
454 {CONNECTIONROLE_ACTIVE, CONNECTIONROLE_PASSIVE, SdpType::kOffer,
455 SdpType::kAnswer},
456 {CONNECTIONROLE_PASSIVE, CONNECTIONROLE_ACTIVE, SdpType::kOffer,
457 SdpType::kAnswer},
458 {CONNECTIONROLE_PASSIVE, CONNECTIONROLE_ACTPASS, SdpType::kOffer,
459 SdpType::kAnswer},
460 {CONNECTIONROLE_ACTIVE, CONNECTIONROLE_PASSIVE, SdpType::kOffer,
461 SdpType::kPrAnswer},
462 {CONNECTIONROLE_PASSIVE, CONNECTIONROLE_ACTIVE, SdpType::kOffer,
463 SdpType::kPrAnswer},
464 {CONNECTIONROLE_PASSIVE, CONNECTIONROLE_ACTPASS, SdpType::kOffer,
465 SdpType::kPrAnswer}};
deadbeef49f34fd2016-12-06 16:22:06 -0800466
467 for (auto& param : offerer_without_actpass_params) {
deadbeefd8cfa1a2017-03-27 10:33:26 -0700468 RecreateTransport();
469 transport_->SetLocalCertificate(certificate);
470
deadbeef49f34fd2016-12-06 16:22:06 -0800471 local_desc.connection_role = param.local_role;
472 remote_desc.connection_role = param.remote_role;
473
deadbeefd8cfa1a2017-03-27 10:33:26 -0700474 // Set the offer first.
475 // TODO(deadbeef): Really this should fail as soon as the offer is
476 // attempted to be applied, and not when the answer is applied.
Steve Anton3828c062017-12-06 10:34:51 -0800477 if (param.local_type == SdpType::kOffer) {
deadbeefd8cfa1a2017-03-27 10:33:26 -0700478 EXPECT_TRUE(transport_->SetLocalTransportDescription(
Steve Anton3828c062017-12-06 10:34:51 -0800479 local_desc, param.local_type, nullptr));
deadbeefd8cfa1a2017-03-27 10:33:26 -0700480 EXPECT_FALSE(transport_->SetRemoteTransportDescription(
Steve Anton3828c062017-12-06 10:34:51 -0800481 remote_desc, param.remote_type, nullptr));
deadbeefd8cfa1a2017-03-27 10:33:26 -0700482 } else {
483 EXPECT_TRUE(transport_->SetRemoteTransportDescription(
Steve Anton3828c062017-12-06 10:34:51 -0800484 remote_desc, param.remote_type, nullptr));
deadbeefd8cfa1a2017-03-27 10:33:26 -0700485 EXPECT_FALSE(transport_->SetLocalTransportDescription(
Steve Anton3828c062017-12-06 10:34:51 -0800486 local_desc, param.local_type, nullptr));
deadbeefd8cfa1a2017-03-27 10:33:26 -0700487 }
deadbeef49f34fd2016-12-06 16:22:06 -0800488 }
489}
deadbeefd8cfa1a2017-03-27 10:33:26 -0700490
Taylor Brandstetter74cefe12017-12-14 15:38:57 -0800491// Test that a reoffer in the opposite direction is successful as long as the
492// role isn't changing. Doesn't test every possible combination like the test
493// above.
494TEST_F(JsepTransportTest, ValidDtlsReofferFromAnswerer) {
495 // Just use the same certificate for both sides; doesn't really matter in a
496 // non end-to-end test.
497 rtc::scoped_refptr<rtc::RTCCertificate> certificate =
498 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
499 rtc::SSLIdentity::Generate("testing", rtc::KT_ECDSA)));
500 transport_->SetLocalCertificate(certificate);
501
502 TransportDescription local_offer = MakeTransportDescription(
503 kIceUfrag1, kIcePwd1, certificate, CONNECTIONROLE_ACTPASS);
504 TransportDescription remote_answer = MakeTransportDescription(
505 kIceUfrag2, kIcePwd2, certificate, CONNECTIONROLE_ACTIVE);
506
507 EXPECT_TRUE(transport_->SetLocalTransportDescription(
508 local_offer, SdpType::kOffer, nullptr));
509 EXPECT_TRUE(transport_->SetRemoteTransportDescription(
510 remote_answer, SdpType::kAnswer, nullptr));
511
512 // We were actpass->active previously, now in the other direction it's
513 // actpass->passive.
514 TransportDescription remote_offer = MakeTransportDescription(
515 kIceUfrag2, kIcePwd2, certificate, CONNECTIONROLE_ACTPASS);
516 TransportDescription local_answer = MakeTransportDescription(
517 kIceUfrag1, kIcePwd1, certificate, CONNECTIONROLE_PASSIVE);
518
519 EXPECT_TRUE(transport_->SetRemoteTransportDescription(
520 remote_offer, SdpType::kOffer, nullptr));
521 EXPECT_TRUE(transport_->SetLocalTransportDescription(
522 local_answer, SdpType::kAnswer, nullptr));
523}
524
525// Test that a reoffer in the opposite direction fails if the role changes.
526// Inverse of test above.
527TEST_F(JsepTransportTest, InvalidDtlsReofferFromAnswerer) {
528 // Just use the same certificate for both sides; doesn't really matter in a
529 // non end-to-end test.
530 rtc::scoped_refptr<rtc::RTCCertificate> certificate =
531 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
532 rtc::SSLIdentity::Generate("testing", rtc::KT_ECDSA)));
533 transport_->SetLocalCertificate(certificate);
534
535 TransportDescription local_offer = MakeTransportDescription(
536 kIceUfrag1, kIcePwd1, certificate, CONNECTIONROLE_ACTPASS);
537 TransportDescription remote_answer = MakeTransportDescription(
538 kIceUfrag2, kIcePwd2, certificate, CONNECTIONROLE_ACTIVE);
539
540 EXPECT_TRUE(transport_->SetLocalTransportDescription(
541 local_offer, SdpType::kOffer, nullptr));
542 EXPECT_TRUE(transport_->SetRemoteTransportDescription(
543 remote_answer, SdpType::kAnswer, nullptr));
544
545 // Changing role to passive here isn't allowed. Though for some reason this
546 // only fails in SetLocalTransportDescription.
547 TransportDescription remote_offer = MakeTransportDescription(
548 kIceUfrag2, kIcePwd2, certificate, CONNECTIONROLE_PASSIVE);
549 TransportDescription local_answer = MakeTransportDescription(
550 kIceUfrag1, kIcePwd1, certificate, CONNECTIONROLE_ACTIVE);
551
552 EXPECT_TRUE(transport_->SetRemoteTransportDescription(
553 remote_offer, SdpType::kOffer, nullptr));
554 EXPECT_FALSE(transport_->SetLocalTransportDescription(
555 local_answer, SdpType::kAnswer, nullptr));
556}
557
deadbeefd8cfa1a2017-03-27 10:33:26 -0700558// Test that a remote offer with the current negotiated role can be accepted.
559// This is allowed by dtls-sdp, though we'll never generate such an offer,
560// since JSEP requires generating "actpass".
561TEST_F(JsepTransportTest, RemoteOfferWithCurrentNegotiatedDtlsRole) {
Taylor Brandstetter74cefe12017-12-14 15:38:57 -0800562 // Just use the same certificate in both descriptions; the remote fingerprint
563 // doesn't matter in a non end-to-end test.
deadbeefd8cfa1a2017-03-27 10:33:26 -0700564 rtc::scoped_refptr<rtc::RTCCertificate> certificate =
565 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
566 rtc::SSLIdentity::Generate("testing", rtc::KT_ECDSA)));
deadbeefd8cfa1a2017-03-27 10:33:26 -0700567 transport_->SetLocalCertificate(certificate);
568
Taylor Brandstetter74cefe12017-12-14 15:38:57 -0800569 TransportDescription remote_desc = MakeTransportDescription(
570 kIceUfrag1, kIcePwd1, certificate, CONNECTIONROLE_ACTPASS);
571 TransportDescription local_desc = MakeTransportDescription(
572 kIceUfrag2, kIcePwd2, certificate, CONNECTIONROLE_ACTIVE);
deadbeefd8cfa1a2017-03-27 10:33:26 -0700573
574 // Normal initial offer/answer with "actpass" in the offer and "active" in
575 // the answer.
576 ASSERT_TRUE(transport_->SetRemoteTransportDescription(
Steve Anton3828c062017-12-06 10:34:51 -0800577 remote_desc, SdpType::kOffer, nullptr));
deadbeefd8cfa1a2017-03-27 10:33:26 -0700578 ASSERT_TRUE(transport_->SetLocalTransportDescription(
Steve Anton3828c062017-12-06 10:34:51 -0800579 local_desc, SdpType::kAnswer, nullptr));
deadbeefd8cfa1a2017-03-27 10:33:26 -0700580
581 // Sanity check that role was actually negotiated.
582 rtc::Optional<rtc::SSLRole> role = transport_->GetSslRole();
583 ASSERT_TRUE(role);
584 EXPECT_EQ(rtc::SSL_CLIENT, *role);
585
586 // Subsequent offer with current negotiated role of "passive".
Taylor Brandstetter74cefe12017-12-14 15:38:57 -0800587 remote_desc.connection_role = CONNECTIONROLE_PASSIVE;
deadbeefd8cfa1a2017-03-27 10:33:26 -0700588 EXPECT_TRUE(transport_->SetRemoteTransportDescription(
Steve Anton3828c062017-12-06 10:34:51 -0800589 remote_desc, SdpType::kOffer, nullptr));
deadbeefd8cfa1a2017-03-27 10:33:26 -0700590 EXPECT_TRUE(transport_->SetLocalTransportDescription(
Steve Anton3828c062017-12-06 10:34:51 -0800591 local_desc, SdpType::kAnswer, nullptr));
deadbeefd8cfa1a2017-03-27 10:33:26 -0700592}
593
594// Test that a remote offer with the inverse of the current negotiated DTLS
595// role is rejected.
596TEST_F(JsepTransportTest, RemoteOfferThatChangesNegotiatedDtlsRole) {
597 rtc::scoped_refptr<rtc::RTCCertificate> certificate =
598 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
599 rtc::SSLIdentity::Generate("testing", rtc::KT_ECDSA)));
600 std::unique_ptr<rtc::SSLFingerprint> fingerprint(
601 rtc::SSLFingerprint::CreateFromCertificate(certificate));
602 transport_->SetLocalCertificate(certificate);
603
604 TransportDescription local_desc(kIceUfrag1, kIcePwd1);
605 TransportDescription remote_desc(kIceUfrag2, kIcePwd2);
606 // Just use the same fingerprint in both descriptions; the remote fingerprint
607 // doesn't matter in a non end-to-end test.
608 local_desc.identity_fingerprint.reset(
609 TransportDescription::CopyFingerprint(fingerprint.get()));
610 remote_desc.identity_fingerprint.reset(
611 TransportDescription::CopyFingerprint(fingerprint.get()));
612
Taylor Brandstetter74cefe12017-12-14 15:38:57 -0800613 remote_desc.connection_role = CONNECTIONROLE_ACTPASS;
614 local_desc.connection_role = CONNECTIONROLE_ACTIVE;
deadbeefd8cfa1a2017-03-27 10:33:26 -0700615
616 // Normal initial offer/answer with "actpass" in the offer and "active" in
617 // the answer.
618 ASSERT_TRUE(transport_->SetRemoteTransportDescription(
Steve Anton3828c062017-12-06 10:34:51 -0800619 remote_desc, SdpType::kOffer, nullptr));
deadbeefd8cfa1a2017-03-27 10:33:26 -0700620 ASSERT_TRUE(transport_->SetLocalTransportDescription(
Steve Anton3828c062017-12-06 10:34:51 -0800621 local_desc, SdpType::kAnswer, nullptr));
deadbeefd8cfa1a2017-03-27 10:33:26 -0700622
623 // Sanity check that role was actually negotiated.
624 rtc::Optional<rtc::SSLRole> role = transport_->GetSslRole();
625 ASSERT_TRUE(role);
626 EXPECT_EQ(rtc::SSL_CLIENT, *role);
627
628 // Subsequent offer with "active", which is the opposite of the remote
629 // endpoint's negotiated role.
630 // TODO(deadbeef): Really this should fail as soon as the offer is
631 // attempted to be applied, and not when the answer is applied.
Taylor Brandstetter74cefe12017-12-14 15:38:57 -0800632 remote_desc.connection_role = CONNECTIONROLE_ACTIVE;
deadbeefd8cfa1a2017-03-27 10:33:26 -0700633 EXPECT_TRUE(transport_->SetRemoteTransportDescription(
Steve Anton3828c062017-12-06 10:34:51 -0800634 remote_desc, SdpType::kOffer, nullptr));
deadbeefd8cfa1a2017-03-27 10:33:26 -0700635 EXPECT_FALSE(transport_->SetLocalTransportDescription(
Steve Anton3828c062017-12-06 10:34:51 -0800636 local_desc, SdpType::kAnswer, nullptr));
deadbeefd8cfa1a2017-03-27 10:33:26 -0700637}
Taylor Brandstetter74cefe12017-12-14 15:38:57 -0800638
639// Testing that a legacy client that doesn't use the setup attribute will be
640// interpreted as having an active role.
641TEST_F(JsepTransportTest, TestDtlsSetupWithLegacyAsAnswerer) {
642 rtc::scoped_refptr<rtc::RTCCertificate> certificate =
643 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
644 rtc::SSLIdentity::Generate("testing", rtc::KT_ECDSA)));
645 std::unique_ptr<rtc::SSLFingerprint> fingerprint(
646 rtc::SSLFingerprint::CreateFromCertificate(certificate));
647 transport_->SetLocalCertificate(certificate);
648
649 TransportDescription local_desc(kIceUfrag1, kIcePwd1);
650 TransportDescription remote_desc(kIceUfrag2, kIcePwd2);
651 // Just use the same fingerprint in both descriptions; the remote fingerprint
652 // doesn't matter in a non end-to-end test.
653 local_desc.identity_fingerprint.reset(
654 TransportDescription::CopyFingerprint(fingerprint.get()));
655 remote_desc.identity_fingerprint.reset(
656 TransportDescription::CopyFingerprint(fingerprint.get()));
657
658 local_desc.connection_role = CONNECTIONROLE_ACTPASS;
659 ASSERT_TRUE(transport_->SetLocalTransportDescription(
660 local_desc, SdpType::kOffer, nullptr));
661 // Use CONNECTIONROLE_NONE to simulate legacy endpoint.
662 remote_desc.connection_role = CONNECTIONROLE_NONE;
663 ASSERT_TRUE(transport_->SetRemoteTransportDescription(
664 remote_desc, SdpType::kAnswer, nullptr));
665
666 rtc::Optional<rtc::SSLRole> role = transport_->GetSslRole();
667 ASSERT_TRUE(role);
668 // Since legacy answer ommitted setup atribute, and we offered actpass, we
669 // should act as passive (server).
670 EXPECT_EQ(rtc::SSL_SERVER, *role);
671}
672
673} // namespace cricket