1 /*
2 * Copyright 2018 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 */
10
11 #include "pc/jsep_transport.h"
12
13 #include <memory>
14 #include <tuple>
15 #include <utility>
16
17 #include "api/ice_transport_factory.h"
18 #include "media/base/fake_rtp.h"
19 #include "p2p/base/fake_dtls_transport.h"
20 #include "p2p/base/fake_ice_transport.h"
21 #include "rtc_base/gunit.h"
22
23 namespace cricket {
24 namespace {
25 using webrtc::SdpType;
26
27 static const char kIceUfrag1[] = "U001";
28 static const char kIcePwd1[] = "TESTICEPWD00000000000001";
29 static const char kIceUfrag2[] = "U002";
30 static const char kIcePwd2[] = "TESTIEPWD00000000000002";
31 static const char kTransportName[] = "Test Transport";
32
33 enum class SrtpMode {
34 kSdes,
35 kDtlsSrtp,
36 };
37
38 struct NegotiateRoleParams {
39 ConnectionRole local_role;
40 ConnectionRole remote_role;
41 SdpType local_type;
42 SdpType remote_type;
43 };
44
CreateIceTransport(std::unique_ptr<FakeIceTransport> internal)45 rtc::scoped_refptr<webrtc::IceTransportInterface> CreateIceTransport(
46 std::unique_ptr<FakeIceTransport> internal) {
47 if (!internal) {
48 return nullptr;
49 }
50
51 return new rtc::RefCountedObject<FakeIceTransportWrapper>(
52 std::move(internal));
53 }
54
55 class JsepTransport2Test : public ::testing::Test, public sigslot::has_slots<> {
56 protected:
CreateSdesTransport(rtc::PacketTransportInternal * rtp_packet_transport,rtc::PacketTransportInternal * rtcp_packet_transport)57 std::unique_ptr<webrtc::SrtpTransport> CreateSdesTransport(
58 rtc::PacketTransportInternal* rtp_packet_transport,
59 rtc::PacketTransportInternal* rtcp_packet_transport) {
60 auto srtp_transport = std::make_unique<webrtc::SrtpTransport>(
61 rtcp_packet_transport == nullptr);
62
63 srtp_transport->SetRtpPacketTransport(rtp_packet_transport);
64 if (rtcp_packet_transport) {
65 srtp_transport->SetRtcpPacketTransport(rtp_packet_transport);
66 }
67 return srtp_transport;
68 }
69
CreateDtlsSrtpTransport(cricket::DtlsTransportInternal * rtp_dtls_transport,cricket::DtlsTransportInternal * rtcp_dtls_transport)70 std::unique_ptr<webrtc::DtlsSrtpTransport> CreateDtlsSrtpTransport(
71 cricket::DtlsTransportInternal* rtp_dtls_transport,
72 cricket::DtlsTransportInternal* rtcp_dtls_transport) {
73 auto dtls_srtp_transport = std::make_unique<webrtc::DtlsSrtpTransport>(
74 rtcp_dtls_transport == nullptr);
75 dtls_srtp_transport->SetDtlsTransports(rtp_dtls_transport,
76 rtcp_dtls_transport);
77 return dtls_srtp_transport;
78 }
79
80 // Create a new JsepTransport with a FakeDtlsTransport and a
81 // FakeIceTransport.
CreateJsepTransport2(bool rtcp_mux_enabled,SrtpMode srtp_mode)82 std::unique_ptr<JsepTransport> CreateJsepTransport2(bool rtcp_mux_enabled,
83 SrtpMode srtp_mode) {
84 auto ice_internal = std::make_unique<FakeIceTransport>(
85 kTransportName, ICE_CANDIDATE_COMPONENT_RTP);
86 auto rtp_dtls_transport =
87 std::make_unique<FakeDtlsTransport>(ice_internal.get());
88 auto ice = CreateIceTransport(std::move(ice_internal));
89
90 std::unique_ptr<FakeIceTransport> rtcp_ice_internal;
91 std::unique_ptr<FakeDtlsTransport> rtcp_dtls_transport;
92 if (!rtcp_mux_enabled) {
93 rtcp_ice_internal = std::make_unique<FakeIceTransport>(
94 kTransportName, ICE_CANDIDATE_COMPONENT_RTCP);
95 rtcp_dtls_transport =
96 std::make_unique<FakeDtlsTransport>(rtcp_ice_internal.get());
97 }
98 auto rtcp_ice = CreateIceTransport(std::move(rtcp_ice_internal));
99
100 std::unique_ptr<webrtc::RtpTransport> unencrypted_rtp_transport;
101 std::unique_ptr<webrtc::SrtpTransport> sdes_transport;
102 std::unique_ptr<webrtc::DtlsSrtpTransport> dtls_srtp_transport;
103 switch (srtp_mode) {
104 case SrtpMode::kSdes:
105 sdes_transport = CreateSdesTransport(rtp_dtls_transport.get(),
106 rtcp_dtls_transport.get());
107 sdes_transport_ = sdes_transport.get();
108 break;
109 case SrtpMode::kDtlsSrtp:
110 dtls_srtp_transport = CreateDtlsSrtpTransport(
111 rtp_dtls_transport.get(), rtcp_dtls_transport.get());
112 break;
113 default:
114 RTC_NOTREACHED();
115 }
116
117 auto jsep_transport = std::make_unique<JsepTransport>(
118 kTransportName, /*local_certificate=*/nullptr, std::move(ice),
119 std::move(rtcp_ice), std::move(unencrypted_rtp_transport),
120 std::move(sdes_transport), std::move(dtls_srtp_transport),
121 /*datagram_rtp_transport=*/nullptr, std::move(rtp_dtls_transport),
122 std::move(rtcp_dtls_transport),
123 /*sctp_transport=*/nullptr);
124
125 signal_rtcp_mux_active_received_ = false;
126 jsep_transport->SignalRtcpMuxActive.connect(
127 this, &JsepTransport2Test::OnRtcpMuxActive);
128 return jsep_transport;
129 }
130
MakeJsepTransportDescription(bool rtcp_mux_enabled,const char * ufrag,const char * pwd,const rtc::scoped_refptr<rtc::RTCCertificate> & cert,ConnectionRole role=CONNECTIONROLE_NONE)131 JsepTransportDescription MakeJsepTransportDescription(
132 bool rtcp_mux_enabled,
133 const char* ufrag,
134 const char* pwd,
135 const rtc::scoped_refptr<rtc::RTCCertificate>& cert,
136 ConnectionRole role = CONNECTIONROLE_NONE) {
137 JsepTransportDescription jsep_description;
138 jsep_description.rtcp_mux_enabled = rtcp_mux_enabled;
139
140 std::unique_ptr<rtc::SSLFingerprint> fingerprint;
141 if (cert) {
142 fingerprint = rtc::SSLFingerprint::CreateFromCertificate(*cert);
143 }
144 jsep_description.transport_desc =
145 TransportDescription(std::vector<std::string>(), ufrag, pwd,
146 ICEMODE_FULL, role, fingerprint.get());
147 return jsep_description;
148 }
149
CreateCandidate(int component)150 Candidate CreateCandidate(int component) {
151 Candidate c;
152 c.set_address(rtc::SocketAddress("192.168.1.1", 8000));
153 c.set_component(component);
154 c.set_protocol(UDP_PROTOCOL_NAME);
155 c.set_priority(1);
156 return c;
157 }
158
OnRtcpMuxActive()159 void OnRtcpMuxActive() { signal_rtcp_mux_active_received_ = true; }
160
161 std::unique_ptr<JsepTransport> jsep_transport_;
162 bool signal_rtcp_mux_active_received_ = false;
163 // The SrtpTransport is owned by |jsep_transport_|. Keep a raw pointer here
164 // for testing.
165 webrtc::SrtpTransport* sdes_transport_ = nullptr;
166 };
167
168 // The parameterized tests cover both cases when RTCP mux is enable and
169 // disabled.
170 class JsepTransport2WithRtcpMux : public JsepTransport2Test,
171 public ::testing::WithParamInterface<bool> {};
172
173 // This test verifies the ICE parameters are properly applied to the transports.
TEST_P(JsepTransport2WithRtcpMux,SetIceParameters)174 TEST_P(JsepTransport2WithRtcpMux, SetIceParameters) {
175 bool rtcp_mux_enabled = GetParam();
176 jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp);
177
178 JsepTransportDescription jsep_description;
179 jsep_description.transport_desc = TransportDescription(kIceUfrag1, kIcePwd1);
180 jsep_description.rtcp_mux_enabled = rtcp_mux_enabled;
181 ASSERT_TRUE(
182 jsep_transport_
183 ->SetLocalJsepTransportDescription(jsep_description, SdpType::kOffer)
184 .ok());
185 auto fake_ice_transport = static_cast<FakeIceTransport*>(
186 jsep_transport_->rtp_dtls_transport()->ice_transport());
187 EXPECT_EQ(ICEMODE_FULL, fake_ice_transport->remote_ice_mode());
188 EXPECT_EQ(kIceUfrag1, fake_ice_transport->ice_ufrag());
189 EXPECT_EQ(kIcePwd1, fake_ice_transport->ice_pwd());
190 if (!rtcp_mux_enabled) {
191 fake_ice_transport = static_cast<FakeIceTransport*>(
192 jsep_transport_->rtcp_dtls_transport()->ice_transport());
193 ASSERT_TRUE(fake_ice_transport);
194 EXPECT_EQ(ICEMODE_FULL, fake_ice_transport->remote_ice_mode());
195 EXPECT_EQ(kIceUfrag1, fake_ice_transport->ice_ufrag());
196 EXPECT_EQ(kIcePwd1, fake_ice_transport->ice_pwd());
197 }
198
199 jsep_description.transport_desc = TransportDescription(kIceUfrag2, kIcePwd2);
200 ASSERT_TRUE(jsep_transport_
201 ->SetRemoteJsepTransportDescription(jsep_description,
202 SdpType::kAnswer)
203 .ok());
204 fake_ice_transport = static_cast<FakeIceTransport*>(
205 jsep_transport_->rtp_dtls_transport()->ice_transport());
206 EXPECT_EQ(ICEMODE_FULL, fake_ice_transport->remote_ice_mode());
207 EXPECT_EQ(kIceUfrag2, fake_ice_transport->remote_ice_ufrag());
208 EXPECT_EQ(kIcePwd2, fake_ice_transport->remote_ice_pwd());
209 if (!rtcp_mux_enabled) {
210 fake_ice_transport = static_cast<FakeIceTransport*>(
211 jsep_transport_->rtcp_dtls_transport()->ice_transport());
212 ASSERT_TRUE(fake_ice_transport);
213 EXPECT_EQ(ICEMODE_FULL, fake_ice_transport->remote_ice_mode());
214 EXPECT_EQ(kIceUfrag2, fake_ice_transport->remote_ice_ufrag());
215 EXPECT_EQ(kIcePwd2, fake_ice_transport->remote_ice_pwd());
216 }
217 }
218
219 // Similarly, test DTLS parameters are properly applied to the transports.
TEST_P(JsepTransport2WithRtcpMux,SetDtlsParameters)220 TEST_P(JsepTransport2WithRtcpMux, SetDtlsParameters) {
221 bool rtcp_mux_enabled = GetParam();
222 jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp);
223
224 // Create certificates.
225 rtc::scoped_refptr<rtc::RTCCertificate> local_cert =
226 rtc::RTCCertificate::Create(
227 rtc::SSLIdentity::Create("local", rtc::KT_DEFAULT));
228 rtc::scoped_refptr<rtc::RTCCertificate> remote_cert =
229 rtc::RTCCertificate::Create(
230 rtc::SSLIdentity::Create("remote", rtc::KT_DEFAULT));
231 jsep_transport_->SetLocalCertificate(local_cert);
232
233 // Apply offer.
234 JsepTransportDescription local_description =
235 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag1, kIcePwd1,
236 local_cert, CONNECTIONROLE_ACTPASS);
237 ASSERT_TRUE(
238 jsep_transport_
239 ->SetLocalJsepTransportDescription(local_description, SdpType::kOffer)
240 .ok());
241 // Apply Answer.
242 JsepTransportDescription remote_description =
243 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag2, kIcePwd2,
244 remote_cert, CONNECTIONROLE_ACTIVE);
245 ASSERT_TRUE(jsep_transport_
246 ->SetRemoteJsepTransportDescription(remote_description,
247 SdpType::kAnswer)
248 .ok());
249
250 // Verify that SSL role and remote fingerprint were set correctly based on
251 // transport descriptions.
252 auto role = jsep_transport_->GetDtlsRole();
253 ASSERT_TRUE(role);
254 EXPECT_EQ(rtc::SSL_SERVER, role); // Because remote description was "active".
255 auto fake_dtls =
256 static_cast<FakeDtlsTransport*>(jsep_transport_->rtp_dtls_transport());
257 EXPECT_EQ(remote_description.transport_desc.identity_fingerprint->ToString(),
258 fake_dtls->dtls_fingerprint().ToString());
259
260 if (!rtcp_mux_enabled) {
261 auto fake_rtcp_dtls =
262 static_cast<FakeDtlsTransport*>(jsep_transport_->rtcp_dtls_transport());
263 EXPECT_EQ(
264 remote_description.transport_desc.identity_fingerprint->ToString(),
265 fake_rtcp_dtls->dtls_fingerprint().ToString());
266 }
267 }
268
269 // Same as above test, but with remote transport description using
270 // CONNECTIONROLE_PASSIVE, expecting SSL_CLIENT role.
TEST_P(JsepTransport2WithRtcpMux,SetDtlsParametersWithPassiveAnswer)271 TEST_P(JsepTransport2WithRtcpMux, SetDtlsParametersWithPassiveAnswer) {
272 bool rtcp_mux_enabled = GetParam();
273 jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp);
274
275 // Create certificates.
276 rtc::scoped_refptr<rtc::RTCCertificate> local_cert =
277 rtc::RTCCertificate::Create(
278 rtc::SSLIdentity::Create("local", rtc::KT_DEFAULT));
279 rtc::scoped_refptr<rtc::RTCCertificate> remote_cert =
280 rtc::RTCCertificate::Create(
281 rtc::SSLIdentity::Create("remote", rtc::KT_DEFAULT));
282 jsep_transport_->SetLocalCertificate(local_cert);
283
284 // Apply offer.
285 JsepTransportDescription local_description =
286 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag1, kIcePwd1,
287 local_cert, CONNECTIONROLE_ACTPASS);
288 ASSERT_TRUE(
289 jsep_transport_
290 ->SetLocalJsepTransportDescription(local_description, SdpType::kOffer)
291 .ok());
292 // Apply Answer.
293 JsepTransportDescription remote_description =
294 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag2, kIcePwd2,
295 remote_cert, CONNECTIONROLE_PASSIVE);
296 ASSERT_TRUE(jsep_transport_
297 ->SetRemoteJsepTransportDescription(remote_description,
298 SdpType::kAnswer)
299 .ok());
300
301 // Verify that SSL role and remote fingerprint were set correctly based on
302 // transport descriptions.
303 auto role = jsep_transport_->GetDtlsRole();
304 ASSERT_TRUE(role);
305 EXPECT_EQ(rtc::SSL_CLIENT,
306 role); // Because remote description was "passive".
307 auto fake_dtls =
308 static_cast<FakeDtlsTransport*>(jsep_transport_->rtp_dtls_transport());
309 EXPECT_EQ(remote_description.transport_desc.identity_fingerprint->ToString(),
310 fake_dtls->dtls_fingerprint().ToString());
311
312 if (!rtcp_mux_enabled) {
313 auto fake_rtcp_dtls =
314 static_cast<FakeDtlsTransport*>(jsep_transport_->rtcp_dtls_transport());
315 EXPECT_EQ(
316 remote_description.transport_desc.identity_fingerprint->ToString(),
317 fake_rtcp_dtls->dtls_fingerprint().ToString());
318 }
319 }
320
321 // Tests SetNeedsIceRestartFlag and need_ice_restart, ensuring needs_ice_restart
322 // only starts returning "false" once an ICE restart has been initiated.
TEST_P(JsepTransport2WithRtcpMux,NeedsIceRestart)323 TEST_P(JsepTransport2WithRtcpMux, NeedsIceRestart) {
324 bool rtcp_mux_enabled = GetParam();
325 jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp);
326
327 // Use the same JsepTransportDescription for both offer and answer.
328 JsepTransportDescription description;
329 description.transport_desc = TransportDescription(kIceUfrag1, kIcePwd1);
330 ASSERT_TRUE(
331 jsep_transport_
332 ->SetLocalJsepTransportDescription(description, SdpType::kOffer)
333 .ok());
334 ASSERT_TRUE(
335 jsep_transport_
336 ->SetRemoteJsepTransportDescription(description, SdpType::kAnswer)
337 .ok());
338 // Flag initially should be false.
339 EXPECT_FALSE(jsep_transport_->needs_ice_restart());
340
341 // After setting flag, it should be true.
342 jsep_transport_->SetNeedsIceRestartFlag();
343 EXPECT_TRUE(jsep_transport_->needs_ice_restart());
344
345 ASSERT_TRUE(
346 jsep_transport_
347 ->SetLocalJsepTransportDescription(description, SdpType::kOffer)
348 .ok());
349 ASSERT_TRUE(
350 jsep_transport_
351 ->SetRemoteJsepTransportDescription(description, SdpType::kAnswer)
352 .ok());
353 EXPECT_TRUE(jsep_transport_->needs_ice_restart());
354
355 // Doing an offer/answer that restarts ICE should clear the flag.
356 description.transport_desc = TransportDescription(kIceUfrag2, kIcePwd2);
357 ASSERT_TRUE(
358 jsep_transport_
359 ->SetLocalJsepTransportDescription(description, SdpType::kOffer)
360 .ok());
361 ASSERT_TRUE(
362 jsep_transport_
363 ->SetRemoteJsepTransportDescription(description, SdpType::kAnswer)
364 .ok());
365 EXPECT_FALSE(jsep_transport_->needs_ice_restart());
366 }
367
TEST_P(JsepTransport2WithRtcpMux,GetStats)368 TEST_P(JsepTransport2WithRtcpMux, GetStats) {
369 bool rtcp_mux_enabled = GetParam();
370 jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp);
371
372 size_t expected_stats_size = rtcp_mux_enabled ? 1u : 2u;
373 TransportStats stats;
374 EXPECT_TRUE(jsep_transport_->GetStats(&stats));
375 EXPECT_EQ(expected_stats_size, stats.channel_stats.size());
376 EXPECT_EQ(ICE_CANDIDATE_COMPONENT_RTP, stats.channel_stats[0].component);
377 if (!rtcp_mux_enabled) {
378 EXPECT_EQ(ICE_CANDIDATE_COMPONENT_RTCP, stats.channel_stats[1].component);
379 }
380 }
381
382 // Tests that VerifyCertificateFingerprint only returns true when the
383 // certificate matches the fingerprint.
TEST_P(JsepTransport2WithRtcpMux,VerifyCertificateFingerprint)384 TEST_P(JsepTransport2WithRtcpMux, VerifyCertificateFingerprint) {
385 bool rtcp_mux_enabled = GetParam();
386 jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp);
387
388 EXPECT_FALSE(
389 jsep_transport_->VerifyCertificateFingerprint(nullptr, nullptr).ok());
390 rtc::KeyType key_types[] = {rtc::KT_RSA, rtc::KT_ECDSA};
391
392 for (auto& key_type : key_types) {
393 rtc::scoped_refptr<rtc::RTCCertificate> certificate =
394 rtc::RTCCertificate::Create(
395 rtc::SSLIdentity::Create("testing", key_type));
396 ASSERT_NE(nullptr, certificate);
397
398 std::string digest_algorithm;
399 ASSERT_TRUE(certificate->GetSSLCertificate().GetSignatureDigestAlgorithm(
400 &digest_algorithm));
401 ASSERT_FALSE(digest_algorithm.empty());
402 std::unique_ptr<rtc::SSLFingerprint> good_fingerprint =
403 rtc::SSLFingerprint::CreateUnique(digest_algorithm,
404 *certificate->identity());
405 ASSERT_NE(nullptr, good_fingerprint);
406
407 EXPECT_TRUE(jsep_transport_
408 ->VerifyCertificateFingerprint(certificate.get(),
409 good_fingerprint.get())
410 .ok());
411 EXPECT_FALSE(jsep_transport_
412 ->VerifyCertificateFingerprint(certificate.get(), nullptr)
413 .ok());
414 EXPECT_FALSE(
415 jsep_transport_
416 ->VerifyCertificateFingerprint(nullptr, good_fingerprint.get())
417 .ok());
418
419 rtc::SSLFingerprint bad_fingerprint = *good_fingerprint;
420 bad_fingerprint.digest.AppendData("0", 1);
421 EXPECT_FALSE(
422 jsep_transport_
423 ->VerifyCertificateFingerprint(certificate.get(), &bad_fingerprint)
424 .ok());
425 }
426 }
427
428 // Tests the logic of DTLS role negotiation for an initial offer/answer.
TEST_P(JsepTransport2WithRtcpMux,ValidDtlsRoleNegotiation)429 TEST_P(JsepTransport2WithRtcpMux, ValidDtlsRoleNegotiation) {
430 bool rtcp_mux_enabled = GetParam();
431 // Just use the same certificate for both sides; doesn't really matter in a
432 // non end-to-end test.
433 rtc::scoped_refptr<rtc::RTCCertificate> certificate =
434 rtc::RTCCertificate::Create(
435 rtc::SSLIdentity::Create("testing", rtc::KT_ECDSA));
436
437 JsepTransportDescription local_description = MakeJsepTransportDescription(
438 rtcp_mux_enabled, kIceUfrag1, kIcePwd1, certificate);
439 JsepTransportDescription remote_description = MakeJsepTransportDescription(
440 rtcp_mux_enabled, kIceUfrag2, kIcePwd2, certificate);
441
442 // Parameters which set the SSL role to SSL_CLIENT.
443 NegotiateRoleParams valid_client_params[] = {
444 {CONNECTIONROLE_ACTIVE, CONNECTIONROLE_ACTPASS, SdpType::kAnswer,
445 SdpType::kOffer},
446 {CONNECTIONROLE_ACTIVE, CONNECTIONROLE_ACTPASS, SdpType::kPrAnswer,
447 SdpType::kOffer},
448 {CONNECTIONROLE_ACTPASS, CONNECTIONROLE_PASSIVE, SdpType::kOffer,
449 SdpType::kAnswer},
450 {CONNECTIONROLE_ACTPASS, CONNECTIONROLE_PASSIVE, SdpType::kOffer,
451 SdpType::kPrAnswer}};
452
453 for (auto& param : valid_client_params) {
454 jsep_transport_ =
455 CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp);
456 jsep_transport_->SetLocalCertificate(certificate);
457
458 local_description.transport_desc.connection_role = param.local_role;
459 remote_description.transport_desc.connection_role = param.remote_role;
460
461 // Set the offer first.
462 if (param.local_type == SdpType::kOffer) {
463 EXPECT_TRUE(jsep_transport_
464 ->SetLocalJsepTransportDescription(local_description,
465 param.local_type)
466 .ok());
467 EXPECT_TRUE(jsep_transport_
468 ->SetRemoteJsepTransportDescription(remote_description,
469 param.remote_type)
470 .ok());
471 } else {
472 EXPECT_TRUE(jsep_transport_
473 ->SetRemoteJsepTransportDescription(remote_description,
474 param.remote_type)
475 .ok());
476 EXPECT_TRUE(jsep_transport_
477 ->SetLocalJsepTransportDescription(local_description,
478 param.local_type)
479 .ok());
480 }
481 EXPECT_EQ(rtc::SSL_CLIENT, *jsep_transport_->GetDtlsRole());
482 }
483
484 // Parameters which set the SSL role to SSL_SERVER.
485 NegotiateRoleParams valid_server_params[] = {
486 {CONNECTIONROLE_PASSIVE, CONNECTIONROLE_ACTPASS, SdpType::kAnswer,
487 SdpType::kOffer},
488 {CONNECTIONROLE_PASSIVE, CONNECTIONROLE_ACTPASS, SdpType::kPrAnswer,
489 SdpType::kOffer},
490 {CONNECTIONROLE_ACTPASS, CONNECTIONROLE_ACTIVE, SdpType::kOffer,
491 SdpType::kAnswer},
492 {CONNECTIONROLE_ACTPASS, CONNECTIONROLE_ACTIVE, SdpType::kOffer,
493 SdpType::kPrAnswer}};
494
495 for (auto& param : valid_server_params) {
496 jsep_transport_ =
497 CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp);
498 jsep_transport_->SetLocalCertificate(certificate);
499
500 local_description.transport_desc.connection_role = param.local_role;
501 remote_description.transport_desc.connection_role = param.remote_role;
502
503 // Set the offer first.
504 if (param.local_type == SdpType::kOffer) {
505 EXPECT_TRUE(jsep_transport_
506 ->SetLocalJsepTransportDescription(local_description,
507 param.local_type)
508 .ok());
509 EXPECT_TRUE(jsep_transport_
510 ->SetRemoteJsepTransportDescription(remote_description,
511 param.remote_type)
512 .ok());
513 } else {
514 EXPECT_TRUE(jsep_transport_
515 ->SetRemoteJsepTransportDescription(remote_description,
516 param.remote_type)
517 .ok());
518 EXPECT_TRUE(jsep_transport_
519 ->SetLocalJsepTransportDescription(local_description,
520 param.local_type)
521 .ok());
522 }
523 EXPECT_EQ(rtc::SSL_SERVER, *jsep_transport_->GetDtlsRole());
524 }
525 }
526
527 // Tests the logic of DTLS role negotiation for an initial offer/answer.
TEST_P(JsepTransport2WithRtcpMux,InvalidDtlsRoleNegotiation)528 TEST_P(JsepTransport2WithRtcpMux, InvalidDtlsRoleNegotiation) {
529 bool rtcp_mux_enabled = GetParam();
530 // Just use the same certificate for both sides; doesn't really matter in a
531 // non end-to-end test.
532 rtc::scoped_refptr<rtc::RTCCertificate> certificate =
533 rtc::RTCCertificate::Create(
534 rtc::SSLIdentity::Create("testing", rtc::KT_ECDSA));
535
536 JsepTransportDescription local_description = MakeJsepTransportDescription(
537 rtcp_mux_enabled, kIceUfrag1, kIcePwd1, certificate);
538 JsepTransportDescription remote_description = MakeJsepTransportDescription(
539 rtcp_mux_enabled, kIceUfrag2, kIcePwd2, certificate);
540
541 NegotiateRoleParams duplicate_params[] = {
542 {CONNECTIONROLE_ACTIVE, CONNECTIONROLE_ACTIVE, SdpType::kAnswer,
543 SdpType::kOffer},
544 {CONNECTIONROLE_ACTPASS, CONNECTIONROLE_ACTPASS, SdpType::kAnswer,
545 SdpType::kOffer},
546 {CONNECTIONROLE_PASSIVE, CONNECTIONROLE_PASSIVE, SdpType::kAnswer,
547 SdpType::kOffer},
548 {CONNECTIONROLE_ACTIVE, CONNECTIONROLE_ACTIVE, SdpType::kPrAnswer,
549 SdpType::kOffer},
550 {CONNECTIONROLE_ACTPASS, CONNECTIONROLE_ACTPASS, SdpType::kPrAnswer,
551 SdpType::kOffer},
552 {CONNECTIONROLE_PASSIVE, CONNECTIONROLE_PASSIVE, SdpType::kPrAnswer,
553 SdpType::kOffer},
554 {CONNECTIONROLE_ACTIVE, CONNECTIONROLE_ACTIVE, SdpType::kOffer,
555 SdpType::kAnswer},
556 {CONNECTIONROLE_ACTPASS, CONNECTIONROLE_ACTPASS, SdpType::kOffer,
557 SdpType::kAnswer},
558 {CONNECTIONROLE_PASSIVE, CONNECTIONROLE_PASSIVE, SdpType::kOffer,
559 SdpType::kAnswer},
560 {CONNECTIONROLE_ACTIVE, CONNECTIONROLE_ACTIVE, SdpType::kOffer,
561 SdpType::kPrAnswer},
562 {CONNECTIONROLE_ACTPASS, CONNECTIONROLE_ACTPASS, SdpType::kOffer,
563 SdpType::kPrAnswer},
564 {CONNECTIONROLE_PASSIVE, CONNECTIONROLE_PASSIVE, SdpType::kOffer,
565 SdpType::kPrAnswer}};
566
567 for (auto& param : duplicate_params) {
568 jsep_transport_ =
569 CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp);
570 jsep_transport_->SetLocalCertificate(certificate);
571
572 local_description.transport_desc.connection_role = param.local_role;
573 remote_description.transport_desc.connection_role = param.remote_role;
574
575 if (param.local_type == SdpType::kOffer) {
576 EXPECT_TRUE(jsep_transport_
577 ->SetLocalJsepTransportDescription(local_description,
578 param.local_type)
579 .ok());
580 EXPECT_FALSE(jsep_transport_
581 ->SetRemoteJsepTransportDescription(remote_description,
582 param.remote_type)
583 .ok());
584 } else {
585 EXPECT_TRUE(jsep_transport_
586 ->SetRemoteJsepTransportDescription(remote_description,
587 param.remote_type)
588 .ok());
589 EXPECT_FALSE(jsep_transport_
590 ->SetLocalJsepTransportDescription(local_description,
591 param.local_type)
592 .ok());
593 }
594 }
595
596 // Invalid parameters due to the offerer not using ACTPASS.
597 NegotiateRoleParams offerer_without_actpass_params[] = {
598 {CONNECTIONROLE_ACTIVE, CONNECTIONROLE_PASSIVE, SdpType::kAnswer,
599 SdpType::kOffer},
600 {CONNECTIONROLE_PASSIVE, CONNECTIONROLE_ACTIVE, SdpType::kAnswer,
601 SdpType::kOffer},
602 {CONNECTIONROLE_ACTPASS, CONNECTIONROLE_PASSIVE, SdpType::kAnswer,
603 SdpType::kOffer},
604 {CONNECTIONROLE_ACTIVE, CONNECTIONROLE_PASSIVE, SdpType::kPrAnswer,
605 SdpType::kOffer},
606 {CONNECTIONROLE_PASSIVE, CONNECTIONROLE_ACTIVE, SdpType::kPrAnswer,
607 SdpType::kOffer},
608 {CONNECTIONROLE_ACTPASS, CONNECTIONROLE_PASSIVE, SdpType::kPrAnswer,
609 SdpType::kOffer},
610 {CONNECTIONROLE_ACTIVE, CONNECTIONROLE_PASSIVE, SdpType::kOffer,
611 SdpType::kAnswer},
612 {CONNECTIONROLE_PASSIVE, CONNECTIONROLE_ACTIVE, SdpType::kOffer,
613 SdpType::kAnswer},
614 {CONNECTIONROLE_PASSIVE, CONNECTIONROLE_ACTPASS, SdpType::kOffer,
615 SdpType::kAnswer},
616 {CONNECTIONROLE_ACTIVE, CONNECTIONROLE_PASSIVE, SdpType::kOffer,
617 SdpType::kPrAnswer},
618 {CONNECTIONROLE_PASSIVE, CONNECTIONROLE_ACTIVE, SdpType::kOffer,
619 SdpType::kPrAnswer},
620 {CONNECTIONROLE_PASSIVE, CONNECTIONROLE_ACTPASS, SdpType::kOffer,
621 SdpType::kPrAnswer}};
622
623 for (auto& param : offerer_without_actpass_params) {
624 jsep_transport_ =
625 CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp);
626 jsep_transport_->SetLocalCertificate(certificate);
627
628 local_description.transport_desc.connection_role = param.local_role;
629 remote_description.transport_desc.connection_role = param.remote_role;
630
631 if (param.local_type == SdpType::kOffer) {
632 EXPECT_TRUE(jsep_transport_
633 ->SetLocalJsepTransportDescription(local_description,
634 param.local_type)
635 .ok());
636 EXPECT_FALSE(jsep_transport_
637 ->SetRemoteJsepTransportDescription(remote_description,
638 param.remote_type)
639 .ok());
640 } else {
641 EXPECT_TRUE(jsep_transport_
642 ->SetRemoteJsepTransportDescription(remote_description,
643 param.remote_type)
644 .ok());
645 EXPECT_FALSE(jsep_transport_
646 ->SetLocalJsepTransportDescription(local_description,
647 param.local_type)
648 .ok());
649 }
650 }
651 }
652
653 INSTANTIATE_TEST_SUITE_P(JsepTransport2Test,
654 JsepTransport2WithRtcpMux,
655 ::testing::Bool());
656
657 // Test that a reoffer in the opposite direction is successful as long as the
658 // role isn't changing. Doesn't test every possible combination like the test
659 // above.
TEST_F(JsepTransport2Test,ValidDtlsReofferFromAnswerer)660 TEST_F(JsepTransport2Test, ValidDtlsReofferFromAnswerer) {
661 // Just use the same certificate for both sides; doesn't really matter in a
662 // non end-to-end test.
663 rtc::scoped_refptr<rtc::RTCCertificate> certificate =
664 rtc::RTCCertificate::Create(
665 rtc::SSLIdentity::Create("testing", rtc::KT_ECDSA));
666 bool rtcp_mux_enabled = true;
667 jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp);
668 jsep_transport_->SetLocalCertificate(certificate);
669
670 JsepTransportDescription local_offer =
671 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag1, kIcePwd1,
672 certificate, CONNECTIONROLE_ACTPASS);
673 JsepTransportDescription remote_answer =
674 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag2, kIcePwd2,
675 certificate, CONNECTIONROLE_ACTIVE);
676
677 EXPECT_TRUE(
678 jsep_transport_
679 ->SetLocalJsepTransportDescription(local_offer, SdpType::kOffer)
680 .ok());
681 EXPECT_TRUE(
682 jsep_transport_
683 ->SetRemoteJsepTransportDescription(remote_answer, SdpType::kAnswer)
684 .ok());
685
686 // We were actpass->active previously, now in the other direction it's
687 // actpass->passive.
688 JsepTransportDescription remote_offer =
689 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag2, kIcePwd2,
690 certificate, CONNECTIONROLE_ACTPASS);
691 JsepTransportDescription local_answer =
692 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag1, kIcePwd1,
693 certificate, CONNECTIONROLE_PASSIVE);
694
695 EXPECT_TRUE(
696 jsep_transport_
697 ->SetRemoteJsepTransportDescription(remote_offer, SdpType::kOffer)
698 .ok());
699 EXPECT_TRUE(
700 jsep_transport_
701 ->SetLocalJsepTransportDescription(local_answer, SdpType::kAnswer)
702 .ok());
703 }
704
705 // Test that a reoffer in the opposite direction fails if the role changes.
706 // Inverse of test above.
TEST_F(JsepTransport2Test,InvalidDtlsReofferFromAnswerer)707 TEST_F(JsepTransport2Test, InvalidDtlsReofferFromAnswerer) {
708 // Just use the same certificate for both sides; doesn't really matter in a
709 // non end-to-end test.
710 rtc::scoped_refptr<rtc::RTCCertificate> certificate =
711 rtc::RTCCertificate::Create(
712 rtc::SSLIdentity::Create("testing", rtc::KT_ECDSA));
713 bool rtcp_mux_enabled = true;
714 jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp);
715 jsep_transport_->SetLocalCertificate(certificate);
716
717 JsepTransportDescription local_offer =
718 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag1, kIcePwd1,
719 certificate, CONNECTIONROLE_ACTPASS);
720 JsepTransportDescription remote_answer =
721 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag2, kIcePwd2,
722 certificate, CONNECTIONROLE_ACTIVE);
723
724 EXPECT_TRUE(
725 jsep_transport_
726 ->SetLocalJsepTransportDescription(local_offer, SdpType::kOffer)
727 .ok());
728 EXPECT_TRUE(
729 jsep_transport_
730 ->SetRemoteJsepTransportDescription(remote_answer, SdpType::kAnswer)
731 .ok());
732
733 // Changing role to passive here isn't allowed. Though for some reason this
734 // only fails in SetLocalTransportDescription.
735 JsepTransportDescription remote_offer =
736 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag2, kIcePwd2,
737 certificate, CONNECTIONROLE_PASSIVE);
738 JsepTransportDescription local_answer =
739 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag1, kIcePwd1,
740 certificate, CONNECTIONROLE_ACTIVE);
741
742 EXPECT_TRUE(
743 jsep_transport_
744 ->SetRemoteJsepTransportDescription(remote_offer, SdpType::kOffer)
745 .ok());
746 EXPECT_FALSE(
747 jsep_transport_
748 ->SetLocalJsepTransportDescription(local_answer, SdpType::kAnswer)
749 .ok());
750 }
751
752 // Test that a remote offer with the current negotiated role can be accepted.
753 // This is allowed by dtls-sdp, though we'll never generate such an offer,
754 // since JSEP requires generating "actpass".
TEST_F(JsepTransport2Test,RemoteOfferWithCurrentNegotiatedDtlsRole)755 TEST_F(JsepTransport2Test, RemoteOfferWithCurrentNegotiatedDtlsRole) {
756 rtc::scoped_refptr<rtc::RTCCertificate> certificate =
757 rtc::RTCCertificate::Create(
758 rtc::SSLIdentity::Create("testing", rtc::KT_ECDSA));
759 bool rtcp_mux_enabled = true;
760 jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp);
761 jsep_transport_->SetLocalCertificate(certificate);
762
763 JsepTransportDescription remote_desc =
764 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag1, kIcePwd1,
765 certificate, CONNECTIONROLE_ACTPASS);
766 JsepTransportDescription local_desc =
767 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag2, kIcePwd2,
768 certificate, CONNECTIONROLE_ACTIVE);
769
770 // Normal initial offer/answer with "actpass" in the offer and "active" in
771 // the answer.
772 ASSERT_TRUE(
773 jsep_transport_
774 ->SetRemoteJsepTransportDescription(remote_desc, SdpType::kOffer)
775 .ok());
776 ASSERT_TRUE(
777 jsep_transport_
778 ->SetLocalJsepTransportDescription(local_desc, SdpType::kAnswer)
779 .ok());
780
781 // Sanity check that role was actually negotiated.
782 absl::optional<rtc::SSLRole> role = jsep_transport_->GetDtlsRole();
783 ASSERT_TRUE(role);
784 EXPECT_EQ(rtc::SSL_CLIENT, *role);
785
786 // Subsequent offer with current negotiated role of "passive".
787 remote_desc.transport_desc.connection_role = CONNECTIONROLE_PASSIVE;
788 EXPECT_TRUE(
789 jsep_transport_
790 ->SetRemoteJsepTransportDescription(remote_desc, SdpType::kOffer)
791 .ok());
792 EXPECT_TRUE(
793 jsep_transport_
794 ->SetLocalJsepTransportDescription(local_desc, SdpType::kAnswer)
795 .ok());
796 }
797
798 // Test that a remote offer with the inverse of the current negotiated DTLS
799 // role is rejected.
TEST_F(JsepTransport2Test,RemoteOfferThatChangesNegotiatedDtlsRole)800 TEST_F(JsepTransport2Test, RemoteOfferThatChangesNegotiatedDtlsRole) {
801 rtc::scoped_refptr<rtc::RTCCertificate> certificate =
802 rtc::RTCCertificate::Create(
803 rtc::SSLIdentity::Create("testing", rtc::KT_ECDSA));
804 bool rtcp_mux_enabled = true;
805 jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp);
806 jsep_transport_->SetLocalCertificate(certificate);
807
808 JsepTransportDescription remote_desc =
809 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag1, kIcePwd1,
810 certificate, CONNECTIONROLE_ACTPASS);
811 JsepTransportDescription local_desc =
812 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag2, kIcePwd2,
813 certificate, CONNECTIONROLE_ACTIVE);
814
815 // Normal initial offer/answer with "actpass" in the offer and "active" in
816 // the answer.
817 ASSERT_TRUE(
818 jsep_transport_
819 ->SetRemoteJsepTransportDescription(remote_desc, SdpType::kOffer)
820 .ok());
821 ASSERT_TRUE(
822 jsep_transport_
823 ->SetLocalJsepTransportDescription(local_desc, SdpType::kAnswer)
824 .ok());
825
826 // Sanity check that role was actually negotiated.
827 absl::optional<rtc::SSLRole> role = jsep_transport_->GetDtlsRole();
828 ASSERT_TRUE(role);
829 EXPECT_EQ(rtc::SSL_CLIENT, *role);
830
831 // Subsequent offer with current negotiated role of "passive".
832 remote_desc.transport_desc.connection_role = CONNECTIONROLE_ACTIVE;
833 EXPECT_TRUE(
834 jsep_transport_
835 ->SetRemoteJsepTransportDescription(remote_desc, SdpType::kOffer)
836 .ok());
837 EXPECT_FALSE(
838 jsep_transport_
839 ->SetLocalJsepTransportDescription(local_desc, SdpType::kAnswer)
840 .ok());
841 }
842
843 // Testing that a legacy client that doesn't use the setup attribute will be
844 // interpreted as having an active role.
TEST_F(JsepTransport2Test,DtlsSetupWithLegacyAsAnswerer)845 TEST_F(JsepTransport2Test, DtlsSetupWithLegacyAsAnswerer) {
846 rtc::scoped_refptr<rtc::RTCCertificate> certificate =
847 rtc::RTCCertificate::Create(
848 rtc::SSLIdentity::Create("testing", rtc::KT_ECDSA));
849 bool rtcp_mux_enabled = true;
850 jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp);
851 jsep_transport_->SetLocalCertificate(certificate);
852
853 JsepTransportDescription remote_desc =
854 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag1, kIcePwd1,
855 certificate, CONNECTIONROLE_ACTPASS);
856 JsepTransportDescription local_desc =
857 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag2, kIcePwd2,
858 certificate, CONNECTIONROLE_ACTIVE);
859
860 local_desc.transport_desc.connection_role = CONNECTIONROLE_ACTPASS;
861 ASSERT_TRUE(
862 jsep_transport_
863 ->SetLocalJsepTransportDescription(local_desc, SdpType::kOffer)
864 .ok());
865 // Use CONNECTIONROLE_NONE to simulate legacy endpoint.
866 remote_desc.transport_desc.connection_role = CONNECTIONROLE_NONE;
867 ASSERT_TRUE(
868 jsep_transport_
869 ->SetRemoteJsepTransportDescription(remote_desc, SdpType::kAnswer)
870 .ok());
871
872 absl::optional<rtc::SSLRole> role = jsep_transport_->GetDtlsRole();
873 ASSERT_TRUE(role);
874 // Since legacy answer ommitted setup atribute, and we offered actpass, we
875 // should act as passive (server).
876 EXPECT_EQ(rtc::SSL_SERVER, *role);
877 }
878
879 // Tests that when the RTCP mux is successfully negotiated, the RTCP transport
880 // will be destroyed and the SignalRtpMuxActive will be fired.
TEST_F(JsepTransport2Test,RtcpMuxNegotiation)881 TEST_F(JsepTransport2Test, RtcpMuxNegotiation) {
882 jsep_transport_ =
883 CreateJsepTransport2(/*rtcp_mux_enabled=*/false, SrtpMode::kDtlsSrtp);
884 JsepTransportDescription local_desc;
885 local_desc.rtcp_mux_enabled = true;
886 ASSERT_NE(nullptr, jsep_transport_->rtcp_dtls_transport());
887 EXPECT_FALSE(signal_rtcp_mux_active_received_);
888
889 // The remote side supports RTCP-mux.
890 JsepTransportDescription remote_desc;
891 remote_desc.rtcp_mux_enabled = true;
892 ASSERT_TRUE(
893 jsep_transport_
894 ->SetLocalJsepTransportDescription(local_desc, SdpType::kOffer)
895 .ok());
896 ASSERT_TRUE(
897 jsep_transport_
898 ->SetRemoteJsepTransportDescription(remote_desc, SdpType::kAnswer)
899 .ok());
900
901 EXPECT_EQ(nullptr, jsep_transport_->rtcp_dtls_transport());
902 EXPECT_TRUE(signal_rtcp_mux_active_received_);
903
904 // The remote side doesn't support RTCP-mux.
905 jsep_transport_ =
906 CreateJsepTransport2(/*rtcp_mux_enabled=*/false, SrtpMode::kDtlsSrtp);
907 signal_rtcp_mux_active_received_ = false;
908 remote_desc.rtcp_mux_enabled = false;
909 ASSERT_TRUE(
910 jsep_transport_
911 ->SetLocalJsepTransportDescription(local_desc, SdpType::kOffer)
912 .ok());
913 ASSERT_TRUE(
914 jsep_transport_
915 ->SetRemoteJsepTransportDescription(remote_desc, SdpType::kAnswer)
916 .ok());
917
918 EXPECT_NE(nullptr, jsep_transport_->rtcp_dtls_transport());
919 EXPECT_FALSE(signal_rtcp_mux_active_received_);
920 }
921
TEST_F(JsepTransport2Test,SdesNegotiation)922 TEST_F(JsepTransport2Test, SdesNegotiation) {
923 jsep_transport_ =
924 CreateJsepTransport2(/*rtcp_mux_enabled=*/true, SrtpMode::kSdes);
925 ASSERT_TRUE(sdes_transport_);
926 EXPECT_FALSE(sdes_transport_->IsSrtpActive());
927
928 JsepTransportDescription offer_desc;
929 offer_desc.cryptos.push_back(cricket::CryptoParams(
930 1, rtc::CS_AES_CM_128_HMAC_SHA1_32,
931 "inline:" + rtc::CreateRandomString(40), std::string()));
932 ASSERT_TRUE(
933 jsep_transport_
934 ->SetLocalJsepTransportDescription(offer_desc, SdpType::kOffer)
935 .ok());
936
937 JsepTransportDescription answer_desc;
938 answer_desc.cryptos.push_back(cricket::CryptoParams(
939 1, rtc::CS_AES_CM_128_HMAC_SHA1_32,
940 "inline:" + rtc::CreateRandomString(40), std::string()));
941 ASSERT_TRUE(
942 jsep_transport_
943 ->SetRemoteJsepTransportDescription(answer_desc, SdpType::kAnswer)
944 .ok());
945 EXPECT_TRUE(sdes_transport_->IsSrtpActive());
946 }
947
TEST_F(JsepTransport2Test,SdesNegotiationWithEmptyCryptosInAnswer)948 TEST_F(JsepTransport2Test, SdesNegotiationWithEmptyCryptosInAnswer) {
949 jsep_transport_ =
950 CreateJsepTransport2(/*rtcp_mux_enabled=*/true, SrtpMode::kSdes);
951 ASSERT_TRUE(sdes_transport_);
952 EXPECT_FALSE(sdes_transport_->IsSrtpActive());
953
954 JsepTransportDescription offer_desc;
955 offer_desc.cryptos.push_back(cricket::CryptoParams(
956 1, rtc::CS_AES_CM_128_HMAC_SHA1_32,
957 "inline:" + rtc::CreateRandomString(40), std::string()));
958 ASSERT_TRUE(
959 jsep_transport_
960 ->SetLocalJsepTransportDescription(offer_desc, SdpType::kOffer)
961 .ok());
962
963 JsepTransportDescription answer_desc;
964 ASSERT_TRUE(
965 jsep_transport_
966 ->SetRemoteJsepTransportDescription(answer_desc, SdpType::kAnswer)
967 .ok());
968 // SRTP is not active because the crypto parameter is answer is empty.
969 EXPECT_FALSE(sdes_transport_->IsSrtpActive());
970 }
971
TEST_F(JsepTransport2Test,SdesNegotiationWithMismatchedCryptos)972 TEST_F(JsepTransport2Test, SdesNegotiationWithMismatchedCryptos) {
973 jsep_transport_ =
974 CreateJsepTransport2(/*rtcp_mux_enabled=*/true, SrtpMode::kSdes);
975 ASSERT_TRUE(sdes_transport_);
976 EXPECT_FALSE(sdes_transport_->IsSrtpActive());
977
978 JsepTransportDescription offer_desc;
979 offer_desc.cryptos.push_back(cricket::CryptoParams(
980 1, rtc::CS_AES_CM_128_HMAC_SHA1_32,
981 "inline:" + rtc::CreateRandomString(40), std::string()));
982 ASSERT_TRUE(
983 jsep_transport_
984 ->SetLocalJsepTransportDescription(offer_desc, SdpType::kOffer)
985 .ok());
986
987 JsepTransportDescription answer_desc;
988 answer_desc.cryptos.push_back(cricket::CryptoParams(
989 1, rtc::CS_AES_CM_128_HMAC_SHA1_80,
990 "inline:" + rtc::CreateRandomString(40), std::string()));
991 // Expected to fail because the crypto parameters don't match.
992 ASSERT_FALSE(
993 jsep_transport_
994 ->SetRemoteJsepTransportDescription(answer_desc, SdpType::kAnswer)
995 .ok());
996 }
997
998 // Tests that the remote candidates can be added to the transports after both
999 // local and remote descriptions are set.
TEST_F(JsepTransport2Test,AddRemoteCandidates)1000 TEST_F(JsepTransport2Test, AddRemoteCandidates) {
1001 jsep_transport_ =
1002 CreateJsepTransport2(/*rtcp_mux_enabled=*/true, SrtpMode::kDtlsSrtp);
1003 auto fake_ice_transport = static_cast<FakeIceTransport*>(
1004 jsep_transport_->rtp_dtls_transport()->ice_transport());
1005
1006 Candidates candidates;
1007 candidates.push_back(CreateCandidate(/*COMPONENT_RTP*/ 1));
1008 candidates.push_back(CreateCandidate(/*COMPONENT_RTP*/ 1));
1009
1010 JsepTransportDescription desc;
1011 ASSERT_TRUE(
1012 jsep_transport_->SetLocalJsepTransportDescription(desc, SdpType::kOffer)
1013 .ok());
1014 // Expected to fail because the remote description is unset.
1015 EXPECT_FALSE(jsep_transport_->AddRemoteCandidates(candidates).ok());
1016
1017 ASSERT_TRUE(
1018 jsep_transport_->SetRemoteJsepTransportDescription(desc, SdpType::kAnswer)
1019 .ok());
1020 EXPECT_EQ(0u, fake_ice_transport->remote_candidates().size());
1021 EXPECT_TRUE(jsep_transport_->AddRemoteCandidates(candidates).ok());
1022 EXPECT_EQ(candidates.size(), fake_ice_transport->remote_candidates().size());
1023 }
1024
1025 enum class Scenario {
1026 kSdes,
1027 kDtlsBeforeCallerSendOffer,
1028 kDtlsBeforeCallerSetAnswer,
1029 kDtlsAfterCallerSetAnswer,
1030 };
1031
1032 class JsepTransport2HeaderExtensionTest
1033 : public JsepTransport2Test,
1034 public ::testing::WithParamInterface<std::tuple<Scenario, bool>> {
1035 protected:
JsepTransport2HeaderExtensionTest()1036 JsepTransport2HeaderExtensionTest() {}
1037
CreateJsepTransportPair(SrtpMode mode)1038 void CreateJsepTransportPair(SrtpMode mode) {
1039 jsep_transport1_ = CreateJsepTransport2(/*rtcp_mux_enabled=*/true, mode);
1040 jsep_transport2_ = CreateJsepTransport2(/*rtcp_mux_enabled=*/true, mode);
1041
1042 auto fake_dtls1 =
1043 static_cast<FakeDtlsTransport*>(jsep_transport1_->rtp_dtls_transport());
1044 auto fake_dtls2 =
1045 static_cast<FakeDtlsTransport*>(jsep_transport2_->rtp_dtls_transport());
1046
1047 fake_dtls1->fake_ice_transport()->SignalReadPacket.connect(
1048 this, &JsepTransport2HeaderExtensionTest::OnReadPacket1);
1049 fake_dtls2->fake_ice_transport()->SignalReadPacket.connect(
1050 this, &JsepTransport2HeaderExtensionTest::OnReadPacket2);
1051
1052 if (mode == SrtpMode::kDtlsSrtp) {
1053 auto cert1 = rtc::RTCCertificate::Create(
1054 rtc::SSLIdentity::Create("session1", rtc::KT_DEFAULT));
1055 jsep_transport1_->rtp_dtls_transport()->SetLocalCertificate(cert1);
1056 auto cert2 = rtc::RTCCertificate::Create(
1057 rtc::SSLIdentity::Create("session1", rtc::KT_DEFAULT));
1058 jsep_transport2_->rtp_dtls_transport()->SetLocalCertificate(cert2);
1059 }
1060 }
1061
OnReadPacket1(rtc::PacketTransportInternal * transport,const char * data,size_t size,const int64_t &,int flags)1062 void OnReadPacket1(rtc::PacketTransportInternal* transport,
1063 const char* data,
1064 size_t size,
1065 const int64_t& /* packet_time_us */,
1066 int flags) {
1067 RTC_LOG(LS_INFO) << "JsepTransport 1 Received a packet.";
1068 CompareHeaderExtensions(
1069 reinterpret_cast<const char*>(kPcmuFrameWithExtensions),
1070 sizeof(kPcmuFrameWithExtensions), data, size, recv_encrypted_headers1_,
1071 false);
1072 received_packet_count_++;
1073 }
1074
OnReadPacket2(rtc::PacketTransportInternal * transport,const char * data,size_t size,const int64_t &,int flags)1075 void OnReadPacket2(rtc::PacketTransportInternal* transport,
1076 const char* data,
1077 size_t size,
1078 const int64_t& /* packet_time_us */,
1079 int flags) {
1080 RTC_LOG(LS_INFO) << "JsepTransport 2 Received a packet.";
1081 CompareHeaderExtensions(
1082 reinterpret_cast<const char*>(kPcmuFrameWithExtensions),
1083 sizeof(kPcmuFrameWithExtensions), data, size, recv_encrypted_headers2_,
1084 false);
1085 received_packet_count_++;
1086 }
1087
ConnectTransport()1088 void ConnectTransport() {
1089 auto rtp_dtls_transport1 =
1090 static_cast<FakeDtlsTransport*>(jsep_transport1_->rtp_dtls_transport());
1091 auto rtp_dtls_transport2 =
1092 static_cast<FakeDtlsTransport*>(jsep_transport2_->rtp_dtls_transport());
1093 rtp_dtls_transport1->SetDestination(rtp_dtls_transport2);
1094 }
1095
GetRtpAuthLen()1096 int GetRtpAuthLen() {
1097 bool use_gcm = std::get<1>(GetParam());
1098 if (use_gcm) {
1099 return 16;
1100 }
1101 return 10;
1102 }
1103
TestSendRecvPacketWithEncryptedHeaderExtension()1104 void TestSendRecvPacketWithEncryptedHeaderExtension() {
1105 TestOneWaySendRecvPacketWithEncryptedHeaderExtension(
1106 jsep_transport1_.get());
1107 TestOneWaySendRecvPacketWithEncryptedHeaderExtension(
1108 jsep_transport2_.get());
1109 }
1110
TestOneWaySendRecvPacketWithEncryptedHeaderExtension(JsepTransport * sender_transport)1111 void TestOneWaySendRecvPacketWithEncryptedHeaderExtension(
1112 JsepTransport* sender_transport) {
1113 size_t rtp_len = sizeof(kPcmuFrameWithExtensions);
1114 size_t packet_size = rtp_len + GetRtpAuthLen();
1115 rtc::Buffer rtp_packet_buffer(packet_size);
1116 char* rtp_packet_data = rtp_packet_buffer.data<char>();
1117 memcpy(rtp_packet_data, kPcmuFrameWithExtensions, rtp_len);
1118 // In order to be able to run this test function multiple times we can not
1119 // use the same sequence number twice. Increase the sequence number by one.
1120 rtc::SetBE16(reinterpret_cast<uint8_t*>(rtp_packet_data) + 2,
1121 ++sequence_number_);
1122 rtc::CopyOnWriteBuffer rtp_packet(rtp_packet_data, rtp_len, packet_size);
1123
1124 int packet_count_before = received_packet_count_;
1125 rtc::PacketOptions options;
1126 // Send a packet and verify that the packet can be successfully received and
1127 // decrypted.
1128 ASSERT_TRUE(sender_transport->rtp_transport()->SendRtpPacket(
1129 &rtp_packet, options, cricket::PF_SRTP_BYPASS));
1130 EXPECT_EQ(packet_count_before + 1, received_packet_count_);
1131 }
1132
1133 int sequence_number_ = 0;
1134 int received_packet_count_ = 0;
1135 std::unique_ptr<JsepTransport> jsep_transport1_;
1136 std::unique_ptr<JsepTransport> jsep_transport2_;
1137 std::vector<int> recv_encrypted_headers1_;
1138 std::vector<int> recv_encrypted_headers2_;
1139 };
1140
1141 // Test that the encrypted header extension works and can be changed in
1142 // different scenarios.
TEST_P(JsepTransport2HeaderExtensionTest,EncryptedHeaderExtensionNegotiation)1143 TEST_P(JsepTransport2HeaderExtensionTest, EncryptedHeaderExtensionNegotiation) {
1144 Scenario scenario = std::get<0>(GetParam());
1145 bool use_gcm = std::get<1>(GetParam());
1146 SrtpMode mode = SrtpMode ::kDtlsSrtp;
1147 if (scenario == Scenario::kSdes) {
1148 mode = SrtpMode::kSdes;
1149 }
1150 CreateJsepTransportPair(mode);
1151 recv_encrypted_headers1_.push_back(kHeaderExtensionIDs[0]);
1152 recv_encrypted_headers2_.push_back(kHeaderExtensionIDs[1]);
1153
1154 cricket::CryptoParams sdes_param(1, rtc::CS_AES_CM_128_HMAC_SHA1_80,
1155 "inline:" + rtc::CreateRandomString(40),
1156 std::string());
1157 if (use_gcm) {
1158 auto fake_dtls1 =
1159 static_cast<FakeDtlsTransport*>(jsep_transport1_->rtp_dtls_transport());
1160 auto fake_dtls2 =
1161 static_cast<FakeDtlsTransport*>(jsep_transport2_->rtp_dtls_transport());
1162
1163 fake_dtls1->SetSrtpCryptoSuite(rtc::SRTP_AEAD_AES_256_GCM);
1164 fake_dtls2->SetSrtpCryptoSuite(rtc::SRTP_AEAD_AES_256_GCM);
1165 }
1166
1167 if (scenario == Scenario::kDtlsBeforeCallerSendOffer) {
1168 ConnectTransport();
1169 }
1170
1171 JsepTransportDescription offer_desc;
1172 offer_desc.encrypted_header_extension_ids = recv_encrypted_headers1_;
1173 if (scenario == Scenario::kSdes) {
1174 offer_desc.cryptos.push_back(sdes_param);
1175 }
1176 ASSERT_TRUE(
1177 jsep_transport1_
1178 ->SetLocalJsepTransportDescription(offer_desc, SdpType::kOffer)
1179 .ok());
1180 ASSERT_TRUE(
1181 jsep_transport2_
1182 ->SetRemoteJsepTransportDescription(offer_desc, SdpType::kOffer)
1183 .ok());
1184
1185 JsepTransportDescription answer_desc;
1186 answer_desc.encrypted_header_extension_ids = recv_encrypted_headers2_;
1187 if (scenario == Scenario::kSdes) {
1188 answer_desc.cryptos.push_back(sdes_param);
1189 }
1190 ASSERT_TRUE(
1191 jsep_transport2_
1192 ->SetLocalJsepTransportDescription(answer_desc, SdpType::kAnswer)
1193 .ok());
1194
1195 if (scenario == Scenario::kDtlsBeforeCallerSetAnswer) {
1196 ConnectTransport();
1197 // Sending packet from transport2 to transport1 should work when they are
1198 // partially configured.
1199 TestOneWaySendRecvPacketWithEncryptedHeaderExtension(
1200 /*sender_transport=*/jsep_transport2_.get());
1201 }
1202
1203 ASSERT_TRUE(
1204 jsep_transport1_
1205 ->SetRemoteJsepTransportDescription(answer_desc, SdpType::kAnswer)
1206 .ok());
1207
1208 if (scenario == Scenario::kDtlsAfterCallerSetAnswer ||
1209 scenario == Scenario::kSdes) {
1210 ConnectTransport();
1211 }
1212 EXPECT_TRUE(jsep_transport1_->rtp_transport()->IsSrtpActive());
1213 EXPECT_TRUE(jsep_transport2_->rtp_transport()->IsSrtpActive());
1214 TestSendRecvPacketWithEncryptedHeaderExtension();
1215
1216 // Change the encrypted header extension in a new offer/answer exchange.
1217 recv_encrypted_headers1_.clear();
1218 recv_encrypted_headers2_.clear();
1219 recv_encrypted_headers1_.push_back(kHeaderExtensionIDs[1]);
1220 recv_encrypted_headers2_.push_back(kHeaderExtensionIDs[0]);
1221 offer_desc.encrypted_header_extension_ids = recv_encrypted_headers1_;
1222 answer_desc.encrypted_header_extension_ids = recv_encrypted_headers2_;
1223 ASSERT_TRUE(
1224 jsep_transport1_
1225 ->SetLocalJsepTransportDescription(offer_desc, SdpType::kOffer)
1226 .ok());
1227 ASSERT_TRUE(
1228 jsep_transport2_
1229 ->SetRemoteJsepTransportDescription(offer_desc, SdpType::kOffer)
1230 .ok());
1231 ASSERT_TRUE(
1232 jsep_transport2_
1233 ->SetLocalJsepTransportDescription(answer_desc, SdpType::kAnswer)
1234 .ok());
1235 ASSERT_TRUE(
1236 jsep_transport1_
1237 ->SetRemoteJsepTransportDescription(answer_desc, SdpType::kAnswer)
1238 .ok());
1239 EXPECT_TRUE(jsep_transport1_->rtp_transport()->IsSrtpActive());
1240 EXPECT_TRUE(jsep_transport2_->rtp_transport()->IsSrtpActive());
1241 TestSendRecvPacketWithEncryptedHeaderExtension();
1242 }
1243
1244 INSTANTIATE_TEST_SUITE_P(
1245 JsepTransport2Test,
1246 JsepTransport2HeaderExtensionTest,
1247 ::testing::Values(
1248 std::make_tuple(Scenario::kSdes, false),
1249 std::make_tuple(Scenario::kDtlsBeforeCallerSendOffer, true),
1250 std::make_tuple(Scenario::kDtlsBeforeCallerSetAnswer, true),
1251 std::make_tuple(Scenario::kDtlsAfterCallerSetAnswer, true),
1252 std::make_tuple(Scenario::kDtlsBeforeCallerSendOffer, false),
1253 std::make_tuple(Scenario::kDtlsBeforeCallerSetAnswer, false),
1254 std::make_tuple(Scenario::kDtlsAfterCallerSetAnswer, false)));
1255
1256 // This test verifies the ICE parameters are properly applied to the transports.
TEST_F(JsepTransport2Test,SetIceParametersWithRenomination)1257 TEST_F(JsepTransport2Test, SetIceParametersWithRenomination) {
1258 jsep_transport_ =
1259 CreateJsepTransport2(/* rtcp_mux_enabled= */ true, SrtpMode::kDtlsSrtp);
1260
1261 JsepTransportDescription jsep_description;
1262 jsep_description.transport_desc = TransportDescription(kIceUfrag1, kIcePwd1);
1263 jsep_description.transport_desc.AddOption(ICE_OPTION_RENOMINATION);
1264 ASSERT_TRUE(
1265 jsep_transport_
1266 ->SetLocalJsepTransportDescription(jsep_description, SdpType::kOffer)
1267 .ok());
1268 auto fake_ice_transport = static_cast<FakeIceTransport*>(
1269 jsep_transport_->rtp_dtls_transport()->ice_transport());
1270 EXPECT_EQ(ICEMODE_FULL, fake_ice_transport->remote_ice_mode());
1271 EXPECT_EQ(kIceUfrag1, fake_ice_transport->ice_ufrag());
1272 EXPECT_EQ(kIcePwd1, fake_ice_transport->ice_pwd());
1273 EXPECT_TRUE(fake_ice_transport->ice_parameters().renomination);
1274
1275 jsep_description.transport_desc = TransportDescription(kIceUfrag2, kIcePwd2);
1276 jsep_description.transport_desc.AddOption(ICE_OPTION_RENOMINATION);
1277 ASSERT_TRUE(jsep_transport_
1278 ->SetRemoteJsepTransportDescription(jsep_description,
1279 SdpType::kAnswer)
1280 .ok());
1281 fake_ice_transport = static_cast<FakeIceTransport*>(
1282 jsep_transport_->rtp_dtls_transport()->ice_transport());
1283 EXPECT_EQ(ICEMODE_FULL, fake_ice_transport->remote_ice_mode());
1284 EXPECT_EQ(kIceUfrag2, fake_ice_transport->remote_ice_ufrag());
1285 EXPECT_EQ(kIcePwd2, fake_ice_transport->remote_ice_pwd());
1286 EXPECT_TRUE(fake_ice_transport->remote_ice_parameters().renomination);
1287 }
1288
1289 } // namespace
1290 } // namespace cricket
1291