• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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