blob: b99f8343af8a2e2a63de30430a02f50763c3d166 [file] [log] [blame]
[email protected]1bc6f5e2012-03-15 00:20:581// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]f61c3972010-12-23 09:54:152// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// This test suite uses SSLClientSocket to test the implementation of
6// SSLServerSocket. In order to establish connections between the sockets
7// we need two additional classes:
8// 1. FakeSocket
9// Connects SSL socket to FakeDataChannel. This class is just a stub.
10//
11// 2. FakeDataChannel
12// Implements the actual exchange of data between two FakeSockets.
13//
14// Implementations of these two classes are included in this file.
15
16#include "net/socket/ssl_server_socket.h"
17
[email protected]55ee0e52011-07-21 18:29:4418#include <stdlib.h>
19
[email protected]f61c3972010-12-23 09:54:1520#include <queue>
21
[email protected]55ee0e52011-07-21 18:29:4422#include "base/compiler_specific.h"
[email protected]57999812013-02-24 05:40:5223#include "base/files/file_path.h"
thestigd8df0332014-09-04 06:33:2924#include "base/files/file_util.h"
skyostil4891b25b2015-06-11 11:43:4525#include "base/location.h"
[email protected]18b577412013-07-18 04:19:1526#include "base/message_loop/message_loop.h"
skyostil4891b25b2015-06-11 11:43:4527#include "base/single_thread_task_runner.h"
28#include "base/thread_task_runner_handle.h"
[email protected]4b559b4d2011-04-14 17:37:1429#include "crypto/nss_util.h"
30#include "crypto/rsa_private_key.h"
[email protected]f61c3972010-12-23 09:54:1531#include "net/base/address_list.h"
[email protected]6ea7b152011-12-21 21:21:1332#include "net/base/completion_callback.h"
[email protected]f61c3972010-12-23 09:54:1533#include "net/base/host_port_pair.h"
34#include "net/base/io_buffer.h"
[email protected]e7f74da2011-04-19 23:49:3535#include "net/base/ip_endpoint.h"
[email protected]f61c3972010-12-23 09:54:1536#include "net/base/net_errors.h"
[email protected]42fdb452012-11-01 12:44:4037#include "net/base/test_data_directory.h"
[email protected]6e7845ae2013-03-29 21:48:1138#include "net/cert/cert_status_flags.h"
39#include "net/cert/mock_cert_verifier.h"
40#include "net/cert/x509_certificate.h"
[email protected]b1c988b2013-06-13 06:48:1141#include "net/http/transport_security_state.h"
eroman87c53d62015-04-02 06:51:0742#include "net/log/net_log.h"
[email protected]f61c3972010-12-23 09:54:1543#include "net/socket/client_socket_factory.h"
44#include "net/socket/socket_test_util.h"
45#include "net/socket/ssl_client_socket.h"
[email protected]3268023f2011-05-05 00:08:1046#include "net/socket/stream_socket.h"
davidben9dd84872015-05-02 00:22:5847#include "net/ssl/ssl_cipher_suite_names.h"
[email protected]536fd0b2013-03-14 17:41:5748#include "net/ssl/ssl_config_service.h"
davidben9dd84872015-05-02 00:22:5849#include "net/ssl/ssl_connection_status_flags.h"
[email protected]536fd0b2013-03-14 17:41:5750#include "net/ssl/ssl_info.h"
[email protected]6e7845ae2013-03-29 21:48:1151#include "net/test/cert_test_util.h"
[email protected]f61c3972010-12-23 09:54:1552#include "testing/gtest/include/gtest/gtest.h"
53#include "testing/platform_test.h"
54
davidben9dd84872015-05-02 00:22:5855#if !defined(USE_OPENSSL)
56#include <pk11pub.h>
57
58#if !defined(CKM_AES_GCM)
59#define CKM_AES_GCM 0x00001087
60#endif
davidben299e3072015-05-04 19:06:4961#if !defined(CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256)
62#define CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256 (CKM_NSS + 24)
63#endif
davidben9dd84872015-05-02 00:22:5864#endif
65
[email protected]f61c3972010-12-23 09:54:1566namespace net {
67
68namespace {
69
70class FakeDataChannel {
71 public:
[email protected]55ee0e52011-07-21 18:29:4472 FakeDataChannel()
[email protected]83039bb2011-12-09 18:43:5573 : read_buf_len_(0),
[email protected]c0e4dd12012-05-16 19:36:3174 closed_(false),
[email protected]d5492c52013-11-10 20:44:3975 write_called_after_close_(false),
76 weak_factory_(this) {
[email protected]f61c3972010-12-23 09:54:1577 }
78
[email protected]47a12862012-04-10 01:00:4979 int Read(IOBuffer* buf, int buf_len, const CompletionCallback& callback) {
[email protected]4da82282014-07-16 18:40:4380 DCHECK(read_callback_.is_null());
dcheng08ea2af02014-08-25 23:38:0981 DCHECK(!read_buf_.get());
[email protected]c0e4dd12012-05-16 19:36:3182 if (closed_)
83 return 0;
[email protected]3f55aa12011-12-07 02:03:3384 if (data_.empty()) {
[email protected]f61c3972010-12-23 09:54:1585 read_callback_ = callback;
86 read_buf_ = buf;
87 read_buf_len_ = buf_len;
[email protected]fa6ce922014-07-17 04:27:0488 return ERR_IO_PENDING;
[email protected]f61c3972010-12-23 09:54:1589 }
90 return PropogateData(buf, buf_len);
91 }
92
[email protected]47a12862012-04-10 01:00:4993 int Write(IOBuffer* buf, int buf_len, const CompletionCallback& callback) {
[email protected]4da82282014-07-16 18:40:4394 DCHECK(write_callback_.is_null());
[email protected]c0e4dd12012-05-16 19:36:3195 if (closed_) {
96 if (write_called_after_close_)
[email protected]fa6ce922014-07-17 04:27:0497 return ERR_CONNECTION_RESET;
[email protected]c0e4dd12012-05-16 19:36:3198 write_called_after_close_ = true;
99 write_callback_ = callback;
skyostil4891b25b2015-06-11 11:43:45100 base::ThreadTaskRunnerHandle::Get()->PostTask(
[email protected]c0e4dd12012-05-16 19:36:31101 FROM_HERE, base::Bind(&FakeDataChannel::DoWriteCallback,
102 weak_factory_.GetWeakPtr()));
[email protected]fa6ce922014-07-17 04:27:04103 return ERR_IO_PENDING;
[email protected]c0e4dd12012-05-16 19:36:31104 }
[email protected]4da82282014-07-16 18:40:43105 // This function returns synchronously, so make a copy of the buffer.
[email protected]fa6ce922014-07-17 04:27:04106 data_.push(new DrainableIOBuffer(
107 new StringIOBuffer(std::string(buf->data(), buf_len)),
[email protected]4da82282014-07-16 18:40:43108 buf_len));
skyostil4891b25b2015-06-11 11:43:45109 base::ThreadTaskRunnerHandle::Get()->PostTask(
[email protected]83039bb2011-12-09 18:43:55110 FROM_HERE, base::Bind(&FakeDataChannel::DoReadCallback,
111 weak_factory_.GetWeakPtr()));
[email protected]f61c3972010-12-23 09:54:15112 return buf_len;
113 }
114
[email protected]c0e4dd12012-05-16 19:36:31115 // Closes the FakeDataChannel. After Close() is called, Read() returns 0,
116 // indicating EOF, and Write() fails with ERR_CONNECTION_RESET. Note that
117 // after the FakeDataChannel is closed, the first Write() call completes
118 // asynchronously, which is necessary to reproduce bug 127822.
119 void Close() {
120 closed_ = true;
121 }
122
[email protected]f61c3972010-12-23 09:54:15123 private:
124 void DoReadCallback() {
[email protected]83039bb2011-12-09 18:43:55125 if (read_callback_.is_null() || data_.empty())
[email protected]f61c3972010-12-23 09:54:15126 return;
127
128 int copied = PropogateData(read_buf_, read_buf_len_);
[email protected]83039bb2011-12-09 18:43:55129 CompletionCallback callback = read_callback_;
130 read_callback_.Reset();
131 read_buf_ = NULL;
132 read_buf_len_ = 0;
133 callback.Run(copied);
[email protected]f61c3972010-12-23 09:54:15134 }
135
[email protected]c0e4dd12012-05-16 19:36:31136 void DoWriteCallback() {
137 if (write_callback_.is_null())
138 return;
139
140 CompletionCallback callback = write_callback_;
141 write_callback_.Reset();
[email protected]fa6ce922014-07-17 04:27:04142 callback.Run(ERR_CONNECTION_RESET);
[email protected]c0e4dd12012-05-16 19:36:31143 }
144
[email protected]fa6ce922014-07-17 04:27:04145 int PropogateData(scoped_refptr<IOBuffer> read_buf, int read_buf_len) {
146 scoped_refptr<DrainableIOBuffer> buf = data_.front();
[email protected]f61c3972010-12-23 09:54:15147 int copied = std::min(buf->BytesRemaining(), read_buf_len);
148 memcpy(read_buf->data(), buf->data(), copied);
149 buf->DidConsume(copied);
150
151 if (!buf->BytesRemaining())
152 data_.pop();
153 return copied;
154 }
155
[email protected]83039bb2011-12-09 18:43:55156 CompletionCallback read_callback_;
[email protected]fa6ce922014-07-17 04:27:04157 scoped_refptr<IOBuffer> read_buf_;
[email protected]f61c3972010-12-23 09:54:15158 int read_buf_len_;
159
[email protected]c0e4dd12012-05-16 19:36:31160 CompletionCallback write_callback_;
161
[email protected]fa6ce922014-07-17 04:27:04162 std::queue<scoped_refptr<DrainableIOBuffer> > data_;
[email protected]f61c3972010-12-23 09:54:15163
[email protected]c0e4dd12012-05-16 19:36:31164 // True if Close() has been called.
165 bool closed_;
166
167 // Controls the completion of Write() after the FakeDataChannel is closed.
168 // After the FakeDataChannel is closed, the first Write() call completes
169 // asynchronously.
170 bool write_called_after_close_;
171
[email protected]d5492c52013-11-10 20:44:39172 base::WeakPtrFactory<FakeDataChannel> weak_factory_;
173
[email protected]f61c3972010-12-23 09:54:15174 DISALLOW_COPY_AND_ASSIGN(FakeDataChannel);
175};
176
[email protected]3268023f2011-05-05 00:08:10177class FakeSocket : public StreamSocket {
[email protected]f61c3972010-12-23 09:54:15178 public:
179 FakeSocket(FakeDataChannel* incoming_channel,
180 FakeDataChannel* outgoing_channel)
181 : incoming_(incoming_channel),
182 outgoing_(outgoing_channel) {
183 }
184
dchengb03027d2014-10-21 12:00:20185 ~FakeSocket() override {}
[email protected]f61c3972010-12-23 09:54:15186
dchengb03027d2014-10-21 12:00:20187 int Read(IOBuffer* buf,
188 int buf_len,
189 const CompletionCallback& callback) override {
[email protected]3f55aa12011-12-07 02:03:33190 // Read random number of bytes.
191 buf_len = rand() % buf_len + 1;
192 return incoming_->Read(buf, buf_len, callback);
193 }
[email protected]f61c3972010-12-23 09:54:15194
dchengb03027d2014-10-21 12:00:20195 int Write(IOBuffer* buf,
196 int buf_len,
197 const CompletionCallback& callback) override {
[email protected]55ee0e52011-07-21 18:29:44198 // Write random number of bytes.
199 buf_len = rand() % buf_len + 1;
[email protected]f61c3972010-12-23 09:54:15200 return outgoing_->Write(buf, buf_len, callback);
201 }
202
dchengb03027d2014-10-21 12:00:20203 int SetReceiveBufferSize(int32 size) override { return OK; }
[email protected]f61c3972010-12-23 09:54:15204
dchengb03027d2014-10-21 12:00:20205 int SetSendBufferSize(int32 size) override { return OK; }
[email protected]f61c3972010-12-23 09:54:15206
dchengb03027d2014-10-21 12:00:20207 int Connect(const CompletionCallback& callback) override { return OK; }
[email protected]f61c3972010-12-23 09:54:15208
dchengb03027d2014-10-21 12:00:20209 void Disconnect() override {
[email protected]c0e4dd12012-05-16 19:36:31210 incoming_->Close();
211 outgoing_->Close();
212 }
[email protected]f61c3972010-12-23 09:54:15213
dchengb03027d2014-10-21 12:00:20214 bool IsConnected() const override { return true; }
[email protected]f61c3972010-12-23 09:54:15215
dchengb03027d2014-10-21 12:00:20216 bool IsConnectedAndIdle() const override { return true; }
[email protected]f61c3972010-12-23 09:54:15217
dchengb03027d2014-10-21 12:00:20218 int GetPeerAddress(IPEndPoint* address) const override {
[email protected]fa6ce922014-07-17 04:27:04219 IPAddressNumber ip_address(kIPv4AddressSize);
220 *address = IPEndPoint(ip_address, 0 /*port*/);
221 return OK;
[email protected]f61c3972010-12-23 09:54:15222 }
223
dchengb03027d2014-10-21 12:00:20224 int GetLocalAddress(IPEndPoint* address) const override {
[email protected]fa6ce922014-07-17 04:27:04225 IPAddressNumber ip_address(4);
226 *address = IPEndPoint(ip_address, 0);
227 return OK;
[email protected]e7f74da2011-04-19 23:49:35228 }
229
dchengb03027d2014-10-21 12:00:20230 const BoundNetLog& NetLog() const override { return net_log_; }
[email protected]f61c3972010-12-23 09:54:15231
dchengb03027d2014-10-21 12:00:20232 void SetSubresourceSpeculation() override {}
233 void SetOmniboxSpeculation() override {}
[email protected]f61c3972010-12-23 09:54:15234
dchengb03027d2014-10-21 12:00:20235 bool WasEverUsed() const override { return true; }
[email protected]f61c3972010-12-23 09:54:15236
dchengb03027d2014-10-21 12:00:20237 bool UsingTCPFastOpen() const override { return false; }
[email protected]f61c3972010-12-23 09:54:15238
dchengb03027d2014-10-21 12:00:20239 bool WasNpnNegotiated() const override { return false; }
[email protected]5e6efa52011-06-27 17:26:41240
dchengb03027d2014-10-21 12:00:20241 NextProto GetNegotiatedProtocol() const override { return kProtoUnknown; }
[email protected]2d88e7d2012-07-19 17:55:17242
dchengb03027d2014-10-21 12:00:20243 bool GetSSLInfo(SSLInfo* ssl_info) override { return false; }
[email protected]2d88e7d2012-07-19 17:55:17244
ttuttle23fdb7b2015-05-15 01:28:03245 void GetConnectionAttempts(ConnectionAttempts* out) const override {
246 out->clear();
247 }
248
249 void ClearConnectionAttempts() override {}
250
251 void AddConnectionAttempts(const ConnectionAttempts& attempts) override {}
252
[email protected]f61c3972010-12-23 09:54:15253 private:
[email protected]fa6ce922014-07-17 04:27:04254 BoundNetLog net_log_;
[email protected]f61c3972010-12-23 09:54:15255 FakeDataChannel* incoming_;
256 FakeDataChannel* outgoing_;
257
258 DISALLOW_COPY_AND_ASSIGN(FakeSocket);
259};
260
261} // namespace
262
263// Verify the correctness of the test helper classes first.
264TEST(FakeSocketTest, DataTransfer) {
265 // Establish channels between two sockets.
266 FakeDataChannel channel_1;
267 FakeDataChannel channel_2;
268 FakeSocket client(&channel_1, &channel_2);
269 FakeSocket server(&channel_2, &channel_1);
270
271 const char kTestData[] = "testing123";
272 const int kTestDataSize = strlen(kTestData);
273 const int kReadBufSize = 1024;
[email protected]fa6ce922014-07-17 04:27:04274 scoped_refptr<IOBuffer> write_buf = new StringIOBuffer(kTestData);
275 scoped_refptr<IOBuffer> read_buf = new IOBuffer(kReadBufSize);
[email protected]f61c3972010-12-23 09:54:15276
277 // Write then read.
[email protected]90499482013-06-01 00:39:50278 int written =
279 server.Write(write_buf.get(), kTestDataSize, CompletionCallback());
[email protected]55ee0e52011-07-21 18:29:44280 EXPECT_GT(written, 0);
281 EXPECT_LE(written, kTestDataSize);
282
[email protected]90499482013-06-01 00:39:50283 int read = client.Read(read_buf.get(), kReadBufSize, CompletionCallback());
[email protected]55ee0e52011-07-21 18:29:44284 EXPECT_GT(read, 0);
285 EXPECT_LE(read, written);
286 EXPECT_EQ(0, memcmp(kTestData, read_buf->data(), read));
[email protected]f61c3972010-12-23 09:54:15287
288 // Read then write.
[email protected]83039bb2011-12-09 18:43:55289 TestCompletionCallback callback;
[email protected]fa6ce922014-07-17 04:27:04290 EXPECT_EQ(ERR_IO_PENDING,
[email protected]90499482013-06-01 00:39:50291 server.Read(read_buf.get(), kReadBufSize, callback.callback()));
[email protected]55ee0e52011-07-21 18:29:44292
[email protected]90499482013-06-01 00:39:50293 written = client.Write(write_buf.get(), kTestDataSize, CompletionCallback());
[email protected]55ee0e52011-07-21 18:29:44294 EXPECT_GT(written, 0);
295 EXPECT_LE(written, kTestDataSize);
296
297 read = callback.WaitForResult();
298 EXPECT_GT(read, 0);
299 EXPECT_LE(read, written);
300 EXPECT_EQ(0, memcmp(kTestData, read_buf->data(), read));
[email protected]f61c3972010-12-23 09:54:15301}
302
303class SSLServerSocketTest : public PlatformTest {
304 public:
305 SSLServerSocketTest()
[email protected]fa6ce922014-07-17 04:27:04306 : socket_factory_(ClientSocketFactory::GetDefaultFactory()),
[email protected]b1c988b2013-06-13 06:48:11307 cert_verifier_(new MockCertVerifier()),
308 transport_security_state_(new TransportSecurityState) {
[email protected]fa6ce922014-07-17 04:27:04309 cert_verifier_->set_default_result(CERT_STATUS_AUTHORITY_INVALID);
[email protected]f61c3972010-12-23 09:54:15310 }
311
312 protected:
313 void Initialize() {
[email protected]18ccfdb2013-08-15 00:13:44314 scoped_ptr<ClientSocketHandle> client_connection(new ClientSocketHandle);
315 client_connection->SetSocket(
316 scoped_ptr<StreamSocket>(new FakeSocket(&channel_1_, &channel_2_)));
317 scoped_ptr<StreamSocket> server_socket(
318 new FakeSocket(&channel_2_, &channel_1_));
[email protected]f61c3972010-12-23 09:54:15319
[email protected]6cdfd7f2013-02-08 20:40:15320 base::FilePath certs_dir(GetTestCertsDirectory());
[email protected]f61c3972010-12-23 09:54:15321
[email protected]6cdfd7f2013-02-08 20:40:15322 base::FilePath cert_path = certs_dir.AppendASCII("unittest.selfsigned.der");
[email protected]f61c3972010-12-23 09:54:15323 std::string cert_der;
[email protected]82f84b92013-08-30 18:23:50324 ASSERT_TRUE(base::ReadFileToString(cert_path, &cert_der));
[email protected]f61c3972010-12-23 09:54:15325
[email protected]fa6ce922014-07-17 04:27:04326 scoped_refptr<X509Certificate> cert =
[email protected]f61c3972010-12-23 09:54:15327 X509Certificate::CreateFromBytes(cert_der.data(), cert_der.size());
328
[email protected]6cdfd7f2013-02-08 20:40:15329 base::FilePath key_path = certs_dir.AppendASCII("unittest.key.bin");
[email protected]f61c3972010-12-23 09:54:15330 std::string key_string;
[email protected]82f84b92013-08-30 18:23:50331 ASSERT_TRUE(base::ReadFileToString(key_path, &key_string));
[email protected]f61c3972010-12-23 09:54:15332 std::vector<uint8> key_vector(
333 reinterpret_cast<const uint8*>(key_string.data()),
334 reinterpret_cast<const uint8*>(key_string.data() +
335 key_string.length()));
336
[email protected]4b559b4d2011-04-14 17:37:14337 scoped_ptr<crypto::RSAPrivateKey> private_key(
338 crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(key_vector));
[email protected]f61c3972010-12-23 09:54:15339
sergeyuff826d5e2015-05-13 20:35:22340 client_ssl_config_.false_start_enabled = false;
341 client_ssl_config_.channel_id_enabled = false;
[email protected]f61c3972010-12-23 09:54:15342
343 // Certificate provided by the host doesn't need authority.
[email protected]fa6ce922014-07-17 04:27:04344 SSLConfig::CertAndStatus cert_and_status;
[email protected]4dc832e2011-04-28 22:04:24345 cert_and_status.cert_status = CERT_STATUS_AUTHORITY_INVALID;
[email protected]3d5c1bd2011-07-20 02:14:01346 cert_and_status.der_cert = cert_der;
sergeyuff826d5e2015-05-13 20:35:22347 client_ssl_config_.allowed_bad_certs.push_back(cert_and_status);
[email protected]f61c3972010-12-23 09:54:15348
[email protected]fa6ce922014-07-17 04:27:04349 HostPortPair host_and_pair("unittest", 0);
350 SSLClientSocketContext context;
[email protected]9f59fac2012-03-21 23:18:11351 context.cert_verifier = cert_verifier_.get();
[email protected]b1c988b2013-06-13 06:48:11352 context.transport_security_state = transport_security_state_.get();
sergeyuff826d5e2015-05-13 20:35:22353 client_socket_ = socket_factory_->CreateSSLClientSocket(
354 client_connection.Pass(), host_and_pair, client_ssl_config_, context);
355 server_socket_ =
356 CreateSSLServerSocket(server_socket.Pass(), cert.get(),
357 private_key.get(), server_ssl_config_);
[email protected]f61c3972010-12-23 09:54:15358 }
359
360 FakeDataChannel channel_1_;
361 FakeDataChannel channel_2_;
sergeyuff826d5e2015-05-13 20:35:22362 SSLConfig client_ssl_config_;
363 SSLConfig server_ssl_config_;
[email protected]fa6ce922014-07-17 04:27:04364 scoped_ptr<SSLClientSocket> client_socket_;
365 scoped_ptr<SSLServerSocket> server_socket_;
366 ClientSocketFactory* socket_factory_;
367 scoped_ptr<MockCertVerifier> cert_verifier_;
368 scoped_ptr<TransportSecurityState> transport_security_state_;
[email protected]f61c3972010-12-23 09:54:15369};
370
[email protected]f61c3972010-12-23 09:54:15371// This test only executes creation of client and server sockets. This is to
372// test that creation of sockets doesn't crash and have minimal code to run
373// under valgrind in order to help debugging memory problems.
374TEST_F(SSLServerSocketTest, Initialize) {
375 Initialize();
376}
377
[email protected]a7ac3c32011-06-17 19:10:15378// This test executes Connect() on SSLClientSocket and Handshake() on
379// SSLServerSocket to make sure handshaking between the two sockets is
[email protected]f61c3972010-12-23 09:54:15380// completed successfully.
381TEST_F(SSLServerSocketTest, Handshake) {
382 Initialize();
383
[email protected]83039bb2011-12-09 18:43:55384 TestCompletionCallback connect_callback;
[email protected]6ea7b152011-12-21 21:21:13385 TestCompletionCallback handshake_callback;
[email protected]f61c3972010-12-23 09:54:15386
[email protected]6ea7b152011-12-21 21:21:13387 int server_ret = server_socket_->Handshake(handshake_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04388 EXPECT_TRUE(server_ret == OK || server_ret == ERR_IO_PENDING);
[email protected]f61c3972010-12-23 09:54:15389
[email protected]83039bb2011-12-09 18:43:55390 int client_ret = client_socket_->Connect(connect_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04391 EXPECT_TRUE(client_ret == OK || client_ret == ERR_IO_PENDING);
[email protected]f61c3972010-12-23 09:54:15392
[email protected]fa6ce922014-07-17 04:27:04393 if (client_ret == ERR_IO_PENDING) {
394 EXPECT_EQ(OK, connect_callback.WaitForResult());
[email protected]f61c3972010-12-23 09:54:15395 }
[email protected]fa6ce922014-07-17 04:27:04396 if (server_ret == ERR_IO_PENDING) {
397 EXPECT_EQ(OK, handshake_callback.WaitForResult());
[email protected]f61c3972010-12-23 09:54:15398 }
[email protected]4dc832e2011-04-28 22:04:24399
400 // Make sure the cert status is expected.
401 SSLInfo ssl_info;
davidben9dd84872015-05-02 00:22:58402 ASSERT_TRUE(client_socket_->GetSSLInfo(&ssl_info));
[email protected]4dc832e2011-04-28 22:04:24403 EXPECT_EQ(CERT_STATUS_AUTHORITY_INVALID, ssl_info.cert_status);
davidben9dd84872015-05-02 00:22:58404
405 // The default cipher suite should be ECDHE and, unless on NSS and the
406 // platform doesn't support it, an AEAD.
407 uint16_t cipher_suite =
408 SSLConnectionStatusToCipherSuite(ssl_info.connection_status);
409 const char* key_exchange;
410 const char* cipher;
411 const char* mac;
412 bool is_aead;
413 SSLCipherSuiteToStrings(&key_exchange, &cipher, &mac, &is_aead, cipher_suite);
414 EXPECT_STREQ("ECDHE_RSA", key_exchange);
415#if defined(USE_OPENSSL)
416 bool supports_aead = true;
417#else
davidben299e3072015-05-04 19:06:49418 bool supports_aead =
419 PK11_TokenExists(CKM_AES_GCM) &&
420 PK11_TokenExists(CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256);
davidben9dd84872015-05-02 00:22:58421#endif
422 EXPECT_TRUE(!supports_aead || is_aead);
[email protected]f61c3972010-12-23 09:54:15423}
424
425TEST_F(SSLServerSocketTest, DataTransfer) {
426 Initialize();
427
[email protected]83039bb2011-12-09 18:43:55428 TestCompletionCallback connect_callback;
[email protected]6ea7b152011-12-21 21:21:13429 TestCompletionCallback handshake_callback;
[email protected]f61c3972010-12-23 09:54:15430
431 // Establish connection.
[email protected]83039bb2011-12-09 18:43:55432 int client_ret = client_socket_->Connect(connect_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04433 ASSERT_TRUE(client_ret == OK || client_ret == ERR_IO_PENDING);
[email protected]f61c3972010-12-23 09:54:15434
[email protected]6ea7b152011-12-21 21:21:13435 int server_ret = server_socket_->Handshake(handshake_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04436 ASSERT_TRUE(server_ret == OK || server_ret == ERR_IO_PENDING);
[email protected]f61c3972010-12-23 09:54:15437
[email protected]febbbb52011-08-17 04:59:23438 client_ret = connect_callback.GetResult(client_ret);
[email protected]fa6ce922014-07-17 04:27:04439 ASSERT_EQ(OK, client_ret);
[email protected]febbbb52011-08-17 04:59:23440 server_ret = handshake_callback.GetResult(server_ret);
[email protected]fa6ce922014-07-17 04:27:04441 ASSERT_EQ(OK, server_ret);
[email protected]f61c3972010-12-23 09:54:15442
443 const int kReadBufSize = 1024;
[email protected]fa6ce922014-07-17 04:27:04444 scoped_refptr<StringIOBuffer> write_buf =
445 new StringIOBuffer("testing123");
446 scoped_refptr<DrainableIOBuffer> read_buf =
447 new DrainableIOBuffer(new IOBuffer(kReadBufSize), kReadBufSize);
[email protected]f61c3972010-12-23 09:54:15448
449 // Write then read.
[email protected]83039bb2011-12-09 18:43:55450 TestCompletionCallback write_callback;
451 TestCompletionCallback read_callback;
[email protected]90499482013-06-01 00:39:50452 server_ret = server_socket_->Write(
453 write_buf.get(), write_buf->size(), write_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04454 EXPECT_TRUE(server_ret > 0 || server_ret == ERR_IO_PENDING);
[email protected]90499482013-06-01 00:39:50455 client_ret = client_socket_->Read(
456 read_buf.get(), read_buf->BytesRemaining(), read_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04457 EXPECT_TRUE(client_ret > 0 || client_ret == ERR_IO_PENDING);
[email protected]f61c3972010-12-23 09:54:15458
[email protected]febbbb52011-08-17 04:59:23459 server_ret = write_callback.GetResult(server_ret);
460 EXPECT_GT(server_ret, 0);
461 client_ret = read_callback.GetResult(client_ret);
462 ASSERT_GT(client_ret, 0);
463
464 read_buf->DidConsume(client_ret);
465 while (read_buf->BytesConsumed() < write_buf->size()) {
[email protected]90499482013-06-01 00:39:50466 client_ret = client_socket_->Read(
467 read_buf.get(), read_buf->BytesRemaining(), read_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04468 EXPECT_TRUE(client_ret > 0 || client_ret == ERR_IO_PENDING);
[email protected]febbbb52011-08-17 04:59:23469 client_ret = read_callback.GetResult(client_ret);
470 ASSERT_GT(client_ret, 0);
471 read_buf->DidConsume(client_ret);
[email protected]f61c3972010-12-23 09:54:15472 }
[email protected]febbbb52011-08-17 04:59:23473 EXPECT_EQ(write_buf->size(), read_buf->BytesConsumed());
474 read_buf->SetOffset(0);
[email protected]f61c3972010-12-23 09:54:15475 EXPECT_EQ(0, memcmp(write_buf->data(), read_buf->data(), write_buf->size()));
476
477 // Read then write.
[email protected]fa6ce922014-07-17 04:27:04478 write_buf = new StringIOBuffer("hello123");
[email protected]90499482013-06-01 00:39:50479 server_ret = server_socket_->Read(
480 read_buf.get(), read_buf->BytesRemaining(), read_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04481 EXPECT_TRUE(server_ret > 0 || server_ret == ERR_IO_PENDING);
[email protected]90499482013-06-01 00:39:50482 client_ret = client_socket_->Write(
483 write_buf.get(), write_buf->size(), write_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04484 EXPECT_TRUE(client_ret > 0 || client_ret == ERR_IO_PENDING);
[email protected]f61c3972010-12-23 09:54:15485
[email protected]febbbb52011-08-17 04:59:23486 server_ret = read_callback.GetResult(server_ret);
487 ASSERT_GT(server_ret, 0);
488 client_ret = write_callback.GetResult(client_ret);
489 EXPECT_GT(client_ret, 0);
490
491 read_buf->DidConsume(server_ret);
492 while (read_buf->BytesConsumed() < write_buf->size()) {
[email protected]90499482013-06-01 00:39:50493 server_ret = server_socket_->Read(
494 read_buf.get(), read_buf->BytesRemaining(), read_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04495 EXPECT_TRUE(server_ret > 0 || server_ret == ERR_IO_PENDING);
[email protected]febbbb52011-08-17 04:59:23496 server_ret = read_callback.GetResult(server_ret);
497 ASSERT_GT(server_ret, 0);
498 read_buf->DidConsume(server_ret);
[email protected]f61c3972010-12-23 09:54:15499 }
[email protected]febbbb52011-08-17 04:59:23500 EXPECT_EQ(write_buf->size(), read_buf->BytesConsumed());
501 read_buf->SetOffset(0);
[email protected]f61c3972010-12-23 09:54:15502 EXPECT_EQ(0, memcmp(write_buf->data(), read_buf->data(), write_buf->size()));
503}
[email protected]b0ff3f82011-07-23 05:12:39504
[email protected]c0e4dd12012-05-16 19:36:31505// A regression test for bug 127822 (http://crbug.com/127822).
506// If the server closes the connection after the handshake is finished,
507// the client's Write() call should not cause an infinite loop.
508// NOTE: this is a test for SSLClientSocket rather than SSLServerSocket.
[email protected]4da82282014-07-16 18:40:43509TEST_F(SSLServerSocketTest, ClientWriteAfterServerClose) {
[email protected]c0e4dd12012-05-16 19:36:31510 Initialize();
511
512 TestCompletionCallback connect_callback;
513 TestCompletionCallback handshake_callback;
514
515 // Establish connection.
516 int client_ret = client_socket_->Connect(connect_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04517 ASSERT_TRUE(client_ret == OK || client_ret == ERR_IO_PENDING);
[email protected]c0e4dd12012-05-16 19:36:31518
519 int server_ret = server_socket_->Handshake(handshake_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04520 ASSERT_TRUE(server_ret == OK || server_ret == ERR_IO_PENDING);
[email protected]c0e4dd12012-05-16 19:36:31521
522 client_ret = connect_callback.GetResult(client_ret);
[email protected]fa6ce922014-07-17 04:27:04523 ASSERT_EQ(OK, client_ret);
[email protected]c0e4dd12012-05-16 19:36:31524 server_ret = handshake_callback.GetResult(server_ret);
[email protected]fa6ce922014-07-17 04:27:04525 ASSERT_EQ(OK, server_ret);
[email protected]c0e4dd12012-05-16 19:36:31526
[email protected]fa6ce922014-07-17 04:27:04527 scoped_refptr<StringIOBuffer> write_buf = new StringIOBuffer("testing123");
[email protected]c0e4dd12012-05-16 19:36:31528
529 // The server closes the connection. The server needs to write some
530 // data first so that the client's Read() calls from the transport
531 // socket won't return ERR_IO_PENDING. This ensures that the client
532 // will call Read() on the transport socket again.
533 TestCompletionCallback write_callback;
534
[email protected]90499482013-06-01 00:39:50535 server_ret = server_socket_->Write(
536 write_buf.get(), write_buf->size(), write_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04537 EXPECT_TRUE(server_ret > 0 || server_ret == ERR_IO_PENDING);
[email protected]c0e4dd12012-05-16 19:36:31538
539 server_ret = write_callback.GetResult(server_ret);
540 EXPECT_GT(server_ret, 0);
541
542 server_socket_->Disconnect();
543
544 // The client writes some data. This should not cause an infinite loop.
[email protected]90499482013-06-01 00:39:50545 client_ret = client_socket_->Write(
546 write_buf.get(), write_buf->size(), write_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04547 EXPECT_TRUE(client_ret > 0 || client_ret == ERR_IO_PENDING);
[email protected]c0e4dd12012-05-16 19:36:31548
549 client_ret = write_callback.GetResult(client_ret);
550 EXPECT_GT(client_ret, 0);
551
skyostil4891b25b2015-06-11 11:43:45552 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
[email protected]2da659e2013-05-23 20:51:34553 FROM_HERE, base::MessageLoop::QuitClosure(),
[email protected]c0e4dd12012-05-16 19:36:31554 base::TimeDelta::FromMilliseconds(10));
[email protected]2da659e2013-05-23 20:51:34555 base::MessageLoop::current()->Run();
[email protected]c0e4dd12012-05-16 19:36:31556}
557
[email protected]b0ff3f82011-07-23 05:12:39558// This test executes ExportKeyingMaterial() on the client and server sockets,
559// after connecting them, and verifies that the results match.
560// This test will fail if False Start is enabled (see crbug.com/90208).
561TEST_F(SSLServerSocketTest, ExportKeyingMaterial) {
562 Initialize();
563
[email protected]83039bb2011-12-09 18:43:55564 TestCompletionCallback connect_callback;
[email protected]6ea7b152011-12-21 21:21:13565 TestCompletionCallback handshake_callback;
[email protected]b0ff3f82011-07-23 05:12:39566
[email protected]83039bb2011-12-09 18:43:55567 int client_ret = client_socket_->Connect(connect_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04568 ASSERT_TRUE(client_ret == OK || client_ret == ERR_IO_PENDING);
[email protected]b0ff3f82011-07-23 05:12:39569
[email protected]6ea7b152011-12-21 21:21:13570 int server_ret = server_socket_->Handshake(handshake_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04571 ASSERT_TRUE(server_ret == OK || server_ret == ERR_IO_PENDING);
[email protected]b0ff3f82011-07-23 05:12:39572
[email protected]fa6ce922014-07-17 04:27:04573 if (client_ret == ERR_IO_PENDING) {
574 ASSERT_EQ(OK, connect_callback.WaitForResult());
[email protected]b0ff3f82011-07-23 05:12:39575 }
[email protected]fa6ce922014-07-17 04:27:04576 if (server_ret == ERR_IO_PENDING) {
577 ASSERT_EQ(OK, handshake_callback.WaitForResult());
[email protected]b0ff3f82011-07-23 05:12:39578 }
579
580 const int kKeyingMaterialSize = 32;
thestig9d3bb0c2015-01-24 00:49:51581 const char kKeyingLabel[] = "EXPERIMENTAL-server-socket-test";
582 const char kKeyingContext[] = "";
[email protected]b0ff3f82011-07-23 05:12:39583 unsigned char server_out[kKeyingMaterialSize];
[email protected]1bc6f5e2012-03-15 00:20:58584 int rv = server_socket_->ExportKeyingMaterial(kKeyingLabel,
585 false, kKeyingContext,
[email protected]b0ff3f82011-07-23 05:12:39586 server_out, sizeof(server_out));
[email protected]fa6ce922014-07-17 04:27:04587 ASSERT_EQ(OK, rv);
[email protected]b0ff3f82011-07-23 05:12:39588
589 unsigned char client_out[kKeyingMaterialSize];
[email protected]1bc6f5e2012-03-15 00:20:58590 rv = client_socket_->ExportKeyingMaterial(kKeyingLabel,
591 false, kKeyingContext,
[email protected]b0ff3f82011-07-23 05:12:39592 client_out, sizeof(client_out));
[email protected]fa6ce922014-07-17 04:27:04593 ASSERT_EQ(OK, rv);
[email protected]47a12862012-04-10 01:00:49594 EXPECT_EQ(0, memcmp(server_out, client_out, sizeof(server_out)));
[email protected]b0ff3f82011-07-23 05:12:39595
thestig9d3bb0c2015-01-24 00:49:51596 const char kKeyingLabelBad[] = "EXPERIMENTAL-server-socket-test-bad";
[email protected]b0ff3f82011-07-23 05:12:39597 unsigned char client_bad[kKeyingMaterialSize];
[email protected]1bc6f5e2012-03-15 00:20:58598 rv = client_socket_->ExportKeyingMaterial(kKeyingLabelBad,
599 false, kKeyingContext,
[email protected]b0ff3f82011-07-23 05:12:39600 client_bad, sizeof(client_bad));
[email protected]fa6ce922014-07-17 04:27:04601 ASSERT_EQ(rv, OK);
[email protected]47a12862012-04-10 01:00:49602 EXPECT_NE(0, memcmp(server_out, client_bad, sizeof(server_out)));
[email protected]b0ff3f82011-07-23 05:12:39603}
[email protected]f61c3972010-12-23 09:54:15604
sergeyuff826d5e2015-05-13 20:35:22605// Verifies that SSLConfig::require_ecdhe flags works properly.
606TEST_F(SSLServerSocketTest, RequireEcdheFlag) {
607 // Disable all ECDHE suites on the client side.
608 uint16_t kEcdheCiphers[] = {
609 0xc007, // ECDHE_ECDSA_WITH_RC4_128_SHA
610 0xc009, // ECDHE_ECDSA_WITH_AES_128_CBC_SHA
611 0xc00a, // ECDHE_ECDSA_WITH_AES_256_CBC_SHA
612 0xc011, // ECDHE_RSA_WITH_RC4_128_SHA
613 0xc013, // ECDHE_RSA_WITH_AES_128_CBC_SHA
614 0xc014, // ECDHE_RSA_WITH_AES_256_CBC_SHA
615 0xc02b, // ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
616 0xc02f, // ECDHE_RSA_WITH_AES_128_GCM_SHA256
617 0xcc13, // ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
618 0xcc14, // ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
619 };
620 client_ssl_config_.disabled_cipher_suites.assign(
621 kEcdheCiphers, kEcdheCiphers + arraysize(kEcdheCiphers));
622
623 // Require ECDHE on the server.
624 server_ssl_config_.require_ecdhe = true;
625
626 Initialize();
627
628 TestCompletionCallback connect_callback;
629 TestCompletionCallback handshake_callback;
630
631 int client_ret = client_socket_->Connect(connect_callback.callback());
632 int server_ret = server_socket_->Handshake(handshake_callback.callback());
633
634 client_ret = connect_callback.GetResult(client_ret);
635 server_ret = handshake_callback.GetResult(server_ret);
636
637 ASSERT_EQ(ERR_SSL_VERSION_OR_CIPHER_MISMATCH, client_ret);
638 ASSERT_EQ(ERR_SSL_VERSION_OR_CIPHER_MISMATCH, server_ret);
639}
640
[email protected]f61c3972010-12-23 09:54:15641} // namespace net