blob: 1419f5c67b980603cbe538445f0f742994b04dfd [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
tbansalf82cc8e2015-10-14 20:05:4918#include <stdint.h>
[email protected]55ee0e52011-07-21 18:29:4419#include <stdlib.h>
[email protected]f61c3972010-12-23 09:54:1520#include <queue>
dchengc7eeda422015-12-26 03:56:4821#include <utility>
[email protected]f61c3972010-12-23 09:54:1522
[email protected]55ee0e52011-07-21 18:29:4423#include "base/compiler_specific.h"
[email protected]57999812013-02-24 05:40:5224#include "base/files/file_path.h"
thestigd8df0332014-09-04 06:33:2925#include "base/files/file_util.h"
skyostil4891b25b2015-06-11 11:43:4526#include "base/location.h"
tbansalf82cc8e2015-10-14 20:05:4927#include "base/logging.h"
Avi Drissman13fc8932015-12-20 04:40:4628#include "base/macros.h"
[email protected]18b577412013-07-18 04:19:1529#include "base/message_loop/message_loop.h"
skyostil4891b25b2015-06-11 11:43:4530#include "base/single_thread_task_runner.h"
31#include "base/thread_task_runner_handle.h"
[email protected]4b559b4d2011-04-14 17:37:1432#include "crypto/nss_util.h"
33#include "crypto/rsa_private_key.h"
[email protected]f61c3972010-12-23 09:54:1534#include "net/base/address_list.h"
[email protected]6ea7b152011-12-21 21:21:1335#include "net/base/completion_callback.h"
[email protected]f61c3972010-12-23 09:54:1536#include "net/base/host_port_pair.h"
37#include "net/base/io_buffer.h"
[email protected]e7f74da2011-04-19 23:49:3538#include "net/base/ip_endpoint.h"
[email protected]f61c3972010-12-23 09:54:1539#include "net/base/net_errors.h"
[email protected]42fdb452012-11-01 12:44:4040#include "net/base/test_data_directory.h"
[email protected]6e7845ae2013-03-29 21:48:1141#include "net/cert/cert_status_flags.h"
42#include "net/cert/mock_cert_verifier.h"
43#include "net/cert/x509_certificate.h"
[email protected]b1c988b2013-06-13 06:48:1144#include "net/http/transport_security_state.h"
eroman87c53d62015-04-02 06:51:0745#include "net/log/net_log.h"
[email protected]f61c3972010-12-23 09:54:1546#include "net/socket/client_socket_factory.h"
47#include "net/socket/socket_test_util.h"
48#include "net/socket/ssl_client_socket.h"
[email protected]3268023f2011-05-05 00:08:1049#include "net/socket/stream_socket.h"
davidben9dd84872015-05-02 00:22:5850#include "net/ssl/ssl_cipher_suite_names.h"
davidben9dd84872015-05-02 00:22:5851#include "net/ssl/ssl_connection_status_flags.h"
[email protected]536fd0b2013-03-14 17:41:5752#include "net/ssl/ssl_info.h"
svaldez6e7e82a22015-10-28 19:39:5353#include "net/ssl/ssl_server_config.h"
[email protected]6e7845ae2013-03-29 21:48:1154#include "net/test/cert_test_util.h"
[email protected]f61c3972010-12-23 09:54:1555#include "testing/gtest/include/gtest/gtest.h"
56#include "testing/platform_test.h"
57
58namespace net {
59
60namespace {
61
62class FakeDataChannel {
63 public:
[email protected]55ee0e52011-07-21 18:29:4464 FakeDataChannel()
[email protected]83039bb2011-12-09 18:43:5565 : read_buf_len_(0),
[email protected]c0e4dd12012-05-16 19:36:3166 closed_(false),
[email protected]d5492c52013-11-10 20:44:3967 write_called_after_close_(false),
68 weak_factory_(this) {
[email protected]f61c3972010-12-23 09:54:1569 }
70
[email protected]47a12862012-04-10 01:00:4971 int Read(IOBuffer* buf, int buf_len, const CompletionCallback& callback) {
[email protected]4da82282014-07-16 18:40:4372 DCHECK(read_callback_.is_null());
dcheng08ea2af02014-08-25 23:38:0973 DCHECK(!read_buf_.get());
[email protected]c0e4dd12012-05-16 19:36:3174 if (closed_)
75 return 0;
[email protected]3f55aa12011-12-07 02:03:3376 if (data_.empty()) {
[email protected]f61c3972010-12-23 09:54:1577 read_callback_ = callback;
78 read_buf_ = buf;
79 read_buf_len_ = buf_len;
[email protected]fa6ce922014-07-17 04:27:0480 return ERR_IO_PENDING;
[email protected]f61c3972010-12-23 09:54:1581 }
tfarina9b6381442015-10-05 22:38:1182 return PropagateData(buf, buf_len);
[email protected]f61c3972010-12-23 09:54:1583 }
84
[email protected]47a12862012-04-10 01:00:4985 int Write(IOBuffer* buf, int buf_len, const CompletionCallback& callback) {
[email protected]4da82282014-07-16 18:40:4386 DCHECK(write_callback_.is_null());
[email protected]c0e4dd12012-05-16 19:36:3187 if (closed_) {
88 if (write_called_after_close_)
[email protected]fa6ce922014-07-17 04:27:0489 return ERR_CONNECTION_RESET;
[email protected]c0e4dd12012-05-16 19:36:3190 write_called_after_close_ = true;
91 write_callback_ = callback;
skyostil4891b25b2015-06-11 11:43:4592 base::ThreadTaskRunnerHandle::Get()->PostTask(
[email protected]c0e4dd12012-05-16 19:36:3193 FROM_HERE, base::Bind(&FakeDataChannel::DoWriteCallback,
94 weak_factory_.GetWeakPtr()));
[email protected]fa6ce922014-07-17 04:27:0495 return ERR_IO_PENDING;
[email protected]c0e4dd12012-05-16 19:36:3196 }
[email protected]4da82282014-07-16 18:40:4397 // This function returns synchronously, so make a copy of the buffer.
[email protected]fa6ce922014-07-17 04:27:0498 data_.push(new DrainableIOBuffer(
99 new StringIOBuffer(std::string(buf->data(), buf_len)),
[email protected]4da82282014-07-16 18:40:43100 buf_len));
skyostil4891b25b2015-06-11 11:43:45101 base::ThreadTaskRunnerHandle::Get()->PostTask(
[email protected]83039bb2011-12-09 18:43:55102 FROM_HERE, base::Bind(&FakeDataChannel::DoReadCallback,
103 weak_factory_.GetWeakPtr()));
[email protected]f61c3972010-12-23 09:54:15104 return buf_len;
105 }
106
[email protected]c0e4dd12012-05-16 19:36:31107 // Closes the FakeDataChannel. After Close() is called, Read() returns 0,
108 // indicating EOF, and Write() fails with ERR_CONNECTION_RESET. Note that
109 // after the FakeDataChannel is closed, the first Write() call completes
110 // asynchronously, which is necessary to reproduce bug 127822.
111 void Close() {
112 closed_ = true;
113 }
114
[email protected]f61c3972010-12-23 09:54:15115 private:
116 void DoReadCallback() {
[email protected]83039bb2011-12-09 18:43:55117 if (read_callback_.is_null() || data_.empty())
[email protected]f61c3972010-12-23 09:54:15118 return;
119
tfarina9b6381442015-10-05 22:38:11120 int copied = PropagateData(read_buf_, read_buf_len_);
[email protected]83039bb2011-12-09 18:43:55121 CompletionCallback callback = read_callback_;
122 read_callback_.Reset();
123 read_buf_ = NULL;
124 read_buf_len_ = 0;
125 callback.Run(copied);
[email protected]f61c3972010-12-23 09:54:15126 }
127
[email protected]c0e4dd12012-05-16 19:36:31128 void DoWriteCallback() {
129 if (write_callback_.is_null())
130 return;
131
132 CompletionCallback callback = write_callback_;
133 write_callback_.Reset();
[email protected]fa6ce922014-07-17 04:27:04134 callback.Run(ERR_CONNECTION_RESET);
[email protected]c0e4dd12012-05-16 19:36:31135 }
136
tfarina9b6381442015-10-05 22:38:11137 int PropagateData(scoped_refptr<IOBuffer> read_buf, int read_buf_len) {
[email protected]fa6ce922014-07-17 04:27:04138 scoped_refptr<DrainableIOBuffer> buf = data_.front();
[email protected]f61c3972010-12-23 09:54:15139 int copied = std::min(buf->BytesRemaining(), read_buf_len);
140 memcpy(read_buf->data(), buf->data(), copied);
141 buf->DidConsume(copied);
142
143 if (!buf->BytesRemaining())
144 data_.pop();
145 return copied;
146 }
147
[email protected]83039bb2011-12-09 18:43:55148 CompletionCallback read_callback_;
[email protected]fa6ce922014-07-17 04:27:04149 scoped_refptr<IOBuffer> read_buf_;
[email protected]f61c3972010-12-23 09:54:15150 int read_buf_len_;
151
[email protected]c0e4dd12012-05-16 19:36:31152 CompletionCallback write_callback_;
153
[email protected]fa6ce922014-07-17 04:27:04154 std::queue<scoped_refptr<DrainableIOBuffer> > data_;
[email protected]f61c3972010-12-23 09:54:15155
[email protected]c0e4dd12012-05-16 19:36:31156 // True if Close() has been called.
157 bool closed_;
158
159 // Controls the completion of Write() after the FakeDataChannel is closed.
160 // After the FakeDataChannel is closed, the first Write() call completes
161 // asynchronously.
162 bool write_called_after_close_;
163
[email protected]d5492c52013-11-10 20:44:39164 base::WeakPtrFactory<FakeDataChannel> weak_factory_;
165
[email protected]f61c3972010-12-23 09:54:15166 DISALLOW_COPY_AND_ASSIGN(FakeDataChannel);
167};
168
[email protected]3268023f2011-05-05 00:08:10169class FakeSocket : public StreamSocket {
[email protected]f61c3972010-12-23 09:54:15170 public:
171 FakeSocket(FakeDataChannel* incoming_channel,
172 FakeDataChannel* outgoing_channel)
173 : incoming_(incoming_channel),
174 outgoing_(outgoing_channel) {
175 }
176
dchengb03027d2014-10-21 12:00:20177 ~FakeSocket() override {}
[email protected]f61c3972010-12-23 09:54:15178
dchengb03027d2014-10-21 12:00:20179 int Read(IOBuffer* buf,
180 int buf_len,
181 const CompletionCallback& callback) override {
[email protected]3f55aa12011-12-07 02:03:33182 // Read random number of bytes.
183 buf_len = rand() % buf_len + 1;
184 return incoming_->Read(buf, buf_len, callback);
185 }
[email protected]f61c3972010-12-23 09:54:15186
dchengb03027d2014-10-21 12:00:20187 int Write(IOBuffer* buf,
188 int buf_len,
189 const CompletionCallback& callback) override {
[email protected]55ee0e52011-07-21 18:29:44190 // Write random number of bytes.
191 buf_len = rand() % buf_len + 1;
[email protected]f61c3972010-12-23 09:54:15192 return outgoing_->Write(buf, buf_len, callback);
193 }
194
Avi Drissman13fc8932015-12-20 04:40:46195 int SetReceiveBufferSize(int32_t size) override { return OK; }
[email protected]f61c3972010-12-23 09:54:15196
Avi Drissman13fc8932015-12-20 04:40:46197 int SetSendBufferSize(int32_t size) override { return OK; }
[email protected]f61c3972010-12-23 09:54:15198
dchengb03027d2014-10-21 12:00:20199 int Connect(const CompletionCallback& callback) override { return OK; }
[email protected]f61c3972010-12-23 09:54:15200
dchengb03027d2014-10-21 12:00:20201 void Disconnect() override {
[email protected]c0e4dd12012-05-16 19:36:31202 incoming_->Close();
203 outgoing_->Close();
204 }
[email protected]f61c3972010-12-23 09:54:15205
dchengb03027d2014-10-21 12:00:20206 bool IsConnected() const override { return true; }
[email protected]f61c3972010-12-23 09:54:15207
dchengb03027d2014-10-21 12:00:20208 bool IsConnectedAndIdle() const override { return true; }
[email protected]f61c3972010-12-23 09:54:15209
dchengb03027d2014-10-21 12:00:20210 int GetPeerAddress(IPEndPoint* address) const override {
[email protected]fa6ce922014-07-17 04:27:04211 IPAddressNumber ip_address(kIPv4AddressSize);
212 *address = IPEndPoint(ip_address, 0 /*port*/);
213 return OK;
[email protected]f61c3972010-12-23 09:54:15214 }
215
dchengb03027d2014-10-21 12:00:20216 int GetLocalAddress(IPEndPoint* address) const override {
[email protected]fa6ce922014-07-17 04:27:04217 IPAddressNumber ip_address(4);
218 *address = IPEndPoint(ip_address, 0);
219 return OK;
[email protected]e7f74da2011-04-19 23:49:35220 }
221
dchengb03027d2014-10-21 12:00:20222 const BoundNetLog& NetLog() const override { return net_log_; }
[email protected]f61c3972010-12-23 09:54:15223
dchengb03027d2014-10-21 12:00:20224 void SetSubresourceSpeculation() override {}
225 void SetOmniboxSpeculation() override {}
[email protected]f61c3972010-12-23 09:54:15226
dchengb03027d2014-10-21 12:00:20227 bool WasEverUsed() const override { return true; }
[email protected]f61c3972010-12-23 09:54:15228
dchengb03027d2014-10-21 12:00:20229 bool UsingTCPFastOpen() const override { return false; }
[email protected]f61c3972010-12-23 09:54:15230
dchengb03027d2014-10-21 12:00:20231 bool WasNpnNegotiated() const override { return false; }
[email protected]5e6efa52011-06-27 17:26:41232
dchengb03027d2014-10-21 12:00:20233 NextProto GetNegotiatedProtocol() const override { return kProtoUnknown; }
[email protected]2d88e7d2012-07-19 17:55:17234
dchengb03027d2014-10-21 12:00:20235 bool GetSSLInfo(SSLInfo* ssl_info) override { return false; }
[email protected]2d88e7d2012-07-19 17:55:17236
ttuttle23fdb7b2015-05-15 01:28:03237 void GetConnectionAttempts(ConnectionAttempts* out) const override {
238 out->clear();
239 }
240
241 void ClearConnectionAttempts() override {}
242
243 void AddConnectionAttempts(const ConnectionAttempts& attempts) override {}
244
tbansalf82cc8e2015-10-14 20:05:49245 int64_t GetTotalReceivedBytes() const override {
246 NOTIMPLEMENTED();
247 return 0;
248 }
249
[email protected]f61c3972010-12-23 09:54:15250 private:
[email protected]fa6ce922014-07-17 04:27:04251 BoundNetLog net_log_;
[email protected]f61c3972010-12-23 09:54:15252 FakeDataChannel* incoming_;
253 FakeDataChannel* outgoing_;
254
255 DISALLOW_COPY_AND_ASSIGN(FakeSocket);
256};
257
258} // namespace
259
260// Verify the correctness of the test helper classes first.
261TEST(FakeSocketTest, DataTransfer) {
262 // Establish channels between two sockets.
263 FakeDataChannel channel_1;
264 FakeDataChannel channel_2;
265 FakeSocket client(&channel_1, &channel_2);
266 FakeSocket server(&channel_2, &channel_1);
267
268 const char kTestData[] = "testing123";
269 const int kTestDataSize = strlen(kTestData);
270 const int kReadBufSize = 1024;
[email protected]fa6ce922014-07-17 04:27:04271 scoped_refptr<IOBuffer> write_buf = new StringIOBuffer(kTestData);
272 scoped_refptr<IOBuffer> read_buf = new IOBuffer(kReadBufSize);
[email protected]f61c3972010-12-23 09:54:15273
274 // Write then read.
[email protected]90499482013-06-01 00:39:50275 int written =
276 server.Write(write_buf.get(), kTestDataSize, CompletionCallback());
[email protected]55ee0e52011-07-21 18:29:44277 EXPECT_GT(written, 0);
278 EXPECT_LE(written, kTestDataSize);
279
[email protected]90499482013-06-01 00:39:50280 int read = client.Read(read_buf.get(), kReadBufSize, CompletionCallback());
[email protected]55ee0e52011-07-21 18:29:44281 EXPECT_GT(read, 0);
282 EXPECT_LE(read, written);
283 EXPECT_EQ(0, memcmp(kTestData, read_buf->data(), read));
[email protected]f61c3972010-12-23 09:54:15284
285 // Read then write.
[email protected]83039bb2011-12-09 18:43:55286 TestCompletionCallback callback;
[email protected]fa6ce922014-07-17 04:27:04287 EXPECT_EQ(ERR_IO_PENDING,
[email protected]90499482013-06-01 00:39:50288 server.Read(read_buf.get(), kReadBufSize, callback.callback()));
[email protected]55ee0e52011-07-21 18:29:44289
[email protected]90499482013-06-01 00:39:50290 written = client.Write(write_buf.get(), kTestDataSize, CompletionCallback());
[email protected]55ee0e52011-07-21 18:29:44291 EXPECT_GT(written, 0);
292 EXPECT_LE(written, kTestDataSize);
293
294 read = callback.WaitForResult();
295 EXPECT_GT(read, 0);
296 EXPECT_LE(read, written);
297 EXPECT_EQ(0, memcmp(kTestData, read_buf->data(), read));
[email protected]f61c3972010-12-23 09:54:15298}
299
300class SSLServerSocketTest : public PlatformTest {
301 public:
302 SSLServerSocketTest()
[email protected]fa6ce922014-07-17 04:27:04303 : socket_factory_(ClientSocketFactory::GetDefaultFactory()),
[email protected]b1c988b2013-06-13 06:48:11304 cert_verifier_(new MockCertVerifier()),
305 transport_security_state_(new TransportSecurityState) {
[email protected]fa6ce922014-07-17 04:27:04306 cert_verifier_->set_default_result(CERT_STATUS_AUTHORITY_INVALID);
[email protected]f61c3972010-12-23 09:54:15307 }
308
309 protected:
310 void Initialize() {
[email protected]18ccfdb2013-08-15 00:13:44311 scoped_ptr<ClientSocketHandle> client_connection(new ClientSocketHandle);
312 client_connection->SetSocket(
313 scoped_ptr<StreamSocket>(new FakeSocket(&channel_1_, &channel_2_)));
314 scoped_ptr<StreamSocket> server_socket(
315 new FakeSocket(&channel_2_, &channel_1_));
[email protected]f61c3972010-12-23 09:54:15316
[email protected]6cdfd7f2013-02-08 20:40:15317 base::FilePath certs_dir(GetTestCertsDirectory());
[email protected]f61c3972010-12-23 09:54:15318
[email protected]6cdfd7f2013-02-08 20:40:15319 base::FilePath cert_path = certs_dir.AppendASCII("unittest.selfsigned.der");
[email protected]f61c3972010-12-23 09:54:15320 std::string cert_der;
[email protected]82f84b92013-08-30 18:23:50321 ASSERT_TRUE(base::ReadFileToString(cert_path, &cert_der));
[email protected]f61c3972010-12-23 09:54:15322
[email protected]fa6ce922014-07-17 04:27:04323 scoped_refptr<X509Certificate> cert =
[email protected]f61c3972010-12-23 09:54:15324 X509Certificate::CreateFromBytes(cert_der.data(), cert_der.size());
325
[email protected]6cdfd7f2013-02-08 20:40:15326 base::FilePath key_path = certs_dir.AppendASCII("unittest.key.bin");
[email protected]f61c3972010-12-23 09:54:15327 std::string key_string;
[email protected]82f84b92013-08-30 18:23:50328 ASSERT_TRUE(base::ReadFileToString(key_path, &key_string));
Avi Drissman13fc8932015-12-20 04:40:46329 std::vector<uint8_t> key_vector(
330 reinterpret_cast<const uint8_t*>(key_string.data()),
331 reinterpret_cast<const uint8_t*>(key_string.data() +
332 key_string.length()));
[email protected]f61c3972010-12-23 09:54:15333
[email protected]4b559b4d2011-04-14 17:37:14334 scoped_ptr<crypto::RSAPrivateKey> private_key(
335 crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(key_vector));
[email protected]f61c3972010-12-23 09:54:15336
sergeyuff826d5e2015-05-13 20:35:22337 client_ssl_config_.false_start_enabled = false;
338 client_ssl_config_.channel_id_enabled = false;
[email protected]f61c3972010-12-23 09:54:15339
340 // Certificate provided by the host doesn't need authority.
[email protected]fa6ce922014-07-17 04:27:04341 SSLConfig::CertAndStatus cert_and_status;
[email protected]4dc832e2011-04-28 22:04:24342 cert_and_status.cert_status = CERT_STATUS_AUTHORITY_INVALID;
[email protected]3d5c1bd2011-07-20 02:14:01343 cert_and_status.der_cert = cert_der;
sergeyuff826d5e2015-05-13 20:35:22344 client_ssl_config_.allowed_bad_certs.push_back(cert_and_status);
[email protected]f61c3972010-12-23 09:54:15345
[email protected]fa6ce922014-07-17 04:27:04346 HostPortPair host_and_pair("unittest", 0);
347 SSLClientSocketContext context;
[email protected]9f59fac2012-03-21 23:18:11348 context.cert_verifier = cert_verifier_.get();
[email protected]b1c988b2013-06-13 06:48:11349 context.transport_security_state = transport_security_state_.get();
sergeyuff826d5e2015-05-13 20:35:22350 client_socket_ = socket_factory_->CreateSSLClientSocket(
dchengc7eeda422015-12-26 03:56:48351 std::move(client_connection), host_and_pair, client_ssl_config_,
352 context);
sergeyuff826d5e2015-05-13 20:35:22353 server_socket_ =
dchengc7eeda422015-12-26 03:56:48354 CreateSSLServerSocket(std::move(server_socket), cert.get(),
sergeyuff826d5e2015-05-13 20:35:22355 private_key.get(), server_ssl_config_);
[email protected]f61c3972010-12-23 09:54:15356 }
357
358 FakeDataChannel channel_1_;
359 FakeDataChannel channel_2_;
sergeyuff826d5e2015-05-13 20:35:22360 SSLConfig client_ssl_config_;
svaldez6e7e82a22015-10-28 19:39:53361 SSLServerConfig server_ssl_config_;
[email protected]fa6ce922014-07-17 04:27:04362 scoped_ptr<SSLClientSocket> client_socket_;
363 scoped_ptr<SSLServerSocket> server_socket_;
364 ClientSocketFactory* socket_factory_;
365 scoped_ptr<MockCertVerifier> cert_verifier_;
366 scoped_ptr<TransportSecurityState> transport_security_state_;
[email protected]f61c3972010-12-23 09:54:15367};
368
[email protected]f61c3972010-12-23 09:54:15369// This test only executes creation of client and server sockets. This is to
370// test that creation of sockets doesn't crash and have minimal code to run
371// under valgrind in order to help debugging memory problems.
372TEST_F(SSLServerSocketTest, Initialize) {
373 Initialize();
374}
375
[email protected]a7ac3c32011-06-17 19:10:15376// This test executes Connect() on SSLClientSocket and Handshake() on
377// SSLServerSocket to make sure handshaking between the two sockets is
[email protected]f61c3972010-12-23 09:54:15378// completed successfully.
379TEST_F(SSLServerSocketTest, Handshake) {
380 Initialize();
381
[email protected]83039bb2011-12-09 18:43:55382 TestCompletionCallback connect_callback;
[email protected]6ea7b152011-12-21 21:21:13383 TestCompletionCallback handshake_callback;
[email protected]f61c3972010-12-23 09:54:15384
[email protected]6ea7b152011-12-21 21:21:13385 int server_ret = server_socket_->Handshake(handshake_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04386 EXPECT_TRUE(server_ret == OK || server_ret == ERR_IO_PENDING);
[email protected]f61c3972010-12-23 09:54:15387
[email protected]83039bb2011-12-09 18:43:55388 int client_ret = client_socket_->Connect(connect_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04389 EXPECT_TRUE(client_ret == OK || client_ret == ERR_IO_PENDING);
[email protected]f61c3972010-12-23 09:54:15390
[email protected]fa6ce922014-07-17 04:27:04391 if (client_ret == ERR_IO_PENDING) {
392 EXPECT_EQ(OK, connect_callback.WaitForResult());
[email protected]f61c3972010-12-23 09:54:15393 }
[email protected]fa6ce922014-07-17 04:27:04394 if (server_ret == ERR_IO_PENDING) {
395 EXPECT_EQ(OK, handshake_callback.WaitForResult());
[email protected]f61c3972010-12-23 09:54:15396 }
[email protected]4dc832e2011-04-28 22:04:24397
398 // Make sure the cert status is expected.
399 SSLInfo ssl_info;
davidben9dd84872015-05-02 00:22:58400 ASSERT_TRUE(client_socket_->GetSSLInfo(&ssl_info));
[email protected]4dc832e2011-04-28 22:04:24401 EXPECT_EQ(CERT_STATUS_AUTHORITY_INVALID, ssl_info.cert_status);
davidben9dd84872015-05-02 00:22:58402
403 // The default cipher suite should be ECDHE and, unless on NSS and the
404 // platform doesn't support it, an AEAD.
405 uint16_t cipher_suite =
406 SSLConnectionStatusToCipherSuite(ssl_info.connection_status);
407 const char* key_exchange;
408 const char* cipher;
409 const char* mac;
410 bool is_aead;
411 SSLCipherSuiteToStrings(&key_exchange, &cipher, &mac, &is_aead, cipher_suite);
412 EXPECT_STREQ("ECDHE_RSA", key_exchange);
davidben6cacd572015-09-29 22:24:10413 EXPECT_TRUE(is_aead);
[email protected]f61c3972010-12-23 09:54:15414}
415
416TEST_F(SSLServerSocketTest, DataTransfer) {
417 Initialize();
418
[email protected]83039bb2011-12-09 18:43:55419 TestCompletionCallback connect_callback;
[email protected]6ea7b152011-12-21 21:21:13420 TestCompletionCallback handshake_callback;
[email protected]f61c3972010-12-23 09:54:15421
422 // Establish connection.
[email protected]83039bb2011-12-09 18:43:55423 int client_ret = client_socket_->Connect(connect_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04424 ASSERT_TRUE(client_ret == OK || client_ret == ERR_IO_PENDING);
[email protected]f61c3972010-12-23 09:54:15425
[email protected]6ea7b152011-12-21 21:21:13426 int server_ret = server_socket_->Handshake(handshake_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04427 ASSERT_TRUE(server_ret == OK || server_ret == ERR_IO_PENDING);
[email protected]f61c3972010-12-23 09:54:15428
[email protected]febbbb52011-08-17 04:59:23429 client_ret = connect_callback.GetResult(client_ret);
[email protected]fa6ce922014-07-17 04:27:04430 ASSERT_EQ(OK, client_ret);
[email protected]febbbb52011-08-17 04:59:23431 server_ret = handshake_callback.GetResult(server_ret);
[email protected]fa6ce922014-07-17 04:27:04432 ASSERT_EQ(OK, server_ret);
[email protected]f61c3972010-12-23 09:54:15433
434 const int kReadBufSize = 1024;
[email protected]fa6ce922014-07-17 04:27:04435 scoped_refptr<StringIOBuffer> write_buf =
436 new StringIOBuffer("testing123");
437 scoped_refptr<DrainableIOBuffer> read_buf =
438 new DrainableIOBuffer(new IOBuffer(kReadBufSize), kReadBufSize);
[email protected]f61c3972010-12-23 09:54:15439
440 // Write then read.
[email protected]83039bb2011-12-09 18:43:55441 TestCompletionCallback write_callback;
442 TestCompletionCallback read_callback;
[email protected]90499482013-06-01 00:39:50443 server_ret = server_socket_->Write(
444 write_buf.get(), write_buf->size(), write_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04445 EXPECT_TRUE(server_ret > 0 || server_ret == ERR_IO_PENDING);
[email protected]90499482013-06-01 00:39:50446 client_ret = client_socket_->Read(
447 read_buf.get(), read_buf->BytesRemaining(), read_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04448 EXPECT_TRUE(client_ret > 0 || client_ret == ERR_IO_PENDING);
[email protected]f61c3972010-12-23 09:54:15449
[email protected]febbbb52011-08-17 04:59:23450 server_ret = write_callback.GetResult(server_ret);
451 EXPECT_GT(server_ret, 0);
452 client_ret = read_callback.GetResult(client_ret);
453 ASSERT_GT(client_ret, 0);
454
455 read_buf->DidConsume(client_ret);
456 while (read_buf->BytesConsumed() < write_buf->size()) {
[email protected]90499482013-06-01 00:39:50457 client_ret = client_socket_->Read(
458 read_buf.get(), read_buf->BytesRemaining(), read_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04459 EXPECT_TRUE(client_ret > 0 || client_ret == ERR_IO_PENDING);
[email protected]febbbb52011-08-17 04:59:23460 client_ret = read_callback.GetResult(client_ret);
461 ASSERT_GT(client_ret, 0);
462 read_buf->DidConsume(client_ret);
[email protected]f61c3972010-12-23 09:54:15463 }
[email protected]febbbb52011-08-17 04:59:23464 EXPECT_EQ(write_buf->size(), read_buf->BytesConsumed());
465 read_buf->SetOffset(0);
[email protected]f61c3972010-12-23 09:54:15466 EXPECT_EQ(0, memcmp(write_buf->data(), read_buf->data(), write_buf->size()));
467
468 // Read then write.
[email protected]fa6ce922014-07-17 04:27:04469 write_buf = new StringIOBuffer("hello123");
[email protected]90499482013-06-01 00:39:50470 server_ret = server_socket_->Read(
471 read_buf.get(), read_buf->BytesRemaining(), read_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04472 EXPECT_TRUE(server_ret > 0 || server_ret == ERR_IO_PENDING);
[email protected]90499482013-06-01 00:39:50473 client_ret = client_socket_->Write(
474 write_buf.get(), write_buf->size(), write_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04475 EXPECT_TRUE(client_ret > 0 || client_ret == ERR_IO_PENDING);
[email protected]f61c3972010-12-23 09:54:15476
[email protected]febbbb52011-08-17 04:59:23477 server_ret = read_callback.GetResult(server_ret);
478 ASSERT_GT(server_ret, 0);
479 client_ret = write_callback.GetResult(client_ret);
480 EXPECT_GT(client_ret, 0);
481
482 read_buf->DidConsume(server_ret);
483 while (read_buf->BytesConsumed() < write_buf->size()) {
[email protected]90499482013-06-01 00:39:50484 server_ret = server_socket_->Read(
485 read_buf.get(), read_buf->BytesRemaining(), read_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04486 EXPECT_TRUE(server_ret > 0 || server_ret == ERR_IO_PENDING);
[email protected]febbbb52011-08-17 04:59:23487 server_ret = read_callback.GetResult(server_ret);
488 ASSERT_GT(server_ret, 0);
489 read_buf->DidConsume(server_ret);
[email protected]f61c3972010-12-23 09:54:15490 }
[email protected]febbbb52011-08-17 04:59:23491 EXPECT_EQ(write_buf->size(), read_buf->BytesConsumed());
492 read_buf->SetOffset(0);
[email protected]f61c3972010-12-23 09:54:15493 EXPECT_EQ(0, memcmp(write_buf->data(), read_buf->data(), write_buf->size()));
494}
[email protected]b0ff3f82011-07-23 05:12:39495
[email protected]c0e4dd12012-05-16 19:36:31496// A regression test for bug 127822 (http://crbug.com/127822).
497// If the server closes the connection after the handshake is finished,
498// the client's Write() call should not cause an infinite loop.
499// NOTE: this is a test for SSLClientSocket rather than SSLServerSocket.
[email protected]4da82282014-07-16 18:40:43500TEST_F(SSLServerSocketTest, ClientWriteAfterServerClose) {
[email protected]c0e4dd12012-05-16 19:36:31501 Initialize();
502
503 TestCompletionCallback connect_callback;
504 TestCompletionCallback handshake_callback;
505
506 // Establish connection.
507 int client_ret = client_socket_->Connect(connect_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04508 ASSERT_TRUE(client_ret == OK || client_ret == ERR_IO_PENDING);
[email protected]c0e4dd12012-05-16 19:36:31509
510 int server_ret = server_socket_->Handshake(handshake_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04511 ASSERT_TRUE(server_ret == OK || server_ret == ERR_IO_PENDING);
[email protected]c0e4dd12012-05-16 19:36:31512
513 client_ret = connect_callback.GetResult(client_ret);
[email protected]fa6ce922014-07-17 04:27:04514 ASSERT_EQ(OK, client_ret);
[email protected]c0e4dd12012-05-16 19:36:31515 server_ret = handshake_callback.GetResult(server_ret);
[email protected]fa6ce922014-07-17 04:27:04516 ASSERT_EQ(OK, server_ret);
[email protected]c0e4dd12012-05-16 19:36:31517
[email protected]fa6ce922014-07-17 04:27:04518 scoped_refptr<StringIOBuffer> write_buf = new StringIOBuffer("testing123");
[email protected]c0e4dd12012-05-16 19:36:31519
520 // The server closes the connection. The server needs to write some
521 // data first so that the client's Read() calls from the transport
522 // socket won't return ERR_IO_PENDING. This ensures that the client
523 // will call Read() on the transport socket again.
524 TestCompletionCallback write_callback;
525
[email protected]90499482013-06-01 00:39:50526 server_ret = server_socket_->Write(
527 write_buf.get(), write_buf->size(), write_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04528 EXPECT_TRUE(server_ret > 0 || server_ret == ERR_IO_PENDING);
[email protected]c0e4dd12012-05-16 19:36:31529
530 server_ret = write_callback.GetResult(server_ret);
531 EXPECT_GT(server_ret, 0);
532
533 server_socket_->Disconnect();
534
535 // The client writes some data. This should not cause an infinite loop.
[email protected]90499482013-06-01 00:39:50536 client_ret = client_socket_->Write(
537 write_buf.get(), write_buf->size(), write_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04538 EXPECT_TRUE(client_ret > 0 || client_ret == ERR_IO_PENDING);
[email protected]c0e4dd12012-05-16 19:36:31539
540 client_ret = write_callback.GetResult(client_ret);
541 EXPECT_GT(client_ret, 0);
542
skyostil4891b25b2015-06-11 11:43:45543 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
ki.stfu375812e2015-10-09 20:23:17544 FROM_HERE, base::MessageLoop::QuitWhenIdleClosure(),
[email protected]c0e4dd12012-05-16 19:36:31545 base::TimeDelta::FromMilliseconds(10));
[email protected]2da659e2013-05-23 20:51:34546 base::MessageLoop::current()->Run();
[email protected]c0e4dd12012-05-16 19:36:31547}
548
[email protected]b0ff3f82011-07-23 05:12:39549// This test executes ExportKeyingMaterial() on the client and server sockets,
550// after connecting them, and verifies that the results match.
551// This test will fail if False Start is enabled (see crbug.com/90208).
552TEST_F(SSLServerSocketTest, ExportKeyingMaterial) {
553 Initialize();
554
[email protected]83039bb2011-12-09 18:43:55555 TestCompletionCallback connect_callback;
[email protected]6ea7b152011-12-21 21:21:13556 TestCompletionCallback handshake_callback;
[email protected]b0ff3f82011-07-23 05:12:39557
[email protected]83039bb2011-12-09 18:43:55558 int client_ret = client_socket_->Connect(connect_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04559 ASSERT_TRUE(client_ret == OK || client_ret == ERR_IO_PENDING);
[email protected]b0ff3f82011-07-23 05:12:39560
[email protected]6ea7b152011-12-21 21:21:13561 int server_ret = server_socket_->Handshake(handshake_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04562 ASSERT_TRUE(server_ret == OK || server_ret == ERR_IO_PENDING);
[email protected]b0ff3f82011-07-23 05:12:39563
[email protected]fa6ce922014-07-17 04:27:04564 if (client_ret == ERR_IO_PENDING) {
565 ASSERT_EQ(OK, connect_callback.WaitForResult());
[email protected]b0ff3f82011-07-23 05:12:39566 }
[email protected]fa6ce922014-07-17 04:27:04567 if (server_ret == ERR_IO_PENDING) {
568 ASSERT_EQ(OK, handshake_callback.WaitForResult());
[email protected]b0ff3f82011-07-23 05:12:39569 }
570
571 const int kKeyingMaterialSize = 32;
thestig9d3bb0c2015-01-24 00:49:51572 const char kKeyingLabel[] = "EXPERIMENTAL-server-socket-test";
573 const char kKeyingContext[] = "";
[email protected]b0ff3f82011-07-23 05:12:39574 unsigned char server_out[kKeyingMaterialSize];
[email protected]1bc6f5e2012-03-15 00:20:58575 int rv = server_socket_->ExportKeyingMaterial(kKeyingLabel,
576 false, kKeyingContext,
[email protected]b0ff3f82011-07-23 05:12:39577 server_out, sizeof(server_out));
[email protected]fa6ce922014-07-17 04:27:04578 ASSERT_EQ(OK, rv);
[email protected]b0ff3f82011-07-23 05:12:39579
580 unsigned char client_out[kKeyingMaterialSize];
[email protected]1bc6f5e2012-03-15 00:20:58581 rv = client_socket_->ExportKeyingMaterial(kKeyingLabel,
582 false, kKeyingContext,
[email protected]b0ff3f82011-07-23 05:12:39583 client_out, sizeof(client_out));
[email protected]fa6ce922014-07-17 04:27:04584 ASSERT_EQ(OK, rv);
[email protected]47a12862012-04-10 01:00:49585 EXPECT_EQ(0, memcmp(server_out, client_out, sizeof(server_out)));
[email protected]b0ff3f82011-07-23 05:12:39586
thestig9d3bb0c2015-01-24 00:49:51587 const char kKeyingLabelBad[] = "EXPERIMENTAL-server-socket-test-bad";
[email protected]b0ff3f82011-07-23 05:12:39588 unsigned char client_bad[kKeyingMaterialSize];
[email protected]1bc6f5e2012-03-15 00:20:58589 rv = client_socket_->ExportKeyingMaterial(kKeyingLabelBad,
590 false, kKeyingContext,
[email protected]b0ff3f82011-07-23 05:12:39591 client_bad, sizeof(client_bad));
[email protected]fa6ce922014-07-17 04:27:04592 ASSERT_EQ(rv, OK);
[email protected]47a12862012-04-10 01:00:49593 EXPECT_NE(0, memcmp(server_out, client_bad, sizeof(server_out)));
[email protected]b0ff3f82011-07-23 05:12:39594}
[email protected]f61c3972010-12-23 09:54:15595
sergeyuff826d5e2015-05-13 20:35:22596// Verifies that SSLConfig::require_ecdhe flags works properly.
597TEST_F(SSLServerSocketTest, RequireEcdheFlag) {
598 // Disable all ECDHE suites on the client side.
599 uint16_t kEcdheCiphers[] = {
600 0xc007, // ECDHE_ECDSA_WITH_RC4_128_SHA
601 0xc009, // ECDHE_ECDSA_WITH_AES_128_CBC_SHA
602 0xc00a, // ECDHE_ECDSA_WITH_AES_256_CBC_SHA
603 0xc011, // ECDHE_RSA_WITH_RC4_128_SHA
604 0xc013, // ECDHE_RSA_WITH_AES_128_CBC_SHA
605 0xc014, // ECDHE_RSA_WITH_AES_256_CBC_SHA
606 0xc02b, // ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
607 0xc02f, // ECDHE_RSA_WITH_AES_128_GCM_SHA256
608 0xcc13, // ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
609 0xcc14, // ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
610 };
611 client_ssl_config_.disabled_cipher_suites.assign(
612 kEcdheCiphers, kEcdheCiphers + arraysize(kEcdheCiphers));
613
614 // Require ECDHE on the server.
615 server_ssl_config_.require_ecdhe = true;
616
617 Initialize();
618
619 TestCompletionCallback connect_callback;
620 TestCompletionCallback handshake_callback;
621
622 int client_ret = client_socket_->Connect(connect_callback.callback());
623 int server_ret = server_socket_->Handshake(handshake_callback.callback());
624
625 client_ret = connect_callback.GetResult(client_ret);
626 server_ret = handshake_callback.GetResult(server_ret);
627
628 ASSERT_EQ(ERR_SSL_VERSION_OR_CIPHER_MISMATCH, client_ret);
629 ASSERT_EQ(ERR_SSL_VERSION_OR_CIPHER_MISMATCH, server_ret);
630}
631
[email protected]f61c3972010-12-23 09:54:15632} // namespace net