blob: cd63249190e7bf4c13f72d4bfe60c82f6323cfe4 [file] [log] [blame]
tkchin@webrtc.orgc569a492014-09-23 05:56:441/*
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 14:47:4911#include "rtc_base/ssl_adapter.h"
12
jbauch555604a2016-04-26 10:13:2213#include <memory>
tkchin@webrtc.orgc569a492014-09-23 05:56:4414#include <string>
Benjamin Wright6e9c3df2018-05-22 23:11:5615#include <utility>
tkchin@webrtc.orgc569a492014-09-23 05:56:4416
Harald Alvestrand8515d5a2020-03-20 21:51:3217#include "absl/memory/memory.h"
Ali Tofigh7fa90572022-03-17 14:47:4918#include "absl/strings/string_view.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3119#include "rtc_base/gunit.h"
Steve Anton10542f22019-01-11 17:11:0020#include "rtc_base/ip_address.h"
21#include "rtc_base/message_digest.h"
22#include "rtc_base/socket_stream.h"
Steve Anton10542f22019-01-11 17:11:0023#include "rtc_base/ssl_identity.h"
24#include "rtc_base/ssl_stream_adapter.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3125#include "rtc_base/stream.h"
Steve Anton10542f22019-01-11 17:11:0026#include "rtc_base/string_encode.h"
27#include "rtc_base/virtual_socket_server.h"
Benjamin Wright6e9c3df2018-05-22 23:11:5628#include "test/gmock.h"
29
30using ::testing::_;
31using ::testing::Return;
tkchin@webrtc.orgc569a492014-09-23 05:56:4432
33static const int kTimeout = 5000;
34
Niels Möllerd0b88792021-08-12 08:32:3035static rtc::Socket* CreateSocket(const rtc::SSLMode& ssl_mode) {
tkchin@webrtc.orgc569a492014-09-23 05:56:4436 rtc::SocketAddress address(rtc::IPAddress(INADDR_ANY), 0);
37
Niels Möllerd0b88792021-08-12 08:32:3038 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:4441 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 23:11:5650// Simple mock for the certificate verifier.
51class MockCertVerifier : public rtc::SSLCertificateVerifier {
52 public:
53 virtual ~MockCertVerifier() = default;
Danil Chapovalov42748d82020-05-14 18:42:4154 MOCK_METHOD(bool, Verify, (const rtc::SSLCertificate&), (override));
Benjamin Wright6e9c3df2018-05-22 23:11:5655};
56
Mirko Bonadeic84f6612019-01-31 11:20:5757// TODO(benwright) - Move to using INSTANTIATE_TEST_SUITE_P instead of using
Benjamin Wright6e9c3df2018-05-22 23:11:5658// duplicate test cases for simple parameter changes.
tkchin@webrtc.orgc569a492014-09-23 05:56:4459class 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 08:32:3063 rtc::Socket* socket = CreateSocket(ssl_mode_);
tkchin@webrtc.orgc569a492014-09-23 05:56:4464
65 ssl_adapter_.reset(rtc::SSLAdapter::Create(socket));
66
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:1467 ssl_adapter_->SetMode(ssl_mode_);
68
tkchin@webrtc.orgc569a492014-09-23 05:56:4469 // 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:3872 ssl_adapter_->SetIgnoreBadCert(true);
tkchin@webrtc.orgc569a492014-09-23 05:56:4473
Yves Gerey665174f2018-06-19 13:03:0574 ssl_adapter_->SignalReadEvent.connect(
75 this, &SSLAdapterTestDummyClient::OnSSLAdapterReadEvent);
76 ssl_adapter_->SignalCloseEvent.connect(
77 this, &SSLAdapterTestDummyClient::OnSSLAdapterCloseEvent);
tkchin@webrtc.orgc569a492014-09-23 05:56:4478 }
79
Sergey Silkin9c147dd2018-09-12 10:45:3880 void SetIgnoreBadCert(bool ignore_bad_cert) {
81 ssl_adapter_->SetIgnoreBadCert(ignore_bad_cert);
Benjamin Wright6e9c3df2018-05-22 23:11:5682 }
83
84 void SetCertVerifier(rtc::SSLCertificateVerifier* ssl_cert_verifier) {
85 ssl_adapter_->SetCertVerifier(ssl_cert_verifier);
86 }
87
Sergey Silkin9c147dd2018-09-12 10:45:3888 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:1496 rtc::SocketAddress GetAddress() const {
97 return ssl_adapter_->GetLocalAddress();
98 }
99
Niels Möllerd0b88792021-08-12 08:32:30100 rtc::Socket::ConnState GetState() const { return ssl_adapter_->GetState(); }
tkchin@webrtc.orgc569a492014-09-23 05:56:44101
Yves Gerey665174f2018-06-19 13:03:05102 const std::string& GetReceivedData() const { return data_; }
tkchin@webrtc.orgc569a492014-09-23 05:56:44103
Ali Tofigh7fa90572022-03-17 14:47:49104 int Connect(absl::string_view hostname, const rtc::SocketAddress& address) {
Jonas Olssonabbe8412018-04-03 11:40:05105 RTC_LOG(LS_INFO) << "Initiating connection with " << address.ToString();
tkchin@webrtc.orgc569a492014-09-23 05:56:44106
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14107 int rv = ssl_adapter_->Connect(address);
108
109 if (rv == 0) {
Mirko Bonadei675513b2017-11-09 10:09:25110 RTC_LOG(LS_INFO) << "Starting " << GetSSLProtocolName(ssl_mode_)
111 << " handshake with " << hostname;
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14112
Ali Tofigh2ab914c2022-04-13 10:55:15113 if (ssl_adapter_->StartSSL(hostname) != 0) {
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14114 return -1;
115 }
116 }
117
118 return rv;
tkchin@webrtc.orgc569a492014-09-23 05:56:44119 }
120
Yves Gerey665174f2018-06-19 13:03:05121 int Close() { return ssl_adapter_->Close(); }
tkchin@webrtc.orgc569a492014-09-23 05:56:44122
Ali Tofigh7fa90572022-03-17 14:47:49123 int Send(absl::string_view message) {
Mirko Bonadei675513b2017-11-09 10:09:25124 RTC_LOG(LS_INFO) << "Client sending '" << message << "'";
tkchin@webrtc.orgc569a492014-09-23 05:56:44125
126 return ssl_adapter_->Send(message.data(), message.length());
127 }
128
Niels Möllerd0b88792021-08-12 08:32:30129 void OnSSLAdapterReadEvent(rtc::Socket* socket) {
tkchin@webrtc.orgc569a492014-09-23 05:56:44130 char buffer[4096] = "";
131
132 // Read data received from the server and store it in our internal buffer.
Stefan Holmer9131efd2016-05-23 16:19:26133 int read = socket->Recv(buffer, sizeof(buffer) - 1, nullptr);
tkchin@webrtc.orgc569a492014-09-23 05:56:44134 if (read != -1) {
135 buffer[read] = '\0';
136
Mirko Bonadei675513b2017-11-09 10:09:25137 RTC_LOG(LS_INFO) << "Client received '" << buffer << "'";
tkchin@webrtc.orgc569a492014-09-23 05:56:44138
139 data_ += buffer;
140 }
141 }
142
Niels Möllerd0b88792021-08-12 08:32:30143 void OnSSLAdapterCloseEvent(rtc::Socket* socket, int error) {
tkchin@webrtc.orgc569a492014-09-23 05:56:44144 // 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 08:32:30147 if (socket->GetState() != rtc::Socket::CS_CLOSED) {
tkchin@webrtc.orgc569a492014-09-23 05:56:44148 socket->Close();
149 }
150 }
151
152 private:
153 const rtc::SSLMode ssl_mode_;
154
jbauch555604a2016-04-26 10:13:22155 std::unique_ptr<rtc::SSLAdapter> ssl_adapter_;
tkchin@webrtc.orgc569a492014-09-23 05:56:44156
157 std::string data_;
158};
159
160class SSLAdapterTestDummyServer : public sigslot::has_slots<> {
161 public:
Torbjorn Granlundb6d4ec42015-08-17 12:08:59162 explicit SSLAdapterTestDummyServer(const rtc::SSLMode& ssl_mode,
torbjorng4e572472015-10-08 16:42:49163 const rtc::KeyParams& key_params)
tkchin@webrtc.orgc569a492014-09-23 05:56:44164 : ssl_mode_(ssl_mode) {
165 // Generate a key pair and a certificate for this host.
Harald Alvestrand8515d5a2020-03-20 21:51:32166 ssl_identity_ = rtc::SSLIdentity::Create(GetHostname(), key_params);
tkchin@webrtc.orgc569a492014-09-23 05:56:44167
168 server_socket_.reset(CreateSocket(ssl_mode_));
169
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14170 if (ssl_mode_ == rtc::SSL_MODE_TLS) {
Yves Gerey665174f2018-06-19 13:03:05171 server_socket_->SignalReadEvent.connect(
172 this, &SSLAdapterTestDummyServer::OnServerSocketReadEvent);
tkchin@webrtc.orgc569a492014-09-23 05:56:44173
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14174 server_socket_->Listen(1);
175 }
tkchin@webrtc.orgc569a492014-09-23 05:56:44176
Mirko Bonadei675513b2017-11-09 10:09:25177 RTC_LOG(LS_INFO) << ((ssl_mode_ == rtc::SSL_MODE_DTLS) ? "UDP" : "TCP")
178 << " server listening on "
Jonas Olssonabbe8412018-04-03 11:40:05179 << server_socket_->GetLocalAddress().ToString();
tkchin@webrtc.orgc569a492014-09-23 05:56:44180 }
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 13:03:05192 const std::string& GetReceivedData() const { return data_; }
tkchin@webrtc.orgc569a492014-09-23 05:56:44193
Ali Tofigh7fa90572022-03-17 14:47:49194 int Send(absl::string_view message) {
deadbeef37f5ecf2017-02-27 22:06:41195 if (ssl_stream_adapter_ == nullptr ||
196 ssl_stream_adapter_->GetState() != rtc::SS_OPEN) {
tkchin@webrtc.orgc569a492014-09-23 05:56:44197 // No connection yet.
198 return -1;
199 }
200
Mirko Bonadei675513b2017-11-09 10:09:25201 RTC_LOG(LS_INFO) << "Server sending '" << message << "'";
tkchin@webrtc.orgc569a492014-09-23 05:56:44202
203 size_t written;
204 int error;
205
Yves Gerey665174f2018-06-19 13:03:05206 rtc::StreamResult r = ssl_stream_adapter_->Write(
207 message.data(), message.length(), &written, &error);
tkchin@webrtc.orgc569a492014-09-23 05:56:44208 if (r == rtc::SR_SUCCESS) {
209 return written;
210 } else {
211 return -1;
212 }
213 }
214
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14215 void AcceptConnection(const rtc::SocketAddress& address) {
216 // Only a single connection is supported.
deadbeef37f5ecf2017-02-27 22:06:41217 ASSERT_TRUE(ssl_stream_adapter_ == nullptr);
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14218
219 // This is only for DTLS.
220 ASSERT_EQ(rtc::SSL_MODE_DTLS, ssl_mode_);
221
222 // Transfer ownership of the socket to the SSLStreamAdapter object.
Niels Möllerd0b88792021-08-12 08:32:30223 rtc::Socket* socket = server_socket_.release();
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14224
225 socket->Connect(address);
226
227 DoHandshake(socket);
228 }
229
Niels Möllerd0b88792021-08-12 08:32:30230 void OnServerSocketReadEvent(rtc::Socket* socket) {
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14231 // Only a single connection is supported.
deadbeef37f5ecf2017-02-27 22:06:41232 ASSERT_TRUE(ssl_stream_adapter_ == nullptr);
tkchin@webrtc.orgc569a492014-09-23 05:56:44233
deadbeef37f5ecf2017-02-27 22:06:41234 DoHandshake(server_socket_->Accept(nullptr));
tkchin@webrtc.orgc569a492014-09-23 05:56:44235 }
236
237 void OnSSLStreamAdapterEvent(rtc::StreamInterface* stream, int sig, int err) {
238 if (sig & rtc::SE_READ) {
239 char buffer[4096] = "";
tkchin@webrtc.orgc569a492014-09-23 05:56:44240 size_t read;
241 int error;
242
243 // Read data received from the client and store it in our internal
244 // buffer.
deadbeefed3b9862017-06-02 17:33:16245 rtc::StreamResult r =
246 stream->Read(buffer, sizeof(buffer) - 1, &read, &error);
tkchin@webrtc.orgc569a492014-09-23 05:56:44247 if (r == rtc::SR_SUCCESS) {
248 buffer[read] = '\0';
Mirko Bonadei675513b2017-11-09 10:09:25249 RTC_LOG(LS_INFO) << "Server received '" << buffer << "'";
tkchin@webrtc.orgc569a492014-09-23 05:56:44250 data_ += buffer;
251 }
252 }
253 }
254
255 private:
Niels Möllerd0b88792021-08-12 08:32:30256 void DoHandshake(rtc::Socket* socket) {
Harald Alvestrand8515d5a2020-03-20 21:51:32257 ssl_stream_adapter_ = rtc::SSLStreamAdapter::Create(
258 std::make_unique<rtc::SocketStream>(socket));
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14259
260 ssl_stream_adapter_->SetMode(ssl_mode_);
261 ssl_stream_adapter_->SetServerRole();
262
263 // SSLStreamAdapter is normally used for peer-to-peer communication, but
264 // here we're testing communication between a client and a server
265 // (e.g. a WebRTC-based application and an RFC 5766 TURN server), where
266 // clients are not required to provide a certificate during handshake.
267 // Accordingly, we must disable client authentication here.
Benjamin Wrightb19b4972018-10-25 17:46:49268 ssl_stream_adapter_->SetClientAuthEnabledForTesting(false);
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14269
Harald Alvestrand8515d5a2020-03-20 21:51:32270 ssl_stream_adapter_->SetIdentity(ssl_identity_->Clone());
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14271
272 // Set a bogus peer certificate digest.
273 unsigned char digest[20];
274 size_t digest_len = sizeof(digest);
275 ssl_stream_adapter_->SetPeerCertificateDigest(rtc::DIGEST_SHA_1, digest,
Yves Gerey665174f2018-06-19 13:03:05276 digest_len);
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14277
Taylor Brandstetterc8762a82016-08-11 19:01:49278 ssl_stream_adapter_->StartSSL();
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14279
Yves Gerey665174f2018-06-19 13:03:05280 ssl_stream_adapter_->SignalEvent.connect(
281 this, &SSLAdapterTestDummyServer::OnSSLStreamAdapterEvent);
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14282 }
283
tkchin@webrtc.orgc569a492014-09-23 05:56:44284 const rtc::SSLMode ssl_mode_;
285
Niels Möllerd0b88792021-08-12 08:32:30286 std::unique_ptr<rtc::Socket> server_socket_;
jbauch555604a2016-04-26 10:13:22287 std::unique_ptr<rtc::SSLStreamAdapter> ssl_stream_adapter_;
tkchin@webrtc.orgc569a492014-09-23 05:56:44288
jbauch555604a2016-04-26 10:13:22289 std::unique_ptr<rtc::SSLIdentity> ssl_identity_;
tkchin@webrtc.orgc569a492014-09-23 05:56:44290
291 std::string data_;
292};
293
Mirko Bonadei6a489f22019-04-09 13:11:12294class SSLAdapterTestBase : public ::testing::Test, public sigslot::has_slots<> {
tkchin@webrtc.orgc569a492014-09-23 05:56:44295 public:
Torbjorn Granlundb6d4ec42015-08-17 12:08:59296 explicit SSLAdapterTestBase(const rtc::SSLMode& ssl_mode,
torbjorng4e572472015-10-08 16:42:49297 const rtc::KeyParams& key_params)
tkchin@webrtc.orgc569a492014-09-23 05:56:44298 : ssl_mode_(ssl_mode),
deadbeef98e186c2017-05-17 01:00:06299 vss_(new rtc::VirtualSocketServer()),
nisse7eaa4ea2017-05-08 12:25:41300 thread_(vss_.get()),
torbjorng4e572472015-10-08 16:42:49301 server_(new SSLAdapterTestDummyServer(ssl_mode_, key_params)),
tkchin@webrtc.orgc569a492014-09-23 05:56:44302 client_(new SSLAdapterTestDummyClient(ssl_mode_)),
Torbjorn Granlundb6d4ec42015-08-17 12:08:59303 handshake_wait_(kTimeout) {}
tkchin@webrtc.orgc569a492014-09-23 05:56:44304
Yves Gerey665174f2018-06-19 13:03:05305 void SetHandshakeWait(int wait) { handshake_wait_ = wait; }
tkchin@webrtc.orgc569a492014-09-23 05:56:44306
Sergey Silkin9c147dd2018-09-12 10:45:38307 void SetIgnoreBadCert(bool ignore_bad_cert) {
308 client_->SetIgnoreBadCert(ignore_bad_cert);
Benjamin Wright6e9c3df2018-05-22 23:11:56309 }
310
311 void SetCertVerifier(rtc::SSLCertificateVerifier* ssl_cert_verifier) {
312 client_->SetCertVerifier(ssl_cert_verifier);
313 }
314
Sergey Silkin9c147dd2018-09-12 10:45:38315 void SetAlpnProtocols(const std::vector<std::string>& protos) {
316 client_->SetAlpnProtocols(protos);
317 }
318
319 void SetEllipticCurves(const std::vector<std::string>& curves) {
320 client_->SetEllipticCurves(curves);
321 }
322
Benjamin Wright6e9c3df2018-05-22 23:11:56323 void SetMockCertVerifier(bool return_value) {
Mirko Bonadei317a1f02019-09-17 15:06:18324 auto mock_verifier = std::make_unique<MockCertVerifier>();
Benjamin Wright6e9c3df2018-05-22 23:11:56325 EXPECT_CALL(*mock_verifier, Verify(_)).WillRepeatedly(Return(return_value));
326 cert_verifier_ =
327 std::unique_ptr<rtc::SSLCertificateVerifier>(std::move(mock_verifier));
328
Sergey Silkin9c147dd2018-09-12 10:45:38329 SetIgnoreBadCert(false);
Benjamin Wright6e9c3df2018-05-22 23:11:56330 SetCertVerifier(cert_verifier_.get());
331 }
332
tkchin@webrtc.orgc569a492014-09-23 05:56:44333 void TestHandshake(bool expect_success) {
334 int rv;
335
336 // The initial state is CS_CLOSED
Niels Möllerd0b88792021-08-12 08:32:30337 ASSERT_EQ(rtc::Socket::CS_CLOSED, client_->GetState());
tkchin@webrtc.orgc569a492014-09-23 05:56:44338
339 rv = client_->Connect(server_->GetHostname(), server_->GetAddress());
340 ASSERT_EQ(0, rv);
341
342 // Now the state should be CS_CONNECTING
Niels Möllerd0b88792021-08-12 08:32:30343 ASSERT_EQ(rtc::Socket::CS_CONNECTING, client_->GetState());
tkchin@webrtc.orgc569a492014-09-23 05:56:44344
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14345 if (ssl_mode_ == rtc::SSL_MODE_DTLS) {
346 // For DTLS, call AcceptConnection() with the client's address.
347 server_->AcceptConnection(client_->GetAddress());
348 }
349
tkchin@webrtc.orgc569a492014-09-23 05:56:44350 if (expect_success) {
351 // If expecting success, the client should end up in the CS_CONNECTED
352 // state after handshake.
Niels Möllerd0b88792021-08-12 08:32:30353 EXPECT_EQ_WAIT(rtc::Socket::CS_CONNECTED, client_->GetState(),
Yves Gerey665174f2018-06-19 13:03:05354 handshake_wait_);
tkchin@webrtc.orgc569a492014-09-23 05:56:44355
Mirko Bonadei675513b2017-11-09 10:09:25356 RTC_LOG(LS_INFO) << GetSSLProtocolName(ssl_mode_)
357 << " handshake complete.";
tkchin@webrtc.orgc569a492014-09-23 05:56:44358
359 } else {
360 // On handshake failure the client should end up in the CS_CLOSED state.
Niels Möllerd0b88792021-08-12 08:32:30361 EXPECT_EQ_WAIT(rtc::Socket::CS_CLOSED, client_->GetState(),
Yves Gerey665174f2018-06-19 13:03:05362 handshake_wait_);
tkchin@webrtc.orgc569a492014-09-23 05:56:44363
Mirko Bonadei675513b2017-11-09 10:09:25364 RTC_LOG(LS_INFO) << GetSSLProtocolName(ssl_mode_) << " handshake failed.";
tkchin@webrtc.orgc569a492014-09-23 05:56:44365 }
366 }
367
Ali Tofigh7fa90572022-03-17 14:47:49368 void TestTransfer(absl::string_view message) {
tkchin@webrtc.orgc569a492014-09-23 05:56:44369 int rv;
370
371 rv = client_->Send(message);
372 ASSERT_EQ(static_cast<int>(message.length()), rv);
373
374 // The server should have received the client's message.
375 EXPECT_EQ_WAIT(message, server_->GetReceivedData(), kTimeout);
376
377 rv = server_->Send(message);
378 ASSERT_EQ(static_cast<int>(message.length()), rv);
379
380 // The client should have received the server's message.
381 EXPECT_EQ_WAIT(message, client_->GetReceivedData(), kTimeout);
382
Mirko Bonadei675513b2017-11-09 10:09:25383 RTC_LOG(LS_INFO) << "Transfer complete.";
tkchin@webrtc.orgc569a492014-09-23 05:56:44384 }
385
deadbeefed3b9862017-06-02 17:33:16386 protected:
tkchin@webrtc.orgc569a492014-09-23 05:56:44387 const rtc::SSLMode ssl_mode_;
388
nisse7eaa4ea2017-05-08 12:25:41389 std::unique_ptr<rtc::VirtualSocketServer> vss_;
390 rtc::AutoSocketServerThread thread_;
jbauch555604a2016-04-26 10:13:22391 std::unique_ptr<SSLAdapterTestDummyServer> server_;
392 std::unique_ptr<SSLAdapterTestDummyClient> client_;
Benjamin Wright6e9c3df2018-05-22 23:11:56393 std::unique_ptr<rtc::SSLCertificateVerifier> cert_verifier_;
tkchin@webrtc.orgc569a492014-09-23 05:56:44394
395 int handshake_wait_;
396};
397
Torbjorn Granlundb6d4ec42015-08-17 12:08:59398class SSLAdapterTestTLS_RSA : public SSLAdapterTestBase {
tkchin@webrtc.orgc569a492014-09-23 05:56:44399 public:
Torbjorn Granlundb6d4ec42015-08-17 12:08:59400 SSLAdapterTestTLS_RSA()
torbjorng4e572472015-10-08 16:42:49401 : SSLAdapterTestBase(rtc::SSL_MODE_TLS, rtc::KeyParams::RSA()) {}
tkchin@webrtc.orgc569a492014-09-23 05:56:44402};
403
Torbjorn Granlundb6d4ec42015-08-17 12:08:59404class SSLAdapterTestTLS_ECDSA : public SSLAdapterTestBase {
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14405 public:
Torbjorn Granlundb6d4ec42015-08-17 12:08:59406 SSLAdapterTestTLS_ECDSA()
torbjorng4e572472015-10-08 16:42:49407 : SSLAdapterTestBase(rtc::SSL_MODE_TLS, rtc::KeyParams::ECDSA()) {}
Torbjorn Granlundb6d4ec42015-08-17 12:08:59408};
409
410class SSLAdapterTestDTLS_RSA : public SSLAdapterTestBase {
411 public:
412 SSLAdapterTestDTLS_RSA()
torbjorng4e572472015-10-08 16:42:49413 : SSLAdapterTestBase(rtc::SSL_MODE_DTLS, rtc::KeyParams::RSA()) {}
Torbjorn Granlundb6d4ec42015-08-17 12:08:59414};
415
416class SSLAdapterTestDTLS_ECDSA : public SSLAdapterTestBase {
417 public:
418 SSLAdapterTestDTLS_ECDSA()
torbjorng4e572472015-10-08 16:42:49419 : SSLAdapterTestBase(rtc::SSL_MODE_DTLS, rtc::KeyParams::ECDSA()) {}
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14420};
tkchin@webrtc.orgc569a492014-09-23 05:56:44421
tkchin@webrtc.orgc569a492014-09-23 05:56:44422// Basic tests: TLS
423
Torbjorn Granlundb6d4ec42015-08-17 12:08:59424// Test that handshake works, using RSA
425TEST_F(SSLAdapterTestTLS_RSA, TestTLSConnect) {
tkchin@webrtc.orgc569a492014-09-23 05:56:44426 TestHandshake(true);
427}
428
Benjamin Wright6e9c3df2018-05-22 23:11:56429// Test that handshake works with a custom verifier that returns true. RSA.
430TEST_F(SSLAdapterTestTLS_RSA, TestTLSConnectCustomCertVerifierSucceeds) {
431 SetMockCertVerifier(/*return_value=*/true);
432 TestHandshake(/*expect_success=*/true);
433}
434
435// Test that handshake fails with a custom verifier that returns false. RSA.
436TEST_F(SSLAdapterTestTLS_RSA, TestTLSConnectCustomCertVerifierFails) {
437 SetMockCertVerifier(/*return_value=*/false);
438 TestHandshake(/*expect_success=*/false);
439}
440
Torbjorn Granlundb6d4ec42015-08-17 12:08:59441// Test that handshake works, using ECDSA
442TEST_F(SSLAdapterTestTLS_ECDSA, TestTLSConnect) {
Benjamin Wright6e9c3df2018-05-22 23:11:56443 SetMockCertVerifier(/*return_value=*/true);
444 TestHandshake(/*expect_success=*/true);
445}
446
447// Test that handshake works with a custom verifier that returns true. ECDSA.
448TEST_F(SSLAdapterTestTLS_ECDSA, TestTLSConnectCustomCertVerifierSucceeds) {
449 SetMockCertVerifier(/*return_value=*/true);
450 TestHandshake(/*expect_success=*/true);
451}
452
453// Test that handshake fails with a custom verifier that returns false. ECDSA.
454TEST_F(SSLAdapterTestTLS_ECDSA, TestTLSConnectCustomCertVerifierFails) {
455 SetMockCertVerifier(/*return_value=*/false);
456 TestHandshake(/*expect_success=*/false);
Torbjorn Granlundb6d4ec42015-08-17 12:08:59457}
458
459// Test transfer between client and server, using RSA
460TEST_F(SSLAdapterTestTLS_RSA, TestTLSTransfer) {
461 TestHandshake(true);
462 TestTransfer("Hello, world!");
463}
464
Benjamin Wright6e9c3df2018-05-22 23:11:56465// Test transfer between client and server, using RSA with custom cert verifier.
466TEST_F(SSLAdapterTestTLS_RSA, TestTLSTransferCustomCertVerifier) {
467 SetMockCertVerifier(/*return_value=*/true);
468 TestHandshake(/*expect_success=*/true);
469 TestTransfer("Hello, world!");
470}
471
deadbeefed3b9862017-06-02 17:33:16472TEST_F(SSLAdapterTestTLS_RSA, TestTLSTransferWithBlockedSocket) {
473 TestHandshake(true);
474
475 // Tell the underlying socket to simulate being blocked.
476 vss_->SetSendingBlocked(true);
477
478 std::string expected;
479 int rv;
480 // Send messages until the SSL socket adapter starts applying backpressure.
481 // Note that this may not occur immediately since there may be some amount of
482 // intermediate buffering (either in our code or in BoringSSL).
483 for (int i = 0; i < 1024; ++i) {
484 std::string message = "Hello, world: " + rtc::ToString(i);
485 rv = client_->Send(message);
486 if (rv != static_cast<int>(message.size())) {
487 // This test assumes either the whole message or none of it is sent.
488 ASSERT_EQ(-1, rv);
489 break;
490 }
491 expected += message;
492 }
493 // Assert that the loop above exited due to Send returning -1.
494 ASSERT_EQ(-1, rv);
495
496 // Try sending another message while blocked. -1 should be returned again and
497 // it shouldn't end up received by the server later.
498 EXPECT_EQ(-1, client_->Send("Never sent"));
499
500 // Unblock the underlying socket. All of the buffered messages should be sent
501 // without any further action.
502 vss_->SetSendingBlocked(false);
503 EXPECT_EQ_WAIT(expected, server_->GetReceivedData(), kTimeout);
504
505 // Send another message. This previously wasn't working
506 std::string final_message = "Fin.";
507 expected += final_message;
508 EXPECT_EQ(static_cast<int>(final_message.size()),
509 client_->Send(final_message));
510 EXPECT_EQ_WAIT(expected, server_->GetReceivedData(), kTimeout);
511}
512
Torbjorn Granlundb6d4ec42015-08-17 12:08:59513// Test transfer between client and server, using ECDSA
514TEST_F(SSLAdapterTestTLS_ECDSA, TestTLSTransfer) {
tkchin@webrtc.orgc569a492014-09-23 05:56:44515 TestHandshake(true);
516 TestTransfer("Hello, world!");
517}
518
Benjamin Wright6e9c3df2018-05-22 23:11:56519// Test transfer between client and server, using ECDSA with custom cert
520// verifier.
521TEST_F(SSLAdapterTestTLS_ECDSA, TestTLSTransferCustomCertVerifier) {
522 SetMockCertVerifier(/*return_value=*/true);
523 TestHandshake(/*expect_success=*/true);
524 TestTransfer("Hello, world!");
525}
526
Diogo Real1dca9d52017-08-29 19:18:32527// Test transfer using ALPN with protos as h2 and http/1.1
528TEST_F(SSLAdapterTestTLS_ECDSA, TestTLSALPN) {
529 std::vector<std::string> alpn_protos{"h2", "http/1.1"};
530 SetAlpnProtocols(alpn_protos);
531 TestHandshake(true);
532 TestTransfer("Hello, world!");
533}
534
Diogo Real7bd1f1b2017-09-08 19:50:41535// Test transfer with TLS Elliptic curves set to "X25519:P-256:P-384:P-521"
536TEST_F(SSLAdapterTestTLS_ECDSA, TestTLSEllipticCurves) {
537 std::vector<std::string> elliptic_curves{"X25519", "P-256", "P-384", "P-521"};
538 SetEllipticCurves(elliptic_curves);
539 TestHandshake(true);
540 TestTransfer("Hello, world!");
541}
542
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14543// Basic tests: DTLS
544
Torbjorn Granlundb6d4ec42015-08-17 12:08:59545// Test that handshake works, using RSA
546TEST_F(SSLAdapterTestDTLS_RSA, TestDTLSConnect) {
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14547 TestHandshake(true);
548}
549
Benjamin Wright6e9c3df2018-05-22 23:11:56550// Test that handshake works with a custom verifier that returns true. DTLS_RSA.
551TEST_F(SSLAdapterTestDTLS_RSA, TestDTLSConnectCustomCertVerifierSucceeds) {
552 SetMockCertVerifier(/*return_value=*/true);
553 TestHandshake(/*expect_success=*/true);
554}
555
556// Test that handshake fails with a custom verifier that returns false.
557// DTLS_RSA.
558TEST_F(SSLAdapterTestDTLS_RSA, TestTLSConnectCustomCertVerifierFails) {
559 SetMockCertVerifier(/*return_value=*/false);
560 TestHandshake(/*expect_success=*/false);
561}
562
Torbjorn Granlundb6d4ec42015-08-17 12:08:59563// Test that handshake works, using ECDSA
564TEST_F(SSLAdapterTestDTLS_ECDSA, TestDTLSConnect) {
565 TestHandshake(true);
566}
567
Benjamin Wright6e9c3df2018-05-22 23:11:56568// Test that handshake works with a custom verifier that returns true.
569// DTLS_ECDSA.
570TEST_F(SSLAdapterTestDTLS_ECDSA, TestDTLSConnectCustomCertVerifierSucceeds) {
571 SetMockCertVerifier(/*return_value=*/true);
572 TestHandshake(/*expect_success=*/true);
573}
574
575// Test that handshake fails with a custom verifier that returns false.
576// DTLS_ECDSA.
577TEST_F(SSLAdapterTestDTLS_ECDSA, TestTLSConnectCustomCertVerifierFails) {
578 SetMockCertVerifier(/*return_value=*/false);
579 TestHandshake(/*expect_success=*/false);
580}
581
Torbjorn Granlundb6d4ec42015-08-17 12:08:59582// Test transfer between client and server, using RSA
583TEST_F(SSLAdapterTestDTLS_RSA, TestDTLSTransfer) {
584 TestHandshake(true);
585 TestTransfer("Hello, world!");
586}
587
Benjamin Wright6e9c3df2018-05-22 23:11:56588// Test transfer between client and server, using RSA with custom cert verifier.
589TEST_F(SSLAdapterTestDTLS_RSA, TestDTLSTransferCustomCertVerifier) {
590 SetMockCertVerifier(/*return_value=*/true);
591 TestHandshake(/*expect_success=*/true);
592 TestTransfer("Hello, world!");
593}
594
Torbjorn Granlundb6d4ec42015-08-17 12:08:59595// Test transfer between client and server, using ECDSA
596TEST_F(SSLAdapterTestDTLS_ECDSA, TestDTLSTransfer) {
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14597 TestHandshake(true);
598 TestTransfer("Hello, world!");
599}
Benjamin Wright6e9c3df2018-05-22 23:11:56600
601// Test transfer between client and server, using ECDSA with custom cert
602// verifier.
603TEST_F(SSLAdapterTestDTLS_ECDSA, TestDTLSTransferCustomCertVerifier) {
604 SetMockCertVerifier(/*return_value=*/true);
605 TestHandshake(/*expect_success=*/true);
606 TestTransfer("Hello, world!");
607}