blob: c15b8cc3cf203541a9647519ff34c6c4a6764686 [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"
[email protected]18b577412013-07-18 04:19:1525#include "base/message_loop/message_loop.h"
[email protected]4b559b4d2011-04-14 17:37:1426#include "crypto/nss_util.h"
27#include "crypto/rsa_private_key.h"
[email protected]f61c3972010-12-23 09:54:1528#include "net/base/address_list.h"
[email protected]6ea7b152011-12-21 21:21:1329#include "net/base/completion_callback.h"
[email protected]f61c3972010-12-23 09:54:1530#include "net/base/host_port_pair.h"
31#include "net/base/io_buffer.h"
[email protected]e7f74da2011-04-19 23:49:3532#include "net/base/ip_endpoint.h"
[email protected]f61c3972010-12-23 09:54:1533#include "net/base/net_errors.h"
[email protected]42fdb452012-11-01 12:44:4034#include "net/base/test_data_directory.h"
[email protected]6e7845ae2013-03-29 21:48:1135#include "net/cert/cert_status_flags.h"
36#include "net/cert/mock_cert_verifier.h"
37#include "net/cert/x509_certificate.h"
[email protected]b1c988b2013-06-13 06:48:1138#include "net/http/transport_security_state.h"
eroman87c53d62015-04-02 06:51:0739#include "net/log/net_log.h"
[email protected]f61c3972010-12-23 09:54:1540#include "net/socket/client_socket_factory.h"
41#include "net/socket/socket_test_util.h"
42#include "net/socket/ssl_client_socket.h"
[email protected]3268023f2011-05-05 00:08:1043#include "net/socket/stream_socket.h"
davidben9dd84872015-05-02 00:22:5844#include "net/ssl/ssl_cipher_suite_names.h"
[email protected]536fd0b2013-03-14 17:41:5745#include "net/ssl/ssl_config_service.h"
davidben9dd84872015-05-02 00:22:5846#include "net/ssl/ssl_connection_status_flags.h"
[email protected]536fd0b2013-03-14 17:41:5747#include "net/ssl/ssl_info.h"
[email protected]6e7845ae2013-03-29 21:48:1148#include "net/test/cert_test_util.h"
[email protected]f61c3972010-12-23 09:54:1549#include "testing/gtest/include/gtest/gtest.h"
50#include "testing/platform_test.h"
51
davidben9dd84872015-05-02 00:22:5852#if !defined(USE_OPENSSL)
53#include <pk11pub.h>
54
55#if !defined(CKM_AES_GCM)
56#define CKM_AES_GCM 0x00001087
57#endif
58#endif
59
[email protected]f61c3972010-12-23 09:54:1560namespace net {
61
62namespace {
63
64class FakeDataChannel {
65 public:
[email protected]55ee0e52011-07-21 18:29:4466 FakeDataChannel()
[email protected]83039bb2011-12-09 18:43:5567 : read_buf_len_(0),
[email protected]c0e4dd12012-05-16 19:36:3168 closed_(false),
[email protected]d5492c52013-11-10 20:44:3969 write_called_after_close_(false),
70 weak_factory_(this) {
[email protected]f61c3972010-12-23 09:54:1571 }
72
[email protected]47a12862012-04-10 01:00:4973 int Read(IOBuffer* buf, int buf_len, const CompletionCallback& callback) {
[email protected]4da82282014-07-16 18:40:4374 DCHECK(read_callback_.is_null());
dcheng08ea2af02014-08-25 23:38:0975 DCHECK(!read_buf_.get());
[email protected]c0e4dd12012-05-16 19:36:3176 if (closed_)
77 return 0;
[email protected]3f55aa12011-12-07 02:03:3378 if (data_.empty()) {
[email protected]f61c3972010-12-23 09:54:1579 read_callback_ = callback;
80 read_buf_ = buf;
81 read_buf_len_ = buf_len;
[email protected]fa6ce922014-07-17 04:27:0482 return ERR_IO_PENDING;
[email protected]f61c3972010-12-23 09:54:1583 }
84 return PropogateData(buf, buf_len);
85 }
86
[email protected]47a12862012-04-10 01:00:4987 int Write(IOBuffer* buf, int buf_len, const CompletionCallback& callback) {
[email protected]4da82282014-07-16 18:40:4388 DCHECK(write_callback_.is_null());
[email protected]c0e4dd12012-05-16 19:36:3189 if (closed_) {
90 if (write_called_after_close_)
[email protected]fa6ce922014-07-17 04:27:0491 return ERR_CONNECTION_RESET;
[email protected]c0e4dd12012-05-16 19:36:3192 write_called_after_close_ = true;
93 write_callback_ = callback;
[email protected]2da659e2013-05-23 20:51:3494 base::MessageLoop::current()->PostTask(
[email protected]c0e4dd12012-05-16 19:36:3195 FROM_HERE, base::Bind(&FakeDataChannel::DoWriteCallback,
96 weak_factory_.GetWeakPtr()));
[email protected]fa6ce922014-07-17 04:27:0497 return ERR_IO_PENDING;
[email protected]c0e4dd12012-05-16 19:36:3198 }
[email protected]4da82282014-07-16 18:40:4399 // This function returns synchronously, so make a copy of the buffer.
[email protected]fa6ce922014-07-17 04:27:04100 data_.push(new DrainableIOBuffer(
101 new StringIOBuffer(std::string(buf->data(), buf_len)),
[email protected]4da82282014-07-16 18:40:43102 buf_len));
[email protected]2da659e2013-05-23 20:51:34103 base::MessageLoop::current()->PostTask(
[email protected]83039bb2011-12-09 18:43:55104 FROM_HERE, base::Bind(&FakeDataChannel::DoReadCallback,
105 weak_factory_.GetWeakPtr()));
[email protected]f61c3972010-12-23 09:54:15106 return buf_len;
107 }
108
[email protected]c0e4dd12012-05-16 19:36:31109 // Closes the FakeDataChannel. After Close() is called, Read() returns 0,
110 // indicating EOF, and Write() fails with ERR_CONNECTION_RESET. Note that
111 // after the FakeDataChannel is closed, the first Write() call completes
112 // asynchronously, which is necessary to reproduce bug 127822.
113 void Close() {
114 closed_ = true;
115 }
116
[email protected]f61c3972010-12-23 09:54:15117 private:
118 void DoReadCallback() {
[email protected]83039bb2011-12-09 18:43:55119 if (read_callback_.is_null() || data_.empty())
[email protected]f61c3972010-12-23 09:54:15120 return;
121
122 int copied = PropogateData(read_buf_, read_buf_len_);
[email protected]83039bb2011-12-09 18:43:55123 CompletionCallback callback = read_callback_;
124 read_callback_.Reset();
125 read_buf_ = NULL;
126 read_buf_len_ = 0;
127 callback.Run(copied);
[email protected]f61c3972010-12-23 09:54:15128 }
129
[email protected]c0e4dd12012-05-16 19:36:31130 void DoWriteCallback() {
131 if (write_callback_.is_null())
132 return;
133
134 CompletionCallback callback = write_callback_;
135 write_callback_.Reset();
[email protected]fa6ce922014-07-17 04:27:04136 callback.Run(ERR_CONNECTION_RESET);
[email protected]c0e4dd12012-05-16 19:36:31137 }
138
[email protected]fa6ce922014-07-17 04:27:04139 int PropogateData(scoped_refptr<IOBuffer> read_buf, int read_buf_len) {
140 scoped_refptr<DrainableIOBuffer> buf = data_.front();
[email protected]f61c3972010-12-23 09:54:15141 int copied = std::min(buf->BytesRemaining(), read_buf_len);
142 memcpy(read_buf->data(), buf->data(), copied);
143 buf->DidConsume(copied);
144
145 if (!buf->BytesRemaining())
146 data_.pop();
147 return copied;
148 }
149
[email protected]83039bb2011-12-09 18:43:55150 CompletionCallback read_callback_;
[email protected]fa6ce922014-07-17 04:27:04151 scoped_refptr<IOBuffer> read_buf_;
[email protected]f61c3972010-12-23 09:54:15152 int read_buf_len_;
153
[email protected]c0e4dd12012-05-16 19:36:31154 CompletionCallback write_callback_;
155
[email protected]fa6ce922014-07-17 04:27:04156 std::queue<scoped_refptr<DrainableIOBuffer> > data_;
[email protected]f61c3972010-12-23 09:54:15157
[email protected]c0e4dd12012-05-16 19:36:31158 // True if Close() has been called.
159 bool closed_;
160
161 // Controls the completion of Write() after the FakeDataChannel is closed.
162 // After the FakeDataChannel is closed, the first Write() call completes
163 // asynchronously.
164 bool write_called_after_close_;
165
[email protected]d5492c52013-11-10 20:44:39166 base::WeakPtrFactory<FakeDataChannel> weak_factory_;
167
[email protected]f61c3972010-12-23 09:54:15168 DISALLOW_COPY_AND_ASSIGN(FakeDataChannel);
169};
170
[email protected]3268023f2011-05-05 00:08:10171class FakeSocket : public StreamSocket {
[email protected]f61c3972010-12-23 09:54:15172 public:
173 FakeSocket(FakeDataChannel* incoming_channel,
174 FakeDataChannel* outgoing_channel)
175 : incoming_(incoming_channel),
176 outgoing_(outgoing_channel) {
177 }
178
dchengb03027d2014-10-21 12:00:20179 ~FakeSocket() override {}
[email protected]f61c3972010-12-23 09:54:15180
dchengb03027d2014-10-21 12:00:20181 int Read(IOBuffer* buf,
182 int buf_len,
183 const CompletionCallback& callback) override {
[email protected]3f55aa12011-12-07 02:03:33184 // Read random number of bytes.
185 buf_len = rand() % buf_len + 1;
186 return incoming_->Read(buf, buf_len, callback);
187 }
[email protected]f61c3972010-12-23 09:54:15188
dchengb03027d2014-10-21 12:00:20189 int Write(IOBuffer* buf,
190 int buf_len,
191 const CompletionCallback& callback) override {
[email protected]55ee0e52011-07-21 18:29:44192 // Write random number of bytes.
193 buf_len = rand() % buf_len + 1;
[email protected]f61c3972010-12-23 09:54:15194 return outgoing_->Write(buf, buf_len, callback);
195 }
196
dchengb03027d2014-10-21 12:00:20197 int SetReceiveBufferSize(int32 size) override { return OK; }
[email protected]f61c3972010-12-23 09:54:15198
dchengb03027d2014-10-21 12:00:20199 int SetSendBufferSize(int32 size) override { return OK; }
[email protected]f61c3972010-12-23 09:54:15200
dchengb03027d2014-10-21 12:00:20201 int Connect(const CompletionCallback& callback) override { return OK; }
[email protected]f61c3972010-12-23 09:54:15202
dchengb03027d2014-10-21 12:00:20203 void Disconnect() override {
[email protected]c0e4dd12012-05-16 19:36:31204 incoming_->Close();
205 outgoing_->Close();
206 }
[email protected]f61c3972010-12-23 09:54:15207
dchengb03027d2014-10-21 12:00:20208 bool IsConnected() const override { return true; }
[email protected]f61c3972010-12-23 09:54:15209
dchengb03027d2014-10-21 12:00:20210 bool IsConnectedAndIdle() const override { return true; }
[email protected]f61c3972010-12-23 09:54:15211
dchengb03027d2014-10-21 12:00:20212 int GetPeerAddress(IPEndPoint* address) const override {
[email protected]fa6ce922014-07-17 04:27:04213 IPAddressNumber ip_address(kIPv4AddressSize);
214 *address = IPEndPoint(ip_address, 0 /*port*/);
215 return OK;
[email protected]f61c3972010-12-23 09:54:15216 }
217
dchengb03027d2014-10-21 12:00:20218 int GetLocalAddress(IPEndPoint* address) const override {
[email protected]fa6ce922014-07-17 04:27:04219 IPAddressNumber ip_address(4);
220 *address = IPEndPoint(ip_address, 0);
221 return OK;
[email protected]e7f74da2011-04-19 23:49:35222 }
223
dchengb03027d2014-10-21 12:00:20224 const BoundNetLog& NetLog() const override { return net_log_; }
[email protected]f61c3972010-12-23 09:54:15225
dchengb03027d2014-10-21 12:00:20226 void SetSubresourceSpeculation() override {}
227 void SetOmniboxSpeculation() override {}
[email protected]f61c3972010-12-23 09:54:15228
dchengb03027d2014-10-21 12:00:20229 bool WasEverUsed() const override { return true; }
[email protected]f61c3972010-12-23 09:54:15230
dchengb03027d2014-10-21 12:00:20231 bool UsingTCPFastOpen() const override { return false; }
[email protected]f61c3972010-12-23 09:54:15232
dchengb03027d2014-10-21 12:00:20233 bool WasNpnNegotiated() const override { return false; }
[email protected]5e6efa52011-06-27 17:26:41234
dchengb03027d2014-10-21 12:00:20235 NextProto GetNegotiatedProtocol() const override { return kProtoUnknown; }
[email protected]2d88e7d2012-07-19 17:55:17236
dchengb03027d2014-10-21 12:00:20237 bool GetSSLInfo(SSLInfo* ssl_info) override { return false; }
[email protected]2d88e7d2012-07-19 17:55:17238
[email protected]f61c3972010-12-23 09:54:15239 private:
[email protected]fa6ce922014-07-17 04:27:04240 BoundNetLog net_log_;
[email protected]f61c3972010-12-23 09:54:15241 FakeDataChannel* incoming_;
242 FakeDataChannel* outgoing_;
243
244 DISALLOW_COPY_AND_ASSIGN(FakeSocket);
245};
246
247} // namespace
248
249// Verify the correctness of the test helper classes first.
250TEST(FakeSocketTest, DataTransfer) {
251 // Establish channels between two sockets.
252 FakeDataChannel channel_1;
253 FakeDataChannel channel_2;
254 FakeSocket client(&channel_1, &channel_2);
255 FakeSocket server(&channel_2, &channel_1);
256
257 const char kTestData[] = "testing123";
258 const int kTestDataSize = strlen(kTestData);
259 const int kReadBufSize = 1024;
[email protected]fa6ce922014-07-17 04:27:04260 scoped_refptr<IOBuffer> write_buf = new StringIOBuffer(kTestData);
261 scoped_refptr<IOBuffer> read_buf = new IOBuffer(kReadBufSize);
[email protected]f61c3972010-12-23 09:54:15262
263 // Write then read.
[email protected]90499482013-06-01 00:39:50264 int written =
265 server.Write(write_buf.get(), kTestDataSize, CompletionCallback());
[email protected]55ee0e52011-07-21 18:29:44266 EXPECT_GT(written, 0);
267 EXPECT_LE(written, kTestDataSize);
268
[email protected]90499482013-06-01 00:39:50269 int read = client.Read(read_buf.get(), kReadBufSize, CompletionCallback());
[email protected]55ee0e52011-07-21 18:29:44270 EXPECT_GT(read, 0);
271 EXPECT_LE(read, written);
272 EXPECT_EQ(0, memcmp(kTestData, read_buf->data(), read));
[email protected]f61c3972010-12-23 09:54:15273
274 // Read then write.
[email protected]83039bb2011-12-09 18:43:55275 TestCompletionCallback callback;
[email protected]fa6ce922014-07-17 04:27:04276 EXPECT_EQ(ERR_IO_PENDING,
[email protected]90499482013-06-01 00:39:50277 server.Read(read_buf.get(), kReadBufSize, callback.callback()));
[email protected]55ee0e52011-07-21 18:29:44278
[email protected]90499482013-06-01 00:39:50279 written = client.Write(write_buf.get(), kTestDataSize, CompletionCallback());
[email protected]55ee0e52011-07-21 18:29:44280 EXPECT_GT(written, 0);
281 EXPECT_LE(written, kTestDataSize);
282
283 read = callback.WaitForResult();
284 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
289class SSLServerSocketTest : public PlatformTest {
290 public:
291 SSLServerSocketTest()
[email protected]fa6ce922014-07-17 04:27:04292 : socket_factory_(ClientSocketFactory::GetDefaultFactory()),
[email protected]b1c988b2013-06-13 06:48:11293 cert_verifier_(new MockCertVerifier()),
294 transport_security_state_(new TransportSecurityState) {
[email protected]fa6ce922014-07-17 04:27:04295 cert_verifier_->set_default_result(CERT_STATUS_AUTHORITY_INVALID);
[email protected]f61c3972010-12-23 09:54:15296 }
297
298 protected:
299 void Initialize() {
[email protected]18ccfdb2013-08-15 00:13:44300 scoped_ptr<ClientSocketHandle> client_connection(new ClientSocketHandle);
301 client_connection->SetSocket(
302 scoped_ptr<StreamSocket>(new FakeSocket(&channel_1_, &channel_2_)));
303 scoped_ptr<StreamSocket> server_socket(
304 new FakeSocket(&channel_2_, &channel_1_));
[email protected]f61c3972010-12-23 09:54:15305
[email protected]6cdfd7f2013-02-08 20:40:15306 base::FilePath certs_dir(GetTestCertsDirectory());
[email protected]f61c3972010-12-23 09:54:15307
[email protected]6cdfd7f2013-02-08 20:40:15308 base::FilePath cert_path = certs_dir.AppendASCII("unittest.selfsigned.der");
[email protected]f61c3972010-12-23 09:54:15309 std::string cert_der;
[email protected]82f84b92013-08-30 18:23:50310 ASSERT_TRUE(base::ReadFileToString(cert_path, &cert_der));
[email protected]f61c3972010-12-23 09:54:15311
[email protected]fa6ce922014-07-17 04:27:04312 scoped_refptr<X509Certificate> cert =
[email protected]f61c3972010-12-23 09:54:15313 X509Certificate::CreateFromBytes(cert_der.data(), cert_der.size());
314
[email protected]6cdfd7f2013-02-08 20:40:15315 base::FilePath key_path = certs_dir.AppendASCII("unittest.key.bin");
[email protected]f61c3972010-12-23 09:54:15316 std::string key_string;
[email protected]82f84b92013-08-30 18:23:50317 ASSERT_TRUE(base::ReadFileToString(key_path, &key_string));
[email protected]f61c3972010-12-23 09:54:15318 std::vector<uint8> key_vector(
319 reinterpret_cast<const uint8*>(key_string.data()),
320 reinterpret_cast<const uint8*>(key_string.data() +
321 key_string.length()));
322
[email protected]4b559b4d2011-04-14 17:37:14323 scoped_ptr<crypto::RSAPrivateKey> private_key(
324 crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(key_vector));
[email protected]f61c3972010-12-23 09:54:15325
[email protected]fa6ce922014-07-17 04:27:04326 SSLConfig ssl_config;
[email protected]f61c3972010-12-23 09:54:15327 ssl_config.false_start_enabled = false;
[email protected]6b4903f2012-06-26 02:13:49328 ssl_config.channel_id_enabled = false;
[email protected]f61c3972010-12-23 09:54:15329
330 // Certificate provided by the host doesn't need authority.
[email protected]fa6ce922014-07-17 04:27:04331 SSLConfig::CertAndStatus cert_and_status;
[email protected]4dc832e2011-04-28 22:04:24332 cert_and_status.cert_status = CERT_STATUS_AUTHORITY_INVALID;
[email protected]3d5c1bd2011-07-20 02:14:01333 cert_and_status.der_cert = cert_der;
[email protected]f61c3972010-12-23 09:54:15334 ssl_config.allowed_bad_certs.push_back(cert_and_status);
335
[email protected]fa6ce922014-07-17 04:27:04336 HostPortPair host_and_pair("unittest", 0);
337 SSLClientSocketContext context;
[email protected]9f59fac2012-03-21 23:18:11338 context.cert_verifier = cert_verifier_.get();
[email protected]b1c988b2013-06-13 06:48:11339 context.transport_security_state = transport_security_state_.get();
[email protected]18ccfdb2013-08-15 00:13:44340 client_socket_ =
[email protected]f61c3972010-12-23 09:54:15341 socket_factory_->CreateSSLClientSocket(
[email protected]18ccfdb2013-08-15 00:13:44342 client_connection.Pass(), host_and_pair, ssl_config, context);
[email protected]fa6ce922014-07-17 04:27:04343 server_socket_ = CreateSSLServerSocket(
[email protected]18ccfdb2013-08-15 00:13:44344 server_socket.Pass(),
[email protected]fa6ce922014-07-17 04:27:04345 cert.get(), private_key.get(), SSLConfig());
[email protected]f61c3972010-12-23 09:54:15346 }
347
348 FakeDataChannel channel_1_;
349 FakeDataChannel channel_2_;
[email protected]fa6ce922014-07-17 04:27:04350 scoped_ptr<SSLClientSocket> client_socket_;
351 scoped_ptr<SSLServerSocket> server_socket_;
352 ClientSocketFactory* socket_factory_;
353 scoped_ptr<MockCertVerifier> cert_verifier_;
354 scoped_ptr<TransportSecurityState> transport_security_state_;
[email protected]f61c3972010-12-23 09:54:15355};
356
[email protected]f61c3972010-12-23 09:54:15357// This test only executes creation of client and server sockets. This is to
358// test that creation of sockets doesn't crash and have minimal code to run
359// under valgrind in order to help debugging memory problems.
360TEST_F(SSLServerSocketTest, Initialize) {
361 Initialize();
362}
363
[email protected]a7ac3c32011-06-17 19:10:15364// This test executes Connect() on SSLClientSocket and Handshake() on
365// SSLServerSocket to make sure handshaking between the two sockets is
[email protected]f61c3972010-12-23 09:54:15366// completed successfully.
367TEST_F(SSLServerSocketTest, Handshake) {
368 Initialize();
369
[email protected]83039bb2011-12-09 18:43:55370 TestCompletionCallback connect_callback;
[email protected]6ea7b152011-12-21 21:21:13371 TestCompletionCallback handshake_callback;
[email protected]f61c3972010-12-23 09:54:15372
[email protected]6ea7b152011-12-21 21:21:13373 int server_ret = server_socket_->Handshake(handshake_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04374 EXPECT_TRUE(server_ret == OK || server_ret == ERR_IO_PENDING);
[email protected]f61c3972010-12-23 09:54:15375
[email protected]83039bb2011-12-09 18:43:55376 int client_ret = client_socket_->Connect(connect_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04377 EXPECT_TRUE(client_ret == OK || client_ret == ERR_IO_PENDING);
[email protected]f61c3972010-12-23 09:54:15378
[email protected]fa6ce922014-07-17 04:27:04379 if (client_ret == ERR_IO_PENDING) {
380 EXPECT_EQ(OK, connect_callback.WaitForResult());
[email protected]f61c3972010-12-23 09:54:15381 }
[email protected]fa6ce922014-07-17 04:27:04382 if (server_ret == ERR_IO_PENDING) {
383 EXPECT_EQ(OK, handshake_callback.WaitForResult());
[email protected]f61c3972010-12-23 09:54:15384 }
[email protected]4dc832e2011-04-28 22:04:24385
386 // Make sure the cert status is expected.
387 SSLInfo ssl_info;
davidben9dd84872015-05-02 00:22:58388 ASSERT_TRUE(client_socket_->GetSSLInfo(&ssl_info));
[email protected]4dc832e2011-04-28 22:04:24389 EXPECT_EQ(CERT_STATUS_AUTHORITY_INVALID, ssl_info.cert_status);
davidben9dd84872015-05-02 00:22:58390
391 // The default cipher suite should be ECDHE and, unless on NSS and the
392 // platform doesn't support it, an AEAD.
393 uint16_t cipher_suite =
394 SSLConnectionStatusToCipherSuite(ssl_info.connection_status);
395 const char* key_exchange;
396 const char* cipher;
397 const char* mac;
398 bool is_aead;
399 SSLCipherSuiteToStrings(&key_exchange, &cipher, &mac, &is_aead, cipher_suite);
400 EXPECT_STREQ("ECDHE_RSA", key_exchange);
401#if defined(USE_OPENSSL)
402 bool supports_aead = true;
403#else
404 bool supports_aead = PK11_TokenExists(CKM_AES_GCM);
405#endif
406 EXPECT_TRUE(!supports_aead || is_aead);
[email protected]f61c3972010-12-23 09:54:15407}
408
409TEST_F(SSLServerSocketTest, DataTransfer) {
410 Initialize();
411
[email protected]83039bb2011-12-09 18:43:55412 TestCompletionCallback connect_callback;
[email protected]6ea7b152011-12-21 21:21:13413 TestCompletionCallback handshake_callback;
[email protected]f61c3972010-12-23 09:54:15414
415 // Establish connection.
[email protected]83039bb2011-12-09 18:43:55416 int client_ret = client_socket_->Connect(connect_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04417 ASSERT_TRUE(client_ret == OK || client_ret == ERR_IO_PENDING);
[email protected]f61c3972010-12-23 09:54:15418
[email protected]6ea7b152011-12-21 21:21:13419 int server_ret = server_socket_->Handshake(handshake_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04420 ASSERT_TRUE(server_ret == OK || server_ret == ERR_IO_PENDING);
[email protected]f61c3972010-12-23 09:54:15421
[email protected]febbbb52011-08-17 04:59:23422 client_ret = connect_callback.GetResult(client_ret);
[email protected]fa6ce922014-07-17 04:27:04423 ASSERT_EQ(OK, client_ret);
[email protected]febbbb52011-08-17 04:59:23424 server_ret = handshake_callback.GetResult(server_ret);
[email protected]fa6ce922014-07-17 04:27:04425 ASSERT_EQ(OK, server_ret);
[email protected]f61c3972010-12-23 09:54:15426
427 const int kReadBufSize = 1024;
[email protected]fa6ce922014-07-17 04:27:04428 scoped_refptr<StringIOBuffer> write_buf =
429 new StringIOBuffer("testing123");
430 scoped_refptr<DrainableIOBuffer> read_buf =
431 new DrainableIOBuffer(new IOBuffer(kReadBufSize), kReadBufSize);
[email protected]f61c3972010-12-23 09:54:15432
433 // Write then read.
[email protected]83039bb2011-12-09 18:43:55434 TestCompletionCallback write_callback;
435 TestCompletionCallback read_callback;
[email protected]90499482013-06-01 00:39:50436 server_ret = server_socket_->Write(
437 write_buf.get(), write_buf->size(), write_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04438 EXPECT_TRUE(server_ret > 0 || server_ret == ERR_IO_PENDING);
[email protected]90499482013-06-01 00:39:50439 client_ret = client_socket_->Read(
440 read_buf.get(), read_buf->BytesRemaining(), read_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04441 EXPECT_TRUE(client_ret > 0 || client_ret == ERR_IO_PENDING);
[email protected]f61c3972010-12-23 09:54:15442
[email protected]febbbb52011-08-17 04:59:23443 server_ret = write_callback.GetResult(server_ret);
444 EXPECT_GT(server_ret, 0);
445 client_ret = read_callback.GetResult(client_ret);
446 ASSERT_GT(client_ret, 0);
447
448 read_buf->DidConsume(client_ret);
449 while (read_buf->BytesConsumed() < write_buf->size()) {
[email protected]90499482013-06-01 00:39:50450 client_ret = client_socket_->Read(
451 read_buf.get(), read_buf->BytesRemaining(), read_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04452 EXPECT_TRUE(client_ret > 0 || client_ret == ERR_IO_PENDING);
[email protected]febbbb52011-08-17 04:59:23453 client_ret = read_callback.GetResult(client_ret);
454 ASSERT_GT(client_ret, 0);
455 read_buf->DidConsume(client_ret);
[email protected]f61c3972010-12-23 09:54:15456 }
[email protected]febbbb52011-08-17 04:59:23457 EXPECT_EQ(write_buf->size(), read_buf->BytesConsumed());
458 read_buf->SetOffset(0);
[email protected]f61c3972010-12-23 09:54:15459 EXPECT_EQ(0, memcmp(write_buf->data(), read_buf->data(), write_buf->size()));
460
461 // Read then write.
[email protected]fa6ce922014-07-17 04:27:04462 write_buf = new StringIOBuffer("hello123");
[email protected]90499482013-06-01 00:39:50463 server_ret = server_socket_->Read(
464 read_buf.get(), read_buf->BytesRemaining(), read_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04465 EXPECT_TRUE(server_ret > 0 || server_ret == ERR_IO_PENDING);
[email protected]90499482013-06-01 00:39:50466 client_ret = client_socket_->Write(
467 write_buf.get(), write_buf->size(), write_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04468 EXPECT_TRUE(client_ret > 0 || client_ret == ERR_IO_PENDING);
[email protected]f61c3972010-12-23 09:54:15469
[email protected]febbbb52011-08-17 04:59:23470 server_ret = read_callback.GetResult(server_ret);
471 ASSERT_GT(server_ret, 0);
472 client_ret = write_callback.GetResult(client_ret);
473 EXPECT_GT(client_ret, 0);
474
475 read_buf->DidConsume(server_ret);
476 while (read_buf->BytesConsumed() < write_buf->size()) {
[email protected]90499482013-06-01 00:39:50477 server_ret = server_socket_->Read(
478 read_buf.get(), read_buf->BytesRemaining(), read_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04479 EXPECT_TRUE(server_ret > 0 || server_ret == ERR_IO_PENDING);
[email protected]febbbb52011-08-17 04:59:23480 server_ret = read_callback.GetResult(server_ret);
481 ASSERT_GT(server_ret, 0);
482 read_buf->DidConsume(server_ret);
[email protected]f61c3972010-12-23 09:54:15483 }
[email protected]febbbb52011-08-17 04:59:23484 EXPECT_EQ(write_buf->size(), read_buf->BytesConsumed());
485 read_buf->SetOffset(0);
[email protected]f61c3972010-12-23 09:54:15486 EXPECT_EQ(0, memcmp(write_buf->data(), read_buf->data(), write_buf->size()));
487}
[email protected]b0ff3f82011-07-23 05:12:39488
[email protected]c0e4dd12012-05-16 19:36:31489// A regression test for bug 127822 (http://crbug.com/127822).
490// If the server closes the connection after the handshake is finished,
491// the client's Write() call should not cause an infinite loop.
492// NOTE: this is a test for SSLClientSocket rather than SSLServerSocket.
[email protected]4da82282014-07-16 18:40:43493TEST_F(SSLServerSocketTest, ClientWriteAfterServerClose) {
[email protected]c0e4dd12012-05-16 19:36:31494 Initialize();
495
496 TestCompletionCallback connect_callback;
497 TestCompletionCallback handshake_callback;
498
499 // Establish connection.
500 int client_ret = client_socket_->Connect(connect_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04501 ASSERT_TRUE(client_ret == OK || client_ret == ERR_IO_PENDING);
[email protected]c0e4dd12012-05-16 19:36:31502
503 int server_ret = server_socket_->Handshake(handshake_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04504 ASSERT_TRUE(server_ret == OK || server_ret == ERR_IO_PENDING);
[email protected]c0e4dd12012-05-16 19:36:31505
506 client_ret = connect_callback.GetResult(client_ret);
[email protected]fa6ce922014-07-17 04:27:04507 ASSERT_EQ(OK, client_ret);
[email protected]c0e4dd12012-05-16 19:36:31508 server_ret = handshake_callback.GetResult(server_ret);
[email protected]fa6ce922014-07-17 04:27:04509 ASSERT_EQ(OK, server_ret);
[email protected]c0e4dd12012-05-16 19:36:31510
[email protected]fa6ce922014-07-17 04:27:04511 scoped_refptr<StringIOBuffer> write_buf = new StringIOBuffer("testing123");
[email protected]c0e4dd12012-05-16 19:36:31512
513 // The server closes the connection. The server needs to write some
514 // data first so that the client's Read() calls from the transport
515 // socket won't return ERR_IO_PENDING. This ensures that the client
516 // will call Read() on the transport socket again.
517 TestCompletionCallback write_callback;
518
[email protected]90499482013-06-01 00:39:50519 server_ret = server_socket_->Write(
520 write_buf.get(), write_buf->size(), write_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04521 EXPECT_TRUE(server_ret > 0 || server_ret == ERR_IO_PENDING);
[email protected]c0e4dd12012-05-16 19:36:31522
523 server_ret = write_callback.GetResult(server_ret);
524 EXPECT_GT(server_ret, 0);
525
526 server_socket_->Disconnect();
527
528 // The client writes some data. This should not cause an infinite loop.
[email protected]90499482013-06-01 00:39:50529 client_ret = client_socket_->Write(
530 write_buf.get(), write_buf->size(), write_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04531 EXPECT_TRUE(client_ret > 0 || client_ret == ERR_IO_PENDING);
[email protected]c0e4dd12012-05-16 19:36:31532
533 client_ret = write_callback.GetResult(client_ret);
534 EXPECT_GT(client_ret, 0);
535
[email protected]2da659e2013-05-23 20:51:34536 base::MessageLoop::current()->PostDelayedTask(
537 FROM_HERE, base::MessageLoop::QuitClosure(),
[email protected]c0e4dd12012-05-16 19:36:31538 base::TimeDelta::FromMilliseconds(10));
[email protected]2da659e2013-05-23 20:51:34539 base::MessageLoop::current()->Run();
[email protected]c0e4dd12012-05-16 19:36:31540}
541
[email protected]b0ff3f82011-07-23 05:12:39542// This test executes ExportKeyingMaterial() on the client and server sockets,
543// after connecting them, and verifies that the results match.
544// This test will fail if False Start is enabled (see crbug.com/90208).
545TEST_F(SSLServerSocketTest, ExportKeyingMaterial) {
546 Initialize();
547
[email protected]83039bb2011-12-09 18:43:55548 TestCompletionCallback connect_callback;
[email protected]6ea7b152011-12-21 21:21:13549 TestCompletionCallback handshake_callback;
[email protected]b0ff3f82011-07-23 05:12:39550
[email protected]83039bb2011-12-09 18:43:55551 int client_ret = client_socket_->Connect(connect_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04552 ASSERT_TRUE(client_ret == OK || client_ret == ERR_IO_PENDING);
[email protected]b0ff3f82011-07-23 05:12:39553
[email protected]6ea7b152011-12-21 21:21:13554 int server_ret = server_socket_->Handshake(handshake_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04555 ASSERT_TRUE(server_ret == OK || server_ret == ERR_IO_PENDING);
[email protected]b0ff3f82011-07-23 05:12:39556
[email protected]fa6ce922014-07-17 04:27:04557 if (client_ret == ERR_IO_PENDING) {
558 ASSERT_EQ(OK, connect_callback.WaitForResult());
[email protected]b0ff3f82011-07-23 05:12:39559 }
[email protected]fa6ce922014-07-17 04:27:04560 if (server_ret == ERR_IO_PENDING) {
561 ASSERT_EQ(OK, handshake_callback.WaitForResult());
[email protected]b0ff3f82011-07-23 05:12:39562 }
563
564 const int kKeyingMaterialSize = 32;
thestig9d3bb0c2015-01-24 00:49:51565 const char kKeyingLabel[] = "EXPERIMENTAL-server-socket-test";
566 const char kKeyingContext[] = "";
[email protected]b0ff3f82011-07-23 05:12:39567 unsigned char server_out[kKeyingMaterialSize];
[email protected]1bc6f5e2012-03-15 00:20:58568 int rv = server_socket_->ExportKeyingMaterial(kKeyingLabel,
569 false, kKeyingContext,
[email protected]b0ff3f82011-07-23 05:12:39570 server_out, sizeof(server_out));
[email protected]fa6ce922014-07-17 04:27:04571 ASSERT_EQ(OK, rv);
[email protected]b0ff3f82011-07-23 05:12:39572
573 unsigned char client_out[kKeyingMaterialSize];
[email protected]1bc6f5e2012-03-15 00:20:58574 rv = client_socket_->ExportKeyingMaterial(kKeyingLabel,
575 false, kKeyingContext,
[email protected]b0ff3f82011-07-23 05:12:39576 client_out, sizeof(client_out));
[email protected]fa6ce922014-07-17 04:27:04577 ASSERT_EQ(OK, rv);
[email protected]47a12862012-04-10 01:00:49578 EXPECT_EQ(0, memcmp(server_out, client_out, sizeof(server_out)));
[email protected]b0ff3f82011-07-23 05:12:39579
thestig9d3bb0c2015-01-24 00:49:51580 const char kKeyingLabelBad[] = "EXPERIMENTAL-server-socket-test-bad";
[email protected]b0ff3f82011-07-23 05:12:39581 unsigned char client_bad[kKeyingMaterialSize];
[email protected]1bc6f5e2012-03-15 00:20:58582 rv = client_socket_->ExportKeyingMaterial(kKeyingLabelBad,
583 false, kKeyingContext,
[email protected]b0ff3f82011-07-23 05:12:39584 client_bad, sizeof(client_bad));
[email protected]fa6ce922014-07-17 04:27:04585 ASSERT_EQ(rv, OK);
[email protected]47a12862012-04-10 01:00:49586 EXPECT_NE(0, memcmp(server_out, client_bad, sizeof(server_out)));
[email protected]b0ff3f82011-07-23 05:12:39587}
[email protected]f61c3972010-12-23 09:54:15588
589} // namespace net