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