blob: ec532b1c442618ff2d74f558d56c602f6fde2809 [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"
17#include "rtc_base/ipaddress.h"
18#include "rtc_base/socketstream.h"
19#include "rtc_base/ssladapter.h"
20#include "rtc_base/sslidentity.h"
21#include "rtc_base/sslstreamadapter.h"
22#include "rtc_base/stream.h"
23#include "rtc_base/stringencode.h"
24#include "rtc_base/virtualsocketserver.h"
Benjamin Wright6e9c3df2018-05-22 16:11:56 -070025#include "test/gmock.h"
26
27using ::testing::_;
28using ::testing::Return;
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +000029
30static const int kTimeout = 5000;
31
32static rtc::AsyncSocket* CreateSocket(const rtc::SSLMode& ssl_mode) {
33 rtc::SocketAddress address(rtc::IPAddress(INADDR_ANY), 0);
34
Yves Gerey665174f2018-06-19 15:03:05 +020035 rtc::AsyncSocket* socket =
36 rtc::Thread::Current()->socketserver()->CreateAsyncSocket(
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;
52 MOCK_METHOD1(Verify, bool(const rtc::SSLCertificate&));
53};
54
55// TODO(benwright) - Move to using INSTANTIATE_TEST_CASE_P instead of using
56// 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) {
61 rtc::AsyncSocket* socket = CreateSocket(ssl_mode_);
62
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
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +000098 rtc::AsyncSocket::ConnState GetState() const {
99 return ssl_adapter_->GetState();
100 }
101
Yves Gerey665174f2018-06-19 15:03:05 +0200102 const std::string& GetReceivedData() const { return data_; }
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000103
104 int Connect(const std::string& 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
113 if (ssl_adapter_->StartSSL(hostname.c_str(), false) != 0) {
114 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
123 int Send(const std::string& 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
129 void OnSSLAdapterReadEvent(rtc::AsyncSocket* socket) {
130 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
143 void OnSSLAdapterCloseEvent(rtc::AsyncSocket* socket, int error) {
144 // 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.
147 if (socket->GetState() != rtc::AsyncSocket::CS_CLOSED) {
148 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.
torbjorng4e572472015-10-08 09:42:49 -0700166 ssl_identity_.reset(rtc::SSLIdentity::Generate(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
194 int Send(const std::string& 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(
207 message.data(), message.length(), &written, &error);
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000208 if (r == rtc::SR_SUCCESS) {
209 return written;
210 } else {
211 return -1;
212 }
213 }
214
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000215 void AcceptConnection(const rtc::SocketAddress& address) {
216 // Only a single connection is supported.
deadbeef37f5ecf2017-02-27 14:06:41 -0800217 ASSERT_TRUE(ssl_stream_adapter_ == nullptr);
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000218
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.
223 rtc::AsyncSocket* socket = server_socket_.release();
224
225 socket->Connect(address);
226
227 DoHandshake(socket);
228 }
229
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000230 void OnServerSocketReadEvent(rtc::AsyncSocket* socket) {
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000231 // Only a single connection is supported.
deadbeef37f5ecf2017-02-27 14:06:41 -0800232 ASSERT_TRUE(ssl_stream_adapter_ == nullptr);
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000233
deadbeef37f5ecf2017-02-27 14:06:41 -0800234 DoHandshake(server_socket_->Accept(nullptr));
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000235 }
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:44 +0000240 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 10:33:16 -0700245 rtc::StreamResult r =
246 stream->Read(buffer, sizeof(buffer) - 1, &read, &error);
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000247 if (r == rtc::SR_SUCCESS) {
248 buffer[read] = '\0';
Mirko Bonadei675513b2017-11-09 11:09:25 +0100249 RTC_LOG(LS_INFO) << "Server received '" << buffer << "'";
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000250 data_ += buffer;
251 }
252 }
253 }
254
255 private:
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000256 void DoHandshake(rtc::AsyncSocket* socket) {
257 rtc::SocketStream* stream = new rtc::SocketStream(socket);
258
259 ssl_stream_adapter_.reset(rtc::SSLStreamAdapter::Create(stream));
260
261 ssl_stream_adapter_->SetMode(ssl_mode_);
262 ssl_stream_adapter_->SetServerRole();
263
264 // SSLStreamAdapter is normally used for peer-to-peer communication, but
265 // here we're testing communication between a client and a server
266 // (e.g. a WebRTC-based application and an RFC 5766 TURN server), where
267 // clients are not required to provide a certificate during handshake.
268 // Accordingly, we must disable client authentication here.
269 ssl_stream_adapter_->set_client_auth_enabled(false);
270
271 ssl_stream_adapter_->SetIdentity(ssl_identity_->GetReference());
272
273 // Set a bogus peer certificate digest.
274 unsigned char digest[20];
275 size_t digest_len = sizeof(digest);
276 ssl_stream_adapter_->SetPeerCertificateDigest(rtc::DIGEST_SHA_1, digest,
Yves Gerey665174f2018-06-19 15:03:05 +0200277 digest_len);
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000278
Taylor Brandstetterc8762a82016-08-11 12:01:49 -0700279 ssl_stream_adapter_->StartSSL();
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000280
Yves Gerey665174f2018-06-19 15:03:05 +0200281 ssl_stream_adapter_->SignalEvent.connect(
282 this, &SSLAdapterTestDummyServer::OnSSLStreamAdapterEvent);
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000283 }
284
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000285 const rtc::SSLMode ssl_mode_;
286
jbauch555604a2016-04-26 03:13:22 -0700287 std::unique_ptr<rtc::AsyncSocket> server_socket_;
288 std::unique_ptr<rtc::SSLStreamAdapter> ssl_stream_adapter_;
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000289
jbauch555604a2016-04-26 03:13:22 -0700290 std::unique_ptr<rtc::SSLIdentity> ssl_identity_;
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000291
292 std::string data_;
293};
294
Yves Gerey665174f2018-06-19 15:03:05 +0200295class SSLAdapterTestBase : public testing::Test, public sigslot::has_slots<> {
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000296 public:
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200297 explicit SSLAdapterTestBase(const rtc::SSLMode& ssl_mode,
torbjorng4e572472015-10-08 09:42:49 -0700298 const rtc::KeyParams& key_params)
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000299 : ssl_mode_(ssl_mode),
deadbeef98e186c2017-05-16 18:00:06 -0700300 vss_(new rtc::VirtualSocketServer()),
nisse7eaa4ea2017-05-08 05:25:41 -0700301 thread_(vss_.get()),
torbjorng4e572472015-10-08 09:42:49 -0700302 server_(new SSLAdapterTestDummyServer(ssl_mode_, key_params)),
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000303 client_(new SSLAdapterTestDummyClient(ssl_mode_)),
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200304 handshake_wait_(kTimeout) {}
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000305
Yves Gerey665174f2018-06-19 15:03:05 +0200306 void SetHandshakeWait(int wait) { handshake_wait_ = wait; }
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000307
Sergey Silkin9c147dd2018-09-12 10:45:38 +0000308 void SetIgnoreBadCert(bool ignore_bad_cert) {
309 client_->SetIgnoreBadCert(ignore_bad_cert);
Benjamin Wright6e9c3df2018-05-22 16:11:56 -0700310 }
311
312 void SetCertVerifier(rtc::SSLCertificateVerifier* ssl_cert_verifier) {
313 client_->SetCertVerifier(ssl_cert_verifier);
314 }
315
Sergey Silkin9c147dd2018-09-12 10:45:38 +0000316 void SetAlpnProtocols(const std::vector<std::string>& protos) {
317 client_->SetAlpnProtocols(protos);
318 }
319
320 void SetEllipticCurves(const std::vector<std::string>& curves) {
321 client_->SetEllipticCurves(curves);
322 }
323
Benjamin Wright6e9c3df2018-05-22 16:11:56 -0700324 void SetMockCertVerifier(bool return_value) {
Karl Wiberg918f50c2018-07-05 11:40:33 +0200325 auto mock_verifier = absl::make_unique<MockCertVerifier>();
Benjamin Wright6e9c3df2018-05-22 16:11:56 -0700326 EXPECT_CALL(*mock_verifier, Verify(_)).WillRepeatedly(Return(return_value));
327 cert_verifier_ =
328 std::unique_ptr<rtc::SSLCertificateVerifier>(std::move(mock_verifier));
329
Sergey Silkin9c147dd2018-09-12 10:45:38 +0000330 SetIgnoreBadCert(false);
Benjamin Wright6e9c3df2018-05-22 16:11:56 -0700331 SetCertVerifier(cert_verifier_.get());
332 }
333
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000334 void TestHandshake(bool expect_success) {
335 int rv;
336
337 // The initial state is CS_CLOSED
338 ASSERT_EQ(rtc::AsyncSocket::CS_CLOSED, client_->GetState());
339
340 rv = client_->Connect(server_->GetHostname(), server_->GetAddress());
341 ASSERT_EQ(0, rv);
342
343 // Now the state should be CS_CONNECTING
344 ASSERT_EQ(rtc::AsyncSocket::CS_CONNECTING, client_->GetState());
345
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000346 if (ssl_mode_ == rtc::SSL_MODE_DTLS) {
347 // For DTLS, call AcceptConnection() with the client's address.
348 server_->AcceptConnection(client_->GetAddress());
349 }
350
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000351 if (expect_success) {
352 // If expecting success, the client should end up in the CS_CONNECTED
353 // state after handshake.
354 EXPECT_EQ_WAIT(rtc::AsyncSocket::CS_CONNECTED, client_->GetState(),
Yves Gerey665174f2018-06-19 15:03:05 +0200355 handshake_wait_);
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000356
Mirko Bonadei675513b2017-11-09 11:09:25 +0100357 RTC_LOG(LS_INFO) << GetSSLProtocolName(ssl_mode_)
358 << " handshake complete.";
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000359
360 } else {
361 // On handshake failure the client should end up in the CS_CLOSED state.
362 EXPECT_EQ_WAIT(rtc::AsyncSocket::CS_CLOSED, client_->GetState(),
Yves Gerey665174f2018-06-19 15:03:05 +0200363 handshake_wait_);
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000364
Mirko Bonadei675513b2017-11-09 11:09:25 +0100365 RTC_LOG(LS_INFO) << GetSSLProtocolName(ssl_mode_) << " handshake failed.";
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000366 }
367 }
368
369 void TestTransfer(const std::string& message) {
370 int rv;
371
372 rv = client_->Send(message);
373 ASSERT_EQ(static_cast<int>(message.length()), rv);
374
375 // The server should have received the client's message.
376 EXPECT_EQ_WAIT(message, server_->GetReceivedData(), kTimeout);
377
378 rv = server_->Send(message);
379 ASSERT_EQ(static_cast<int>(message.length()), rv);
380
381 // The client should have received the server's message.
382 EXPECT_EQ_WAIT(message, client_->GetReceivedData(), kTimeout);
383
Mirko Bonadei675513b2017-11-09 11:09:25 +0100384 RTC_LOG(LS_INFO) << "Transfer complete.";
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000385 }
386
deadbeefed3b9862017-06-02 10:33:16 -0700387 protected:
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000388 const rtc::SSLMode ssl_mode_;
389
nisse7eaa4ea2017-05-08 05:25:41 -0700390 std::unique_ptr<rtc::VirtualSocketServer> vss_;
391 rtc::AutoSocketServerThread thread_;
jbauch555604a2016-04-26 03:13:22 -0700392 std::unique_ptr<SSLAdapterTestDummyServer> server_;
393 std::unique_ptr<SSLAdapterTestDummyClient> client_;
Benjamin Wright6e9c3df2018-05-22 16:11:56 -0700394 std::unique_ptr<rtc::SSLCertificateVerifier> cert_verifier_;
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000395
396 int handshake_wait_;
397};
398
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200399class SSLAdapterTestTLS_RSA : public SSLAdapterTestBase {
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000400 public:
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200401 SSLAdapterTestTLS_RSA()
torbjorng4e572472015-10-08 09:42:49 -0700402 : SSLAdapterTestBase(rtc::SSL_MODE_TLS, rtc::KeyParams::RSA()) {}
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000403};
404
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200405class SSLAdapterTestTLS_ECDSA : public SSLAdapterTestBase {
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000406 public:
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200407 SSLAdapterTestTLS_ECDSA()
torbjorng4e572472015-10-08 09:42:49 -0700408 : SSLAdapterTestBase(rtc::SSL_MODE_TLS, rtc::KeyParams::ECDSA()) {}
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200409};
410
411class SSLAdapterTestDTLS_RSA : public SSLAdapterTestBase {
412 public:
413 SSLAdapterTestDTLS_RSA()
torbjorng4e572472015-10-08 09:42:49 -0700414 : SSLAdapterTestBase(rtc::SSL_MODE_DTLS, rtc::KeyParams::RSA()) {}
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200415};
416
417class SSLAdapterTestDTLS_ECDSA : public SSLAdapterTestBase {
418 public:
419 SSLAdapterTestDTLS_ECDSA()
torbjorng4e572472015-10-08 09:42:49 -0700420 : SSLAdapterTestBase(rtc::SSL_MODE_DTLS, rtc::KeyParams::ECDSA()) {}
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000421};
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000422
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000423// Basic tests: TLS
424
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200425// Test that handshake works, using RSA
426TEST_F(SSLAdapterTestTLS_RSA, TestTLSConnect) {
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000427 TestHandshake(true);
428}
429
Benjamin Wright6e9c3df2018-05-22 16:11:56 -0700430// Test that handshake works with a custom verifier that returns true. RSA.
431TEST_F(SSLAdapterTestTLS_RSA, TestTLSConnectCustomCertVerifierSucceeds) {
432 SetMockCertVerifier(/*return_value=*/true);
433 TestHandshake(/*expect_success=*/true);
434}
435
436// Test that handshake fails with a custom verifier that returns false. RSA.
437TEST_F(SSLAdapterTestTLS_RSA, TestTLSConnectCustomCertVerifierFails) {
438 SetMockCertVerifier(/*return_value=*/false);
439 TestHandshake(/*expect_success=*/false);
440}
441
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200442// Test that handshake works, using ECDSA
443TEST_F(SSLAdapterTestTLS_ECDSA, TestTLSConnect) {
Benjamin Wright6e9c3df2018-05-22 16:11:56 -0700444 SetMockCertVerifier(/*return_value=*/true);
445 TestHandshake(/*expect_success=*/true);
446}
447
448// Test that handshake works with a custom verifier that returns true. ECDSA.
449TEST_F(SSLAdapterTestTLS_ECDSA, TestTLSConnectCustomCertVerifierSucceeds) {
450 SetMockCertVerifier(/*return_value=*/true);
451 TestHandshake(/*expect_success=*/true);
452}
453
454// Test that handshake fails with a custom verifier that returns false. ECDSA.
455TEST_F(SSLAdapterTestTLS_ECDSA, TestTLSConnectCustomCertVerifierFails) {
456 SetMockCertVerifier(/*return_value=*/false);
457 TestHandshake(/*expect_success=*/false);
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200458}
459
460// Test transfer between client and server, using RSA
461TEST_F(SSLAdapterTestTLS_RSA, TestTLSTransfer) {
462 TestHandshake(true);
463 TestTransfer("Hello, world!");
464}
465
Benjamin Wright6e9c3df2018-05-22 16:11:56 -0700466// Test transfer between client and server, using RSA with custom cert verifier.
467TEST_F(SSLAdapterTestTLS_RSA, TestTLSTransferCustomCertVerifier) {
468 SetMockCertVerifier(/*return_value=*/true);
469 TestHandshake(/*expect_success=*/true);
470 TestTransfer("Hello, world!");
471}
472
deadbeefed3b9862017-06-02 10:33:16 -0700473TEST_F(SSLAdapterTestTLS_RSA, TestTLSTransferWithBlockedSocket) {
474 TestHandshake(true);
475
476 // Tell the underlying socket to simulate being blocked.
477 vss_->SetSendingBlocked(true);
478
479 std::string expected;
480 int rv;
481 // Send messages until the SSL socket adapter starts applying backpressure.
482 // Note that this may not occur immediately since there may be some amount of
483 // intermediate buffering (either in our code or in BoringSSL).
484 for (int i = 0; i < 1024; ++i) {
485 std::string message = "Hello, world: " + rtc::ToString(i);
486 rv = client_->Send(message);
487 if (rv != static_cast<int>(message.size())) {
488 // This test assumes either the whole message or none of it is sent.
489 ASSERT_EQ(-1, rv);
490 break;
491 }
492 expected += message;
493 }
494 // Assert that the loop above exited due to Send returning -1.
495 ASSERT_EQ(-1, rv);
496
497 // Try sending another message while blocked. -1 should be returned again and
498 // it shouldn't end up received by the server later.
499 EXPECT_EQ(-1, client_->Send("Never sent"));
500
501 // Unblock the underlying socket. All of the buffered messages should be sent
502 // without any further action.
503 vss_->SetSendingBlocked(false);
504 EXPECT_EQ_WAIT(expected, server_->GetReceivedData(), kTimeout);
505
506 // Send another message. This previously wasn't working
507 std::string final_message = "Fin.";
508 expected += final_message;
509 EXPECT_EQ(static_cast<int>(final_message.size()),
510 client_->Send(final_message));
511 EXPECT_EQ_WAIT(expected, server_->GetReceivedData(), kTimeout);
512}
513
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200514// Test transfer between client and server, using ECDSA
515TEST_F(SSLAdapterTestTLS_ECDSA, TestTLSTransfer) {
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000516 TestHandshake(true);
517 TestTransfer("Hello, world!");
518}
519
Benjamin Wright6e9c3df2018-05-22 16:11:56 -0700520// Test transfer between client and server, using ECDSA with custom cert
521// verifier.
522TEST_F(SSLAdapterTestTLS_ECDSA, TestTLSTransferCustomCertVerifier) {
523 SetMockCertVerifier(/*return_value=*/true);
524 TestHandshake(/*expect_success=*/true);
525 TestTransfer("Hello, world!");
526}
527
Diogo Real1dca9d52017-08-29 12:18:32 -0700528// Test transfer using ALPN with protos as h2 and http/1.1
529TEST_F(SSLAdapterTestTLS_ECDSA, TestTLSALPN) {
530 std::vector<std::string> alpn_protos{"h2", "http/1.1"};
531 SetAlpnProtocols(alpn_protos);
532 TestHandshake(true);
533 TestTransfer("Hello, world!");
534}
535
Diogo Real7bd1f1b2017-09-08 12:50:41 -0700536// Test transfer with TLS Elliptic curves set to "X25519:P-256:P-384:P-521"
537TEST_F(SSLAdapterTestTLS_ECDSA, TestTLSEllipticCurves) {
538 std::vector<std::string> elliptic_curves{"X25519", "P-256", "P-384", "P-521"};
539 SetEllipticCurves(elliptic_curves);
540 TestHandshake(true);
541 TestTransfer("Hello, world!");
542}
543
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000544// Basic tests: DTLS
545
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200546// Test that handshake works, using RSA
547TEST_F(SSLAdapterTestDTLS_RSA, TestDTLSConnect) {
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000548 TestHandshake(true);
549}
550
Benjamin Wright6e9c3df2018-05-22 16:11:56 -0700551// Test that handshake works with a custom verifier that returns true. DTLS_RSA.
552TEST_F(SSLAdapterTestDTLS_RSA, TestDTLSConnectCustomCertVerifierSucceeds) {
553 SetMockCertVerifier(/*return_value=*/true);
554 TestHandshake(/*expect_success=*/true);
555}
556
557// Test that handshake fails with a custom verifier that returns false.
558// DTLS_RSA.
559TEST_F(SSLAdapterTestDTLS_RSA, TestTLSConnectCustomCertVerifierFails) {
560 SetMockCertVerifier(/*return_value=*/false);
561 TestHandshake(/*expect_success=*/false);
562}
563
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200564// Test that handshake works, using ECDSA
565TEST_F(SSLAdapterTestDTLS_ECDSA, TestDTLSConnect) {
566 TestHandshake(true);
567}
568
Benjamin Wright6e9c3df2018-05-22 16:11:56 -0700569// Test that handshake works with a custom verifier that returns true.
570// DTLS_ECDSA.
571TEST_F(SSLAdapterTestDTLS_ECDSA, TestDTLSConnectCustomCertVerifierSucceeds) {
572 SetMockCertVerifier(/*return_value=*/true);
573 TestHandshake(/*expect_success=*/true);
574}
575
576// Test that handshake fails with a custom verifier that returns false.
577// DTLS_ECDSA.
578TEST_F(SSLAdapterTestDTLS_ECDSA, TestTLSConnectCustomCertVerifierFails) {
579 SetMockCertVerifier(/*return_value=*/false);
580 TestHandshake(/*expect_success=*/false);
581}
582
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200583// Test transfer between client and server, using RSA
584TEST_F(SSLAdapterTestDTLS_RSA, TestDTLSTransfer) {
585 TestHandshake(true);
586 TestTransfer("Hello, world!");
587}
588
Benjamin Wright6e9c3df2018-05-22 16:11:56 -0700589// Test transfer between client and server, using RSA with custom cert verifier.
590TEST_F(SSLAdapterTestDTLS_RSA, TestDTLSTransferCustomCertVerifier) {
591 SetMockCertVerifier(/*return_value=*/true);
592 TestHandshake(/*expect_success=*/true);
593 TestTransfer("Hello, world!");
594}
595
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200596// Test transfer between client and server, using ECDSA
597TEST_F(SSLAdapterTestDTLS_ECDSA, TestDTLSTransfer) {
pthatcher@webrtc.orga9b1ec02014-12-29 23:00:14 +0000598 TestHandshake(true);
599 TestTransfer("Hello, world!");
600}
Benjamin Wright6e9c3df2018-05-22 16:11:56 -0700601
602// Test transfer between client and server, using ECDSA with custom cert
603// verifier.
604TEST_F(SSLAdapterTestDTLS_ECDSA, TestDTLSTransferCustomCertVerifier) {
605 SetMockCertVerifier(/*return_value=*/true);
606 TestHandshake(/*expect_success=*/true);
607 TestTransfer("Hello, world!");
608}