blob: 03ff36102c90c50da61fdd9be2c6a348a41095a9 [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>
20
[email protected]f61c3972010-12-23 09:54:1521#include <queue>
22
[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"
[email protected]18b577412013-07-18 04:19:1528#include "base/message_loop/message_loop.h"
skyostil4891b25b2015-06-11 11:43:4529#include "base/single_thread_task_runner.h"
30#include "base/thread_task_runner_handle.h"
[email protected]4b559b4d2011-04-14 17:37:1431#include "crypto/nss_util.h"
32#include "crypto/rsa_private_key.h"
[email protected]f61c3972010-12-23 09:54:1533#include "net/base/address_list.h"
[email protected]6ea7b152011-12-21 21:21:1334#include "net/base/completion_callback.h"
[email protected]f61c3972010-12-23 09:54:1535#include "net/base/host_port_pair.h"
36#include "net/base/io_buffer.h"
[email protected]e7f74da2011-04-19 23:49:3537#include "net/base/ip_endpoint.h"
[email protected]f61c3972010-12-23 09:54:1538#include "net/base/net_errors.h"
[email protected]42fdb452012-11-01 12:44:4039#include "net/base/test_data_directory.h"
[email protected]6e7845ae2013-03-29 21:48:1140#include "net/cert/cert_status_flags.h"
41#include "net/cert/mock_cert_verifier.h"
42#include "net/cert/x509_certificate.h"
[email protected]b1c988b2013-06-13 06:48:1143#include "net/http/transport_security_state.h"
eroman87c53d62015-04-02 06:51:0744#include "net/log/net_log.h"
[email protected]f61c3972010-12-23 09:54:1545#include "net/socket/client_socket_factory.h"
46#include "net/socket/socket_test_util.h"
47#include "net/socket/ssl_client_socket.h"
[email protected]3268023f2011-05-05 00:08:1048#include "net/socket/stream_socket.h"
davidben9dd84872015-05-02 00:22:5849#include "net/ssl/ssl_cipher_suite_names.h"
[email protected]536fd0b2013-03-14 17:41:5750#include "net/ssl/ssl_config_service.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"
[email protected]6e7845ae2013-03-29 21:48:1153#include "net/test/cert_test_util.h"
[email protected]f61c3972010-12-23 09:54:1554#include "testing/gtest/include/gtest/gtest.h"
55#include "testing/platform_test.h"
56
[email protected]f61c3972010-12-23 09:54:1557namespace net {
58
59namespace {
60
61class FakeDataChannel {
62 public:
[email protected]55ee0e52011-07-21 18:29:4463 FakeDataChannel()
[email protected]83039bb2011-12-09 18:43:5564 : read_buf_len_(0),
[email protected]c0e4dd12012-05-16 19:36:3165 closed_(false),
[email protected]d5492c52013-11-10 20:44:3966 write_called_after_close_(false),
67 weak_factory_(this) {
[email protected]f61c3972010-12-23 09:54:1568 }
69
[email protected]47a12862012-04-10 01:00:4970 int Read(IOBuffer* buf, int buf_len, const CompletionCallback& callback) {
[email protected]4da82282014-07-16 18:40:4371 DCHECK(read_callback_.is_null());
dcheng08ea2af02014-08-25 23:38:0972 DCHECK(!read_buf_.get());
[email protected]c0e4dd12012-05-16 19:36:3173 if (closed_)
74 return 0;
[email protected]3f55aa12011-12-07 02:03:3375 if (data_.empty()) {
[email protected]f61c3972010-12-23 09:54:1576 read_callback_ = callback;
77 read_buf_ = buf;
78 read_buf_len_ = buf_len;
[email protected]fa6ce922014-07-17 04:27:0479 return ERR_IO_PENDING;
[email protected]f61c3972010-12-23 09:54:1580 }
tfarina9b6381442015-10-05 22:38:1181 return PropagateData(buf, buf_len);
[email protected]f61c3972010-12-23 09:54:1582 }
83
[email protected]47a12862012-04-10 01:00:4984 int Write(IOBuffer* buf, int buf_len, const CompletionCallback& callback) {
[email protected]4da82282014-07-16 18:40:4385 DCHECK(write_callback_.is_null());
[email protected]c0e4dd12012-05-16 19:36:3186 if (closed_) {
87 if (write_called_after_close_)
[email protected]fa6ce922014-07-17 04:27:0488 return ERR_CONNECTION_RESET;
[email protected]c0e4dd12012-05-16 19:36:3189 write_called_after_close_ = true;
90 write_callback_ = callback;
skyostil4891b25b2015-06-11 11:43:4591 base::ThreadTaskRunnerHandle::Get()->PostTask(
[email protected]c0e4dd12012-05-16 19:36:3192 FROM_HERE, base::Bind(&FakeDataChannel::DoWriteCallback,
93 weak_factory_.GetWeakPtr()));
[email protected]fa6ce922014-07-17 04:27:0494 return ERR_IO_PENDING;
[email protected]c0e4dd12012-05-16 19:36:3195 }
[email protected]4da82282014-07-16 18:40:4396 // This function returns synchronously, so make a copy of the buffer.
[email protected]fa6ce922014-07-17 04:27:0497 data_.push(new DrainableIOBuffer(
98 new StringIOBuffer(std::string(buf->data(), buf_len)),
[email protected]4da82282014-07-16 18:40:4399 buf_len));
skyostil4891b25b2015-06-11 11:43:45100 base::ThreadTaskRunnerHandle::Get()->PostTask(
[email protected]83039bb2011-12-09 18:43:55101 FROM_HERE, base::Bind(&FakeDataChannel::DoReadCallback,
102 weak_factory_.GetWeakPtr()));
[email protected]f61c3972010-12-23 09:54:15103 return buf_len;
104 }
105
[email protected]c0e4dd12012-05-16 19:36:31106 // Closes the FakeDataChannel. After Close() is called, Read() returns 0,
107 // indicating EOF, and Write() fails with ERR_CONNECTION_RESET. Note that
108 // after the FakeDataChannel is closed, the first Write() call completes
109 // asynchronously, which is necessary to reproduce bug 127822.
110 void Close() {
111 closed_ = true;
112 }
113
[email protected]f61c3972010-12-23 09:54:15114 private:
115 void DoReadCallback() {
[email protected]83039bb2011-12-09 18:43:55116 if (read_callback_.is_null() || data_.empty())
[email protected]f61c3972010-12-23 09:54:15117 return;
118
tfarina9b6381442015-10-05 22:38:11119 int copied = PropagateData(read_buf_, read_buf_len_);
[email protected]83039bb2011-12-09 18:43:55120 CompletionCallback callback = read_callback_;
121 read_callback_.Reset();
122 read_buf_ = NULL;
123 read_buf_len_ = 0;
124 callback.Run(copied);
[email protected]f61c3972010-12-23 09:54:15125 }
126
[email protected]c0e4dd12012-05-16 19:36:31127 void DoWriteCallback() {
128 if (write_callback_.is_null())
129 return;
130
131 CompletionCallback callback = write_callback_;
132 write_callback_.Reset();
[email protected]fa6ce922014-07-17 04:27:04133 callback.Run(ERR_CONNECTION_RESET);
[email protected]c0e4dd12012-05-16 19:36:31134 }
135
tfarina9b6381442015-10-05 22:38:11136 int PropagateData(scoped_refptr<IOBuffer> read_buf, int read_buf_len) {
[email protected]fa6ce922014-07-17 04:27:04137 scoped_refptr<DrainableIOBuffer> buf = data_.front();
[email protected]f61c3972010-12-23 09:54:15138 int copied = std::min(buf->BytesRemaining(), read_buf_len);
139 memcpy(read_buf->data(), buf->data(), copied);
140 buf->DidConsume(copied);
141
142 if (!buf->BytesRemaining())
143 data_.pop();
144 return copied;
145 }
146
[email protected]83039bb2011-12-09 18:43:55147 CompletionCallback read_callback_;
[email protected]fa6ce922014-07-17 04:27:04148 scoped_refptr<IOBuffer> read_buf_;
[email protected]f61c3972010-12-23 09:54:15149 int read_buf_len_;
150
[email protected]c0e4dd12012-05-16 19:36:31151 CompletionCallback write_callback_;
152
[email protected]fa6ce922014-07-17 04:27:04153 std::queue<scoped_refptr<DrainableIOBuffer> > data_;
[email protected]f61c3972010-12-23 09:54:15154
[email protected]c0e4dd12012-05-16 19:36:31155 // True if Close() has been called.
156 bool closed_;
157
158 // Controls the completion of Write() after the FakeDataChannel is closed.
159 // After the FakeDataChannel is closed, the first Write() call completes
160 // asynchronously.
161 bool write_called_after_close_;
162
[email protected]d5492c52013-11-10 20:44:39163 base::WeakPtrFactory<FakeDataChannel> weak_factory_;
164
[email protected]f61c3972010-12-23 09:54:15165 DISALLOW_COPY_AND_ASSIGN(FakeDataChannel);
166};
167
[email protected]3268023f2011-05-05 00:08:10168class FakeSocket : public StreamSocket {
[email protected]f61c3972010-12-23 09:54:15169 public:
170 FakeSocket(FakeDataChannel* incoming_channel,
171 FakeDataChannel* outgoing_channel)
172 : incoming_(incoming_channel),
173 outgoing_(outgoing_channel) {
174 }
175
dchengb03027d2014-10-21 12:00:20176 ~FakeSocket() override {}
[email protected]f61c3972010-12-23 09:54:15177
dchengb03027d2014-10-21 12:00:20178 int Read(IOBuffer* buf,
179 int buf_len,
180 const CompletionCallback& callback) override {
[email protected]3f55aa12011-12-07 02:03:33181 // Read random number of bytes.
182 buf_len = rand() % buf_len + 1;
183 return incoming_->Read(buf, buf_len, callback);
184 }
[email protected]f61c3972010-12-23 09:54:15185
dchengb03027d2014-10-21 12:00:20186 int Write(IOBuffer* buf,
187 int buf_len,
188 const CompletionCallback& callback) override {
[email protected]55ee0e52011-07-21 18:29:44189 // Write random number of bytes.
190 buf_len = rand() % buf_len + 1;
[email protected]f61c3972010-12-23 09:54:15191 return outgoing_->Write(buf, buf_len, callback);
192 }
193
dchengb03027d2014-10-21 12:00:20194 int SetReceiveBufferSize(int32 size) override { return OK; }
[email protected]f61c3972010-12-23 09:54:15195
dchengb03027d2014-10-21 12:00:20196 int SetSendBufferSize(int32 size) override { return OK; }
[email protected]f61c3972010-12-23 09:54:15197
dchengb03027d2014-10-21 12:00:20198 int Connect(const CompletionCallback& callback) override { return OK; }
[email protected]f61c3972010-12-23 09:54:15199
dchengb03027d2014-10-21 12:00:20200 void Disconnect() override {
[email protected]c0e4dd12012-05-16 19:36:31201 incoming_->Close();
202 outgoing_->Close();
203 }
[email protected]f61c3972010-12-23 09:54:15204
dchengb03027d2014-10-21 12:00:20205 bool IsConnected() const override { return true; }
[email protected]f61c3972010-12-23 09:54:15206
dchengb03027d2014-10-21 12:00:20207 bool IsConnectedAndIdle() const override { return true; }
[email protected]f61c3972010-12-23 09:54:15208
dchengb03027d2014-10-21 12:00:20209 int GetPeerAddress(IPEndPoint* address) const override {
[email protected]fa6ce922014-07-17 04:27:04210 IPAddressNumber ip_address(kIPv4AddressSize);
211 *address = IPEndPoint(ip_address, 0 /*port*/);
212 return OK;
[email protected]f61c3972010-12-23 09:54:15213 }
214
dchengb03027d2014-10-21 12:00:20215 int GetLocalAddress(IPEndPoint* address) const override {
[email protected]fa6ce922014-07-17 04:27:04216 IPAddressNumber ip_address(4);
217 *address = IPEndPoint(ip_address, 0);
218 return OK;
[email protected]e7f74da2011-04-19 23:49:35219 }
220
dchengb03027d2014-10-21 12:00:20221 const BoundNetLog& NetLog() const override { return net_log_; }
[email protected]f61c3972010-12-23 09:54:15222
dchengb03027d2014-10-21 12:00:20223 void SetSubresourceSpeculation() override {}
224 void SetOmniboxSpeculation() override {}
[email protected]f61c3972010-12-23 09:54:15225
dchengb03027d2014-10-21 12:00:20226 bool WasEverUsed() const override { return true; }
[email protected]f61c3972010-12-23 09:54:15227
dchengb03027d2014-10-21 12:00:20228 bool UsingTCPFastOpen() const override { return false; }
[email protected]f61c3972010-12-23 09:54:15229
dchengb03027d2014-10-21 12:00:20230 bool WasNpnNegotiated() const override { return false; }
[email protected]5e6efa52011-06-27 17:26:41231
dchengb03027d2014-10-21 12:00:20232 NextProto GetNegotiatedProtocol() const override { return kProtoUnknown; }
[email protected]2d88e7d2012-07-19 17:55:17233
dchengb03027d2014-10-21 12:00:20234 bool GetSSLInfo(SSLInfo* ssl_info) override { return false; }
[email protected]2d88e7d2012-07-19 17:55:17235
ttuttle23fdb7b2015-05-15 01:28:03236 void GetConnectionAttempts(ConnectionAttempts* out) const override {
237 out->clear();
238 }
239
240 void ClearConnectionAttempts() override {}
241
242 void AddConnectionAttempts(const ConnectionAttempts& attempts) override {}
243
tbansalf82cc8e2015-10-14 20:05:49244 int64_t GetTotalReceivedBytes() const override {
245 NOTIMPLEMENTED();
246 return 0;
247 }
248
[email protected]f61c3972010-12-23 09:54:15249 private:
[email protected]fa6ce922014-07-17 04:27:04250 BoundNetLog net_log_;
[email protected]f61c3972010-12-23 09:54:15251 FakeDataChannel* incoming_;
252 FakeDataChannel* outgoing_;
253
254 DISALLOW_COPY_AND_ASSIGN(FakeSocket);
255};
256
257} // namespace
258
259// Verify the correctness of the test helper classes first.
260TEST(FakeSocketTest, DataTransfer) {
261 // Establish channels between two sockets.
262 FakeDataChannel channel_1;
263 FakeDataChannel channel_2;
264 FakeSocket client(&channel_1, &channel_2);
265 FakeSocket server(&channel_2, &channel_1);
266
267 const char kTestData[] = "testing123";
268 const int kTestDataSize = strlen(kTestData);
269 const int kReadBufSize = 1024;
[email protected]fa6ce922014-07-17 04:27:04270 scoped_refptr<IOBuffer> write_buf = new StringIOBuffer(kTestData);
271 scoped_refptr<IOBuffer> read_buf = new IOBuffer(kReadBufSize);
[email protected]f61c3972010-12-23 09:54:15272
273 // Write then read.
[email protected]90499482013-06-01 00:39:50274 int written =
275 server.Write(write_buf.get(), kTestDataSize, CompletionCallback());
[email protected]55ee0e52011-07-21 18:29:44276 EXPECT_GT(written, 0);
277 EXPECT_LE(written, kTestDataSize);
278
[email protected]90499482013-06-01 00:39:50279 int read = client.Read(read_buf.get(), kReadBufSize, CompletionCallback());
[email protected]55ee0e52011-07-21 18:29:44280 EXPECT_GT(read, 0);
281 EXPECT_LE(read, written);
282 EXPECT_EQ(0, memcmp(kTestData, read_buf->data(), read));
[email protected]f61c3972010-12-23 09:54:15283
284 // Read then write.
[email protected]83039bb2011-12-09 18:43:55285 TestCompletionCallback callback;
[email protected]fa6ce922014-07-17 04:27:04286 EXPECT_EQ(ERR_IO_PENDING,
[email protected]90499482013-06-01 00:39:50287 server.Read(read_buf.get(), kReadBufSize, callback.callback()));
[email protected]55ee0e52011-07-21 18:29:44288
[email protected]90499482013-06-01 00:39:50289 written = client.Write(write_buf.get(), kTestDataSize, CompletionCallback());
[email protected]55ee0e52011-07-21 18:29:44290 EXPECT_GT(written, 0);
291 EXPECT_LE(written, kTestDataSize);
292
293 read = callback.WaitForResult();
294 EXPECT_GT(read, 0);
295 EXPECT_LE(read, written);
296 EXPECT_EQ(0, memcmp(kTestData, read_buf->data(), read));
[email protected]f61c3972010-12-23 09:54:15297}
298
299class SSLServerSocketTest : public PlatformTest {
300 public:
301 SSLServerSocketTest()
[email protected]fa6ce922014-07-17 04:27:04302 : socket_factory_(ClientSocketFactory::GetDefaultFactory()),
[email protected]b1c988b2013-06-13 06:48:11303 cert_verifier_(new MockCertVerifier()),
304 transport_security_state_(new TransportSecurityState) {
[email protected]fa6ce922014-07-17 04:27:04305 cert_verifier_->set_default_result(CERT_STATUS_AUTHORITY_INVALID);
[email protected]f61c3972010-12-23 09:54:15306 }
307
308 protected:
309 void Initialize() {
[email protected]18ccfdb2013-08-15 00:13:44310 scoped_ptr<ClientSocketHandle> client_connection(new ClientSocketHandle);
311 client_connection->SetSocket(
312 scoped_ptr<StreamSocket>(new FakeSocket(&channel_1_, &channel_2_)));
313 scoped_ptr<StreamSocket> server_socket(
314 new FakeSocket(&channel_2_, &channel_1_));
[email protected]f61c3972010-12-23 09:54:15315
[email protected]6cdfd7f2013-02-08 20:40:15316 base::FilePath certs_dir(GetTestCertsDirectory());
[email protected]f61c3972010-12-23 09:54:15317
[email protected]6cdfd7f2013-02-08 20:40:15318 base::FilePath cert_path = certs_dir.AppendASCII("unittest.selfsigned.der");
[email protected]f61c3972010-12-23 09:54:15319 std::string cert_der;
[email protected]82f84b92013-08-30 18:23:50320 ASSERT_TRUE(base::ReadFileToString(cert_path, &cert_der));
[email protected]f61c3972010-12-23 09:54:15321
[email protected]fa6ce922014-07-17 04:27:04322 scoped_refptr<X509Certificate> cert =
[email protected]f61c3972010-12-23 09:54:15323 X509Certificate::CreateFromBytes(cert_der.data(), cert_der.size());
324
[email protected]6cdfd7f2013-02-08 20:40:15325 base::FilePath key_path = certs_dir.AppendASCII("unittest.key.bin");
[email protected]f61c3972010-12-23 09:54:15326 std::string key_string;
[email protected]82f84b92013-08-30 18:23:50327 ASSERT_TRUE(base::ReadFileToString(key_path, &key_string));
[email protected]f61c3972010-12-23 09:54:15328 std::vector<uint8> key_vector(
329 reinterpret_cast<const uint8*>(key_string.data()),
330 reinterpret_cast<const uint8*>(key_string.data() +
331 key_string.length()));
332
[email protected]4b559b4d2011-04-14 17:37:14333 scoped_ptr<crypto::RSAPrivateKey> private_key(
334 crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(key_vector));
[email protected]f61c3972010-12-23 09:54:15335
sergeyuff826d5e2015-05-13 20:35:22336 client_ssl_config_.false_start_enabled = false;
337 client_ssl_config_.channel_id_enabled = false;
[email protected]f61c3972010-12-23 09:54:15338
339 // Certificate provided by the host doesn't need authority.
[email protected]fa6ce922014-07-17 04:27:04340 SSLConfig::CertAndStatus cert_and_status;
[email protected]4dc832e2011-04-28 22:04:24341 cert_and_status.cert_status = CERT_STATUS_AUTHORITY_INVALID;
[email protected]3d5c1bd2011-07-20 02:14:01342 cert_and_status.der_cert = cert_der;
sergeyuff826d5e2015-05-13 20:35:22343 client_ssl_config_.allowed_bad_certs.push_back(cert_and_status);
[email protected]f61c3972010-12-23 09:54:15344
[email protected]fa6ce922014-07-17 04:27:04345 HostPortPair host_and_pair("unittest", 0);
346 SSLClientSocketContext context;
[email protected]9f59fac2012-03-21 23:18:11347 context.cert_verifier = cert_verifier_.get();
[email protected]b1c988b2013-06-13 06:48:11348 context.transport_security_state = transport_security_state_.get();
sergeyuff826d5e2015-05-13 20:35:22349 client_socket_ = socket_factory_->CreateSSLClientSocket(
350 client_connection.Pass(), host_and_pair, client_ssl_config_, context);
351 server_socket_ =
352 CreateSSLServerSocket(server_socket.Pass(), cert.get(),
353 private_key.get(), server_ssl_config_);
[email protected]f61c3972010-12-23 09:54:15354 }
355
356 FakeDataChannel channel_1_;
357 FakeDataChannel channel_2_;
sergeyuff826d5e2015-05-13 20:35:22358 SSLConfig client_ssl_config_;
359 SSLConfig server_ssl_config_;
[email protected]fa6ce922014-07-17 04:27:04360 scoped_ptr<SSLClientSocket> client_socket_;
361 scoped_ptr<SSLServerSocket> server_socket_;
362 ClientSocketFactory* socket_factory_;
363 scoped_ptr<MockCertVerifier> cert_verifier_;
364 scoped_ptr<TransportSecurityState> transport_security_state_;
[email protected]f61c3972010-12-23 09:54:15365};
366
[email protected]f61c3972010-12-23 09:54:15367// This test only executes creation of client and server sockets. This is to
368// test that creation of sockets doesn't crash and have minimal code to run
369// under valgrind in order to help debugging memory problems.
370TEST_F(SSLServerSocketTest, Initialize) {
371 Initialize();
372}
373
[email protected]a7ac3c32011-06-17 19:10:15374// This test executes Connect() on SSLClientSocket and Handshake() on
375// SSLServerSocket to make sure handshaking between the two sockets is
[email protected]f61c3972010-12-23 09:54:15376// completed successfully.
377TEST_F(SSLServerSocketTest, Handshake) {
378 Initialize();
379
[email protected]83039bb2011-12-09 18:43:55380 TestCompletionCallback connect_callback;
[email protected]6ea7b152011-12-21 21:21:13381 TestCompletionCallback handshake_callback;
[email protected]f61c3972010-12-23 09:54:15382
[email protected]6ea7b152011-12-21 21:21:13383 int server_ret = server_socket_->Handshake(handshake_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04384 EXPECT_TRUE(server_ret == OK || server_ret == ERR_IO_PENDING);
[email protected]f61c3972010-12-23 09:54:15385
[email protected]83039bb2011-12-09 18:43:55386 int client_ret = client_socket_->Connect(connect_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04387 EXPECT_TRUE(client_ret == OK || client_ret == ERR_IO_PENDING);
[email protected]f61c3972010-12-23 09:54:15388
[email protected]fa6ce922014-07-17 04:27:04389 if (client_ret == ERR_IO_PENDING) {
390 EXPECT_EQ(OK, connect_callback.WaitForResult());
[email protected]f61c3972010-12-23 09:54:15391 }
[email protected]fa6ce922014-07-17 04:27:04392 if (server_ret == ERR_IO_PENDING) {
393 EXPECT_EQ(OK, handshake_callback.WaitForResult());
[email protected]f61c3972010-12-23 09:54:15394 }
[email protected]4dc832e2011-04-28 22:04:24395
396 // Make sure the cert status is expected.
397 SSLInfo ssl_info;
davidben9dd84872015-05-02 00:22:58398 ASSERT_TRUE(client_socket_->GetSSLInfo(&ssl_info));
[email protected]4dc832e2011-04-28 22:04:24399 EXPECT_EQ(CERT_STATUS_AUTHORITY_INVALID, ssl_info.cert_status);
davidben9dd84872015-05-02 00:22:58400
401 // The default cipher suite should be ECDHE and, unless on NSS and the
402 // platform doesn't support it, an AEAD.
403 uint16_t cipher_suite =
404 SSLConnectionStatusToCipherSuite(ssl_info.connection_status);
405 const char* key_exchange;
406 const char* cipher;
407 const char* mac;
408 bool is_aead;
409 SSLCipherSuiteToStrings(&key_exchange, &cipher, &mac, &is_aead, cipher_suite);
410 EXPECT_STREQ("ECDHE_RSA", key_exchange);
davidben6cacd572015-09-29 22:24:10411 EXPECT_TRUE(is_aead);
[email protected]f61c3972010-12-23 09:54:15412}
413
414TEST_F(SSLServerSocketTest, DataTransfer) {
415 Initialize();
416
[email protected]83039bb2011-12-09 18:43:55417 TestCompletionCallback connect_callback;
[email protected]6ea7b152011-12-21 21:21:13418 TestCompletionCallback handshake_callback;
[email protected]f61c3972010-12-23 09:54:15419
420 // Establish connection.
[email protected]83039bb2011-12-09 18:43:55421 int client_ret = client_socket_->Connect(connect_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04422 ASSERT_TRUE(client_ret == OK || client_ret == ERR_IO_PENDING);
[email protected]f61c3972010-12-23 09:54:15423
[email protected]6ea7b152011-12-21 21:21:13424 int server_ret = server_socket_->Handshake(handshake_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04425 ASSERT_TRUE(server_ret == OK || server_ret == ERR_IO_PENDING);
[email protected]f61c3972010-12-23 09:54:15426
[email protected]febbbb52011-08-17 04:59:23427 client_ret = connect_callback.GetResult(client_ret);
[email protected]fa6ce922014-07-17 04:27:04428 ASSERT_EQ(OK, client_ret);
[email protected]febbbb52011-08-17 04:59:23429 server_ret = handshake_callback.GetResult(server_ret);
[email protected]fa6ce922014-07-17 04:27:04430 ASSERT_EQ(OK, server_ret);
[email protected]f61c3972010-12-23 09:54:15431
432 const int kReadBufSize = 1024;
[email protected]fa6ce922014-07-17 04:27:04433 scoped_refptr<StringIOBuffer> write_buf =
434 new StringIOBuffer("testing123");
435 scoped_refptr<DrainableIOBuffer> read_buf =
436 new DrainableIOBuffer(new IOBuffer(kReadBufSize), kReadBufSize);
[email protected]f61c3972010-12-23 09:54:15437
438 // Write then read.
[email protected]83039bb2011-12-09 18:43:55439 TestCompletionCallback write_callback;
440 TestCompletionCallback read_callback;
[email protected]90499482013-06-01 00:39:50441 server_ret = server_socket_->Write(
442 write_buf.get(), write_buf->size(), write_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04443 EXPECT_TRUE(server_ret > 0 || server_ret == ERR_IO_PENDING);
[email protected]90499482013-06-01 00:39:50444 client_ret = client_socket_->Read(
445 read_buf.get(), read_buf->BytesRemaining(), read_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04446 EXPECT_TRUE(client_ret > 0 || client_ret == ERR_IO_PENDING);
[email protected]f61c3972010-12-23 09:54:15447
[email protected]febbbb52011-08-17 04:59:23448 server_ret = write_callback.GetResult(server_ret);
449 EXPECT_GT(server_ret, 0);
450 client_ret = read_callback.GetResult(client_ret);
451 ASSERT_GT(client_ret, 0);
452
453 read_buf->DidConsume(client_ret);
454 while (read_buf->BytesConsumed() < write_buf->size()) {
[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]febbbb52011-08-17 04:59:23458 client_ret = read_callback.GetResult(client_ret);
459 ASSERT_GT(client_ret, 0);
460 read_buf->DidConsume(client_ret);
[email protected]f61c3972010-12-23 09:54:15461 }
[email protected]febbbb52011-08-17 04:59:23462 EXPECT_EQ(write_buf->size(), read_buf->BytesConsumed());
463 read_buf->SetOffset(0);
[email protected]f61c3972010-12-23 09:54:15464 EXPECT_EQ(0, memcmp(write_buf->data(), read_buf->data(), write_buf->size()));
465
466 // Read then write.
[email protected]fa6ce922014-07-17 04:27:04467 write_buf = new StringIOBuffer("hello123");
[email protected]90499482013-06-01 00:39:50468 server_ret = server_socket_->Read(
469 read_buf.get(), read_buf->BytesRemaining(), read_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04470 EXPECT_TRUE(server_ret > 0 || server_ret == ERR_IO_PENDING);
[email protected]90499482013-06-01 00:39:50471 client_ret = client_socket_->Write(
472 write_buf.get(), write_buf->size(), write_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04473 EXPECT_TRUE(client_ret > 0 || client_ret == ERR_IO_PENDING);
[email protected]f61c3972010-12-23 09:54:15474
[email protected]febbbb52011-08-17 04:59:23475 server_ret = read_callback.GetResult(server_ret);
476 ASSERT_GT(server_ret, 0);
477 client_ret = write_callback.GetResult(client_ret);
478 EXPECT_GT(client_ret, 0);
479
480 read_buf->DidConsume(server_ret);
481 while (read_buf->BytesConsumed() < write_buf->size()) {
[email protected]90499482013-06-01 00:39:50482 server_ret = server_socket_->Read(
483 read_buf.get(), read_buf->BytesRemaining(), read_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04484 EXPECT_TRUE(server_ret > 0 || server_ret == ERR_IO_PENDING);
[email protected]febbbb52011-08-17 04:59:23485 server_ret = read_callback.GetResult(server_ret);
486 ASSERT_GT(server_ret, 0);
487 read_buf->DidConsume(server_ret);
[email protected]f61c3972010-12-23 09:54:15488 }
[email protected]febbbb52011-08-17 04:59:23489 EXPECT_EQ(write_buf->size(), read_buf->BytesConsumed());
490 read_buf->SetOffset(0);
[email protected]f61c3972010-12-23 09:54:15491 EXPECT_EQ(0, memcmp(write_buf->data(), read_buf->data(), write_buf->size()));
492}
[email protected]b0ff3f82011-07-23 05:12:39493
[email protected]c0e4dd12012-05-16 19:36:31494// A regression test for bug 127822 (http://crbug.com/127822).
495// If the server closes the connection after the handshake is finished,
496// the client's Write() call should not cause an infinite loop.
497// NOTE: this is a test for SSLClientSocket rather than SSLServerSocket.
[email protected]4da82282014-07-16 18:40:43498TEST_F(SSLServerSocketTest, ClientWriteAfterServerClose) {
[email protected]c0e4dd12012-05-16 19:36:31499 Initialize();
500
501 TestCompletionCallback connect_callback;
502 TestCompletionCallback handshake_callback;
503
504 // Establish connection.
505 int client_ret = client_socket_->Connect(connect_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04506 ASSERT_TRUE(client_ret == OK || client_ret == ERR_IO_PENDING);
[email protected]c0e4dd12012-05-16 19:36:31507
508 int server_ret = server_socket_->Handshake(handshake_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04509 ASSERT_TRUE(server_ret == OK || server_ret == ERR_IO_PENDING);
[email protected]c0e4dd12012-05-16 19:36:31510
511 client_ret = connect_callback.GetResult(client_ret);
[email protected]fa6ce922014-07-17 04:27:04512 ASSERT_EQ(OK, client_ret);
[email protected]c0e4dd12012-05-16 19:36:31513 server_ret = handshake_callback.GetResult(server_ret);
[email protected]fa6ce922014-07-17 04:27:04514 ASSERT_EQ(OK, server_ret);
[email protected]c0e4dd12012-05-16 19:36:31515
[email protected]fa6ce922014-07-17 04:27:04516 scoped_refptr<StringIOBuffer> write_buf = new StringIOBuffer("testing123");
[email protected]c0e4dd12012-05-16 19:36:31517
518 // The server closes the connection. The server needs to write some
519 // data first so that the client's Read() calls from the transport
520 // socket won't return ERR_IO_PENDING. This ensures that the client
521 // will call Read() on the transport socket again.
522 TestCompletionCallback write_callback;
523
[email protected]90499482013-06-01 00:39:50524 server_ret = server_socket_->Write(
525 write_buf.get(), write_buf->size(), write_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04526 EXPECT_TRUE(server_ret > 0 || server_ret == ERR_IO_PENDING);
[email protected]c0e4dd12012-05-16 19:36:31527
528 server_ret = write_callback.GetResult(server_ret);
529 EXPECT_GT(server_ret, 0);
530
531 server_socket_->Disconnect();
532
533 // The client writes some data. This should not cause an infinite loop.
[email protected]90499482013-06-01 00:39:50534 client_ret = client_socket_->Write(
535 write_buf.get(), write_buf->size(), write_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04536 EXPECT_TRUE(client_ret > 0 || client_ret == ERR_IO_PENDING);
[email protected]c0e4dd12012-05-16 19:36:31537
538 client_ret = write_callback.GetResult(client_ret);
539 EXPECT_GT(client_ret, 0);
540
skyostil4891b25b2015-06-11 11:43:45541 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
ki.stfu375812e2015-10-09 20:23:17542 FROM_HERE, base::MessageLoop::QuitWhenIdleClosure(),
[email protected]c0e4dd12012-05-16 19:36:31543 base::TimeDelta::FromMilliseconds(10));
[email protected]2da659e2013-05-23 20:51:34544 base::MessageLoop::current()->Run();
[email protected]c0e4dd12012-05-16 19:36:31545}
546
[email protected]b0ff3f82011-07-23 05:12:39547// This test executes ExportKeyingMaterial() on the client and server sockets,
548// after connecting them, and verifies that the results match.
549// This test will fail if False Start is enabled (see crbug.com/90208).
550TEST_F(SSLServerSocketTest, ExportKeyingMaterial) {
551 Initialize();
552
[email protected]83039bb2011-12-09 18:43:55553 TestCompletionCallback connect_callback;
[email protected]6ea7b152011-12-21 21:21:13554 TestCompletionCallback handshake_callback;
[email protected]b0ff3f82011-07-23 05:12:39555
[email protected]83039bb2011-12-09 18:43:55556 int client_ret = client_socket_->Connect(connect_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04557 ASSERT_TRUE(client_ret == OK || client_ret == ERR_IO_PENDING);
[email protected]b0ff3f82011-07-23 05:12:39558
[email protected]6ea7b152011-12-21 21:21:13559 int server_ret = server_socket_->Handshake(handshake_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04560 ASSERT_TRUE(server_ret == OK || server_ret == ERR_IO_PENDING);
[email protected]b0ff3f82011-07-23 05:12:39561
[email protected]fa6ce922014-07-17 04:27:04562 if (client_ret == ERR_IO_PENDING) {
563 ASSERT_EQ(OK, connect_callback.WaitForResult());
[email protected]b0ff3f82011-07-23 05:12:39564 }
[email protected]fa6ce922014-07-17 04:27:04565 if (server_ret == ERR_IO_PENDING) {
566 ASSERT_EQ(OK, handshake_callback.WaitForResult());
[email protected]b0ff3f82011-07-23 05:12:39567 }
568
569 const int kKeyingMaterialSize = 32;
thestig9d3bb0c2015-01-24 00:49:51570 const char kKeyingLabel[] = "EXPERIMENTAL-server-socket-test";
571 const char kKeyingContext[] = "";
[email protected]b0ff3f82011-07-23 05:12:39572 unsigned char server_out[kKeyingMaterialSize];
[email protected]1bc6f5e2012-03-15 00:20:58573 int rv = server_socket_->ExportKeyingMaterial(kKeyingLabel,
574 false, kKeyingContext,
[email protected]b0ff3f82011-07-23 05:12:39575 server_out, sizeof(server_out));
[email protected]fa6ce922014-07-17 04:27:04576 ASSERT_EQ(OK, rv);
[email protected]b0ff3f82011-07-23 05:12:39577
578 unsigned char client_out[kKeyingMaterialSize];
[email protected]1bc6f5e2012-03-15 00:20:58579 rv = client_socket_->ExportKeyingMaterial(kKeyingLabel,
580 false, kKeyingContext,
[email protected]b0ff3f82011-07-23 05:12:39581 client_out, sizeof(client_out));
[email protected]fa6ce922014-07-17 04:27:04582 ASSERT_EQ(OK, rv);
[email protected]47a12862012-04-10 01:00:49583 EXPECT_EQ(0, memcmp(server_out, client_out, sizeof(server_out)));
[email protected]b0ff3f82011-07-23 05:12:39584
thestig9d3bb0c2015-01-24 00:49:51585 const char kKeyingLabelBad[] = "EXPERIMENTAL-server-socket-test-bad";
[email protected]b0ff3f82011-07-23 05:12:39586 unsigned char client_bad[kKeyingMaterialSize];
[email protected]1bc6f5e2012-03-15 00:20:58587 rv = client_socket_->ExportKeyingMaterial(kKeyingLabelBad,
588 false, kKeyingContext,
[email protected]b0ff3f82011-07-23 05:12:39589 client_bad, sizeof(client_bad));
[email protected]fa6ce922014-07-17 04:27:04590 ASSERT_EQ(rv, OK);
[email protected]47a12862012-04-10 01:00:49591 EXPECT_NE(0, memcmp(server_out, client_bad, sizeof(server_out)));
[email protected]b0ff3f82011-07-23 05:12:39592}
[email protected]f61c3972010-12-23 09:54:15593
sergeyuff826d5e2015-05-13 20:35:22594// Verifies that SSLConfig::require_ecdhe flags works properly.
595TEST_F(SSLServerSocketTest, RequireEcdheFlag) {
596 // Disable all ECDHE suites on the client side.
597 uint16_t kEcdheCiphers[] = {
598 0xc007, // ECDHE_ECDSA_WITH_RC4_128_SHA
599 0xc009, // ECDHE_ECDSA_WITH_AES_128_CBC_SHA
600 0xc00a, // ECDHE_ECDSA_WITH_AES_256_CBC_SHA
601 0xc011, // ECDHE_RSA_WITH_RC4_128_SHA
602 0xc013, // ECDHE_RSA_WITH_AES_128_CBC_SHA
603 0xc014, // ECDHE_RSA_WITH_AES_256_CBC_SHA
604 0xc02b, // ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
605 0xc02f, // ECDHE_RSA_WITH_AES_128_GCM_SHA256
606 0xcc13, // ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
607 0xcc14, // ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
608 };
609 client_ssl_config_.disabled_cipher_suites.assign(
610 kEcdheCiphers, kEcdheCiphers + arraysize(kEcdheCiphers));
611
612 // Require ECDHE on the server.
613 server_ssl_config_.require_ecdhe = true;
614
615 Initialize();
616
617 TestCompletionCallback connect_callback;
618 TestCompletionCallback handshake_callback;
619
620 int client_ret = client_socket_->Connect(connect_callback.callback());
621 int server_ret = server_socket_->Handshake(handshake_callback.callback());
622
623 client_ret = connect_callback.GetResult(client_ret);
624 server_ret = handshake_callback.GetResult(server_ret);
625
626 ASSERT_EQ(ERR_SSL_VERSION_OR_CIPHER_MISMATCH, client_ret);
627 ASSERT_EQ(ERR_SSL_VERSION_OR_CIPHER_MISMATCH, server_ret);
628}
629
[email protected]f61c3972010-12-23 09:54:15630} // namespace net