blob: 2b552110860ad58b5c864c6b22a3466176336daf [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
jbauch555604a2016-04-26 03:13:22 -070011#include <memory>
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +000012#include <string>
Benjamin Wright6e9c3df2018-05-22 16:11:56 -070013#include <utility>
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +000014
Harald Alvestrand8515d5a2020-03-20 22:51:32 +010015#include "absl/memory/memory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020016#include "rtc_base/gunit.h"
Steve Anton10542f22019-01-11 09:11:00 -080017#include "rtc_base/ip_address.h"
18#include "rtc_base/message_digest.h"
19#include "rtc_base/socket_stream.h"
20#include "rtc_base/ssl_adapter.h"
21#include "rtc_base/ssl_identity.h"
22#include "rtc_base/ssl_stream_adapter.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020023#include "rtc_base/stream.h"
Steve Anton10542f22019-01-11 09:11:00 -080024#include "rtc_base/string_encode.h"
25#include "rtc_base/virtual_socket_server.h"
Benjamin Wright6e9c3df2018-05-22 16:11:56 -070026#include "test/gmock.h"
27
28using ::testing::_;
29using ::testing::Return;
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +000030
31static const int kTimeout = 5000;
32
Niels Möllerd0b88792021-08-12 10:32:30 +020033static rtc::Socket* CreateSocket(const rtc::SSLMode& ssl_mode) {
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +000034 rtc::SocketAddress address(rtc::IPAddress(INADDR_ANY), 0);
35
Niels Möllerd0b88792021-08-12 10:32:30 +020036 rtc::Socket* socket = rtc::Thread::Current()->socketserver()->CreateSocket(
37 address.family(),
38 (ssl_mode == rtc::SSL_MODE_DTLS) ? SOCK_DGRAM : SOCK_STREAM);
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +000039 socket->Bind(address);
40
41 return socket;
42}
43
44static std::string GetSSLProtocolName(const rtc::SSLMode& ssl_mode) {
45 return (ssl_mode == rtc::SSL_MODE_DTLS) ? "DTLS" : "TLS";
46}
47
Benjamin Wright6e9c3df2018-05-22 16:11:56 -070048// Simple mock for the certificate verifier.
49class MockCertVerifier : public rtc::SSLCertificateVerifier {
50 public:
51 virtual ~MockCertVerifier() = default;
Danil Chapovalov42748d82020-05-14 20:42:41 +020052 MOCK_METHOD(bool, Verify, (const rtc::SSLCertificate&), (override));
Benjamin Wright6e9c3df2018-05-22 16:11:56 -070053};
54
Mirko Bonadeic84f6612019-01-31 12:20:57 +010055// TODO(benwright) - Move to using INSTANTIATE_TEST_SUITE_P instead of using
Benjamin Wright6e9c3df2018-05-22 16:11:56 -070056// duplicate test cases for simple parameter changes.
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +000057class SSLAdapterTestDummyClient : public sigslot::has_slots<> {
58 public:
59 explicit SSLAdapterTestDummyClient(const rtc::SSLMode& ssl_mode)
60 : ssl_mode_(ssl_mode) {
Niels Möllerd0b88792021-08-12 10:32:30 +020061 rtc::Socket* socket = CreateSocket(ssl_mode_);
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +000062
63 ssl_adapter_.reset(rtc::SSLAdapter::Create(socket));
64
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +000065 ssl_adapter_->SetMode(ssl_mode_);
66
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +000067 // Ignore any certificate errors for the purpose of testing.
68 // Note: We do this only because we don't have a real certificate.
69 // NEVER USE THIS IN PRODUCTION CODE!
Sergey Silkin9c147dd2018-09-12 10:45:38 +000070 ssl_adapter_->SetIgnoreBadCert(true);
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +000071
Yves Gerey665174f2018-06-19 15:03:05 +020072 ssl_adapter_->SignalReadEvent.connect(
73 this, &SSLAdapterTestDummyClient::OnSSLAdapterReadEvent);
74 ssl_adapter_->SignalCloseEvent.connect(
75 this, &SSLAdapterTestDummyClient::OnSSLAdapterCloseEvent);
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +000076 }
77
Sergey Silkin9c147dd2018-09-12 10:45:38 +000078 void SetIgnoreBadCert(bool ignore_bad_cert) {
79 ssl_adapter_->SetIgnoreBadCert(ignore_bad_cert);
Benjamin Wright6e9c3df2018-05-22 16:11:56 -070080 }
81
82 void SetCertVerifier(rtc::SSLCertificateVerifier* ssl_cert_verifier) {
83 ssl_adapter_->SetCertVerifier(ssl_cert_verifier);
84 }
85
Sergey Silkin9c147dd2018-09-12 10:45:38 +000086 void SetAlpnProtocols(const std::vector<std::string>& protos) {
87 ssl_adapter_->SetAlpnProtocols(protos);
88 }
89
90 void SetEllipticCurves(const std::vector<std::string>& curves) {
91 ssl_adapter_->SetEllipticCurves(curves);
92 }
93
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +000094 rtc::SocketAddress GetAddress() const {
95 return ssl_adapter_->GetLocalAddress();
96 }
97
Niels Möllerd0b88792021-08-12 10:32:30 +020098 rtc::Socket::ConnState GetState() const { return ssl_adapter_->GetState(); }
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +000099
Yves Gerey665174f2018-06-19 15:03:05 +0200100 const std::string& GetReceivedData() const { return data_; }
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000101
102 int Connect(const std::string& hostname, const rtc::SocketAddress& address) {
Jonas Olssonabbe8412018-04-03 13:40:05 +0200103 RTC_LOG(LS_INFO) << "Initiating connection with " << address.ToString();
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000104
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000105 int rv = ssl_adapter_->Connect(address);
106
107 if (rv == 0) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100108 RTC_LOG(LS_INFO) << "Starting " << GetSSLProtocolName(ssl_mode_)
109 << " handshake with " << hostname;
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000110
Mirko Bonadei2d2c2942020-04-11 00:01:43 +0200111 if (ssl_adapter_->StartSSL(hostname.c_str()) != 0) {
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000112 return -1;
113 }
114 }
115
116 return rv;
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000117 }
118
Yves Gerey665174f2018-06-19 15:03:05 +0200119 int Close() { return ssl_adapter_->Close(); }
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000120
121 int Send(const std::string& message) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100122 RTC_LOG(LS_INFO) << "Client sending '" << message << "'";
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000123
124 return ssl_adapter_->Send(message.data(), message.length());
125 }
126
Niels Möllerd0b88792021-08-12 10:32:30 +0200127 void OnSSLAdapterReadEvent(rtc::Socket* socket) {
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000128 char buffer[4096] = "";
129
130 // Read data received from the server and store it in our internal buffer.
Stefan Holmer9131efd2016-05-23 18:19:26 +0200131 int read = socket->Recv(buffer, sizeof(buffer) - 1, nullptr);
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000132 if (read != -1) {
133 buffer[read] = '\0';
134
Mirko Bonadei675513b2017-11-09 11:09:25 +0100135 RTC_LOG(LS_INFO) << "Client received '" << buffer << "'";
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000136
137 data_ += buffer;
138 }
139 }
140
Niels Möllerd0b88792021-08-12 10:32:30 +0200141 void OnSSLAdapterCloseEvent(rtc::Socket* socket, int error) {
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000142 // OpenSSLAdapter signals handshake failure with a close event, but without
143 // closing the socket! Let's close the socket here. This way GetState() can
144 // return CS_CLOSED after failure.
Niels Möllerd0b88792021-08-12 10:32:30 +0200145 if (socket->GetState() != rtc::Socket::CS_CLOSED) {
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000146 socket->Close();
147 }
148 }
149
150 private:
151 const rtc::SSLMode ssl_mode_;
152
jbauch555604a2016-04-26 03:13:22 -0700153 std::unique_ptr<rtc::SSLAdapter> ssl_adapter_;
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000154
155 std::string data_;
156};
157
158class SSLAdapterTestDummyServer : public sigslot::has_slots<> {
159 public:
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200160 explicit SSLAdapterTestDummyServer(const rtc::SSLMode& ssl_mode,
torbjorng4e572472015-10-08 09:42:49 -0700161 const rtc::KeyParams& key_params)
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000162 : ssl_mode_(ssl_mode) {
163 // Generate a key pair and a certificate for this host.
Harald Alvestrand8515d5a2020-03-20 22:51:32 +0100164 ssl_identity_ = rtc::SSLIdentity::Create(GetHostname(), key_params);
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000165
166 server_socket_.reset(CreateSocket(ssl_mode_));
167
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000168 if (ssl_mode_ == rtc::SSL_MODE_TLS) {
Yves Gerey665174f2018-06-19 15:03:05 +0200169 server_socket_->SignalReadEvent.connect(
170 this, &SSLAdapterTestDummyServer::OnServerSocketReadEvent);
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000171
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000172 server_socket_->Listen(1);
173 }
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000174
Mirko Bonadei675513b2017-11-09 11:09:25 +0100175 RTC_LOG(LS_INFO) << ((ssl_mode_ == rtc::SSL_MODE_DTLS) ? "UDP" : "TCP")
176 << " server listening on "
Jonas Olssonabbe8412018-04-03 13:40:05 +0200177 << server_socket_->GetLocalAddress().ToString();
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000178 }
179
180 rtc::SocketAddress GetAddress() const {
181 return server_socket_->GetLocalAddress();
182 }
183
184 std::string GetHostname() const {
185 // Since we don't have a real certificate anyway, the value here doesn't
186 // really matter.
187 return "example.com";
188 }
189
Yves Gerey665174f2018-06-19 15:03:05 +0200190 const std::string& GetReceivedData() const { return data_; }
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000191
192 int Send(const std::string& message) {
deadbeef37f5ecf2017-02-27 14:06:41 -0800193 if (ssl_stream_adapter_ == nullptr ||
194 ssl_stream_adapter_->GetState() != rtc::SS_OPEN) {
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000195 // No connection yet.
196 return -1;
197 }
198
Mirko Bonadei675513b2017-11-09 11:09:25 +0100199 RTC_LOG(LS_INFO) << "Server sending '" << message << "'";
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000200
201 size_t written;
202 int error;
203
Yves Gerey665174f2018-06-19 15:03:05 +0200204 rtc::StreamResult r = ssl_stream_adapter_->Write(
205 message.data(), message.length(), &written, &error);
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000206 if (r == rtc::SR_SUCCESS) {
207 return written;
208 } else {
209 return -1;
210 }
211 }
212
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000213 void AcceptConnection(const rtc::SocketAddress& address) {
214 // Only a single connection is supported.
deadbeef37f5ecf2017-02-27 14:06:41 -0800215 ASSERT_TRUE(ssl_stream_adapter_ == nullptr);
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000216
217 // This is only for DTLS.
218 ASSERT_EQ(rtc::SSL_MODE_DTLS, ssl_mode_);
219
220 // Transfer ownership of the socket to the SSLStreamAdapter object.
Niels Möllerd0b88792021-08-12 10:32:30 +0200221 rtc::Socket* socket = server_socket_.release();
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000222
223 socket->Connect(address);
224
225 DoHandshake(socket);
226 }
227
Niels Möllerd0b88792021-08-12 10:32:30 +0200228 void OnServerSocketReadEvent(rtc::Socket* socket) {
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000229 // Only a single connection is supported.
deadbeef37f5ecf2017-02-27 14:06:41 -0800230 ASSERT_TRUE(ssl_stream_adapter_ == nullptr);
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000231
deadbeef37f5ecf2017-02-27 14:06:41 -0800232 DoHandshake(server_socket_->Accept(nullptr));
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000233 }
234
235 void OnSSLStreamAdapterEvent(rtc::StreamInterface* stream, int sig, int err) {
236 if (sig & rtc::SE_READ) {
237 char buffer[4096] = "";
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000238 size_t read;
239 int error;
240
241 // Read data received from the client and store it in our internal
242 // buffer.
deadbeefed3b9862017-06-02 10:33:16 -0700243 rtc::StreamResult r =
244 stream->Read(buffer, sizeof(buffer) - 1, &read, &error);
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000245 if (r == rtc::SR_SUCCESS) {
246 buffer[read] = '\0';
Mirko Bonadei675513b2017-11-09 11:09:25 +0100247 RTC_LOG(LS_INFO) << "Server received '" << buffer << "'";
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000248 data_ += buffer;
249 }
250 }
251 }
252
253 private:
Niels Möllerd0b88792021-08-12 10:32:30 +0200254 void DoHandshake(rtc::Socket* socket) {
Harald Alvestrand8515d5a2020-03-20 22:51:32 +0100255 ssl_stream_adapter_ = rtc::SSLStreamAdapter::Create(
256 std::make_unique<rtc::SocketStream>(socket));
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000257
258 ssl_stream_adapter_->SetMode(ssl_mode_);
259 ssl_stream_adapter_->SetServerRole();
260
261 // SSLStreamAdapter is normally used for peer-to-peer communication, but
262 // here we're testing communication between a client and a server
263 // (e.g. a WebRTC-based application and an RFC 5766 TURN server), where
264 // clients are not required to provide a certificate during handshake.
265 // Accordingly, we must disable client authentication here.
Benjamin Wrightb19b4972018-10-25 10:46:49 -0700266 ssl_stream_adapter_->SetClientAuthEnabledForTesting(false);
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000267
Harald Alvestrand8515d5a2020-03-20 22:51:32 +0100268 ssl_stream_adapter_->SetIdentity(ssl_identity_->Clone());
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000269
270 // Set a bogus peer certificate digest.
271 unsigned char digest[20];
272 size_t digest_len = sizeof(digest);
273 ssl_stream_adapter_->SetPeerCertificateDigest(rtc::DIGEST_SHA_1, digest,
Yves Gerey665174f2018-06-19 15:03:05 +0200274 digest_len);
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000275
Taylor Brandstetterc8762a82016-08-11 12:01:49 -0700276 ssl_stream_adapter_->StartSSL();
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000277
Yves Gerey665174f2018-06-19 15:03:05 +0200278 ssl_stream_adapter_->SignalEvent.connect(
279 this, &SSLAdapterTestDummyServer::OnSSLStreamAdapterEvent);
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000280 }
281
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000282 const rtc::SSLMode ssl_mode_;
283
Niels Möllerd0b88792021-08-12 10:32:30 +0200284 std::unique_ptr<rtc::Socket> server_socket_;
jbauch555604a2016-04-26 03:13:22 -0700285 std::unique_ptr<rtc::SSLStreamAdapter> ssl_stream_adapter_;
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000286
jbauch555604a2016-04-26 03:13:22 -0700287 std::unique_ptr<rtc::SSLIdentity> ssl_identity_;
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000288
289 std::string data_;
290};
291
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200292class SSLAdapterTestBase : public ::testing::Test, public sigslot::has_slots<> {
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000293 public:
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200294 explicit SSLAdapterTestBase(const rtc::SSLMode& ssl_mode,
torbjorng4e572472015-10-08 09:42:49 -0700295 const rtc::KeyParams& key_params)
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000296 : ssl_mode_(ssl_mode),
deadbeef98e186c2017-05-16 18:00:06 -0700297 vss_(new rtc::VirtualSocketServer()),
nisse7eaa4ea2017-05-08 05:25:41 -0700298 thread_(vss_.get()),
torbjorng4e572472015-10-08 09:42:49 -0700299 server_(new SSLAdapterTestDummyServer(ssl_mode_, key_params)),
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000300 client_(new SSLAdapterTestDummyClient(ssl_mode_)),
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200301 handshake_wait_(kTimeout) {}
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000302
Yves Gerey665174f2018-06-19 15:03:05 +0200303 void SetHandshakeWait(int wait) { handshake_wait_ = wait; }
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000304
Sergey Silkin9c147dd2018-09-12 10:45:38 +0000305 void SetIgnoreBadCert(bool ignore_bad_cert) {
306 client_->SetIgnoreBadCert(ignore_bad_cert);
Benjamin Wright6e9c3df2018-05-22 16:11:56 -0700307 }
308
309 void SetCertVerifier(rtc::SSLCertificateVerifier* ssl_cert_verifier) {
310 client_->SetCertVerifier(ssl_cert_verifier);
311 }
312
Sergey Silkin9c147dd2018-09-12 10:45:38 +0000313 void SetAlpnProtocols(const std::vector<std::string>& protos) {
314 client_->SetAlpnProtocols(protos);
315 }
316
317 void SetEllipticCurves(const std::vector<std::string>& curves) {
318 client_->SetEllipticCurves(curves);
319 }
320
Benjamin Wright6e9c3df2018-05-22 16:11:56 -0700321 void SetMockCertVerifier(bool return_value) {
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200322 auto mock_verifier = std::make_unique<MockCertVerifier>();
Benjamin Wright6e9c3df2018-05-22 16:11:56 -0700323 EXPECT_CALL(*mock_verifier, Verify(_)).WillRepeatedly(Return(return_value));
324 cert_verifier_ =
325 std::unique_ptr<rtc::SSLCertificateVerifier>(std::move(mock_verifier));
326
Sergey Silkin9c147dd2018-09-12 10:45:38 +0000327 SetIgnoreBadCert(false);
Benjamin Wright6e9c3df2018-05-22 16:11:56 -0700328 SetCertVerifier(cert_verifier_.get());
329 }
330
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000331 void TestHandshake(bool expect_success) {
332 int rv;
333
334 // The initial state is CS_CLOSED
Niels Möllerd0b88792021-08-12 10:32:30 +0200335 ASSERT_EQ(rtc::Socket::CS_CLOSED, client_->GetState());
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000336
337 rv = client_->Connect(server_->GetHostname(), server_->GetAddress());
338 ASSERT_EQ(0, rv);
339
340 // Now the state should be CS_CONNECTING
Niels Möllerd0b88792021-08-12 10:32:30 +0200341 ASSERT_EQ(rtc::Socket::CS_CONNECTING, client_->GetState());
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000342
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000343 if (ssl_mode_ == rtc::SSL_MODE_DTLS) {
344 // For DTLS, call AcceptConnection() with the client's address.
345 server_->AcceptConnection(client_->GetAddress());
346 }
347
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000348 if (expect_success) {
349 // If expecting success, the client should end up in the CS_CONNECTED
350 // state after handshake.
Niels Möllerd0b88792021-08-12 10:32:30 +0200351 EXPECT_EQ_WAIT(rtc::Socket::CS_CONNECTED, client_->GetState(),
Yves Gerey665174f2018-06-19 15:03:05 +0200352 handshake_wait_);
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000353
Mirko Bonadei675513b2017-11-09 11:09:25 +0100354 RTC_LOG(LS_INFO) << GetSSLProtocolName(ssl_mode_)
355 << " handshake complete.";
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000356
357 } else {
358 // On handshake failure the client should end up in the CS_CLOSED state.
Niels Möllerd0b88792021-08-12 10:32:30 +0200359 EXPECT_EQ_WAIT(rtc::Socket::CS_CLOSED, client_->GetState(),
Yves Gerey665174f2018-06-19 15:03:05 +0200360 handshake_wait_);
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000361
Mirko Bonadei675513b2017-11-09 11:09:25 +0100362 RTC_LOG(LS_INFO) << GetSSLProtocolName(ssl_mode_) << " handshake failed.";
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000363 }
364 }
365
366 void TestTransfer(const std::string& message) {
367 int rv;
368
369 rv = client_->Send(message);
370 ASSERT_EQ(static_cast<int>(message.length()), rv);
371
372 // The server should have received the client's message.
373 EXPECT_EQ_WAIT(message, server_->GetReceivedData(), kTimeout);
374
375 rv = server_->Send(message);
376 ASSERT_EQ(static_cast<int>(message.length()), rv);
377
378 // The client should have received the server's message.
379 EXPECT_EQ_WAIT(message, client_->GetReceivedData(), kTimeout);
380
Mirko Bonadei675513b2017-11-09 11:09:25 +0100381 RTC_LOG(LS_INFO) << "Transfer complete.";
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000382 }
383
deadbeefed3b9862017-06-02 10:33:16 -0700384 protected:
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000385 const rtc::SSLMode ssl_mode_;
386
nisse7eaa4ea2017-05-08 05:25:41 -0700387 std::unique_ptr<rtc::VirtualSocketServer> vss_;
388 rtc::AutoSocketServerThread thread_;
jbauch555604a2016-04-26 03:13:22 -0700389 std::unique_ptr<SSLAdapterTestDummyServer> server_;
390 std::unique_ptr<SSLAdapterTestDummyClient> client_;
Benjamin Wright6e9c3df2018-05-22 16:11:56 -0700391 std::unique_ptr<rtc::SSLCertificateVerifier> cert_verifier_;
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000392
393 int handshake_wait_;
394};
395
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200396class SSLAdapterTestTLS_RSA : public SSLAdapterTestBase {
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000397 public:
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200398 SSLAdapterTestTLS_RSA()
torbjorng4e572472015-10-08 09:42:49 -0700399 : SSLAdapterTestBase(rtc::SSL_MODE_TLS, rtc::KeyParams::RSA()) {}
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000400};
401
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200402class SSLAdapterTestTLS_ECDSA : public SSLAdapterTestBase {
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000403 public:
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200404 SSLAdapterTestTLS_ECDSA()
torbjorng4e572472015-10-08 09:42:49 -0700405 : SSLAdapterTestBase(rtc::SSL_MODE_TLS, rtc::KeyParams::ECDSA()) {}
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200406};
407
408class SSLAdapterTestDTLS_RSA : public SSLAdapterTestBase {
409 public:
410 SSLAdapterTestDTLS_RSA()
torbjorng4e572472015-10-08 09:42:49 -0700411 : SSLAdapterTestBase(rtc::SSL_MODE_DTLS, rtc::KeyParams::RSA()) {}
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200412};
413
414class SSLAdapterTestDTLS_ECDSA : public SSLAdapterTestBase {
415 public:
416 SSLAdapterTestDTLS_ECDSA()
torbjorng4e572472015-10-08 09:42:49 -0700417 : SSLAdapterTestBase(rtc::SSL_MODE_DTLS, rtc::KeyParams::ECDSA()) {}
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000418};
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000419
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000420// Basic tests: TLS
421
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200422// Test that handshake works, using RSA
423TEST_F(SSLAdapterTestTLS_RSA, TestTLSConnect) {
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000424 TestHandshake(true);
425}
426
Benjamin Wright6e9c3df2018-05-22 16:11:56 -0700427// Test that handshake works with a custom verifier that returns true. RSA.
428TEST_F(SSLAdapterTestTLS_RSA, TestTLSConnectCustomCertVerifierSucceeds) {
429 SetMockCertVerifier(/*return_value=*/true);
430 TestHandshake(/*expect_success=*/true);
431}
432
433// Test that handshake fails with a custom verifier that returns false. RSA.
434TEST_F(SSLAdapterTestTLS_RSA, TestTLSConnectCustomCertVerifierFails) {
435 SetMockCertVerifier(/*return_value=*/false);
436 TestHandshake(/*expect_success=*/false);
437}
438
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200439// Test that handshake works, using ECDSA
440TEST_F(SSLAdapterTestTLS_ECDSA, TestTLSConnect) {
Benjamin Wright6e9c3df2018-05-22 16:11:56 -0700441 SetMockCertVerifier(/*return_value=*/true);
442 TestHandshake(/*expect_success=*/true);
443}
444
445// Test that handshake works with a custom verifier that returns true. ECDSA.
446TEST_F(SSLAdapterTestTLS_ECDSA, TestTLSConnectCustomCertVerifierSucceeds) {
447 SetMockCertVerifier(/*return_value=*/true);
448 TestHandshake(/*expect_success=*/true);
449}
450
451// Test that handshake fails with a custom verifier that returns false. ECDSA.
452TEST_F(SSLAdapterTestTLS_ECDSA, TestTLSConnectCustomCertVerifierFails) {
453 SetMockCertVerifier(/*return_value=*/false);
454 TestHandshake(/*expect_success=*/false);
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200455}
456
457// Test transfer between client and server, using RSA
458TEST_F(SSLAdapterTestTLS_RSA, TestTLSTransfer) {
459 TestHandshake(true);
460 TestTransfer("Hello, world!");
461}
462
Benjamin Wright6e9c3df2018-05-22 16:11:56 -0700463// Test transfer between client and server, using RSA with custom cert verifier.
464TEST_F(SSLAdapterTestTLS_RSA, TestTLSTransferCustomCertVerifier) {
465 SetMockCertVerifier(/*return_value=*/true);
466 TestHandshake(/*expect_success=*/true);
467 TestTransfer("Hello, world!");
468}
469
deadbeefed3b9862017-06-02 10:33:16 -0700470TEST_F(SSLAdapterTestTLS_RSA, TestTLSTransferWithBlockedSocket) {
471 TestHandshake(true);
472
473 // Tell the underlying socket to simulate being blocked.
474 vss_->SetSendingBlocked(true);
475
476 std::string expected;
477 int rv;
478 // Send messages until the SSL socket adapter starts applying backpressure.
479 // Note that this may not occur immediately since there may be some amount of
480 // intermediate buffering (either in our code or in BoringSSL).
481 for (int i = 0; i < 1024; ++i) {
482 std::string message = "Hello, world: " + rtc::ToString(i);
483 rv = client_->Send(message);
484 if (rv != static_cast<int>(message.size())) {
485 // This test assumes either the whole message or none of it is sent.
486 ASSERT_EQ(-1, rv);
487 break;
488 }
489 expected += message;
490 }
491 // Assert that the loop above exited due to Send returning -1.
492 ASSERT_EQ(-1, rv);
493
494 // Try sending another message while blocked. -1 should be returned again and
495 // it shouldn't end up received by the server later.
496 EXPECT_EQ(-1, client_->Send("Never sent"));
497
498 // Unblock the underlying socket. All of the buffered messages should be sent
499 // without any further action.
500 vss_->SetSendingBlocked(false);
501 EXPECT_EQ_WAIT(expected, server_->GetReceivedData(), kTimeout);
502
503 // Send another message. This previously wasn't working
504 std::string final_message = "Fin.";
505 expected += final_message;
506 EXPECT_EQ(static_cast<int>(final_message.size()),
507 client_->Send(final_message));
508 EXPECT_EQ_WAIT(expected, server_->GetReceivedData(), kTimeout);
509}
510
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200511// Test transfer between client and server, using ECDSA
512TEST_F(SSLAdapterTestTLS_ECDSA, TestTLSTransfer) {
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000513 TestHandshake(true);
514 TestTransfer("Hello, world!");
515}
516
Benjamin Wright6e9c3df2018-05-22 16:11:56 -0700517// Test transfer between client and server, using ECDSA with custom cert
518// verifier.
519TEST_F(SSLAdapterTestTLS_ECDSA, TestTLSTransferCustomCertVerifier) {
520 SetMockCertVerifier(/*return_value=*/true);
521 TestHandshake(/*expect_success=*/true);
522 TestTransfer("Hello, world!");
523}
524
Diogo Real1dca9d52017-08-29 12:18:32 -0700525// Test transfer using ALPN with protos as h2 and http/1.1
526TEST_F(SSLAdapterTestTLS_ECDSA, TestTLSALPN) {
527 std::vector<std::string> alpn_protos{"h2", "http/1.1"};
528 SetAlpnProtocols(alpn_protos);
529 TestHandshake(true);
530 TestTransfer("Hello, world!");
531}
532
Diogo Real7bd1f1b2017-09-08 12:50:41 -0700533// Test transfer with TLS Elliptic curves set to "X25519:P-256:P-384:P-521"
534TEST_F(SSLAdapterTestTLS_ECDSA, TestTLSEllipticCurves) {
535 std::vector<std::string> elliptic_curves{"X25519", "P-256", "P-384", "P-521"};
536 SetEllipticCurves(elliptic_curves);
537 TestHandshake(true);
538 TestTransfer("Hello, world!");
539}
540
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000541// Basic tests: DTLS
542
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200543// Test that handshake works, using RSA
544TEST_F(SSLAdapterTestDTLS_RSA, TestDTLSConnect) {
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000545 TestHandshake(true);
546}
547
Benjamin Wright6e9c3df2018-05-22 16:11:56 -0700548// Test that handshake works with a custom verifier that returns true. DTLS_RSA.
549TEST_F(SSLAdapterTestDTLS_RSA, TestDTLSConnectCustomCertVerifierSucceeds) {
550 SetMockCertVerifier(/*return_value=*/true);
551 TestHandshake(/*expect_success=*/true);
552}
553
554// Test that handshake fails with a custom verifier that returns false.
555// DTLS_RSA.
556TEST_F(SSLAdapterTestDTLS_RSA, TestTLSConnectCustomCertVerifierFails) {
557 SetMockCertVerifier(/*return_value=*/false);
558 TestHandshake(/*expect_success=*/false);
559}
560
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200561// Test that handshake works, using ECDSA
562TEST_F(SSLAdapterTestDTLS_ECDSA, TestDTLSConnect) {
563 TestHandshake(true);
564}
565
Benjamin Wright6e9c3df2018-05-22 16:11:56 -0700566// Test that handshake works with a custom verifier that returns true.
567// DTLS_ECDSA.
568TEST_F(SSLAdapterTestDTLS_ECDSA, TestDTLSConnectCustomCertVerifierSucceeds) {
569 SetMockCertVerifier(/*return_value=*/true);
570 TestHandshake(/*expect_success=*/true);
571}
572
573// Test that handshake fails with a custom verifier that returns false.
574// DTLS_ECDSA.
575TEST_F(SSLAdapterTestDTLS_ECDSA, TestTLSConnectCustomCertVerifierFails) {
576 SetMockCertVerifier(/*return_value=*/false);
577 TestHandshake(/*expect_success=*/false);
578}
579
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200580// Test transfer between client and server, using RSA
581TEST_F(SSLAdapterTestDTLS_RSA, TestDTLSTransfer) {
582 TestHandshake(true);
583 TestTransfer("Hello, world!");
584}
585
Benjamin Wright6e9c3df2018-05-22 16:11:56 -0700586// Test transfer between client and server, using RSA with custom cert verifier.
587TEST_F(SSLAdapterTestDTLS_RSA, TestDTLSTransferCustomCertVerifier) {
588 SetMockCertVerifier(/*return_value=*/true);
589 TestHandshake(/*expect_success=*/true);
590 TestTransfer("Hello, world!");
591}
592
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200593// Test transfer between client and server, using ECDSA
594TEST_F(SSLAdapterTestDTLS_ECDSA, TestDTLSTransfer) {
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000595 TestHandshake(true);
596 TestTransfer("Hello, world!");
597}
Benjamin Wright6e9c3df2018-05-22 16:11:56 -0700598
599// Test transfer between client and server, using ECDSA with custom cert
600// verifier.
601TEST_F(SSLAdapterTestDTLS_ECDSA, TestDTLSTransferCustomCertVerifier) {
602 SetMockCertVerifier(/*return_value=*/true);
603 TestHandshake(/*expect_success=*/true);
604 TestTransfer("Hello, world!");
605}