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