blob: 9774c0a5d9d72f625e3a5108fcd51598f1fe7e66 [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
Karl Wiberg918f50c2018-07-05 11:40:33 +020015#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
33static rtc::AsyncSocket* CreateSocket(const rtc::SSLMode& ssl_mode) {
34 rtc::SocketAddress address(rtc::IPAddress(INADDR_ANY), 0);
35
Yves Gerey665174f2018-06-19 15:03:05 +020036 rtc::AsyncSocket* socket =
37 rtc::Thread::Current()->socketserver()->CreateAsyncSocket(
38 address.family(),
39 (ssl_mode == rtc::SSL_MODE_DTLS) ? SOCK_DGRAM : SOCK_STREAM);
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +000040 socket->Bind(address);
41
42 return socket;
43}
44
45static std::string GetSSLProtocolName(const rtc::SSLMode& ssl_mode) {
46 return (ssl_mode == rtc::SSL_MODE_DTLS) ? "DTLS" : "TLS";
47}
48
Benjamin Wright6e9c3df2018-05-22 16:11:56 -070049// Simple mock for the certificate verifier.
50class MockCertVerifier : public rtc::SSLCertificateVerifier {
51 public:
52 virtual ~MockCertVerifier() = default;
53 MOCK_METHOD1(Verify, bool(const rtc::SSLCertificate&));
54};
55
56// TODO(benwright) - Move to using INSTANTIATE_TEST_CASE_P instead of using
57// duplicate test cases for simple parameter changes.
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +000058class SSLAdapterTestDummyClient : public sigslot::has_slots<> {
59 public:
60 explicit SSLAdapterTestDummyClient(const rtc::SSLMode& ssl_mode)
61 : ssl_mode_(ssl_mode) {
62 rtc::AsyncSocket* socket = CreateSocket(ssl_mode_);
63
64 ssl_adapter_.reset(rtc::SSLAdapter::Create(socket));
65
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +000066 ssl_adapter_->SetMode(ssl_mode_);
67
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +000068 // Ignore any certificate errors for the purpose of testing.
69 // Note: We do this only because we don't have a real certificate.
70 // NEVER USE THIS IN PRODUCTION CODE!
Sergey Silkin9c147dd2018-09-12 10:45:38 +000071 ssl_adapter_->SetIgnoreBadCert(true);
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +000072
Yves Gerey665174f2018-06-19 15:03:05 +020073 ssl_adapter_->SignalReadEvent.connect(
74 this, &SSLAdapterTestDummyClient::OnSSLAdapterReadEvent);
75 ssl_adapter_->SignalCloseEvent.connect(
76 this, &SSLAdapterTestDummyClient::OnSSLAdapterCloseEvent);
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +000077 }
78
Sergey Silkin9c147dd2018-09-12 10:45:38 +000079 void SetIgnoreBadCert(bool ignore_bad_cert) {
80 ssl_adapter_->SetIgnoreBadCert(ignore_bad_cert);
Benjamin Wright6e9c3df2018-05-22 16:11:56 -070081 }
82
83 void SetCertVerifier(rtc::SSLCertificateVerifier* ssl_cert_verifier) {
84 ssl_adapter_->SetCertVerifier(ssl_cert_verifier);
85 }
86
Sergey Silkin9c147dd2018-09-12 10:45:38 +000087 void SetAlpnProtocols(const std::vector<std::string>& protos) {
88 ssl_adapter_->SetAlpnProtocols(protos);
89 }
90
91 void SetEllipticCurves(const std::vector<std::string>& curves) {
92 ssl_adapter_->SetEllipticCurves(curves);
93 }
94
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +000095 rtc::SocketAddress GetAddress() const {
96 return ssl_adapter_->GetLocalAddress();
97 }
98
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +000099 rtc::AsyncSocket::ConnState GetState() const {
100 return ssl_adapter_->GetState();
101 }
102
Yves Gerey665174f2018-06-19 15:03:05 +0200103 const std::string& GetReceivedData() const { return data_; }
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000104
105 int Connect(const std::string& hostname, const rtc::SocketAddress& address) {
Jonas Olssonabbe8412018-04-03 13:40:05 +0200106 RTC_LOG(LS_INFO) << "Initiating connection with " << address.ToString();
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000107
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000108 int rv = ssl_adapter_->Connect(address);
109
110 if (rv == 0) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100111 RTC_LOG(LS_INFO) << "Starting " << GetSSLProtocolName(ssl_mode_)
112 << " handshake with " << hostname;
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000113
114 if (ssl_adapter_->StartSSL(hostname.c_str(), false) != 0) {
115 return -1;
116 }
117 }
118
119 return rv;
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000120 }
121
Yves Gerey665174f2018-06-19 15:03:05 +0200122 int Close() { return ssl_adapter_->Close(); }
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000123
124 int Send(const std::string& message) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100125 RTC_LOG(LS_INFO) << "Client sending '" << message << "'";
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000126
127 return ssl_adapter_->Send(message.data(), message.length());
128 }
129
130 void OnSSLAdapterReadEvent(rtc::AsyncSocket* socket) {
131 char buffer[4096] = "";
132
133 // Read data received from the server and store it in our internal buffer.
Stefan Holmer9131efd2016-05-23 18:19:26 +0200134 int read = socket->Recv(buffer, sizeof(buffer) - 1, nullptr);
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000135 if (read != -1) {
136 buffer[read] = '\0';
137
Mirko Bonadei675513b2017-11-09 11:09:25 +0100138 RTC_LOG(LS_INFO) << "Client received '" << buffer << "'";
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000139
140 data_ += buffer;
141 }
142 }
143
144 void OnSSLAdapterCloseEvent(rtc::AsyncSocket* socket, int error) {
145 // OpenSSLAdapter signals handshake failure with a close event, but without
146 // closing the socket! Let's close the socket here. This way GetState() can
147 // return CS_CLOSED after failure.
148 if (socket->GetState() != rtc::AsyncSocket::CS_CLOSED) {
149 socket->Close();
150 }
151 }
152
153 private:
154 const rtc::SSLMode ssl_mode_;
155
jbauch555604a2016-04-26 03:13:22 -0700156 std::unique_ptr<rtc::SSLAdapter> ssl_adapter_;
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000157
158 std::string data_;
159};
160
161class SSLAdapterTestDummyServer : public sigslot::has_slots<> {
162 public:
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200163 explicit SSLAdapterTestDummyServer(const rtc::SSLMode& ssl_mode,
torbjorng4e572472015-10-08 09:42:49 -0700164 const rtc::KeyParams& key_params)
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000165 : ssl_mode_(ssl_mode) {
166 // Generate a key pair and a certificate for this host.
torbjorng4e572472015-10-08 09:42:49 -0700167 ssl_identity_.reset(rtc::SSLIdentity::Generate(GetHostname(), key_params));
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000168
169 server_socket_.reset(CreateSocket(ssl_mode_));
170
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000171 if (ssl_mode_ == rtc::SSL_MODE_TLS) {
Yves Gerey665174f2018-06-19 15:03:05 +0200172 server_socket_->SignalReadEvent.connect(
173 this, &SSLAdapterTestDummyServer::OnServerSocketReadEvent);
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000174
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000175 server_socket_->Listen(1);
176 }
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000177
Mirko Bonadei675513b2017-11-09 11:09:25 +0100178 RTC_LOG(LS_INFO) << ((ssl_mode_ == rtc::SSL_MODE_DTLS) ? "UDP" : "TCP")
179 << " server listening on "
Jonas Olssonabbe8412018-04-03 13:40:05 +0200180 << server_socket_->GetLocalAddress().ToString();
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000181 }
182
183 rtc::SocketAddress GetAddress() const {
184 return server_socket_->GetLocalAddress();
185 }
186
187 std::string GetHostname() const {
188 // Since we don't have a real certificate anyway, the value here doesn't
189 // really matter.
190 return "example.com";
191 }
192
Yves Gerey665174f2018-06-19 15:03:05 +0200193 const std::string& GetReceivedData() const { return data_; }
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000194
195 int Send(const std::string& message) {
deadbeef37f5ecf2017-02-27 14:06:41 -0800196 if (ssl_stream_adapter_ == nullptr ||
197 ssl_stream_adapter_->GetState() != rtc::SS_OPEN) {
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000198 // No connection yet.
199 return -1;
200 }
201
Mirko Bonadei675513b2017-11-09 11:09:25 +0100202 RTC_LOG(LS_INFO) << "Server sending '" << message << "'";
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000203
204 size_t written;
205 int error;
206
Yves Gerey665174f2018-06-19 15:03:05 +0200207 rtc::StreamResult r = ssl_stream_adapter_->Write(
208 message.data(), message.length(), &written, &error);
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000209 if (r == rtc::SR_SUCCESS) {
210 return written;
211 } else {
212 return -1;
213 }
214 }
215
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000216 void AcceptConnection(const rtc::SocketAddress& address) {
217 // Only a single connection is supported.
deadbeef37f5ecf2017-02-27 14:06:41 -0800218 ASSERT_TRUE(ssl_stream_adapter_ == nullptr);
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000219
220 // This is only for DTLS.
221 ASSERT_EQ(rtc::SSL_MODE_DTLS, ssl_mode_);
222
223 // Transfer ownership of the socket to the SSLStreamAdapter object.
224 rtc::AsyncSocket* socket = server_socket_.release();
225
226 socket->Connect(address);
227
228 DoHandshake(socket);
229 }
230
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000231 void OnServerSocketReadEvent(rtc::AsyncSocket* socket) {
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000232 // Only a single connection is supported.
deadbeef37f5ecf2017-02-27 14:06:41 -0800233 ASSERT_TRUE(ssl_stream_adapter_ == nullptr);
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000234
deadbeef37f5ecf2017-02-27 14:06:41 -0800235 DoHandshake(server_socket_->Accept(nullptr));
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000236 }
237
238 void OnSSLStreamAdapterEvent(rtc::StreamInterface* stream, int sig, int err) {
239 if (sig & rtc::SE_READ) {
240 char buffer[4096] = "";
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000241 size_t read;
242 int error;
243
244 // Read data received from the client and store it in our internal
245 // buffer.
deadbeefed3b9862017-06-02 10:33:16 -0700246 rtc::StreamResult r =
247 stream->Read(buffer, sizeof(buffer) - 1, &read, &error);
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000248 if (r == rtc::SR_SUCCESS) {
249 buffer[read] = '\0';
Mirko Bonadei675513b2017-11-09 11:09:25 +0100250 RTC_LOG(LS_INFO) << "Server received '" << buffer << "'";
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000251 data_ += buffer;
252 }
253 }
254 }
255
256 private:
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000257 void DoHandshake(rtc::AsyncSocket* socket) {
258 rtc::SocketStream* stream = new rtc::SocketStream(socket);
259
260 ssl_stream_adapter_.reset(rtc::SSLStreamAdapter::Create(stream));
261
262 ssl_stream_adapter_->SetMode(ssl_mode_);
263 ssl_stream_adapter_->SetServerRole();
264
265 // SSLStreamAdapter is normally used for peer-to-peer communication, but
266 // here we're testing communication between a client and a server
267 // (e.g. a WebRTC-based application and an RFC 5766 TURN server), where
268 // clients are not required to provide a certificate during handshake.
269 // Accordingly, we must disable client authentication here.
Benjamin Wrightb19b4972018-10-25 10:46:49 -0700270 ssl_stream_adapter_->SetClientAuthEnabledForTesting(false);
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000271
272 ssl_stream_adapter_->SetIdentity(ssl_identity_->GetReference());
273
274 // Set a bogus peer certificate digest.
275 unsigned char digest[20];
276 size_t digest_len = sizeof(digest);
277 ssl_stream_adapter_->SetPeerCertificateDigest(rtc::DIGEST_SHA_1, digest,
Yves Gerey665174f2018-06-19 15:03:05 +0200278 digest_len);
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000279
Taylor Brandstetterc8762a82016-08-11 12:01:49 -0700280 ssl_stream_adapter_->StartSSL();
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000281
Yves Gerey665174f2018-06-19 15:03:05 +0200282 ssl_stream_adapter_->SignalEvent.connect(
283 this, &SSLAdapterTestDummyServer::OnSSLStreamAdapterEvent);
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000284 }
285
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000286 const rtc::SSLMode ssl_mode_;
287
jbauch555604a2016-04-26 03:13:22 -0700288 std::unique_ptr<rtc::AsyncSocket> server_socket_;
289 std::unique_ptr<rtc::SSLStreamAdapter> ssl_stream_adapter_;
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000290
jbauch555604a2016-04-26 03:13:22 -0700291 std::unique_ptr<rtc::SSLIdentity> ssl_identity_;
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000292
293 std::string data_;
294};
295
Yves Gerey665174f2018-06-19 15:03:05 +0200296class SSLAdapterTestBase : public testing::Test, public sigslot::has_slots<> {
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000297 public:
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200298 explicit SSLAdapterTestBase(const rtc::SSLMode& ssl_mode,
torbjorng4e572472015-10-08 09:42:49 -0700299 const rtc::KeyParams& key_params)
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000300 : ssl_mode_(ssl_mode),
deadbeef98e186c2017-05-16 18:00:06 -0700301 vss_(new rtc::VirtualSocketServer()),
nisse7eaa4ea2017-05-08 05:25:41 -0700302 thread_(vss_.get()),
torbjorng4e572472015-10-08 09:42:49 -0700303 server_(new SSLAdapterTestDummyServer(ssl_mode_, key_params)),
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000304 client_(new SSLAdapterTestDummyClient(ssl_mode_)),
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200305 handshake_wait_(kTimeout) {}
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000306
Yves Gerey665174f2018-06-19 15:03:05 +0200307 void SetHandshakeWait(int wait) { handshake_wait_ = wait; }
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000308
Sergey Silkin9c147dd2018-09-12 10:45:38 +0000309 void SetIgnoreBadCert(bool ignore_bad_cert) {
310 client_->SetIgnoreBadCert(ignore_bad_cert);
Benjamin Wright6e9c3df2018-05-22 16:11:56 -0700311 }
312
313 void SetCertVerifier(rtc::SSLCertificateVerifier* ssl_cert_verifier) {
314 client_->SetCertVerifier(ssl_cert_verifier);
315 }
316
Sergey Silkin9c147dd2018-09-12 10:45:38 +0000317 void SetAlpnProtocols(const std::vector<std::string>& protos) {
318 client_->SetAlpnProtocols(protos);
319 }
320
321 void SetEllipticCurves(const std::vector<std::string>& curves) {
322 client_->SetEllipticCurves(curves);
323 }
324
Benjamin Wright6e9c3df2018-05-22 16:11:56 -0700325 void SetMockCertVerifier(bool return_value) {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200326 auto mock_verifier = absl::make_unique<MockCertVerifier>();
Benjamin Wright6e9c3df2018-05-22 16:11:56 -0700327 EXPECT_CALL(*mock_verifier, Verify(_)).WillRepeatedly(Return(return_value));
328 cert_verifier_ =
329 std::unique_ptr<rtc::SSLCertificateVerifier>(std::move(mock_verifier));
330
Sergey Silkin9c147dd2018-09-12 10:45:38 +0000331 SetIgnoreBadCert(false);
Benjamin Wright6e9c3df2018-05-22 16:11:56 -0700332 SetCertVerifier(cert_verifier_.get());
333 }
334
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000335 void TestHandshake(bool expect_success) {
336 int rv;
337
338 // The initial state is CS_CLOSED
339 ASSERT_EQ(rtc::AsyncSocket::CS_CLOSED, client_->GetState());
340
341 rv = client_->Connect(server_->GetHostname(), server_->GetAddress());
342 ASSERT_EQ(0, rv);
343
344 // Now the state should be CS_CONNECTING
345 ASSERT_EQ(rtc::AsyncSocket::CS_CONNECTING, client_->GetState());
346
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000347 if (ssl_mode_ == rtc::SSL_MODE_DTLS) {
348 // For DTLS, call AcceptConnection() with the client's address.
349 server_->AcceptConnection(client_->GetAddress());
350 }
351
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000352 if (expect_success) {
353 // If expecting success, the client should end up in the CS_CONNECTED
354 // state after handshake.
355 EXPECT_EQ_WAIT(rtc::AsyncSocket::CS_CONNECTED, client_->GetState(),
Yves Gerey665174f2018-06-19 15:03:05 +0200356 handshake_wait_);
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000357
Mirko Bonadei675513b2017-11-09 11:09:25 +0100358 RTC_LOG(LS_INFO) << GetSSLProtocolName(ssl_mode_)
359 << " handshake complete.";
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000360
361 } else {
362 // On handshake failure the client should end up in the CS_CLOSED state.
363 EXPECT_EQ_WAIT(rtc::AsyncSocket::CS_CLOSED, client_->GetState(),
Yves Gerey665174f2018-06-19 15:03:05 +0200364 handshake_wait_);
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000365
Mirko Bonadei675513b2017-11-09 11:09:25 +0100366 RTC_LOG(LS_INFO) << GetSSLProtocolName(ssl_mode_) << " handshake failed.";
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000367 }
368 }
369
370 void TestTransfer(const std::string& message) {
371 int rv;
372
373 rv = client_->Send(message);
374 ASSERT_EQ(static_cast<int>(message.length()), rv);
375
376 // The server should have received the client's message.
377 EXPECT_EQ_WAIT(message, server_->GetReceivedData(), kTimeout);
378
379 rv = server_->Send(message);
380 ASSERT_EQ(static_cast<int>(message.length()), rv);
381
382 // The client should have received the server's message.
383 EXPECT_EQ_WAIT(message, client_->GetReceivedData(), kTimeout);
384
Mirko Bonadei675513b2017-11-09 11:09:25 +0100385 RTC_LOG(LS_INFO) << "Transfer complete.";
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000386 }
387
deadbeefed3b9862017-06-02 10:33:16 -0700388 protected:
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000389 const rtc::SSLMode ssl_mode_;
390
nisse7eaa4ea2017-05-08 05:25:41 -0700391 std::unique_ptr<rtc::VirtualSocketServer> vss_;
392 rtc::AutoSocketServerThread thread_;
jbauch555604a2016-04-26 03:13:22 -0700393 std::unique_ptr<SSLAdapterTestDummyServer> server_;
394 std::unique_ptr<SSLAdapterTestDummyClient> client_;
Benjamin Wright6e9c3df2018-05-22 16:11:56 -0700395 std::unique_ptr<rtc::SSLCertificateVerifier> cert_verifier_;
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000396
397 int handshake_wait_;
398};
399
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200400class SSLAdapterTestTLS_RSA : public SSLAdapterTestBase {
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000401 public:
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200402 SSLAdapterTestTLS_RSA()
torbjorng4e572472015-10-08 09:42:49 -0700403 : SSLAdapterTestBase(rtc::SSL_MODE_TLS, rtc::KeyParams::RSA()) {}
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000404};
405
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200406class SSLAdapterTestTLS_ECDSA : public SSLAdapterTestBase {
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000407 public:
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200408 SSLAdapterTestTLS_ECDSA()
torbjorng4e572472015-10-08 09:42:49 -0700409 : SSLAdapterTestBase(rtc::SSL_MODE_TLS, rtc::KeyParams::ECDSA()) {}
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200410};
411
412class SSLAdapterTestDTLS_RSA : public SSLAdapterTestBase {
413 public:
414 SSLAdapterTestDTLS_RSA()
torbjorng4e572472015-10-08 09:42:49 -0700415 : SSLAdapterTestBase(rtc::SSL_MODE_DTLS, rtc::KeyParams::RSA()) {}
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200416};
417
418class SSLAdapterTestDTLS_ECDSA : public SSLAdapterTestBase {
419 public:
420 SSLAdapterTestDTLS_ECDSA()
torbjorng4e572472015-10-08 09:42:49 -0700421 : SSLAdapterTestBase(rtc::SSL_MODE_DTLS, rtc::KeyParams::ECDSA()) {}
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000422};
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000423
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000424// Basic tests: TLS
425
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200426// Test that handshake works, using RSA
427TEST_F(SSLAdapterTestTLS_RSA, TestTLSConnect) {
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000428 TestHandshake(true);
429}
430
Benjamin Wright6e9c3df2018-05-22 16:11:56 -0700431// Test that handshake works with a custom verifier that returns true. RSA.
432TEST_F(SSLAdapterTestTLS_RSA, TestTLSConnectCustomCertVerifierSucceeds) {
433 SetMockCertVerifier(/*return_value=*/true);
434 TestHandshake(/*expect_success=*/true);
435}
436
437// Test that handshake fails with a custom verifier that returns false. RSA.
438TEST_F(SSLAdapterTestTLS_RSA, TestTLSConnectCustomCertVerifierFails) {
439 SetMockCertVerifier(/*return_value=*/false);
440 TestHandshake(/*expect_success=*/false);
441}
442
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200443// Test that handshake works, using ECDSA
444TEST_F(SSLAdapterTestTLS_ECDSA, TestTLSConnect) {
Benjamin Wright6e9c3df2018-05-22 16:11:56 -0700445 SetMockCertVerifier(/*return_value=*/true);
446 TestHandshake(/*expect_success=*/true);
447}
448
449// Test that handshake works with a custom verifier that returns true. ECDSA.
450TEST_F(SSLAdapterTestTLS_ECDSA, TestTLSConnectCustomCertVerifierSucceeds) {
451 SetMockCertVerifier(/*return_value=*/true);
452 TestHandshake(/*expect_success=*/true);
453}
454
455// Test that handshake fails with a custom verifier that returns false. ECDSA.
456TEST_F(SSLAdapterTestTLS_ECDSA, TestTLSConnectCustomCertVerifierFails) {
457 SetMockCertVerifier(/*return_value=*/false);
458 TestHandshake(/*expect_success=*/false);
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200459}
460
461// Test transfer between client and server, using RSA
462TEST_F(SSLAdapterTestTLS_RSA, TestTLSTransfer) {
463 TestHandshake(true);
464 TestTransfer("Hello, world!");
465}
466
Benjamin Wright6e9c3df2018-05-22 16:11:56 -0700467// Test transfer between client and server, using RSA with custom cert verifier.
468TEST_F(SSLAdapterTestTLS_RSA, TestTLSTransferCustomCertVerifier) {
469 SetMockCertVerifier(/*return_value=*/true);
470 TestHandshake(/*expect_success=*/true);
471 TestTransfer("Hello, world!");
472}
473
deadbeefed3b9862017-06-02 10:33:16 -0700474TEST_F(SSLAdapterTestTLS_RSA, TestTLSTransferWithBlockedSocket) {
475 TestHandshake(true);
476
477 // Tell the underlying socket to simulate being blocked.
478 vss_->SetSendingBlocked(true);
479
480 std::string expected;
481 int rv;
482 // Send messages until the SSL socket adapter starts applying backpressure.
483 // Note that this may not occur immediately since there may be some amount of
484 // intermediate buffering (either in our code or in BoringSSL).
485 for (int i = 0; i < 1024; ++i) {
486 std::string message = "Hello, world: " + rtc::ToString(i);
487 rv = client_->Send(message);
488 if (rv != static_cast<int>(message.size())) {
489 // This test assumes either the whole message or none of it is sent.
490 ASSERT_EQ(-1, rv);
491 break;
492 }
493 expected += message;
494 }
495 // Assert that the loop above exited due to Send returning -1.
496 ASSERT_EQ(-1, rv);
497
498 // Try sending another message while blocked. -1 should be returned again and
499 // it shouldn't end up received by the server later.
500 EXPECT_EQ(-1, client_->Send("Never sent"));
501
502 // Unblock the underlying socket. All of the buffered messages should be sent
503 // without any further action.
504 vss_->SetSendingBlocked(false);
505 EXPECT_EQ_WAIT(expected, server_->GetReceivedData(), kTimeout);
506
507 // Send another message. This previously wasn't working
508 std::string final_message = "Fin.";
509 expected += final_message;
510 EXPECT_EQ(static_cast<int>(final_message.size()),
511 client_->Send(final_message));
512 EXPECT_EQ_WAIT(expected, server_->GetReceivedData(), kTimeout);
513}
514
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200515// Test transfer between client and server, using ECDSA
516TEST_F(SSLAdapterTestTLS_ECDSA, TestTLSTransfer) {
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000517 TestHandshake(true);
518 TestTransfer("Hello, world!");
519}
520
Benjamin Wright6e9c3df2018-05-22 16:11:56 -0700521// Test transfer between client and server, using ECDSA with custom cert
522// verifier.
523TEST_F(SSLAdapterTestTLS_ECDSA, TestTLSTransferCustomCertVerifier) {
524 SetMockCertVerifier(/*return_value=*/true);
525 TestHandshake(/*expect_success=*/true);
526 TestTransfer("Hello, world!");
527}
528
Diogo Real1dca9d52017-08-29 12:18:32 -0700529// Test transfer using ALPN with protos as h2 and http/1.1
530TEST_F(SSLAdapterTestTLS_ECDSA, TestTLSALPN) {
531 std::vector<std::string> alpn_protos{"h2", "http/1.1"};
532 SetAlpnProtocols(alpn_protos);
533 TestHandshake(true);
534 TestTransfer("Hello, world!");
535}
536
Diogo Real7bd1f1b2017-09-08 12:50:41 -0700537// Test transfer with TLS Elliptic curves set to "X25519:P-256:P-384:P-521"
538TEST_F(SSLAdapterTestTLS_ECDSA, TestTLSEllipticCurves) {
539 std::vector<std::string> elliptic_curves{"X25519", "P-256", "P-384", "P-521"};
540 SetEllipticCurves(elliptic_curves);
541 TestHandshake(true);
542 TestTransfer("Hello, world!");
543}
544
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000545// Basic tests: DTLS
546
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200547// Test that handshake works, using RSA
548TEST_F(SSLAdapterTestDTLS_RSA, TestDTLSConnect) {
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000549 TestHandshake(true);
550}
551
Benjamin Wright6e9c3df2018-05-22 16:11:56 -0700552// Test that handshake works with a custom verifier that returns true. DTLS_RSA.
553TEST_F(SSLAdapterTestDTLS_RSA, TestDTLSConnectCustomCertVerifierSucceeds) {
554 SetMockCertVerifier(/*return_value=*/true);
555 TestHandshake(/*expect_success=*/true);
556}
557
558// Test that handshake fails with a custom verifier that returns false.
559// DTLS_RSA.
560TEST_F(SSLAdapterTestDTLS_RSA, TestTLSConnectCustomCertVerifierFails) {
561 SetMockCertVerifier(/*return_value=*/false);
562 TestHandshake(/*expect_success=*/false);
563}
564
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200565// Test that handshake works, using ECDSA
566TEST_F(SSLAdapterTestDTLS_ECDSA, TestDTLSConnect) {
567 TestHandshake(true);
568}
569
Benjamin Wright6e9c3df2018-05-22 16:11:56 -0700570// Test that handshake works with a custom verifier that returns true.
571// DTLS_ECDSA.
572TEST_F(SSLAdapterTestDTLS_ECDSA, TestDTLSConnectCustomCertVerifierSucceeds) {
573 SetMockCertVerifier(/*return_value=*/true);
574 TestHandshake(/*expect_success=*/true);
575}
576
577// Test that handshake fails with a custom verifier that returns false.
578// DTLS_ECDSA.
579TEST_F(SSLAdapterTestDTLS_ECDSA, TestTLSConnectCustomCertVerifierFails) {
580 SetMockCertVerifier(/*return_value=*/false);
581 TestHandshake(/*expect_success=*/false);
582}
583
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200584// Test transfer between client and server, using RSA
585TEST_F(SSLAdapterTestDTLS_RSA, TestDTLSTransfer) {
586 TestHandshake(true);
587 TestTransfer("Hello, world!");
588}
589
Benjamin Wright6e9c3df2018-05-22 16:11:56 -0700590// Test transfer between client and server, using RSA with custom cert verifier.
591TEST_F(SSLAdapterTestDTLS_RSA, TestDTLSTransferCustomCertVerifier) {
592 SetMockCertVerifier(/*return_value=*/true);
593 TestHandshake(/*expect_success=*/true);
594 TestTransfer("Hello, world!");
595}
596
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200597// Test transfer between client and server, using ECDSA
598TEST_F(SSLAdapterTestDTLS_ECDSA, TestDTLSTransfer) {
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000599 TestHandshake(true);
600 TestTransfer("Hello, world!");
601}
Benjamin Wright6e9c3df2018-05-22 16:11:56 -0700602
603// Test transfer between client and server, using ECDSA with custom cert
604// verifier.
605TEST_F(SSLAdapterTestDTLS_ECDSA, TestDTLSTransferCustomCertVerifier) {
606 SetMockCertVerifier(/*return_value=*/true);
607 TestHandshake(/*expect_success=*/true);
608 TestTransfer("Hello, world!");
609}