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