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