blob: 00f58f64a0e5230b7c607ea86eed52f9e6103d7d [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),
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -0700112 /*sctp_transport=*/nullptr,
Anton Sukhanov292ce4e2019-06-03 13:00:24 -0700113 /*media_transport=*/nullptr,
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -0700114 /*datagram_transport=*/nullptr,
115 /*data_channel_transport=*/nullptr);
Zhi Huange818b6e2018-02-22 15:26:27 -0800116
117 signal_rtcp_mux_active_received_ = false;
Zhi Huange830e682018-03-30 10:48:35 -0700118 jsep_transport->SignalRtcpMuxActive.connect(
Zhi Huange818b6e2018-02-22 15:26:27 -0800119 this, &JsepTransport2Test::OnRtcpMuxActive);
Zhi Huange830e682018-03-30 10:48:35 -0700120 return jsep_transport;
Zhi Huange818b6e2018-02-22 15:26:27 -0800121 }
122
123 JsepTransportDescription MakeJsepTransportDescription(
124 bool rtcp_mux_enabled,
125 const char* ufrag,
126 const char* pwd,
127 const rtc::scoped_refptr<rtc::RTCCertificate>& cert,
128 ConnectionRole role = CONNECTIONROLE_NONE) {
129 JsepTransportDescription jsep_description;
130 jsep_description.rtcp_mux_enabled = rtcp_mux_enabled;
131
132 std::unique_ptr<rtc::SSLFingerprint> fingerprint;
133 if (cert) {
Steve Anton4905edb2018-10-15 19:27:44 -0700134 fingerprint = rtc::SSLFingerprint::CreateFromCertificate(*cert);
Zhi Huange818b6e2018-02-22 15:26:27 -0800135 }
136 jsep_description.transport_desc =
137 TransportDescription(std::vector<std::string>(), ufrag, pwd,
138 ICEMODE_FULL, role, fingerprint.get());
139 return jsep_description;
140 }
141
142 Candidate CreateCandidate(int component) {
143 Candidate c;
144 c.set_address(rtc::SocketAddress("192.168.1.1", 8000));
145 c.set_component(component);
146 c.set_protocol(UDP_PROTOCOL_NAME);
147 c.set_priority(1);
148 return c;
149 }
150
151 void OnRtcpMuxActive() { signal_rtcp_mux_active_received_ = true; }
152
Zhi Huang365381f2018-04-13 16:44:34 -0700153 std::unique_ptr<JsepTransport> jsep_transport_;
Zhi Huange818b6e2018-02-22 15:26:27 -0800154 bool signal_rtcp_mux_active_received_ = false;
155 // The SrtpTransport is owned by |jsep_transport_|. Keep a raw pointer here
156 // for testing.
157 webrtc::SrtpTransport* sdes_transport_ = nullptr;
158};
159
160// The parameterized tests cover both cases when RTCP mux is enable and
161// disabled.
162class JsepTransport2WithRtcpMux : public JsepTransport2Test,
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200163 public ::testing::WithParamInterface<bool> {};
Zhi Huange818b6e2018-02-22 15:26:27 -0800164
165// This test verifies the ICE parameters are properly applied to the transports.
166TEST_P(JsepTransport2WithRtcpMux, SetIceParameters) {
167 bool rtcp_mux_enabled = GetParam();
Zhi Huange830e682018-03-30 10:48:35 -0700168 jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp);
Zhi Huange818b6e2018-02-22 15:26:27 -0800169
170 JsepTransportDescription jsep_description;
171 jsep_description.transport_desc = TransportDescription(kIceUfrag1, kIcePwd1);
172 jsep_description.rtcp_mux_enabled = rtcp_mux_enabled;
173 ASSERT_TRUE(
174 jsep_transport_
175 ->SetLocalJsepTransportDescription(jsep_description, SdpType::kOffer)
176 .ok());
177 auto fake_ice_transport = static_cast<FakeIceTransport*>(
178 jsep_transport_->rtp_dtls_transport()->ice_transport());
179 EXPECT_EQ(ICEMODE_FULL, fake_ice_transport->remote_ice_mode());
180 EXPECT_EQ(kIceUfrag1, fake_ice_transport->ice_ufrag());
181 EXPECT_EQ(kIcePwd1, fake_ice_transport->ice_pwd());
182 if (!rtcp_mux_enabled) {
183 fake_ice_transport = static_cast<FakeIceTransport*>(
184 jsep_transport_->rtcp_dtls_transport()->ice_transport());
185 ASSERT_TRUE(fake_ice_transport);
186 EXPECT_EQ(ICEMODE_FULL, fake_ice_transport->remote_ice_mode());
187 EXPECT_EQ(kIceUfrag1, fake_ice_transport->ice_ufrag());
188 EXPECT_EQ(kIcePwd1, fake_ice_transport->ice_pwd());
189 }
190
191 jsep_description.transport_desc = TransportDescription(kIceUfrag2, kIcePwd2);
192 ASSERT_TRUE(jsep_transport_
193 ->SetRemoteJsepTransportDescription(jsep_description,
194 SdpType::kAnswer)
195 .ok());
196 fake_ice_transport = static_cast<FakeIceTransport*>(
197 jsep_transport_->rtp_dtls_transport()->ice_transport());
198 EXPECT_EQ(ICEMODE_FULL, fake_ice_transport->remote_ice_mode());
199 EXPECT_EQ(kIceUfrag2, fake_ice_transport->remote_ice_ufrag());
200 EXPECT_EQ(kIcePwd2, fake_ice_transport->remote_ice_pwd());
201 if (!rtcp_mux_enabled) {
202 fake_ice_transport = static_cast<FakeIceTransport*>(
203 jsep_transport_->rtcp_dtls_transport()->ice_transport());
204 ASSERT_TRUE(fake_ice_transport);
205 EXPECT_EQ(ICEMODE_FULL, fake_ice_transport->remote_ice_mode());
206 EXPECT_EQ(kIceUfrag2, fake_ice_transport->remote_ice_ufrag());
207 EXPECT_EQ(kIcePwd2, fake_ice_transport->remote_ice_pwd());
208 }
209}
210
211// Similarly, test DTLS parameters are properly applied to the transports.
212TEST_P(JsepTransport2WithRtcpMux, SetDtlsParameters) {
213 bool rtcp_mux_enabled = GetParam();
Zhi Huange830e682018-03-30 10:48:35 -0700214 jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp);
Zhi Huange818b6e2018-02-22 15:26:27 -0800215
216 // Create certificates.
217 rtc::scoped_refptr<rtc::RTCCertificate> local_cert =
218 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
219 rtc::SSLIdentity::Generate("local", rtc::KT_DEFAULT)));
220 rtc::scoped_refptr<rtc::RTCCertificate> remote_cert =
221 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
222 rtc::SSLIdentity::Generate("remote", rtc::KT_DEFAULT)));
223 jsep_transport_->SetLocalCertificate(local_cert);
224
225 // Apply offer.
226 JsepTransportDescription local_description =
227 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag1, kIcePwd1,
228 local_cert, CONNECTIONROLE_ACTPASS);
229 ASSERT_TRUE(
230 jsep_transport_
231 ->SetLocalJsepTransportDescription(local_description, SdpType::kOffer)
232 .ok());
233 // Apply Answer.
234 JsepTransportDescription remote_description =
235 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag2, kIcePwd2,
236 remote_cert, CONNECTIONROLE_ACTIVE);
237 ASSERT_TRUE(jsep_transport_
238 ->SetRemoteJsepTransportDescription(remote_description,
239 SdpType::kAnswer)
240 .ok());
241
242 // Verify that SSL role and remote fingerprint were set correctly based on
243 // transport descriptions.
244 auto role = jsep_transport_->GetDtlsRole();
245 ASSERT_TRUE(role);
246 EXPECT_EQ(rtc::SSL_SERVER, role); // Because remote description was "active".
247 auto fake_dtls =
248 static_cast<FakeDtlsTransport*>(jsep_transport_->rtp_dtls_transport());
249 EXPECT_EQ(remote_description.transport_desc.identity_fingerprint->ToString(),
250 fake_dtls->dtls_fingerprint().ToString());
251
252 if (!rtcp_mux_enabled) {
253 auto fake_rtcp_dtls =
254 static_cast<FakeDtlsTransport*>(jsep_transport_->rtcp_dtls_transport());
255 EXPECT_EQ(
256 remote_description.transport_desc.identity_fingerprint->ToString(),
257 fake_rtcp_dtls->dtls_fingerprint().ToString());
258 }
259}
260
261// Same as above test, but with remote transport description using
262// CONNECTIONROLE_PASSIVE, expecting SSL_CLIENT role.
263TEST_P(JsepTransport2WithRtcpMux, SetDtlsParametersWithPassiveAnswer) {
264 bool rtcp_mux_enabled = GetParam();
Zhi Huange830e682018-03-30 10:48:35 -0700265 jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp);
Zhi Huange818b6e2018-02-22 15:26:27 -0800266
267 // Create certificates.
268 rtc::scoped_refptr<rtc::RTCCertificate> local_cert =
269 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
270 rtc::SSLIdentity::Generate("local", rtc::KT_DEFAULT)));
271 rtc::scoped_refptr<rtc::RTCCertificate> remote_cert =
272 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
273 rtc::SSLIdentity::Generate("remote", rtc::KT_DEFAULT)));
274 jsep_transport_->SetLocalCertificate(local_cert);
275
276 // Apply offer.
277 JsepTransportDescription local_description =
278 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag1, kIcePwd1,
279 local_cert, CONNECTIONROLE_ACTPASS);
280 ASSERT_TRUE(
281 jsep_transport_
282 ->SetLocalJsepTransportDescription(local_description, SdpType::kOffer)
283 .ok());
284 // Apply Answer.
285 JsepTransportDescription remote_description =
286 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag2, kIcePwd2,
287 remote_cert, CONNECTIONROLE_PASSIVE);
288 ASSERT_TRUE(jsep_transport_
289 ->SetRemoteJsepTransportDescription(remote_description,
290 SdpType::kAnswer)
291 .ok());
292
293 // Verify that SSL role and remote fingerprint were set correctly based on
294 // transport descriptions.
295 auto role = jsep_transport_->GetDtlsRole();
296 ASSERT_TRUE(role);
297 EXPECT_EQ(rtc::SSL_CLIENT,
298 role); // Because remote description was "passive".
299 auto fake_dtls =
300 static_cast<FakeDtlsTransport*>(jsep_transport_->rtp_dtls_transport());
301 EXPECT_EQ(remote_description.transport_desc.identity_fingerprint->ToString(),
302 fake_dtls->dtls_fingerprint().ToString());
303
304 if (!rtcp_mux_enabled) {
305 auto fake_rtcp_dtls =
306 static_cast<FakeDtlsTransport*>(jsep_transport_->rtcp_dtls_transport());
307 EXPECT_EQ(
308 remote_description.transport_desc.identity_fingerprint->ToString(),
309 fake_rtcp_dtls->dtls_fingerprint().ToString());
310 }
311}
312
313// Tests SetNeedsIceRestartFlag and need_ice_restart, ensuring needs_ice_restart
314// only starts returning "false" once an ICE restart has been initiated.
315TEST_P(JsepTransport2WithRtcpMux, NeedsIceRestart) {
316 bool rtcp_mux_enabled = GetParam();
Zhi Huange830e682018-03-30 10:48:35 -0700317 jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp);
Zhi Huange818b6e2018-02-22 15:26:27 -0800318
319 // Use the same JsepTransportDescription for both offer and answer.
320 JsepTransportDescription description;
321 description.transport_desc = TransportDescription(kIceUfrag1, kIcePwd1);
322 ASSERT_TRUE(
323 jsep_transport_
324 ->SetLocalJsepTransportDescription(description, SdpType::kOffer)
325 .ok());
326 ASSERT_TRUE(
327 jsep_transport_
328 ->SetRemoteJsepTransportDescription(description, SdpType::kAnswer)
329 .ok());
330 // Flag initially should be false.
331 EXPECT_FALSE(jsep_transport_->needs_ice_restart());
332
333 // After setting flag, it should be true.
334 jsep_transport_->SetNeedsIceRestartFlag();
335 EXPECT_TRUE(jsep_transport_->needs_ice_restart());
336
337 ASSERT_TRUE(
338 jsep_transport_
339 ->SetLocalJsepTransportDescription(description, SdpType::kOffer)
340 .ok());
341 ASSERT_TRUE(
342 jsep_transport_
343 ->SetRemoteJsepTransportDescription(description, SdpType::kAnswer)
344 .ok());
345 EXPECT_TRUE(jsep_transport_->needs_ice_restart());
346
347 // Doing an offer/answer that restarts ICE should clear the flag.
348 description.transport_desc = TransportDescription(kIceUfrag2, kIcePwd2);
349 ASSERT_TRUE(
350 jsep_transport_
351 ->SetLocalJsepTransportDescription(description, SdpType::kOffer)
352 .ok());
353 ASSERT_TRUE(
354 jsep_transport_
355 ->SetRemoteJsepTransportDescription(description, SdpType::kAnswer)
356 .ok());
357 EXPECT_FALSE(jsep_transport_->needs_ice_restart());
358}
359
360TEST_P(JsepTransport2WithRtcpMux, GetStats) {
361 bool rtcp_mux_enabled = GetParam();
Zhi Huange830e682018-03-30 10:48:35 -0700362 jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp);
Zhi Huange818b6e2018-02-22 15:26:27 -0800363
364 size_t expected_stats_size = rtcp_mux_enabled ? 1u : 2u;
365 TransportStats stats;
366 EXPECT_TRUE(jsep_transport_->GetStats(&stats));
367 EXPECT_EQ(expected_stats_size, stats.channel_stats.size());
368 EXPECT_EQ(ICE_CANDIDATE_COMPONENT_RTP, stats.channel_stats[0].component);
369 if (!rtcp_mux_enabled) {
370 EXPECT_EQ(ICE_CANDIDATE_COMPONENT_RTCP, stats.channel_stats[1].component);
371 }
372}
373
374// Tests that VerifyCertificateFingerprint only returns true when the
375// certificate matches the fingerprint.
376TEST_P(JsepTransport2WithRtcpMux, VerifyCertificateFingerprint) {
377 bool rtcp_mux_enabled = GetParam();
Zhi Huange830e682018-03-30 10:48:35 -0700378 jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp);
Zhi Huange818b6e2018-02-22 15:26:27 -0800379
380 EXPECT_FALSE(
381 jsep_transport_->VerifyCertificateFingerprint(nullptr, nullptr).ok());
382 rtc::KeyType key_types[] = {rtc::KT_RSA, rtc::KT_ECDSA};
383
384 for (auto& key_type : key_types) {
385 rtc::scoped_refptr<rtc::RTCCertificate> certificate =
386 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
387 rtc::SSLIdentity::Generate("testing", key_type)));
388 ASSERT_NE(nullptr, certificate);
389
390 std::string digest_algorithm;
Benjamin Wright6c6c9df2018-10-25 01:16:26 -0700391 ASSERT_TRUE(certificate->GetSSLCertificate().GetSignatureDigestAlgorithm(
Zhi Huange818b6e2018-02-22 15:26:27 -0800392 &digest_algorithm));
393 ASSERT_FALSE(digest_algorithm.empty());
Steve Anton4905edb2018-10-15 19:27:44 -0700394 std::unique_ptr<rtc::SSLFingerprint> good_fingerprint =
395 rtc::SSLFingerprint::CreateUnique(digest_algorithm,
396 *certificate->identity());
Zhi Huange818b6e2018-02-22 15:26:27 -0800397 ASSERT_NE(nullptr, good_fingerprint);
398
399 EXPECT_TRUE(jsep_transport_
400 ->VerifyCertificateFingerprint(certificate.get(),
401 good_fingerprint.get())
402 .ok());
403 EXPECT_FALSE(jsep_transport_
404 ->VerifyCertificateFingerprint(certificate.get(), nullptr)
405 .ok());
406 EXPECT_FALSE(
407 jsep_transport_
408 ->VerifyCertificateFingerprint(nullptr, good_fingerprint.get())
409 .ok());
410
411 rtc::SSLFingerprint bad_fingerprint = *good_fingerprint;
412 bad_fingerprint.digest.AppendData("0", 1);
413 EXPECT_FALSE(
414 jsep_transport_
415 ->VerifyCertificateFingerprint(certificate.get(), &bad_fingerprint)
416 .ok());
417 }
418}
419
420// Tests the logic of DTLS role negotiation for an initial offer/answer.
421TEST_P(JsepTransport2WithRtcpMux, ValidDtlsRoleNegotiation) {
422 bool rtcp_mux_enabled = GetParam();
423 // Just use the same certificate for both sides; doesn't really matter in a
424 // non end-to-end test.
425 rtc::scoped_refptr<rtc::RTCCertificate> certificate =
426 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
427 rtc::SSLIdentity::Generate("testing", rtc::KT_ECDSA)));
428
429 JsepTransportDescription local_description = MakeJsepTransportDescription(
430 rtcp_mux_enabled, kIceUfrag1, kIcePwd1, certificate);
431 JsepTransportDescription remote_description = MakeJsepTransportDescription(
432 rtcp_mux_enabled, kIceUfrag2, kIcePwd2, certificate);
433
434 // Parameters which set the SSL role to SSL_CLIENT.
435 NegotiateRoleParams valid_client_params[] = {
436 {CONNECTIONROLE_ACTIVE, CONNECTIONROLE_ACTPASS, SdpType::kAnswer,
437 SdpType::kOffer},
438 {CONNECTIONROLE_ACTIVE, CONNECTIONROLE_ACTPASS, SdpType::kPrAnswer,
439 SdpType::kOffer},
440 {CONNECTIONROLE_ACTPASS, CONNECTIONROLE_PASSIVE, SdpType::kOffer,
441 SdpType::kAnswer},
442 {CONNECTIONROLE_ACTPASS, CONNECTIONROLE_PASSIVE, SdpType::kOffer,
443 SdpType::kPrAnswer}};
444
445 for (auto& param : valid_client_params) {
Zhi Huange830e682018-03-30 10:48:35 -0700446 jsep_transport_ =
447 CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp);
Zhi Huange818b6e2018-02-22 15:26:27 -0800448 jsep_transport_->SetLocalCertificate(certificate);
449
450 local_description.transport_desc.connection_role = param.local_role;
451 remote_description.transport_desc.connection_role = param.remote_role;
452
453 // Set the offer first.
454 if (param.local_type == SdpType::kOffer) {
455 EXPECT_TRUE(jsep_transport_
456 ->SetLocalJsepTransportDescription(local_description,
457 param.local_type)
458 .ok());
459 EXPECT_TRUE(jsep_transport_
460 ->SetRemoteJsepTransportDescription(remote_description,
461 param.remote_type)
462 .ok());
463 } else {
464 EXPECT_TRUE(jsep_transport_
465 ->SetRemoteJsepTransportDescription(remote_description,
466 param.remote_type)
467 .ok());
468 EXPECT_TRUE(jsep_transport_
469 ->SetLocalJsepTransportDescription(local_description,
470 param.local_type)
471 .ok());
472 }
473 EXPECT_EQ(rtc::SSL_CLIENT, *jsep_transport_->GetDtlsRole());
474 }
475
476 // Parameters which set the SSL role to SSL_SERVER.
477 NegotiateRoleParams valid_server_params[] = {
478 {CONNECTIONROLE_PASSIVE, CONNECTIONROLE_ACTPASS, SdpType::kAnswer,
479 SdpType::kOffer},
480 {CONNECTIONROLE_PASSIVE, CONNECTIONROLE_ACTPASS, SdpType::kPrAnswer,
481 SdpType::kOffer},
482 {CONNECTIONROLE_ACTPASS, CONNECTIONROLE_ACTIVE, SdpType::kOffer,
483 SdpType::kAnswer},
484 {CONNECTIONROLE_ACTPASS, CONNECTIONROLE_ACTIVE, SdpType::kOffer,
485 SdpType::kPrAnswer}};
486
487 for (auto& param : valid_server_params) {
Zhi Huange830e682018-03-30 10:48:35 -0700488 jsep_transport_ =
489 CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp);
Zhi Huange818b6e2018-02-22 15:26:27 -0800490 jsep_transport_->SetLocalCertificate(certificate);
491
492 local_description.transport_desc.connection_role = param.local_role;
493 remote_description.transport_desc.connection_role = param.remote_role;
494
495 // Set the offer first.
496 if (param.local_type == SdpType::kOffer) {
497 EXPECT_TRUE(jsep_transport_
498 ->SetLocalJsepTransportDescription(local_description,
499 param.local_type)
500 .ok());
501 EXPECT_TRUE(jsep_transport_
502 ->SetRemoteJsepTransportDescription(remote_description,
503 param.remote_type)
504 .ok());
505 } else {
506 EXPECT_TRUE(jsep_transport_
507 ->SetRemoteJsepTransportDescription(remote_description,
508 param.remote_type)
509 .ok());
510 EXPECT_TRUE(jsep_transport_
511 ->SetLocalJsepTransportDescription(local_description,
512 param.local_type)
513 .ok());
514 }
515 EXPECT_EQ(rtc::SSL_SERVER, *jsep_transport_->GetDtlsRole());
516 }
517}
518
519// Tests the logic of DTLS role negotiation for an initial offer/answer.
520TEST_P(JsepTransport2WithRtcpMux, InvalidDtlsRoleNegotiation) {
521 bool rtcp_mux_enabled = GetParam();
522 // Just use the same certificate for both sides; doesn't really matter in a
523 // non end-to-end test.
524 rtc::scoped_refptr<rtc::RTCCertificate> certificate =
525 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
526 rtc::SSLIdentity::Generate("testing", rtc::KT_ECDSA)));
527
528 JsepTransportDescription local_description = MakeJsepTransportDescription(
529 rtcp_mux_enabled, kIceUfrag1, kIcePwd1, certificate);
530 JsepTransportDescription remote_description = MakeJsepTransportDescription(
531 rtcp_mux_enabled, kIceUfrag2, kIcePwd2, certificate);
532
533 NegotiateRoleParams duplicate_params[] = {
534 {CONNECTIONROLE_ACTIVE, CONNECTIONROLE_ACTIVE, SdpType::kAnswer,
535 SdpType::kOffer},
536 {CONNECTIONROLE_ACTPASS, CONNECTIONROLE_ACTPASS, SdpType::kAnswer,
537 SdpType::kOffer},
538 {CONNECTIONROLE_PASSIVE, CONNECTIONROLE_PASSIVE, SdpType::kAnswer,
539 SdpType::kOffer},
540 {CONNECTIONROLE_ACTIVE, CONNECTIONROLE_ACTIVE, SdpType::kPrAnswer,
541 SdpType::kOffer},
542 {CONNECTIONROLE_ACTPASS, CONNECTIONROLE_ACTPASS, SdpType::kPrAnswer,
543 SdpType::kOffer},
544 {CONNECTIONROLE_PASSIVE, CONNECTIONROLE_PASSIVE, SdpType::kPrAnswer,
545 SdpType::kOffer},
546 {CONNECTIONROLE_ACTIVE, CONNECTIONROLE_ACTIVE, SdpType::kOffer,
547 SdpType::kAnswer},
548 {CONNECTIONROLE_ACTPASS, CONNECTIONROLE_ACTPASS, SdpType::kOffer,
549 SdpType::kAnswer},
550 {CONNECTIONROLE_PASSIVE, CONNECTIONROLE_PASSIVE, SdpType::kOffer,
551 SdpType::kAnswer},
552 {CONNECTIONROLE_ACTIVE, CONNECTIONROLE_ACTIVE, SdpType::kOffer,
553 SdpType::kPrAnswer},
554 {CONNECTIONROLE_ACTPASS, CONNECTIONROLE_ACTPASS, SdpType::kOffer,
555 SdpType::kPrAnswer},
556 {CONNECTIONROLE_PASSIVE, CONNECTIONROLE_PASSIVE, SdpType::kOffer,
557 SdpType::kPrAnswer}};
558
559 for (auto& param : duplicate_params) {
Zhi Huange830e682018-03-30 10:48:35 -0700560 jsep_transport_ =
561 CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp);
Zhi Huange818b6e2018-02-22 15:26:27 -0800562 jsep_transport_->SetLocalCertificate(certificate);
563
564 local_description.transport_desc.connection_role = param.local_role;
565 remote_description.transport_desc.connection_role = param.remote_role;
566
567 if (param.local_type == SdpType::kOffer) {
568 EXPECT_TRUE(jsep_transport_
569 ->SetLocalJsepTransportDescription(local_description,
570 param.local_type)
571 .ok());
572 EXPECT_FALSE(jsep_transport_
573 ->SetRemoteJsepTransportDescription(remote_description,
574 param.remote_type)
575 .ok());
576 } else {
577 EXPECT_TRUE(jsep_transport_
578 ->SetRemoteJsepTransportDescription(remote_description,
579 param.remote_type)
580 .ok());
581 EXPECT_FALSE(jsep_transport_
582 ->SetLocalJsepTransportDescription(local_description,
583 param.local_type)
584 .ok());
585 }
586 }
587
588 // Invalid parameters due to the offerer not using ACTPASS.
589 NegotiateRoleParams offerer_without_actpass_params[] = {
590 {CONNECTIONROLE_ACTIVE, CONNECTIONROLE_PASSIVE, SdpType::kAnswer,
591 SdpType::kOffer},
592 {CONNECTIONROLE_PASSIVE, CONNECTIONROLE_ACTIVE, SdpType::kAnswer,
593 SdpType::kOffer},
594 {CONNECTIONROLE_ACTPASS, CONNECTIONROLE_PASSIVE, SdpType::kAnswer,
595 SdpType::kOffer},
596 {CONNECTIONROLE_ACTIVE, CONNECTIONROLE_PASSIVE, SdpType::kPrAnswer,
597 SdpType::kOffer},
598 {CONNECTIONROLE_PASSIVE, CONNECTIONROLE_ACTIVE, SdpType::kPrAnswer,
599 SdpType::kOffer},
600 {CONNECTIONROLE_ACTPASS, CONNECTIONROLE_PASSIVE, SdpType::kPrAnswer,
601 SdpType::kOffer},
602 {CONNECTIONROLE_ACTIVE, CONNECTIONROLE_PASSIVE, SdpType::kOffer,
603 SdpType::kAnswer},
604 {CONNECTIONROLE_PASSIVE, CONNECTIONROLE_ACTIVE, SdpType::kOffer,
605 SdpType::kAnswer},
606 {CONNECTIONROLE_PASSIVE, CONNECTIONROLE_ACTPASS, SdpType::kOffer,
607 SdpType::kAnswer},
608 {CONNECTIONROLE_ACTIVE, CONNECTIONROLE_PASSIVE, SdpType::kOffer,
609 SdpType::kPrAnswer},
610 {CONNECTIONROLE_PASSIVE, CONNECTIONROLE_ACTIVE, SdpType::kOffer,
611 SdpType::kPrAnswer},
612 {CONNECTIONROLE_PASSIVE, CONNECTIONROLE_ACTPASS, SdpType::kOffer,
613 SdpType::kPrAnswer}};
614
615 for (auto& param : offerer_without_actpass_params) {
Zhi Huange830e682018-03-30 10:48:35 -0700616 jsep_transport_ =
617 CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp);
Zhi Huange818b6e2018-02-22 15:26:27 -0800618 jsep_transport_->SetLocalCertificate(certificate);
619
620 local_description.transport_desc.connection_role = param.local_role;
621 remote_description.transport_desc.connection_role = param.remote_role;
622
623 if (param.local_type == SdpType::kOffer) {
624 EXPECT_TRUE(jsep_transport_
625 ->SetLocalJsepTransportDescription(local_description,
626 param.local_type)
627 .ok());
628 EXPECT_FALSE(jsep_transport_
629 ->SetRemoteJsepTransportDescription(remote_description,
630 param.remote_type)
631 .ok());
632 } else {
633 EXPECT_TRUE(jsep_transport_
634 ->SetRemoteJsepTransportDescription(remote_description,
635 param.remote_type)
636 .ok());
637 EXPECT_FALSE(jsep_transport_
638 ->SetLocalJsepTransportDescription(local_description,
639 param.local_type)
640 .ok());
641 }
642 }
643}
644
Mirko Bonadeic84f6612019-01-31 12:20:57 +0100645INSTANTIATE_TEST_SUITE_P(JsepTransport2Test,
646 JsepTransport2WithRtcpMux,
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200647 ::testing::Bool());
Zhi Huange818b6e2018-02-22 15:26:27 -0800648
649// Test that a reoffer in the opposite direction is successful as long as the
650// role isn't changing. Doesn't test every possible combination like the test
651// above.
652TEST_F(JsepTransport2Test, ValidDtlsReofferFromAnswerer) {
653 // Just use the same certificate for both sides; doesn't really matter in a
654 // non end-to-end test.
655 rtc::scoped_refptr<rtc::RTCCertificate> certificate =
656 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
657 rtc::SSLIdentity::Generate("testing", rtc::KT_ECDSA)));
658 bool rtcp_mux_enabled = true;
Zhi Huange830e682018-03-30 10:48:35 -0700659 jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp);
Zhi Huange818b6e2018-02-22 15:26:27 -0800660 jsep_transport_->SetLocalCertificate(certificate);
661
662 JsepTransportDescription local_offer =
663 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag1, kIcePwd1,
664 certificate, CONNECTIONROLE_ACTPASS);
665 JsepTransportDescription remote_answer =
666 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag2, kIcePwd2,
667 certificate, CONNECTIONROLE_ACTIVE);
668
669 EXPECT_TRUE(
670 jsep_transport_
671 ->SetLocalJsepTransportDescription(local_offer, SdpType::kOffer)
672 .ok());
673 EXPECT_TRUE(
674 jsep_transport_
675 ->SetRemoteJsepTransportDescription(remote_answer, SdpType::kAnswer)
676 .ok());
677
678 // We were actpass->active previously, now in the other direction it's
679 // actpass->passive.
680 JsepTransportDescription remote_offer =
681 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag2, kIcePwd2,
682 certificate, CONNECTIONROLE_ACTPASS);
683 JsepTransportDescription local_answer =
684 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag1, kIcePwd1,
685 certificate, CONNECTIONROLE_PASSIVE);
686
687 EXPECT_TRUE(
688 jsep_transport_
689 ->SetRemoteJsepTransportDescription(remote_offer, SdpType::kOffer)
690 .ok());
691 EXPECT_TRUE(
692 jsep_transport_
693 ->SetLocalJsepTransportDescription(local_answer, SdpType::kAnswer)
694 .ok());
695}
696
697// Test that a reoffer in the opposite direction fails if the role changes.
698// Inverse of test above.
699TEST_F(JsepTransport2Test, InvalidDtlsReofferFromAnswerer) {
700 // Just use the same certificate for both sides; doesn't really matter in a
701 // non end-to-end test.
702 rtc::scoped_refptr<rtc::RTCCertificate> certificate =
703 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
704 rtc::SSLIdentity::Generate("testing", rtc::KT_ECDSA)));
705 bool rtcp_mux_enabled = true;
Zhi Huange830e682018-03-30 10:48:35 -0700706 jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp);
Zhi Huange818b6e2018-02-22 15:26:27 -0800707 jsep_transport_->SetLocalCertificate(certificate);
708
709 JsepTransportDescription local_offer =
710 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag1, kIcePwd1,
711 certificate, CONNECTIONROLE_ACTPASS);
712 JsepTransportDescription remote_answer =
713 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag2, kIcePwd2,
714 certificate, CONNECTIONROLE_ACTIVE);
715
716 EXPECT_TRUE(
717 jsep_transport_
718 ->SetLocalJsepTransportDescription(local_offer, SdpType::kOffer)
719 .ok());
720 EXPECT_TRUE(
721 jsep_transport_
722 ->SetRemoteJsepTransportDescription(remote_answer, SdpType::kAnswer)
723 .ok());
724
725 // Changing role to passive here isn't allowed. Though for some reason this
726 // only fails in SetLocalTransportDescription.
727 JsepTransportDescription remote_offer =
728 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag2, kIcePwd2,
729 certificate, CONNECTIONROLE_PASSIVE);
730 JsepTransportDescription local_answer =
731 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag1, kIcePwd1,
732 certificate, CONNECTIONROLE_ACTIVE);
733
734 EXPECT_TRUE(
735 jsep_transport_
736 ->SetRemoteJsepTransportDescription(remote_offer, SdpType::kOffer)
737 .ok());
738 EXPECT_FALSE(
739 jsep_transport_
740 ->SetLocalJsepTransportDescription(local_answer, SdpType::kAnswer)
741 .ok());
742}
743
744// Test that a remote offer with the current negotiated role can be accepted.
745// This is allowed by dtls-sdp, though we'll never generate such an offer,
746// since JSEP requires generating "actpass".
747TEST_F(JsepTransport2Test, RemoteOfferWithCurrentNegotiatedDtlsRole) {
748 rtc::scoped_refptr<rtc::RTCCertificate> certificate =
749 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
750 rtc::SSLIdentity::Generate("testing", rtc::KT_ECDSA)));
751 bool rtcp_mux_enabled = true;
Zhi Huange830e682018-03-30 10:48:35 -0700752 jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp);
Zhi Huange818b6e2018-02-22 15:26:27 -0800753 jsep_transport_->SetLocalCertificate(certificate);
754
755 JsepTransportDescription remote_desc =
756 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag1, kIcePwd1,
757 certificate, CONNECTIONROLE_ACTPASS);
758 JsepTransportDescription local_desc =
759 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag2, kIcePwd2,
760 certificate, CONNECTIONROLE_ACTIVE);
761
762 // Normal initial offer/answer with "actpass" in the offer and "active" in
763 // the answer.
764 ASSERT_TRUE(
765 jsep_transport_
766 ->SetRemoteJsepTransportDescription(remote_desc, SdpType::kOffer)
767 .ok());
768 ASSERT_TRUE(
769 jsep_transport_
770 ->SetLocalJsepTransportDescription(local_desc, SdpType::kAnswer)
771 .ok());
772
773 // Sanity check that role was actually negotiated.
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200774 absl::optional<rtc::SSLRole> role = jsep_transport_->GetDtlsRole();
Zhi Huange818b6e2018-02-22 15:26:27 -0800775 ASSERT_TRUE(role);
776 EXPECT_EQ(rtc::SSL_CLIENT, *role);
777
778 // Subsequent offer with current negotiated role of "passive".
779 remote_desc.transport_desc.connection_role = CONNECTIONROLE_PASSIVE;
780 EXPECT_TRUE(
781 jsep_transport_
782 ->SetRemoteJsepTransportDescription(remote_desc, SdpType::kOffer)
783 .ok());
784 EXPECT_TRUE(
785 jsep_transport_
786 ->SetLocalJsepTransportDescription(local_desc, SdpType::kAnswer)
787 .ok());
788}
789
790// Test that a remote offer with the inverse of the current negotiated DTLS
791// role is rejected.
792TEST_F(JsepTransport2Test, RemoteOfferThatChangesNegotiatedDtlsRole) {
793 rtc::scoped_refptr<rtc::RTCCertificate> certificate =
794 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
795 rtc::SSLIdentity::Generate("testing", rtc::KT_ECDSA)));
796 bool rtcp_mux_enabled = true;
Zhi Huange830e682018-03-30 10:48:35 -0700797 jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp);
Zhi Huange818b6e2018-02-22 15:26:27 -0800798 jsep_transport_->SetLocalCertificate(certificate);
799
800 JsepTransportDescription remote_desc =
801 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag1, kIcePwd1,
802 certificate, CONNECTIONROLE_ACTPASS);
803 JsepTransportDescription local_desc =
804 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag2, kIcePwd2,
805 certificate, CONNECTIONROLE_ACTIVE);
806
807 // Normal initial offer/answer with "actpass" in the offer and "active" in
808 // the answer.
809 ASSERT_TRUE(
810 jsep_transport_
811 ->SetRemoteJsepTransportDescription(remote_desc, SdpType::kOffer)
812 .ok());
813 ASSERT_TRUE(
814 jsep_transport_
815 ->SetLocalJsepTransportDescription(local_desc, SdpType::kAnswer)
816 .ok());
817
818 // Sanity check that role was actually negotiated.
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200819 absl::optional<rtc::SSLRole> role = jsep_transport_->GetDtlsRole();
Zhi Huange818b6e2018-02-22 15:26:27 -0800820 ASSERT_TRUE(role);
821 EXPECT_EQ(rtc::SSL_CLIENT, *role);
822
823 // Subsequent offer with current negotiated role of "passive".
824 remote_desc.transport_desc.connection_role = CONNECTIONROLE_ACTIVE;
825 EXPECT_TRUE(
826 jsep_transport_
827 ->SetRemoteJsepTransportDescription(remote_desc, SdpType::kOffer)
828 .ok());
829 EXPECT_FALSE(
830 jsep_transport_
831 ->SetLocalJsepTransportDescription(local_desc, SdpType::kAnswer)
832 .ok());
833}
834
835// Testing that a legacy client that doesn't use the setup attribute will be
836// interpreted as having an active role.
837TEST_F(JsepTransport2Test, DtlsSetupWithLegacyAsAnswerer) {
838 rtc::scoped_refptr<rtc::RTCCertificate> certificate =
839 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
840 rtc::SSLIdentity::Generate("testing", rtc::KT_ECDSA)));
841 bool rtcp_mux_enabled = true;
Zhi Huange830e682018-03-30 10:48:35 -0700842 jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp);
Zhi Huange818b6e2018-02-22 15:26:27 -0800843 jsep_transport_->SetLocalCertificate(certificate);
844
845 JsepTransportDescription remote_desc =
846 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag1, kIcePwd1,
847 certificate, CONNECTIONROLE_ACTPASS);
848 JsepTransportDescription local_desc =
849 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag2, kIcePwd2,
850 certificate, CONNECTIONROLE_ACTIVE);
851
852 local_desc.transport_desc.connection_role = CONNECTIONROLE_ACTPASS;
853 ASSERT_TRUE(
854 jsep_transport_
855 ->SetLocalJsepTransportDescription(local_desc, SdpType::kOffer)
856 .ok());
857 // Use CONNECTIONROLE_NONE to simulate legacy endpoint.
858 remote_desc.transport_desc.connection_role = CONNECTIONROLE_NONE;
859 ASSERT_TRUE(
860 jsep_transport_
861 ->SetRemoteJsepTransportDescription(remote_desc, SdpType::kAnswer)
862 .ok());
863
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200864 absl::optional<rtc::SSLRole> role = jsep_transport_->GetDtlsRole();
Zhi Huange818b6e2018-02-22 15:26:27 -0800865 ASSERT_TRUE(role);
866 // Since legacy answer ommitted setup atribute, and we offered actpass, we
867 // should act as passive (server).
868 EXPECT_EQ(rtc::SSL_SERVER, *role);
869}
870
871// Tests that when the RTCP mux is successfully negotiated, the RTCP transport
872// will be destroyed and the SignalRtpMuxActive will be fired.
873TEST_F(JsepTransport2Test, RtcpMuxNegotiation) {
Zhi Huange830e682018-03-30 10:48:35 -0700874 jsep_transport_ =
875 CreateJsepTransport2(/*rtcp_mux_enabled=*/false, SrtpMode::kDtlsSrtp);
Zhi Huange818b6e2018-02-22 15:26:27 -0800876 JsepTransportDescription local_desc;
877 local_desc.rtcp_mux_enabled = true;
Harald Alvestrandad88c882018-11-28 16:47:46 +0100878 ASSERT_NE(nullptr, jsep_transport_->rtcp_dtls_transport());
Zhi Huange818b6e2018-02-22 15:26:27 -0800879 EXPECT_FALSE(signal_rtcp_mux_active_received_);
880
881 // The remote side supports RTCP-mux.
882 JsepTransportDescription remote_desc;
883 remote_desc.rtcp_mux_enabled = true;
884 ASSERT_TRUE(
885 jsep_transport_
886 ->SetLocalJsepTransportDescription(local_desc, SdpType::kOffer)
887 .ok());
888 ASSERT_TRUE(
889 jsep_transport_
890 ->SetRemoteJsepTransportDescription(remote_desc, SdpType::kAnswer)
891 .ok());
892
893 EXPECT_EQ(nullptr, jsep_transport_->rtcp_dtls_transport());
894 EXPECT_TRUE(signal_rtcp_mux_active_received_);
895
896 // The remote side doesn't support RTCP-mux.
Zhi Huange830e682018-03-30 10:48:35 -0700897 jsep_transport_ =
898 CreateJsepTransport2(/*rtcp_mux_enabled=*/false, SrtpMode::kDtlsSrtp);
Zhi Huange818b6e2018-02-22 15:26:27 -0800899 signal_rtcp_mux_active_received_ = false;
900 remote_desc.rtcp_mux_enabled = false;
901 ASSERT_TRUE(
902 jsep_transport_
903 ->SetLocalJsepTransportDescription(local_desc, SdpType::kOffer)
904 .ok());
905 ASSERT_TRUE(
906 jsep_transport_
907 ->SetRemoteJsepTransportDescription(remote_desc, SdpType::kAnswer)
908 .ok());
909
910 EXPECT_NE(nullptr, jsep_transport_->rtcp_dtls_transport());
911 EXPECT_FALSE(signal_rtcp_mux_active_received_);
912}
913
914TEST_F(JsepTransport2Test, SdesNegotiation) {
Zhi Huange830e682018-03-30 10:48:35 -0700915 jsep_transport_ =
916 CreateJsepTransport2(/*rtcp_mux_enabled=*/true, SrtpMode::kSdes);
Zhi Huange818b6e2018-02-22 15:26:27 -0800917 ASSERT_TRUE(sdes_transport_);
Zhi Huange830e682018-03-30 10:48:35 -0700918 EXPECT_FALSE(sdes_transport_->IsSrtpActive());
Zhi Huange818b6e2018-02-22 15:26:27 -0800919
920 JsepTransportDescription offer_desc;
921 offer_desc.cryptos.push_back(cricket::CryptoParams(
922 1, rtc::CS_AES_CM_128_HMAC_SHA1_32,
923 "inline:" + rtc::CreateRandomString(40), std::string()));
924 ASSERT_TRUE(
925 jsep_transport_
926 ->SetLocalJsepTransportDescription(offer_desc, SdpType::kOffer)
927 .ok());
928
929 JsepTransportDescription answer_desc;
930 answer_desc.cryptos.push_back(cricket::CryptoParams(
931 1, rtc::CS_AES_CM_128_HMAC_SHA1_32,
932 "inline:" + rtc::CreateRandomString(40), std::string()));
933 ASSERT_TRUE(
934 jsep_transport_
935 ->SetRemoteJsepTransportDescription(answer_desc, SdpType::kAnswer)
936 .ok());
Zhi Huange830e682018-03-30 10:48:35 -0700937 EXPECT_TRUE(sdes_transport_->IsSrtpActive());
Zhi Huange818b6e2018-02-22 15:26:27 -0800938}
939
940TEST_F(JsepTransport2Test, SdesNegotiationWithEmptyCryptosInAnswer) {
Zhi Huange830e682018-03-30 10:48:35 -0700941 jsep_transport_ =
942 CreateJsepTransport2(/*rtcp_mux_enabled=*/true, SrtpMode::kSdes);
Zhi Huange818b6e2018-02-22 15:26:27 -0800943 ASSERT_TRUE(sdes_transport_);
Zhi Huange830e682018-03-30 10:48:35 -0700944 EXPECT_FALSE(sdes_transport_->IsSrtpActive());
Zhi Huange818b6e2018-02-22 15:26:27 -0800945
946 JsepTransportDescription offer_desc;
947 offer_desc.cryptos.push_back(cricket::CryptoParams(
948 1, rtc::CS_AES_CM_128_HMAC_SHA1_32,
949 "inline:" + rtc::CreateRandomString(40), std::string()));
950 ASSERT_TRUE(
951 jsep_transport_
952 ->SetLocalJsepTransportDescription(offer_desc, SdpType::kOffer)
953 .ok());
954
955 JsepTransportDescription answer_desc;
956 ASSERT_TRUE(
957 jsep_transport_
958 ->SetRemoteJsepTransportDescription(answer_desc, SdpType::kAnswer)
959 .ok());
960 // SRTP is not active because the crypto parameter is answer is empty.
Zhi Huange830e682018-03-30 10:48:35 -0700961 EXPECT_FALSE(sdes_transport_->IsSrtpActive());
Zhi Huange818b6e2018-02-22 15:26:27 -0800962}
963
964TEST_F(JsepTransport2Test, SdesNegotiationWithMismatchedCryptos) {
Zhi Huange830e682018-03-30 10:48:35 -0700965 jsep_transport_ =
966 CreateJsepTransport2(/*rtcp_mux_enabled=*/true, SrtpMode::kSdes);
Zhi Huange818b6e2018-02-22 15:26:27 -0800967 ASSERT_TRUE(sdes_transport_);
Zhi Huange830e682018-03-30 10:48:35 -0700968 EXPECT_FALSE(sdes_transport_->IsSrtpActive());
Zhi Huange818b6e2018-02-22 15:26:27 -0800969
970 JsepTransportDescription offer_desc;
971 offer_desc.cryptos.push_back(cricket::CryptoParams(
972 1, rtc::CS_AES_CM_128_HMAC_SHA1_32,
973 "inline:" + rtc::CreateRandomString(40), std::string()));
974 ASSERT_TRUE(
975 jsep_transport_
976 ->SetLocalJsepTransportDescription(offer_desc, SdpType::kOffer)
977 .ok());
978
979 JsepTransportDescription answer_desc;
980 answer_desc.cryptos.push_back(cricket::CryptoParams(
981 1, rtc::CS_AES_CM_128_HMAC_SHA1_80,
982 "inline:" + rtc::CreateRandomString(40), std::string()));
983 // Expected to fail because the crypto parameters don't match.
984 ASSERT_FALSE(
985 jsep_transport_
986 ->SetRemoteJsepTransportDescription(answer_desc, SdpType::kAnswer)
987 .ok());
988}
989
990// Tests that the remote candidates can be added to the transports after both
991// local and remote descriptions are set.
992TEST_F(JsepTransport2Test, AddRemoteCandidates) {
Zhi Huange830e682018-03-30 10:48:35 -0700993 jsep_transport_ =
994 CreateJsepTransport2(/*rtcp_mux_enabled=*/true, SrtpMode::kDtlsSrtp);
Zhi Huange818b6e2018-02-22 15:26:27 -0800995 auto fake_ice_transport = static_cast<FakeIceTransport*>(
996 jsep_transport_->rtp_dtls_transport()->ice_transport());
997
998 Candidates candidates;
999 candidates.push_back(CreateCandidate(/*COMPONENT_RTP*/ 1));
1000 candidates.push_back(CreateCandidate(/*COMPONENT_RTP*/ 1));
1001
1002 JsepTransportDescription desc;
1003 ASSERT_TRUE(
1004 jsep_transport_->SetLocalJsepTransportDescription(desc, SdpType::kOffer)
1005 .ok());
1006 // Expected to fail because the remote description is unset.
1007 EXPECT_FALSE(jsep_transport_->AddRemoteCandidates(candidates).ok());
1008
1009 ASSERT_TRUE(
1010 jsep_transport_->SetRemoteJsepTransportDescription(desc, SdpType::kAnswer)
1011 .ok());
1012 EXPECT_EQ(0u, fake_ice_transport->remote_candidates().size());
1013 EXPECT_TRUE(jsep_transport_->AddRemoteCandidates(candidates).ok());
1014 EXPECT_EQ(candidates.size(), fake_ice_transport->remote_candidates().size());
1015}
1016
Zhi Huange830e682018-03-30 10:48:35 -07001017enum class Scenario {
1018 kSdes,
1019 kDtlsBeforeCallerSendOffer,
1020 kDtlsBeforeCallerSetAnswer,
1021 kDtlsAfterCallerSetAnswer,
1022};
1023
1024class JsepTransport2HeaderExtensionTest
1025 : public JsepTransport2Test,
1026 public ::testing::WithParamInterface<std::tuple<Scenario, bool>> {
1027 protected:
1028 JsepTransport2HeaderExtensionTest() {}
1029
1030 void CreateJsepTransportPair(SrtpMode mode) {
1031 jsep_transport1_ = CreateJsepTransport2(/*rtcp_mux_enabled=*/true, mode);
1032 jsep_transport2_ = CreateJsepTransport2(/*rtcp_mux_enabled=*/true, mode);
1033
1034 auto fake_dtls1 =
1035 static_cast<FakeDtlsTransport*>(jsep_transport1_->rtp_dtls_transport());
1036 auto fake_dtls2 =
1037 static_cast<FakeDtlsTransport*>(jsep_transport2_->rtp_dtls_transport());
1038
1039 fake_dtls1->fake_ice_transport()->SignalReadPacket.connect(
1040 this, &JsepTransport2HeaderExtensionTest::OnReadPacket1);
1041 fake_dtls2->fake_ice_transport()->SignalReadPacket.connect(
1042 this, &JsepTransport2HeaderExtensionTest::OnReadPacket2);
1043
1044 if (mode == SrtpMode::kDtlsSrtp) {
1045 auto cert1 =
1046 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
1047 rtc::SSLIdentity::Generate("session1", rtc::KT_DEFAULT)));
1048 jsep_transport1_->rtp_dtls_transport()->SetLocalCertificate(cert1);
1049 auto cert2 =
1050 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
1051 rtc::SSLIdentity::Generate("session1", rtc::KT_DEFAULT)));
1052 jsep_transport2_->rtp_dtls_transport()->SetLocalCertificate(cert2);
1053 }
1054 }
1055
1056 void OnReadPacket1(rtc::PacketTransportInternal* transport,
1057 const char* data,
1058 size_t size,
Niels Möllere6933812018-11-05 13:01:41 +01001059 const int64_t& /* packet_time_us */,
Zhi Huange830e682018-03-30 10:48:35 -07001060 int flags) {
1061 RTC_LOG(LS_INFO) << "JsepTransport 1 Received a packet.";
1062 CompareHeaderExtensions(
1063 reinterpret_cast<const char*>(kPcmuFrameWithExtensions),
1064 sizeof(kPcmuFrameWithExtensions), data, size, recv_encrypted_headers1_,
1065 false);
1066 received_packet_count_++;
1067 }
1068
1069 void OnReadPacket2(rtc::PacketTransportInternal* transport,
1070 const char* data,
1071 size_t size,
Niels Möllere6933812018-11-05 13:01:41 +01001072 const int64_t& /* packet_time_us */,
Zhi Huange830e682018-03-30 10:48:35 -07001073 int flags) {
1074 RTC_LOG(LS_INFO) << "JsepTransport 2 Received a packet.";
1075 CompareHeaderExtensions(
1076 reinterpret_cast<const char*>(kPcmuFrameWithExtensions),
1077 sizeof(kPcmuFrameWithExtensions), data, size, recv_encrypted_headers2_,
1078 false);
1079 received_packet_count_++;
1080 }
1081
1082 void ConnectTransport() {
1083 auto rtp_dtls_transport1 =
1084 static_cast<FakeDtlsTransport*>(jsep_transport1_->rtp_dtls_transport());
1085 auto rtp_dtls_transport2 =
1086 static_cast<FakeDtlsTransport*>(jsep_transport2_->rtp_dtls_transport());
1087 rtp_dtls_transport1->SetDestination(rtp_dtls_transport2);
1088 }
1089
1090 int GetRtpAuthLen() {
1091 bool use_gcm = std::get<1>(GetParam());
1092 if (use_gcm) {
1093 return 16;
1094 }
1095 return 10;
1096 }
1097
1098 void TestSendRecvPacketWithEncryptedHeaderExtension() {
1099 TestOneWaySendRecvPacketWithEncryptedHeaderExtension(
1100 jsep_transport1_.get());
1101 TestOneWaySendRecvPacketWithEncryptedHeaderExtension(
1102 jsep_transport2_.get());
1103 }
1104
1105 void TestOneWaySendRecvPacketWithEncryptedHeaderExtension(
Zhi Huang365381f2018-04-13 16:44:34 -07001106 JsepTransport* sender_transport) {
Zhi Huange830e682018-03-30 10:48:35 -07001107 size_t rtp_len = sizeof(kPcmuFrameWithExtensions);
1108 size_t packet_size = rtp_len + GetRtpAuthLen();
1109 rtc::Buffer rtp_packet_buffer(packet_size);
1110 char* rtp_packet_data = rtp_packet_buffer.data<char>();
1111 memcpy(rtp_packet_data, kPcmuFrameWithExtensions, rtp_len);
1112 // In order to be able to run this test function multiple times we can not
1113 // use the same sequence number twice. Increase the sequence number by one.
1114 rtc::SetBE16(reinterpret_cast<uint8_t*>(rtp_packet_data) + 2,
1115 ++sequence_number_);
1116 rtc::CopyOnWriteBuffer rtp_packet(rtp_packet_data, rtp_len, packet_size);
1117
1118 int packet_count_before = received_packet_count_;
1119 rtc::PacketOptions options;
1120 // Send a packet and verify that the packet can be successfully received and
1121 // decrypted.
1122 ASSERT_TRUE(sender_transport->rtp_transport()->SendRtpPacket(
1123 &rtp_packet, options, cricket::PF_SRTP_BYPASS));
1124 EXPECT_EQ(packet_count_before + 1, received_packet_count_);
1125 }
1126
1127 int sequence_number_ = 0;
1128 int received_packet_count_ = 0;
Zhi Huang365381f2018-04-13 16:44:34 -07001129 std::unique_ptr<JsepTransport> jsep_transport1_;
1130 std::unique_ptr<JsepTransport> jsep_transport2_;
Zhi Huange830e682018-03-30 10:48:35 -07001131 std::vector<int> recv_encrypted_headers1_;
1132 std::vector<int> recv_encrypted_headers2_;
1133};
1134
1135// Test that the encrypted header extension works and can be changed in
1136// different scenarios.
1137TEST_P(JsepTransport2HeaderExtensionTest, EncryptedHeaderExtensionNegotiation) {
1138 Scenario scenario = std::get<0>(GetParam());
1139 bool use_gcm = std::get<1>(GetParam());
1140 SrtpMode mode = SrtpMode ::kDtlsSrtp;
1141 if (scenario == Scenario::kSdes) {
1142 mode = SrtpMode::kSdes;
1143 }
1144 CreateJsepTransportPair(mode);
1145 recv_encrypted_headers1_.push_back(kHeaderExtensionIDs[0]);
1146 recv_encrypted_headers2_.push_back(kHeaderExtensionIDs[1]);
1147
1148 cricket::CryptoParams sdes_param(1, rtc::CS_AES_CM_128_HMAC_SHA1_80,
1149 "inline:" + rtc::CreateRandomString(40),
1150 std::string());
1151 if (use_gcm) {
1152 auto fake_dtls1 =
1153 static_cast<FakeDtlsTransport*>(jsep_transport1_->rtp_dtls_transport());
1154 auto fake_dtls2 =
1155 static_cast<FakeDtlsTransport*>(jsep_transport2_->rtp_dtls_transport());
1156
1157 fake_dtls1->SetSrtpCryptoSuite(rtc::SRTP_AEAD_AES_256_GCM);
1158 fake_dtls2->SetSrtpCryptoSuite(rtc::SRTP_AEAD_AES_256_GCM);
1159 }
1160
1161 if (scenario == Scenario::kDtlsBeforeCallerSendOffer) {
1162 ConnectTransport();
1163 }
1164
1165 JsepTransportDescription offer_desc;
1166 offer_desc.encrypted_header_extension_ids = recv_encrypted_headers1_;
1167 if (scenario == Scenario::kSdes) {
1168 offer_desc.cryptos.push_back(sdes_param);
1169 }
1170 ASSERT_TRUE(
1171 jsep_transport1_
1172 ->SetLocalJsepTransportDescription(offer_desc, SdpType::kOffer)
1173 .ok());
1174 ASSERT_TRUE(
1175 jsep_transport2_
1176 ->SetRemoteJsepTransportDescription(offer_desc, SdpType::kOffer)
1177 .ok());
1178
1179 JsepTransportDescription answer_desc;
1180 answer_desc.encrypted_header_extension_ids = recv_encrypted_headers2_;
1181 if (scenario == Scenario::kSdes) {
1182 answer_desc.cryptos.push_back(sdes_param);
1183 }
1184 ASSERT_TRUE(
1185 jsep_transport2_
1186 ->SetLocalJsepTransportDescription(answer_desc, SdpType::kAnswer)
1187 .ok());
1188
1189 if (scenario == Scenario::kDtlsBeforeCallerSetAnswer) {
1190 ConnectTransport();
1191 // Sending packet from transport2 to transport1 should work when they are
1192 // partially configured.
1193 TestOneWaySendRecvPacketWithEncryptedHeaderExtension(
1194 /*sender_transport=*/jsep_transport2_.get());
1195 }
1196
1197 ASSERT_TRUE(
1198 jsep_transport1_
1199 ->SetRemoteJsepTransportDescription(answer_desc, SdpType::kAnswer)
1200 .ok());
1201
1202 if (scenario == Scenario::kDtlsAfterCallerSetAnswer ||
1203 scenario == Scenario::kSdes) {
1204 ConnectTransport();
1205 }
1206 EXPECT_TRUE(jsep_transport1_->rtp_transport()->IsSrtpActive());
1207 EXPECT_TRUE(jsep_transport2_->rtp_transport()->IsSrtpActive());
1208 TestSendRecvPacketWithEncryptedHeaderExtension();
1209
1210 // Change the encrypted header extension in a new offer/answer exchange.
1211 recv_encrypted_headers1_.clear();
1212 recv_encrypted_headers2_.clear();
1213 recv_encrypted_headers1_.push_back(kHeaderExtensionIDs[1]);
1214 recv_encrypted_headers2_.push_back(kHeaderExtensionIDs[0]);
1215 offer_desc.encrypted_header_extension_ids = recv_encrypted_headers1_;
1216 answer_desc.encrypted_header_extension_ids = recv_encrypted_headers2_;
1217 ASSERT_TRUE(
1218 jsep_transport1_
1219 ->SetLocalJsepTransportDescription(offer_desc, SdpType::kOffer)
1220 .ok());
1221 ASSERT_TRUE(
1222 jsep_transport2_
1223 ->SetRemoteJsepTransportDescription(offer_desc, SdpType::kOffer)
1224 .ok());
1225 ASSERT_TRUE(
1226 jsep_transport2_
1227 ->SetLocalJsepTransportDescription(answer_desc, SdpType::kAnswer)
1228 .ok());
1229 ASSERT_TRUE(
1230 jsep_transport1_
1231 ->SetRemoteJsepTransportDescription(answer_desc, SdpType::kAnswer)
1232 .ok());
1233 EXPECT_TRUE(jsep_transport1_->rtp_transport()->IsSrtpActive());
1234 EXPECT_TRUE(jsep_transport2_->rtp_transport()->IsSrtpActive());
1235 TestSendRecvPacketWithEncryptedHeaderExtension();
1236}
1237
Mirko Bonadeic84f6612019-01-31 12:20:57 +01001238INSTANTIATE_TEST_SUITE_P(
Zhi Huange830e682018-03-30 10:48:35 -07001239 JsepTransport2Test,
1240 JsepTransport2HeaderExtensionTest,
1241 ::testing::Values(
1242 std::make_tuple(Scenario::kSdes, false),
1243 std::make_tuple(Scenario::kDtlsBeforeCallerSendOffer, true),
1244 std::make_tuple(Scenario::kDtlsBeforeCallerSetAnswer, true),
1245 std::make_tuple(Scenario::kDtlsAfterCallerSetAnswer, true),
1246 std::make_tuple(Scenario::kDtlsBeforeCallerSendOffer, false),
1247 std::make_tuple(Scenario::kDtlsBeforeCallerSetAnswer, false),
1248 std::make_tuple(Scenario::kDtlsAfterCallerSetAnswer, false)));
1249
Zhi Huange818b6e2018-02-22 15:26:27 -08001250} // namespace cricket