blob: 2da59ddbb2cb6aebe9d0bb76e5c1dcd280827770 [file] [log] [blame]
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +00001/*
2 * Copyright 2014 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
Ali Tofigh7fa90572022-03-17 15:47:49 +010011#include "rtc_base/ssl_adapter.h"
12
jbauch555604a2016-04-26 03:13:22 -070013#include <memory>
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +000014#include <string>
Benjamin Wright6e9c3df2018-05-22 16:11:56 -070015#include <utility>
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +000016
Harald Alvestrand8515d5a2020-03-20 22:51:32 +010017#include "absl/memory/memory.h"
Ali Tofigh7fa90572022-03-17 15:47:49 +010018#include "absl/strings/string_view.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020019#include "rtc_base/gunit.h"
Steve Anton10542f22019-01-11 09:11:00 -080020#include "rtc_base/ip_address.h"
21#include "rtc_base/message_digest.h"
22#include "rtc_base/socket_stream.h"
Steve Anton10542f22019-01-11 09:11:00 -080023#include "rtc_base/ssl_identity.h"
24#include "rtc_base/ssl_stream_adapter.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020025#include "rtc_base/stream.h"
Steve Anton10542f22019-01-11 09:11:00 -080026#include "rtc_base/string_encode.h"
27#include "rtc_base/virtual_socket_server.h"
Benjamin Wright6e9c3df2018-05-22 16:11:56 -070028#include "test/gmock.h"
29
30using ::testing::_;
31using ::testing::Return;
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +000032
33static const int kTimeout = 5000;
34
Niels Möllerd0b88792021-08-12 10:32:30 +020035static rtc::Socket* CreateSocket(const rtc::SSLMode& ssl_mode) {
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +000036 rtc::SocketAddress address(rtc::IPAddress(INADDR_ANY), 0);
37
Niels Möllerd0b88792021-08-12 10:32:30 +020038 rtc::Socket* socket = rtc::Thread::Current()->socketserver()->CreateSocket(
39 address.family(),
40 (ssl_mode == rtc::SSL_MODE_DTLS) ? SOCK_DGRAM : SOCK_STREAM);
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +000041 socket->Bind(address);
42
43 return socket;
44}
45
46static std::string GetSSLProtocolName(const rtc::SSLMode& ssl_mode) {
47 return (ssl_mode == rtc::SSL_MODE_DTLS) ? "DTLS" : "TLS";
48}
49
Benjamin Wright6e9c3df2018-05-22 16:11:56 -070050// Simple mock for the certificate verifier.
51class MockCertVerifier : public rtc::SSLCertificateVerifier {
52 public:
53 virtual ~MockCertVerifier() = default;
Danil Chapovalov42748d82020-05-14 20:42:41 +020054 MOCK_METHOD(bool, Verify, (const rtc::SSLCertificate&), (override));
Benjamin Wright6e9c3df2018-05-22 16:11:56 -070055};
56
Mirko Bonadeic84f6612019-01-31 12:20:57 +010057// TODO(benwright) - Move to using INSTANTIATE_TEST_SUITE_P instead of using
Benjamin Wright6e9c3df2018-05-22 16:11:56 -070058// duplicate test cases for simple parameter changes.
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +000059class SSLAdapterTestDummyClient : public sigslot::has_slots<> {
60 public:
61 explicit SSLAdapterTestDummyClient(const rtc::SSLMode& ssl_mode)
62 : ssl_mode_(ssl_mode) {
Niels Möllerd0b88792021-08-12 10:32:30 +020063 rtc::Socket* socket = CreateSocket(ssl_mode_);
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +000064
65 ssl_adapter_.reset(rtc::SSLAdapter::Create(socket));
66
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +000067 ssl_adapter_->SetMode(ssl_mode_);
68
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +000069 // Ignore any certificate errors for the purpose of testing.
70 // Note: We do this only because we don't have a real certificate.
71 // NEVER USE THIS IN PRODUCTION CODE!
Sergey Silkin9c147dd2018-09-12 10:45:38 +000072 ssl_adapter_->SetIgnoreBadCert(true);
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +000073
Yves Gerey665174f2018-06-19 15:03:05 +020074 ssl_adapter_->SignalReadEvent.connect(
75 this, &SSLAdapterTestDummyClient::OnSSLAdapterReadEvent);
76 ssl_adapter_->SignalCloseEvent.connect(
77 this, &SSLAdapterTestDummyClient::OnSSLAdapterCloseEvent);
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +000078 }
79
Sergey Silkin9c147dd2018-09-12 10:45:38 +000080 void SetIgnoreBadCert(bool ignore_bad_cert) {
81 ssl_adapter_->SetIgnoreBadCert(ignore_bad_cert);
Benjamin Wright6e9c3df2018-05-22 16:11:56 -070082 }
83
84 void SetCertVerifier(rtc::SSLCertificateVerifier* ssl_cert_verifier) {
85 ssl_adapter_->SetCertVerifier(ssl_cert_verifier);
86 }
87
Sergey Silkin9c147dd2018-09-12 10:45:38 +000088 void SetAlpnProtocols(const std::vector<std::string>& protos) {
89 ssl_adapter_->SetAlpnProtocols(protos);
90 }
91
92 void SetEllipticCurves(const std::vector<std::string>& curves) {
93 ssl_adapter_->SetEllipticCurves(curves);
94 }
95
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +000096 rtc::SocketAddress GetAddress() const {
97 return ssl_adapter_->GetLocalAddress();
98 }
99
Niels Möllerd0b88792021-08-12 10:32:30 +0200100 rtc::Socket::ConnState GetState() const { return ssl_adapter_->GetState(); }
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000101
Yves Gerey665174f2018-06-19 15:03:05 +0200102 const std::string& GetReceivedData() const { return data_; }
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000103
Ali Tofigh7fa90572022-03-17 15:47:49 +0100104 int Connect(absl::string_view hostname, const rtc::SocketAddress& address) {
Jonas Olssonabbe8412018-04-03 13:40:05 +0200105 RTC_LOG(LS_INFO) << "Initiating connection with " << address.ToString();
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000106
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000107 int rv = ssl_adapter_->Connect(address);
108
109 if (rv == 0) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100110 RTC_LOG(LS_INFO) << "Starting " << GetSSLProtocolName(ssl_mode_)
111 << " handshake with " << hostname;
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000112
Ali Tofigh2ab914c2022-04-13 12:55:15 +0200113 if (ssl_adapter_->StartSSL(hostname) != 0) {
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000114 return -1;
115 }
116 }
117
118 return rv;
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000119 }
120
Yves Gerey665174f2018-06-19 15:03:05 +0200121 int Close() { return ssl_adapter_->Close(); }
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000122
Ali Tofigh7fa90572022-03-17 15:47:49 +0100123 int Send(absl::string_view message) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100124 RTC_LOG(LS_INFO) << "Client sending '" << message << "'";
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000125
126 return ssl_adapter_->Send(message.data(), message.length());
127 }
128
Niels Möllerd0b88792021-08-12 10:32:30 +0200129 void OnSSLAdapterReadEvent(rtc::Socket* socket) {
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000130 char buffer[4096] = "";
131
132 // Read data received from the server and store it in our internal buffer.
Stefan Holmer9131efd2016-05-23 18:19:26 +0200133 int read = socket->Recv(buffer, sizeof(buffer) - 1, nullptr);
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000134 if (read != -1) {
135 buffer[read] = '\0';
136
Mirko Bonadei675513b2017-11-09 11:09:25 +0100137 RTC_LOG(LS_INFO) << "Client received '" << buffer << "'";
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000138
139 data_ += buffer;
140 }
141 }
142
Niels Möllerd0b88792021-08-12 10:32:30 +0200143 void OnSSLAdapterCloseEvent(rtc::Socket* socket, int error) {
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000144 // OpenSSLAdapter signals handshake failure with a close event, but without
145 // closing the socket! Let's close the socket here. This way GetState() can
146 // return CS_CLOSED after failure.
Niels Möllerd0b88792021-08-12 10:32:30 +0200147 if (socket->GetState() != rtc::Socket::CS_CLOSED) {
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000148 socket->Close();
149 }
150 }
151
152 private:
153 const rtc::SSLMode ssl_mode_;
154
jbauch555604a2016-04-26 03:13:22 -0700155 std::unique_ptr<rtc::SSLAdapter> ssl_adapter_;
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000156
157 std::string data_;
158};
159
160class SSLAdapterTestDummyServer : public sigslot::has_slots<> {
161 public:
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200162 explicit SSLAdapterTestDummyServer(const rtc::SSLMode& ssl_mode,
torbjorng4e572472015-10-08 09:42:49 -0700163 const rtc::KeyParams& key_params)
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000164 : ssl_mode_(ssl_mode) {
165 // Generate a key pair and a certificate for this host.
Harald Alvestrand8515d5a2020-03-20 22:51:32 +0100166 ssl_identity_ = rtc::SSLIdentity::Create(GetHostname(), key_params);
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000167
168 server_socket_.reset(CreateSocket(ssl_mode_));
169
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000170 if (ssl_mode_ == rtc::SSL_MODE_TLS) {
Yves Gerey665174f2018-06-19 15:03:05 +0200171 server_socket_->SignalReadEvent.connect(
172 this, &SSLAdapterTestDummyServer::OnServerSocketReadEvent);
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000173
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000174 server_socket_->Listen(1);
175 }
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000176
Mirko Bonadei675513b2017-11-09 11:09:25 +0100177 RTC_LOG(LS_INFO) << ((ssl_mode_ == rtc::SSL_MODE_DTLS) ? "UDP" : "TCP")
178 << " server listening on "
Jonas Olssonabbe8412018-04-03 13:40:05 +0200179 << server_socket_->GetLocalAddress().ToString();
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000180 }
181
182 rtc::SocketAddress GetAddress() const {
183 return server_socket_->GetLocalAddress();
184 }
185
186 std::string GetHostname() const {
187 // Since we don't have a real certificate anyway, the value here doesn't
188 // really matter.
189 return "example.com";
190 }
191
Yves Gerey665174f2018-06-19 15:03:05 +0200192 const std::string& GetReceivedData() const { return data_; }
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000193
Ali Tofigh7fa90572022-03-17 15:47:49 +0100194 int Send(absl::string_view message) {
deadbeef37f5ecf2017-02-27 14:06:41 -0800195 if (ssl_stream_adapter_ == nullptr ||
196 ssl_stream_adapter_->GetState() != rtc::SS_OPEN) {
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000197 // No connection yet.
198 return -1;
199 }
200
Mirko Bonadei675513b2017-11-09 11:09:25 +0100201 RTC_LOG(LS_INFO) << "Server sending '" << message << "'";
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000202
203 size_t written;
204 int error;
205
Yves Gerey665174f2018-06-19 15:03:05 +0200206 rtc::StreamResult r = ssl_stream_adapter_->Write(
Harald Alvestrand11840ce2022-11-10 10:50:50 +0000207 rtc::MakeArrayView(reinterpret_cast<const uint8_t*>(message.data()),
208 message.size()),
209 written, error);
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000210 if (r == rtc::SR_SUCCESS) {
211 return written;
212 } else {
213 return -1;
214 }
215 }
216
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000217 void AcceptConnection(const rtc::SocketAddress& address) {
218 // Only a single connection is supported.
deadbeef37f5ecf2017-02-27 14:06:41 -0800219 ASSERT_TRUE(ssl_stream_adapter_ == nullptr);
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000220
221 // This is only for DTLS.
222 ASSERT_EQ(rtc::SSL_MODE_DTLS, ssl_mode_);
223
224 // Transfer ownership of the socket to the SSLStreamAdapter object.
Niels Möllerd0b88792021-08-12 10:32:30 +0200225 rtc::Socket* socket = server_socket_.release();
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000226
227 socket->Connect(address);
228
229 DoHandshake(socket);
230 }
231
Niels Möllerd0b88792021-08-12 10:32:30 +0200232 void OnServerSocketReadEvent(rtc::Socket* socket) {
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000233 // Only a single connection is supported.
deadbeef37f5ecf2017-02-27 14:06:41 -0800234 ASSERT_TRUE(ssl_stream_adapter_ == nullptr);
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000235
deadbeef37f5ecf2017-02-27 14:06:41 -0800236 DoHandshake(server_socket_->Accept(nullptr));
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000237 }
238
239 void OnSSLStreamAdapterEvent(rtc::StreamInterface* stream, int sig, int err) {
240 if (sig & rtc::SE_READ) {
Harald Alvestrand11840ce2022-11-10 10:50:50 +0000241 uint8_t buffer[4096] = "";
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000242 size_t read;
243 int error;
244
245 // Read data received from the client and store it in our internal
246 // buffer.
Harald Alvestrand11840ce2022-11-10 10:50:50 +0000247 rtc::StreamResult r = stream->Read(buffer, read, error);
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000248 if (r == rtc::SR_SUCCESS) {
249 buffer[read] = '\0';
Harald Alvestrand11840ce2022-11-10 10:50:50 +0000250 // Here we assume that the buffer is interpretable as string.
251 char* buffer_as_char = reinterpret_cast<char*>(buffer);
252 RTC_LOG(LS_INFO) << "Server received '" << buffer_as_char << "'";
253 data_ += buffer_as_char;
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000254 }
255 }
256 }
257
258 private:
Niels Möllerd0b88792021-08-12 10:32:30 +0200259 void DoHandshake(rtc::Socket* socket) {
Harald Alvestrand8515d5a2020-03-20 22:51:32 +0100260 ssl_stream_adapter_ = rtc::SSLStreamAdapter::Create(
261 std::make_unique<rtc::SocketStream>(socket));
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000262
263 ssl_stream_adapter_->SetMode(ssl_mode_);
264 ssl_stream_adapter_->SetServerRole();
265
266 // SSLStreamAdapter is normally used for peer-to-peer communication, but
267 // here we're testing communication between a client and a server
268 // (e.g. a WebRTC-based application and an RFC 5766 TURN server), where
269 // clients are not required to provide a certificate during handshake.
270 // Accordingly, we must disable client authentication here.
Benjamin Wrightb19b4972018-10-25 10:46:49 -0700271 ssl_stream_adapter_->SetClientAuthEnabledForTesting(false);
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000272
Harald Alvestrand8515d5a2020-03-20 22:51:32 +0100273 ssl_stream_adapter_->SetIdentity(ssl_identity_->Clone());
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000274
275 // Set a bogus peer certificate digest.
276 unsigned char digest[20];
277 size_t digest_len = sizeof(digest);
278 ssl_stream_adapter_->SetPeerCertificateDigest(rtc::DIGEST_SHA_1, digest,
Yves Gerey665174f2018-06-19 15:03:05 +0200279 digest_len);
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000280
Taylor Brandstetterc8762a82016-08-11 12:01:49 -0700281 ssl_stream_adapter_->StartSSL();
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000282
Yves Gerey665174f2018-06-19 15:03:05 +0200283 ssl_stream_adapter_->SignalEvent.connect(
284 this, &SSLAdapterTestDummyServer::OnSSLStreamAdapterEvent);
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000285 }
286
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000287 const rtc::SSLMode ssl_mode_;
288
Niels Möllerd0b88792021-08-12 10:32:30 +0200289 std::unique_ptr<rtc::Socket> server_socket_;
jbauch555604a2016-04-26 03:13:22 -0700290 std::unique_ptr<rtc::SSLStreamAdapter> ssl_stream_adapter_;
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000291
jbauch555604a2016-04-26 03:13:22 -0700292 std::unique_ptr<rtc::SSLIdentity> ssl_identity_;
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000293
294 std::string data_;
295};
296
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200297class SSLAdapterTestBase : public ::testing::Test, public sigslot::has_slots<> {
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000298 public:
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200299 explicit SSLAdapterTestBase(const rtc::SSLMode& ssl_mode,
torbjorng4e572472015-10-08 09:42:49 -0700300 const rtc::KeyParams& key_params)
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000301 : ssl_mode_(ssl_mode),
deadbeef98e186c2017-05-16 18:00:06 -0700302 vss_(new rtc::VirtualSocketServer()),
nisse7eaa4ea2017-05-08 05:25:41 -0700303 thread_(vss_.get()),
torbjorng4e572472015-10-08 09:42:49 -0700304 server_(new SSLAdapterTestDummyServer(ssl_mode_, key_params)),
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000305 client_(new SSLAdapterTestDummyClient(ssl_mode_)),
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200306 handshake_wait_(kTimeout) {}
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000307
Yves Gerey665174f2018-06-19 15:03:05 +0200308 void SetHandshakeWait(int wait) { handshake_wait_ = wait; }
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000309
Sergey Silkin9c147dd2018-09-12 10:45:38 +0000310 void SetIgnoreBadCert(bool ignore_bad_cert) {
311 client_->SetIgnoreBadCert(ignore_bad_cert);
Benjamin Wright6e9c3df2018-05-22 16:11:56 -0700312 }
313
314 void SetCertVerifier(rtc::SSLCertificateVerifier* ssl_cert_verifier) {
315 client_->SetCertVerifier(ssl_cert_verifier);
316 }
317
Sergey Silkin9c147dd2018-09-12 10:45:38 +0000318 void SetAlpnProtocols(const std::vector<std::string>& protos) {
319 client_->SetAlpnProtocols(protos);
320 }
321
322 void SetEllipticCurves(const std::vector<std::string>& curves) {
323 client_->SetEllipticCurves(curves);
324 }
325
Benjamin Wright6e9c3df2018-05-22 16:11:56 -0700326 void SetMockCertVerifier(bool return_value) {
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200327 auto mock_verifier = std::make_unique<MockCertVerifier>();
Benjamin Wright6e9c3df2018-05-22 16:11:56 -0700328 EXPECT_CALL(*mock_verifier, Verify(_)).WillRepeatedly(Return(return_value));
329 cert_verifier_ =
330 std::unique_ptr<rtc::SSLCertificateVerifier>(std::move(mock_verifier));
331
Sergey Silkin9c147dd2018-09-12 10:45:38 +0000332 SetIgnoreBadCert(false);
Benjamin Wright6e9c3df2018-05-22 16:11:56 -0700333 SetCertVerifier(cert_verifier_.get());
334 }
335
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000336 void TestHandshake(bool expect_success) {
337 int rv;
338
339 // The initial state is CS_CLOSED
Niels Möllerd0b88792021-08-12 10:32:30 +0200340 ASSERT_EQ(rtc::Socket::CS_CLOSED, client_->GetState());
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000341
342 rv = client_->Connect(server_->GetHostname(), server_->GetAddress());
343 ASSERT_EQ(0, rv);
344
345 // Now the state should be CS_CONNECTING
Niels Möllerd0b88792021-08-12 10:32:30 +0200346 ASSERT_EQ(rtc::Socket::CS_CONNECTING, client_->GetState());
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000347
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000348 if (ssl_mode_ == rtc::SSL_MODE_DTLS) {
349 // For DTLS, call AcceptConnection() with the client's address.
350 server_->AcceptConnection(client_->GetAddress());
351 }
352
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000353 if (expect_success) {
354 // If expecting success, the client should end up in the CS_CONNECTED
355 // state after handshake.
Niels Möllerd0b88792021-08-12 10:32:30 +0200356 EXPECT_EQ_WAIT(rtc::Socket::CS_CONNECTED, client_->GetState(),
Yves Gerey665174f2018-06-19 15:03:05 +0200357 handshake_wait_);
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000358
Mirko Bonadei675513b2017-11-09 11:09:25 +0100359 RTC_LOG(LS_INFO) << GetSSLProtocolName(ssl_mode_)
360 << " handshake complete.";
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000361
362 } else {
363 // On handshake failure the client should end up in the CS_CLOSED state.
Niels Möllerd0b88792021-08-12 10:32:30 +0200364 EXPECT_EQ_WAIT(rtc::Socket::CS_CLOSED, client_->GetState(),
Yves Gerey665174f2018-06-19 15:03:05 +0200365 handshake_wait_);
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000366
Mirko Bonadei675513b2017-11-09 11:09:25 +0100367 RTC_LOG(LS_INFO) << GetSSLProtocolName(ssl_mode_) << " handshake failed.";
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000368 }
369 }
370
Ali Tofigh7fa90572022-03-17 15:47:49 +0100371 void TestTransfer(absl::string_view message) {
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000372 int rv;
373
374 rv = client_->Send(message);
375 ASSERT_EQ(static_cast<int>(message.length()), rv);
376
377 // The server should have received the client's message.
378 EXPECT_EQ_WAIT(message, server_->GetReceivedData(), kTimeout);
379
380 rv = server_->Send(message);
381 ASSERT_EQ(static_cast<int>(message.length()), rv);
382
383 // The client should have received the server's message.
384 EXPECT_EQ_WAIT(message, client_->GetReceivedData(), kTimeout);
385
Mirko Bonadei675513b2017-11-09 11:09:25 +0100386 RTC_LOG(LS_INFO) << "Transfer complete.";
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000387 }
388
deadbeefed3b9862017-06-02 10:33:16 -0700389 protected:
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000390 const rtc::SSLMode ssl_mode_;
391
nisse7eaa4ea2017-05-08 05:25:41 -0700392 std::unique_ptr<rtc::VirtualSocketServer> vss_;
393 rtc::AutoSocketServerThread thread_;
jbauch555604a2016-04-26 03:13:22 -0700394 std::unique_ptr<SSLAdapterTestDummyServer> server_;
395 std::unique_ptr<SSLAdapterTestDummyClient> client_;
Benjamin Wright6e9c3df2018-05-22 16:11:56 -0700396 std::unique_ptr<rtc::SSLCertificateVerifier> cert_verifier_;
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000397
398 int handshake_wait_;
399};
400
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200401class SSLAdapterTestTLS_RSA : public SSLAdapterTestBase {
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000402 public:
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200403 SSLAdapterTestTLS_RSA()
torbjorng4e572472015-10-08 09:42:49 -0700404 : SSLAdapterTestBase(rtc::SSL_MODE_TLS, rtc::KeyParams::RSA()) {}
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000405};
406
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200407class SSLAdapterTestTLS_ECDSA : public SSLAdapterTestBase {
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000408 public:
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200409 SSLAdapterTestTLS_ECDSA()
torbjorng4e572472015-10-08 09:42:49 -0700410 : SSLAdapterTestBase(rtc::SSL_MODE_TLS, rtc::KeyParams::ECDSA()) {}
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200411};
412
413class SSLAdapterTestDTLS_RSA : public SSLAdapterTestBase {
414 public:
415 SSLAdapterTestDTLS_RSA()
torbjorng4e572472015-10-08 09:42:49 -0700416 : SSLAdapterTestBase(rtc::SSL_MODE_DTLS, rtc::KeyParams::RSA()) {}
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200417};
418
419class SSLAdapterTestDTLS_ECDSA : public SSLAdapterTestBase {
420 public:
421 SSLAdapterTestDTLS_ECDSA()
torbjorng4e572472015-10-08 09:42:49 -0700422 : SSLAdapterTestBase(rtc::SSL_MODE_DTLS, rtc::KeyParams::ECDSA()) {}
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000423};
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000424
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000425// Basic tests: TLS
426
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200427// Test that handshake works, using RSA
428TEST_F(SSLAdapterTestTLS_RSA, TestTLSConnect) {
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000429 TestHandshake(true);
430}
431
Benjamin Wright6e9c3df2018-05-22 16:11:56 -0700432// Test that handshake works with a custom verifier that returns true. RSA.
433TEST_F(SSLAdapterTestTLS_RSA, TestTLSConnectCustomCertVerifierSucceeds) {
434 SetMockCertVerifier(/*return_value=*/true);
435 TestHandshake(/*expect_success=*/true);
436}
437
438// Test that handshake fails with a custom verifier that returns false. RSA.
439TEST_F(SSLAdapterTestTLS_RSA, TestTLSConnectCustomCertVerifierFails) {
440 SetMockCertVerifier(/*return_value=*/false);
441 TestHandshake(/*expect_success=*/false);
442}
443
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200444// Test that handshake works, using ECDSA
445TEST_F(SSLAdapterTestTLS_ECDSA, TestTLSConnect) {
Benjamin Wright6e9c3df2018-05-22 16:11:56 -0700446 SetMockCertVerifier(/*return_value=*/true);
447 TestHandshake(/*expect_success=*/true);
448}
449
450// Test that handshake works with a custom verifier that returns true. ECDSA.
451TEST_F(SSLAdapterTestTLS_ECDSA, TestTLSConnectCustomCertVerifierSucceeds) {
452 SetMockCertVerifier(/*return_value=*/true);
453 TestHandshake(/*expect_success=*/true);
454}
455
456// Test that handshake fails with a custom verifier that returns false. ECDSA.
457TEST_F(SSLAdapterTestTLS_ECDSA, TestTLSConnectCustomCertVerifierFails) {
458 SetMockCertVerifier(/*return_value=*/false);
459 TestHandshake(/*expect_success=*/false);
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200460}
461
462// Test transfer between client and server, using RSA
463TEST_F(SSLAdapterTestTLS_RSA, TestTLSTransfer) {
464 TestHandshake(true);
465 TestTransfer("Hello, world!");
466}
467
Benjamin Wright6e9c3df2018-05-22 16:11:56 -0700468// Test transfer between client and server, using RSA with custom cert verifier.
469TEST_F(SSLAdapterTestTLS_RSA, TestTLSTransferCustomCertVerifier) {
470 SetMockCertVerifier(/*return_value=*/true);
471 TestHandshake(/*expect_success=*/true);
472 TestTransfer("Hello, world!");
473}
474
deadbeefed3b9862017-06-02 10:33:16 -0700475TEST_F(SSLAdapterTestTLS_RSA, TestTLSTransferWithBlockedSocket) {
476 TestHandshake(true);
477
478 // Tell the underlying socket to simulate being blocked.
479 vss_->SetSendingBlocked(true);
480
481 std::string expected;
482 int rv;
483 // Send messages until the SSL socket adapter starts applying backpressure.
484 // Note that this may not occur immediately since there may be some amount of
485 // intermediate buffering (either in our code or in BoringSSL).
486 for (int i = 0; i < 1024; ++i) {
487 std::string message = "Hello, world: " + rtc::ToString(i);
488 rv = client_->Send(message);
489 if (rv != static_cast<int>(message.size())) {
490 // This test assumes either the whole message or none of it is sent.
491 ASSERT_EQ(-1, rv);
492 break;
493 }
494 expected += message;
495 }
496 // Assert that the loop above exited due to Send returning -1.
497 ASSERT_EQ(-1, rv);
498
499 // Try sending another message while blocked. -1 should be returned again and
500 // it shouldn't end up received by the server later.
501 EXPECT_EQ(-1, client_->Send("Never sent"));
502
503 // Unblock the underlying socket. All of the buffered messages should be sent
504 // without any further action.
505 vss_->SetSendingBlocked(false);
506 EXPECT_EQ_WAIT(expected, server_->GetReceivedData(), kTimeout);
507
508 // Send another message. This previously wasn't working
509 std::string final_message = "Fin.";
510 expected += final_message;
511 EXPECT_EQ(static_cast<int>(final_message.size()),
512 client_->Send(final_message));
513 EXPECT_EQ_WAIT(expected, server_->GetReceivedData(), kTimeout);
514}
515
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200516// Test transfer between client and server, using ECDSA
517TEST_F(SSLAdapterTestTLS_ECDSA, TestTLSTransfer) {
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000518 TestHandshake(true);
519 TestTransfer("Hello, world!");
520}
521
Benjamin Wright6e9c3df2018-05-22 16:11:56 -0700522// Test transfer between client and server, using ECDSA with custom cert
523// verifier.
524TEST_F(SSLAdapterTestTLS_ECDSA, TestTLSTransferCustomCertVerifier) {
525 SetMockCertVerifier(/*return_value=*/true);
526 TestHandshake(/*expect_success=*/true);
527 TestTransfer("Hello, world!");
528}
529
Diogo Real1dca9d52017-08-29 12:18:32 -0700530// Test transfer using ALPN with protos as h2 and http/1.1
531TEST_F(SSLAdapterTestTLS_ECDSA, TestTLSALPN) {
532 std::vector<std::string> alpn_protos{"h2", "http/1.1"};
533 SetAlpnProtocols(alpn_protos);
534 TestHandshake(true);
535 TestTransfer("Hello, world!");
536}
537
Diogo Real7bd1f1b2017-09-08 12:50:41 -0700538// Test transfer with TLS Elliptic curves set to "X25519:P-256:P-384:P-521"
539TEST_F(SSLAdapterTestTLS_ECDSA, TestTLSEllipticCurves) {
540 std::vector<std::string> elliptic_curves{"X25519", "P-256", "P-384", "P-521"};
541 SetEllipticCurves(elliptic_curves);
542 TestHandshake(true);
543 TestTransfer("Hello, world!");
544}
545
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000546// Basic tests: DTLS
547
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200548// Test that handshake works, using RSA
549TEST_F(SSLAdapterTestDTLS_RSA, TestDTLSConnect) {
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000550 TestHandshake(true);
551}
552
Benjamin Wright6e9c3df2018-05-22 16:11:56 -0700553// Test that handshake works with a custom verifier that returns true. DTLS_RSA.
554TEST_F(SSLAdapterTestDTLS_RSA, TestDTLSConnectCustomCertVerifierSucceeds) {
555 SetMockCertVerifier(/*return_value=*/true);
556 TestHandshake(/*expect_success=*/true);
557}
558
559// Test that handshake fails with a custom verifier that returns false.
560// DTLS_RSA.
561TEST_F(SSLAdapterTestDTLS_RSA, TestTLSConnectCustomCertVerifierFails) {
562 SetMockCertVerifier(/*return_value=*/false);
563 TestHandshake(/*expect_success=*/false);
564}
565
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200566// Test that handshake works, using ECDSA
567TEST_F(SSLAdapterTestDTLS_ECDSA, TestDTLSConnect) {
568 TestHandshake(true);
569}
570
Benjamin Wright6e9c3df2018-05-22 16:11:56 -0700571// Test that handshake works with a custom verifier that returns true.
572// DTLS_ECDSA.
573TEST_F(SSLAdapterTestDTLS_ECDSA, TestDTLSConnectCustomCertVerifierSucceeds) {
574 SetMockCertVerifier(/*return_value=*/true);
575 TestHandshake(/*expect_success=*/true);
576}
577
578// Test that handshake fails with a custom verifier that returns false.
579// DTLS_ECDSA.
580TEST_F(SSLAdapterTestDTLS_ECDSA, TestTLSConnectCustomCertVerifierFails) {
581 SetMockCertVerifier(/*return_value=*/false);
582 TestHandshake(/*expect_success=*/false);
583}
584
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200585// Test transfer between client and server, using RSA
586TEST_F(SSLAdapterTestDTLS_RSA, TestDTLSTransfer) {
587 TestHandshake(true);
588 TestTransfer("Hello, world!");
589}
590
Benjamin Wright6e9c3df2018-05-22 16:11:56 -0700591// Test transfer between client and server, using RSA with custom cert verifier.
592TEST_F(SSLAdapterTestDTLS_RSA, TestDTLSTransferCustomCertVerifier) {
593 SetMockCertVerifier(/*return_value=*/true);
594 TestHandshake(/*expect_success=*/true);
595 TestTransfer("Hello, world!");
596}
597
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200598// Test transfer between client and server, using ECDSA
599TEST_F(SSLAdapterTestDTLS_ECDSA, TestDTLSTransfer) {
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000600 TestHandshake(true);
601 TestTransfer("Hello, world!");
602}
Benjamin Wright6e9c3df2018-05-22 16:11:56 -0700603
604// Test transfer between client and server, using ECDSA with custom cert
605// verifier.
606TEST_F(SSLAdapterTestDTLS_ECDSA, TestDTLSTransferCustomCertVerifier) {
607 SetMockCertVerifier(/*return_value=*/true);
608 TestHandshake(/*expect_success=*/true);
609 TestTransfer("Hello, world!");
610}