blob: 87d6e87212af333bdbc2391f450e46d5b9bf7177 [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
Qingsi Wang25ec8882019-11-15 12:33:05 -080017#include "api/ice_transport_factory.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 {
Qingsi Wang25ec8882019-11-15 12:33:05 -080024namespace {
Zhi Huange818b6e2018-02-22 15:26:27 -080025using webrtc::SdpType;
26
27static const char kIceUfrag1[] = "U001";
28static const char kIcePwd1[] = "TESTICEPWD00000000000001";
29static const char kIceUfrag2[] = "U002";
30static const char kIcePwd2[] = "TESTIEPWD00000000000002";
31static const char kTransportName[] = "Test Transport";
32
33enum class SrtpMode {
34 kSdes,
35 kDtlsSrtp,
36};
37
38struct NegotiateRoleParams {
39 ConnectionRole local_role;
40 ConnectionRole remote_role;
41 SdpType local_type;
42 SdpType remote_type;
43};
44
Qingsi Wang25ec8882019-11-15 12:33:05 -080045rtc::scoped_refptr<webrtc::IceTransportInterface> CreateIceTransport(
46 std::unique_ptr<FakeIceTransport> internal) {
47 if (!internal) {
48 return nullptr;
49 }
50
51 return new rtc::RefCountedObject<FakeIceTransportWrapper>(
52 std::move(internal));
53}
54
Mirko Bonadei6a489f22019-04-09 15:11:12 +020055class JsepTransport2Test : public ::testing::Test, public sigslot::has_slots<> {
Zhi Huange818b6e2018-02-22 15:26:27 -080056 protected:
57 std::unique_ptr<webrtc::SrtpTransport> CreateSdesTransport(
Zhi Huange818b6e2018-02-22 15:26:27 -080058 rtc::PacketTransportInternal* rtp_packet_transport,
59 rtc::PacketTransportInternal* rtcp_packet_transport) {
Mirko Bonadei317a1f02019-09-17 17:06:18 +020060 auto srtp_transport = std::make_unique<webrtc::SrtpTransport>(
Zhi Huang365381f2018-04-13 16:44:34 -070061 rtcp_packet_transport == nullptr);
Zhi Huange818b6e2018-02-22 15:26:27 -080062
63 srtp_transport->SetRtpPacketTransport(rtp_packet_transport);
64 if (rtcp_packet_transport) {
65 srtp_transport->SetRtcpPacketTransport(rtp_packet_transport);
66 }
67 return srtp_transport;
68 }
69
70 std::unique_ptr<webrtc::DtlsSrtpTransport> CreateDtlsSrtpTransport(
Zhi Huange818b6e2018-02-22 15:26:27 -080071 cricket::DtlsTransportInternal* rtp_dtls_transport,
72 cricket::DtlsTransportInternal* rtcp_dtls_transport) {
Mirko Bonadei317a1f02019-09-17 17:06:18 +020073 auto dtls_srtp_transport = std::make_unique<webrtc::DtlsSrtpTransport>(
Zhi Huang365381f2018-04-13 16:44:34 -070074 rtcp_dtls_transport == nullptr);
Zhi Huange818b6e2018-02-22 15:26:27 -080075 dtls_srtp_transport->SetDtlsTransports(rtp_dtls_transport,
76 rtcp_dtls_transport);
77 return dtls_srtp_transport;
78 }
79
Zhi Huang365381f2018-04-13 16:44:34 -070080 // Create a new JsepTransport with a FakeDtlsTransport and a
Zhi Huange818b6e2018-02-22 15:26:27 -080081 // FakeIceTransport.
Zhi Huang365381f2018-04-13 16:44:34 -070082 std::unique_ptr<JsepTransport> CreateJsepTransport2(bool rtcp_mux_enabled,
83 SrtpMode srtp_mode) {
Qingsi Wang25ec8882019-11-15 12:33:05 -080084 auto ice_internal = std::make_unique<FakeIceTransport>(
85 kTransportName, ICE_CANDIDATE_COMPONENT_RTP);
86 auto rtp_dtls_transport =
87 std::make_unique<FakeDtlsTransport>(ice_internal.get());
88 auto ice = CreateIceTransport(std::move(ice_internal));
Zhi Huange818b6e2018-02-22 15:26:27 -080089
Qingsi Wang25ec8882019-11-15 12:33:05 -080090 std::unique_ptr<FakeIceTransport> rtcp_ice_internal;
Zhi Huange818b6e2018-02-22 15:26:27 -080091 std::unique_ptr<FakeDtlsTransport> rtcp_dtls_transport;
92 if (!rtcp_mux_enabled) {
Qingsi Wang25ec8882019-11-15 12:33:05 -080093 rtcp_ice_internal = std::make_unique<FakeIceTransport>(
Bjorn A Mellem0c1c1b42019-05-29 17:34:13 -070094 kTransportName, ICE_CANDIDATE_COMPONENT_RTCP);
Qingsi Wang25ec8882019-11-15 12:33:05 -080095 rtcp_dtls_transport =
96 std::make_unique<FakeDtlsTransport>(rtcp_ice_internal.get());
Zhi Huange818b6e2018-02-22 15:26:27 -080097 }
Qingsi Wang25ec8882019-11-15 12:33:05 -080098 auto rtcp_ice = CreateIceTransport(std::move(rtcp_ice_internal));
Zhi Huange818b6e2018-02-22 15:26:27 -080099
100 std::unique_ptr<webrtc::RtpTransport> unencrypted_rtp_transport;
101 std::unique_ptr<webrtc::SrtpTransport> sdes_transport;
102 std::unique_ptr<webrtc::DtlsSrtpTransport> dtls_srtp_transport;
103 switch (srtp_mode) {
104 case SrtpMode::kSdes:
Zhi Huange830e682018-03-30 10:48:35 -0700105 sdes_transport = CreateSdesTransport(rtp_dtls_transport.get(),
106 rtcp_dtls_transport.get());
Zhi Huange818b6e2018-02-22 15:26:27 -0800107 sdes_transport_ = sdes_transport.get();
108 break;
109 case SrtpMode::kDtlsSrtp:
Zhi Huange830e682018-03-30 10:48:35 -0700110 dtls_srtp_transport = CreateDtlsSrtpTransport(
111 rtp_dtls_transport.get(), rtcp_dtls_transport.get());
Zhi Huange818b6e2018-02-22 15:26:27 -0800112 break;
113 default:
114 RTC_NOTREACHED();
115 }
116
Anton Sukhanov7940da02018-10-10 10:34:49 -0700117 // TODO(sukhanov): Currently there is no media_transport specific
118 // logic in jseptransport, so jseptransport unittests are created with
119 // media_transport = nullptr. In the future we will probably add
120 // more logic that require unit tests. Note that creation of media_transport
121 // is covered in jseptransportcontroller_unittest.
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200122 auto jsep_transport = std::make_unique<JsepTransport>(
Bjorn A Mellem0c1c1b42019-05-29 17:34:13 -0700123 kTransportName, /*local_certificate=*/nullptr, std::move(ice),
124 std::move(rtcp_ice), std::move(unencrypted_rtp_transport),
125 std::move(sdes_transport), std::move(dtls_srtp_transport),
Bjorn A Mellemc85ebbe2019-06-07 10:28:06 -0700126 /*datagram_rtp_transport=*/nullptr, std::move(rtp_dtls_transport),
127 std::move(rtcp_dtls_transport),
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -0700128 /*sctp_transport=*/nullptr,
Anton Sukhanov292ce4e2019-06-03 13:00:24 -0700129 /*media_transport=*/nullptr,
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -0700130 /*datagram_transport=*/nullptr,
131 /*data_channel_transport=*/nullptr);
Zhi Huange818b6e2018-02-22 15:26:27 -0800132
133 signal_rtcp_mux_active_received_ = false;
Zhi Huange830e682018-03-30 10:48:35 -0700134 jsep_transport->SignalRtcpMuxActive.connect(
Zhi Huange818b6e2018-02-22 15:26:27 -0800135 this, &JsepTransport2Test::OnRtcpMuxActive);
Zhi Huange830e682018-03-30 10:48:35 -0700136 return jsep_transport;
Zhi Huange818b6e2018-02-22 15:26:27 -0800137 }
138
139 JsepTransportDescription MakeJsepTransportDescription(
140 bool rtcp_mux_enabled,
141 const char* ufrag,
142 const char* pwd,
143 const rtc::scoped_refptr<rtc::RTCCertificate>& cert,
144 ConnectionRole role = CONNECTIONROLE_NONE) {
145 JsepTransportDescription jsep_description;
146 jsep_description.rtcp_mux_enabled = rtcp_mux_enabled;
147
148 std::unique_ptr<rtc::SSLFingerprint> fingerprint;
149 if (cert) {
Steve Anton4905edb2018-10-15 19:27:44 -0700150 fingerprint = rtc::SSLFingerprint::CreateFromCertificate(*cert);
Zhi Huange818b6e2018-02-22 15:26:27 -0800151 }
152 jsep_description.transport_desc =
153 TransportDescription(std::vector<std::string>(), ufrag, pwd,
154 ICEMODE_FULL, role, fingerprint.get());
155 return jsep_description;
156 }
157
158 Candidate CreateCandidate(int component) {
159 Candidate c;
160 c.set_address(rtc::SocketAddress("192.168.1.1", 8000));
161 c.set_component(component);
162 c.set_protocol(UDP_PROTOCOL_NAME);
163 c.set_priority(1);
164 return c;
165 }
166
167 void OnRtcpMuxActive() { signal_rtcp_mux_active_received_ = true; }
168
Zhi Huang365381f2018-04-13 16:44:34 -0700169 std::unique_ptr<JsepTransport> jsep_transport_;
Zhi Huange818b6e2018-02-22 15:26:27 -0800170 bool signal_rtcp_mux_active_received_ = false;
171 // The SrtpTransport is owned by |jsep_transport_|. Keep a raw pointer here
172 // for testing.
173 webrtc::SrtpTransport* sdes_transport_ = nullptr;
174};
175
176// The parameterized tests cover both cases when RTCP mux is enable and
177// disabled.
178class JsepTransport2WithRtcpMux : public JsepTransport2Test,
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200179 public ::testing::WithParamInterface<bool> {};
Zhi Huange818b6e2018-02-22 15:26:27 -0800180
181// This test verifies the ICE parameters are properly applied to the transports.
182TEST_P(JsepTransport2WithRtcpMux, SetIceParameters) {
183 bool rtcp_mux_enabled = GetParam();
Zhi Huange830e682018-03-30 10:48:35 -0700184 jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp);
Zhi Huange818b6e2018-02-22 15:26:27 -0800185
186 JsepTransportDescription jsep_description;
187 jsep_description.transport_desc = TransportDescription(kIceUfrag1, kIcePwd1);
188 jsep_description.rtcp_mux_enabled = rtcp_mux_enabled;
189 ASSERT_TRUE(
190 jsep_transport_
191 ->SetLocalJsepTransportDescription(jsep_description, SdpType::kOffer)
192 .ok());
193 auto fake_ice_transport = static_cast<FakeIceTransport*>(
194 jsep_transport_->rtp_dtls_transport()->ice_transport());
195 EXPECT_EQ(ICEMODE_FULL, fake_ice_transport->remote_ice_mode());
196 EXPECT_EQ(kIceUfrag1, fake_ice_transport->ice_ufrag());
197 EXPECT_EQ(kIcePwd1, fake_ice_transport->ice_pwd());
198 if (!rtcp_mux_enabled) {
199 fake_ice_transport = static_cast<FakeIceTransport*>(
200 jsep_transport_->rtcp_dtls_transport()->ice_transport());
201 ASSERT_TRUE(fake_ice_transport);
202 EXPECT_EQ(ICEMODE_FULL, fake_ice_transport->remote_ice_mode());
203 EXPECT_EQ(kIceUfrag1, fake_ice_transport->ice_ufrag());
204 EXPECT_EQ(kIcePwd1, fake_ice_transport->ice_pwd());
205 }
206
207 jsep_description.transport_desc = TransportDescription(kIceUfrag2, kIcePwd2);
208 ASSERT_TRUE(jsep_transport_
209 ->SetRemoteJsepTransportDescription(jsep_description,
210 SdpType::kAnswer)
211 .ok());
212 fake_ice_transport = static_cast<FakeIceTransport*>(
213 jsep_transport_->rtp_dtls_transport()->ice_transport());
214 EXPECT_EQ(ICEMODE_FULL, fake_ice_transport->remote_ice_mode());
215 EXPECT_EQ(kIceUfrag2, fake_ice_transport->remote_ice_ufrag());
216 EXPECT_EQ(kIcePwd2, fake_ice_transport->remote_ice_pwd());
217 if (!rtcp_mux_enabled) {
218 fake_ice_transport = static_cast<FakeIceTransport*>(
219 jsep_transport_->rtcp_dtls_transport()->ice_transport());
220 ASSERT_TRUE(fake_ice_transport);
221 EXPECT_EQ(ICEMODE_FULL, fake_ice_transport->remote_ice_mode());
222 EXPECT_EQ(kIceUfrag2, fake_ice_transport->remote_ice_ufrag());
223 EXPECT_EQ(kIcePwd2, fake_ice_transport->remote_ice_pwd());
224 }
225}
226
227// Similarly, test DTLS parameters are properly applied to the transports.
228TEST_P(JsepTransport2WithRtcpMux, SetDtlsParameters) {
229 bool rtcp_mux_enabled = GetParam();
Zhi Huange830e682018-03-30 10:48:35 -0700230 jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp);
Zhi Huange818b6e2018-02-22 15:26:27 -0800231
232 // Create certificates.
233 rtc::scoped_refptr<rtc::RTCCertificate> local_cert =
234 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
235 rtc::SSLIdentity::Generate("local", rtc::KT_DEFAULT)));
236 rtc::scoped_refptr<rtc::RTCCertificate> remote_cert =
237 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
238 rtc::SSLIdentity::Generate("remote", rtc::KT_DEFAULT)));
239 jsep_transport_->SetLocalCertificate(local_cert);
240
241 // Apply offer.
242 JsepTransportDescription local_description =
243 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag1, kIcePwd1,
244 local_cert, CONNECTIONROLE_ACTPASS);
245 ASSERT_TRUE(
246 jsep_transport_
247 ->SetLocalJsepTransportDescription(local_description, SdpType::kOffer)
248 .ok());
249 // Apply Answer.
250 JsepTransportDescription remote_description =
251 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag2, kIcePwd2,
252 remote_cert, CONNECTIONROLE_ACTIVE);
253 ASSERT_TRUE(jsep_transport_
254 ->SetRemoteJsepTransportDescription(remote_description,
255 SdpType::kAnswer)
256 .ok());
257
258 // Verify that SSL role and remote fingerprint were set correctly based on
259 // transport descriptions.
260 auto role = jsep_transport_->GetDtlsRole();
261 ASSERT_TRUE(role);
262 EXPECT_EQ(rtc::SSL_SERVER, role); // Because remote description was "active".
263 auto fake_dtls =
264 static_cast<FakeDtlsTransport*>(jsep_transport_->rtp_dtls_transport());
265 EXPECT_EQ(remote_description.transport_desc.identity_fingerprint->ToString(),
266 fake_dtls->dtls_fingerprint().ToString());
267
268 if (!rtcp_mux_enabled) {
269 auto fake_rtcp_dtls =
270 static_cast<FakeDtlsTransport*>(jsep_transport_->rtcp_dtls_transport());
271 EXPECT_EQ(
272 remote_description.transport_desc.identity_fingerprint->ToString(),
273 fake_rtcp_dtls->dtls_fingerprint().ToString());
274 }
275}
276
277// Same as above test, but with remote transport description using
278// CONNECTIONROLE_PASSIVE, expecting SSL_CLIENT role.
279TEST_P(JsepTransport2WithRtcpMux, SetDtlsParametersWithPassiveAnswer) {
280 bool rtcp_mux_enabled = GetParam();
Zhi Huange830e682018-03-30 10:48:35 -0700281 jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp);
Zhi Huange818b6e2018-02-22 15:26:27 -0800282
283 // Create certificates.
284 rtc::scoped_refptr<rtc::RTCCertificate> local_cert =
285 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
286 rtc::SSLIdentity::Generate("local", rtc::KT_DEFAULT)));
287 rtc::scoped_refptr<rtc::RTCCertificate> remote_cert =
288 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
289 rtc::SSLIdentity::Generate("remote", rtc::KT_DEFAULT)));
290 jsep_transport_->SetLocalCertificate(local_cert);
291
292 // Apply offer.
293 JsepTransportDescription local_description =
294 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag1, kIcePwd1,
295 local_cert, CONNECTIONROLE_ACTPASS);
296 ASSERT_TRUE(
297 jsep_transport_
298 ->SetLocalJsepTransportDescription(local_description, SdpType::kOffer)
299 .ok());
300 // Apply Answer.
301 JsepTransportDescription remote_description =
302 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag2, kIcePwd2,
303 remote_cert, CONNECTIONROLE_PASSIVE);
304 ASSERT_TRUE(jsep_transport_
305 ->SetRemoteJsepTransportDescription(remote_description,
306 SdpType::kAnswer)
307 .ok());
308
309 // Verify that SSL role and remote fingerprint were set correctly based on
310 // transport descriptions.
311 auto role = jsep_transport_->GetDtlsRole();
312 ASSERT_TRUE(role);
313 EXPECT_EQ(rtc::SSL_CLIENT,
314 role); // Because remote description was "passive".
315 auto fake_dtls =
316 static_cast<FakeDtlsTransport*>(jsep_transport_->rtp_dtls_transport());
317 EXPECT_EQ(remote_description.transport_desc.identity_fingerprint->ToString(),
318 fake_dtls->dtls_fingerprint().ToString());
319
320 if (!rtcp_mux_enabled) {
321 auto fake_rtcp_dtls =
322 static_cast<FakeDtlsTransport*>(jsep_transport_->rtcp_dtls_transport());
323 EXPECT_EQ(
324 remote_description.transport_desc.identity_fingerprint->ToString(),
325 fake_rtcp_dtls->dtls_fingerprint().ToString());
326 }
327}
328
329// Tests SetNeedsIceRestartFlag and need_ice_restart, ensuring needs_ice_restart
330// only starts returning "false" once an ICE restart has been initiated.
331TEST_P(JsepTransport2WithRtcpMux, NeedsIceRestart) {
332 bool rtcp_mux_enabled = GetParam();
Zhi Huange830e682018-03-30 10:48:35 -0700333 jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp);
Zhi Huange818b6e2018-02-22 15:26:27 -0800334
335 // Use the same JsepTransportDescription for both offer and answer.
336 JsepTransportDescription description;
337 description.transport_desc = TransportDescription(kIceUfrag1, kIcePwd1);
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 // Flag initially should be false.
347 EXPECT_FALSE(jsep_transport_->needs_ice_restart());
348
349 // After setting flag, it should be true.
350 jsep_transport_->SetNeedsIceRestartFlag();
351 EXPECT_TRUE(jsep_transport_->needs_ice_restart());
352
353 ASSERT_TRUE(
354 jsep_transport_
355 ->SetLocalJsepTransportDescription(description, SdpType::kOffer)
356 .ok());
357 ASSERT_TRUE(
358 jsep_transport_
359 ->SetRemoteJsepTransportDescription(description, SdpType::kAnswer)
360 .ok());
361 EXPECT_TRUE(jsep_transport_->needs_ice_restart());
362
363 // Doing an offer/answer that restarts ICE should clear the flag.
364 description.transport_desc = TransportDescription(kIceUfrag2, kIcePwd2);
365 ASSERT_TRUE(
366 jsep_transport_
367 ->SetLocalJsepTransportDescription(description, SdpType::kOffer)
368 .ok());
369 ASSERT_TRUE(
370 jsep_transport_
371 ->SetRemoteJsepTransportDescription(description, SdpType::kAnswer)
372 .ok());
373 EXPECT_FALSE(jsep_transport_->needs_ice_restart());
374}
375
376TEST_P(JsepTransport2WithRtcpMux, GetStats) {
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 size_t expected_stats_size = rtcp_mux_enabled ? 1u : 2u;
381 TransportStats stats;
382 EXPECT_TRUE(jsep_transport_->GetStats(&stats));
383 EXPECT_EQ(expected_stats_size, stats.channel_stats.size());
384 EXPECT_EQ(ICE_CANDIDATE_COMPONENT_RTP, stats.channel_stats[0].component);
385 if (!rtcp_mux_enabled) {
386 EXPECT_EQ(ICE_CANDIDATE_COMPONENT_RTCP, stats.channel_stats[1].component);
387 }
388}
389
390// Tests that VerifyCertificateFingerprint only returns true when the
391// certificate matches the fingerprint.
392TEST_P(JsepTransport2WithRtcpMux, VerifyCertificateFingerprint) {
393 bool rtcp_mux_enabled = GetParam();
Zhi Huange830e682018-03-30 10:48:35 -0700394 jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp);
Zhi Huange818b6e2018-02-22 15:26:27 -0800395
396 EXPECT_FALSE(
397 jsep_transport_->VerifyCertificateFingerprint(nullptr, nullptr).ok());
398 rtc::KeyType key_types[] = {rtc::KT_RSA, rtc::KT_ECDSA};
399
400 for (auto& key_type : key_types) {
401 rtc::scoped_refptr<rtc::RTCCertificate> certificate =
402 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
403 rtc::SSLIdentity::Generate("testing", key_type)));
404 ASSERT_NE(nullptr, certificate);
405
406 std::string digest_algorithm;
Benjamin Wright6c6c9df2018-10-25 01:16:26 -0700407 ASSERT_TRUE(certificate->GetSSLCertificate().GetSignatureDigestAlgorithm(
Zhi Huange818b6e2018-02-22 15:26:27 -0800408 &digest_algorithm));
409 ASSERT_FALSE(digest_algorithm.empty());
Steve Anton4905edb2018-10-15 19:27:44 -0700410 std::unique_ptr<rtc::SSLFingerprint> good_fingerprint =
411 rtc::SSLFingerprint::CreateUnique(digest_algorithm,
412 *certificate->identity());
Zhi Huange818b6e2018-02-22 15:26:27 -0800413 ASSERT_NE(nullptr, good_fingerprint);
414
415 EXPECT_TRUE(jsep_transport_
416 ->VerifyCertificateFingerprint(certificate.get(),
417 good_fingerprint.get())
418 .ok());
419 EXPECT_FALSE(jsep_transport_
420 ->VerifyCertificateFingerprint(certificate.get(), nullptr)
421 .ok());
422 EXPECT_FALSE(
423 jsep_transport_
424 ->VerifyCertificateFingerprint(nullptr, good_fingerprint.get())
425 .ok());
426
427 rtc::SSLFingerprint bad_fingerprint = *good_fingerprint;
428 bad_fingerprint.digest.AppendData("0", 1);
429 EXPECT_FALSE(
430 jsep_transport_
431 ->VerifyCertificateFingerprint(certificate.get(), &bad_fingerprint)
432 .ok());
433 }
434}
435
436// Tests the logic of DTLS role negotiation for an initial offer/answer.
437TEST_P(JsepTransport2WithRtcpMux, ValidDtlsRoleNegotiation) {
438 bool rtcp_mux_enabled = GetParam();
439 // Just use the same certificate for both sides; doesn't really matter in a
440 // non end-to-end test.
441 rtc::scoped_refptr<rtc::RTCCertificate> certificate =
442 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
443 rtc::SSLIdentity::Generate("testing", rtc::KT_ECDSA)));
444
445 JsepTransportDescription local_description = MakeJsepTransportDescription(
446 rtcp_mux_enabled, kIceUfrag1, kIcePwd1, certificate);
447 JsepTransportDescription remote_description = MakeJsepTransportDescription(
448 rtcp_mux_enabled, kIceUfrag2, kIcePwd2, certificate);
449
450 // Parameters which set the SSL role to SSL_CLIENT.
451 NegotiateRoleParams valid_client_params[] = {
452 {CONNECTIONROLE_ACTIVE, CONNECTIONROLE_ACTPASS, SdpType::kAnswer,
453 SdpType::kOffer},
454 {CONNECTIONROLE_ACTIVE, CONNECTIONROLE_ACTPASS, SdpType::kPrAnswer,
455 SdpType::kOffer},
456 {CONNECTIONROLE_ACTPASS, CONNECTIONROLE_PASSIVE, SdpType::kOffer,
457 SdpType::kAnswer},
458 {CONNECTIONROLE_ACTPASS, CONNECTIONROLE_PASSIVE, SdpType::kOffer,
459 SdpType::kPrAnswer}};
460
461 for (auto& param : valid_client_params) {
Zhi Huange830e682018-03-30 10:48:35 -0700462 jsep_transport_ =
463 CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp);
Zhi Huange818b6e2018-02-22 15:26:27 -0800464 jsep_transport_->SetLocalCertificate(certificate);
465
466 local_description.transport_desc.connection_role = param.local_role;
467 remote_description.transport_desc.connection_role = param.remote_role;
468
469 // Set the offer first.
470 if (param.local_type == SdpType::kOffer) {
471 EXPECT_TRUE(jsep_transport_
472 ->SetLocalJsepTransportDescription(local_description,
473 param.local_type)
474 .ok());
475 EXPECT_TRUE(jsep_transport_
476 ->SetRemoteJsepTransportDescription(remote_description,
477 param.remote_type)
478 .ok());
479 } else {
480 EXPECT_TRUE(jsep_transport_
481 ->SetRemoteJsepTransportDescription(remote_description,
482 param.remote_type)
483 .ok());
484 EXPECT_TRUE(jsep_transport_
485 ->SetLocalJsepTransportDescription(local_description,
486 param.local_type)
487 .ok());
488 }
489 EXPECT_EQ(rtc::SSL_CLIENT, *jsep_transport_->GetDtlsRole());
490 }
491
492 // Parameters which set the SSL role to SSL_SERVER.
493 NegotiateRoleParams valid_server_params[] = {
494 {CONNECTIONROLE_PASSIVE, CONNECTIONROLE_ACTPASS, SdpType::kAnswer,
495 SdpType::kOffer},
496 {CONNECTIONROLE_PASSIVE, CONNECTIONROLE_ACTPASS, SdpType::kPrAnswer,
497 SdpType::kOffer},
498 {CONNECTIONROLE_ACTPASS, CONNECTIONROLE_ACTIVE, SdpType::kOffer,
499 SdpType::kAnswer},
500 {CONNECTIONROLE_ACTPASS, CONNECTIONROLE_ACTIVE, SdpType::kOffer,
501 SdpType::kPrAnswer}};
502
503 for (auto& param : valid_server_params) {
Zhi Huange830e682018-03-30 10:48:35 -0700504 jsep_transport_ =
505 CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp);
Zhi Huange818b6e2018-02-22 15:26:27 -0800506 jsep_transport_->SetLocalCertificate(certificate);
507
508 local_description.transport_desc.connection_role = param.local_role;
509 remote_description.transport_desc.connection_role = param.remote_role;
510
511 // Set the offer first.
512 if (param.local_type == SdpType::kOffer) {
513 EXPECT_TRUE(jsep_transport_
514 ->SetLocalJsepTransportDescription(local_description,
515 param.local_type)
516 .ok());
517 EXPECT_TRUE(jsep_transport_
518 ->SetRemoteJsepTransportDescription(remote_description,
519 param.remote_type)
520 .ok());
521 } else {
522 EXPECT_TRUE(jsep_transport_
523 ->SetRemoteJsepTransportDescription(remote_description,
524 param.remote_type)
525 .ok());
526 EXPECT_TRUE(jsep_transport_
527 ->SetLocalJsepTransportDescription(local_description,
528 param.local_type)
529 .ok());
530 }
531 EXPECT_EQ(rtc::SSL_SERVER, *jsep_transport_->GetDtlsRole());
532 }
533}
534
535// Tests the logic of DTLS role negotiation for an initial offer/answer.
536TEST_P(JsepTransport2WithRtcpMux, InvalidDtlsRoleNegotiation) {
537 bool rtcp_mux_enabled = GetParam();
538 // Just use the same certificate for both sides; doesn't really matter in a
539 // non end-to-end test.
540 rtc::scoped_refptr<rtc::RTCCertificate> certificate =
541 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
542 rtc::SSLIdentity::Generate("testing", rtc::KT_ECDSA)));
543
544 JsepTransportDescription local_description = MakeJsepTransportDescription(
545 rtcp_mux_enabled, kIceUfrag1, kIcePwd1, certificate);
546 JsepTransportDescription remote_description = MakeJsepTransportDescription(
547 rtcp_mux_enabled, kIceUfrag2, kIcePwd2, certificate);
548
549 NegotiateRoleParams duplicate_params[] = {
550 {CONNECTIONROLE_ACTIVE, CONNECTIONROLE_ACTIVE, SdpType::kAnswer,
551 SdpType::kOffer},
552 {CONNECTIONROLE_ACTPASS, CONNECTIONROLE_ACTPASS, SdpType::kAnswer,
553 SdpType::kOffer},
554 {CONNECTIONROLE_PASSIVE, CONNECTIONROLE_PASSIVE, SdpType::kAnswer,
555 SdpType::kOffer},
556 {CONNECTIONROLE_ACTIVE, CONNECTIONROLE_ACTIVE, SdpType::kPrAnswer,
557 SdpType::kOffer},
558 {CONNECTIONROLE_ACTPASS, CONNECTIONROLE_ACTPASS, SdpType::kPrAnswer,
559 SdpType::kOffer},
560 {CONNECTIONROLE_PASSIVE, CONNECTIONROLE_PASSIVE, SdpType::kPrAnswer,
561 SdpType::kOffer},
562 {CONNECTIONROLE_ACTIVE, CONNECTIONROLE_ACTIVE, SdpType::kOffer,
563 SdpType::kAnswer},
564 {CONNECTIONROLE_ACTPASS, CONNECTIONROLE_ACTPASS, SdpType::kOffer,
565 SdpType::kAnswer},
566 {CONNECTIONROLE_PASSIVE, CONNECTIONROLE_PASSIVE, SdpType::kOffer,
567 SdpType::kAnswer},
568 {CONNECTIONROLE_ACTIVE, CONNECTIONROLE_ACTIVE, SdpType::kOffer,
569 SdpType::kPrAnswer},
570 {CONNECTIONROLE_ACTPASS, CONNECTIONROLE_ACTPASS, SdpType::kOffer,
571 SdpType::kPrAnswer},
572 {CONNECTIONROLE_PASSIVE, CONNECTIONROLE_PASSIVE, SdpType::kOffer,
573 SdpType::kPrAnswer}};
574
575 for (auto& param : duplicate_params) {
Zhi Huange830e682018-03-30 10:48:35 -0700576 jsep_transport_ =
577 CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp);
Zhi Huange818b6e2018-02-22 15:26:27 -0800578 jsep_transport_->SetLocalCertificate(certificate);
579
580 local_description.transport_desc.connection_role = param.local_role;
581 remote_description.transport_desc.connection_role = param.remote_role;
582
583 if (param.local_type == SdpType::kOffer) {
584 EXPECT_TRUE(jsep_transport_
585 ->SetLocalJsepTransportDescription(local_description,
586 param.local_type)
587 .ok());
588 EXPECT_FALSE(jsep_transport_
589 ->SetRemoteJsepTransportDescription(remote_description,
590 param.remote_type)
591 .ok());
592 } else {
593 EXPECT_TRUE(jsep_transport_
594 ->SetRemoteJsepTransportDescription(remote_description,
595 param.remote_type)
596 .ok());
597 EXPECT_FALSE(jsep_transport_
598 ->SetLocalJsepTransportDescription(local_description,
599 param.local_type)
600 .ok());
601 }
602 }
603
604 // Invalid parameters due to the offerer not using ACTPASS.
605 NegotiateRoleParams offerer_without_actpass_params[] = {
606 {CONNECTIONROLE_ACTIVE, CONNECTIONROLE_PASSIVE, SdpType::kAnswer,
607 SdpType::kOffer},
608 {CONNECTIONROLE_PASSIVE, CONNECTIONROLE_ACTIVE, SdpType::kAnswer,
609 SdpType::kOffer},
610 {CONNECTIONROLE_ACTPASS, CONNECTIONROLE_PASSIVE, SdpType::kAnswer,
611 SdpType::kOffer},
612 {CONNECTIONROLE_ACTIVE, CONNECTIONROLE_PASSIVE, SdpType::kPrAnswer,
613 SdpType::kOffer},
614 {CONNECTIONROLE_PASSIVE, CONNECTIONROLE_ACTIVE, SdpType::kPrAnswer,
615 SdpType::kOffer},
616 {CONNECTIONROLE_ACTPASS, CONNECTIONROLE_PASSIVE, SdpType::kPrAnswer,
617 SdpType::kOffer},
618 {CONNECTIONROLE_ACTIVE, CONNECTIONROLE_PASSIVE, SdpType::kOffer,
619 SdpType::kAnswer},
620 {CONNECTIONROLE_PASSIVE, CONNECTIONROLE_ACTIVE, SdpType::kOffer,
621 SdpType::kAnswer},
622 {CONNECTIONROLE_PASSIVE, CONNECTIONROLE_ACTPASS, SdpType::kOffer,
623 SdpType::kAnswer},
624 {CONNECTIONROLE_ACTIVE, CONNECTIONROLE_PASSIVE, SdpType::kOffer,
625 SdpType::kPrAnswer},
626 {CONNECTIONROLE_PASSIVE, CONNECTIONROLE_ACTIVE, SdpType::kOffer,
627 SdpType::kPrAnswer},
628 {CONNECTIONROLE_PASSIVE, CONNECTIONROLE_ACTPASS, SdpType::kOffer,
629 SdpType::kPrAnswer}};
630
631 for (auto& param : offerer_without_actpass_params) {
Zhi Huange830e682018-03-30 10:48:35 -0700632 jsep_transport_ =
633 CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp);
Zhi Huange818b6e2018-02-22 15:26:27 -0800634 jsep_transport_->SetLocalCertificate(certificate);
635
636 local_description.transport_desc.connection_role = param.local_role;
637 remote_description.transport_desc.connection_role = param.remote_role;
638
639 if (param.local_type == SdpType::kOffer) {
640 EXPECT_TRUE(jsep_transport_
641 ->SetLocalJsepTransportDescription(local_description,
642 param.local_type)
643 .ok());
644 EXPECT_FALSE(jsep_transport_
645 ->SetRemoteJsepTransportDescription(remote_description,
646 param.remote_type)
647 .ok());
648 } else {
649 EXPECT_TRUE(jsep_transport_
650 ->SetRemoteJsepTransportDescription(remote_description,
651 param.remote_type)
652 .ok());
653 EXPECT_FALSE(jsep_transport_
654 ->SetLocalJsepTransportDescription(local_description,
655 param.local_type)
656 .ok());
657 }
658 }
659}
660
Mirko Bonadeic84f6612019-01-31 12:20:57 +0100661INSTANTIATE_TEST_SUITE_P(JsepTransport2Test,
662 JsepTransport2WithRtcpMux,
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200663 ::testing::Bool());
Zhi Huange818b6e2018-02-22 15:26:27 -0800664
665// Test that a reoffer in the opposite direction is successful as long as the
666// role isn't changing. Doesn't test every possible combination like the test
667// above.
668TEST_F(JsepTransport2Test, ValidDtlsReofferFromAnswerer) {
669 // Just use the same certificate for both sides; doesn't really matter in a
670 // non end-to-end test.
671 rtc::scoped_refptr<rtc::RTCCertificate> certificate =
672 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
673 rtc::SSLIdentity::Generate("testing", rtc::KT_ECDSA)));
674 bool rtcp_mux_enabled = true;
Zhi Huange830e682018-03-30 10:48:35 -0700675 jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp);
Zhi Huange818b6e2018-02-22 15:26:27 -0800676 jsep_transport_->SetLocalCertificate(certificate);
677
678 JsepTransportDescription local_offer =
679 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag1, kIcePwd1,
680 certificate, CONNECTIONROLE_ACTPASS);
681 JsepTransportDescription remote_answer =
682 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag2, kIcePwd2,
683 certificate, CONNECTIONROLE_ACTIVE);
684
685 EXPECT_TRUE(
686 jsep_transport_
687 ->SetLocalJsepTransportDescription(local_offer, SdpType::kOffer)
688 .ok());
689 EXPECT_TRUE(
690 jsep_transport_
691 ->SetRemoteJsepTransportDescription(remote_answer, SdpType::kAnswer)
692 .ok());
693
694 // We were actpass->active previously, now in the other direction it's
695 // actpass->passive.
696 JsepTransportDescription remote_offer =
697 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag2, kIcePwd2,
698 certificate, CONNECTIONROLE_ACTPASS);
699 JsepTransportDescription local_answer =
700 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag1, kIcePwd1,
701 certificate, CONNECTIONROLE_PASSIVE);
702
703 EXPECT_TRUE(
704 jsep_transport_
705 ->SetRemoteJsepTransportDescription(remote_offer, SdpType::kOffer)
706 .ok());
707 EXPECT_TRUE(
708 jsep_transport_
709 ->SetLocalJsepTransportDescription(local_answer, SdpType::kAnswer)
710 .ok());
711}
712
713// Test that a reoffer in the opposite direction fails if the role changes.
714// Inverse of test above.
715TEST_F(JsepTransport2Test, InvalidDtlsReofferFromAnswerer) {
716 // Just use the same certificate for both sides; doesn't really matter in a
717 // non end-to-end test.
718 rtc::scoped_refptr<rtc::RTCCertificate> certificate =
719 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
720 rtc::SSLIdentity::Generate("testing", rtc::KT_ECDSA)));
721 bool rtcp_mux_enabled = true;
Zhi Huange830e682018-03-30 10:48:35 -0700722 jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp);
Zhi Huange818b6e2018-02-22 15:26:27 -0800723 jsep_transport_->SetLocalCertificate(certificate);
724
725 JsepTransportDescription local_offer =
726 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag1, kIcePwd1,
727 certificate, CONNECTIONROLE_ACTPASS);
728 JsepTransportDescription remote_answer =
729 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag2, kIcePwd2,
730 certificate, CONNECTIONROLE_ACTIVE);
731
732 EXPECT_TRUE(
733 jsep_transport_
734 ->SetLocalJsepTransportDescription(local_offer, SdpType::kOffer)
735 .ok());
736 EXPECT_TRUE(
737 jsep_transport_
738 ->SetRemoteJsepTransportDescription(remote_answer, SdpType::kAnswer)
739 .ok());
740
741 // Changing role to passive here isn't allowed. Though for some reason this
742 // only fails in SetLocalTransportDescription.
743 JsepTransportDescription remote_offer =
744 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag2, kIcePwd2,
745 certificate, CONNECTIONROLE_PASSIVE);
746 JsepTransportDescription local_answer =
747 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag1, kIcePwd1,
748 certificate, CONNECTIONROLE_ACTIVE);
749
750 EXPECT_TRUE(
751 jsep_transport_
752 ->SetRemoteJsepTransportDescription(remote_offer, SdpType::kOffer)
753 .ok());
754 EXPECT_FALSE(
755 jsep_transport_
756 ->SetLocalJsepTransportDescription(local_answer, SdpType::kAnswer)
757 .ok());
758}
759
760// Test that a remote offer with the current negotiated role can be accepted.
761// This is allowed by dtls-sdp, though we'll never generate such an offer,
762// since JSEP requires generating "actpass".
763TEST_F(JsepTransport2Test, RemoteOfferWithCurrentNegotiatedDtlsRole) {
764 rtc::scoped_refptr<rtc::RTCCertificate> certificate =
765 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
766 rtc::SSLIdentity::Generate("testing", rtc::KT_ECDSA)));
767 bool rtcp_mux_enabled = true;
Zhi Huange830e682018-03-30 10:48:35 -0700768 jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp);
Zhi Huange818b6e2018-02-22 15:26:27 -0800769 jsep_transport_->SetLocalCertificate(certificate);
770
771 JsepTransportDescription remote_desc =
772 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag1, kIcePwd1,
773 certificate, CONNECTIONROLE_ACTPASS);
774 JsepTransportDescription local_desc =
775 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag2, kIcePwd2,
776 certificate, CONNECTIONROLE_ACTIVE);
777
778 // Normal initial offer/answer with "actpass" in the offer and "active" in
779 // the answer.
780 ASSERT_TRUE(
781 jsep_transport_
782 ->SetRemoteJsepTransportDescription(remote_desc, SdpType::kOffer)
783 .ok());
784 ASSERT_TRUE(
785 jsep_transport_
786 ->SetLocalJsepTransportDescription(local_desc, SdpType::kAnswer)
787 .ok());
788
789 // Sanity check that role was actually negotiated.
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200790 absl::optional<rtc::SSLRole> role = jsep_transport_->GetDtlsRole();
Zhi Huange818b6e2018-02-22 15:26:27 -0800791 ASSERT_TRUE(role);
792 EXPECT_EQ(rtc::SSL_CLIENT, *role);
793
794 // Subsequent offer with current negotiated role of "passive".
795 remote_desc.transport_desc.connection_role = CONNECTIONROLE_PASSIVE;
796 EXPECT_TRUE(
797 jsep_transport_
798 ->SetRemoteJsepTransportDescription(remote_desc, SdpType::kOffer)
799 .ok());
800 EXPECT_TRUE(
801 jsep_transport_
802 ->SetLocalJsepTransportDescription(local_desc, SdpType::kAnswer)
803 .ok());
804}
805
806// Test that a remote offer with the inverse of the current negotiated DTLS
807// role is rejected.
808TEST_F(JsepTransport2Test, RemoteOfferThatChangesNegotiatedDtlsRole) {
809 rtc::scoped_refptr<rtc::RTCCertificate> certificate =
810 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
811 rtc::SSLIdentity::Generate("testing", rtc::KT_ECDSA)));
812 bool rtcp_mux_enabled = true;
Zhi Huange830e682018-03-30 10:48:35 -0700813 jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp);
Zhi Huange818b6e2018-02-22 15:26:27 -0800814 jsep_transport_->SetLocalCertificate(certificate);
815
816 JsepTransportDescription remote_desc =
817 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag1, kIcePwd1,
818 certificate, CONNECTIONROLE_ACTPASS);
819 JsepTransportDescription local_desc =
820 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag2, kIcePwd2,
821 certificate, CONNECTIONROLE_ACTIVE);
822
823 // Normal initial offer/answer with "actpass" in the offer and "active" in
824 // the answer.
825 ASSERT_TRUE(
826 jsep_transport_
827 ->SetRemoteJsepTransportDescription(remote_desc, SdpType::kOffer)
828 .ok());
829 ASSERT_TRUE(
830 jsep_transport_
831 ->SetLocalJsepTransportDescription(local_desc, SdpType::kAnswer)
832 .ok());
833
834 // Sanity check that role was actually negotiated.
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200835 absl::optional<rtc::SSLRole> role = jsep_transport_->GetDtlsRole();
Zhi Huange818b6e2018-02-22 15:26:27 -0800836 ASSERT_TRUE(role);
837 EXPECT_EQ(rtc::SSL_CLIENT, *role);
838
839 // Subsequent offer with current negotiated role of "passive".
840 remote_desc.transport_desc.connection_role = CONNECTIONROLE_ACTIVE;
841 EXPECT_TRUE(
842 jsep_transport_
843 ->SetRemoteJsepTransportDescription(remote_desc, SdpType::kOffer)
844 .ok());
845 EXPECT_FALSE(
846 jsep_transport_
847 ->SetLocalJsepTransportDescription(local_desc, SdpType::kAnswer)
848 .ok());
849}
850
851// Testing that a legacy client that doesn't use the setup attribute will be
852// interpreted as having an active role.
853TEST_F(JsepTransport2Test, DtlsSetupWithLegacyAsAnswerer) {
854 rtc::scoped_refptr<rtc::RTCCertificate> certificate =
855 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
856 rtc::SSLIdentity::Generate("testing", rtc::KT_ECDSA)));
857 bool rtcp_mux_enabled = true;
Zhi Huange830e682018-03-30 10:48:35 -0700858 jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp);
Zhi Huange818b6e2018-02-22 15:26:27 -0800859 jsep_transport_->SetLocalCertificate(certificate);
860
861 JsepTransportDescription remote_desc =
862 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag1, kIcePwd1,
863 certificate, CONNECTIONROLE_ACTPASS);
864 JsepTransportDescription local_desc =
865 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag2, kIcePwd2,
866 certificate, CONNECTIONROLE_ACTIVE);
867
868 local_desc.transport_desc.connection_role = CONNECTIONROLE_ACTPASS;
869 ASSERT_TRUE(
870 jsep_transport_
871 ->SetLocalJsepTransportDescription(local_desc, SdpType::kOffer)
872 .ok());
873 // Use CONNECTIONROLE_NONE to simulate legacy endpoint.
874 remote_desc.transport_desc.connection_role = CONNECTIONROLE_NONE;
875 ASSERT_TRUE(
876 jsep_transport_
877 ->SetRemoteJsepTransportDescription(remote_desc, SdpType::kAnswer)
878 .ok());
879
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200880 absl::optional<rtc::SSLRole> role = jsep_transport_->GetDtlsRole();
Zhi Huange818b6e2018-02-22 15:26:27 -0800881 ASSERT_TRUE(role);
882 // Since legacy answer ommitted setup atribute, and we offered actpass, we
883 // should act as passive (server).
884 EXPECT_EQ(rtc::SSL_SERVER, *role);
885}
886
887// Tests that when the RTCP mux is successfully negotiated, the RTCP transport
888// will be destroyed and the SignalRtpMuxActive will be fired.
889TEST_F(JsepTransport2Test, RtcpMuxNegotiation) {
Zhi Huange830e682018-03-30 10:48:35 -0700890 jsep_transport_ =
891 CreateJsepTransport2(/*rtcp_mux_enabled=*/false, SrtpMode::kDtlsSrtp);
Zhi Huange818b6e2018-02-22 15:26:27 -0800892 JsepTransportDescription local_desc;
893 local_desc.rtcp_mux_enabled = true;
Harald Alvestrandad88c882018-11-28 16:47:46 +0100894 ASSERT_NE(nullptr, jsep_transport_->rtcp_dtls_transport());
Zhi Huange818b6e2018-02-22 15:26:27 -0800895 EXPECT_FALSE(signal_rtcp_mux_active_received_);
896
897 // The remote side supports RTCP-mux.
898 JsepTransportDescription remote_desc;
899 remote_desc.rtcp_mux_enabled = true;
900 ASSERT_TRUE(
901 jsep_transport_
902 ->SetLocalJsepTransportDescription(local_desc, SdpType::kOffer)
903 .ok());
904 ASSERT_TRUE(
905 jsep_transport_
906 ->SetRemoteJsepTransportDescription(remote_desc, SdpType::kAnswer)
907 .ok());
908
909 EXPECT_EQ(nullptr, jsep_transport_->rtcp_dtls_transport());
910 EXPECT_TRUE(signal_rtcp_mux_active_received_);
911
912 // The remote side doesn't support RTCP-mux.
Zhi Huange830e682018-03-30 10:48:35 -0700913 jsep_transport_ =
914 CreateJsepTransport2(/*rtcp_mux_enabled=*/false, SrtpMode::kDtlsSrtp);
Zhi Huange818b6e2018-02-22 15:26:27 -0800915 signal_rtcp_mux_active_received_ = false;
916 remote_desc.rtcp_mux_enabled = false;
917 ASSERT_TRUE(
918 jsep_transport_
919 ->SetLocalJsepTransportDescription(local_desc, SdpType::kOffer)
920 .ok());
921 ASSERT_TRUE(
922 jsep_transport_
923 ->SetRemoteJsepTransportDescription(remote_desc, SdpType::kAnswer)
924 .ok());
925
926 EXPECT_NE(nullptr, jsep_transport_->rtcp_dtls_transport());
927 EXPECT_FALSE(signal_rtcp_mux_active_received_);
928}
929
930TEST_F(JsepTransport2Test, SdesNegotiation) {
Zhi Huange830e682018-03-30 10:48:35 -0700931 jsep_transport_ =
932 CreateJsepTransport2(/*rtcp_mux_enabled=*/true, SrtpMode::kSdes);
Zhi Huange818b6e2018-02-22 15:26:27 -0800933 ASSERT_TRUE(sdes_transport_);
Zhi Huange830e682018-03-30 10:48:35 -0700934 EXPECT_FALSE(sdes_transport_->IsSrtpActive());
Zhi Huange818b6e2018-02-22 15:26:27 -0800935
936 JsepTransportDescription offer_desc;
937 offer_desc.cryptos.push_back(cricket::CryptoParams(
938 1, rtc::CS_AES_CM_128_HMAC_SHA1_32,
939 "inline:" + rtc::CreateRandomString(40), std::string()));
940 ASSERT_TRUE(
941 jsep_transport_
942 ->SetLocalJsepTransportDescription(offer_desc, SdpType::kOffer)
943 .ok());
944
945 JsepTransportDescription answer_desc;
946 answer_desc.cryptos.push_back(cricket::CryptoParams(
947 1, rtc::CS_AES_CM_128_HMAC_SHA1_32,
948 "inline:" + rtc::CreateRandomString(40), std::string()));
949 ASSERT_TRUE(
950 jsep_transport_
951 ->SetRemoteJsepTransportDescription(answer_desc, SdpType::kAnswer)
952 .ok());
Zhi Huange830e682018-03-30 10:48:35 -0700953 EXPECT_TRUE(sdes_transport_->IsSrtpActive());
Zhi Huange818b6e2018-02-22 15:26:27 -0800954}
955
956TEST_F(JsepTransport2Test, SdesNegotiationWithEmptyCryptosInAnswer) {
Zhi Huange830e682018-03-30 10:48:35 -0700957 jsep_transport_ =
958 CreateJsepTransport2(/*rtcp_mux_enabled=*/true, SrtpMode::kSdes);
Zhi Huange818b6e2018-02-22 15:26:27 -0800959 ASSERT_TRUE(sdes_transport_);
Zhi Huange830e682018-03-30 10:48:35 -0700960 EXPECT_FALSE(sdes_transport_->IsSrtpActive());
Zhi Huange818b6e2018-02-22 15:26:27 -0800961
962 JsepTransportDescription offer_desc;
963 offer_desc.cryptos.push_back(cricket::CryptoParams(
964 1, rtc::CS_AES_CM_128_HMAC_SHA1_32,
965 "inline:" + rtc::CreateRandomString(40), std::string()));
966 ASSERT_TRUE(
967 jsep_transport_
968 ->SetLocalJsepTransportDescription(offer_desc, SdpType::kOffer)
969 .ok());
970
971 JsepTransportDescription answer_desc;
972 ASSERT_TRUE(
973 jsep_transport_
974 ->SetRemoteJsepTransportDescription(answer_desc, SdpType::kAnswer)
975 .ok());
976 // SRTP is not active because the crypto parameter is answer is empty.
Zhi Huange830e682018-03-30 10:48:35 -0700977 EXPECT_FALSE(sdes_transport_->IsSrtpActive());
Zhi Huange818b6e2018-02-22 15:26:27 -0800978}
979
980TEST_F(JsepTransport2Test, SdesNegotiationWithMismatchedCryptos) {
Zhi Huange830e682018-03-30 10:48:35 -0700981 jsep_transport_ =
982 CreateJsepTransport2(/*rtcp_mux_enabled=*/true, SrtpMode::kSdes);
Zhi Huange818b6e2018-02-22 15:26:27 -0800983 ASSERT_TRUE(sdes_transport_);
Zhi Huange830e682018-03-30 10:48:35 -0700984 EXPECT_FALSE(sdes_transport_->IsSrtpActive());
Zhi Huange818b6e2018-02-22 15:26:27 -0800985
986 JsepTransportDescription offer_desc;
987 offer_desc.cryptos.push_back(cricket::CryptoParams(
988 1, rtc::CS_AES_CM_128_HMAC_SHA1_32,
989 "inline:" + rtc::CreateRandomString(40), std::string()));
990 ASSERT_TRUE(
991 jsep_transport_
992 ->SetLocalJsepTransportDescription(offer_desc, SdpType::kOffer)
993 .ok());
994
995 JsepTransportDescription answer_desc;
996 answer_desc.cryptos.push_back(cricket::CryptoParams(
997 1, rtc::CS_AES_CM_128_HMAC_SHA1_80,
998 "inline:" + rtc::CreateRandomString(40), std::string()));
999 // Expected to fail because the crypto parameters don't match.
1000 ASSERT_FALSE(
1001 jsep_transport_
1002 ->SetRemoteJsepTransportDescription(answer_desc, SdpType::kAnswer)
1003 .ok());
1004}
1005
1006// Tests that the remote candidates can be added to the transports after both
1007// local and remote descriptions are set.
1008TEST_F(JsepTransport2Test, AddRemoteCandidates) {
Zhi Huange830e682018-03-30 10:48:35 -07001009 jsep_transport_ =
1010 CreateJsepTransport2(/*rtcp_mux_enabled=*/true, SrtpMode::kDtlsSrtp);
Zhi Huange818b6e2018-02-22 15:26:27 -08001011 auto fake_ice_transport = static_cast<FakeIceTransport*>(
1012 jsep_transport_->rtp_dtls_transport()->ice_transport());
1013
1014 Candidates candidates;
1015 candidates.push_back(CreateCandidate(/*COMPONENT_RTP*/ 1));
1016 candidates.push_back(CreateCandidate(/*COMPONENT_RTP*/ 1));
1017
1018 JsepTransportDescription desc;
1019 ASSERT_TRUE(
1020 jsep_transport_->SetLocalJsepTransportDescription(desc, SdpType::kOffer)
1021 .ok());
1022 // Expected to fail because the remote description is unset.
1023 EXPECT_FALSE(jsep_transport_->AddRemoteCandidates(candidates).ok());
1024
1025 ASSERT_TRUE(
1026 jsep_transport_->SetRemoteJsepTransportDescription(desc, SdpType::kAnswer)
1027 .ok());
1028 EXPECT_EQ(0u, fake_ice_transport->remote_candidates().size());
1029 EXPECT_TRUE(jsep_transport_->AddRemoteCandidates(candidates).ok());
1030 EXPECT_EQ(candidates.size(), fake_ice_transport->remote_candidates().size());
1031}
1032
Zhi Huange830e682018-03-30 10:48:35 -07001033enum class Scenario {
1034 kSdes,
1035 kDtlsBeforeCallerSendOffer,
1036 kDtlsBeforeCallerSetAnswer,
1037 kDtlsAfterCallerSetAnswer,
1038};
1039
1040class JsepTransport2HeaderExtensionTest
1041 : public JsepTransport2Test,
1042 public ::testing::WithParamInterface<std::tuple<Scenario, bool>> {
1043 protected:
1044 JsepTransport2HeaderExtensionTest() {}
1045
1046 void CreateJsepTransportPair(SrtpMode mode) {
1047 jsep_transport1_ = CreateJsepTransport2(/*rtcp_mux_enabled=*/true, mode);
1048 jsep_transport2_ = CreateJsepTransport2(/*rtcp_mux_enabled=*/true, mode);
1049
1050 auto fake_dtls1 =
1051 static_cast<FakeDtlsTransport*>(jsep_transport1_->rtp_dtls_transport());
1052 auto fake_dtls2 =
1053 static_cast<FakeDtlsTransport*>(jsep_transport2_->rtp_dtls_transport());
1054
1055 fake_dtls1->fake_ice_transport()->SignalReadPacket.connect(
1056 this, &JsepTransport2HeaderExtensionTest::OnReadPacket1);
1057 fake_dtls2->fake_ice_transport()->SignalReadPacket.connect(
1058 this, &JsepTransport2HeaderExtensionTest::OnReadPacket2);
1059
1060 if (mode == SrtpMode::kDtlsSrtp) {
1061 auto cert1 =
1062 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
1063 rtc::SSLIdentity::Generate("session1", rtc::KT_DEFAULT)));
1064 jsep_transport1_->rtp_dtls_transport()->SetLocalCertificate(cert1);
1065 auto cert2 =
1066 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
1067 rtc::SSLIdentity::Generate("session1", rtc::KT_DEFAULT)));
1068 jsep_transport2_->rtp_dtls_transport()->SetLocalCertificate(cert2);
1069 }
1070 }
1071
1072 void OnReadPacket1(rtc::PacketTransportInternal* transport,
1073 const char* data,
1074 size_t size,
Niels Möllere6933812018-11-05 13:01:41 +01001075 const int64_t& /* packet_time_us */,
Zhi Huange830e682018-03-30 10:48:35 -07001076 int flags) {
1077 RTC_LOG(LS_INFO) << "JsepTransport 1 Received a packet.";
1078 CompareHeaderExtensions(
1079 reinterpret_cast<const char*>(kPcmuFrameWithExtensions),
1080 sizeof(kPcmuFrameWithExtensions), data, size, recv_encrypted_headers1_,
1081 false);
1082 received_packet_count_++;
1083 }
1084
1085 void OnReadPacket2(rtc::PacketTransportInternal* transport,
1086 const char* data,
1087 size_t size,
Niels Möllere6933812018-11-05 13:01:41 +01001088 const int64_t& /* packet_time_us */,
Zhi Huange830e682018-03-30 10:48:35 -07001089 int flags) {
1090 RTC_LOG(LS_INFO) << "JsepTransport 2 Received a packet.";
1091 CompareHeaderExtensions(
1092 reinterpret_cast<const char*>(kPcmuFrameWithExtensions),
1093 sizeof(kPcmuFrameWithExtensions), data, size, recv_encrypted_headers2_,
1094 false);
1095 received_packet_count_++;
1096 }
1097
1098 void ConnectTransport() {
1099 auto rtp_dtls_transport1 =
1100 static_cast<FakeDtlsTransport*>(jsep_transport1_->rtp_dtls_transport());
1101 auto rtp_dtls_transport2 =
1102 static_cast<FakeDtlsTransport*>(jsep_transport2_->rtp_dtls_transport());
1103 rtp_dtls_transport1->SetDestination(rtp_dtls_transport2);
1104 }
1105
1106 int GetRtpAuthLen() {
1107 bool use_gcm = std::get<1>(GetParam());
1108 if (use_gcm) {
1109 return 16;
1110 }
1111 return 10;
1112 }
1113
1114 void TestSendRecvPacketWithEncryptedHeaderExtension() {
1115 TestOneWaySendRecvPacketWithEncryptedHeaderExtension(
1116 jsep_transport1_.get());
1117 TestOneWaySendRecvPacketWithEncryptedHeaderExtension(
1118 jsep_transport2_.get());
1119 }
1120
1121 void TestOneWaySendRecvPacketWithEncryptedHeaderExtension(
Zhi Huang365381f2018-04-13 16:44:34 -07001122 JsepTransport* sender_transport) {
Zhi Huange830e682018-03-30 10:48:35 -07001123 size_t rtp_len = sizeof(kPcmuFrameWithExtensions);
1124 size_t packet_size = rtp_len + GetRtpAuthLen();
1125 rtc::Buffer rtp_packet_buffer(packet_size);
1126 char* rtp_packet_data = rtp_packet_buffer.data<char>();
1127 memcpy(rtp_packet_data, kPcmuFrameWithExtensions, rtp_len);
1128 // In order to be able to run this test function multiple times we can not
1129 // use the same sequence number twice. Increase the sequence number by one.
1130 rtc::SetBE16(reinterpret_cast<uint8_t*>(rtp_packet_data) + 2,
1131 ++sequence_number_);
1132 rtc::CopyOnWriteBuffer rtp_packet(rtp_packet_data, rtp_len, packet_size);
1133
1134 int packet_count_before = received_packet_count_;
1135 rtc::PacketOptions options;
1136 // Send a packet and verify that the packet can be successfully received and
1137 // decrypted.
1138 ASSERT_TRUE(sender_transport->rtp_transport()->SendRtpPacket(
1139 &rtp_packet, options, cricket::PF_SRTP_BYPASS));
1140 EXPECT_EQ(packet_count_before + 1, received_packet_count_);
1141 }
1142
1143 int sequence_number_ = 0;
1144 int received_packet_count_ = 0;
Zhi Huang365381f2018-04-13 16:44:34 -07001145 std::unique_ptr<JsepTransport> jsep_transport1_;
1146 std::unique_ptr<JsepTransport> jsep_transport2_;
Zhi Huange830e682018-03-30 10:48:35 -07001147 std::vector<int> recv_encrypted_headers1_;
1148 std::vector<int> recv_encrypted_headers2_;
1149};
1150
1151// Test that the encrypted header extension works and can be changed in
1152// different scenarios.
1153TEST_P(JsepTransport2HeaderExtensionTest, EncryptedHeaderExtensionNegotiation) {
1154 Scenario scenario = std::get<0>(GetParam());
1155 bool use_gcm = std::get<1>(GetParam());
1156 SrtpMode mode = SrtpMode ::kDtlsSrtp;
1157 if (scenario == Scenario::kSdes) {
1158 mode = SrtpMode::kSdes;
1159 }
1160 CreateJsepTransportPair(mode);
1161 recv_encrypted_headers1_.push_back(kHeaderExtensionIDs[0]);
1162 recv_encrypted_headers2_.push_back(kHeaderExtensionIDs[1]);
1163
1164 cricket::CryptoParams sdes_param(1, rtc::CS_AES_CM_128_HMAC_SHA1_80,
1165 "inline:" + rtc::CreateRandomString(40),
1166 std::string());
1167 if (use_gcm) {
1168 auto fake_dtls1 =
1169 static_cast<FakeDtlsTransport*>(jsep_transport1_->rtp_dtls_transport());
1170 auto fake_dtls2 =
1171 static_cast<FakeDtlsTransport*>(jsep_transport2_->rtp_dtls_transport());
1172
1173 fake_dtls1->SetSrtpCryptoSuite(rtc::SRTP_AEAD_AES_256_GCM);
1174 fake_dtls2->SetSrtpCryptoSuite(rtc::SRTP_AEAD_AES_256_GCM);
1175 }
1176
1177 if (scenario == Scenario::kDtlsBeforeCallerSendOffer) {
1178 ConnectTransport();
1179 }
1180
1181 JsepTransportDescription offer_desc;
1182 offer_desc.encrypted_header_extension_ids = recv_encrypted_headers1_;
1183 if (scenario == Scenario::kSdes) {
1184 offer_desc.cryptos.push_back(sdes_param);
1185 }
1186 ASSERT_TRUE(
1187 jsep_transport1_
1188 ->SetLocalJsepTransportDescription(offer_desc, SdpType::kOffer)
1189 .ok());
1190 ASSERT_TRUE(
1191 jsep_transport2_
1192 ->SetRemoteJsepTransportDescription(offer_desc, SdpType::kOffer)
1193 .ok());
1194
1195 JsepTransportDescription answer_desc;
1196 answer_desc.encrypted_header_extension_ids = recv_encrypted_headers2_;
1197 if (scenario == Scenario::kSdes) {
1198 answer_desc.cryptos.push_back(sdes_param);
1199 }
1200 ASSERT_TRUE(
1201 jsep_transport2_
1202 ->SetLocalJsepTransportDescription(answer_desc, SdpType::kAnswer)
1203 .ok());
1204
1205 if (scenario == Scenario::kDtlsBeforeCallerSetAnswer) {
1206 ConnectTransport();
1207 // Sending packet from transport2 to transport1 should work when they are
1208 // partially configured.
1209 TestOneWaySendRecvPacketWithEncryptedHeaderExtension(
1210 /*sender_transport=*/jsep_transport2_.get());
1211 }
1212
1213 ASSERT_TRUE(
1214 jsep_transport1_
1215 ->SetRemoteJsepTransportDescription(answer_desc, SdpType::kAnswer)
1216 .ok());
1217
1218 if (scenario == Scenario::kDtlsAfterCallerSetAnswer ||
1219 scenario == Scenario::kSdes) {
1220 ConnectTransport();
1221 }
1222 EXPECT_TRUE(jsep_transport1_->rtp_transport()->IsSrtpActive());
1223 EXPECT_TRUE(jsep_transport2_->rtp_transport()->IsSrtpActive());
1224 TestSendRecvPacketWithEncryptedHeaderExtension();
1225
1226 // Change the encrypted header extension in a new offer/answer exchange.
1227 recv_encrypted_headers1_.clear();
1228 recv_encrypted_headers2_.clear();
1229 recv_encrypted_headers1_.push_back(kHeaderExtensionIDs[1]);
1230 recv_encrypted_headers2_.push_back(kHeaderExtensionIDs[0]);
1231 offer_desc.encrypted_header_extension_ids = recv_encrypted_headers1_;
1232 answer_desc.encrypted_header_extension_ids = recv_encrypted_headers2_;
1233 ASSERT_TRUE(
1234 jsep_transport1_
1235 ->SetLocalJsepTransportDescription(offer_desc, SdpType::kOffer)
1236 .ok());
1237 ASSERT_TRUE(
1238 jsep_transport2_
1239 ->SetRemoteJsepTransportDescription(offer_desc, SdpType::kOffer)
1240 .ok());
1241 ASSERT_TRUE(
1242 jsep_transport2_
1243 ->SetLocalJsepTransportDescription(answer_desc, SdpType::kAnswer)
1244 .ok());
1245 ASSERT_TRUE(
1246 jsep_transport1_
1247 ->SetRemoteJsepTransportDescription(answer_desc, SdpType::kAnswer)
1248 .ok());
1249 EXPECT_TRUE(jsep_transport1_->rtp_transport()->IsSrtpActive());
1250 EXPECT_TRUE(jsep_transport2_->rtp_transport()->IsSrtpActive());
1251 TestSendRecvPacketWithEncryptedHeaderExtension();
1252}
1253
Mirko Bonadeic84f6612019-01-31 12:20:57 +01001254INSTANTIATE_TEST_SUITE_P(
Zhi Huange830e682018-03-30 10:48:35 -07001255 JsepTransport2Test,
1256 JsepTransport2HeaderExtensionTest,
1257 ::testing::Values(
1258 std::make_tuple(Scenario::kSdes, false),
1259 std::make_tuple(Scenario::kDtlsBeforeCallerSendOffer, true),
1260 std::make_tuple(Scenario::kDtlsBeforeCallerSetAnswer, true),
1261 std::make_tuple(Scenario::kDtlsAfterCallerSetAnswer, true),
1262 std::make_tuple(Scenario::kDtlsBeforeCallerSendOffer, false),
1263 std::make_tuple(Scenario::kDtlsBeforeCallerSetAnswer, false),
1264 std::make_tuple(Scenario::kDtlsAfterCallerSetAnswer, false)));
Qingsi Wang25ec8882019-11-15 12:33:05 -08001265} // namespace
Zhi Huange818b6e2018-02-22 15:26:27 -08001266} // namespace cricket