blob: f7d7a88d1ed0940e0cafdb69bad82e3e4ae99298 [file] [log] [blame]
Harald Alvestrandd02541e2019-01-03 12:43:28 +01001/*
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
Steve Anton10542f22019-01-11 09:11:00 -080011#include "pc/dtls_transport.h"
Harald Alvestrandd02541e2019-01-03 12:43:28 +010012
13#include <utility>
14#include <vector>
15
16#include "absl/memory/memory.h"
Steve Anton10542f22019-01-11 09:11:00 -080017#include "p2p/base/fake_dtls_transport.h"
Harald Alvestrandd02541e2019-01-03 12:43:28 +010018#include "rtc_base/gunit.h"
19#include "test/gmock.h"
20#include "test/gtest.h"
21
22constexpr int kDefaultTimeout = 1000; // milliseconds
Harald Alvestrand114871b2019-04-11 13:37:41 +020023constexpr int kNonsenseCipherSuite = 1234;
Harald Alvestrandd02541e2019-01-03 12:43:28 +010024
25using cricket::FakeDtlsTransport;
26using ::testing::ElementsAre;
27
28namespace webrtc {
29
30class TestDtlsTransportObserver : public DtlsTransportObserverInterface {
31 public:
32 void OnStateChange(DtlsTransportInformation info) override {
33 state_change_called_ = true;
34 states_.push_back(info.state());
Harald Alvestrand7061e512019-04-10 17:20:42 +020035 info_ = info;
Harald Alvestrandd02541e2019-01-03 12:43:28 +010036 }
37
38 void OnError(RTCError error) override {}
39
Harald Alvestrandcdc30452019-01-08 18:08:04 +010040 DtlsTransportState state() {
41 if (states_.size() > 0) {
42 return states_[states_.size() - 1];
43 } else {
44 return DtlsTransportState::kNew;
45 }
46 }
47
Harald Alvestrandd02541e2019-01-03 12:43:28 +010048 bool state_change_called_ = false;
Harald Alvestrand7061e512019-04-10 17:20:42 +020049 DtlsTransportInformation info_;
Harald Alvestrandd02541e2019-01-03 12:43:28 +010050 std::vector<DtlsTransportState> states_;
51};
52
Mirko Bonadei6a489f22019-04-09 15:11:12 +020053class DtlsTransportTest : public ::testing::Test {
Harald Alvestrandd02541e2019-01-03 12:43:28 +010054 public:
55 DtlsTransport* transport() { return transport_.get(); }
56 DtlsTransportObserverInterface* observer() { return &observer_; }
57
Harald Alvestrand7061e512019-04-10 17:20:42 +020058 void CreateTransport(rtc::FakeSSLCertificate* certificate = nullptr) {
Mirko Bonadei317a1f02019-09-17 17:06:18 +020059 auto cricket_transport = std::make_unique<FakeDtlsTransport>(
Harald Alvestrandd02541e2019-01-03 12:43:28 +010060 "audio", cricket::ICE_CANDIDATE_COMPONENT_RTP);
Harald Alvestrand7061e512019-04-10 17:20:42 +020061 if (certificate) {
62 cricket_transport->SetRemoteSSLCertificate(certificate);
63 }
Harald Alvestrand114871b2019-04-11 13:37:41 +020064 cricket_transport->SetSslCipherSuite(kNonsenseCipherSuite);
Harald Alvestrandd02541e2019-01-03 12:43:28 +010065 transport_ =
66 new rtc::RefCountedObject<DtlsTransport>(std::move(cricket_transport));
67 }
68
69 void CompleteDtlsHandshake() {
70 auto fake_dtls1 = static_cast<FakeDtlsTransport*>(transport_->internal());
Mirko Bonadei317a1f02019-09-17 17:06:18 +020071 auto fake_dtls2 = std::make_unique<FakeDtlsTransport>(
Harald Alvestrandd02541e2019-01-03 12:43:28 +010072 "audio", cricket::ICE_CANDIDATE_COMPONENT_RTP);
73 auto cert1 = rtc::RTCCertificate::Create(absl::WrapUnique(
74 rtc::SSLIdentity::Generate("session1", rtc::KT_DEFAULT)));
75 fake_dtls1->SetLocalCertificate(cert1);
76 auto cert2 = rtc::RTCCertificate::Create(absl::WrapUnique(
77 rtc::SSLIdentity::Generate("session1", rtc::KT_DEFAULT)));
78 fake_dtls2->SetLocalCertificate(cert2);
79 fake_dtls1->SetDestination(fake_dtls2.get());
80 }
81
82 rtc::scoped_refptr<DtlsTransport> transport_;
83 TestDtlsTransportObserver observer_;
84};
85
86TEST_F(DtlsTransportTest, CreateClearDelete) {
Mirko Bonadei317a1f02019-09-17 17:06:18 +020087 auto cricket_transport = std::make_unique<FakeDtlsTransport>(
Harald Alvestrandd02541e2019-01-03 12:43:28 +010088 "audio", cricket::ICE_CANDIDATE_COMPONENT_RTP);
89 rtc::scoped_refptr<DtlsTransport> webrtc_transport =
90 new rtc::RefCountedObject<DtlsTransport>(std::move(cricket_transport));
91 ASSERT_TRUE(webrtc_transport->internal());
92 ASSERT_EQ(DtlsTransportState::kNew, webrtc_transport->Information().state());
93 webrtc_transport->Clear();
94 ASSERT_FALSE(webrtc_transport->internal());
95 ASSERT_EQ(DtlsTransportState::kClosed,
96 webrtc_transport->Information().state());
97}
98
99TEST_F(DtlsTransportTest, EventsObservedWhenConnecting) {
100 CreateTransport();
101 transport()->RegisterObserver(observer());
102 CompleteDtlsHandshake();
103 ASSERT_TRUE_WAIT(observer_.state_change_called_, kDefaultTimeout);
104 EXPECT_THAT(
105 observer_.states_,
106 ElementsAre( // FakeDtlsTransport doesn't signal the "connecting" state.
107 // TODO(hta): fix FakeDtlsTransport or file bug on it.
108 // DtlsTransportState::kConnecting,
109 DtlsTransportState::kConnected));
110}
111
Harald Alvestrandcdc30452019-01-08 18:08:04 +0100112TEST_F(DtlsTransportTest, CloseWhenClearing) {
113 CreateTransport();
114 transport()->RegisterObserver(observer());
115 CompleteDtlsHandshake();
116 ASSERT_TRUE_WAIT(observer_.state() == DtlsTransportState::kConnected,
117 kDefaultTimeout);
118 transport()->Clear();
119 ASSERT_TRUE_WAIT(observer_.state() == DtlsTransportState::kClosed,
120 kDefaultTimeout);
121}
122
Harald Alvestrand7061e512019-04-10 17:20:42 +0200123TEST_F(DtlsTransportTest, CertificateAppearsOnConnect) {
124 rtc::FakeSSLCertificate fake_certificate("fake data");
125 CreateTransport(&fake_certificate);
126 transport()->RegisterObserver(observer());
127 CompleteDtlsHandshake();
128 ASSERT_TRUE_WAIT(observer_.state() == DtlsTransportState::kConnected,
129 kDefaultTimeout);
130 EXPECT_TRUE(observer_.info_.remote_ssl_certificates() != nullptr);
131}
132
133TEST_F(DtlsTransportTest, CertificateDisappearsOnClose) {
134 rtc::FakeSSLCertificate fake_certificate("fake data");
135 CreateTransport(&fake_certificate);
136 transport()->RegisterObserver(observer());
137 CompleteDtlsHandshake();
138 ASSERT_TRUE_WAIT(observer_.state() == DtlsTransportState::kConnected,
139 kDefaultTimeout);
140 EXPECT_TRUE(observer_.info_.remote_ssl_certificates() != nullptr);
141 transport()->Clear();
142 ASSERT_TRUE_WAIT(observer_.state() == DtlsTransportState::kClosed,
143 kDefaultTimeout);
144 EXPECT_FALSE(observer_.info_.remote_ssl_certificates());
145}
146
Harald Alvestrand114871b2019-04-11 13:37:41 +0200147TEST_F(DtlsTransportTest, CipherSuiteVisibleWhenConnected) {
148 CreateTransport();
149 transport()->RegisterObserver(observer());
150 CompleteDtlsHandshake();
151 ASSERT_TRUE_WAIT(observer_.state() == DtlsTransportState::kConnected,
152 kDefaultTimeout);
153 ASSERT_TRUE(observer_.info_.ssl_cipher_suite());
154 EXPECT_EQ(kNonsenseCipherSuite, *observer_.info_.ssl_cipher_suite());
155 transport()->Clear();
156 ASSERT_TRUE_WAIT(observer_.state() == DtlsTransportState::kClosed,
157 kDefaultTimeout);
158 EXPECT_FALSE(observer_.info_.ssl_cipher_suite());
159}
160
Harald Alvestrandd02541e2019-01-03 12:43:28 +0100161} // namespace webrtc