blob: c234176635405beaaeb9635ed79db8fa707834fb [file] [log] [blame]
Harald Alvestrandd02541e2019-01-03 11:43:281/*
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 17:11:0011#include "pc/dtls_transport.h"
Harald Alvestrandd02541e2019-01-03 11:43:2812
13#include <utility>
14#include <vector>
15
Harald Alvestrandc24a2182022-02-23 13:44:5916#include "absl/types/optional.h"
Niels Möller105711e2022-06-14 13:48:2617#include "api/make_ref_counted.h"
Harald Alvestrandc24a2182022-02-23 13:44:5918#include "api/rtc_error.h"
Steve Anton10542f22019-01-11 17:11:0019#include "p2p/base/fake_dtls_transport.h"
Harald Alvestrandc24a2182022-02-23 13:44:5920#include "p2p/base/p2p_constants.h"
21#include "rtc_base/fake_ssl_identity.h"
Harald Alvestrandd02541e2019-01-03 11:43:2822#include "rtc_base/gunit.h"
Harald Alvestrandc24a2182022-02-23 13:44:5923#include "rtc_base/rtc_certificate.h"
24#include "rtc_base/ssl_identity.h"
Harald Alvestrandd02541e2019-01-03 11:43:2825#include "test/gmock.h"
26#include "test/gtest.h"
27
28constexpr int kDefaultTimeout = 1000; // milliseconds
Harald Alvestrand114871b2019-04-11 11:37:4129constexpr int kNonsenseCipherSuite = 1234;
Harald Alvestrandd02541e2019-01-03 11:43:2830
31using cricket::FakeDtlsTransport;
32using ::testing::ElementsAre;
33
34namespace webrtc {
35
36class TestDtlsTransportObserver : public DtlsTransportObserverInterface {
37 public:
38 void OnStateChange(DtlsTransportInformation info) override {
39 state_change_called_ = true;
40 states_.push_back(info.state());
Harald Alvestrand7061e512019-04-10 15:20:4241 info_ = info;
Harald Alvestrandd02541e2019-01-03 11:43:2842 }
43
44 void OnError(RTCError error) override {}
45
Harald Alvestrandcdc30452019-01-08 17:08:0446 DtlsTransportState state() {
47 if (states_.size() > 0) {
48 return states_[states_.size() - 1];
49 } else {
50 return DtlsTransportState::kNew;
51 }
52 }
53
Harald Alvestrandd02541e2019-01-03 11:43:2854 bool state_change_called_ = false;
Harald Alvestrand7061e512019-04-10 15:20:4255 DtlsTransportInformation info_;
Harald Alvestrandd02541e2019-01-03 11:43:2856 std::vector<DtlsTransportState> states_;
57};
58
Mirko Bonadei6a489f22019-04-09 13:11:1259class DtlsTransportTest : public ::testing::Test {
Harald Alvestrandd02541e2019-01-03 11:43:2860 public:
61 DtlsTransport* transport() { return transport_.get(); }
62 DtlsTransportObserverInterface* observer() { return &observer_; }
63
Harald Alvestrand7061e512019-04-10 15:20:4264 void CreateTransport(rtc::FakeSSLCertificate* certificate = nullptr) {
Mirko Bonadei317a1f02019-09-17 15:06:1865 auto cricket_transport = std::make_unique<FakeDtlsTransport>(
Harald Alvestrandd02541e2019-01-03 11:43:2866 "audio", cricket::ICE_CANDIDATE_COMPONENT_RTP);
Harald Alvestrand7061e512019-04-10 15:20:4267 if (certificate) {
68 cricket_transport->SetRemoteSSLCertificate(certificate);
69 }
Harald Alvestrand114871b2019-04-11 11:37:4170 cricket_transport->SetSslCipherSuite(kNonsenseCipherSuite);
Harald Alvestrandd02541e2019-01-03 11:43:2871 transport_ =
Tommi87f70902021-04-27 12:43:0872 rtc::make_ref_counted<DtlsTransport>(std::move(cricket_transport));
Harald Alvestrandd02541e2019-01-03 11:43:2873 }
74
75 void CompleteDtlsHandshake() {
76 auto fake_dtls1 = static_cast<FakeDtlsTransport*>(transport_->internal());
Mirko Bonadei317a1f02019-09-17 15:06:1877 auto fake_dtls2 = std::make_unique<FakeDtlsTransport>(
Harald Alvestrandd02541e2019-01-03 11:43:2878 "audio", cricket::ICE_CANDIDATE_COMPONENT_RTP);
Harald Alvestrand8515d5a2020-03-20 21:51:3279 auto cert1 = rtc::RTCCertificate::Create(
80 rtc::SSLIdentity::Create("session1", rtc::KT_DEFAULT));
Harald Alvestrandd02541e2019-01-03 11:43:2881 fake_dtls1->SetLocalCertificate(cert1);
Harald Alvestrand8515d5a2020-03-20 21:51:3282 auto cert2 = rtc::RTCCertificate::Create(
83 rtc::SSLIdentity::Create("session1", rtc::KT_DEFAULT));
Harald Alvestrandd02541e2019-01-03 11:43:2884 fake_dtls2->SetLocalCertificate(cert2);
85 fake_dtls1->SetDestination(fake_dtls2.get());
86 }
87
Niels Möller83830f32022-05-20 07:12:5788 rtc::AutoThread main_thread_;
Harald Alvestrandd02541e2019-01-03 11:43:2889 rtc::scoped_refptr<DtlsTransport> transport_;
90 TestDtlsTransportObserver observer_;
91};
92
93TEST_F(DtlsTransportTest, CreateClearDelete) {
Mirko Bonadei317a1f02019-09-17 15:06:1894 auto cricket_transport = std::make_unique<FakeDtlsTransport>(
Harald Alvestrandd02541e2019-01-03 11:43:2895 "audio", cricket::ICE_CANDIDATE_COMPONENT_RTP);
Tommi87f70902021-04-27 12:43:0896 auto webrtc_transport =
97 rtc::make_ref_counted<DtlsTransport>(std::move(cricket_transport));
Harald Alvestrandd02541e2019-01-03 11:43:2898 ASSERT_TRUE(webrtc_transport->internal());
99 ASSERT_EQ(DtlsTransportState::kNew, webrtc_transport->Information().state());
100 webrtc_transport->Clear();
101 ASSERT_FALSE(webrtc_transport->internal());
102 ASSERT_EQ(DtlsTransportState::kClosed,
103 webrtc_transport->Information().state());
104}
105
106TEST_F(DtlsTransportTest, EventsObservedWhenConnecting) {
107 CreateTransport();
108 transport()->RegisterObserver(observer());
109 CompleteDtlsHandshake();
110 ASSERT_TRUE_WAIT(observer_.state_change_called_, kDefaultTimeout);
111 EXPECT_THAT(
112 observer_.states_,
113 ElementsAre( // FakeDtlsTransport doesn't signal the "connecting" state.
114 // TODO(hta): fix FakeDtlsTransport or file bug on it.
115 // DtlsTransportState::kConnecting,
116 DtlsTransportState::kConnected));
117}
118
Harald Alvestrandcdc30452019-01-08 17:08:04119TEST_F(DtlsTransportTest, CloseWhenClearing) {
120 CreateTransport();
121 transport()->RegisterObserver(observer());
122 CompleteDtlsHandshake();
123 ASSERT_TRUE_WAIT(observer_.state() == DtlsTransportState::kConnected,
124 kDefaultTimeout);
125 transport()->Clear();
126 ASSERT_TRUE_WAIT(observer_.state() == DtlsTransportState::kClosed,
127 kDefaultTimeout);
128}
129
Harald Alvestrand316ab122022-02-10 08:23:47130TEST_F(DtlsTransportTest, RoleAppearsOnConnect) {
131 rtc::FakeSSLCertificate fake_certificate("fake data");
132 CreateTransport(&fake_certificate);
133 transport()->RegisterObserver(observer());
134 EXPECT_FALSE(transport()->Information().role());
135 CompleteDtlsHandshake();
136 ASSERT_TRUE_WAIT(observer_.state() == DtlsTransportState::kConnected,
137 kDefaultTimeout);
138 EXPECT_TRUE(observer_.info_.role());
139 EXPECT_TRUE(transport()->Information().role());
Harald Alvestrand321ec3b2022-02-10 13:42:18140 EXPECT_EQ(transport()->Information().role(), DtlsTransportTlsRole::kClient);
Harald Alvestrand316ab122022-02-10 08:23:47141}
142
Harald Alvestrand7061e512019-04-10 15:20:42143TEST_F(DtlsTransportTest, CertificateAppearsOnConnect) {
144 rtc::FakeSSLCertificate fake_certificate("fake data");
145 CreateTransport(&fake_certificate);
146 transport()->RegisterObserver(observer());
147 CompleteDtlsHandshake();
148 ASSERT_TRUE_WAIT(observer_.state() == DtlsTransportState::kConnected,
149 kDefaultTimeout);
150 EXPECT_TRUE(observer_.info_.remote_ssl_certificates() != nullptr);
151}
152
153TEST_F(DtlsTransportTest, CertificateDisappearsOnClose) {
154 rtc::FakeSSLCertificate fake_certificate("fake data");
155 CreateTransport(&fake_certificate);
156 transport()->RegisterObserver(observer());
157 CompleteDtlsHandshake();
158 ASSERT_TRUE_WAIT(observer_.state() == DtlsTransportState::kConnected,
159 kDefaultTimeout);
160 EXPECT_TRUE(observer_.info_.remote_ssl_certificates() != nullptr);
161 transport()->Clear();
162 ASSERT_TRUE_WAIT(observer_.state() == DtlsTransportState::kClosed,
163 kDefaultTimeout);
164 EXPECT_FALSE(observer_.info_.remote_ssl_certificates());
165}
166
Harald Alvestrand114871b2019-04-11 11:37:41167TEST_F(DtlsTransportTest, CipherSuiteVisibleWhenConnected) {
168 CreateTransport();
169 transport()->RegisterObserver(observer());
170 CompleteDtlsHandshake();
171 ASSERT_TRUE_WAIT(observer_.state() == DtlsTransportState::kConnected,
172 kDefaultTimeout);
173 ASSERT_TRUE(observer_.info_.ssl_cipher_suite());
174 EXPECT_EQ(kNonsenseCipherSuite, *observer_.info_.ssl_cipher_suite());
175 transport()->Clear();
176 ASSERT_TRUE_WAIT(observer_.state() == DtlsTransportState::kClosed,
177 kDefaultTimeout);
178 EXPECT_FALSE(observer_.info_.ssl_cipher_suite());
179}
180
Harald Alvestrandd02541e2019-01-03 11:43:28181} // namespace webrtc