blob: 2f015cdc69e5b3b215fedf4e3506b9760917fa97 [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
11#include <memory>
Zhi Huange830e682018-03-30 10:48:35 -070012#include <tuple>
Zhi Huange818b6e2018-02-22 15:26:27 -080013#include <utility>
14
Zhi Huange830e682018-03-30 10:48:35 -070015#include "media/base/fakertp.h"
Zhi Huange818b6e2018-02-22 15:26:27 -080016#include "p2p/base/fakedtlstransport.h"
17#include "p2p/base/fakeicetransport.h"
18#include "pc/jseptransport2.h"
19#include "rtc_base/gunit.h"
20
21namespace cricket {
22using webrtc::SdpType;
23
24static const char kIceUfrag1[] = "U001";
25static const char kIcePwd1[] = "TESTICEPWD00000000000001";
26static const char kIceUfrag2[] = "U002";
27static const char kIcePwd2[] = "TESTIEPWD00000000000002";
28static const char kTransportName[] = "Test Transport";
29
30enum class SrtpMode {
31 kSdes,
32 kDtlsSrtp,
33};
34
35struct NegotiateRoleParams {
36 ConnectionRole local_role;
37 ConnectionRole remote_role;
38 SdpType local_type;
39 SdpType remote_type;
40};
41
42class JsepTransport2Test : public testing::Test, public sigslot::has_slots<> {
43 protected:
44 std::unique_ptr<webrtc::SrtpTransport> CreateSdesTransport(
Zhi Huange818b6e2018-02-22 15:26:27 -080045 rtc::PacketTransportInternal* rtp_packet_transport,
46 rtc::PacketTransportInternal* rtcp_packet_transport) {
Zhi Huang95e7dbb2018-03-29 00:08:03 +000047 bool rtcp_mux_enabled = (rtcp_packet_transport == nullptr);
48 auto srtp_transport =
49 rtc::MakeUnique<webrtc::SrtpTransport>(rtcp_mux_enabled);
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) {
Zhi Huang95e7dbb2018-03-29 00:08:03 +000061 bool rtcp_mux_enabled = (rtcp_dtls_transport == nullptr);
62 auto srtp_transport =
63 rtc::MakeUnique<webrtc::SrtpTransport>(rtcp_mux_enabled);
64 auto dtls_srtp_transport =
65 rtc::MakeUnique<webrtc::DtlsSrtpTransport>(std::move(srtp_transport));
Zhi Huange818b6e2018-02-22 15:26:27 -080066
67 dtls_srtp_transport->SetDtlsTransports(rtp_dtls_transport,
68 rtcp_dtls_transport);
69 return dtls_srtp_transport;
70 }
71
72 // Create a new JsepTransport2 with a FakeDtlsTransport and a
73 // FakeIceTransport.
Zhi Huange830e682018-03-30 10:48:35 -070074 std::unique_ptr<JsepTransport2> CreateJsepTransport2(bool rtcp_mux_enabled,
75 SrtpMode srtp_mode) {
Zhi Huange818b6e2018-02-22 15:26:27 -080076 auto ice = rtc::MakeUnique<FakeIceTransport>(kTransportName,
77 ICE_CANDIDATE_COMPONENT_RTP);
78 auto rtp_dtls_transport =
79 rtc::MakeUnique<FakeDtlsTransport>(std::move(ice));
80
81 std::unique_ptr<FakeDtlsTransport> rtcp_dtls_transport;
82 if (!rtcp_mux_enabled) {
83 ice = rtc::MakeUnique<FakeIceTransport>(kTransportName,
84 ICE_CANDIDATE_COMPONENT_RTCP);
85 rtcp_dtls_transport = rtc::MakeUnique<FakeDtlsTransport>(std::move(ice));
86 }
87
88 std::unique_ptr<webrtc::RtpTransport> unencrypted_rtp_transport;
89 std::unique_ptr<webrtc::SrtpTransport> sdes_transport;
90 std::unique_ptr<webrtc::DtlsSrtpTransport> dtls_srtp_transport;
91 switch (srtp_mode) {
92 case SrtpMode::kSdes:
Zhi Huange830e682018-03-30 10:48:35 -070093 sdes_transport = CreateSdesTransport(rtp_dtls_transport.get(),
94 rtcp_dtls_transport.get());
Zhi Huange818b6e2018-02-22 15:26:27 -080095 sdes_transport_ = sdes_transport.get();
96 break;
97 case SrtpMode::kDtlsSrtp:
Zhi Huange830e682018-03-30 10:48:35 -070098 dtls_srtp_transport = CreateDtlsSrtpTransport(
99 rtp_dtls_transport.get(), rtcp_dtls_transport.get());
Zhi Huange818b6e2018-02-22 15:26:27 -0800100 break;
101 default:
102 RTC_NOTREACHED();
103 }
104
Zhi Huange830e682018-03-30 10:48:35 -0700105 auto jsep_transport = rtc::MakeUnique<JsepTransport2>(
Zhi Huange818b6e2018-02-22 15:26:27 -0800106 kTransportName, /*local_certificate=*/nullptr,
107 std::move(unencrypted_rtp_transport), std::move(sdes_transport),
108 std::move(dtls_srtp_transport), std::move(rtp_dtls_transport),
109 std::move(rtcp_dtls_transport));
110
111 signal_rtcp_mux_active_received_ = false;
Zhi Huange830e682018-03-30 10:48:35 -0700112 jsep_transport->SignalRtcpMuxActive.connect(
Zhi Huange818b6e2018-02-22 15:26:27 -0800113 this, &JsepTransport2Test::OnRtcpMuxActive);
Zhi Huange830e682018-03-30 10:48:35 -0700114 return jsep_transport;
Zhi Huange818b6e2018-02-22 15:26:27 -0800115 }
116
117 JsepTransportDescription MakeJsepTransportDescription(
118 bool rtcp_mux_enabled,
119 const char* ufrag,
120 const char* pwd,
121 const rtc::scoped_refptr<rtc::RTCCertificate>& cert,
122 ConnectionRole role = CONNECTIONROLE_NONE) {
123 JsepTransportDescription jsep_description;
124 jsep_description.rtcp_mux_enabled = rtcp_mux_enabled;
125
126 std::unique_ptr<rtc::SSLFingerprint> fingerprint;
127 if (cert) {
128 fingerprint.reset(rtc::SSLFingerprint::CreateFromCertificate(cert));
129 }
130 jsep_description.transport_desc =
131 TransportDescription(std::vector<std::string>(), ufrag, pwd,
132 ICEMODE_FULL, role, fingerprint.get());
133 return jsep_description;
134 }
135
136 Candidate CreateCandidate(int component) {
137 Candidate c;
138 c.set_address(rtc::SocketAddress("192.168.1.1", 8000));
139 c.set_component(component);
140 c.set_protocol(UDP_PROTOCOL_NAME);
141 c.set_priority(1);
142 return c;
143 }
144
145 void OnRtcpMuxActive() { signal_rtcp_mux_active_received_ = true; }
146
147 std::unique_ptr<JsepTransport2> jsep_transport_;
148 bool signal_rtcp_mux_active_received_ = false;
149 // The SrtpTransport is owned by |jsep_transport_|. Keep a raw pointer here
150 // for testing.
151 webrtc::SrtpTransport* sdes_transport_ = nullptr;
152};
153
154// The parameterized tests cover both cases when RTCP mux is enable and
155// disabled.
156class JsepTransport2WithRtcpMux : public JsepTransport2Test,
157 public testing::WithParamInterface<bool> {};
158
159// This test verifies the ICE parameters are properly applied to the transports.
160TEST_P(JsepTransport2WithRtcpMux, SetIceParameters) {
161 bool rtcp_mux_enabled = GetParam();
Zhi Huange830e682018-03-30 10:48:35 -0700162 jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp);
Zhi Huange818b6e2018-02-22 15:26:27 -0800163
164 JsepTransportDescription jsep_description;
165 jsep_description.transport_desc = TransportDescription(kIceUfrag1, kIcePwd1);
166 jsep_description.rtcp_mux_enabled = rtcp_mux_enabled;
167 ASSERT_TRUE(
168 jsep_transport_
169 ->SetLocalJsepTransportDescription(jsep_description, SdpType::kOffer)
170 .ok());
171 auto fake_ice_transport = static_cast<FakeIceTransport*>(
172 jsep_transport_->rtp_dtls_transport()->ice_transport());
173 EXPECT_EQ(ICEMODE_FULL, fake_ice_transport->remote_ice_mode());
174 EXPECT_EQ(kIceUfrag1, fake_ice_transport->ice_ufrag());
175 EXPECT_EQ(kIcePwd1, fake_ice_transport->ice_pwd());
176 if (!rtcp_mux_enabled) {
177 fake_ice_transport = static_cast<FakeIceTransport*>(
178 jsep_transport_->rtcp_dtls_transport()->ice_transport());
179 ASSERT_TRUE(fake_ice_transport);
180 EXPECT_EQ(ICEMODE_FULL, fake_ice_transport->remote_ice_mode());
181 EXPECT_EQ(kIceUfrag1, fake_ice_transport->ice_ufrag());
182 EXPECT_EQ(kIcePwd1, fake_ice_transport->ice_pwd());
183 }
184
185 jsep_description.transport_desc = TransportDescription(kIceUfrag2, kIcePwd2);
186 ASSERT_TRUE(jsep_transport_
187 ->SetRemoteJsepTransportDescription(jsep_description,
188 SdpType::kAnswer)
189 .ok());
190 fake_ice_transport = static_cast<FakeIceTransport*>(
191 jsep_transport_->rtp_dtls_transport()->ice_transport());
192 EXPECT_EQ(ICEMODE_FULL, fake_ice_transport->remote_ice_mode());
193 EXPECT_EQ(kIceUfrag2, fake_ice_transport->remote_ice_ufrag());
194 EXPECT_EQ(kIcePwd2, fake_ice_transport->remote_ice_pwd());
195 if (!rtcp_mux_enabled) {
196 fake_ice_transport = static_cast<FakeIceTransport*>(
197 jsep_transport_->rtcp_dtls_transport()->ice_transport());
198 ASSERT_TRUE(fake_ice_transport);
199 EXPECT_EQ(ICEMODE_FULL, fake_ice_transport->remote_ice_mode());
200 EXPECT_EQ(kIceUfrag2, fake_ice_transport->remote_ice_ufrag());
201 EXPECT_EQ(kIcePwd2, fake_ice_transport->remote_ice_pwd());
202 }
203}
204
205// Similarly, test DTLS parameters are properly applied to the transports.
206TEST_P(JsepTransport2WithRtcpMux, SetDtlsParameters) {
207 bool rtcp_mux_enabled = GetParam();
Zhi Huange830e682018-03-30 10:48:35 -0700208 jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp);
Zhi Huange818b6e2018-02-22 15:26:27 -0800209
210 // Create certificates.
211 rtc::scoped_refptr<rtc::RTCCertificate> local_cert =
212 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
213 rtc::SSLIdentity::Generate("local", rtc::KT_DEFAULT)));
214 rtc::scoped_refptr<rtc::RTCCertificate> remote_cert =
215 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
216 rtc::SSLIdentity::Generate("remote", rtc::KT_DEFAULT)));
217 jsep_transport_->SetLocalCertificate(local_cert);
218
219 // Apply offer.
220 JsepTransportDescription local_description =
221 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag1, kIcePwd1,
222 local_cert, CONNECTIONROLE_ACTPASS);
223 ASSERT_TRUE(
224 jsep_transport_
225 ->SetLocalJsepTransportDescription(local_description, SdpType::kOffer)
226 .ok());
227 // Apply Answer.
228 JsepTransportDescription remote_description =
229 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag2, kIcePwd2,
230 remote_cert, CONNECTIONROLE_ACTIVE);
231 ASSERT_TRUE(jsep_transport_
232 ->SetRemoteJsepTransportDescription(remote_description,
233 SdpType::kAnswer)
234 .ok());
235
236 // Verify that SSL role and remote fingerprint were set correctly based on
237 // transport descriptions.
238 auto role = jsep_transport_->GetDtlsRole();
239 ASSERT_TRUE(role);
240 EXPECT_EQ(rtc::SSL_SERVER, role); // Because remote description was "active".
241 auto fake_dtls =
242 static_cast<FakeDtlsTransport*>(jsep_transport_->rtp_dtls_transport());
243 EXPECT_EQ(remote_description.transport_desc.identity_fingerprint->ToString(),
244 fake_dtls->dtls_fingerprint().ToString());
245
246 if (!rtcp_mux_enabled) {
247 auto fake_rtcp_dtls =
248 static_cast<FakeDtlsTransport*>(jsep_transport_->rtcp_dtls_transport());
249 EXPECT_EQ(
250 remote_description.transport_desc.identity_fingerprint->ToString(),
251 fake_rtcp_dtls->dtls_fingerprint().ToString());
252 }
253}
254
255// Same as above test, but with remote transport description using
256// CONNECTIONROLE_PASSIVE, expecting SSL_CLIENT role.
257TEST_P(JsepTransport2WithRtcpMux, SetDtlsParametersWithPassiveAnswer) {
258 bool rtcp_mux_enabled = GetParam();
Zhi Huange830e682018-03-30 10:48:35 -0700259 jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp);
Zhi Huange818b6e2018-02-22 15:26:27 -0800260
261 // Create certificates.
262 rtc::scoped_refptr<rtc::RTCCertificate> local_cert =
263 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
264 rtc::SSLIdentity::Generate("local", rtc::KT_DEFAULT)));
265 rtc::scoped_refptr<rtc::RTCCertificate> remote_cert =
266 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
267 rtc::SSLIdentity::Generate("remote", rtc::KT_DEFAULT)));
268 jsep_transport_->SetLocalCertificate(local_cert);
269
270 // Apply offer.
271 JsepTransportDescription local_description =
272 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag1, kIcePwd1,
273 local_cert, CONNECTIONROLE_ACTPASS);
274 ASSERT_TRUE(
275 jsep_transport_
276 ->SetLocalJsepTransportDescription(local_description, SdpType::kOffer)
277 .ok());
278 // Apply Answer.
279 JsepTransportDescription remote_description =
280 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag2, kIcePwd2,
281 remote_cert, CONNECTIONROLE_PASSIVE);
282 ASSERT_TRUE(jsep_transport_
283 ->SetRemoteJsepTransportDescription(remote_description,
284 SdpType::kAnswer)
285 .ok());
286
287 // Verify that SSL role and remote fingerprint were set correctly based on
288 // transport descriptions.
289 auto role = jsep_transport_->GetDtlsRole();
290 ASSERT_TRUE(role);
291 EXPECT_EQ(rtc::SSL_CLIENT,
292 role); // Because remote description was "passive".
293 auto fake_dtls =
294 static_cast<FakeDtlsTransport*>(jsep_transport_->rtp_dtls_transport());
295 EXPECT_EQ(remote_description.transport_desc.identity_fingerprint->ToString(),
296 fake_dtls->dtls_fingerprint().ToString());
297
298 if (!rtcp_mux_enabled) {
299 auto fake_rtcp_dtls =
300 static_cast<FakeDtlsTransport*>(jsep_transport_->rtcp_dtls_transport());
301 EXPECT_EQ(
302 remote_description.transport_desc.identity_fingerprint->ToString(),
303 fake_rtcp_dtls->dtls_fingerprint().ToString());
304 }
305}
306
307// Tests SetNeedsIceRestartFlag and need_ice_restart, ensuring needs_ice_restart
308// only starts returning "false" once an ICE restart has been initiated.
309TEST_P(JsepTransport2WithRtcpMux, NeedsIceRestart) {
310 bool rtcp_mux_enabled = GetParam();
Zhi Huange830e682018-03-30 10:48:35 -0700311 jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp);
Zhi Huange818b6e2018-02-22 15:26:27 -0800312
313 // Use the same JsepTransportDescription for both offer and answer.
314 JsepTransportDescription description;
315 description.transport_desc = TransportDescription(kIceUfrag1, kIcePwd1);
316 ASSERT_TRUE(
317 jsep_transport_
318 ->SetLocalJsepTransportDescription(description, SdpType::kOffer)
319 .ok());
320 ASSERT_TRUE(
321 jsep_transport_
322 ->SetRemoteJsepTransportDescription(description, SdpType::kAnswer)
323 .ok());
324 // Flag initially should be false.
325 EXPECT_FALSE(jsep_transport_->needs_ice_restart());
326
327 // After setting flag, it should be true.
328 jsep_transport_->SetNeedsIceRestartFlag();
329 EXPECT_TRUE(jsep_transport_->needs_ice_restart());
330
331 ASSERT_TRUE(
332 jsep_transport_
333 ->SetLocalJsepTransportDescription(description, SdpType::kOffer)
334 .ok());
335 ASSERT_TRUE(
336 jsep_transport_
337 ->SetRemoteJsepTransportDescription(description, SdpType::kAnswer)
338 .ok());
339 EXPECT_TRUE(jsep_transport_->needs_ice_restart());
340
341 // Doing an offer/answer that restarts ICE should clear the flag.
342 description.transport_desc = TransportDescription(kIceUfrag2, kIcePwd2);
343 ASSERT_TRUE(
344 jsep_transport_
345 ->SetLocalJsepTransportDescription(description, SdpType::kOffer)
346 .ok());
347 ASSERT_TRUE(
348 jsep_transport_
349 ->SetRemoteJsepTransportDescription(description, SdpType::kAnswer)
350 .ok());
351 EXPECT_FALSE(jsep_transport_->needs_ice_restart());
352}
353
354TEST_P(JsepTransport2WithRtcpMux, GetStats) {
355 bool rtcp_mux_enabled = GetParam();
Zhi Huange830e682018-03-30 10:48:35 -0700356 jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp);
Zhi Huange818b6e2018-02-22 15:26:27 -0800357
358 size_t expected_stats_size = rtcp_mux_enabled ? 1u : 2u;
359 TransportStats stats;
360 EXPECT_TRUE(jsep_transport_->GetStats(&stats));
361 EXPECT_EQ(expected_stats_size, stats.channel_stats.size());
362 EXPECT_EQ(ICE_CANDIDATE_COMPONENT_RTP, stats.channel_stats[0].component);
363 if (!rtcp_mux_enabled) {
364 EXPECT_EQ(ICE_CANDIDATE_COMPONENT_RTCP, stats.channel_stats[1].component);
365 }
366}
367
368// Tests that VerifyCertificateFingerprint only returns true when the
369// certificate matches the fingerprint.
370TEST_P(JsepTransport2WithRtcpMux, VerifyCertificateFingerprint) {
371 bool rtcp_mux_enabled = GetParam();
Zhi Huange830e682018-03-30 10:48:35 -0700372 jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp);
Zhi Huange818b6e2018-02-22 15:26:27 -0800373
374 EXPECT_FALSE(
375 jsep_transport_->VerifyCertificateFingerprint(nullptr, nullptr).ok());
376 rtc::KeyType key_types[] = {rtc::KT_RSA, rtc::KT_ECDSA};
377
378 for (auto& key_type : key_types) {
379 rtc::scoped_refptr<rtc::RTCCertificate> certificate =
380 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
381 rtc::SSLIdentity::Generate("testing", key_type)));
382 ASSERT_NE(nullptr, certificate);
383
384 std::string digest_algorithm;
385 ASSERT_TRUE(certificate->ssl_certificate().GetSignatureDigestAlgorithm(
386 &digest_algorithm));
387 ASSERT_FALSE(digest_algorithm.empty());
388 std::unique_ptr<rtc::SSLFingerprint> good_fingerprint(
389 rtc::SSLFingerprint::Create(digest_algorithm, certificate->identity()));
390 ASSERT_NE(nullptr, good_fingerprint);
391
392 EXPECT_TRUE(jsep_transport_
393 ->VerifyCertificateFingerprint(certificate.get(),
394 good_fingerprint.get())
395 .ok());
396 EXPECT_FALSE(jsep_transport_
397 ->VerifyCertificateFingerprint(certificate.get(), nullptr)
398 .ok());
399 EXPECT_FALSE(
400 jsep_transport_
401 ->VerifyCertificateFingerprint(nullptr, good_fingerprint.get())
402 .ok());
403
404 rtc::SSLFingerprint bad_fingerprint = *good_fingerprint;
405 bad_fingerprint.digest.AppendData("0", 1);
406 EXPECT_FALSE(
407 jsep_transport_
408 ->VerifyCertificateFingerprint(certificate.get(), &bad_fingerprint)
409 .ok());
410 }
411}
412
413// Tests the logic of DTLS role negotiation for an initial offer/answer.
414TEST_P(JsepTransport2WithRtcpMux, ValidDtlsRoleNegotiation) {
415 bool rtcp_mux_enabled = GetParam();
416 // Just use the same certificate for both sides; doesn't really matter in a
417 // non end-to-end test.
418 rtc::scoped_refptr<rtc::RTCCertificate> certificate =
419 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
420 rtc::SSLIdentity::Generate("testing", rtc::KT_ECDSA)));
421
422 JsepTransportDescription local_description = MakeJsepTransportDescription(
423 rtcp_mux_enabled, kIceUfrag1, kIcePwd1, certificate);
424 JsepTransportDescription remote_description = MakeJsepTransportDescription(
425 rtcp_mux_enabled, kIceUfrag2, kIcePwd2, certificate);
426
427 // Parameters which set the SSL role to SSL_CLIENT.
428 NegotiateRoleParams valid_client_params[] = {
429 {CONNECTIONROLE_ACTIVE, CONNECTIONROLE_ACTPASS, SdpType::kAnswer,
430 SdpType::kOffer},
431 {CONNECTIONROLE_ACTIVE, CONNECTIONROLE_ACTPASS, SdpType::kPrAnswer,
432 SdpType::kOffer},
433 {CONNECTIONROLE_ACTPASS, CONNECTIONROLE_PASSIVE, SdpType::kOffer,
434 SdpType::kAnswer},
435 {CONNECTIONROLE_ACTPASS, CONNECTIONROLE_PASSIVE, SdpType::kOffer,
436 SdpType::kPrAnswer}};
437
438 for (auto& param : valid_client_params) {
Zhi Huange830e682018-03-30 10:48:35 -0700439 jsep_transport_ =
440 CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp);
Zhi Huange818b6e2018-02-22 15:26:27 -0800441 jsep_transport_->SetLocalCertificate(certificate);
442
443 local_description.transport_desc.connection_role = param.local_role;
444 remote_description.transport_desc.connection_role = param.remote_role;
445
446 // Set the offer first.
447 if (param.local_type == SdpType::kOffer) {
448 EXPECT_TRUE(jsep_transport_
449 ->SetLocalJsepTransportDescription(local_description,
450 param.local_type)
451 .ok());
452 EXPECT_TRUE(jsep_transport_
453 ->SetRemoteJsepTransportDescription(remote_description,
454 param.remote_type)
455 .ok());
456 } else {
457 EXPECT_TRUE(jsep_transport_
458 ->SetRemoteJsepTransportDescription(remote_description,
459 param.remote_type)
460 .ok());
461 EXPECT_TRUE(jsep_transport_
462 ->SetLocalJsepTransportDescription(local_description,
463 param.local_type)
464 .ok());
465 }
466 EXPECT_EQ(rtc::SSL_CLIENT, *jsep_transport_->GetDtlsRole());
467 }
468
469 // Parameters which set the SSL role to SSL_SERVER.
470 NegotiateRoleParams valid_server_params[] = {
471 {CONNECTIONROLE_PASSIVE, CONNECTIONROLE_ACTPASS, SdpType::kAnswer,
472 SdpType::kOffer},
473 {CONNECTIONROLE_PASSIVE, CONNECTIONROLE_ACTPASS, SdpType::kPrAnswer,
474 SdpType::kOffer},
475 {CONNECTIONROLE_ACTPASS, CONNECTIONROLE_ACTIVE, SdpType::kOffer,
476 SdpType::kAnswer},
477 {CONNECTIONROLE_ACTPASS, CONNECTIONROLE_ACTIVE, SdpType::kOffer,
478 SdpType::kPrAnswer}};
479
480 for (auto& param : valid_server_params) {
Zhi Huange830e682018-03-30 10:48:35 -0700481 jsep_transport_ =
482 CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp);
Zhi Huange818b6e2018-02-22 15:26:27 -0800483 jsep_transport_->SetLocalCertificate(certificate);
484
485 local_description.transport_desc.connection_role = param.local_role;
486 remote_description.transport_desc.connection_role = param.remote_role;
487
488 // Set the offer first.
489 if (param.local_type == SdpType::kOffer) {
490 EXPECT_TRUE(jsep_transport_
491 ->SetLocalJsepTransportDescription(local_description,
492 param.local_type)
493 .ok());
494 EXPECT_TRUE(jsep_transport_
495 ->SetRemoteJsepTransportDescription(remote_description,
496 param.remote_type)
497 .ok());
498 } else {
499 EXPECT_TRUE(jsep_transport_
500 ->SetRemoteJsepTransportDescription(remote_description,
501 param.remote_type)
502 .ok());
503 EXPECT_TRUE(jsep_transport_
504 ->SetLocalJsepTransportDescription(local_description,
505 param.local_type)
506 .ok());
507 }
508 EXPECT_EQ(rtc::SSL_SERVER, *jsep_transport_->GetDtlsRole());
509 }
510}
511
512// Tests the logic of DTLS role negotiation for an initial offer/answer.
513TEST_P(JsepTransport2WithRtcpMux, InvalidDtlsRoleNegotiation) {
514 bool rtcp_mux_enabled = GetParam();
515 // Just use the same certificate for both sides; doesn't really matter in a
516 // non end-to-end test.
517 rtc::scoped_refptr<rtc::RTCCertificate> certificate =
518 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
519 rtc::SSLIdentity::Generate("testing", rtc::KT_ECDSA)));
520
521 JsepTransportDescription local_description = MakeJsepTransportDescription(
522 rtcp_mux_enabled, kIceUfrag1, kIcePwd1, certificate);
523 JsepTransportDescription remote_description = MakeJsepTransportDescription(
524 rtcp_mux_enabled, kIceUfrag2, kIcePwd2, certificate);
525
526 NegotiateRoleParams duplicate_params[] = {
527 {CONNECTIONROLE_ACTIVE, CONNECTIONROLE_ACTIVE, SdpType::kAnswer,
528 SdpType::kOffer},
529 {CONNECTIONROLE_ACTPASS, CONNECTIONROLE_ACTPASS, SdpType::kAnswer,
530 SdpType::kOffer},
531 {CONNECTIONROLE_PASSIVE, CONNECTIONROLE_PASSIVE, SdpType::kAnswer,
532 SdpType::kOffer},
533 {CONNECTIONROLE_ACTIVE, CONNECTIONROLE_ACTIVE, SdpType::kPrAnswer,
534 SdpType::kOffer},
535 {CONNECTIONROLE_ACTPASS, CONNECTIONROLE_ACTPASS, SdpType::kPrAnswer,
536 SdpType::kOffer},
537 {CONNECTIONROLE_PASSIVE, CONNECTIONROLE_PASSIVE, SdpType::kPrAnswer,
538 SdpType::kOffer},
539 {CONNECTIONROLE_ACTIVE, CONNECTIONROLE_ACTIVE, SdpType::kOffer,
540 SdpType::kAnswer},
541 {CONNECTIONROLE_ACTPASS, CONNECTIONROLE_ACTPASS, SdpType::kOffer,
542 SdpType::kAnswer},
543 {CONNECTIONROLE_PASSIVE, CONNECTIONROLE_PASSIVE, SdpType::kOffer,
544 SdpType::kAnswer},
545 {CONNECTIONROLE_ACTIVE, CONNECTIONROLE_ACTIVE, SdpType::kOffer,
546 SdpType::kPrAnswer},
547 {CONNECTIONROLE_ACTPASS, CONNECTIONROLE_ACTPASS, SdpType::kOffer,
548 SdpType::kPrAnswer},
549 {CONNECTIONROLE_PASSIVE, CONNECTIONROLE_PASSIVE, SdpType::kOffer,
550 SdpType::kPrAnswer}};
551
552 for (auto& param : duplicate_params) {
Zhi Huange830e682018-03-30 10:48:35 -0700553 jsep_transport_ =
554 CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp);
Zhi Huange818b6e2018-02-22 15:26:27 -0800555 jsep_transport_->SetLocalCertificate(certificate);
556
557 local_description.transport_desc.connection_role = param.local_role;
558 remote_description.transport_desc.connection_role = param.remote_role;
559
560 if (param.local_type == SdpType::kOffer) {
561 EXPECT_TRUE(jsep_transport_
562 ->SetLocalJsepTransportDescription(local_description,
563 param.local_type)
564 .ok());
565 EXPECT_FALSE(jsep_transport_
566 ->SetRemoteJsepTransportDescription(remote_description,
567 param.remote_type)
568 .ok());
569 } else {
570 EXPECT_TRUE(jsep_transport_
571 ->SetRemoteJsepTransportDescription(remote_description,
572 param.remote_type)
573 .ok());
574 EXPECT_FALSE(jsep_transport_
575 ->SetLocalJsepTransportDescription(local_description,
576 param.local_type)
577 .ok());
578 }
579 }
580
581 // Invalid parameters due to the offerer not using ACTPASS.
582 NegotiateRoleParams offerer_without_actpass_params[] = {
583 {CONNECTIONROLE_ACTIVE, CONNECTIONROLE_PASSIVE, SdpType::kAnswer,
584 SdpType::kOffer},
585 {CONNECTIONROLE_PASSIVE, CONNECTIONROLE_ACTIVE, SdpType::kAnswer,
586 SdpType::kOffer},
587 {CONNECTIONROLE_ACTPASS, CONNECTIONROLE_PASSIVE, SdpType::kAnswer,
588 SdpType::kOffer},
589 {CONNECTIONROLE_ACTIVE, CONNECTIONROLE_PASSIVE, SdpType::kPrAnswer,
590 SdpType::kOffer},
591 {CONNECTIONROLE_PASSIVE, CONNECTIONROLE_ACTIVE, SdpType::kPrAnswer,
592 SdpType::kOffer},
593 {CONNECTIONROLE_ACTPASS, CONNECTIONROLE_PASSIVE, SdpType::kPrAnswer,
594 SdpType::kOffer},
595 {CONNECTIONROLE_ACTIVE, CONNECTIONROLE_PASSIVE, SdpType::kOffer,
596 SdpType::kAnswer},
597 {CONNECTIONROLE_PASSIVE, CONNECTIONROLE_ACTIVE, SdpType::kOffer,
598 SdpType::kAnswer},
599 {CONNECTIONROLE_PASSIVE, CONNECTIONROLE_ACTPASS, SdpType::kOffer,
600 SdpType::kAnswer},
601 {CONNECTIONROLE_ACTIVE, CONNECTIONROLE_PASSIVE, SdpType::kOffer,
602 SdpType::kPrAnswer},
603 {CONNECTIONROLE_PASSIVE, CONNECTIONROLE_ACTIVE, SdpType::kOffer,
604 SdpType::kPrAnswer},
605 {CONNECTIONROLE_PASSIVE, CONNECTIONROLE_ACTPASS, SdpType::kOffer,
606 SdpType::kPrAnswer}};
607
608 for (auto& param : offerer_without_actpass_params) {
Zhi Huange830e682018-03-30 10:48:35 -0700609 jsep_transport_ =
610 CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp);
Zhi Huange818b6e2018-02-22 15:26:27 -0800611 jsep_transport_->SetLocalCertificate(certificate);
612
613 local_description.transport_desc.connection_role = param.local_role;
614 remote_description.transport_desc.connection_role = param.remote_role;
615
616 if (param.local_type == SdpType::kOffer) {
617 EXPECT_TRUE(jsep_transport_
618 ->SetLocalJsepTransportDescription(local_description,
619 param.local_type)
620 .ok());
621 EXPECT_FALSE(jsep_transport_
622 ->SetRemoteJsepTransportDescription(remote_description,
623 param.remote_type)
624 .ok());
625 } else {
626 EXPECT_TRUE(jsep_transport_
627 ->SetRemoteJsepTransportDescription(remote_description,
628 param.remote_type)
629 .ok());
630 EXPECT_FALSE(jsep_transport_
631 ->SetLocalJsepTransportDescription(local_description,
632 param.local_type)
633 .ok());
634 }
635 }
636}
637
638INSTANTIATE_TEST_CASE_P(JsepTransport2Test,
639 JsepTransport2WithRtcpMux,
640 testing::Bool());
641
642// Test that a reoffer in the opposite direction is successful as long as the
643// role isn't changing. Doesn't test every possible combination like the test
644// above.
645TEST_F(JsepTransport2Test, ValidDtlsReofferFromAnswerer) {
646 // Just use the same certificate for both sides; doesn't really matter in a
647 // non end-to-end test.
648 rtc::scoped_refptr<rtc::RTCCertificate> certificate =
649 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
650 rtc::SSLIdentity::Generate("testing", rtc::KT_ECDSA)));
651 bool rtcp_mux_enabled = true;
Zhi Huange830e682018-03-30 10:48:35 -0700652 jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp);
Zhi Huange818b6e2018-02-22 15:26:27 -0800653 jsep_transport_->SetLocalCertificate(certificate);
654
655 JsepTransportDescription local_offer =
656 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag1, kIcePwd1,
657 certificate, CONNECTIONROLE_ACTPASS);
658 JsepTransportDescription remote_answer =
659 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag2, kIcePwd2,
660 certificate, CONNECTIONROLE_ACTIVE);
661
662 EXPECT_TRUE(
663 jsep_transport_
664 ->SetLocalJsepTransportDescription(local_offer, SdpType::kOffer)
665 .ok());
666 EXPECT_TRUE(
667 jsep_transport_
668 ->SetRemoteJsepTransportDescription(remote_answer, SdpType::kAnswer)
669 .ok());
670
671 // We were actpass->active previously, now in the other direction it's
672 // actpass->passive.
673 JsepTransportDescription remote_offer =
674 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag2, kIcePwd2,
675 certificate, CONNECTIONROLE_ACTPASS);
676 JsepTransportDescription local_answer =
677 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag1, kIcePwd1,
678 certificate, CONNECTIONROLE_PASSIVE);
679
680 EXPECT_TRUE(
681 jsep_transport_
682 ->SetRemoteJsepTransportDescription(remote_offer, SdpType::kOffer)
683 .ok());
684 EXPECT_TRUE(
685 jsep_transport_
686 ->SetLocalJsepTransportDescription(local_answer, SdpType::kAnswer)
687 .ok());
688}
689
690// Test that a reoffer in the opposite direction fails if the role changes.
691// Inverse of test above.
692TEST_F(JsepTransport2Test, InvalidDtlsReofferFromAnswerer) {
693 // Just use the same certificate for both sides; doesn't really matter in a
694 // non end-to-end test.
695 rtc::scoped_refptr<rtc::RTCCertificate> certificate =
696 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
697 rtc::SSLIdentity::Generate("testing", rtc::KT_ECDSA)));
698 bool rtcp_mux_enabled = true;
Zhi Huange830e682018-03-30 10:48:35 -0700699 jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp);
Zhi Huange818b6e2018-02-22 15:26:27 -0800700 jsep_transport_->SetLocalCertificate(certificate);
701
702 JsepTransportDescription local_offer =
703 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag1, kIcePwd1,
704 certificate, CONNECTIONROLE_ACTPASS);
705 JsepTransportDescription remote_answer =
706 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag2, kIcePwd2,
707 certificate, CONNECTIONROLE_ACTIVE);
708
709 EXPECT_TRUE(
710 jsep_transport_
711 ->SetLocalJsepTransportDescription(local_offer, SdpType::kOffer)
712 .ok());
713 EXPECT_TRUE(
714 jsep_transport_
715 ->SetRemoteJsepTransportDescription(remote_answer, SdpType::kAnswer)
716 .ok());
717
718 // Changing role to passive here isn't allowed. Though for some reason this
719 // only fails in SetLocalTransportDescription.
720 JsepTransportDescription remote_offer =
721 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag2, kIcePwd2,
722 certificate, CONNECTIONROLE_PASSIVE);
723 JsepTransportDescription local_answer =
724 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag1, kIcePwd1,
725 certificate, CONNECTIONROLE_ACTIVE);
726
727 EXPECT_TRUE(
728 jsep_transport_
729 ->SetRemoteJsepTransportDescription(remote_offer, SdpType::kOffer)
730 .ok());
731 EXPECT_FALSE(
732 jsep_transport_
733 ->SetLocalJsepTransportDescription(local_answer, SdpType::kAnswer)
734 .ok());
735}
736
737// Test that a remote offer with the current negotiated role can be accepted.
738// This is allowed by dtls-sdp, though we'll never generate such an offer,
739// since JSEP requires generating "actpass".
740TEST_F(JsepTransport2Test, RemoteOfferWithCurrentNegotiatedDtlsRole) {
741 rtc::scoped_refptr<rtc::RTCCertificate> certificate =
742 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
743 rtc::SSLIdentity::Generate("testing", rtc::KT_ECDSA)));
744 bool rtcp_mux_enabled = true;
Zhi Huange830e682018-03-30 10:48:35 -0700745 jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp);
Zhi Huange818b6e2018-02-22 15:26:27 -0800746 jsep_transport_->SetLocalCertificate(certificate);
747
748 JsepTransportDescription remote_desc =
749 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag1, kIcePwd1,
750 certificate, CONNECTIONROLE_ACTPASS);
751 JsepTransportDescription local_desc =
752 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag2, kIcePwd2,
753 certificate, CONNECTIONROLE_ACTIVE);
754
755 // Normal initial offer/answer with "actpass" in the offer and "active" in
756 // the answer.
757 ASSERT_TRUE(
758 jsep_transport_
759 ->SetRemoteJsepTransportDescription(remote_desc, SdpType::kOffer)
760 .ok());
761 ASSERT_TRUE(
762 jsep_transport_
763 ->SetLocalJsepTransportDescription(local_desc, SdpType::kAnswer)
764 .ok());
765
766 // Sanity check that role was actually negotiated.
767 rtc::Optional<rtc::SSLRole> role = jsep_transport_->GetDtlsRole();
768 ASSERT_TRUE(role);
769 EXPECT_EQ(rtc::SSL_CLIENT, *role);
770
771 // Subsequent offer with current negotiated role of "passive".
772 remote_desc.transport_desc.connection_role = CONNECTIONROLE_PASSIVE;
773 EXPECT_TRUE(
774 jsep_transport_
775 ->SetRemoteJsepTransportDescription(remote_desc, SdpType::kOffer)
776 .ok());
777 EXPECT_TRUE(
778 jsep_transport_
779 ->SetLocalJsepTransportDescription(local_desc, SdpType::kAnswer)
780 .ok());
781}
782
783// Test that a remote offer with the inverse of the current negotiated DTLS
784// role is rejected.
785TEST_F(JsepTransport2Test, RemoteOfferThatChangesNegotiatedDtlsRole) {
786 rtc::scoped_refptr<rtc::RTCCertificate> certificate =
787 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
788 rtc::SSLIdentity::Generate("testing", rtc::KT_ECDSA)));
789 bool rtcp_mux_enabled = true;
Zhi Huange830e682018-03-30 10:48:35 -0700790 jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp);
Zhi Huange818b6e2018-02-22 15:26:27 -0800791 jsep_transport_->SetLocalCertificate(certificate);
792
793 JsepTransportDescription remote_desc =
794 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag1, kIcePwd1,
795 certificate, CONNECTIONROLE_ACTPASS);
796 JsepTransportDescription local_desc =
797 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag2, kIcePwd2,
798 certificate, CONNECTIONROLE_ACTIVE);
799
800 // Normal initial offer/answer with "actpass" in the offer and "active" in
801 // the answer.
802 ASSERT_TRUE(
803 jsep_transport_
804 ->SetRemoteJsepTransportDescription(remote_desc, SdpType::kOffer)
805 .ok());
806 ASSERT_TRUE(
807 jsep_transport_
808 ->SetLocalJsepTransportDescription(local_desc, SdpType::kAnswer)
809 .ok());
810
811 // Sanity check that role was actually negotiated.
812 rtc::Optional<rtc::SSLRole> role = jsep_transport_->GetDtlsRole();
813 ASSERT_TRUE(role);
814 EXPECT_EQ(rtc::SSL_CLIENT, *role);
815
816 // Subsequent offer with current negotiated role of "passive".
817 remote_desc.transport_desc.connection_role = CONNECTIONROLE_ACTIVE;
818 EXPECT_TRUE(
819 jsep_transport_
820 ->SetRemoteJsepTransportDescription(remote_desc, SdpType::kOffer)
821 .ok());
822 EXPECT_FALSE(
823 jsep_transport_
824 ->SetLocalJsepTransportDescription(local_desc, SdpType::kAnswer)
825 .ok());
826}
827
828// Testing that a legacy client that doesn't use the setup attribute will be
829// interpreted as having an active role.
830TEST_F(JsepTransport2Test, DtlsSetupWithLegacyAsAnswerer) {
831 rtc::scoped_refptr<rtc::RTCCertificate> certificate =
832 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
833 rtc::SSLIdentity::Generate("testing", rtc::KT_ECDSA)));
834 bool rtcp_mux_enabled = true;
Zhi Huange830e682018-03-30 10:48:35 -0700835 jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp);
Zhi Huange818b6e2018-02-22 15:26:27 -0800836 jsep_transport_->SetLocalCertificate(certificate);
837
838 JsepTransportDescription remote_desc =
839 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag1, kIcePwd1,
840 certificate, CONNECTIONROLE_ACTPASS);
841 JsepTransportDescription local_desc =
842 MakeJsepTransportDescription(rtcp_mux_enabled, kIceUfrag2, kIcePwd2,
843 certificate, CONNECTIONROLE_ACTIVE);
844
845 local_desc.transport_desc.connection_role = CONNECTIONROLE_ACTPASS;
846 ASSERT_TRUE(
847 jsep_transport_
848 ->SetLocalJsepTransportDescription(local_desc, SdpType::kOffer)
849 .ok());
850 // Use CONNECTIONROLE_NONE to simulate legacy endpoint.
851 remote_desc.transport_desc.connection_role = CONNECTIONROLE_NONE;
852 ASSERT_TRUE(
853 jsep_transport_
854 ->SetRemoteJsepTransportDescription(remote_desc, SdpType::kAnswer)
855 .ok());
856
857 rtc::Optional<rtc::SSLRole> role = jsep_transport_->GetDtlsRole();
858 ASSERT_TRUE(role);
859 // Since legacy answer ommitted setup atribute, and we offered actpass, we
860 // should act as passive (server).
861 EXPECT_EQ(rtc::SSL_SERVER, *role);
862}
863
864// Tests that when the RTCP mux is successfully negotiated, the RTCP transport
865// will be destroyed and the SignalRtpMuxActive will be fired.
866TEST_F(JsepTransport2Test, RtcpMuxNegotiation) {
Zhi Huange830e682018-03-30 10:48:35 -0700867 jsep_transport_ =
868 CreateJsepTransport2(/*rtcp_mux_enabled=*/false, SrtpMode::kDtlsSrtp);
Zhi Huange818b6e2018-02-22 15:26:27 -0800869 JsepTransportDescription local_desc;
870 local_desc.rtcp_mux_enabled = true;
871 EXPECT_NE(nullptr, jsep_transport_->rtcp_dtls_transport());
872 EXPECT_FALSE(signal_rtcp_mux_active_received_);
873
874 // The remote side supports RTCP-mux.
875 JsepTransportDescription remote_desc;
876 remote_desc.rtcp_mux_enabled = true;
877 ASSERT_TRUE(
878 jsep_transport_
879 ->SetLocalJsepTransportDescription(local_desc, SdpType::kOffer)
880 .ok());
881 ASSERT_TRUE(
882 jsep_transport_
883 ->SetRemoteJsepTransportDescription(remote_desc, SdpType::kAnswer)
884 .ok());
885
886 EXPECT_EQ(nullptr, jsep_transport_->rtcp_dtls_transport());
887 EXPECT_TRUE(signal_rtcp_mux_active_received_);
888
889 // The remote side doesn't support RTCP-mux.
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 signal_rtcp_mux_active_received_ = false;
893 remote_desc.rtcp_mux_enabled = false;
894 ASSERT_TRUE(
895 jsep_transport_
896 ->SetLocalJsepTransportDescription(local_desc, SdpType::kOffer)
897 .ok());
898 ASSERT_TRUE(
899 jsep_transport_
900 ->SetRemoteJsepTransportDescription(remote_desc, SdpType::kAnswer)
901 .ok());
902
903 EXPECT_NE(nullptr, jsep_transport_->rtcp_dtls_transport());
904 EXPECT_FALSE(signal_rtcp_mux_active_received_);
905}
906
907TEST_F(JsepTransport2Test, SdesNegotiation) {
Zhi Huange830e682018-03-30 10:48:35 -0700908 jsep_transport_ =
909 CreateJsepTransport2(/*rtcp_mux_enabled=*/true, SrtpMode::kSdes);
Zhi Huange818b6e2018-02-22 15:26:27 -0800910 ASSERT_TRUE(sdes_transport_);
Zhi Huange830e682018-03-30 10:48:35 -0700911 EXPECT_FALSE(sdes_transport_->IsSrtpActive());
Zhi Huange818b6e2018-02-22 15:26:27 -0800912
913 JsepTransportDescription offer_desc;
914 offer_desc.cryptos.push_back(cricket::CryptoParams(
915 1, rtc::CS_AES_CM_128_HMAC_SHA1_32,
916 "inline:" + rtc::CreateRandomString(40), std::string()));
917 ASSERT_TRUE(
918 jsep_transport_
919 ->SetLocalJsepTransportDescription(offer_desc, SdpType::kOffer)
920 .ok());
921
922 JsepTransportDescription answer_desc;
923 answer_desc.cryptos.push_back(cricket::CryptoParams(
924 1, rtc::CS_AES_CM_128_HMAC_SHA1_32,
925 "inline:" + rtc::CreateRandomString(40), std::string()));
926 ASSERT_TRUE(
927 jsep_transport_
928 ->SetRemoteJsepTransportDescription(answer_desc, SdpType::kAnswer)
929 .ok());
Zhi Huange830e682018-03-30 10:48:35 -0700930 EXPECT_TRUE(sdes_transport_->IsSrtpActive());
Zhi Huange818b6e2018-02-22 15:26:27 -0800931}
932
933TEST_F(JsepTransport2Test, SdesNegotiationWithEmptyCryptosInAnswer) {
Zhi Huange830e682018-03-30 10:48:35 -0700934 jsep_transport_ =
935 CreateJsepTransport2(/*rtcp_mux_enabled=*/true, SrtpMode::kSdes);
Zhi Huange818b6e2018-02-22 15:26:27 -0800936 ASSERT_TRUE(sdes_transport_);
Zhi Huange830e682018-03-30 10:48:35 -0700937 EXPECT_FALSE(sdes_transport_->IsSrtpActive());
Zhi Huange818b6e2018-02-22 15:26:27 -0800938
939 JsepTransportDescription offer_desc;
940 offer_desc.cryptos.push_back(cricket::CryptoParams(
941 1, rtc::CS_AES_CM_128_HMAC_SHA1_32,
942 "inline:" + rtc::CreateRandomString(40), std::string()));
943 ASSERT_TRUE(
944 jsep_transport_
945 ->SetLocalJsepTransportDescription(offer_desc, SdpType::kOffer)
946 .ok());
947
948 JsepTransportDescription answer_desc;
949 ASSERT_TRUE(
950 jsep_transport_
951 ->SetRemoteJsepTransportDescription(answer_desc, SdpType::kAnswer)
952 .ok());
953 // SRTP is not active because the crypto parameter is answer is empty.
Zhi Huange830e682018-03-30 10:48:35 -0700954 EXPECT_FALSE(sdes_transport_->IsSrtpActive());
Zhi Huange818b6e2018-02-22 15:26:27 -0800955}
956
957TEST_F(JsepTransport2Test, SdesNegotiationWithMismatchedCryptos) {
Zhi Huange830e682018-03-30 10:48:35 -0700958 jsep_transport_ =
959 CreateJsepTransport2(/*rtcp_mux_enabled=*/true, SrtpMode::kSdes);
Zhi Huange818b6e2018-02-22 15:26:27 -0800960 ASSERT_TRUE(sdes_transport_);
Zhi Huange830e682018-03-30 10:48:35 -0700961 EXPECT_FALSE(sdes_transport_->IsSrtpActive());
Zhi Huange818b6e2018-02-22 15:26:27 -0800962
963 JsepTransportDescription offer_desc;
964 offer_desc.cryptos.push_back(cricket::CryptoParams(
965 1, rtc::CS_AES_CM_128_HMAC_SHA1_32,
966 "inline:" + rtc::CreateRandomString(40), std::string()));
967 ASSERT_TRUE(
968 jsep_transport_
969 ->SetLocalJsepTransportDescription(offer_desc, SdpType::kOffer)
970 .ok());
971
972 JsepTransportDescription answer_desc;
973 answer_desc.cryptos.push_back(cricket::CryptoParams(
974 1, rtc::CS_AES_CM_128_HMAC_SHA1_80,
975 "inline:" + rtc::CreateRandomString(40), std::string()));
976 // Expected to fail because the crypto parameters don't match.
977 ASSERT_FALSE(
978 jsep_transport_
979 ->SetRemoteJsepTransportDescription(answer_desc, SdpType::kAnswer)
980 .ok());
981}
982
983// Tests that the remote candidates can be added to the transports after both
984// local and remote descriptions are set.
985TEST_F(JsepTransport2Test, AddRemoteCandidates) {
Zhi Huange830e682018-03-30 10:48:35 -0700986 jsep_transport_ =
987 CreateJsepTransport2(/*rtcp_mux_enabled=*/true, SrtpMode::kDtlsSrtp);
Zhi Huange818b6e2018-02-22 15:26:27 -0800988 auto fake_ice_transport = static_cast<FakeIceTransport*>(
989 jsep_transport_->rtp_dtls_transport()->ice_transport());
990
991 Candidates candidates;
992 candidates.push_back(CreateCandidate(/*COMPONENT_RTP*/ 1));
993 candidates.push_back(CreateCandidate(/*COMPONENT_RTP*/ 1));
994
995 JsepTransportDescription desc;
996 ASSERT_TRUE(
997 jsep_transport_->SetLocalJsepTransportDescription(desc, SdpType::kOffer)
998 .ok());
999 // Expected to fail because the remote description is unset.
1000 EXPECT_FALSE(jsep_transport_->AddRemoteCandidates(candidates).ok());
1001
1002 ASSERT_TRUE(
1003 jsep_transport_->SetRemoteJsepTransportDescription(desc, SdpType::kAnswer)
1004 .ok());
1005 EXPECT_EQ(0u, fake_ice_transport->remote_candidates().size());
1006 EXPECT_TRUE(jsep_transport_->AddRemoteCandidates(candidates).ok());
1007 EXPECT_EQ(candidates.size(), fake_ice_transport->remote_candidates().size());
1008}
1009
Zhi Huange830e682018-03-30 10:48:35 -07001010enum class Scenario {
1011 kSdes,
1012 kDtlsBeforeCallerSendOffer,
1013 kDtlsBeforeCallerSetAnswer,
1014 kDtlsAfterCallerSetAnswer,
1015};
1016
1017class JsepTransport2HeaderExtensionTest
1018 : public JsepTransport2Test,
1019 public ::testing::WithParamInterface<std::tuple<Scenario, bool>> {
1020 protected:
1021 JsepTransport2HeaderExtensionTest() {}
1022
1023 void CreateJsepTransportPair(SrtpMode mode) {
1024 jsep_transport1_ = CreateJsepTransport2(/*rtcp_mux_enabled=*/true, mode);
1025 jsep_transport2_ = CreateJsepTransport2(/*rtcp_mux_enabled=*/true, mode);
1026
1027 auto fake_dtls1 =
1028 static_cast<FakeDtlsTransport*>(jsep_transport1_->rtp_dtls_transport());
1029 auto fake_dtls2 =
1030 static_cast<FakeDtlsTransport*>(jsep_transport2_->rtp_dtls_transport());
1031
1032 fake_dtls1->fake_ice_transport()->SignalReadPacket.connect(
1033 this, &JsepTransport2HeaderExtensionTest::OnReadPacket1);
1034 fake_dtls2->fake_ice_transport()->SignalReadPacket.connect(
1035 this, &JsepTransport2HeaderExtensionTest::OnReadPacket2);
1036
1037 if (mode == SrtpMode::kDtlsSrtp) {
1038 auto cert1 =
1039 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
1040 rtc::SSLIdentity::Generate("session1", rtc::KT_DEFAULT)));
1041 jsep_transport1_->rtp_dtls_transport()->SetLocalCertificate(cert1);
1042 auto cert2 =
1043 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
1044 rtc::SSLIdentity::Generate("session1", rtc::KT_DEFAULT)));
1045 jsep_transport2_->rtp_dtls_transport()->SetLocalCertificate(cert2);
1046 }
1047 }
1048
1049 void OnReadPacket1(rtc::PacketTransportInternal* transport,
1050 const char* data,
1051 size_t size,
1052 const rtc::PacketTime& time,
1053 int flags) {
1054 RTC_LOG(LS_INFO) << "JsepTransport 1 Received a packet.";
1055 CompareHeaderExtensions(
1056 reinterpret_cast<const char*>(kPcmuFrameWithExtensions),
1057 sizeof(kPcmuFrameWithExtensions), data, size, recv_encrypted_headers1_,
1058 false);
1059 received_packet_count_++;
1060 }
1061
1062 void OnReadPacket2(rtc::PacketTransportInternal* transport,
1063 const char* data,
1064 size_t size,
1065 const rtc::PacketTime& time,
1066 int flags) {
1067 RTC_LOG(LS_INFO) << "JsepTransport 2 Received a packet.";
1068 CompareHeaderExtensions(
1069 reinterpret_cast<const char*>(kPcmuFrameWithExtensions),
1070 sizeof(kPcmuFrameWithExtensions), data, size, recv_encrypted_headers2_,
1071 false);
1072 received_packet_count_++;
1073 }
1074
1075 void ConnectTransport() {
1076 auto rtp_dtls_transport1 =
1077 static_cast<FakeDtlsTransport*>(jsep_transport1_->rtp_dtls_transport());
1078 auto rtp_dtls_transport2 =
1079 static_cast<FakeDtlsTransport*>(jsep_transport2_->rtp_dtls_transport());
1080 rtp_dtls_transport1->SetDestination(rtp_dtls_transport2);
1081 }
1082
1083 int GetRtpAuthLen() {
1084 bool use_gcm = std::get<1>(GetParam());
1085 if (use_gcm) {
1086 return 16;
1087 }
1088 return 10;
1089 }
1090
1091 void TestSendRecvPacketWithEncryptedHeaderExtension() {
1092 TestOneWaySendRecvPacketWithEncryptedHeaderExtension(
1093 jsep_transport1_.get());
1094 TestOneWaySendRecvPacketWithEncryptedHeaderExtension(
1095 jsep_transport2_.get());
1096 }
1097
1098 void TestOneWaySendRecvPacketWithEncryptedHeaderExtension(
1099 JsepTransport2* sender_transport) {
1100 size_t rtp_len = sizeof(kPcmuFrameWithExtensions);
1101 size_t packet_size = rtp_len + GetRtpAuthLen();
1102 rtc::Buffer rtp_packet_buffer(packet_size);
1103 char* rtp_packet_data = rtp_packet_buffer.data<char>();
1104 memcpy(rtp_packet_data, kPcmuFrameWithExtensions, rtp_len);
1105 // In order to be able to run this test function multiple times we can not
1106 // use the same sequence number twice. Increase the sequence number by one.
1107 rtc::SetBE16(reinterpret_cast<uint8_t*>(rtp_packet_data) + 2,
1108 ++sequence_number_);
1109 rtc::CopyOnWriteBuffer rtp_packet(rtp_packet_data, rtp_len, packet_size);
1110
1111 int packet_count_before = received_packet_count_;
1112 rtc::PacketOptions options;
1113 // Send a packet and verify that the packet can be successfully received and
1114 // decrypted.
1115 ASSERT_TRUE(sender_transport->rtp_transport()->SendRtpPacket(
1116 &rtp_packet, options, cricket::PF_SRTP_BYPASS));
1117 EXPECT_EQ(packet_count_before + 1, received_packet_count_);
1118 }
1119
1120 int sequence_number_ = 0;
1121 int received_packet_count_ = 0;
1122 std::unique_ptr<JsepTransport2> jsep_transport1_;
1123 std::unique_ptr<JsepTransport2> jsep_transport2_;
1124 std::vector<int> recv_encrypted_headers1_;
1125 std::vector<int> recv_encrypted_headers2_;
1126};
1127
1128// Test that the encrypted header extension works and can be changed in
1129// different scenarios.
1130TEST_P(JsepTransport2HeaderExtensionTest, EncryptedHeaderExtensionNegotiation) {
1131 Scenario scenario = std::get<0>(GetParam());
1132 bool use_gcm = std::get<1>(GetParam());
1133 SrtpMode mode = SrtpMode ::kDtlsSrtp;
1134 if (scenario == Scenario::kSdes) {
1135 mode = SrtpMode::kSdes;
1136 }
1137 CreateJsepTransportPair(mode);
1138 recv_encrypted_headers1_.push_back(kHeaderExtensionIDs[0]);
1139 recv_encrypted_headers2_.push_back(kHeaderExtensionIDs[1]);
1140
1141 cricket::CryptoParams sdes_param(1, rtc::CS_AES_CM_128_HMAC_SHA1_80,
1142 "inline:" + rtc::CreateRandomString(40),
1143 std::string());
1144 if (use_gcm) {
1145 auto fake_dtls1 =
1146 static_cast<FakeDtlsTransport*>(jsep_transport1_->rtp_dtls_transport());
1147 auto fake_dtls2 =
1148 static_cast<FakeDtlsTransport*>(jsep_transport2_->rtp_dtls_transport());
1149
1150 fake_dtls1->SetSrtpCryptoSuite(rtc::SRTP_AEAD_AES_256_GCM);
1151 fake_dtls2->SetSrtpCryptoSuite(rtc::SRTP_AEAD_AES_256_GCM);
1152 }
1153
1154 if (scenario == Scenario::kDtlsBeforeCallerSendOffer) {
1155 ConnectTransport();
1156 }
1157
1158 JsepTransportDescription offer_desc;
1159 offer_desc.encrypted_header_extension_ids = recv_encrypted_headers1_;
1160 if (scenario == Scenario::kSdes) {
1161 offer_desc.cryptos.push_back(sdes_param);
1162 }
1163 ASSERT_TRUE(
1164 jsep_transport1_
1165 ->SetLocalJsepTransportDescription(offer_desc, SdpType::kOffer)
1166 .ok());
1167 ASSERT_TRUE(
1168 jsep_transport2_
1169 ->SetRemoteJsepTransportDescription(offer_desc, SdpType::kOffer)
1170 .ok());
1171
1172 JsepTransportDescription answer_desc;
1173 answer_desc.encrypted_header_extension_ids = recv_encrypted_headers2_;
1174 if (scenario == Scenario::kSdes) {
1175 answer_desc.cryptos.push_back(sdes_param);
1176 }
1177 ASSERT_TRUE(
1178 jsep_transport2_
1179 ->SetLocalJsepTransportDescription(answer_desc, SdpType::kAnswer)
1180 .ok());
1181
1182 if (scenario == Scenario::kDtlsBeforeCallerSetAnswer) {
1183 ConnectTransport();
1184 // Sending packet from transport2 to transport1 should work when they are
1185 // partially configured.
1186 TestOneWaySendRecvPacketWithEncryptedHeaderExtension(
1187 /*sender_transport=*/jsep_transport2_.get());
1188 }
1189
1190 ASSERT_TRUE(
1191 jsep_transport1_
1192 ->SetRemoteJsepTransportDescription(answer_desc, SdpType::kAnswer)
1193 .ok());
1194
1195 if (scenario == Scenario::kDtlsAfterCallerSetAnswer ||
1196 scenario == Scenario::kSdes) {
1197 ConnectTransport();
1198 }
1199 EXPECT_TRUE(jsep_transport1_->rtp_transport()->IsSrtpActive());
1200 EXPECT_TRUE(jsep_transport2_->rtp_transport()->IsSrtpActive());
1201 TestSendRecvPacketWithEncryptedHeaderExtension();
1202
1203 // Change the encrypted header extension in a new offer/answer exchange.
1204 recv_encrypted_headers1_.clear();
1205 recv_encrypted_headers2_.clear();
1206 recv_encrypted_headers1_.push_back(kHeaderExtensionIDs[1]);
1207 recv_encrypted_headers2_.push_back(kHeaderExtensionIDs[0]);
1208 offer_desc.encrypted_header_extension_ids = recv_encrypted_headers1_;
1209 answer_desc.encrypted_header_extension_ids = recv_encrypted_headers2_;
1210 ASSERT_TRUE(
1211 jsep_transport1_
1212 ->SetLocalJsepTransportDescription(offer_desc, SdpType::kOffer)
1213 .ok());
1214 ASSERT_TRUE(
1215 jsep_transport2_
1216 ->SetRemoteJsepTransportDescription(offer_desc, SdpType::kOffer)
1217 .ok());
1218 ASSERT_TRUE(
1219 jsep_transport2_
1220 ->SetLocalJsepTransportDescription(answer_desc, SdpType::kAnswer)
1221 .ok());
1222 ASSERT_TRUE(
1223 jsep_transport1_
1224 ->SetRemoteJsepTransportDescription(answer_desc, SdpType::kAnswer)
1225 .ok());
1226 EXPECT_TRUE(jsep_transport1_->rtp_transport()->IsSrtpActive());
1227 EXPECT_TRUE(jsep_transport2_->rtp_transport()->IsSrtpActive());
1228 TestSendRecvPacketWithEncryptedHeaderExtension();
1229}
1230
1231INSTANTIATE_TEST_CASE_P(
1232 JsepTransport2Test,
1233 JsepTransport2HeaderExtensionTest,
1234 ::testing::Values(
1235 std::make_tuple(Scenario::kSdes, false),
1236 std::make_tuple(Scenario::kDtlsBeforeCallerSendOffer, true),
1237 std::make_tuple(Scenario::kDtlsBeforeCallerSetAnswer, true),
1238 std::make_tuple(Scenario::kDtlsAfterCallerSetAnswer, true),
1239 std::make_tuple(Scenario::kDtlsBeforeCallerSendOffer, false),
1240 std::make_tuple(Scenario::kDtlsBeforeCallerSetAnswer, false),
1241 std::make_tuple(Scenario::kDtlsAfterCallerSetAnswer, false)));
1242
Zhi Huange818b6e2018-02-22 15:26:27 -08001243} // namespace cricket