blob: a9ac73c9b8b4dd1e207f714b30f2f76ac5d56eae [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
Harald Alvestrandc24a2182022-02-23 13:44:59 +000016#include "absl/types/optional.h"
17#include "api/rtc_error.h"
Steve Anton10542f22019-01-11 09:11:00 -080018#include "p2p/base/fake_dtls_transport.h"
Harald Alvestrandc24a2182022-02-23 13:44:59 +000019#include "p2p/base/p2p_constants.h"
20#include "rtc_base/fake_ssl_identity.h"
Harald Alvestrandd02541e2019-01-03 12:43:28 +010021#include "rtc_base/gunit.h"
Harald Alvestrandc24a2182022-02-23 13:44:59 +000022#include "rtc_base/ref_counted_object.h"
23#include "rtc_base/rtc_certificate.h"
24#include "rtc_base/ssl_identity.h"
Harald Alvestrandd02541e2019-01-03 12:43:28 +010025#include "test/gmock.h"
26#include "test/gtest.h"
27
28constexpr int kDefaultTimeout = 1000; // milliseconds
Harald Alvestrand114871b2019-04-11 13:37:41 +020029constexpr int kNonsenseCipherSuite = 1234;
Harald Alvestrandd02541e2019-01-03 12:43:28 +010030
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 17:20:42 +020041 info_ = info;
Harald Alvestrandd02541e2019-01-03 12:43:28 +010042 }
43
44 void OnError(RTCError error) override {}
45
Harald Alvestrandcdc30452019-01-08 18:08:04 +010046 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 12:43:28 +010054 bool state_change_called_ = false;
Harald Alvestrand7061e512019-04-10 17:20:42 +020055 DtlsTransportInformation info_;
Harald Alvestrandd02541e2019-01-03 12:43:28 +010056 std::vector<DtlsTransportState> states_;
57};
58
Mirko Bonadei6a489f22019-04-09 15:11:12 +020059class DtlsTransportTest : public ::testing::Test {
Harald Alvestrandd02541e2019-01-03 12:43:28 +010060 public:
61 DtlsTransport* transport() { return transport_.get(); }
62 DtlsTransportObserverInterface* observer() { return &observer_; }
63
Harald Alvestrand7061e512019-04-10 17:20:42 +020064 void CreateTransport(rtc::FakeSSLCertificate* certificate = nullptr) {
Mirko Bonadei317a1f02019-09-17 17:06:18 +020065 auto cricket_transport = std::make_unique<FakeDtlsTransport>(
Harald Alvestrandd02541e2019-01-03 12:43:28 +010066 "audio", cricket::ICE_CANDIDATE_COMPONENT_RTP);
Harald Alvestrand7061e512019-04-10 17:20:42 +020067 if (certificate) {
68 cricket_transport->SetRemoteSSLCertificate(certificate);
69 }
Harald Alvestrand114871b2019-04-11 13:37:41 +020070 cricket_transport->SetSslCipherSuite(kNonsenseCipherSuite);
Harald Alvestrandd02541e2019-01-03 12:43:28 +010071 transport_ =
Tommi87f70902021-04-27 14:43:08 +020072 rtc::make_ref_counted<DtlsTransport>(std::move(cricket_transport));
Harald Alvestrandd02541e2019-01-03 12:43:28 +010073 }
74
75 void CompleteDtlsHandshake() {
76 auto fake_dtls1 = static_cast<FakeDtlsTransport*>(transport_->internal());
Mirko Bonadei317a1f02019-09-17 17:06:18 +020077 auto fake_dtls2 = std::make_unique<FakeDtlsTransport>(
Harald Alvestrandd02541e2019-01-03 12:43:28 +010078 "audio", cricket::ICE_CANDIDATE_COMPONENT_RTP);
Harald Alvestrand8515d5a2020-03-20 22:51:32 +010079 auto cert1 = rtc::RTCCertificate::Create(
80 rtc::SSLIdentity::Create("session1", rtc::KT_DEFAULT));
Harald Alvestrandd02541e2019-01-03 12:43:28 +010081 fake_dtls1->SetLocalCertificate(cert1);
Harald Alvestrand8515d5a2020-03-20 22:51:32 +010082 auto cert2 = rtc::RTCCertificate::Create(
83 rtc::SSLIdentity::Create("session1", rtc::KT_DEFAULT));
Harald Alvestrandd02541e2019-01-03 12:43:28 +010084 fake_dtls2->SetLocalCertificate(cert2);
85 fake_dtls1->SetDestination(fake_dtls2.get());
86 }
87
88 rtc::scoped_refptr<DtlsTransport> transport_;
89 TestDtlsTransportObserver observer_;
90};
91
92TEST_F(DtlsTransportTest, CreateClearDelete) {
Mirko Bonadei317a1f02019-09-17 17:06:18 +020093 auto cricket_transport = std::make_unique<FakeDtlsTransport>(
Harald Alvestrandd02541e2019-01-03 12:43:28 +010094 "audio", cricket::ICE_CANDIDATE_COMPONENT_RTP);
Tommi87f70902021-04-27 14:43:08 +020095 auto webrtc_transport =
96 rtc::make_ref_counted<DtlsTransport>(std::move(cricket_transport));
Harald Alvestrandd02541e2019-01-03 12:43:28 +010097 ASSERT_TRUE(webrtc_transport->internal());
98 ASSERT_EQ(DtlsTransportState::kNew, webrtc_transport->Information().state());
99 webrtc_transport->Clear();
100 ASSERT_FALSE(webrtc_transport->internal());
101 ASSERT_EQ(DtlsTransportState::kClosed,
102 webrtc_transport->Information().state());
103}
104
105TEST_F(DtlsTransportTest, EventsObservedWhenConnecting) {
106 CreateTransport();
107 transport()->RegisterObserver(observer());
108 CompleteDtlsHandshake();
109 ASSERT_TRUE_WAIT(observer_.state_change_called_, kDefaultTimeout);
110 EXPECT_THAT(
111 observer_.states_,
112 ElementsAre( // FakeDtlsTransport doesn't signal the "connecting" state.
113 // TODO(hta): fix FakeDtlsTransport or file bug on it.
114 // DtlsTransportState::kConnecting,
115 DtlsTransportState::kConnected));
116}
117
Harald Alvestrandcdc30452019-01-08 18:08:04 +0100118TEST_F(DtlsTransportTest, CloseWhenClearing) {
119 CreateTransport();
120 transport()->RegisterObserver(observer());
121 CompleteDtlsHandshake();
122 ASSERT_TRUE_WAIT(observer_.state() == DtlsTransportState::kConnected,
123 kDefaultTimeout);
124 transport()->Clear();
125 ASSERT_TRUE_WAIT(observer_.state() == DtlsTransportState::kClosed,
126 kDefaultTimeout);
127}
128
Harald Alvestrand316ab122022-02-10 08:23:47 +0000129TEST_F(DtlsTransportTest, RoleAppearsOnConnect) {
130 rtc::FakeSSLCertificate fake_certificate("fake data");
131 CreateTransport(&fake_certificate);
132 transport()->RegisterObserver(observer());
133 EXPECT_FALSE(transport()->Information().role());
134 CompleteDtlsHandshake();
135 ASSERT_TRUE_WAIT(observer_.state() == DtlsTransportState::kConnected,
136 kDefaultTimeout);
137 EXPECT_TRUE(observer_.info_.role());
138 EXPECT_TRUE(transport()->Information().role());
Harald Alvestrand321ec3b2022-02-10 13:42:18 +0000139 EXPECT_EQ(transport()->Information().role(), DtlsTransportTlsRole::kClient);
Harald Alvestrand316ab122022-02-10 08:23:47 +0000140}
141
Harald Alvestrand7061e512019-04-10 17:20:42 +0200142TEST_F(DtlsTransportTest, CertificateAppearsOnConnect) {
143 rtc::FakeSSLCertificate fake_certificate("fake data");
144 CreateTransport(&fake_certificate);
145 transport()->RegisterObserver(observer());
146 CompleteDtlsHandshake();
147 ASSERT_TRUE_WAIT(observer_.state() == DtlsTransportState::kConnected,
148 kDefaultTimeout);
149 EXPECT_TRUE(observer_.info_.remote_ssl_certificates() != nullptr);
150}
151
152TEST_F(DtlsTransportTest, CertificateDisappearsOnClose) {
153 rtc::FakeSSLCertificate fake_certificate("fake data");
154 CreateTransport(&fake_certificate);
155 transport()->RegisterObserver(observer());
156 CompleteDtlsHandshake();
157 ASSERT_TRUE_WAIT(observer_.state() == DtlsTransportState::kConnected,
158 kDefaultTimeout);
159 EXPECT_TRUE(observer_.info_.remote_ssl_certificates() != nullptr);
160 transport()->Clear();
161 ASSERT_TRUE_WAIT(observer_.state() == DtlsTransportState::kClosed,
162 kDefaultTimeout);
163 EXPECT_FALSE(observer_.info_.remote_ssl_certificates());
164}
165
Harald Alvestrand114871b2019-04-11 13:37:41 +0200166TEST_F(DtlsTransportTest, CipherSuiteVisibleWhenConnected) {
167 CreateTransport();
168 transport()->RegisterObserver(observer());
169 CompleteDtlsHandshake();
170 ASSERT_TRUE_WAIT(observer_.state() == DtlsTransportState::kConnected,
171 kDefaultTimeout);
172 ASSERT_TRUE(observer_.info_.ssl_cipher_suite());
173 EXPECT_EQ(kNonsenseCipherSuite, *observer_.info_.ssl_cipher_suite());
174 transport()->Clear();
175 ASSERT_TRUE_WAIT(observer_.state() == DtlsTransportState::kClosed,
176 kDefaultTimeout);
177 EXPECT_FALSE(observer_.info_.ssl_cipher_suite());
178}
179
Harald Alvestrandd02541e2019-01-03 12:43:28 +0100180} // namespace webrtc