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