1 /*
2 * Copyright 2011 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 "p2p/base/dtls_transport.h"
12
13 #include <algorithm>
14 #include <memory>
15 #include <set>
16 #include <utility>
17
18 #include "p2p/base/fake_ice_transport.h"
19 #include "p2p/base/packet_transport_internal.h"
20 #include "rtc_base/checks.h"
21 #include "rtc_base/dscp.h"
22 #include "rtc_base/gunit.h"
23 #include "rtc_base/helpers.h"
24 #include "rtc_base/rtc_certificate.h"
25 #include "rtc_base/ssl_adapter.h"
26 #include "rtc_base/ssl_identity.h"
27 #include "rtc_base/ssl_stream_adapter.h"
28
29 #define MAYBE_SKIP_TEST(feature) \
30 if (!(rtc::SSLStreamAdapter::feature())) { \
31 RTC_LOG(LS_INFO) << #feature " feature disabled... skipping"; \
32 return; \
33 }
34
35 namespace cricket {
36
37 static const size_t kPacketNumOffset = 8;
38 static const size_t kPacketHeaderLen = 12;
39 static const int kFakePacketId = 0x1234;
40 static const int kTimeout = 10000;
41
IsRtpLeadByte(uint8_t b)42 static bool IsRtpLeadByte(uint8_t b) {
43 return ((b & 0xC0) == 0x80);
44 }
45
46 // |modify_digest| is used to set modified fingerprints that are meant to fail
47 // validation.
SetRemoteFingerprintFromCert(DtlsTransport * transport,const rtc::scoped_refptr<rtc::RTCCertificate> & cert,bool modify_digest=false)48 void SetRemoteFingerprintFromCert(
49 DtlsTransport* transport,
50 const rtc::scoped_refptr<rtc::RTCCertificate>& cert,
51 bool modify_digest = false) {
52 std::unique_ptr<rtc::SSLFingerprint> fingerprint =
53 rtc::SSLFingerprint::CreateFromCertificate(*cert);
54 if (modify_digest) {
55 ++fingerprint->digest[0];
56 }
57 // Even if digest is verified to be incorrect, should fail asynchrnously.
58 EXPECT_TRUE(transport->SetRemoteFingerprint(
59 fingerprint->algorithm,
60 reinterpret_cast<const uint8_t*>(fingerprint->digest.data()),
61 fingerprint->digest.size()));
62 }
63
64 class DtlsTestClient : public sigslot::has_slots<> {
65 public:
DtlsTestClient(const std::string & name)66 explicit DtlsTestClient(const std::string& name) : name_(name) {}
CreateCertificate(rtc::KeyType key_type)67 void CreateCertificate(rtc::KeyType key_type) {
68 certificate_ =
69 rtc::RTCCertificate::Create(rtc::SSLIdentity::Create(name_, key_type));
70 }
certificate()71 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate() {
72 return certificate_;
73 }
SetupMaxProtocolVersion(rtc::SSLProtocolVersion version)74 void SetupMaxProtocolVersion(rtc::SSLProtocolVersion version) {
75 ssl_max_version_ = version;
76 }
77 // Set up fake ICE transport and real DTLS transport under test.
SetupTransports(IceRole role,int async_delay_ms=0)78 void SetupTransports(IceRole role, int async_delay_ms = 0) {
79 fake_ice_transport_.reset(new FakeIceTransport("fake", 0));
80 fake_ice_transport_->SetAsync(true);
81 fake_ice_transport_->SetAsyncDelay(async_delay_ms);
82 fake_ice_transport_->SetIceRole(role);
83 fake_ice_transport_->SetIceTiebreaker((role == ICEROLE_CONTROLLING) ? 1
84 : 2);
85 // Hook the raw packets so that we can verify they are encrypted.
86 fake_ice_transport_->SignalReadPacket.connect(
87 this, &DtlsTestClient::OnFakeIceTransportReadPacket);
88
89 dtls_transport_ = std::make_unique<DtlsTransport>(fake_ice_transport_.get(),
90 webrtc::CryptoOptions(),
91 /*event_log=*/nullptr);
92 dtls_transport_->SetSslMaxProtocolVersion(ssl_max_version_);
93 // Note: Certificate may be null here if testing passthrough.
94 dtls_transport_->SetLocalCertificate(certificate_);
95 dtls_transport_->SignalWritableState.connect(
96 this, &DtlsTestClient::OnTransportWritableState);
97 dtls_transport_->SignalReadPacket.connect(
98 this, &DtlsTestClient::OnTransportReadPacket);
99 dtls_transport_->SignalSentPacket.connect(
100 this, &DtlsTestClient::OnTransportSentPacket);
101 }
102
fake_ice_transport()103 FakeIceTransport* fake_ice_transport() {
104 return static_cast<FakeIceTransport*>(dtls_transport_->ice_transport());
105 }
106
dtls_transport()107 DtlsTransport* dtls_transport() { return dtls_transport_.get(); }
108
109 // Simulate fake ICE transports connecting.
Connect(DtlsTestClient * peer,bool asymmetric)110 bool Connect(DtlsTestClient* peer, bool asymmetric) {
111 fake_ice_transport()->SetDestination(peer->fake_ice_transport(),
112 asymmetric);
113 return true;
114 }
115
received_dtls_client_hellos() const116 int received_dtls_client_hellos() const {
117 return received_dtls_client_hellos_;
118 }
119
received_dtls_server_hellos() const120 int received_dtls_server_hellos() const {
121 return received_dtls_server_hellos_;
122 }
123
CheckRole(rtc::SSLRole role)124 void CheckRole(rtc::SSLRole role) {
125 if (role == rtc::SSL_CLIENT) {
126 ASSERT_EQ(0, received_dtls_client_hellos_);
127 ASSERT_GT(received_dtls_server_hellos_, 0);
128 } else {
129 ASSERT_GT(received_dtls_client_hellos_, 0);
130 ASSERT_EQ(0, received_dtls_server_hellos_);
131 }
132 }
133
CheckSrtp(int expected_crypto_suite)134 void CheckSrtp(int expected_crypto_suite) {
135 int crypto_suite;
136 bool rv = dtls_transport_->GetSrtpCryptoSuite(&crypto_suite);
137 if (dtls_transport_->IsDtlsActive() && expected_crypto_suite) {
138 ASSERT_TRUE(rv);
139 ASSERT_EQ(crypto_suite, expected_crypto_suite);
140 } else {
141 ASSERT_FALSE(rv);
142 }
143 }
144
CheckSsl()145 void CheckSsl() {
146 int cipher;
147 bool rv = dtls_transport_->GetSslCipherSuite(&cipher);
148 if (dtls_transport_->IsDtlsActive()) {
149 ASSERT_TRUE(rv);
150 EXPECT_TRUE(
151 rtc::SSLStreamAdapter::IsAcceptableCipher(cipher, rtc::KT_DEFAULT));
152 } else {
153 ASSERT_FALSE(rv);
154 }
155 }
156
SendPackets(size_t size,size_t count,bool srtp)157 void SendPackets(size_t size, size_t count, bool srtp) {
158 std::unique_ptr<char[]> packet(new char[size]);
159 size_t sent = 0;
160 do {
161 // Fill the packet with a known value and a sequence number to check
162 // against, and make sure that it doesn't look like DTLS.
163 memset(packet.get(), sent & 0xff, size);
164 packet[0] = (srtp) ? 0x80 : 0x00;
165 rtc::SetBE32(packet.get() + kPacketNumOffset,
166 static_cast<uint32_t>(sent));
167
168 // Only set the bypass flag if we've activated DTLS.
169 int flags = (certificate_ && srtp) ? PF_SRTP_BYPASS : 0;
170 rtc::PacketOptions packet_options;
171 packet_options.packet_id = kFakePacketId;
172 int rv = dtls_transport_->SendPacket(packet.get(), size, packet_options,
173 flags);
174 ASSERT_GT(rv, 0);
175 ASSERT_EQ(size, static_cast<size_t>(rv));
176 ++sent;
177 } while (sent < count);
178 }
179
SendInvalidSrtpPacket(size_t size)180 int SendInvalidSrtpPacket(size_t size) {
181 std::unique_ptr<char[]> packet(new char[size]);
182 // Fill the packet with 0 to form an invalid SRTP packet.
183 memset(packet.get(), 0, size);
184
185 rtc::PacketOptions packet_options;
186 return dtls_transport_->SendPacket(packet.get(), size, packet_options,
187 PF_SRTP_BYPASS);
188 }
189
ExpectPackets(size_t size)190 void ExpectPackets(size_t size) {
191 packet_size_ = size;
192 received_.clear();
193 }
194
NumPacketsReceived()195 size_t NumPacketsReceived() { return received_.size(); }
196
197 // Inverse of SendPackets.
VerifyPacket(const char * data,size_t size,uint32_t * out_num)198 bool VerifyPacket(const char* data, size_t size, uint32_t* out_num) {
199 if (size != packet_size_ ||
200 (data[0] != 0 && static_cast<uint8_t>(data[0]) != 0x80)) {
201 return false;
202 }
203 uint32_t packet_num = rtc::GetBE32(data + kPacketNumOffset);
204 for (size_t i = kPacketHeaderLen; i < size; ++i) {
205 if (static_cast<uint8_t>(data[i]) != (packet_num & 0xff)) {
206 return false;
207 }
208 }
209 if (out_num) {
210 *out_num = packet_num;
211 }
212 return true;
213 }
VerifyEncryptedPacket(const char * data,size_t size)214 bool VerifyEncryptedPacket(const char* data, size_t size) {
215 // This is an encrypted data packet; let's make sure it's mostly random;
216 // less than 10% of the bytes should be equal to the cleartext packet.
217 if (size <= packet_size_) {
218 return false;
219 }
220 uint32_t packet_num = rtc::GetBE32(data + kPacketNumOffset);
221 int num_matches = 0;
222 for (size_t i = kPacketNumOffset; i < size; ++i) {
223 if (static_cast<uint8_t>(data[i]) == (packet_num & 0xff)) {
224 ++num_matches;
225 }
226 }
227 return (num_matches < ((static_cast<int>(size) - 5) / 10));
228 }
229
230 // Transport callbacks
OnTransportWritableState(rtc::PacketTransportInternal * transport)231 void OnTransportWritableState(rtc::PacketTransportInternal* transport) {
232 RTC_LOG(LS_INFO) << name_ << ": Transport '" << transport->transport_name()
233 << "' is writable";
234 }
235
OnTransportReadPacket(rtc::PacketTransportInternal * transport,const char * data,size_t size,const int64_t &,int flags)236 void OnTransportReadPacket(rtc::PacketTransportInternal* transport,
237 const char* data,
238 size_t size,
239 const int64_t& /* packet_time_us */,
240 int flags) {
241 uint32_t packet_num = 0;
242 ASSERT_TRUE(VerifyPacket(data, size, &packet_num));
243 received_.insert(packet_num);
244 // Only DTLS-SRTP packets should have the bypass flag set.
245 int expected_flags =
246 (certificate_ && IsRtpLeadByte(data[0])) ? PF_SRTP_BYPASS : 0;
247 ASSERT_EQ(expected_flags, flags);
248 }
249
OnTransportSentPacket(rtc::PacketTransportInternal * transport,const rtc::SentPacket & sent_packet)250 void OnTransportSentPacket(rtc::PacketTransportInternal* transport,
251 const rtc::SentPacket& sent_packet) {
252 sent_packet_ = sent_packet;
253 }
254
sent_packet() const255 rtc::SentPacket sent_packet() const { return sent_packet_; }
256
257 // Hook into the raw packet stream to make sure DTLS packets are encrypted.
OnFakeIceTransportReadPacket(rtc::PacketTransportInternal * transport,const char * data,size_t size,const int64_t &,int flags)258 void OnFakeIceTransportReadPacket(rtc::PacketTransportInternal* transport,
259 const char* data,
260 size_t size,
261 const int64_t& /* packet_time_us */,
262 int flags) {
263 // Flags shouldn't be set on the underlying Transport packets.
264 ASSERT_EQ(0, flags);
265
266 // Look at the handshake packets to see what role we played.
267 // Check that non-handshake packets are DTLS data or SRTP bypass.
268 if (data[0] == 22 && size > 17) {
269 if (data[13] == 1) {
270 ++received_dtls_client_hellos_;
271 } else if (data[13] == 2) {
272 ++received_dtls_server_hellos_;
273 }
274 } else if (dtls_transport_->IsDtlsActive() &&
275 !(data[0] >= 20 && data[0] <= 22)) {
276 ASSERT_TRUE(data[0] == 23 || IsRtpLeadByte(data[0]));
277 if (data[0] == 23) {
278 ASSERT_TRUE(VerifyEncryptedPacket(data, size));
279 } else if (IsRtpLeadByte(data[0])) {
280 ASSERT_TRUE(VerifyPacket(data, size, NULL));
281 }
282 }
283 }
284
285 private:
286 std::string name_;
287 rtc::scoped_refptr<rtc::RTCCertificate> certificate_;
288 std::unique_ptr<FakeIceTransport> fake_ice_transport_;
289 std::unique_ptr<DtlsTransport> dtls_transport_;
290 size_t packet_size_ = 0u;
291 std::set<int> received_;
292 rtc::SSLProtocolVersion ssl_max_version_ = rtc::SSL_PROTOCOL_DTLS_12;
293 int received_dtls_client_hellos_ = 0;
294 int received_dtls_server_hellos_ = 0;
295 rtc::SentPacket sent_packet_;
296 };
297
298 // Base class for DtlsTransportTest and DtlsEventOrderingTest, which
299 // inherit from different variants of ::testing::Test.
300 //
301 // Note that this test always uses a FakeClock, due to the |fake_clock_| member
302 // variable.
303 class DtlsTransportTestBase {
304 public:
DtlsTransportTestBase()305 DtlsTransportTestBase() : client1_("P1"), client2_("P2"), use_dtls_(false) {}
306
SetMaxProtocolVersions(rtc::SSLProtocolVersion c1,rtc::SSLProtocolVersion c2)307 void SetMaxProtocolVersions(rtc::SSLProtocolVersion c1,
308 rtc::SSLProtocolVersion c2) {
309 client1_.SetupMaxProtocolVersion(c1);
310 client2_.SetupMaxProtocolVersion(c2);
311 }
312 // If not called, DtlsTransport will be used in SRTP bypass mode.
PrepareDtls(rtc::KeyType key_type)313 void PrepareDtls(rtc::KeyType key_type) {
314 client1_.CreateCertificate(key_type);
315 client2_.CreateCertificate(key_type);
316 use_dtls_ = true;
317 }
318
319 // This test negotiates DTLS parameters before the underlying transports are
320 // writable. DtlsEventOrderingTest is responsible for exercising differerent
321 // orderings.
Connect(bool client1_server=true)322 bool Connect(bool client1_server = true) {
323 Negotiate(client1_server);
324 EXPECT_TRUE(client1_.Connect(&client2_, false));
325
326 EXPECT_TRUE_SIMULATED_WAIT(client1_.dtls_transport()->writable() &&
327 client2_.dtls_transport()->writable(),
328 kTimeout, fake_clock_);
329 if (!client1_.dtls_transport()->writable() ||
330 !client2_.dtls_transport()->writable())
331 return false;
332
333 // Check that we used the right roles.
334 if (use_dtls_) {
335 client1_.CheckRole(client1_server ? rtc::SSL_SERVER : rtc::SSL_CLIENT);
336 client2_.CheckRole(client1_server ? rtc::SSL_CLIENT : rtc::SSL_SERVER);
337 }
338
339 if (use_dtls_) {
340 // Check that we negotiated the right ciphers. Since GCM ciphers are not
341 // negotiated by default, we should end up with SRTP_AES128_CM_SHA1_80.
342 client1_.CheckSrtp(rtc::SRTP_AES128_CM_SHA1_80);
343 client2_.CheckSrtp(rtc::SRTP_AES128_CM_SHA1_80);
344 } else {
345 // If DTLS isn't actually being used, GetSrtpCryptoSuite should return
346 // false.
347 client1_.CheckSrtp(rtc::SRTP_INVALID_CRYPTO_SUITE);
348 client2_.CheckSrtp(rtc::SRTP_INVALID_CRYPTO_SUITE);
349 }
350
351 client1_.CheckSsl();
352 client2_.CheckSsl();
353
354 return true;
355 }
356
Negotiate(bool client1_server=true)357 void Negotiate(bool client1_server = true) {
358 client1_.SetupTransports(ICEROLE_CONTROLLING);
359 client2_.SetupTransports(ICEROLE_CONTROLLED);
360 client1_.dtls_transport()->SetDtlsRole(client1_server ? rtc::SSL_SERVER
361 : rtc::SSL_CLIENT);
362 client2_.dtls_transport()->SetDtlsRole(client1_server ? rtc::SSL_CLIENT
363 : rtc::SSL_SERVER);
364 if (client2_.certificate()) {
365 SetRemoteFingerprintFromCert(client1_.dtls_transport(),
366 client2_.certificate());
367 }
368 if (client1_.certificate()) {
369 SetRemoteFingerprintFromCert(client2_.dtls_transport(),
370 client1_.certificate());
371 }
372 }
373
TestTransfer(size_t size,size_t count,bool srtp)374 void TestTransfer(size_t size, size_t count, bool srtp) {
375 RTC_LOG(LS_INFO) << "Expect packets, size=" << size;
376 client2_.ExpectPackets(size);
377 client1_.SendPackets(size, count, srtp);
378 EXPECT_EQ_SIMULATED_WAIT(count, client2_.NumPacketsReceived(), kTimeout,
379 fake_clock_);
380 }
381
382 protected:
383 rtc::ScopedFakeClock fake_clock_;
384 DtlsTestClient client1_;
385 DtlsTestClient client2_;
386 bool use_dtls_;
387 rtc::SSLProtocolVersion ssl_expected_version_;
388 };
389
390 class DtlsTransportTest : public DtlsTransportTestBase,
391 public ::testing::Test {};
392
393 // Connect without DTLS, and transfer RTP data.
TEST_F(DtlsTransportTest,TestTransferRtp)394 TEST_F(DtlsTransportTest, TestTransferRtp) {
395 ASSERT_TRUE(Connect());
396 TestTransfer(1000, 100, /*srtp=*/false);
397 }
398
399 // Test that the SignalSentPacket signal is wired up.
TEST_F(DtlsTransportTest,TestSignalSentPacket)400 TEST_F(DtlsTransportTest, TestSignalSentPacket) {
401 ASSERT_TRUE(Connect());
402 // Sanity check default value (-1).
403 ASSERT_EQ(client1_.sent_packet().send_time_ms, -1);
404 TestTransfer(1000, 100, false);
405 // Check that we get the expected fake packet ID, and a time of 0 from the
406 // fake clock.
407 EXPECT_EQ(kFakePacketId, client1_.sent_packet().packet_id);
408 EXPECT_GE(client1_.sent_packet().send_time_ms, 0);
409 }
410
411 // Connect without DTLS, and transfer SRTP data.
TEST_F(DtlsTransportTest,TestTransferSrtp)412 TEST_F(DtlsTransportTest, TestTransferSrtp) {
413 ASSERT_TRUE(Connect());
414 TestTransfer(1000, 100, /*srtp=*/true);
415 }
416
417 // Connect with DTLS, and transfer data over DTLS.
TEST_F(DtlsTransportTest,TestTransferDtls)418 TEST_F(DtlsTransportTest, TestTransferDtls) {
419 PrepareDtls(rtc::KT_DEFAULT);
420 ASSERT_TRUE(Connect());
421 TestTransfer(1000, 100, /*srtp=*/false);
422 }
423
424 // Connect with DTLS, combine multiple DTLS records into one packet.
425 // Our DTLS implementation doesn't do this, but other implementations may;
426 // see https://tools.ietf.org/html/rfc6347#section-4.1.1.
427 // This has caused interoperability problems with ORTCLib in the past.
TEST_F(DtlsTransportTest,TestTransferDtlsCombineRecords)428 TEST_F(DtlsTransportTest, TestTransferDtlsCombineRecords) {
429 PrepareDtls(rtc::KT_DEFAULT);
430 ASSERT_TRUE(Connect());
431 // Our DTLS implementation always sends one record per packet, so to simulate
432 // an endpoint that sends multiple records per packet, we configure the fake
433 // ICE transport to combine every two consecutive packets into a single
434 // packet.
435 FakeIceTransport* transport = client1_.fake_ice_transport();
436 transport->combine_outgoing_packets(true);
437 TestTransfer(500, 100, /*srtp=*/false);
438 }
439
440 class DtlsTransportVersionTest
441 : public DtlsTransportTestBase,
442 public ::testing::TestWithParam<
443 ::testing::tuple<rtc::SSLProtocolVersion, rtc::SSLProtocolVersion>> {
444 };
445
446 // Test that an acceptable cipher suite is negotiated when different versions
447 // of DTLS are supported. Note that it's IsAcceptableCipher that does the actual
448 // work.
TEST_P(DtlsTransportVersionTest,TestCipherSuiteNegotiation)449 TEST_P(DtlsTransportVersionTest, TestCipherSuiteNegotiation) {
450 PrepareDtls(rtc::KT_DEFAULT);
451 SetMaxProtocolVersions(::testing::get<0>(GetParam()),
452 ::testing::get<1>(GetParam()));
453 ASSERT_TRUE(Connect());
454 }
455
456 // Will test every combination of 1.0/1.2 on the client and server.
457 INSTANTIATE_TEST_SUITE_P(
458 TestCipherSuiteNegotiation,
459 DtlsTransportVersionTest,
460 ::testing::Combine(::testing::Values(rtc::SSL_PROTOCOL_DTLS_10,
461 rtc::SSL_PROTOCOL_DTLS_12),
462 ::testing::Values(rtc::SSL_PROTOCOL_DTLS_10,
463 rtc::SSL_PROTOCOL_DTLS_12)));
464
465 // Connect with DTLS, negotiating DTLS-SRTP, and transfer SRTP using bypass.
TEST_F(DtlsTransportTest,TestTransferDtlsSrtp)466 TEST_F(DtlsTransportTest, TestTransferDtlsSrtp) {
467 PrepareDtls(rtc::KT_DEFAULT);
468 ASSERT_TRUE(Connect());
469 TestTransfer(1000, 100, /*srtp=*/true);
470 }
471
472 // Connect with DTLS-SRTP, transfer an invalid SRTP packet, and expects -1
473 // returned.
TEST_F(DtlsTransportTest,TestTransferDtlsInvalidSrtpPacket)474 TEST_F(DtlsTransportTest, TestTransferDtlsInvalidSrtpPacket) {
475 PrepareDtls(rtc::KT_DEFAULT);
476 ASSERT_TRUE(Connect());
477 EXPECT_EQ(-1, client1_.SendInvalidSrtpPacket(100));
478 }
479
480 // Create a single transport with DTLS, and send normal data and SRTP data on
481 // it.
TEST_F(DtlsTransportTest,TestTransferDtlsSrtpDemux)482 TEST_F(DtlsTransportTest, TestTransferDtlsSrtpDemux) {
483 PrepareDtls(rtc::KT_DEFAULT);
484 ASSERT_TRUE(Connect());
485 TestTransfer(1000, 100, /*srtp=*/false);
486 TestTransfer(1000, 100, /*srtp=*/true);
487 }
488
489 // Test transferring when the "answerer" has the server role.
TEST_F(DtlsTransportTest,TestTransferDtlsSrtpAnswererIsPassive)490 TEST_F(DtlsTransportTest, TestTransferDtlsSrtpAnswererIsPassive) {
491 PrepareDtls(rtc::KT_DEFAULT);
492 ASSERT_TRUE(Connect(/*client1_server=*/false));
493 TestTransfer(1000, 100, /*srtp=*/true);
494 }
495
496 // Test that renegotiation (setting same role and fingerprint again) can be
497 // started before the clients become connected in the first negotiation.
TEST_F(DtlsTransportTest,TestRenegotiateBeforeConnect)498 TEST_F(DtlsTransportTest, TestRenegotiateBeforeConnect) {
499 PrepareDtls(rtc::KT_DEFAULT);
500 // Note: This is doing the same thing Connect normally does, minus some
501 // additional checks not relevant for this test.
502 Negotiate();
503 Negotiate();
504 EXPECT_TRUE(client1_.Connect(&client2_, false));
505 EXPECT_TRUE_SIMULATED_WAIT(client1_.dtls_transport()->writable() &&
506 client2_.dtls_transport()->writable(),
507 kTimeout, fake_clock_);
508 TestTransfer(1000, 100, true);
509 }
510
511 // Test Certificates state after negotiation but before connection.
TEST_F(DtlsTransportTest,TestCertificatesBeforeConnect)512 TEST_F(DtlsTransportTest, TestCertificatesBeforeConnect) {
513 PrepareDtls(rtc::KT_DEFAULT);
514 Negotiate();
515
516 // After negotiation, each side has a distinct local certificate, but still no
517 // remote certificate, because connection has not yet occurred.
518 auto certificate1 = client1_.dtls_transport()->GetLocalCertificate();
519 auto certificate2 = client2_.dtls_transport()->GetLocalCertificate();
520 ASSERT_NE(certificate1->GetSSLCertificate().ToPEMString(),
521 certificate2->GetSSLCertificate().ToPEMString());
522 ASSERT_FALSE(client1_.dtls_transport()->GetRemoteSSLCertChain());
523 ASSERT_FALSE(client2_.dtls_transport()->GetRemoteSSLCertChain());
524 }
525
526 // Test Certificates state after connection.
TEST_F(DtlsTransportTest,TestCertificatesAfterConnect)527 TEST_F(DtlsTransportTest, TestCertificatesAfterConnect) {
528 PrepareDtls(rtc::KT_DEFAULT);
529 ASSERT_TRUE(Connect());
530
531 // After connection, each side has a distinct local certificate.
532 auto certificate1 = client1_.dtls_transport()->GetLocalCertificate();
533 auto certificate2 = client2_.dtls_transport()->GetLocalCertificate();
534 ASSERT_NE(certificate1->GetSSLCertificate().ToPEMString(),
535 certificate2->GetSSLCertificate().ToPEMString());
536
537 // Each side's remote certificate is the other side's local certificate.
538 std::unique_ptr<rtc::SSLCertChain> remote_cert1 =
539 client1_.dtls_transport()->GetRemoteSSLCertChain();
540 ASSERT_TRUE(remote_cert1);
541 ASSERT_EQ(1u, remote_cert1->GetSize());
542 ASSERT_EQ(remote_cert1->Get(0).ToPEMString(),
543 certificate2->GetSSLCertificate().ToPEMString());
544 std::unique_ptr<rtc::SSLCertChain> remote_cert2 =
545 client2_.dtls_transport()->GetRemoteSSLCertChain();
546 ASSERT_TRUE(remote_cert2);
547 ASSERT_EQ(1u, remote_cert2->GetSize());
548 ASSERT_EQ(remote_cert2->Get(0).ToPEMString(),
549 certificate1->GetSSLCertificate().ToPEMString());
550 }
551
552 // Test that packets are retransmitted according to the expected schedule.
553 // Each time a timeout occurs, the retransmission timer should be doubled up to
554 // 60 seconds. The timer defaults to 1 second, but for WebRTC we should be
555 // initializing it to 50ms.
TEST_F(DtlsTransportTest,TestRetransmissionSchedule)556 TEST_F(DtlsTransportTest, TestRetransmissionSchedule) {
557 // We can only change the retransmission schedule with a recently-added
558 // BoringSSL API. Skip the test if not built with BoringSSL.
559 MAYBE_SKIP_TEST(IsBoringSsl);
560
561 PrepareDtls(rtc::KT_DEFAULT);
562 // Exchange fingerprints and set SSL roles.
563 Negotiate();
564
565 // Make client2_ writable, but not client1_.
566 // This means client1_ will send DTLS client hellos but get no response.
567 EXPECT_TRUE(client2_.Connect(&client1_, true));
568 EXPECT_TRUE_SIMULATED_WAIT(client2_.fake_ice_transport()->writable(),
569 kTimeout, fake_clock_);
570
571 // Wait for the first client hello to be sent.
572 EXPECT_EQ_WAIT(1, client1_.received_dtls_client_hellos(), kTimeout);
573 EXPECT_FALSE(client1_.fake_ice_transport()->writable());
574
575 static int timeout_schedule_ms[] = {50, 100, 200, 400, 800, 1600,
576 3200, 6400, 12800, 25600, 51200, 60000};
577
578 int expected_hellos = 1;
579 for (size_t i = 0;
580 i < (sizeof(timeout_schedule_ms) / sizeof(timeout_schedule_ms[0]));
581 ++i) {
582 // For each expected retransmission time, advance the fake clock a
583 // millisecond before the expected time and verify that no unexpected
584 // retransmissions were sent. Then advance it the final millisecond and
585 // verify that the expected retransmission was sent.
586 fake_clock_.AdvanceTime(
587 webrtc::TimeDelta::Millis(timeout_schedule_ms[i] - 1));
588 EXPECT_EQ(expected_hellos, client1_.received_dtls_client_hellos());
589 fake_clock_.AdvanceTime(webrtc::TimeDelta::Millis(1));
590 EXPECT_EQ(++expected_hellos, client1_.received_dtls_client_hellos());
591 }
592 }
593
594 // The following events can occur in many different orders:
595 // 1. Caller receives remote fingerprint.
596 // 2. Caller is writable.
597 // 3. Caller receives ClientHello.
598 // 4. DTLS handshake finishes.
599 //
600 // The tests below cover all causally consistent permutations of these events;
601 // the caller must be writable and receive a ClientHello before the handshake
602 // finishes, but otherwise any ordering is possible.
603 //
604 // For each permutation, the test verifies that a connection is established and
605 // fingerprint verified without any DTLS packet needing to be retransmitted.
606 //
607 // Each permutation is also tested with valid and invalid fingerprints,
608 // ensuring that the handshake fails with an invalid fingerprint.
609 enum DtlsTransportEvent {
610 CALLER_RECEIVES_FINGERPRINT,
611 CALLER_WRITABLE,
612 CALLER_RECEIVES_CLIENTHELLO,
613 HANDSHAKE_FINISHES
614 };
615
616 class DtlsEventOrderingTest
617 : public DtlsTransportTestBase,
618 public ::testing::TestWithParam<
619 ::testing::tuple<std::vector<DtlsTransportEvent>, bool>> {
620 protected:
621 // If |valid_fingerprint| is false, the caller will receive a fingerprint
622 // that doesn't match the callee's certificate, so the handshake should fail.
TestEventOrdering(const std::vector<DtlsTransportEvent> & events,bool valid_fingerprint)623 void TestEventOrdering(const std::vector<DtlsTransportEvent>& events,
624 bool valid_fingerprint) {
625 // Pre-setup: Set local certificate on both caller and callee, and
626 // remote fingerprint on callee, but neither is writable and the caller
627 // doesn't have the callee's fingerprint.
628 PrepareDtls(rtc::KT_DEFAULT);
629 // Simulate packets being sent and arriving asynchronously.
630 // Otherwise the entire DTLS handshake would occur in one clock tick, and
631 // we couldn't inject method calls in the middle of it.
632 int simulated_delay_ms = 10;
633 client1_.SetupTransports(ICEROLE_CONTROLLING, simulated_delay_ms);
634 client2_.SetupTransports(ICEROLE_CONTROLLED, simulated_delay_ms);
635 // Similar to how NegotiateOrdering works.
636 client1_.dtls_transport()->SetDtlsRole(rtc::SSL_SERVER);
637 client2_.dtls_transport()->SetDtlsRole(rtc::SSL_CLIENT);
638 SetRemoteFingerprintFromCert(client2_.dtls_transport(),
639 client1_.certificate());
640
641 for (DtlsTransportEvent e : events) {
642 switch (e) {
643 case CALLER_RECEIVES_FINGERPRINT:
644 if (valid_fingerprint) {
645 SetRemoteFingerprintFromCert(client1_.dtls_transport(),
646 client2_.certificate());
647 } else {
648 SetRemoteFingerprintFromCert(client1_.dtls_transport(),
649 client2_.certificate(),
650 true /*modify_digest*/);
651 }
652 break;
653 case CALLER_WRITABLE:
654 EXPECT_TRUE(client1_.Connect(&client2_, true));
655 EXPECT_TRUE_SIMULATED_WAIT(client1_.fake_ice_transport()->writable(),
656 kTimeout, fake_clock_);
657 break;
658 case CALLER_RECEIVES_CLIENTHELLO:
659 // Sanity check that a ClientHello hasn't already been received.
660 EXPECT_EQ(0, client1_.received_dtls_client_hellos());
661 // Making client2_ writable will cause it to send the ClientHello.
662 EXPECT_TRUE(client2_.Connect(&client1_, true));
663 EXPECT_TRUE_SIMULATED_WAIT(client2_.fake_ice_transport()->writable(),
664 kTimeout, fake_clock_);
665 EXPECT_EQ_SIMULATED_WAIT(1, client1_.received_dtls_client_hellos(),
666 kTimeout, fake_clock_);
667 break;
668 case HANDSHAKE_FINISHES:
669 // Sanity check that the handshake hasn't already finished.
670 EXPECT_FALSE(client1_.dtls_transport()->IsDtlsConnected() ||
671 client1_.dtls_transport()->dtls_state() ==
672 DTLS_TRANSPORT_FAILED);
673 EXPECT_TRUE_SIMULATED_WAIT(
674 client1_.dtls_transport()->IsDtlsConnected() ||
675 client1_.dtls_transport()->dtls_state() ==
676 DTLS_TRANSPORT_FAILED,
677 kTimeout, fake_clock_);
678 break;
679 }
680 }
681
682 DtlsTransportState expected_final_state =
683 valid_fingerprint ? DTLS_TRANSPORT_CONNECTED : DTLS_TRANSPORT_FAILED;
684 EXPECT_EQ_SIMULATED_WAIT(expected_final_state,
685 client1_.dtls_transport()->dtls_state(), kTimeout,
686 fake_clock_);
687 EXPECT_EQ_SIMULATED_WAIT(expected_final_state,
688 client2_.dtls_transport()->dtls_state(), kTimeout,
689 fake_clock_);
690
691 // Transports should be writable iff there was a valid fingerprint.
692 EXPECT_EQ(valid_fingerprint, client1_.dtls_transport()->writable());
693 EXPECT_EQ(valid_fingerprint, client2_.dtls_transport()->writable());
694
695 // Check that no hello needed to be retransmitted.
696 EXPECT_EQ(1, client1_.received_dtls_client_hellos());
697 EXPECT_EQ(1, client2_.received_dtls_server_hellos());
698
699 if (valid_fingerprint) {
700 TestTransfer(1000, 100, false);
701 }
702 }
703 };
704
TEST_P(DtlsEventOrderingTest,TestEventOrdering)705 TEST_P(DtlsEventOrderingTest, TestEventOrdering) {
706 TestEventOrdering(::testing::get<0>(GetParam()),
707 ::testing::get<1>(GetParam()));
708 }
709
710 INSTANTIATE_TEST_SUITE_P(
711 TestEventOrdering,
712 DtlsEventOrderingTest,
713 ::testing::Combine(
714 ::testing::Values(
715 std::vector<DtlsTransportEvent>{
716 CALLER_RECEIVES_FINGERPRINT, CALLER_WRITABLE,
717 CALLER_RECEIVES_CLIENTHELLO, HANDSHAKE_FINISHES},
718 std::vector<DtlsTransportEvent>{
719 CALLER_WRITABLE, CALLER_RECEIVES_FINGERPRINT,
720 CALLER_RECEIVES_CLIENTHELLO, HANDSHAKE_FINISHES},
721 std::vector<DtlsTransportEvent>{
722 CALLER_WRITABLE, CALLER_RECEIVES_CLIENTHELLO,
723 CALLER_RECEIVES_FINGERPRINT, HANDSHAKE_FINISHES},
724 std::vector<DtlsTransportEvent>{
725 CALLER_WRITABLE, CALLER_RECEIVES_CLIENTHELLO,
726 HANDSHAKE_FINISHES, CALLER_RECEIVES_FINGERPRINT},
727 std::vector<DtlsTransportEvent>{
728 CALLER_RECEIVES_FINGERPRINT, CALLER_RECEIVES_CLIENTHELLO,
729 CALLER_WRITABLE, HANDSHAKE_FINISHES},
730 std::vector<DtlsTransportEvent>{
731 CALLER_RECEIVES_CLIENTHELLO, CALLER_RECEIVES_FINGERPRINT,
732 CALLER_WRITABLE, HANDSHAKE_FINISHES},
733 std::vector<DtlsTransportEvent>{
734 CALLER_RECEIVES_CLIENTHELLO, CALLER_WRITABLE,
735 CALLER_RECEIVES_FINGERPRINT, HANDSHAKE_FINISHES},
736 std::vector<DtlsTransportEvent>{CALLER_RECEIVES_CLIENTHELLO,
737 CALLER_WRITABLE, HANDSHAKE_FINISHES,
738 CALLER_RECEIVES_FINGERPRINT}),
739 ::testing::Bool()));
740
741 } // namespace cricket
742