1 /*
2 * Copyright 2017 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 "pc/dtls_srtp_transport.h"
12
13 #include <string.h>
14
15 #include <cstdint>
16 #include <memory>
17
18 #include "call/rtp_demuxer.h"
19 #include "media/base/fake_rtp.h"
20 #include "p2p/base/dtls_transport_internal.h"
21 #include "p2p/base/fake_dtls_transport.h"
22 #include "p2p/base/fake_ice_transport.h"
23 #include "p2p/base/p2p_constants.h"
24 #include "pc/rtp_transport.h"
25 #include "pc/test/rtp_transport_test_util.h"
26 #include "rtc_base/async_packet_socket.h"
27 #include "rtc_base/byte_order.h"
28 #include "rtc_base/containers/flat_set.h"
29 #include "rtc_base/copy_on_write_buffer.h"
30 #include "rtc_base/rtc_certificate.h"
31 #include "rtc_base/ssl_identity.h"
32 #include "rtc_base/third_party/sigslot/sigslot.h"
33 #include "test/gtest.h"
34 #include "test/scoped_key_value_config.h"
35
36 using cricket::FakeDtlsTransport;
37 using cricket::FakeIceTransport;
38 using webrtc::DtlsSrtpTransport;
39 using webrtc::RtpTransport;
40 using webrtc::SrtpTransport;
41
42 const int kRtpAuthTagLen = 10;
43
44 class DtlsSrtpTransportTest : public ::testing::Test,
45 public sigslot::has_slots<> {
46 protected:
DtlsSrtpTransportTest()47 DtlsSrtpTransportTest() {}
48
~DtlsSrtpTransportTest()49 ~DtlsSrtpTransportTest() {
50 if (dtls_srtp_transport1_) {
51 dtls_srtp_transport1_->UnregisterRtpDemuxerSink(&transport_observer1_);
52 }
53 if (dtls_srtp_transport2_) {
54 dtls_srtp_transport2_->UnregisterRtpDemuxerSink(&transport_observer2_);
55 }
56 }
57
MakeDtlsSrtpTransport(FakeDtlsTransport * rtp_dtls,FakeDtlsTransport * rtcp_dtls,bool rtcp_mux_enabled)58 std::unique_ptr<DtlsSrtpTransport> MakeDtlsSrtpTransport(
59 FakeDtlsTransport* rtp_dtls,
60 FakeDtlsTransport* rtcp_dtls,
61 bool rtcp_mux_enabled) {
62 auto dtls_srtp_transport =
63 std::make_unique<DtlsSrtpTransport>(rtcp_mux_enabled, field_trials_);
64
65 dtls_srtp_transport->SetDtlsTransports(rtp_dtls, rtcp_dtls);
66
67 return dtls_srtp_transport;
68 }
69
MakeDtlsSrtpTransports(FakeDtlsTransport * rtp_dtls1,FakeDtlsTransport * rtcp_dtls1,FakeDtlsTransport * rtp_dtls2,FakeDtlsTransport * rtcp_dtls2,bool rtcp_mux_enabled)70 void MakeDtlsSrtpTransports(FakeDtlsTransport* rtp_dtls1,
71 FakeDtlsTransport* rtcp_dtls1,
72 FakeDtlsTransport* rtp_dtls2,
73 FakeDtlsTransport* rtcp_dtls2,
74 bool rtcp_mux_enabled) {
75 dtls_srtp_transport1_ =
76 MakeDtlsSrtpTransport(rtp_dtls1, rtcp_dtls1, rtcp_mux_enabled);
77 dtls_srtp_transport2_ =
78 MakeDtlsSrtpTransport(rtp_dtls2, rtcp_dtls2, rtcp_mux_enabled);
79
80 dtls_srtp_transport1_->SignalRtcpPacketReceived.connect(
81 &transport_observer1_,
82 &webrtc::TransportObserver::OnRtcpPacketReceived);
83 dtls_srtp_transport1_->SignalReadyToSend.connect(
84 &transport_observer1_, &webrtc::TransportObserver::OnReadyToSend);
85
86 dtls_srtp_transport2_->SignalRtcpPacketReceived.connect(
87 &transport_observer2_,
88 &webrtc::TransportObserver::OnRtcpPacketReceived);
89 dtls_srtp_transport2_->SignalReadyToSend.connect(
90 &transport_observer2_, &webrtc::TransportObserver::OnReadyToSend);
91 webrtc::RtpDemuxerCriteria demuxer_criteria;
92 // 0x00 is the payload type used in kPcmuFrame.
93 demuxer_criteria.payload_types() = {0x00};
94 dtls_srtp_transport1_->RegisterRtpDemuxerSink(demuxer_criteria,
95 &transport_observer1_);
96 dtls_srtp_transport2_->RegisterRtpDemuxerSink(demuxer_criteria,
97 &transport_observer2_);
98 }
99
CompleteDtlsHandshake(FakeDtlsTransport * fake_dtls1,FakeDtlsTransport * fake_dtls2)100 void CompleteDtlsHandshake(FakeDtlsTransport* fake_dtls1,
101 FakeDtlsTransport* fake_dtls2) {
102 auto cert1 = rtc::RTCCertificate::Create(
103 rtc::SSLIdentity::Create("session1", rtc::KT_DEFAULT));
104 fake_dtls1->SetLocalCertificate(cert1);
105 auto cert2 = rtc::RTCCertificate::Create(
106 rtc::SSLIdentity::Create("session1", rtc::KT_DEFAULT));
107 fake_dtls2->SetLocalCertificate(cert2);
108 fake_dtls1->SetDestination(fake_dtls2);
109 }
110
SendRecvRtpPackets()111 void SendRecvRtpPackets() {
112 ASSERT_TRUE(dtls_srtp_transport1_);
113 ASSERT_TRUE(dtls_srtp_transport2_);
114 ASSERT_TRUE(dtls_srtp_transport1_->IsSrtpActive());
115 ASSERT_TRUE(dtls_srtp_transport2_->IsSrtpActive());
116
117 size_t rtp_len = sizeof(kPcmuFrame);
118 size_t packet_size = rtp_len + kRtpAuthTagLen;
119 rtc::Buffer rtp_packet_buffer(packet_size);
120 char* rtp_packet_data = rtp_packet_buffer.data<char>();
121 memcpy(rtp_packet_data, kPcmuFrame, rtp_len);
122 // In order to be able to run this test function multiple times we can not
123 // use the same sequence number twice. Increase the sequence number by one.
124 rtc::SetBE16(reinterpret_cast<uint8_t*>(rtp_packet_data) + 2,
125 ++sequence_number_);
126 rtc::CopyOnWriteBuffer rtp_packet1to2(rtp_packet_data, rtp_len,
127 packet_size);
128 rtc::CopyOnWriteBuffer rtp_packet2to1(rtp_packet_data, rtp_len,
129 packet_size);
130
131 rtc::PacketOptions options;
132 // Send a packet from `srtp_transport1_` to `srtp_transport2_` and verify
133 // that the packet can be successfully received and decrypted.
134 int prev_received_packets = transport_observer2_.rtp_count();
135 ASSERT_TRUE(dtls_srtp_transport1_->SendRtpPacket(&rtp_packet1to2, options,
136 cricket::PF_SRTP_BYPASS));
137 ASSERT_TRUE(transport_observer2_.last_recv_rtp_packet().data());
138 EXPECT_EQ(0, memcmp(transport_observer2_.last_recv_rtp_packet().data(),
139 kPcmuFrame, rtp_len));
140 EXPECT_EQ(prev_received_packets + 1, transport_observer2_.rtp_count());
141
142 prev_received_packets = transport_observer1_.rtp_count();
143 ASSERT_TRUE(dtls_srtp_transport2_->SendRtpPacket(&rtp_packet2to1, options,
144 cricket::PF_SRTP_BYPASS));
145 ASSERT_TRUE(transport_observer1_.last_recv_rtp_packet().data());
146 EXPECT_EQ(0, memcmp(transport_observer1_.last_recv_rtp_packet().data(),
147 kPcmuFrame, rtp_len));
148 EXPECT_EQ(prev_received_packets + 1, transport_observer1_.rtp_count());
149 }
150
SendRecvRtcpPackets()151 void SendRecvRtcpPackets() {
152 size_t rtcp_len = sizeof(kRtcpReport);
153 size_t packet_size = rtcp_len + 4 + kRtpAuthTagLen;
154 rtc::Buffer rtcp_packet_buffer(packet_size);
155
156 // TODO(zhihuang): Remove the extra copy when the SendRtpPacket method
157 // doesn't take the CopyOnWriteBuffer by pointer.
158 rtc::CopyOnWriteBuffer rtcp_packet1to2(kRtcpReport, rtcp_len, packet_size);
159 rtc::CopyOnWriteBuffer rtcp_packet2to1(kRtcpReport, rtcp_len, packet_size);
160
161 rtc::PacketOptions options;
162 // Send a packet from `srtp_transport1_` to `srtp_transport2_` and verify
163 // that the packet can be successfully received and decrypted.
164 int prev_received_packets = transport_observer2_.rtcp_count();
165 ASSERT_TRUE(dtls_srtp_transport1_->SendRtcpPacket(&rtcp_packet1to2, options,
166 cricket::PF_SRTP_BYPASS));
167 ASSERT_TRUE(transport_observer2_.last_recv_rtcp_packet().data());
168 EXPECT_EQ(0, memcmp(transport_observer2_.last_recv_rtcp_packet().data(),
169 kRtcpReport, rtcp_len));
170 EXPECT_EQ(prev_received_packets + 1, transport_observer2_.rtcp_count());
171
172 // Do the same thing in the opposite direction;
173 prev_received_packets = transport_observer1_.rtcp_count();
174 ASSERT_TRUE(dtls_srtp_transport2_->SendRtcpPacket(&rtcp_packet2to1, options,
175 cricket::PF_SRTP_BYPASS));
176 ASSERT_TRUE(transport_observer1_.last_recv_rtcp_packet().data());
177 EXPECT_EQ(0, memcmp(transport_observer1_.last_recv_rtcp_packet().data(),
178 kRtcpReport, rtcp_len));
179 EXPECT_EQ(prev_received_packets + 1, transport_observer1_.rtcp_count());
180 }
181
SendRecvRtpPacketsWithHeaderExtension(const std::vector<int> & encrypted_header_ids)182 void SendRecvRtpPacketsWithHeaderExtension(
183 const std::vector<int>& encrypted_header_ids) {
184 ASSERT_TRUE(dtls_srtp_transport1_);
185 ASSERT_TRUE(dtls_srtp_transport2_);
186 ASSERT_TRUE(dtls_srtp_transport1_->IsSrtpActive());
187 ASSERT_TRUE(dtls_srtp_transport2_->IsSrtpActive());
188
189 size_t rtp_len = sizeof(kPcmuFrameWithExtensions);
190 size_t packet_size = rtp_len + kRtpAuthTagLen;
191 rtc::Buffer rtp_packet_buffer(packet_size);
192 char* rtp_packet_data = rtp_packet_buffer.data<char>();
193 memcpy(rtp_packet_data, kPcmuFrameWithExtensions, rtp_len);
194 // In order to be able to run this test function multiple times we can not
195 // use the same sequence number twice. Increase the sequence number by one.
196 rtc::SetBE16(reinterpret_cast<uint8_t*>(rtp_packet_data) + 2,
197 ++sequence_number_);
198 rtc::CopyOnWriteBuffer rtp_packet1to2(rtp_packet_data, rtp_len,
199 packet_size);
200 rtc::CopyOnWriteBuffer rtp_packet2to1(rtp_packet_data, rtp_len,
201 packet_size);
202
203 char original_rtp_data[sizeof(kPcmuFrameWithExtensions)];
204 memcpy(original_rtp_data, rtp_packet_data, rtp_len);
205
206 rtc::PacketOptions options;
207 // Send a packet from `srtp_transport1_` to `srtp_transport2_` and verify
208 // that the packet can be successfully received and decrypted.
209 ASSERT_TRUE(dtls_srtp_transport1_->SendRtpPacket(&rtp_packet1to2, options,
210 cricket::PF_SRTP_BYPASS));
211 ASSERT_TRUE(transport_observer2_.last_recv_rtp_packet().data());
212 EXPECT_EQ(0, memcmp(transport_observer2_.last_recv_rtp_packet().data(),
213 original_rtp_data, rtp_len));
214 // Get the encrypted packet from underneath packet transport and verify the
215 // data and header extension are actually encrypted.
216 auto fake_dtls_transport = static_cast<FakeDtlsTransport*>(
217 dtls_srtp_transport1_->rtp_packet_transport());
218 auto fake_ice_transport =
219 static_cast<FakeIceTransport*>(fake_dtls_transport->ice_transport());
220 EXPECT_NE(0, memcmp(fake_ice_transport->last_sent_packet().data(),
221 original_rtp_data, rtp_len));
222 CompareHeaderExtensions(reinterpret_cast<const char*>(
223 fake_ice_transport->last_sent_packet().data()),
224 fake_ice_transport->last_sent_packet().size(),
225 original_rtp_data, rtp_len, encrypted_header_ids,
226 false);
227
228 // Do the same thing in the opposite direction.
229 ASSERT_TRUE(dtls_srtp_transport2_->SendRtpPacket(&rtp_packet2to1, options,
230 cricket::PF_SRTP_BYPASS));
231 ASSERT_TRUE(transport_observer1_.last_recv_rtp_packet().data());
232 EXPECT_EQ(0, memcmp(transport_observer1_.last_recv_rtp_packet().data(),
233 original_rtp_data, rtp_len));
234 // Get the encrypted packet from underneath packet transport and verify the
235 // data and header extension are actually encrypted.
236 fake_dtls_transport = static_cast<FakeDtlsTransport*>(
237 dtls_srtp_transport2_->rtp_packet_transport());
238 fake_ice_transport =
239 static_cast<FakeIceTransport*>(fake_dtls_transport->ice_transport());
240 EXPECT_NE(0, memcmp(fake_ice_transport->last_sent_packet().data(),
241 original_rtp_data, rtp_len));
242 CompareHeaderExtensions(reinterpret_cast<const char*>(
243 fake_ice_transport->last_sent_packet().data()),
244 fake_ice_transport->last_sent_packet().size(),
245 original_rtp_data, rtp_len, encrypted_header_ids,
246 false);
247 }
248
SendRecvPackets()249 void SendRecvPackets() {
250 SendRecvRtpPackets();
251 SendRecvRtcpPackets();
252 }
253
254 rtc::AutoThread main_thread_;
255 std::unique_ptr<DtlsSrtpTransport> dtls_srtp_transport1_;
256 std::unique_ptr<DtlsSrtpTransport> dtls_srtp_transport2_;
257 webrtc::TransportObserver transport_observer1_;
258 webrtc::TransportObserver transport_observer2_;
259
260 int sequence_number_ = 0;
261 webrtc::test::ScopedKeyValueConfig field_trials_;
262 };
263
264 // Tests that if RTCP muxing is enabled and transports are set after RTP
265 // transport finished the handshake, SRTP is set up.
TEST_F(DtlsSrtpTransportTest,SetTransportsAfterHandshakeCompleteWithRtcpMux)266 TEST_F(DtlsSrtpTransportTest, SetTransportsAfterHandshakeCompleteWithRtcpMux) {
267 auto rtp_dtls1 = std::make_unique<FakeDtlsTransport>(
268 "video", cricket::ICE_CANDIDATE_COMPONENT_RTP);
269 auto rtp_dtls2 = std::make_unique<FakeDtlsTransport>(
270 "video", cricket::ICE_CANDIDATE_COMPONENT_RTP);
271
272 MakeDtlsSrtpTransports(rtp_dtls1.get(), nullptr, rtp_dtls2.get(), nullptr,
273 /*rtcp_mux_enabled=*/true);
274
275 auto rtp_dtls3 = std::make_unique<FakeDtlsTransport>(
276 "audio", cricket::ICE_CANDIDATE_COMPONENT_RTP);
277 auto rtp_dtls4 = std::make_unique<FakeDtlsTransport>(
278 "audio", cricket::ICE_CANDIDATE_COMPONENT_RTP);
279
280 CompleteDtlsHandshake(rtp_dtls3.get(), rtp_dtls4.get());
281
282 dtls_srtp_transport1_->SetDtlsTransports(rtp_dtls3.get(), nullptr);
283 dtls_srtp_transport2_->SetDtlsTransports(rtp_dtls4.get(), nullptr);
284
285 SendRecvPackets();
286 }
287
288 // Tests that if RTCP muxing is not enabled and transports are set after both
289 // RTP and RTCP transports finished the handshake, SRTP is set up.
TEST_F(DtlsSrtpTransportTest,SetTransportsAfterHandshakeCompleteWithoutRtcpMux)290 TEST_F(DtlsSrtpTransportTest,
291 SetTransportsAfterHandshakeCompleteWithoutRtcpMux) {
292 auto rtp_dtls1 = std::make_unique<FakeDtlsTransport>(
293 "video", cricket::ICE_CANDIDATE_COMPONENT_RTP);
294 auto rtcp_dtls1 = std::make_unique<FakeDtlsTransport>(
295 "video", cricket::ICE_CANDIDATE_COMPONENT_RTCP);
296 auto rtp_dtls2 = std::make_unique<FakeDtlsTransport>(
297 "video", cricket::ICE_CANDIDATE_COMPONENT_RTP);
298 auto rtcp_dtls2 = std::make_unique<FakeDtlsTransport>(
299 "video", cricket::ICE_CANDIDATE_COMPONENT_RTCP);
300
301 MakeDtlsSrtpTransports(rtp_dtls1.get(), rtcp_dtls1.get(), rtp_dtls2.get(),
302 rtcp_dtls2.get(), /*rtcp_mux_enabled=*/false);
303
304 auto rtp_dtls3 = std::make_unique<FakeDtlsTransport>(
305 "audio", cricket::ICE_CANDIDATE_COMPONENT_RTP);
306 auto rtcp_dtls3 = std::make_unique<FakeDtlsTransport>(
307 "audio", cricket::ICE_CANDIDATE_COMPONENT_RTCP);
308 auto rtp_dtls4 = std::make_unique<FakeDtlsTransport>(
309 "audio", cricket::ICE_CANDIDATE_COMPONENT_RTP);
310 auto rtcp_dtls4 = std::make_unique<FakeDtlsTransport>(
311 "audio", cricket::ICE_CANDIDATE_COMPONENT_RTCP);
312 CompleteDtlsHandshake(rtp_dtls3.get(), rtp_dtls4.get());
313 CompleteDtlsHandshake(rtcp_dtls3.get(), rtcp_dtls4.get());
314
315 dtls_srtp_transport1_->SetDtlsTransports(rtp_dtls3.get(), rtcp_dtls3.get());
316 dtls_srtp_transport2_->SetDtlsTransports(rtp_dtls4.get(), rtcp_dtls4.get());
317
318 SendRecvPackets();
319 }
320
321 // Tests if RTCP muxing is enabled, SRTP is set up as soon as the RTP DTLS
322 // handshake is finished.
TEST_F(DtlsSrtpTransportTest,SetTransportsBeforeHandshakeCompleteWithRtcpMux)323 TEST_F(DtlsSrtpTransportTest, SetTransportsBeforeHandshakeCompleteWithRtcpMux) {
324 auto rtp_dtls1 = std::make_unique<FakeDtlsTransport>(
325 "audio", cricket::ICE_CANDIDATE_COMPONENT_RTP);
326 auto rtcp_dtls1 = std::make_unique<FakeDtlsTransport>(
327 "audio", cricket::ICE_CANDIDATE_COMPONENT_RTCP);
328 auto rtp_dtls2 = std::make_unique<FakeDtlsTransport>(
329 "audio", cricket::ICE_CANDIDATE_COMPONENT_RTP);
330 auto rtcp_dtls2 = std::make_unique<FakeDtlsTransport>(
331 "audio", cricket::ICE_CANDIDATE_COMPONENT_RTCP);
332
333 MakeDtlsSrtpTransports(rtp_dtls1.get(), rtcp_dtls1.get(), rtp_dtls2.get(),
334 rtcp_dtls2.get(),
335 /*rtcp_mux_enabled=*/false);
336
337 dtls_srtp_transport1_->SetRtcpMuxEnabled(true);
338 dtls_srtp_transport2_->SetRtcpMuxEnabled(true);
339 CompleteDtlsHandshake(rtp_dtls1.get(), rtp_dtls2.get());
340 SendRecvPackets();
341 }
342
343 // Tests if RTCP muxing is not enabled, SRTP is set up when both the RTP and
344 // RTCP DTLS handshake are finished.
TEST_F(DtlsSrtpTransportTest,SetTransportsBeforeHandshakeCompleteWithoutRtcpMux)345 TEST_F(DtlsSrtpTransportTest,
346 SetTransportsBeforeHandshakeCompleteWithoutRtcpMux) {
347 auto rtp_dtls1 = std::make_unique<FakeDtlsTransport>(
348 "audio", cricket::ICE_CANDIDATE_COMPONENT_RTP);
349 auto rtcp_dtls1 = std::make_unique<FakeDtlsTransport>(
350 "audio", cricket::ICE_CANDIDATE_COMPONENT_RTCP);
351 auto rtp_dtls2 = std::make_unique<FakeDtlsTransport>(
352 "audio", cricket::ICE_CANDIDATE_COMPONENT_RTP);
353 auto rtcp_dtls2 = std::make_unique<FakeDtlsTransport>(
354 "audio", cricket::ICE_CANDIDATE_COMPONENT_RTCP);
355
356 MakeDtlsSrtpTransports(rtp_dtls1.get(), rtcp_dtls1.get(), rtp_dtls2.get(),
357 rtcp_dtls2.get(), /*rtcp_mux_enabled=*/false);
358
359 CompleteDtlsHandshake(rtp_dtls1.get(), rtp_dtls2.get());
360 EXPECT_FALSE(dtls_srtp_transport1_->IsSrtpActive());
361 EXPECT_FALSE(dtls_srtp_transport2_->IsSrtpActive());
362 CompleteDtlsHandshake(rtcp_dtls1.get(), rtcp_dtls2.get());
363 SendRecvPackets();
364 }
365
366 // Tests that if the DtlsTransport underneath is changed, the previous DTLS-SRTP
367 // context will be reset and will be re-setup once the new transports' handshake
368 // complete.
TEST_F(DtlsSrtpTransportTest,DtlsSrtpResetAfterDtlsTransportChange)369 TEST_F(DtlsSrtpTransportTest, DtlsSrtpResetAfterDtlsTransportChange) {
370 auto rtp_dtls1 = std::make_unique<FakeDtlsTransport>(
371 "audio", cricket::ICE_CANDIDATE_COMPONENT_RTP);
372 auto rtp_dtls2 = std::make_unique<FakeDtlsTransport>(
373 "audio", cricket::ICE_CANDIDATE_COMPONENT_RTP);
374
375 MakeDtlsSrtpTransports(rtp_dtls1.get(), nullptr, rtp_dtls2.get(), nullptr,
376 /*rtcp_mux_enabled=*/true);
377
378 CompleteDtlsHandshake(rtp_dtls1.get(), rtp_dtls2.get());
379 EXPECT_TRUE(dtls_srtp_transport1_->IsSrtpActive());
380 EXPECT_TRUE(dtls_srtp_transport2_->IsSrtpActive());
381
382 auto rtp_dtls3 = std::make_unique<FakeDtlsTransport>(
383 "audio", cricket::ICE_CANDIDATE_COMPONENT_RTP);
384 auto rtp_dtls4 = std::make_unique<FakeDtlsTransport>(
385 "audio", cricket::ICE_CANDIDATE_COMPONENT_RTP);
386
387 // The previous context is reset.
388 dtls_srtp_transport1_->SetDtlsTransports(rtp_dtls3.get(), nullptr);
389 dtls_srtp_transport2_->SetDtlsTransports(rtp_dtls4.get(), nullptr);
390 EXPECT_FALSE(dtls_srtp_transport1_->IsSrtpActive());
391 EXPECT_FALSE(dtls_srtp_transport2_->IsSrtpActive());
392
393 // Re-setup.
394 CompleteDtlsHandshake(rtp_dtls3.get(), rtp_dtls4.get());
395 SendRecvPackets();
396 }
397
398 // Tests if only the RTP DTLS handshake complete, and then RTCP muxing is
399 // enabled, SRTP is set up.
TEST_F(DtlsSrtpTransportTest,RtcpMuxEnabledAfterRtpTransportHandshakeComplete)400 TEST_F(DtlsSrtpTransportTest,
401 RtcpMuxEnabledAfterRtpTransportHandshakeComplete) {
402 auto rtp_dtls1 = std::make_unique<FakeDtlsTransport>(
403 "audio", cricket::ICE_CANDIDATE_COMPONENT_RTP);
404 auto rtcp_dtls1 = std::make_unique<FakeDtlsTransport>(
405 "audio", cricket::ICE_CANDIDATE_COMPONENT_RTCP);
406 auto rtp_dtls2 = std::make_unique<FakeDtlsTransport>(
407 "audio", cricket::ICE_CANDIDATE_COMPONENT_RTP);
408 auto rtcp_dtls2 = std::make_unique<FakeDtlsTransport>(
409 "audio", cricket::ICE_CANDIDATE_COMPONENT_RTCP);
410
411 MakeDtlsSrtpTransports(rtp_dtls1.get(), rtcp_dtls1.get(), rtp_dtls2.get(),
412 rtcp_dtls2.get(), /*rtcp_mux_enabled=*/false);
413
414 CompleteDtlsHandshake(rtp_dtls1.get(), rtp_dtls2.get());
415 // Inactive because the RTCP transport handshake didn't complete.
416 EXPECT_FALSE(dtls_srtp_transport1_->IsSrtpActive());
417 EXPECT_FALSE(dtls_srtp_transport2_->IsSrtpActive());
418
419 dtls_srtp_transport1_->SetRtcpMuxEnabled(true);
420 dtls_srtp_transport2_->SetRtcpMuxEnabled(true);
421 // The transports should be active and be able to send packets when the
422 // RTCP muxing is enabled.
423 SendRecvPackets();
424 }
425
426 // Tests that when SetSend/RecvEncryptedHeaderExtensionIds is called, the SRTP
427 // sessions are updated with new encryped header extension IDs immediately.
TEST_F(DtlsSrtpTransportTest,EncryptedHeaderExtensionIdUpdated)428 TEST_F(DtlsSrtpTransportTest, EncryptedHeaderExtensionIdUpdated) {
429 auto rtp_dtls1 = std::make_unique<FakeDtlsTransport>(
430 "audio", cricket::ICE_CANDIDATE_COMPONENT_RTP);
431 auto rtp_dtls2 = std::make_unique<FakeDtlsTransport>(
432 "audio", cricket::ICE_CANDIDATE_COMPONENT_RTP);
433
434 MakeDtlsSrtpTransports(rtp_dtls1.get(), nullptr, rtp_dtls2.get(), nullptr,
435 /*rtcp_mux_enabled=*/true);
436 CompleteDtlsHandshake(rtp_dtls1.get(), rtp_dtls2.get());
437
438 std::vector<int> encrypted_headers;
439 encrypted_headers.push_back(kHeaderExtensionIDs[0]);
440 encrypted_headers.push_back(kHeaderExtensionIDs[1]);
441
442 dtls_srtp_transport1_->UpdateSendEncryptedHeaderExtensionIds(
443 encrypted_headers);
444 dtls_srtp_transport1_->UpdateRecvEncryptedHeaderExtensionIds(
445 encrypted_headers);
446 dtls_srtp_transport2_->UpdateSendEncryptedHeaderExtensionIds(
447 encrypted_headers);
448 dtls_srtp_transport2_->UpdateRecvEncryptedHeaderExtensionIds(
449 encrypted_headers);
450 }
451
452 // Tests if RTCP muxing is enabled. DtlsSrtpTransport is ready to send once the
453 // RTP DtlsTransport is ready.
TEST_F(DtlsSrtpTransportTest,SignalReadyToSendFiredWithRtcpMux)454 TEST_F(DtlsSrtpTransportTest, SignalReadyToSendFiredWithRtcpMux) {
455 auto rtp_dtls1 = std::make_unique<FakeDtlsTransport>(
456 "audio", cricket::ICE_CANDIDATE_COMPONENT_RTP);
457 auto rtp_dtls2 = std::make_unique<FakeDtlsTransport>(
458 "audio", cricket::ICE_CANDIDATE_COMPONENT_RTP);
459
460 MakeDtlsSrtpTransports(rtp_dtls1.get(), nullptr, rtp_dtls2.get(), nullptr,
461 /*rtcp_mux_enabled=*/true);
462
463 rtp_dtls1->SetDestination(rtp_dtls2.get());
464 EXPECT_TRUE(transport_observer1_.ready_to_send());
465 EXPECT_TRUE(transport_observer2_.ready_to_send());
466 }
467
468 // Tests if RTCP muxing is not enabled. DtlsSrtpTransport is ready to send once
469 // both the RTP and RTCP DtlsTransport are ready.
TEST_F(DtlsSrtpTransportTest,SignalReadyToSendFiredWithoutRtcpMux)470 TEST_F(DtlsSrtpTransportTest, SignalReadyToSendFiredWithoutRtcpMux) {
471 auto rtp_dtls1 = std::make_unique<FakeDtlsTransport>(
472 "audio", cricket::ICE_CANDIDATE_COMPONENT_RTP);
473 auto rtcp_dtls1 = std::make_unique<FakeDtlsTransport>(
474 "audio", cricket::ICE_CANDIDATE_COMPONENT_RTCP);
475 auto rtp_dtls2 = std::make_unique<FakeDtlsTransport>(
476 "audio", cricket::ICE_CANDIDATE_COMPONENT_RTP);
477 auto rtcp_dtls2 = std::make_unique<FakeDtlsTransport>(
478 "audio", cricket::ICE_CANDIDATE_COMPONENT_RTCP);
479
480 MakeDtlsSrtpTransports(rtp_dtls1.get(), rtcp_dtls1.get(), rtp_dtls2.get(),
481 rtcp_dtls2.get(), /*rtcp_mux_enabled=*/false);
482
483 rtp_dtls1->SetDestination(rtp_dtls2.get());
484 EXPECT_FALSE(transport_observer1_.ready_to_send());
485 EXPECT_FALSE(transport_observer2_.ready_to_send());
486
487 rtcp_dtls1->SetDestination(rtcp_dtls2.get());
488 EXPECT_TRUE(transport_observer1_.ready_to_send());
489 EXPECT_TRUE(transport_observer2_.ready_to_send());
490 }
491
492 // Test that if an endpoint "fully" enables RTCP mux, setting the RTCP
493 // transport to null, it *doesn't* reset its SRTP context. That would cause the
494 // ROC and SRTCP index to be reset, causing replay detection and other errors
495 // when attempting to unprotect packets.
496 // Regression test for bugs.webrtc.org/8996
TEST_F(DtlsSrtpTransportTest,SrtpSessionNotResetWhenRtcpTransportRemoved)497 TEST_F(DtlsSrtpTransportTest, SrtpSessionNotResetWhenRtcpTransportRemoved) {
498 auto rtp_dtls1 = std::make_unique<FakeDtlsTransport>(
499 "audio", cricket::ICE_CANDIDATE_COMPONENT_RTP);
500 auto rtcp_dtls1 = std::make_unique<FakeDtlsTransport>(
501 "audio", cricket::ICE_CANDIDATE_COMPONENT_RTCP);
502 auto rtp_dtls2 = std::make_unique<FakeDtlsTransport>(
503 "audio", cricket::ICE_CANDIDATE_COMPONENT_RTP);
504 auto rtcp_dtls2 = std::make_unique<FakeDtlsTransport>(
505 "audio", cricket::ICE_CANDIDATE_COMPONENT_RTCP);
506
507 MakeDtlsSrtpTransports(rtp_dtls1.get(), rtcp_dtls1.get(), rtp_dtls2.get(),
508 rtcp_dtls2.get(), /*rtcp_mux_enabled=*/true);
509 CompleteDtlsHandshake(rtp_dtls1.get(), rtp_dtls2.get());
510 CompleteDtlsHandshake(rtcp_dtls1.get(), rtcp_dtls2.get());
511
512 // Send some RTCP packets, causing the SRTCP index to be incremented.
513 SendRecvRtcpPackets();
514
515 // Set RTCP transport to null, which previously would trigger this problem.
516 dtls_srtp_transport1_->SetDtlsTransports(rtp_dtls1.get(), nullptr);
517
518 // Attempt to send more RTCP packets. If the issue occurred, one side would
519 // reset its context while the other would not, causing replay detection
520 // errors when a packet with a duplicate SRTCP index is received.
521 SendRecvRtcpPackets();
522 }
523
524 // Tests that RTCP packets can be sent and received if both sides actively reset
525 // the SRTP parameters with the `active_reset_srtp_params_` flag.
TEST_F(DtlsSrtpTransportTest,ActivelyResetSrtpParams)526 TEST_F(DtlsSrtpTransportTest, ActivelyResetSrtpParams) {
527 auto rtp_dtls1 = std::make_unique<FakeDtlsTransport>(
528 "audio", cricket::ICE_CANDIDATE_COMPONENT_RTP);
529 auto rtcp_dtls1 = std::make_unique<FakeDtlsTransport>(
530 "audio", cricket::ICE_CANDIDATE_COMPONENT_RTCP);
531 auto rtp_dtls2 = std::make_unique<FakeDtlsTransport>(
532 "audio", cricket::ICE_CANDIDATE_COMPONENT_RTP);
533 auto rtcp_dtls2 = std::make_unique<FakeDtlsTransport>(
534 "audio", cricket::ICE_CANDIDATE_COMPONENT_RTCP);
535
536 MakeDtlsSrtpTransports(rtp_dtls1.get(), rtcp_dtls1.get(), rtp_dtls2.get(),
537 rtcp_dtls2.get(), /*rtcp_mux_enabled=*/true);
538 CompleteDtlsHandshake(rtp_dtls1.get(), rtp_dtls2.get());
539 CompleteDtlsHandshake(rtcp_dtls1.get(), rtcp_dtls2.get());
540
541 // Send some RTCP packets, causing the SRTCP index to be incremented.
542 SendRecvRtcpPackets();
543
544 // Only set the `active_reset_srtp_params_` flag to be true one side.
545 dtls_srtp_transport1_->SetActiveResetSrtpParams(true);
546 // Set RTCP transport to null to trigger the SRTP parameters update.
547 dtls_srtp_transport1_->SetDtlsTransports(rtp_dtls1.get(), nullptr);
548 dtls_srtp_transport2_->SetDtlsTransports(rtp_dtls2.get(), nullptr);
549
550 // Sending some RTCP packets.
551 size_t rtcp_len = sizeof(kRtcpReport);
552 size_t packet_size = rtcp_len + 4 + kRtpAuthTagLen;
553 rtc::Buffer rtcp_packet_buffer(packet_size);
554 rtc::CopyOnWriteBuffer rtcp_packet(kRtcpReport, rtcp_len, packet_size);
555 int prev_received_packets = transport_observer2_.rtcp_count();
556 ASSERT_TRUE(dtls_srtp_transport1_->SendRtcpPacket(
557 &rtcp_packet, rtc::PacketOptions(), cricket::PF_SRTP_BYPASS));
558 // The RTCP packet is not exepected to be received because the SRTP parameters
559 // are only reset on one side and the SRTCP index is out of sync.
560 EXPECT_EQ(prev_received_packets, transport_observer2_.rtcp_count());
561
562 // Set the flag to be true on the other side.
563 dtls_srtp_transport2_->SetActiveResetSrtpParams(true);
564 // Set RTCP transport to null to trigger the SRTP parameters update.
565 dtls_srtp_transport1_->SetDtlsTransports(rtp_dtls1.get(), nullptr);
566 dtls_srtp_transport2_->SetDtlsTransports(rtp_dtls2.get(), nullptr);
567
568 // RTCP packets flow is expected to work just fine.
569 SendRecvRtcpPackets();
570 }
571