blob: 9a2dd9cadd6ee38e6b529d970874643ce4f6a824 [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
ryanchung987b2ff2016-02-19 00:17:1223#include "base/callback_helpers.h"
[email protected]55ee0e52011-07-21 18:29:4424#include "base/compiler_specific.h"
[email protected]57999812013-02-24 05:40:5225#include "base/files/file_path.h"
thestigd8df0332014-09-04 06:33:2926#include "base/files/file_util.h"
skyostil4891b25b2015-06-11 11:43:4527#include "base/location.h"
tbansalf82cc8e2015-10-14 20:05:4928#include "base/logging.h"
Avi Drissman13fc8932015-12-20 04:40:4629#include "base/macros.h"
[email protected]18b577412013-07-18 04:19:1530#include "base/message_loop/message_loop.h"
skyostil4891b25b2015-06-11 11:43:4531#include "base/single_thread_task_runner.h"
32#include "base/thread_task_runner_handle.h"
ryanchung987b2ff2016-02-19 00:17:1233#include "build/build_config.h"
[email protected]4b559b4d2011-04-14 17:37:1434#include "crypto/nss_util.h"
35#include "crypto/rsa_private_key.h"
ryanchung987b2ff2016-02-19 00:17:1236#include "crypto/scoped_openssl_types.h"
37#include "crypto/signature_creator.h"
[email protected]f61c3972010-12-23 09:54:1538#include "net/base/address_list.h"
[email protected]6ea7b152011-12-21 21:21:1339#include "net/base/completion_callback.h"
[email protected]f61c3972010-12-23 09:54:1540#include "net/base/host_port_pair.h"
41#include "net/base/io_buffer.h"
[email protected]e7f74da2011-04-19 23:49:3542#include "net/base/ip_endpoint.h"
[email protected]f61c3972010-12-23 09:54:1543#include "net/base/net_errors.h"
[email protected]42fdb452012-11-01 12:44:4044#include "net/base/test_data_directory.h"
[email protected]6e7845ae2013-03-29 21:48:1145#include "net/cert/cert_status_flags.h"
46#include "net/cert/mock_cert_verifier.h"
ryanchung987b2ff2016-02-19 00:17:1247#include "net/cert/mock_client_cert_verifier.h"
[email protected]6e7845ae2013-03-29 21:48:1148#include "net/cert/x509_certificate.h"
[email protected]b1c988b2013-06-13 06:48:1149#include "net/http/transport_security_state.h"
eroman87c53d62015-04-02 06:51:0750#include "net/log/net_log.h"
[email protected]f61c3972010-12-23 09:54:1551#include "net/socket/client_socket_factory.h"
52#include "net/socket/socket_test_util.h"
53#include "net/socket/ssl_client_socket.h"
[email protected]3268023f2011-05-05 00:08:1054#include "net/socket/stream_socket.h"
ryanchung987b2ff2016-02-19 00:17:1255#include "net/ssl/scoped_openssl_types.h"
56#include "net/ssl/ssl_cert_request_info.h"
davidben9dd84872015-05-02 00:22:5857#include "net/ssl/ssl_cipher_suite_names.h"
davidben9dd84872015-05-02 00:22:5858#include "net/ssl/ssl_connection_status_flags.h"
[email protected]536fd0b2013-03-14 17:41:5759#include "net/ssl/ssl_info.h"
ryanchung987b2ff2016-02-19 00:17:1260#include "net/ssl/ssl_private_key.h"
svaldez6e7e82a22015-10-28 19:39:5361#include "net/ssl/ssl_server_config.h"
ryanchung987b2ff2016-02-19 00:17:1262#include "net/ssl/test_ssl_private_key.h"
[email protected]6e7845ae2013-03-29 21:48:1163#include "net/test/cert_test_util.h"
[email protected]f61c3972010-12-23 09:54:1564#include "testing/gtest/include/gtest/gtest.h"
65#include "testing/platform_test.h"
66
ryanchung987b2ff2016-02-19 00:17:1267#if defined(USE_OPENSSL)
68#include <openssl/evp.h>
69#include <openssl/ssl.h>
70#include <openssl/x509.h>
71#endif
72
[email protected]f61c3972010-12-23 09:54:1573namespace net {
74
75namespace {
76
ryanchung987b2ff2016-02-19 00:17:1277const char kClientCertFileName[] = "client_1.pem";
78const char kClientPrivateKeyFileName[] = "client_1.pk8";
79const char kWrongClientCertFileName[] = "client_2.pem";
80const char kWrongClientPrivateKeyFileName[] = "client_2.pk8";
81const char kClientCertCAFileName[] = "client_1_ca.pem";
82
[email protected]f61c3972010-12-23 09:54:1583class FakeDataChannel {
84 public:
[email protected]55ee0e52011-07-21 18:29:4485 FakeDataChannel()
[email protected]83039bb2011-12-09 18:43:5586 : read_buf_len_(0),
[email protected]c0e4dd12012-05-16 19:36:3187 closed_(false),
[email protected]d5492c52013-11-10 20:44:3988 write_called_after_close_(false),
89 weak_factory_(this) {
[email protected]f61c3972010-12-23 09:54:1590 }
91
[email protected]47a12862012-04-10 01:00:4992 int Read(IOBuffer* buf, int buf_len, const CompletionCallback& callback) {
[email protected]4da82282014-07-16 18:40:4393 DCHECK(read_callback_.is_null());
dcheng08ea2af02014-08-25 23:38:0994 DCHECK(!read_buf_.get());
[email protected]c0e4dd12012-05-16 19:36:3195 if (closed_)
96 return 0;
[email protected]3f55aa12011-12-07 02:03:3397 if (data_.empty()) {
[email protected]f61c3972010-12-23 09:54:1598 read_callback_ = callback;
99 read_buf_ = buf;
100 read_buf_len_ = buf_len;
[email protected]fa6ce922014-07-17 04:27:04101 return ERR_IO_PENDING;
[email protected]f61c3972010-12-23 09:54:15102 }
tfarina9b6381442015-10-05 22:38:11103 return PropagateData(buf, buf_len);
[email protected]f61c3972010-12-23 09:54:15104 }
105
[email protected]47a12862012-04-10 01:00:49106 int Write(IOBuffer* buf, int buf_len, const CompletionCallback& callback) {
[email protected]4da82282014-07-16 18:40:43107 DCHECK(write_callback_.is_null());
[email protected]c0e4dd12012-05-16 19:36:31108 if (closed_) {
109 if (write_called_after_close_)
[email protected]fa6ce922014-07-17 04:27:04110 return ERR_CONNECTION_RESET;
[email protected]c0e4dd12012-05-16 19:36:31111 write_called_after_close_ = true;
112 write_callback_ = callback;
skyostil4891b25b2015-06-11 11:43:45113 base::ThreadTaskRunnerHandle::Get()->PostTask(
[email protected]c0e4dd12012-05-16 19:36:31114 FROM_HERE, base::Bind(&FakeDataChannel::DoWriteCallback,
115 weak_factory_.GetWeakPtr()));
[email protected]fa6ce922014-07-17 04:27:04116 return ERR_IO_PENDING;
[email protected]c0e4dd12012-05-16 19:36:31117 }
[email protected]4da82282014-07-16 18:40:43118 // This function returns synchronously, so make a copy of the buffer.
[email protected]fa6ce922014-07-17 04:27:04119 data_.push(new DrainableIOBuffer(
120 new StringIOBuffer(std::string(buf->data(), buf_len)),
[email protected]4da82282014-07-16 18:40:43121 buf_len));
skyostil4891b25b2015-06-11 11:43:45122 base::ThreadTaskRunnerHandle::Get()->PostTask(
[email protected]83039bb2011-12-09 18:43:55123 FROM_HERE, base::Bind(&FakeDataChannel::DoReadCallback,
124 weak_factory_.GetWeakPtr()));
[email protected]f61c3972010-12-23 09:54:15125 return buf_len;
126 }
127
[email protected]c0e4dd12012-05-16 19:36:31128 // Closes the FakeDataChannel. After Close() is called, Read() returns 0,
129 // indicating EOF, and Write() fails with ERR_CONNECTION_RESET. Note that
130 // after the FakeDataChannel is closed, the first Write() call completes
131 // asynchronously, which is necessary to reproduce bug 127822.
132 void Close() {
133 closed_ = true;
ryanchung987b2ff2016-02-19 00:17:12134 if (!read_callback_.is_null()) {
135 base::ThreadTaskRunnerHandle::Get()->PostTask(
136 FROM_HERE, base::Bind(&FakeDataChannel::DoReadCallback,
137 weak_factory_.GetWeakPtr()));
138 }
[email protected]c0e4dd12012-05-16 19:36:31139 }
140
[email protected]f61c3972010-12-23 09:54:15141 private:
142 void DoReadCallback() {
ryanchung987b2ff2016-02-19 00:17:12143 if (read_callback_.is_null())
144 return;
145
146 if (closed_) {
147 base::ResetAndReturn(&read_callback_).Run(ERR_CONNECTION_CLOSED);
148 return;
149 }
150
151 if (data_.empty())
[email protected]f61c3972010-12-23 09:54:15152 return;
153
tfarina9b6381442015-10-05 22:38:11154 int copied = PropagateData(read_buf_, read_buf_len_);
[email protected]83039bb2011-12-09 18:43:55155 CompletionCallback callback = read_callback_;
156 read_callback_.Reset();
157 read_buf_ = NULL;
158 read_buf_len_ = 0;
159 callback.Run(copied);
[email protected]f61c3972010-12-23 09:54:15160 }
161
[email protected]c0e4dd12012-05-16 19:36:31162 void DoWriteCallback() {
163 if (write_callback_.is_null())
164 return;
165
166 CompletionCallback callback = write_callback_;
167 write_callback_.Reset();
[email protected]fa6ce922014-07-17 04:27:04168 callback.Run(ERR_CONNECTION_RESET);
[email protected]c0e4dd12012-05-16 19:36:31169 }
170
tfarina9b6381442015-10-05 22:38:11171 int PropagateData(scoped_refptr<IOBuffer> read_buf, int read_buf_len) {
[email protected]fa6ce922014-07-17 04:27:04172 scoped_refptr<DrainableIOBuffer> buf = data_.front();
[email protected]f61c3972010-12-23 09:54:15173 int copied = std::min(buf->BytesRemaining(), read_buf_len);
174 memcpy(read_buf->data(), buf->data(), copied);
175 buf->DidConsume(copied);
176
177 if (!buf->BytesRemaining())
178 data_.pop();
179 return copied;
180 }
181
[email protected]83039bb2011-12-09 18:43:55182 CompletionCallback read_callback_;
[email protected]fa6ce922014-07-17 04:27:04183 scoped_refptr<IOBuffer> read_buf_;
[email protected]f61c3972010-12-23 09:54:15184 int read_buf_len_;
185
[email protected]c0e4dd12012-05-16 19:36:31186 CompletionCallback write_callback_;
187
[email protected]fa6ce922014-07-17 04:27:04188 std::queue<scoped_refptr<DrainableIOBuffer> > data_;
[email protected]f61c3972010-12-23 09:54:15189
[email protected]c0e4dd12012-05-16 19:36:31190 // True if Close() has been called.
191 bool closed_;
192
193 // Controls the completion of Write() after the FakeDataChannel is closed.
194 // After the FakeDataChannel is closed, the first Write() call completes
195 // asynchronously.
196 bool write_called_after_close_;
197
[email protected]d5492c52013-11-10 20:44:39198 base::WeakPtrFactory<FakeDataChannel> weak_factory_;
199
[email protected]f61c3972010-12-23 09:54:15200 DISALLOW_COPY_AND_ASSIGN(FakeDataChannel);
201};
202
[email protected]3268023f2011-05-05 00:08:10203class FakeSocket : public StreamSocket {
[email protected]f61c3972010-12-23 09:54:15204 public:
205 FakeSocket(FakeDataChannel* incoming_channel,
206 FakeDataChannel* outgoing_channel)
207 : incoming_(incoming_channel),
208 outgoing_(outgoing_channel) {
209 }
210
dchengb03027d2014-10-21 12:00:20211 ~FakeSocket() override {}
[email protected]f61c3972010-12-23 09:54:15212
dchengb03027d2014-10-21 12:00:20213 int Read(IOBuffer* buf,
214 int buf_len,
215 const CompletionCallback& callback) override {
[email protected]3f55aa12011-12-07 02:03:33216 // Read random number of bytes.
217 buf_len = rand() % buf_len + 1;
218 return incoming_->Read(buf, buf_len, callback);
219 }
[email protected]f61c3972010-12-23 09:54:15220
dchengb03027d2014-10-21 12:00:20221 int Write(IOBuffer* buf,
222 int buf_len,
223 const CompletionCallback& callback) override {
[email protected]55ee0e52011-07-21 18:29:44224 // Write random number of bytes.
225 buf_len = rand() % buf_len + 1;
[email protected]f61c3972010-12-23 09:54:15226 return outgoing_->Write(buf, buf_len, callback);
227 }
228
Avi Drissman13fc8932015-12-20 04:40:46229 int SetReceiveBufferSize(int32_t size) override { return OK; }
[email protected]f61c3972010-12-23 09:54:15230
Avi Drissman13fc8932015-12-20 04:40:46231 int SetSendBufferSize(int32_t size) override { return OK; }
[email protected]f61c3972010-12-23 09:54:15232
dchengb03027d2014-10-21 12:00:20233 int Connect(const CompletionCallback& callback) override { return OK; }
[email protected]f61c3972010-12-23 09:54:15234
dchengb03027d2014-10-21 12:00:20235 void Disconnect() override {
[email protected]c0e4dd12012-05-16 19:36:31236 incoming_->Close();
237 outgoing_->Close();
238 }
[email protected]f61c3972010-12-23 09:54:15239
dchengb03027d2014-10-21 12:00:20240 bool IsConnected() const override { return true; }
[email protected]f61c3972010-12-23 09:54:15241
dchengb03027d2014-10-21 12:00:20242 bool IsConnectedAndIdle() const override { return true; }
[email protected]f61c3972010-12-23 09:54:15243
dchengb03027d2014-10-21 12:00:20244 int GetPeerAddress(IPEndPoint* address) const override {
[email protected]fa6ce922014-07-17 04:27:04245 IPAddressNumber ip_address(kIPv4AddressSize);
246 *address = IPEndPoint(ip_address, 0 /*port*/);
247 return OK;
[email protected]f61c3972010-12-23 09:54:15248 }
249
dchengb03027d2014-10-21 12:00:20250 int GetLocalAddress(IPEndPoint* address) const override {
[email protected]fa6ce922014-07-17 04:27:04251 IPAddressNumber ip_address(4);
252 *address = IPEndPoint(ip_address, 0);
253 return OK;
[email protected]e7f74da2011-04-19 23:49:35254 }
255
dchengb03027d2014-10-21 12:00:20256 const BoundNetLog& NetLog() const override { return net_log_; }
[email protected]f61c3972010-12-23 09:54:15257
dchengb03027d2014-10-21 12:00:20258 void SetSubresourceSpeculation() override {}
259 void SetOmniboxSpeculation() override {}
[email protected]f61c3972010-12-23 09:54:15260
dchengb03027d2014-10-21 12:00:20261 bool WasEverUsed() const override { return true; }
[email protected]f61c3972010-12-23 09:54:15262
dchengb03027d2014-10-21 12:00:20263 bool UsingTCPFastOpen() const override { return false; }
[email protected]f61c3972010-12-23 09:54:15264
dchengb03027d2014-10-21 12:00:20265 bool WasNpnNegotiated() const override { return false; }
[email protected]5e6efa52011-06-27 17:26:41266
dchengb03027d2014-10-21 12:00:20267 NextProto GetNegotiatedProtocol() const override { return kProtoUnknown; }
[email protected]2d88e7d2012-07-19 17:55:17268
dchengb03027d2014-10-21 12:00:20269 bool GetSSLInfo(SSLInfo* ssl_info) override { return false; }
[email protected]2d88e7d2012-07-19 17:55:17270
ttuttle23fdb7b2015-05-15 01:28:03271 void GetConnectionAttempts(ConnectionAttempts* out) const override {
272 out->clear();
273 }
274
275 void ClearConnectionAttempts() override {}
276
277 void AddConnectionAttempts(const ConnectionAttempts& attempts) override {}
278
tbansalf82cc8e2015-10-14 20:05:49279 int64_t GetTotalReceivedBytes() const override {
280 NOTIMPLEMENTED();
281 return 0;
282 }
283
[email protected]f61c3972010-12-23 09:54:15284 private:
[email protected]fa6ce922014-07-17 04:27:04285 BoundNetLog net_log_;
[email protected]f61c3972010-12-23 09:54:15286 FakeDataChannel* incoming_;
287 FakeDataChannel* outgoing_;
288
289 DISALLOW_COPY_AND_ASSIGN(FakeSocket);
290};
291
292} // namespace
293
294// Verify the correctness of the test helper classes first.
295TEST(FakeSocketTest, DataTransfer) {
296 // Establish channels between two sockets.
297 FakeDataChannel channel_1;
298 FakeDataChannel channel_2;
299 FakeSocket client(&channel_1, &channel_2);
300 FakeSocket server(&channel_2, &channel_1);
301
302 const char kTestData[] = "testing123";
303 const int kTestDataSize = strlen(kTestData);
304 const int kReadBufSize = 1024;
[email protected]fa6ce922014-07-17 04:27:04305 scoped_refptr<IOBuffer> write_buf = new StringIOBuffer(kTestData);
306 scoped_refptr<IOBuffer> read_buf = new IOBuffer(kReadBufSize);
[email protected]f61c3972010-12-23 09:54:15307
308 // Write then read.
[email protected]90499482013-06-01 00:39:50309 int written =
310 server.Write(write_buf.get(), kTestDataSize, CompletionCallback());
[email protected]55ee0e52011-07-21 18:29:44311 EXPECT_GT(written, 0);
312 EXPECT_LE(written, kTestDataSize);
313
[email protected]90499482013-06-01 00:39:50314 int read = client.Read(read_buf.get(), kReadBufSize, CompletionCallback());
[email protected]55ee0e52011-07-21 18:29:44315 EXPECT_GT(read, 0);
316 EXPECT_LE(read, written);
317 EXPECT_EQ(0, memcmp(kTestData, read_buf->data(), read));
[email protected]f61c3972010-12-23 09:54:15318
319 // Read then write.
[email protected]83039bb2011-12-09 18:43:55320 TestCompletionCallback callback;
[email protected]fa6ce922014-07-17 04:27:04321 EXPECT_EQ(ERR_IO_PENDING,
[email protected]90499482013-06-01 00:39:50322 server.Read(read_buf.get(), kReadBufSize, callback.callback()));
[email protected]55ee0e52011-07-21 18:29:44323
[email protected]90499482013-06-01 00:39:50324 written = client.Write(write_buf.get(), kTestDataSize, CompletionCallback());
[email protected]55ee0e52011-07-21 18:29:44325 EXPECT_GT(written, 0);
326 EXPECT_LE(written, kTestDataSize);
327
328 read = callback.WaitForResult();
329 EXPECT_GT(read, 0);
330 EXPECT_LE(read, written);
331 EXPECT_EQ(0, memcmp(kTestData, read_buf->data(), read));
[email protected]f61c3972010-12-23 09:54:15332}
333
334class SSLServerSocketTest : public PlatformTest {
335 public:
336 SSLServerSocketTest()
[email protected]fa6ce922014-07-17 04:27:04337 : socket_factory_(ClientSocketFactory::GetDefaultFactory()),
[email protected]b1c988b2013-06-13 06:48:11338 cert_verifier_(new MockCertVerifier()),
ryanchung987b2ff2016-02-19 00:17:12339 client_cert_verifier_(new MockClientCertVerifier()),
[email protected]b1c988b2013-06-13 06:48:11340 transport_security_state_(new TransportSecurityState) {
ryanchung987b2ff2016-02-19 00:17:12341 cert_verifier_->set_default_result(ERR_CERT_AUTHORITY_INVALID);
342 client_cert_verifier_->set_default_result(ERR_CERT_AUTHORITY_INVALID);
[email protected]f61c3972010-12-23 09:54:15343 }
344
345 protected:
346 void Initialize() {
[email protected]18ccfdb2013-08-15 00:13:44347 scoped_ptr<ClientSocketHandle> client_connection(new ClientSocketHandle);
348 client_connection->SetSocket(
349 scoped_ptr<StreamSocket>(new FakeSocket(&channel_1_, &channel_2_)));
350 scoped_ptr<StreamSocket> server_socket(
351 new FakeSocket(&channel_2_, &channel_1_));
[email protected]f61c3972010-12-23 09:54:15352
ryanchung987b2ff2016-02-19 00:17:12353 scoped_refptr<X509Certificate> server_cert(
354 ImportCertFromFile(GetTestCertsDirectory(), "unittest.selfsigned.der"));
355 scoped_ptr<crypto::RSAPrivateKey> server_private_key(
356 ReadTestKey("unittest.key.bin"));
[email protected]f61c3972010-12-23 09:54:15357
sergeyuff826d5e2015-05-13 20:35:22358 client_ssl_config_.false_start_enabled = false;
359 client_ssl_config_.channel_id_enabled = false;
[email protected]f61c3972010-12-23 09:54:15360
361 // Certificate provided by the host doesn't need authority.
[email protected]fa6ce922014-07-17 04:27:04362 SSLConfig::CertAndStatus cert_and_status;
[email protected]4dc832e2011-04-28 22:04:24363 cert_and_status.cert_status = CERT_STATUS_AUTHORITY_INVALID;
ryanchung987b2ff2016-02-19 00:17:12364 std::string server_cert_der;
365 CHECK(X509Certificate::GetDEREncoded(server_cert->os_cert_handle(),
366 &server_cert_der));
367 cert_and_status.der_cert = server_cert_der;
sergeyuff826d5e2015-05-13 20:35:22368 client_ssl_config_.allowed_bad_certs.push_back(cert_and_status);
[email protected]f61c3972010-12-23 09:54:15369
[email protected]fa6ce922014-07-17 04:27:04370 HostPortPair host_and_pair("unittest", 0);
371 SSLClientSocketContext context;
[email protected]9f59fac2012-03-21 23:18:11372 context.cert_verifier = cert_verifier_.get();
[email protected]b1c988b2013-06-13 06:48:11373 context.transport_security_state = transport_security_state_.get();
ryanchung987b2ff2016-02-19 00:17:12374 socket_factory_->ClearSSLSessionCache();
sergeyuff826d5e2015-05-13 20:35:22375 client_socket_ = socket_factory_->CreateSSLClientSocket(
dchengc7eeda422015-12-26 03:56:48376 std::move(client_connection), host_and_pair, client_ssl_config_,
377 context);
ryanchung987b2ff2016-02-19 00:17:12378 server_socket_ =
379 CreateSSLServerSocket(std::move(server_socket), server_cert.get(),
380 *server_private_key, server_ssl_config_);
[email protected]f61c3972010-12-23 09:54:15381 }
382
ryanchung987b2ff2016-02-19 00:17:12383#if defined(USE_OPENSSL)
384 void ConfigureClientCertsForClient(const char* cert_file_name,
385 const char* private_key_file_name) {
386 client_ssl_config_.send_client_cert = true;
387 client_ssl_config_.client_cert =
388 ImportCertFromFile(GetTestCertsDirectory(), cert_file_name);
389 ASSERT_TRUE(client_ssl_config_.client_cert);
390 scoped_ptr<crypto::RSAPrivateKey> key = ReadTestKey(private_key_file_name);
391 ASSERT_TRUE(key);
392 client_ssl_config_.client_private_key = WrapOpenSSLPrivateKey(
393 crypto::ScopedEVP_PKEY(EVP_PKEY_up_ref(key->key())));
394 }
395
396 void ConfigureClientCertsForServer() {
397 server_ssl_config_.client_cert_type =
398 SSLServerConfig::ClientCertType::REQUIRE_CLIENT_CERT;
399
400 ScopedX509NameStack cert_names(
401 SSL_load_client_CA_file(GetTestCertsDirectory()
402 .AppendASCII(kClientCertCAFileName)
403 .MaybeAsASCII()
404 .c_str()));
405 ASSERT_TRUE(cert_names);
406 for (size_t i = 0; i < sk_X509_NAME_num(cert_names.get()); ++i) {
407 uint8_t* str = nullptr;
408 int length = i2d_X509_NAME(sk_X509_NAME_value(cert_names.get(), i), &str);
409 server_ssl_config_.cert_authorities_.push_back(std::string(
410 reinterpret_cast<const char*>(str), static_cast<size_t>(length)));
411 OPENSSL_free(str);
412 }
413
414 scoped_refptr<X509Certificate> expected_client_cert(
415 ImportCertFromFile(GetTestCertsDirectory(), kClientCertFileName));
416 client_cert_verifier_->AddResultForCert(expected_client_cert.get(), OK);
417
418 server_ssl_config_.client_cert_verifier = client_cert_verifier_.get();
419 }
420
421 scoped_ptr<crypto::RSAPrivateKey> ReadTestKey(const base::StringPiece& name) {
422 base::FilePath certs_dir(GetTestCertsDirectory());
423 base::FilePath key_path = certs_dir.AppendASCII(name);
424 std::string key_string;
425 if (!base::ReadFileToString(key_path, &key_string))
426 return nullptr;
427 std::vector<uint8_t> key_vector(
428 reinterpret_cast<const uint8_t*>(key_string.data()),
429 reinterpret_cast<const uint8_t*>(key_string.data() +
430 key_string.length()));
431 scoped_ptr<crypto::RSAPrivateKey> key(
432 crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(key_vector));
433 return key;
434 }
435#endif
436
[email protected]f61c3972010-12-23 09:54:15437 FakeDataChannel channel_1_;
438 FakeDataChannel channel_2_;
sergeyuff826d5e2015-05-13 20:35:22439 SSLConfig client_ssl_config_;
svaldez6e7e82a22015-10-28 19:39:53440 SSLServerConfig server_ssl_config_;
[email protected]fa6ce922014-07-17 04:27:04441 scoped_ptr<SSLClientSocket> client_socket_;
442 scoped_ptr<SSLServerSocket> server_socket_;
443 ClientSocketFactory* socket_factory_;
444 scoped_ptr<MockCertVerifier> cert_verifier_;
ryanchung987b2ff2016-02-19 00:17:12445 scoped_ptr<MockClientCertVerifier> client_cert_verifier_;
[email protected]fa6ce922014-07-17 04:27:04446 scoped_ptr<TransportSecurityState> transport_security_state_;
[email protected]f61c3972010-12-23 09:54:15447};
448
[email protected]f61c3972010-12-23 09:54:15449// This test only executes creation of client and server sockets. This is to
450// test that creation of sockets doesn't crash and have minimal code to run
451// under valgrind in order to help debugging memory problems.
452TEST_F(SSLServerSocketTest, Initialize) {
453 Initialize();
454}
455
[email protected]a7ac3c32011-06-17 19:10:15456// This test executes Connect() on SSLClientSocket and Handshake() on
457// SSLServerSocket to make sure handshaking between the two sockets is
[email protected]f61c3972010-12-23 09:54:15458// completed successfully.
459TEST_F(SSLServerSocketTest, Handshake) {
460 Initialize();
461
[email protected]6ea7b152011-12-21 21:21:13462 TestCompletionCallback handshake_callback;
[email protected]6ea7b152011-12-21 21:21:13463 int server_ret = server_socket_->Handshake(handshake_callback.callback());
[email protected]f61c3972010-12-23 09:54:15464
ryanchung987b2ff2016-02-19 00:17:12465 TestCompletionCallback connect_callback;
[email protected]83039bb2011-12-09 18:43:55466 int client_ret = client_socket_->Connect(connect_callback.callback());
[email protected]f61c3972010-12-23 09:54:15467
ryanchung987b2ff2016-02-19 00:17:12468 client_ret = connect_callback.GetResult(client_ret);
469 server_ret = handshake_callback.GetResult(server_ret);
470
471 ASSERT_EQ(OK, client_ret);
472 ASSERT_EQ(OK, server_ret);
[email protected]4dc832e2011-04-28 22:04:24473
474 // Make sure the cert status is expected.
475 SSLInfo ssl_info;
davidben9dd84872015-05-02 00:22:58476 ASSERT_TRUE(client_socket_->GetSSLInfo(&ssl_info));
[email protected]4dc832e2011-04-28 22:04:24477 EXPECT_EQ(CERT_STATUS_AUTHORITY_INVALID, ssl_info.cert_status);
davidben9dd84872015-05-02 00:22:58478
479 // The default cipher suite should be ECDHE and, unless on NSS and the
480 // platform doesn't support it, an AEAD.
481 uint16_t cipher_suite =
482 SSLConnectionStatusToCipherSuite(ssl_info.connection_status);
483 const char* key_exchange;
484 const char* cipher;
485 const char* mac;
486 bool is_aead;
487 SSLCipherSuiteToStrings(&key_exchange, &cipher, &mac, &is_aead, cipher_suite);
488 EXPECT_STREQ("ECDHE_RSA", key_exchange);
davidben6cacd572015-09-29 22:24:10489 EXPECT_TRUE(is_aead);
[email protected]f61c3972010-12-23 09:54:15490}
491
ryanchung987b2ff2016-02-19 00:17:12492// NSS ports don't support client certificates.
493#if defined(USE_OPENSSL)
494
495// This test executes Connect() on SSLClientSocket and Handshake() on
496// SSLServerSocket to make sure handshaking between the two sockets is
497// completed successfully, using client certificate.
498TEST_F(SSLServerSocketTest, HandshakeWithClientCert) {
499 scoped_refptr<X509Certificate> client_cert =
500 ImportCertFromFile(GetTestCertsDirectory(), kClientCertFileName);
501 ConfigureClientCertsForClient(kClientCertFileName, kClientPrivateKeyFileName);
502 ConfigureClientCertsForServer();
503 Initialize();
504
505 TestCompletionCallback handshake_callback;
506 int server_ret = server_socket_->Handshake(handshake_callback.callback());
507
508 TestCompletionCallback connect_callback;
509 int client_ret = client_socket_->Connect(connect_callback.callback());
510
511 client_ret = connect_callback.GetResult(client_ret);
512 server_ret = handshake_callback.GetResult(server_ret);
513
514 ASSERT_EQ(OK, client_ret);
515 ASSERT_EQ(OK, server_ret);
516
517 // Make sure the cert status is expected.
518 SSLInfo ssl_info;
519 client_socket_->GetSSLInfo(&ssl_info);
520 EXPECT_EQ(CERT_STATUS_AUTHORITY_INVALID, ssl_info.cert_status);
521 server_socket_->GetSSLInfo(&ssl_info);
522 EXPECT_TRUE(ssl_info.cert.get());
523 EXPECT_TRUE(client_cert->Equals(ssl_info.cert.get()));
524}
525
526TEST_F(SSLServerSocketTest, HandshakeWithClientCertRequiredNotSupplied) {
527 ConfigureClientCertsForServer();
528 Initialize();
529 // Use the default setting for the client socket, which is to not send
530 // a client certificate. This will cause the client to receive an
531 // ERR_SSL_CLIENT_AUTH_CERT_NEEDED error, and allow for inspecting the
532 // requested cert_authorities from the CertificateRequest sent by the
533 // server.
534
535 TestCompletionCallback handshake_callback;
536 int server_ret = server_socket_->Handshake(handshake_callback.callback());
537
538 TestCompletionCallback connect_callback;
539 EXPECT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED,
540 connect_callback.GetResult(
541 client_socket_->Connect(connect_callback.callback())));
542
543 scoped_refptr<SSLCertRequestInfo> request_info = new SSLCertRequestInfo();
544 client_socket_->GetSSLCertRequestInfo(request_info.get());
545
546 // Check that the authority name that arrived in the CertificateRequest
547 // handshake message is as expected.
548 scoped_refptr<X509Certificate> client_cert =
549 ImportCertFromFile(GetTestCertsDirectory(), kClientCertFileName);
550 EXPECT_TRUE(client_cert->IsIssuedByEncoded(request_info->cert_authorities));
551
552 client_socket_->Disconnect();
553
554 EXPECT_EQ(ERR_FAILED, handshake_callback.GetResult(server_ret));
555}
556
557TEST_F(SSLServerSocketTest, HandshakeWithWrongClientCertSupplied) {
558 scoped_refptr<X509Certificate> client_cert =
559 ImportCertFromFile(GetTestCertsDirectory(), kClientCertFileName);
560 ConfigureClientCertsForClient(kWrongClientCertFileName,
561 kWrongClientPrivateKeyFileName);
562 ConfigureClientCertsForServer();
563 Initialize();
564
565 TestCompletionCallback handshake_callback;
566 int server_ret = server_socket_->Handshake(handshake_callback.callback());
567
568 TestCompletionCallback connect_callback;
569 int client_ret = client_socket_->Connect(connect_callback.callback());
570
571 EXPECT_EQ(ERR_BAD_SSL_CLIENT_AUTH_CERT,
572 connect_callback.GetResult(client_ret));
573 EXPECT_EQ(ERR_BAD_SSL_CLIENT_AUTH_CERT,
574 handshake_callback.GetResult(server_ret));
575}
576#endif // defined(USE_OPENSSL)
577
[email protected]f61c3972010-12-23 09:54:15578TEST_F(SSLServerSocketTest, DataTransfer) {
579 Initialize();
580
[email protected]f61c3972010-12-23 09:54:15581 // Establish connection.
ryanchung987b2ff2016-02-19 00:17:12582 TestCompletionCallback connect_callback;
[email protected]83039bb2011-12-09 18:43:55583 int client_ret = client_socket_->Connect(connect_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04584 ASSERT_TRUE(client_ret == OK || client_ret == ERR_IO_PENDING);
[email protected]f61c3972010-12-23 09:54:15585
ryanchung987b2ff2016-02-19 00:17:12586 TestCompletionCallback handshake_callback;
[email protected]6ea7b152011-12-21 21:21:13587 int server_ret = server_socket_->Handshake(handshake_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04588 ASSERT_TRUE(server_ret == OK || server_ret == ERR_IO_PENDING);
[email protected]f61c3972010-12-23 09:54:15589
[email protected]febbbb52011-08-17 04:59:23590 client_ret = connect_callback.GetResult(client_ret);
[email protected]fa6ce922014-07-17 04:27:04591 ASSERT_EQ(OK, client_ret);
[email protected]febbbb52011-08-17 04:59:23592 server_ret = handshake_callback.GetResult(server_ret);
[email protected]fa6ce922014-07-17 04:27:04593 ASSERT_EQ(OK, server_ret);
[email protected]f61c3972010-12-23 09:54:15594
595 const int kReadBufSize = 1024;
[email protected]fa6ce922014-07-17 04:27:04596 scoped_refptr<StringIOBuffer> write_buf =
597 new StringIOBuffer("testing123");
598 scoped_refptr<DrainableIOBuffer> read_buf =
599 new DrainableIOBuffer(new IOBuffer(kReadBufSize), kReadBufSize);
[email protected]f61c3972010-12-23 09:54:15600
601 // Write then read.
[email protected]83039bb2011-12-09 18:43:55602 TestCompletionCallback write_callback;
603 TestCompletionCallback read_callback;
[email protected]90499482013-06-01 00:39:50604 server_ret = server_socket_->Write(
605 write_buf.get(), write_buf->size(), write_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04606 EXPECT_TRUE(server_ret > 0 || server_ret == ERR_IO_PENDING);
[email protected]90499482013-06-01 00:39:50607 client_ret = client_socket_->Read(
608 read_buf.get(), read_buf->BytesRemaining(), read_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04609 EXPECT_TRUE(client_ret > 0 || client_ret == ERR_IO_PENDING);
[email protected]f61c3972010-12-23 09:54:15610
[email protected]febbbb52011-08-17 04:59:23611 server_ret = write_callback.GetResult(server_ret);
612 EXPECT_GT(server_ret, 0);
613 client_ret = read_callback.GetResult(client_ret);
614 ASSERT_GT(client_ret, 0);
615
616 read_buf->DidConsume(client_ret);
617 while (read_buf->BytesConsumed() < write_buf->size()) {
[email protected]90499482013-06-01 00:39:50618 client_ret = client_socket_->Read(
619 read_buf.get(), read_buf->BytesRemaining(), read_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04620 EXPECT_TRUE(client_ret > 0 || client_ret == ERR_IO_PENDING);
[email protected]febbbb52011-08-17 04:59:23621 client_ret = read_callback.GetResult(client_ret);
622 ASSERT_GT(client_ret, 0);
623 read_buf->DidConsume(client_ret);
[email protected]f61c3972010-12-23 09:54:15624 }
[email protected]febbbb52011-08-17 04:59:23625 EXPECT_EQ(write_buf->size(), read_buf->BytesConsumed());
626 read_buf->SetOffset(0);
[email protected]f61c3972010-12-23 09:54:15627 EXPECT_EQ(0, memcmp(write_buf->data(), read_buf->data(), write_buf->size()));
628
629 // Read then write.
[email protected]fa6ce922014-07-17 04:27:04630 write_buf = new StringIOBuffer("hello123");
[email protected]90499482013-06-01 00:39:50631 server_ret = server_socket_->Read(
632 read_buf.get(), read_buf->BytesRemaining(), read_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04633 EXPECT_TRUE(server_ret > 0 || server_ret == ERR_IO_PENDING);
[email protected]90499482013-06-01 00:39:50634 client_ret = client_socket_->Write(
635 write_buf.get(), write_buf->size(), write_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04636 EXPECT_TRUE(client_ret > 0 || client_ret == ERR_IO_PENDING);
[email protected]f61c3972010-12-23 09:54:15637
[email protected]febbbb52011-08-17 04:59:23638 server_ret = read_callback.GetResult(server_ret);
639 ASSERT_GT(server_ret, 0);
640 client_ret = write_callback.GetResult(client_ret);
641 EXPECT_GT(client_ret, 0);
642
643 read_buf->DidConsume(server_ret);
644 while (read_buf->BytesConsumed() < write_buf->size()) {
[email protected]90499482013-06-01 00:39:50645 server_ret = server_socket_->Read(
646 read_buf.get(), read_buf->BytesRemaining(), read_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04647 EXPECT_TRUE(server_ret > 0 || server_ret == ERR_IO_PENDING);
[email protected]febbbb52011-08-17 04:59:23648 server_ret = read_callback.GetResult(server_ret);
649 ASSERT_GT(server_ret, 0);
650 read_buf->DidConsume(server_ret);
[email protected]f61c3972010-12-23 09:54:15651 }
[email protected]febbbb52011-08-17 04:59:23652 EXPECT_EQ(write_buf->size(), read_buf->BytesConsumed());
653 read_buf->SetOffset(0);
[email protected]f61c3972010-12-23 09:54:15654 EXPECT_EQ(0, memcmp(write_buf->data(), read_buf->data(), write_buf->size()));
655}
[email protected]b0ff3f82011-07-23 05:12:39656
[email protected]c0e4dd12012-05-16 19:36:31657// A regression test for bug 127822 (http://crbug.com/127822).
658// If the server closes the connection after the handshake is finished,
659// the client's Write() call should not cause an infinite loop.
660// NOTE: this is a test for SSLClientSocket rather than SSLServerSocket.
[email protected]4da82282014-07-16 18:40:43661TEST_F(SSLServerSocketTest, ClientWriteAfterServerClose) {
[email protected]c0e4dd12012-05-16 19:36:31662 Initialize();
663
[email protected]c0e4dd12012-05-16 19:36:31664
665 // Establish connection.
ryanchung987b2ff2016-02-19 00:17:12666 TestCompletionCallback connect_callback;
[email protected]c0e4dd12012-05-16 19:36:31667 int client_ret = client_socket_->Connect(connect_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04668 ASSERT_TRUE(client_ret == OK || client_ret == ERR_IO_PENDING);
[email protected]c0e4dd12012-05-16 19:36:31669
ryanchung987b2ff2016-02-19 00:17:12670 TestCompletionCallback handshake_callback;
[email protected]c0e4dd12012-05-16 19:36:31671 int server_ret = server_socket_->Handshake(handshake_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04672 ASSERT_TRUE(server_ret == OK || server_ret == ERR_IO_PENDING);
[email protected]c0e4dd12012-05-16 19:36:31673
674 client_ret = connect_callback.GetResult(client_ret);
[email protected]fa6ce922014-07-17 04:27:04675 ASSERT_EQ(OK, client_ret);
[email protected]c0e4dd12012-05-16 19:36:31676 server_ret = handshake_callback.GetResult(server_ret);
[email protected]fa6ce922014-07-17 04:27:04677 ASSERT_EQ(OK, server_ret);
[email protected]c0e4dd12012-05-16 19:36:31678
[email protected]fa6ce922014-07-17 04:27:04679 scoped_refptr<StringIOBuffer> write_buf = new StringIOBuffer("testing123");
[email protected]c0e4dd12012-05-16 19:36:31680
681 // The server closes the connection. The server needs to write some
682 // data first so that the client's Read() calls from the transport
683 // socket won't return ERR_IO_PENDING. This ensures that the client
684 // will call Read() on the transport socket again.
685 TestCompletionCallback write_callback;
[email protected]90499482013-06-01 00:39:50686 server_ret = server_socket_->Write(
687 write_buf.get(), write_buf->size(), write_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04688 EXPECT_TRUE(server_ret > 0 || server_ret == ERR_IO_PENDING);
[email protected]c0e4dd12012-05-16 19:36:31689
690 server_ret = write_callback.GetResult(server_ret);
691 EXPECT_GT(server_ret, 0);
692
693 server_socket_->Disconnect();
694
695 // The client writes some data. This should not cause an infinite loop.
[email protected]90499482013-06-01 00:39:50696 client_ret = client_socket_->Write(
697 write_buf.get(), write_buf->size(), write_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04698 EXPECT_TRUE(client_ret > 0 || client_ret == ERR_IO_PENDING);
[email protected]c0e4dd12012-05-16 19:36:31699
700 client_ret = write_callback.GetResult(client_ret);
701 EXPECT_GT(client_ret, 0);
702
skyostil4891b25b2015-06-11 11:43:45703 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
ki.stfu375812e2015-10-09 20:23:17704 FROM_HERE, base::MessageLoop::QuitWhenIdleClosure(),
[email protected]c0e4dd12012-05-16 19:36:31705 base::TimeDelta::FromMilliseconds(10));
[email protected]2da659e2013-05-23 20:51:34706 base::MessageLoop::current()->Run();
[email protected]c0e4dd12012-05-16 19:36:31707}
708
[email protected]b0ff3f82011-07-23 05:12:39709// This test executes ExportKeyingMaterial() on the client and server sockets,
710// after connecting them, and verifies that the results match.
711// This test will fail if False Start is enabled (see crbug.com/90208).
712TEST_F(SSLServerSocketTest, ExportKeyingMaterial) {
713 Initialize();
714
[email protected]83039bb2011-12-09 18:43:55715 TestCompletionCallback connect_callback;
[email protected]83039bb2011-12-09 18:43:55716 int client_ret = client_socket_->Connect(connect_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04717 ASSERT_TRUE(client_ret == OK || client_ret == ERR_IO_PENDING);
[email protected]b0ff3f82011-07-23 05:12:39718
ryanchung987b2ff2016-02-19 00:17:12719 TestCompletionCallback handshake_callback;
[email protected]6ea7b152011-12-21 21:21:13720 int server_ret = server_socket_->Handshake(handshake_callback.callback());
[email protected]fa6ce922014-07-17 04:27:04721 ASSERT_TRUE(server_ret == OK || server_ret == ERR_IO_PENDING);
[email protected]b0ff3f82011-07-23 05:12:39722
[email protected]fa6ce922014-07-17 04:27:04723 if (client_ret == ERR_IO_PENDING) {
724 ASSERT_EQ(OK, connect_callback.WaitForResult());
[email protected]b0ff3f82011-07-23 05:12:39725 }
[email protected]fa6ce922014-07-17 04:27:04726 if (server_ret == ERR_IO_PENDING) {
727 ASSERT_EQ(OK, handshake_callback.WaitForResult());
[email protected]b0ff3f82011-07-23 05:12:39728 }
729
730 const int kKeyingMaterialSize = 32;
thestig9d3bb0c2015-01-24 00:49:51731 const char kKeyingLabel[] = "EXPERIMENTAL-server-socket-test";
732 const char kKeyingContext[] = "";
[email protected]b0ff3f82011-07-23 05:12:39733 unsigned char server_out[kKeyingMaterialSize];
[email protected]1bc6f5e2012-03-15 00:20:58734 int rv = server_socket_->ExportKeyingMaterial(kKeyingLabel,
735 false, kKeyingContext,
[email protected]b0ff3f82011-07-23 05:12:39736 server_out, sizeof(server_out));
[email protected]fa6ce922014-07-17 04:27:04737 ASSERT_EQ(OK, rv);
[email protected]b0ff3f82011-07-23 05:12:39738
739 unsigned char client_out[kKeyingMaterialSize];
[email protected]1bc6f5e2012-03-15 00:20:58740 rv = client_socket_->ExportKeyingMaterial(kKeyingLabel,
741 false, kKeyingContext,
[email protected]b0ff3f82011-07-23 05:12:39742 client_out, sizeof(client_out));
[email protected]fa6ce922014-07-17 04:27:04743 ASSERT_EQ(OK, rv);
[email protected]47a12862012-04-10 01:00:49744 EXPECT_EQ(0, memcmp(server_out, client_out, sizeof(server_out)));
[email protected]b0ff3f82011-07-23 05:12:39745
thestig9d3bb0c2015-01-24 00:49:51746 const char kKeyingLabelBad[] = "EXPERIMENTAL-server-socket-test-bad";
[email protected]b0ff3f82011-07-23 05:12:39747 unsigned char client_bad[kKeyingMaterialSize];
[email protected]1bc6f5e2012-03-15 00:20:58748 rv = client_socket_->ExportKeyingMaterial(kKeyingLabelBad,
749 false, kKeyingContext,
[email protected]b0ff3f82011-07-23 05:12:39750 client_bad, sizeof(client_bad));
[email protected]fa6ce922014-07-17 04:27:04751 ASSERT_EQ(rv, OK);
[email protected]47a12862012-04-10 01:00:49752 EXPECT_NE(0, memcmp(server_out, client_bad, sizeof(server_out)));
[email protected]b0ff3f82011-07-23 05:12:39753}
[email protected]f61c3972010-12-23 09:54:15754
sergeyuff826d5e2015-05-13 20:35:22755// Verifies that SSLConfig::require_ecdhe flags works properly.
756TEST_F(SSLServerSocketTest, RequireEcdheFlag) {
757 // Disable all ECDHE suites on the client side.
758 uint16_t kEcdheCiphers[] = {
759 0xc007, // ECDHE_ECDSA_WITH_RC4_128_SHA
760 0xc009, // ECDHE_ECDSA_WITH_AES_128_CBC_SHA
761 0xc00a, // ECDHE_ECDSA_WITH_AES_256_CBC_SHA
762 0xc011, // ECDHE_RSA_WITH_RC4_128_SHA
763 0xc013, // ECDHE_RSA_WITH_AES_128_CBC_SHA
764 0xc014, // ECDHE_RSA_WITH_AES_256_CBC_SHA
765 0xc02b, // ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
766 0xc02f, // ECDHE_RSA_WITH_AES_128_GCM_SHA256
767 0xcc13, // ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
768 0xcc14, // ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
769 };
770 client_ssl_config_.disabled_cipher_suites.assign(
771 kEcdheCiphers, kEcdheCiphers + arraysize(kEcdheCiphers));
772
773 // Require ECDHE on the server.
774 server_ssl_config_.require_ecdhe = true;
775
776 Initialize();
777
778 TestCompletionCallback connect_callback;
sergeyuff826d5e2015-05-13 20:35:22779 int client_ret = client_socket_->Connect(connect_callback.callback());
ryanchung987b2ff2016-02-19 00:17:12780
781 TestCompletionCallback handshake_callback;
sergeyuff826d5e2015-05-13 20:35:22782 int server_ret = server_socket_->Handshake(handshake_callback.callback());
783
784 client_ret = connect_callback.GetResult(client_ret);
785 server_ret = handshake_callback.GetResult(server_ret);
786
787 ASSERT_EQ(ERR_SSL_VERSION_OR_CIPHER_MISMATCH, client_ret);
788 ASSERT_EQ(ERR_SSL_VERSION_OR_CIPHER_MISMATCH, server_ret);
789}
790
[email protected]f61c3972010-12-23 09:54:15791} // namespace net