Move encrypted media content browser tests into browser tests.
[chromium-blink-merge.git] / net / socket / ssl_client_socket_unittest.cc
blobf791928580f60c07bce57cf057d7c0bffed94ecf
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "net/socket/ssl_client_socket.h"
7 #include "base/callback_helpers.h"
8 #include "base/memory/ref_counted.h"
9 #include "net/base/address_list.h"
10 #include "net/base/io_buffer.h"
11 #include "net/base/net_errors.h"
12 #include "net/base/net_log.h"
13 #include "net/base/net_log_unittest.h"
14 #include "net/base/test_completion_callback.h"
15 #include "net/base/test_data_directory.h"
16 #include "net/cert/mock_cert_verifier.h"
17 #include "net/cert/test_root_certs.h"
18 #include "net/dns/host_resolver.h"
19 #include "net/http/transport_security_state.h"
20 #include "net/socket/client_socket_factory.h"
21 #include "net/socket/client_socket_handle.h"
22 #include "net/socket/socket_test_util.h"
23 #include "net/socket/tcp_client_socket.h"
24 #include "net/ssl/ssl_cert_request_info.h"
25 #include "net/ssl/ssl_config_service.h"
26 #include "net/test/cert_test_util.h"
27 #include "net/test/spawned_test_server/spawned_test_server.h"
28 #include "testing/gtest/include/gtest/gtest.h"
29 #include "testing/platform_test.h"
31 //-----------------------------------------------------------------------------
33 namespace net {
35 namespace {
37 const SSLConfig kDefaultSSLConfig;
39 // WrappedStreamSocket is a base class that wraps an existing StreamSocket,
40 // forwarding the Socket and StreamSocket interfaces to the underlying
41 // transport.
42 // This is to provide a common base class for subclasses to override specific
43 // StreamSocket methods for testing, while still communicating with a 'real'
44 // StreamSocket.
45 class WrappedStreamSocket : public StreamSocket {
46 public:
47 explicit WrappedStreamSocket(scoped_ptr<StreamSocket> transport)
48 : transport_(transport.Pass()) {}
49 virtual ~WrappedStreamSocket() {}
51 // StreamSocket implementation:
52 virtual int Connect(const CompletionCallback& callback) OVERRIDE {
53 return transport_->Connect(callback);
55 virtual void Disconnect() OVERRIDE { transport_->Disconnect(); }
56 virtual bool IsConnected() const OVERRIDE {
57 return transport_->IsConnected();
59 virtual bool IsConnectedAndIdle() const OVERRIDE {
60 return transport_->IsConnectedAndIdle();
62 virtual int GetPeerAddress(IPEndPoint* address) const OVERRIDE {
63 return transport_->GetPeerAddress(address);
65 virtual int GetLocalAddress(IPEndPoint* address) const OVERRIDE {
66 return transport_->GetLocalAddress(address);
68 virtual const BoundNetLog& NetLog() const OVERRIDE {
69 return transport_->NetLog();
71 virtual void SetSubresourceSpeculation() OVERRIDE {
72 transport_->SetSubresourceSpeculation();
74 virtual void SetOmniboxSpeculation() OVERRIDE {
75 transport_->SetOmniboxSpeculation();
77 virtual bool WasEverUsed() const OVERRIDE {
78 return transport_->WasEverUsed();
80 virtual bool UsingTCPFastOpen() const OVERRIDE {
81 return transport_->UsingTCPFastOpen();
83 virtual bool WasNpnNegotiated() const OVERRIDE {
84 return transport_->WasNpnNegotiated();
86 virtual NextProto GetNegotiatedProtocol() const OVERRIDE {
87 return transport_->GetNegotiatedProtocol();
89 virtual bool GetSSLInfo(SSLInfo* ssl_info) OVERRIDE {
90 return transport_->GetSSLInfo(ssl_info);
93 // Socket implementation:
94 virtual int Read(IOBuffer* buf,
95 int buf_len,
96 const CompletionCallback& callback) OVERRIDE {
97 return transport_->Read(buf, buf_len, callback);
99 virtual int Write(IOBuffer* buf,
100 int buf_len,
101 const CompletionCallback& callback) OVERRIDE {
102 return transport_->Write(buf, buf_len, callback);
104 virtual bool SetReceiveBufferSize(int32 size) OVERRIDE {
105 return transport_->SetReceiveBufferSize(size);
107 virtual bool SetSendBufferSize(int32 size) OVERRIDE {
108 return transport_->SetSendBufferSize(size);
111 protected:
112 scoped_ptr<StreamSocket> transport_;
115 // ReadBufferingStreamSocket is a wrapper for an existing StreamSocket that
116 // will ensure a certain amount of data is internally buffered before
117 // satisfying a Read() request. It exists to mimic OS-level internal
118 // buffering, but in a way to guarantee that X number of bytes will be
119 // returned to callers of Read(), regardless of how quickly the OS receives
120 // them from the TestServer.
121 class ReadBufferingStreamSocket : public WrappedStreamSocket {
122 public:
123 explicit ReadBufferingStreamSocket(scoped_ptr<StreamSocket> transport);
124 virtual ~ReadBufferingStreamSocket() {}
126 // Socket implementation:
127 virtual int Read(IOBuffer* buf,
128 int buf_len,
129 const CompletionCallback& callback) OVERRIDE;
131 // Sets the internal buffer to |size|. This must not be greater than
132 // the largest value supplied to Read() - that is, it does not handle
133 // having "leftovers" at the end of Read().
134 // Each call to Read() will be prevented from completion until at least
135 // |size| data has been read.
136 // Set to 0 to turn off buffering, causing Read() to transparently
137 // read via the underlying transport.
138 void SetBufferSize(int size);
140 private:
141 enum State {
142 STATE_NONE,
143 STATE_READ,
144 STATE_READ_COMPLETE,
147 int DoLoop(int result);
148 int DoRead();
149 int DoReadComplete(int result);
150 void OnReadCompleted(int result);
152 State state_;
153 scoped_refptr<GrowableIOBuffer> read_buffer_;
154 int buffer_size_;
156 scoped_refptr<IOBuffer> user_read_buf_;
157 CompletionCallback user_read_callback_;
160 ReadBufferingStreamSocket::ReadBufferingStreamSocket(
161 scoped_ptr<StreamSocket> transport)
162 : WrappedStreamSocket(transport.Pass()),
163 read_buffer_(new GrowableIOBuffer()),
164 buffer_size_(0) {}
166 void ReadBufferingStreamSocket::SetBufferSize(int size) {
167 DCHECK(!user_read_buf_.get());
168 buffer_size_ = size;
169 read_buffer_->SetCapacity(size);
172 int ReadBufferingStreamSocket::Read(IOBuffer* buf,
173 int buf_len,
174 const CompletionCallback& callback) {
175 if (buffer_size_ == 0)
176 return transport_->Read(buf, buf_len, callback);
178 if (buf_len < buffer_size_)
179 return ERR_UNEXPECTED;
181 state_ = STATE_READ;
182 user_read_buf_ = buf;
183 int result = DoLoop(OK);
184 if (result == ERR_IO_PENDING)
185 user_read_callback_ = callback;
186 else
187 user_read_buf_ = NULL;
188 return result;
191 int ReadBufferingStreamSocket::DoLoop(int result) {
192 int rv = result;
193 do {
194 State current_state = state_;
195 state_ = STATE_NONE;
196 switch (current_state) {
197 case STATE_READ:
198 rv = DoRead();
199 break;
200 case STATE_READ_COMPLETE:
201 rv = DoReadComplete(rv);
202 break;
203 case STATE_NONE:
204 default:
205 NOTREACHED() << "Unexpected state: " << current_state;
206 rv = ERR_UNEXPECTED;
207 break;
209 } while (rv != ERR_IO_PENDING && state_ != STATE_NONE);
210 return rv;
213 int ReadBufferingStreamSocket::DoRead() {
214 state_ = STATE_READ_COMPLETE;
215 int rv =
216 transport_->Read(read_buffer_.get(),
217 read_buffer_->RemainingCapacity(),
218 base::Bind(&ReadBufferingStreamSocket::OnReadCompleted,
219 base::Unretained(this)));
220 return rv;
223 int ReadBufferingStreamSocket::DoReadComplete(int result) {
224 state_ = STATE_NONE;
225 if (result <= 0)
226 return result;
228 read_buffer_->set_offset(read_buffer_->offset() + result);
229 if (read_buffer_->RemainingCapacity() > 0) {
230 state_ = STATE_READ;
231 return OK;
234 memcpy(user_read_buf_->data(),
235 read_buffer_->StartOfBuffer(),
236 read_buffer_->capacity());
237 read_buffer_->set_offset(0);
238 return read_buffer_->capacity();
241 void ReadBufferingStreamSocket::OnReadCompleted(int result) {
242 result = DoLoop(result);
243 if (result == ERR_IO_PENDING)
244 return;
246 user_read_buf_ = NULL;
247 base::ResetAndReturn(&user_read_callback_).Run(result);
250 // Simulates synchronously receiving an error during Read() or Write()
251 class SynchronousErrorStreamSocket : public WrappedStreamSocket {
252 public:
253 explicit SynchronousErrorStreamSocket(scoped_ptr<StreamSocket> transport);
254 virtual ~SynchronousErrorStreamSocket() {}
256 // Socket implementation:
257 virtual int Read(IOBuffer* buf,
258 int buf_len,
259 const CompletionCallback& callback) OVERRIDE;
260 virtual int Write(IOBuffer* buf,
261 int buf_len,
262 const CompletionCallback& callback) OVERRIDE;
264 // Sets the next Read() call and all future calls to return |error|.
265 // If there is already a pending asynchronous read, the configured error
266 // will not be returned until that asynchronous read has completed and Read()
267 // is called again.
268 void SetNextReadError(Error error) {
269 DCHECK_GE(0, error);
270 have_read_error_ = true;
271 pending_read_error_ = error;
274 // Sets the next Write() call and all future calls to return |error|.
275 // If there is already a pending asynchronous write, the configured error
276 // will not be returned until that asynchronous write has completed and
277 // Write() is called again.
278 void SetNextWriteError(Error error) {
279 DCHECK_GE(0, error);
280 have_write_error_ = true;
281 pending_write_error_ = error;
284 private:
285 bool have_read_error_;
286 int pending_read_error_;
288 bool have_write_error_;
289 int pending_write_error_;
291 DISALLOW_COPY_AND_ASSIGN(SynchronousErrorStreamSocket);
294 SynchronousErrorStreamSocket::SynchronousErrorStreamSocket(
295 scoped_ptr<StreamSocket> transport)
296 : WrappedStreamSocket(transport.Pass()),
297 have_read_error_(false),
298 pending_read_error_(OK),
299 have_write_error_(false),
300 pending_write_error_(OK) {}
302 int SynchronousErrorStreamSocket::Read(IOBuffer* buf,
303 int buf_len,
304 const CompletionCallback& callback) {
305 if (have_read_error_)
306 return pending_read_error_;
307 return transport_->Read(buf, buf_len, callback);
310 int SynchronousErrorStreamSocket::Write(IOBuffer* buf,
311 int buf_len,
312 const CompletionCallback& callback) {
313 if (have_write_error_)
314 return pending_write_error_;
315 return transport_->Write(buf, buf_len, callback);
318 // FakeBlockingStreamSocket wraps an existing StreamSocket and simulates the
319 // underlying transport needing to complete things asynchronously in a
320 // deterministic manner (e.g.: independent of the TestServer and the OS's
321 // semantics).
322 class FakeBlockingStreamSocket : public WrappedStreamSocket {
323 public:
324 explicit FakeBlockingStreamSocket(scoped_ptr<StreamSocket> transport);
325 virtual ~FakeBlockingStreamSocket() {}
327 // Socket implementation:
328 virtual int Read(IOBuffer* buf,
329 int buf_len,
330 const CompletionCallback& callback) OVERRIDE {
331 return read_state_.RunWrappedFunction(buf, buf_len, callback);
333 virtual int Write(IOBuffer* buf,
334 int buf_len,
335 const CompletionCallback& callback) OVERRIDE {
336 return write_state_.RunWrappedFunction(buf, buf_len, callback);
339 // Causes the next call to Read() to return ERR_IO_PENDING, not completing
340 // (invoking the callback) until UnblockRead() has been called and the
341 // underlying transport has completed.
342 void SetNextReadShouldBlock() { read_state_.SetShouldBlock(); }
343 void UnblockRead() { read_state_.Unblock(); }
345 // Causes the next call to Write() to return ERR_IO_PENDING, not completing
346 // (invoking the callback) until UnblockWrite() has been called and the
347 // underlying transport has completed.
348 void SetNextWriteShouldBlock() { write_state_.SetShouldBlock(); }
349 void UnblockWrite() { write_state_.Unblock(); }
351 private:
352 // Tracks the state for simulating a blocking Read/Write operation.
353 class BlockingState {
354 public:
355 // Wrapper for the underlying Socket function to call (ie: Read/Write).
356 typedef base::Callback<int(IOBuffer*, int, const CompletionCallback&)>
357 WrappedSocketFunction;
359 explicit BlockingState(const WrappedSocketFunction& function);
360 ~BlockingState() {}
362 // Sets the next call to RunWrappedFunction() to block, returning
363 // ERR_IO_PENDING and not invoking the user callback until Unblock() is
364 // called.
365 void SetShouldBlock();
367 // Unblocks the currently blocked pending function, invoking the user
368 // callback if the results are immediately available.
369 // Note: It's not valid to call this unless SetShouldBlock() has been
370 // called beforehand.
371 void Unblock();
373 // Performs the wrapped socket function on the underlying transport. If
374 // configured to block via SetShouldBlock(), then |user_callback| will not
375 // be invoked until Unblock() has been called.
376 int RunWrappedFunction(IOBuffer* buf,
377 int len,
378 const CompletionCallback& user_callback);
380 private:
381 // Handles completion from the underlying wrapped socket function.
382 void OnCompleted(int result);
384 WrappedSocketFunction wrapped_function_;
385 bool should_block_;
386 bool have_result_;
387 int pending_result_;
388 CompletionCallback user_callback_;
391 BlockingState read_state_;
392 BlockingState write_state_;
394 DISALLOW_COPY_AND_ASSIGN(FakeBlockingStreamSocket);
397 FakeBlockingStreamSocket::FakeBlockingStreamSocket(
398 scoped_ptr<StreamSocket> transport)
399 : WrappedStreamSocket(transport.Pass()),
400 read_state_(base::Bind(&Socket::Read,
401 base::Unretained(transport_.get()))),
402 write_state_(base::Bind(&Socket::Write,
403 base::Unretained(transport_.get()))) {}
405 FakeBlockingStreamSocket::BlockingState::BlockingState(
406 const WrappedSocketFunction& function)
407 : wrapped_function_(function),
408 should_block_(false),
409 have_result_(false),
410 pending_result_(OK) {}
412 void FakeBlockingStreamSocket::BlockingState::SetShouldBlock() {
413 DCHECK(!should_block_);
414 should_block_ = true;
417 void FakeBlockingStreamSocket::BlockingState::Unblock() {
418 DCHECK(should_block_);
419 should_block_ = false;
421 // If the operation is still pending in the underlying transport, immediately
422 // return - OnCompleted() will handle invoking the callback once the transport
423 // has completed.
424 if (!have_result_)
425 return;
427 have_result_ = false;
429 base::ResetAndReturn(&user_callback_).Run(pending_result_);
432 int FakeBlockingStreamSocket::BlockingState::RunWrappedFunction(
433 IOBuffer* buf,
434 int len,
435 const CompletionCallback& callback) {
437 // The callback to be called by the underlying transport. Either forward
438 // directly to the user's callback if not set to block, or intercept it with
439 // OnCompleted so that the user's callback is not invoked until Unblock() is
440 // called.
441 CompletionCallback transport_callback =
442 !should_block_ ? callback : base::Bind(&BlockingState::OnCompleted,
443 base::Unretained(this));
444 int rv = wrapped_function_.Run(buf, len, transport_callback);
445 if (should_block_) {
446 user_callback_ = callback;
447 // May have completed synchronously.
448 have_result_ = (rv != ERR_IO_PENDING);
449 pending_result_ = rv;
450 return ERR_IO_PENDING;
453 return rv;
456 void FakeBlockingStreamSocket::BlockingState::OnCompleted(int result) {
457 if (should_block_) {
458 // Store the result so that the callback can be invoked once Unblock() is
459 // called.
460 have_result_ = true;
461 pending_result_ = result;
462 return;
465 // Otherwise, the Unblock() function was called before the underlying
466 // transport completed, so run the user's callback immediately.
467 base::ResetAndReturn(&user_callback_).Run(result);
470 // CompletionCallback that will delete the associated StreamSocket when
471 // the callback is invoked.
472 class DeleteSocketCallback : public TestCompletionCallbackBase {
473 public:
474 explicit DeleteSocketCallback(StreamSocket* socket)
475 : socket_(socket),
476 callback_(base::Bind(&DeleteSocketCallback::OnComplete,
477 base::Unretained(this))) {}
478 virtual ~DeleteSocketCallback() {}
480 const CompletionCallback& callback() const { return callback_; }
482 private:
483 void OnComplete(int result) {
484 if (socket_) {
485 delete socket_;
486 socket_ = NULL;
487 } else {
488 ADD_FAILURE() << "Deleting socket twice";
490 SetResult(result);
493 StreamSocket* socket_;
494 CompletionCallback callback_;
496 DISALLOW_COPY_AND_ASSIGN(DeleteSocketCallback);
499 class SSLClientSocketTest : public PlatformTest {
500 public:
501 SSLClientSocketTest()
502 : socket_factory_(ClientSocketFactory::GetDefaultFactory()),
503 cert_verifier_(new MockCertVerifier),
504 transport_security_state_(new TransportSecurityState) {
505 cert_verifier_->set_default_result(OK);
506 context_.cert_verifier = cert_verifier_.get();
507 context_.transport_security_state = transport_security_state_.get();
510 protected:
511 scoped_ptr<SSLClientSocket> CreateSSLClientSocket(
512 scoped_ptr<StreamSocket> transport_socket,
513 const HostPortPair& host_and_port,
514 const SSLConfig& ssl_config) {
515 scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
516 connection->SetSocket(transport_socket.Pass());
517 return socket_factory_->CreateSSLClientSocket(
518 connection.Pass(), host_and_port, ssl_config, context_);
521 ClientSocketFactory* socket_factory_;
522 scoped_ptr<MockCertVerifier> cert_verifier_;
523 scoped_ptr<TransportSecurityState> transport_security_state_;
524 SSLClientSocketContext context_;
527 //-----------------------------------------------------------------------------
529 // LogContainsSSLConnectEndEvent returns true if the given index in the given
530 // log is an SSL connect end event. The NSS sockets will cork in an attempt to
531 // merge the first application data record with the Finished message when false
532 // starting. However, in order to avoid the server timing out the handshake,
533 // they'll give up waiting for application data and send the Finished after a
534 // timeout. This means that an SSL connect end event may appear as a socket
535 // write.
536 static bool LogContainsSSLConnectEndEvent(
537 const CapturingNetLog::CapturedEntryList& log,
538 int i) {
539 return LogContainsEndEvent(log, i, NetLog::TYPE_SSL_CONNECT) ||
540 LogContainsEvent(
541 log, i, NetLog::TYPE_SOCKET_BYTES_SENT, NetLog::PHASE_NONE);
545 TEST_F(SSLClientSocketTest, Connect) {
546 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS,
547 SpawnedTestServer::kLocalhost,
548 base::FilePath());
549 ASSERT_TRUE(test_server.Start());
551 AddressList addr;
552 ASSERT_TRUE(test_server.GetAddressList(&addr));
554 TestCompletionCallback callback;
555 CapturingNetLog log;
556 scoped_ptr<StreamSocket> transport(
557 new TCPClientSocket(addr, &log, NetLog::Source()));
558 int rv = transport->Connect(callback.callback());
559 if (rv == ERR_IO_PENDING)
560 rv = callback.WaitForResult();
561 EXPECT_EQ(OK, rv);
563 scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
564 transport.Pass(), test_server.host_port_pair(), kDefaultSSLConfig));
566 EXPECT_FALSE(sock->IsConnected());
568 rv = sock->Connect(callback.callback());
570 CapturingNetLog::CapturedEntryList entries;
571 log.GetEntries(&entries);
572 EXPECT_TRUE(LogContainsBeginEvent(entries, 5, NetLog::TYPE_SSL_CONNECT));
573 if (rv == ERR_IO_PENDING)
574 rv = callback.WaitForResult();
575 EXPECT_EQ(OK, rv);
576 EXPECT_TRUE(sock->IsConnected());
577 log.GetEntries(&entries);
578 EXPECT_TRUE(LogContainsSSLConnectEndEvent(entries, -1));
580 sock->Disconnect();
581 EXPECT_FALSE(sock->IsConnected());
584 TEST_F(SSLClientSocketTest, ConnectExpired) {
585 SpawnedTestServer::SSLOptions ssl_options(
586 SpawnedTestServer::SSLOptions::CERT_EXPIRED);
587 SpawnedTestServer test_server(
588 SpawnedTestServer::TYPE_HTTPS, ssl_options, base::FilePath());
589 ASSERT_TRUE(test_server.Start());
591 cert_verifier_->set_default_result(ERR_CERT_DATE_INVALID);
593 AddressList addr;
594 ASSERT_TRUE(test_server.GetAddressList(&addr));
596 TestCompletionCallback callback;
597 CapturingNetLog log;
598 scoped_ptr<StreamSocket> transport(
599 new TCPClientSocket(addr, &log, NetLog::Source()));
600 int rv = transport->Connect(callback.callback());
601 if (rv == ERR_IO_PENDING)
602 rv = callback.WaitForResult();
603 EXPECT_EQ(OK, rv);
605 scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
606 transport.Pass(), test_server.host_port_pair(), kDefaultSSLConfig));
608 EXPECT_FALSE(sock->IsConnected());
610 rv = sock->Connect(callback.callback());
612 CapturingNetLog::CapturedEntryList entries;
613 log.GetEntries(&entries);
614 EXPECT_TRUE(LogContainsBeginEvent(entries, 5, NetLog::TYPE_SSL_CONNECT));
615 if (rv == ERR_IO_PENDING)
616 rv = callback.WaitForResult();
618 EXPECT_EQ(ERR_CERT_DATE_INVALID, rv);
620 // Rather than testing whether or not the underlying socket is connected,
621 // test that the handshake has finished. This is because it may be
622 // desirable to disconnect the socket before showing a user prompt, since
623 // the user may take indefinitely long to respond.
624 log.GetEntries(&entries);
625 EXPECT_TRUE(LogContainsSSLConnectEndEvent(entries, -1));
628 TEST_F(SSLClientSocketTest, ConnectMismatched) {
629 SpawnedTestServer::SSLOptions ssl_options(
630 SpawnedTestServer::SSLOptions::CERT_MISMATCHED_NAME);
631 SpawnedTestServer test_server(
632 SpawnedTestServer::TYPE_HTTPS, ssl_options, base::FilePath());
633 ASSERT_TRUE(test_server.Start());
635 cert_verifier_->set_default_result(ERR_CERT_COMMON_NAME_INVALID);
637 AddressList addr;
638 ASSERT_TRUE(test_server.GetAddressList(&addr));
640 TestCompletionCallback callback;
641 CapturingNetLog log;
642 scoped_ptr<StreamSocket> transport(
643 new TCPClientSocket(addr, &log, NetLog::Source()));
644 int rv = transport->Connect(callback.callback());
645 if (rv == ERR_IO_PENDING)
646 rv = callback.WaitForResult();
647 EXPECT_EQ(OK, rv);
649 scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
650 transport.Pass(), test_server.host_port_pair(), kDefaultSSLConfig));
652 EXPECT_FALSE(sock->IsConnected());
654 rv = sock->Connect(callback.callback());
656 CapturingNetLog::CapturedEntryList entries;
657 log.GetEntries(&entries);
658 EXPECT_TRUE(LogContainsBeginEvent(entries, 5, NetLog::TYPE_SSL_CONNECT));
659 if (rv == ERR_IO_PENDING)
660 rv = callback.WaitForResult();
662 EXPECT_EQ(ERR_CERT_COMMON_NAME_INVALID, rv);
664 // Rather than testing whether or not the underlying socket is connected,
665 // test that the handshake has finished. This is because it may be
666 // desirable to disconnect the socket before showing a user prompt, since
667 // the user may take indefinitely long to respond.
668 log.GetEntries(&entries);
669 EXPECT_TRUE(LogContainsSSLConnectEndEvent(entries, -1));
672 // Attempt to connect to a page which requests a client certificate. It should
673 // return an error code on connect.
674 TEST_F(SSLClientSocketTest, ConnectClientAuthCertRequested) {
675 SpawnedTestServer::SSLOptions ssl_options;
676 ssl_options.request_client_certificate = true;
677 SpawnedTestServer test_server(
678 SpawnedTestServer::TYPE_HTTPS, ssl_options, base::FilePath());
679 ASSERT_TRUE(test_server.Start());
681 AddressList addr;
682 ASSERT_TRUE(test_server.GetAddressList(&addr));
684 TestCompletionCallback callback;
685 CapturingNetLog log;
686 scoped_ptr<StreamSocket> transport(
687 new TCPClientSocket(addr, &log, NetLog::Source()));
688 int rv = transport->Connect(callback.callback());
689 if (rv == ERR_IO_PENDING)
690 rv = callback.WaitForResult();
691 EXPECT_EQ(OK, rv);
693 scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
694 transport.Pass(), test_server.host_port_pair(), kDefaultSSLConfig));
696 EXPECT_FALSE(sock->IsConnected());
698 rv = sock->Connect(callback.callback());
700 CapturingNetLog::CapturedEntryList entries;
701 log.GetEntries(&entries);
702 EXPECT_TRUE(LogContainsBeginEvent(entries, 5, NetLog::TYPE_SSL_CONNECT));
703 if (rv == ERR_IO_PENDING)
704 rv = callback.WaitForResult();
706 log.GetEntries(&entries);
707 // Because we prematurely kill the handshake at CertificateRequest,
708 // the server may still send data (notably the ServerHelloDone)
709 // after the error is returned. As a result, the SSL_CONNECT may not
710 // be the last entry. See http://crbug.com/54445. We use
711 // ExpectLogContainsSomewhere instead of
712 // LogContainsSSLConnectEndEvent to avoid assuming, e.g., only one
713 // extra read instead of two. This occurs before the handshake ends,
714 // so the corking logic of LogContainsSSLConnectEndEvent isn't
715 // necessary.
717 // TODO(davidben): When SSL_RestartHandshakeAfterCertReq in NSS is
718 // fixed and we can respond to the first CertificateRequest
719 // without closing the socket, add a unit test for sending the
720 // certificate. This test may still be useful as we'll want to close
721 // the socket on a timeout if the user takes a long time to pick a
722 // cert. Related bug: https://bugzilla.mozilla.org/show_bug.cgi?id=542832
723 ExpectLogContainsSomewhere(
724 entries, 0, NetLog::TYPE_SSL_CONNECT, NetLog::PHASE_END);
725 EXPECT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
726 EXPECT_FALSE(sock->IsConnected());
729 // Connect to a server requesting optional client authentication. Send it a
730 // null certificate. It should allow the connection.
732 // TODO(davidben): Also test providing an actual certificate.
733 TEST_F(SSLClientSocketTest, ConnectClientAuthSendNullCert) {
734 SpawnedTestServer::SSLOptions ssl_options;
735 ssl_options.request_client_certificate = true;
736 SpawnedTestServer test_server(
737 SpawnedTestServer::TYPE_HTTPS, ssl_options, base::FilePath());
738 ASSERT_TRUE(test_server.Start());
740 AddressList addr;
741 ASSERT_TRUE(test_server.GetAddressList(&addr));
743 TestCompletionCallback callback;
744 CapturingNetLog log;
745 scoped_ptr<StreamSocket> transport(
746 new TCPClientSocket(addr, &log, NetLog::Source()));
747 int rv = transport->Connect(callback.callback());
748 if (rv == ERR_IO_PENDING)
749 rv = callback.WaitForResult();
750 EXPECT_EQ(OK, rv);
752 SSLConfig ssl_config = kDefaultSSLConfig;
753 ssl_config.send_client_cert = true;
754 ssl_config.client_cert = NULL;
756 scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
757 transport.Pass(), test_server.host_port_pair(), ssl_config));
759 EXPECT_FALSE(sock->IsConnected());
761 // Our test server accepts certificate-less connections.
762 // TODO(davidben): Add a test which requires them and verify the error.
763 rv = sock->Connect(callback.callback());
765 CapturingNetLog::CapturedEntryList entries;
766 log.GetEntries(&entries);
767 EXPECT_TRUE(LogContainsBeginEvent(entries, 5, NetLog::TYPE_SSL_CONNECT));
768 if (rv == ERR_IO_PENDING)
769 rv = callback.WaitForResult();
771 EXPECT_EQ(OK, rv);
772 EXPECT_TRUE(sock->IsConnected());
773 log.GetEntries(&entries);
774 EXPECT_TRUE(LogContainsSSLConnectEndEvent(entries, -1));
776 // We responded to the server's certificate request with a Certificate
777 // message with no client certificate in it. ssl_info.client_cert_sent
778 // should be false in this case.
779 SSLInfo ssl_info;
780 sock->GetSSLInfo(&ssl_info);
781 EXPECT_FALSE(ssl_info.client_cert_sent);
783 sock->Disconnect();
784 EXPECT_FALSE(sock->IsConnected());
787 // TODO(wtc): Add unit tests for IsConnectedAndIdle:
788 // - Server closes an SSL connection (with a close_notify alert message).
789 // - Server closes the underlying TCP connection directly.
790 // - Server sends data unexpectedly.
792 TEST_F(SSLClientSocketTest, Read) {
793 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS,
794 SpawnedTestServer::kLocalhost,
795 base::FilePath());
796 ASSERT_TRUE(test_server.Start());
798 AddressList addr;
799 ASSERT_TRUE(test_server.GetAddressList(&addr));
801 TestCompletionCallback callback;
802 scoped_ptr<StreamSocket> transport(
803 new TCPClientSocket(addr, NULL, NetLog::Source()));
804 int rv = transport->Connect(callback.callback());
805 if (rv == ERR_IO_PENDING)
806 rv = callback.WaitForResult();
807 EXPECT_EQ(OK, rv);
809 scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
810 transport.Pass(), test_server.host_port_pair(), kDefaultSSLConfig));
812 rv = sock->Connect(callback.callback());
813 if (rv == ERR_IO_PENDING)
814 rv = callback.WaitForResult();
815 EXPECT_EQ(OK, rv);
816 EXPECT_TRUE(sock->IsConnected());
818 const char request_text[] = "GET / HTTP/1.0\r\n\r\n";
819 scoped_refptr<IOBuffer> request_buffer(
820 new IOBuffer(arraysize(request_text) - 1));
821 memcpy(request_buffer->data(), request_text, arraysize(request_text) - 1);
823 rv = sock->Write(
824 request_buffer.get(), arraysize(request_text) - 1, callback.callback());
825 EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING);
827 if (rv == ERR_IO_PENDING)
828 rv = callback.WaitForResult();
829 EXPECT_EQ(static_cast<int>(arraysize(request_text) - 1), rv);
831 scoped_refptr<IOBuffer> buf(new IOBuffer(4096));
832 for (;;) {
833 rv = sock->Read(buf.get(), 4096, callback.callback());
834 EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING);
836 if (rv == ERR_IO_PENDING)
837 rv = callback.WaitForResult();
839 EXPECT_GE(rv, 0);
840 if (rv <= 0)
841 break;
845 // Tests that the SSLClientSocket properly handles when the underlying transport
846 // synchronously returns an error code - such as if an intermediary terminates
847 // the socket connection uncleanly.
848 // This is a regression test for http://crbug.com/238536
849 TEST_F(SSLClientSocketTest, Read_WithSynchronousError) {
850 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS,
851 SpawnedTestServer::kLocalhost,
852 base::FilePath());
853 ASSERT_TRUE(test_server.Start());
855 AddressList addr;
856 ASSERT_TRUE(test_server.GetAddressList(&addr));
858 TestCompletionCallback callback;
859 scoped_ptr<StreamSocket> real_transport(
860 new TCPClientSocket(addr, NULL, NetLog::Source()));
861 scoped_ptr<SynchronousErrorStreamSocket> transport(
862 new SynchronousErrorStreamSocket(real_transport.Pass()));
863 int rv = callback.GetResult(transport->Connect(callback.callback()));
864 EXPECT_EQ(OK, rv);
866 // Disable TLS False Start to avoid handshake non-determinism.
867 SSLConfig ssl_config;
868 ssl_config.false_start_enabled = false;
870 SynchronousErrorStreamSocket* raw_transport = transport.get();
871 scoped_ptr<SSLClientSocket> sock(
872 CreateSSLClientSocket(transport.PassAs<StreamSocket>(),
873 test_server.host_port_pair(),
874 ssl_config));
876 rv = callback.GetResult(sock->Connect(callback.callback()));
877 EXPECT_EQ(OK, rv);
878 EXPECT_TRUE(sock->IsConnected());
880 const char request_text[] = "GET / HTTP/1.0\r\n\r\n";
881 static const int kRequestTextSize =
882 static_cast<int>(arraysize(request_text) - 1);
883 scoped_refptr<IOBuffer> request_buffer(new IOBuffer(kRequestTextSize));
884 memcpy(request_buffer->data(), request_text, kRequestTextSize);
886 rv = callback.GetResult(
887 sock->Write(request_buffer.get(), kRequestTextSize, callback.callback()));
888 EXPECT_EQ(kRequestTextSize, rv);
890 // Simulate an unclean/forcible shutdown.
891 raw_transport->SetNextReadError(ERR_CONNECTION_RESET);
893 scoped_refptr<IOBuffer> buf(new IOBuffer(4096));
895 // Note: This test will hang if this bug has regressed. Simply checking that
896 // rv != ERR_IO_PENDING is insufficient, as ERR_IO_PENDING is a legitimate
897 // result when using a dedicated task runner for NSS.
898 rv = callback.GetResult(sock->Read(buf.get(), 4096, callback.callback()));
900 #if !defined(USE_OPENSSL)
901 // SSLClientSocketNSS records the error exactly
902 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
903 #else
904 // SSLClientSocketOpenSSL treats any errors as a simple EOF.
905 EXPECT_EQ(0, rv);
906 #endif
909 // Tests that the SSLClientSocket properly handles when the underlying transport
910 // asynchronously returns an error code while writing data - such as if an
911 // intermediary terminates the socket connection uncleanly.
912 // This is a regression test for http://crbug.com/249848
913 TEST_F(SSLClientSocketTest, Write_WithSynchronousError) {
914 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS,
915 SpawnedTestServer::kLocalhost,
916 base::FilePath());
917 ASSERT_TRUE(test_server.Start());
919 AddressList addr;
920 ASSERT_TRUE(test_server.GetAddressList(&addr));
922 TestCompletionCallback callback;
923 scoped_ptr<StreamSocket> real_transport(
924 new TCPClientSocket(addr, NULL, NetLog::Source()));
925 // Note: |error_socket|'s ownership is handed to |transport|, but a pointer
926 // is retained in order to configure additional errors.
927 scoped_ptr<SynchronousErrorStreamSocket> error_socket(
928 new SynchronousErrorStreamSocket(real_transport.Pass()));
929 SynchronousErrorStreamSocket* raw_error_socket = error_socket.get();
930 scoped_ptr<FakeBlockingStreamSocket> transport(
931 new FakeBlockingStreamSocket(error_socket.PassAs<StreamSocket>()));
932 FakeBlockingStreamSocket* raw_transport = transport.get();
933 int rv = callback.GetResult(transport->Connect(callback.callback()));
934 EXPECT_EQ(OK, rv);
936 // Disable TLS False Start to avoid handshake non-determinism.
937 SSLConfig ssl_config;
938 ssl_config.false_start_enabled = false;
940 scoped_ptr<SSLClientSocket> sock(
941 CreateSSLClientSocket(transport.PassAs<StreamSocket>(),
942 test_server.host_port_pair(),
943 ssl_config));
945 rv = callback.GetResult(sock->Connect(callback.callback()));
946 EXPECT_EQ(OK, rv);
947 EXPECT_TRUE(sock->IsConnected());
949 const char request_text[] = "GET / HTTP/1.0\r\n\r\n";
950 static const int kRequestTextSize =
951 static_cast<int>(arraysize(request_text) - 1);
952 scoped_refptr<IOBuffer> request_buffer(new IOBuffer(kRequestTextSize));
953 memcpy(request_buffer->data(), request_text, kRequestTextSize);
955 // Simulate an unclean/forcible shutdown on the underlying socket.
956 // However, simulate this error asynchronously.
957 raw_error_socket->SetNextWriteError(ERR_CONNECTION_RESET);
958 raw_transport->SetNextWriteShouldBlock();
960 // This write should complete synchronously, because the TLS ciphertext
961 // can be created and placed into the outgoing buffers independent of the
962 // underlying transport.
963 rv = callback.GetResult(
964 sock->Write(request_buffer.get(), kRequestTextSize, callback.callback()));
965 EXPECT_EQ(kRequestTextSize, rv);
967 scoped_refptr<IOBuffer> buf(new IOBuffer(4096));
969 rv = sock->Read(buf.get(), 4096, callback.callback());
970 EXPECT_EQ(ERR_IO_PENDING, rv);
972 // Now unblock the outgoing request, having it fail with the connection
973 // being reset.
974 raw_transport->UnblockWrite();
976 // Note: This will cause an inifite loop if this bug has regressed. Simply
977 // checking that rv != ERR_IO_PENDING is insufficient, as ERR_IO_PENDING
978 // is a legitimate result when using a dedicated task runner for NSS.
979 rv = callback.GetResult(rv);
981 #if !defined(USE_OPENSSL)
982 // SSLClientSocketNSS records the error exactly
983 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
984 #else
985 // SSLClientSocketOpenSSL treats any errors as a simple EOF.
986 EXPECT_EQ(0, rv);
987 #endif
990 // Test the full duplex mode, with Read and Write pending at the same time.
991 // This test also serves as a regression test for http://crbug.com/29815.
992 TEST_F(SSLClientSocketTest, Read_FullDuplex) {
993 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS,
994 SpawnedTestServer::kLocalhost,
995 base::FilePath());
996 ASSERT_TRUE(test_server.Start());
998 AddressList addr;
999 ASSERT_TRUE(test_server.GetAddressList(&addr));
1001 TestCompletionCallback callback; // Used for everything except Write.
1003 scoped_ptr<StreamSocket> transport(
1004 new TCPClientSocket(addr, NULL, NetLog::Source()));
1005 int rv = transport->Connect(callback.callback());
1006 if (rv == ERR_IO_PENDING)
1007 rv = callback.WaitForResult();
1008 EXPECT_EQ(OK, rv);
1010 scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
1011 transport.Pass(), test_server.host_port_pair(), kDefaultSSLConfig));
1013 rv = sock->Connect(callback.callback());
1014 if (rv == ERR_IO_PENDING)
1015 rv = callback.WaitForResult();
1016 EXPECT_EQ(OK, rv);
1017 EXPECT_TRUE(sock->IsConnected());
1019 // Issue a "hanging" Read first.
1020 scoped_refptr<IOBuffer> buf(new IOBuffer(4096));
1021 rv = sock->Read(buf.get(), 4096, callback.callback());
1022 // We haven't written the request, so there should be no response yet.
1023 ASSERT_EQ(ERR_IO_PENDING, rv);
1025 // Write the request.
1026 // The request is padded with a User-Agent header to a size that causes the
1027 // memio circular buffer (4k bytes) in SSLClientSocketNSS to wrap around.
1028 // This tests the fix for http://crbug.com/29815.
1029 std::string request_text = "GET / HTTP/1.1\r\nUser-Agent: long browser name ";
1030 for (int i = 0; i < 3770; ++i)
1031 request_text.push_back('*');
1032 request_text.append("\r\n\r\n");
1033 scoped_refptr<IOBuffer> request_buffer(new StringIOBuffer(request_text));
1035 TestCompletionCallback callback2; // Used for Write only.
1036 rv = sock->Write(
1037 request_buffer.get(), request_text.size(), callback2.callback());
1038 EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING);
1040 if (rv == ERR_IO_PENDING)
1041 rv = callback2.WaitForResult();
1042 EXPECT_EQ(static_cast<int>(request_text.size()), rv);
1044 // Now get the Read result.
1045 rv = callback.WaitForResult();
1046 EXPECT_GT(rv, 0);
1049 // Attempts to Read() and Write() from an SSLClientSocketNSS in full duplex
1050 // mode when the underlying transport is blocked on sending data. When the
1051 // underlying transport completes due to an error, it should invoke both the
1052 // Read() and Write() callbacks. If the socket is deleted by the Read()
1053 // callback, the Write() callback should not be invoked.
1054 // Regression test for http://crbug.com/232633
1055 TEST_F(SSLClientSocketTest, Read_DeleteWhilePendingFullDuplex) {
1056 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS,
1057 SpawnedTestServer::kLocalhost,
1058 base::FilePath());
1059 ASSERT_TRUE(test_server.Start());
1061 AddressList addr;
1062 ASSERT_TRUE(test_server.GetAddressList(&addr));
1064 TestCompletionCallback callback;
1065 scoped_ptr<StreamSocket> real_transport(
1066 new TCPClientSocket(addr, NULL, NetLog::Source()));
1067 // Note: |error_socket|'s ownership is handed to |transport|, but a pointer
1068 // is retained in order to configure additional errors.
1069 scoped_ptr<SynchronousErrorStreamSocket> error_socket(
1070 new SynchronousErrorStreamSocket(real_transport.Pass()));
1071 SynchronousErrorStreamSocket* raw_error_socket = error_socket.get();
1072 scoped_ptr<FakeBlockingStreamSocket> transport(
1073 new FakeBlockingStreamSocket(error_socket.PassAs<StreamSocket>()));
1074 FakeBlockingStreamSocket* raw_transport = transport.get();
1076 int rv = callback.GetResult(transport->Connect(callback.callback()));
1077 EXPECT_EQ(OK, rv);
1079 // Disable TLS False Start to avoid handshake non-determinism.
1080 SSLConfig ssl_config;
1081 ssl_config.false_start_enabled = false;
1083 scoped_ptr<SSLClientSocket> sock =
1084 CreateSSLClientSocket(transport.PassAs<StreamSocket>(),
1085 test_server.host_port_pair(),
1086 ssl_config);
1088 rv = callback.GetResult(sock->Connect(callback.callback()));
1089 EXPECT_EQ(OK, rv);
1090 EXPECT_TRUE(sock->IsConnected());
1092 std::string request_text = "GET / HTTP/1.1\r\nUser-Agent: long browser name ";
1093 request_text.append(20 * 1024, '*');
1094 request_text.append("\r\n\r\n");
1095 scoped_refptr<DrainableIOBuffer> request_buffer(new DrainableIOBuffer(
1096 new StringIOBuffer(request_text), request_text.size()));
1098 // Simulate errors being returned from the underlying Read() and Write() ...
1099 raw_error_socket->SetNextReadError(ERR_CONNECTION_RESET);
1100 raw_error_socket->SetNextWriteError(ERR_CONNECTION_RESET);
1101 // ... but have those errors returned asynchronously. Because the Write() will
1102 // return first, this will trigger the error.
1103 raw_transport->SetNextReadShouldBlock();
1104 raw_transport->SetNextWriteShouldBlock();
1106 // Enqueue a Read() before calling Write(), which should "hang" due to
1107 // the ERR_IO_PENDING caused by SetReadShouldBlock() and thus return.
1108 SSLClientSocket* raw_sock = sock.get();
1109 DeleteSocketCallback read_callback(sock.release());
1110 scoped_refptr<IOBuffer> read_buf(new IOBuffer(4096));
1111 rv = raw_sock->Read(read_buf.get(), 4096, read_callback.callback());
1113 // Ensure things didn't complete synchronously, otherwise |sock| is invalid.
1114 ASSERT_EQ(ERR_IO_PENDING, rv);
1115 ASSERT_FALSE(read_callback.have_result());
1117 #if !defined(USE_OPENSSL)
1118 // NSS follows a pattern where a call to PR_Write will only consume as
1119 // much data as it can encode into application data records before the
1120 // internal memio buffer is full, which should only fill if writing a large
1121 // amount of data and the underlying transport is blocked. Once this happens,
1122 // NSS will return (total size of all application data records it wrote) - 1,
1123 // with the caller expected to resume with the remaining unsent data.
1125 // This causes SSLClientSocketNSS::Write to return that it wrote some data
1126 // before it will return ERR_IO_PENDING, so make an extra call to Write() to
1127 // get the socket in the state needed for the test below.
1129 // This is not needed for OpenSSL, because for OpenSSL,
1130 // SSL_MODE_ENABLE_PARTIAL_WRITE is not specified - thus
1131 // SSLClientSocketOpenSSL::Write() will not return until all of
1132 // |request_buffer| has been written to the underlying BIO (although not
1133 // necessarily the underlying transport).
1134 rv = callback.GetResult(raw_sock->Write(request_buffer.get(),
1135 request_buffer->BytesRemaining(),
1136 callback.callback()));
1137 ASSERT_LT(0, rv);
1138 request_buffer->DidConsume(rv);
1140 // Guard to ensure that |request_buffer| was larger than all of the internal
1141 // buffers (transport, memio, NSS) along the way - otherwise the next call
1142 // to Write() will crash with an invalid buffer.
1143 ASSERT_LT(0, request_buffer->BytesRemaining());
1144 #endif
1146 // Attempt to write the remaining data. NSS will not be able to consume the
1147 // application data because the internal buffers are full, while OpenSSL will
1148 // return that its blocked because the underlying transport is blocked.
1149 rv = raw_sock->Write(request_buffer.get(),
1150 request_buffer->BytesRemaining(),
1151 callback.callback());
1152 ASSERT_EQ(ERR_IO_PENDING, rv);
1153 ASSERT_FALSE(callback.have_result());
1155 // Now unblock Write(), which will invoke OnSendComplete and (eventually)
1156 // call the Read() callback, deleting the socket and thus aborting calling
1157 // the Write() callback.
1158 raw_transport->UnblockWrite();
1160 rv = read_callback.WaitForResult();
1162 #if !defined(USE_OPENSSL)
1163 // NSS records the error exactly.
1164 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
1165 #else
1166 // OpenSSL treats any errors as a simple EOF.
1167 EXPECT_EQ(0, rv);
1168 #endif
1170 // The Write callback should not have been called.
1171 EXPECT_FALSE(callback.have_result());
1174 TEST_F(SSLClientSocketTest, Read_SmallChunks) {
1175 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS,
1176 SpawnedTestServer::kLocalhost,
1177 base::FilePath());
1178 ASSERT_TRUE(test_server.Start());
1180 AddressList addr;
1181 ASSERT_TRUE(test_server.GetAddressList(&addr));
1183 TestCompletionCallback callback;
1184 scoped_ptr<StreamSocket> transport(
1185 new TCPClientSocket(addr, NULL, NetLog::Source()));
1186 int rv = transport->Connect(callback.callback());
1187 if (rv == ERR_IO_PENDING)
1188 rv = callback.WaitForResult();
1189 EXPECT_EQ(OK, rv);
1191 scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
1192 transport.Pass(), test_server.host_port_pair(), kDefaultSSLConfig));
1194 rv = sock->Connect(callback.callback());
1195 if (rv == ERR_IO_PENDING)
1196 rv = callback.WaitForResult();
1197 EXPECT_EQ(OK, rv);
1199 const char request_text[] = "GET / HTTP/1.0\r\n\r\n";
1200 scoped_refptr<IOBuffer> request_buffer(
1201 new IOBuffer(arraysize(request_text) - 1));
1202 memcpy(request_buffer->data(), request_text, arraysize(request_text) - 1);
1204 rv = sock->Write(
1205 request_buffer.get(), arraysize(request_text) - 1, callback.callback());
1206 EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING);
1208 if (rv == ERR_IO_PENDING)
1209 rv = callback.WaitForResult();
1210 EXPECT_EQ(static_cast<int>(arraysize(request_text) - 1), rv);
1212 scoped_refptr<IOBuffer> buf(new IOBuffer(1));
1213 for (;;) {
1214 rv = sock->Read(buf.get(), 1, callback.callback());
1215 EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING);
1217 if (rv == ERR_IO_PENDING)
1218 rv = callback.WaitForResult();
1220 EXPECT_GE(rv, 0);
1221 if (rv <= 0)
1222 break;
1226 TEST_F(SSLClientSocketTest, Read_ManySmallRecords) {
1227 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS,
1228 SpawnedTestServer::kLocalhost,
1229 base::FilePath());
1230 ASSERT_TRUE(test_server.Start());
1232 AddressList addr;
1233 ASSERT_TRUE(test_server.GetAddressList(&addr));
1235 TestCompletionCallback callback;
1237 scoped_ptr<StreamSocket> real_transport(
1238 new TCPClientSocket(addr, NULL, NetLog::Source()));
1239 scoped_ptr<ReadBufferingStreamSocket> transport(
1240 new ReadBufferingStreamSocket(real_transport.Pass()));
1241 ReadBufferingStreamSocket* raw_transport = transport.get();
1242 int rv = callback.GetResult(transport->Connect(callback.callback()));
1243 ASSERT_EQ(OK, rv);
1245 scoped_ptr<SSLClientSocket> sock(
1246 CreateSSLClientSocket(transport.PassAs<StreamSocket>(),
1247 test_server.host_port_pair(),
1248 kDefaultSSLConfig));
1250 rv = callback.GetResult(sock->Connect(callback.callback()));
1251 ASSERT_EQ(OK, rv);
1252 ASSERT_TRUE(sock->IsConnected());
1254 const char request_text[] = "GET /ssl-many-small-records HTTP/1.0\r\n\r\n";
1255 scoped_refptr<IOBuffer> request_buffer(
1256 new IOBuffer(arraysize(request_text) - 1));
1257 memcpy(request_buffer->data(), request_text, arraysize(request_text) - 1);
1259 rv = callback.GetResult(sock->Write(
1260 request_buffer.get(), arraysize(request_text) - 1, callback.callback()));
1261 ASSERT_GT(rv, 0);
1262 ASSERT_EQ(static_cast<int>(arraysize(request_text) - 1), rv);
1264 // Note: This relies on SSLClientSocketNSS attempting to read up to 17K of
1265 // data (the max SSL record size) at a time. Ensure that at least 15K worth
1266 // of SSL data is buffered first. The 15K of buffered data is made up of
1267 // many smaller SSL records (the TestServer writes along 1350 byte
1268 // plaintext boundaries), although there may also be a few records that are
1269 // smaller or larger, due to timing and SSL False Start.
1270 // 15K was chosen because 15K is smaller than the 17K (max) read issued by
1271 // the SSLClientSocket implementation, and larger than the minimum amount
1272 // of ciphertext necessary to contain the 8K of plaintext requested below.
1273 raw_transport->SetBufferSize(15000);
1275 scoped_refptr<IOBuffer> buffer(new IOBuffer(8192));
1276 rv = callback.GetResult(sock->Read(buffer.get(), 8192, callback.callback()));
1277 ASSERT_EQ(rv, 8192);
1280 TEST_F(SSLClientSocketTest, Read_Interrupted) {
1281 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS,
1282 SpawnedTestServer::kLocalhost,
1283 base::FilePath());
1284 ASSERT_TRUE(test_server.Start());
1286 AddressList addr;
1287 ASSERT_TRUE(test_server.GetAddressList(&addr));
1289 TestCompletionCallback callback;
1290 scoped_ptr<StreamSocket> transport(
1291 new TCPClientSocket(addr, NULL, NetLog::Source()));
1292 int rv = transport->Connect(callback.callback());
1293 if (rv == ERR_IO_PENDING)
1294 rv = callback.WaitForResult();
1295 EXPECT_EQ(OK, rv);
1297 scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
1298 transport.Pass(), test_server.host_port_pair(), kDefaultSSLConfig));
1300 rv = sock->Connect(callback.callback());
1301 if (rv == ERR_IO_PENDING)
1302 rv = callback.WaitForResult();
1303 EXPECT_EQ(OK, rv);
1305 const char request_text[] = "GET / HTTP/1.0\r\n\r\n";
1306 scoped_refptr<IOBuffer> request_buffer(
1307 new IOBuffer(arraysize(request_text) - 1));
1308 memcpy(request_buffer->data(), request_text, arraysize(request_text) - 1);
1310 rv = sock->Write(
1311 request_buffer.get(), arraysize(request_text) - 1, callback.callback());
1312 EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING);
1314 if (rv == ERR_IO_PENDING)
1315 rv = callback.WaitForResult();
1316 EXPECT_EQ(static_cast<int>(arraysize(request_text) - 1), rv);
1318 // Do a partial read and then exit. This test should not crash!
1319 scoped_refptr<IOBuffer> buf(new IOBuffer(512));
1320 rv = sock->Read(buf.get(), 512, callback.callback());
1321 EXPECT_TRUE(rv > 0 || rv == ERR_IO_PENDING);
1323 if (rv == ERR_IO_PENDING)
1324 rv = callback.WaitForResult();
1326 EXPECT_GT(rv, 0);
1329 TEST_F(SSLClientSocketTest, Read_FullLogging) {
1330 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS,
1331 SpawnedTestServer::kLocalhost,
1332 base::FilePath());
1333 ASSERT_TRUE(test_server.Start());
1335 AddressList addr;
1336 ASSERT_TRUE(test_server.GetAddressList(&addr));
1338 TestCompletionCallback callback;
1339 CapturingNetLog log;
1340 log.SetLogLevel(NetLog::LOG_ALL);
1341 scoped_ptr<StreamSocket> transport(
1342 new TCPClientSocket(addr, &log, NetLog::Source()));
1343 int rv = transport->Connect(callback.callback());
1344 if (rv == ERR_IO_PENDING)
1345 rv = callback.WaitForResult();
1346 EXPECT_EQ(OK, rv);
1348 scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
1349 transport.Pass(), test_server.host_port_pair(), kDefaultSSLConfig));
1351 rv = sock->Connect(callback.callback());
1352 if (rv == ERR_IO_PENDING)
1353 rv = callback.WaitForResult();
1354 EXPECT_EQ(OK, rv);
1355 EXPECT_TRUE(sock->IsConnected());
1357 const char request_text[] = "GET / HTTP/1.0\r\n\r\n";
1358 scoped_refptr<IOBuffer> request_buffer(
1359 new IOBuffer(arraysize(request_text) - 1));
1360 memcpy(request_buffer->data(), request_text, arraysize(request_text) - 1);
1362 rv = sock->Write(
1363 request_buffer.get(), arraysize(request_text) - 1, callback.callback());
1364 EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING);
1366 if (rv == ERR_IO_PENDING)
1367 rv = callback.WaitForResult();
1368 EXPECT_EQ(static_cast<int>(arraysize(request_text) - 1), rv);
1370 CapturingNetLog::CapturedEntryList entries;
1371 log.GetEntries(&entries);
1372 size_t last_index = ExpectLogContainsSomewhereAfter(
1373 entries, 5, NetLog::TYPE_SSL_SOCKET_BYTES_SENT, NetLog::PHASE_NONE);
1375 scoped_refptr<IOBuffer> buf(new IOBuffer(4096));
1376 for (;;) {
1377 rv = sock->Read(buf.get(), 4096, callback.callback());
1378 EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING);
1380 if (rv == ERR_IO_PENDING)
1381 rv = callback.WaitForResult();
1383 EXPECT_GE(rv, 0);
1384 if (rv <= 0)
1385 break;
1387 log.GetEntries(&entries);
1388 last_index =
1389 ExpectLogContainsSomewhereAfter(entries,
1390 last_index + 1,
1391 NetLog::TYPE_SSL_SOCKET_BYTES_RECEIVED,
1392 NetLog::PHASE_NONE);
1396 // Regression test for http://crbug.com/42538
1397 TEST_F(SSLClientSocketTest, PrematureApplicationData) {
1398 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS,
1399 SpawnedTestServer::kLocalhost,
1400 base::FilePath());
1401 ASSERT_TRUE(test_server.Start());
1403 AddressList addr;
1404 TestCompletionCallback callback;
1406 static const unsigned char application_data[] = {
1407 0x17, 0x03, 0x01, 0x00, 0x4a, 0x02, 0x00, 0x00, 0x46, 0x03, 0x01, 0x4b,
1408 0xc2, 0xf8, 0xb2, 0xc1, 0x56, 0x42, 0xb9, 0x57, 0x7f, 0xde, 0x87, 0x46,
1409 0xf7, 0xa3, 0x52, 0x42, 0x21, 0xf0, 0x13, 0x1c, 0x9c, 0x83, 0x88, 0xd6,
1410 0x93, 0x0c, 0xf6, 0x36, 0x30, 0x05, 0x7e, 0x20, 0xb5, 0xb5, 0x73, 0x36,
1411 0x53, 0x83, 0x0a, 0xfc, 0x17, 0x63, 0xbf, 0xa0, 0xe4, 0x42, 0x90, 0x0d,
1412 0x2f, 0x18, 0x6d, 0x20, 0xd8, 0x36, 0x3f, 0xfc, 0xe6, 0x01, 0xfa, 0x0f,
1413 0xa5, 0x75, 0x7f, 0x09, 0x00, 0x04, 0x00, 0x16, 0x03, 0x01, 0x11, 0x57,
1414 0x0b, 0x00, 0x11, 0x53, 0x00, 0x11, 0x50, 0x00, 0x06, 0x22, 0x30, 0x82,
1415 0x06, 0x1e, 0x30, 0x82, 0x05, 0x06, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
1416 0x0a};
1418 // All reads and writes complete synchronously (async=false).
1419 MockRead data_reads[] = {
1420 MockRead(SYNCHRONOUS,
1421 reinterpret_cast<const char*>(application_data),
1422 arraysize(application_data)),
1423 MockRead(SYNCHRONOUS, OK), };
1425 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1427 scoped_ptr<StreamSocket> transport(
1428 new MockTCPClientSocket(addr, NULL, &data));
1429 int rv = transport->Connect(callback.callback());
1430 if (rv == ERR_IO_PENDING)
1431 rv = callback.WaitForResult();
1432 EXPECT_EQ(OK, rv);
1434 scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
1435 transport.Pass(), test_server.host_port_pair(), kDefaultSSLConfig));
1437 rv = sock->Connect(callback.callback());
1438 if (rv == ERR_IO_PENDING)
1439 rv = callback.WaitForResult();
1440 EXPECT_EQ(ERR_SSL_PROTOCOL_ERROR, rv);
1443 TEST_F(SSLClientSocketTest, CipherSuiteDisables) {
1444 // Rather than exhaustively disabling every RC4 ciphersuite defined at
1445 // http://www.iana.org/assignments/tls-parameters/tls-parameters.xml,
1446 // only disabling those cipher suites that the test server actually
1447 // implements.
1448 const uint16 kCiphersToDisable[] = {0x0005, // TLS_RSA_WITH_RC4_128_SHA
1451 SpawnedTestServer::SSLOptions ssl_options;
1452 // Enable only RC4 on the test server.
1453 ssl_options.bulk_ciphers = SpawnedTestServer::SSLOptions::BULK_CIPHER_RC4;
1454 SpawnedTestServer test_server(
1455 SpawnedTestServer::TYPE_HTTPS, ssl_options, base::FilePath());
1456 ASSERT_TRUE(test_server.Start());
1458 AddressList addr;
1459 ASSERT_TRUE(test_server.GetAddressList(&addr));
1461 TestCompletionCallback callback;
1462 CapturingNetLog log;
1463 scoped_ptr<StreamSocket> transport(
1464 new TCPClientSocket(addr, &log, NetLog::Source()));
1465 int rv = transport->Connect(callback.callback());
1466 if (rv == ERR_IO_PENDING)
1467 rv = callback.WaitForResult();
1468 EXPECT_EQ(OK, rv);
1470 SSLConfig ssl_config;
1471 for (size_t i = 0; i < arraysize(kCiphersToDisable); ++i)
1472 ssl_config.disabled_cipher_suites.push_back(kCiphersToDisable[i]);
1474 scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
1475 transport.Pass(), test_server.host_port_pair(), ssl_config));
1477 EXPECT_FALSE(sock->IsConnected());
1479 rv = sock->Connect(callback.callback());
1480 CapturingNetLog::CapturedEntryList entries;
1481 log.GetEntries(&entries);
1482 EXPECT_TRUE(LogContainsBeginEvent(entries, 5, NetLog::TYPE_SSL_CONNECT));
1484 // NSS has special handling that maps a handshake_failure alert received
1485 // immediately after a client_hello to be a mismatched cipher suite error,
1486 // leading to ERR_SSL_VERSION_OR_CIPHER_MISMATCH. When using OpenSSL or
1487 // Secure Transport (OS X), the handshake_failure is bubbled up without any
1488 // interpretation, leading to ERR_SSL_PROTOCOL_ERROR. Either way, a failure
1489 // indicates that no cipher suite was negotiated with the test server.
1490 if (rv == ERR_IO_PENDING)
1491 rv = callback.WaitForResult();
1492 EXPECT_TRUE(rv == ERR_SSL_VERSION_OR_CIPHER_MISMATCH ||
1493 rv == ERR_SSL_PROTOCOL_ERROR);
1494 // The exact ordering differs between SSLClientSocketNSS (which issues an
1495 // extra read) and SSLClientSocketMac (which does not). Just make sure the
1496 // error appears somewhere in the log.
1497 log.GetEntries(&entries);
1498 ExpectLogContainsSomewhere(
1499 entries, 0, NetLog::TYPE_SSL_HANDSHAKE_ERROR, NetLog::PHASE_NONE);
1501 // We cannot test sock->IsConnected(), as the NSS implementation disconnects
1502 // the socket when it encounters an error, whereas other implementations
1503 // leave it connected.
1504 // Because this an error that the test server is mutually aware of, as opposed
1505 // to being an error such as a certificate name mismatch, which is
1506 // client-only, the exact index of the SSL connect end depends on how
1507 // quickly the test server closes the underlying socket. If the test server
1508 // closes before the IO message loop pumps messages, there may be a 0-byte
1509 // Read event in the NetLog due to TCPClientSocket picking up the EOF. As a
1510 // result, the SSL connect end event will be the second-to-last entry,
1511 // rather than the last entry.
1512 EXPECT_TRUE(LogContainsSSLConnectEndEvent(entries, -1) ||
1513 LogContainsSSLConnectEndEvent(entries, -2));
1516 // When creating an SSLClientSocket, it is allowed to pass in a
1517 // ClientSocketHandle that is not obtained from a client socket pool.
1518 // Here we verify that such a simple ClientSocketHandle, not associated with any
1519 // client socket pool, can be destroyed safely.
1520 TEST_F(SSLClientSocketTest, ClientSocketHandleNotFromPool) {
1521 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS,
1522 SpawnedTestServer::kLocalhost,
1523 base::FilePath());
1524 ASSERT_TRUE(test_server.Start());
1526 AddressList addr;
1527 ASSERT_TRUE(test_server.GetAddressList(&addr));
1529 TestCompletionCallback callback;
1530 scoped_ptr<StreamSocket> transport(
1531 new TCPClientSocket(addr, NULL, NetLog::Source()));
1532 int rv = transport->Connect(callback.callback());
1533 if (rv == ERR_IO_PENDING)
1534 rv = callback.WaitForResult();
1535 EXPECT_EQ(OK, rv);
1537 scoped_ptr<ClientSocketHandle> socket_handle(new ClientSocketHandle());
1538 socket_handle->SetSocket(transport.Pass());
1540 scoped_ptr<SSLClientSocket> sock(
1541 socket_factory_->CreateSSLClientSocket(socket_handle.Pass(),
1542 test_server.host_port_pair(),
1543 kDefaultSSLConfig,
1544 context_));
1546 EXPECT_FALSE(sock->IsConnected());
1547 rv = sock->Connect(callback.callback());
1548 if (rv == ERR_IO_PENDING)
1549 rv = callback.WaitForResult();
1550 EXPECT_EQ(OK, rv);
1553 // Verifies that SSLClientSocket::ExportKeyingMaterial return a success
1554 // code and different keying label results in different keying material.
1555 TEST_F(SSLClientSocketTest, ExportKeyingMaterial) {
1556 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS,
1557 SpawnedTestServer::kLocalhost,
1558 base::FilePath());
1559 ASSERT_TRUE(test_server.Start());
1561 AddressList addr;
1562 ASSERT_TRUE(test_server.GetAddressList(&addr));
1564 TestCompletionCallback callback;
1566 scoped_ptr<StreamSocket> transport(
1567 new TCPClientSocket(addr, NULL, NetLog::Source()));
1568 int rv = transport->Connect(callback.callback());
1569 if (rv == ERR_IO_PENDING)
1570 rv = callback.WaitForResult();
1571 EXPECT_EQ(OK, rv);
1573 scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
1574 transport.Pass(), test_server.host_port_pair(), kDefaultSSLConfig));
1576 rv = sock->Connect(callback.callback());
1577 if (rv == ERR_IO_PENDING)
1578 rv = callback.WaitForResult();
1579 EXPECT_EQ(OK, rv);
1580 EXPECT_TRUE(sock->IsConnected());
1582 const int kKeyingMaterialSize = 32;
1583 const char* kKeyingLabel1 = "client-socket-test-1";
1584 const char* kKeyingContext = "";
1585 unsigned char client_out1[kKeyingMaterialSize];
1586 memset(client_out1, 0, sizeof(client_out1));
1587 rv = sock->ExportKeyingMaterial(
1588 kKeyingLabel1, false, kKeyingContext, client_out1, sizeof(client_out1));
1589 EXPECT_EQ(rv, OK);
1591 const char* kKeyingLabel2 = "client-socket-test-2";
1592 unsigned char client_out2[kKeyingMaterialSize];
1593 memset(client_out2, 0, sizeof(client_out2));
1594 rv = sock->ExportKeyingMaterial(
1595 kKeyingLabel2, false, kKeyingContext, client_out2, sizeof(client_out2));
1596 EXPECT_EQ(rv, OK);
1597 EXPECT_NE(memcmp(client_out1, client_out2, kKeyingMaterialSize), 0);
1600 // Verifies that SSLClientSocket::ClearSessionCache can be called without
1601 // explicit NSS initialization.
1602 TEST(SSLClientSocket, ClearSessionCache) {
1603 SSLClientSocket::ClearSessionCache();
1606 // This tests that SSLInfo contains a properly re-constructed certificate
1607 // chain. That, in turn, verifies that GetSSLInfo is giving us the chain as
1608 // verified, not the chain as served by the server. (They may be different.)
1610 // CERT_CHAIN_WRONG_ROOT is redundant-server-chain.pem. It contains A
1611 // (end-entity) -> B -> C, and C is signed by D. redundant-validated-chain.pem
1612 // contains a chain of A -> B -> C2, where C2 is the same public key as C, but
1613 // a self-signed root. Such a situation can occur when a new root (C2) is
1614 // cross-certified by an old root (D) and has two different versions of its
1615 // floating around. Servers may supply C2 as an intermediate, but the
1616 // SSLClientSocket should return the chain that was verified, from
1617 // verify_result, instead.
1618 TEST_F(SSLClientSocketTest, VerifyReturnChainProperlyOrdered) {
1619 // By default, cause the CertVerifier to treat all certificates as
1620 // expired.
1621 cert_verifier_->set_default_result(ERR_CERT_DATE_INVALID);
1623 // We will expect SSLInfo to ultimately contain this chain.
1624 CertificateList certs =
1625 CreateCertificateListFromFile(GetTestCertsDirectory(),
1626 "redundant-validated-chain.pem",
1627 X509Certificate::FORMAT_AUTO);
1628 ASSERT_EQ(3U, certs.size());
1630 X509Certificate::OSCertHandles temp_intermediates;
1631 temp_intermediates.push_back(certs[1]->os_cert_handle());
1632 temp_intermediates.push_back(certs[2]->os_cert_handle());
1634 CertVerifyResult verify_result;
1635 verify_result.verified_cert = X509Certificate::CreateFromHandle(
1636 certs[0]->os_cert_handle(), temp_intermediates);
1638 // Add a rule that maps the server cert (A) to the chain of A->B->C2
1639 // rather than A->B->C.
1640 cert_verifier_->AddResultForCert(certs[0].get(), verify_result, OK);
1642 // Load and install the root for the validated chain.
1643 scoped_refptr<X509Certificate> root_cert = ImportCertFromFile(
1644 GetTestCertsDirectory(), "redundant-validated-chain-root.pem");
1645 ASSERT_NE(static_cast<X509Certificate*>(NULL), root_cert);
1646 ScopedTestRoot scoped_root(root_cert.get());
1648 // Set up a test server with CERT_CHAIN_WRONG_ROOT.
1649 SpawnedTestServer::SSLOptions ssl_options(
1650 SpawnedTestServer::SSLOptions::CERT_CHAIN_WRONG_ROOT);
1651 SpawnedTestServer test_server(
1652 SpawnedTestServer::TYPE_HTTPS,
1653 ssl_options,
1654 base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
1655 ASSERT_TRUE(test_server.Start());
1657 AddressList addr;
1658 ASSERT_TRUE(test_server.GetAddressList(&addr));
1660 TestCompletionCallback callback;
1661 CapturingNetLog log;
1662 scoped_ptr<StreamSocket> transport(
1663 new TCPClientSocket(addr, &log, NetLog::Source()));
1664 int rv = transport->Connect(callback.callback());
1665 if (rv == ERR_IO_PENDING)
1666 rv = callback.WaitForResult();
1667 EXPECT_EQ(OK, rv);
1669 scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
1670 transport.Pass(), test_server.host_port_pair(), kDefaultSSLConfig));
1671 EXPECT_FALSE(sock->IsConnected());
1672 rv = sock->Connect(callback.callback());
1674 CapturingNetLog::CapturedEntryList entries;
1675 log.GetEntries(&entries);
1676 EXPECT_TRUE(LogContainsBeginEvent(entries, 5, NetLog::TYPE_SSL_CONNECT));
1677 if (rv == ERR_IO_PENDING)
1678 rv = callback.WaitForResult();
1680 EXPECT_EQ(OK, rv);
1681 EXPECT_TRUE(sock->IsConnected());
1682 log.GetEntries(&entries);
1683 EXPECT_TRUE(LogContainsSSLConnectEndEvent(entries, -1));
1685 SSLInfo ssl_info;
1686 sock->GetSSLInfo(&ssl_info);
1688 // Verify that SSLInfo contains the corrected re-constructed chain A -> B
1689 // -> C2.
1690 const X509Certificate::OSCertHandles& intermediates =
1691 ssl_info.cert->GetIntermediateCertificates();
1692 ASSERT_EQ(2U, intermediates.size());
1693 EXPECT_TRUE(X509Certificate::IsSameOSCert(ssl_info.cert->os_cert_handle(),
1694 certs[0]->os_cert_handle()));
1695 EXPECT_TRUE(X509Certificate::IsSameOSCert(intermediates[0],
1696 certs[1]->os_cert_handle()));
1697 EXPECT_TRUE(X509Certificate::IsSameOSCert(intermediates[1],
1698 certs[2]->os_cert_handle()));
1700 sock->Disconnect();
1701 EXPECT_FALSE(sock->IsConnected());
1704 // Verifies the correctness of GetSSLCertRequestInfo.
1705 class SSLClientSocketCertRequestInfoTest : public SSLClientSocketTest {
1706 protected:
1707 // Creates a test server with the given SSLOptions, connects to it and returns
1708 // the SSLCertRequestInfo reported by the socket.
1709 scoped_refptr<SSLCertRequestInfo> GetCertRequest(
1710 SpawnedTestServer::SSLOptions ssl_options) {
1711 SpawnedTestServer test_server(
1712 SpawnedTestServer::TYPE_HTTPS, ssl_options, base::FilePath());
1713 if (!test_server.Start())
1714 return NULL;
1716 AddressList addr;
1717 if (!test_server.GetAddressList(&addr))
1718 return NULL;
1720 TestCompletionCallback callback;
1721 CapturingNetLog log;
1722 scoped_ptr<StreamSocket> transport(
1723 new TCPClientSocket(addr, &log, NetLog::Source()));
1724 int rv = transport->Connect(callback.callback());
1725 if (rv == ERR_IO_PENDING)
1726 rv = callback.WaitForResult();
1727 EXPECT_EQ(OK, rv);
1729 scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket(
1730 transport.Pass(), test_server.host_port_pair(), kDefaultSSLConfig));
1731 EXPECT_FALSE(sock->IsConnected());
1733 rv = sock->Connect(callback.callback());
1734 if (rv == ERR_IO_PENDING)
1735 rv = callback.WaitForResult();
1736 scoped_refptr<SSLCertRequestInfo> request_info = new SSLCertRequestInfo();
1737 sock->GetSSLCertRequestInfo(request_info.get());
1738 sock->Disconnect();
1739 EXPECT_FALSE(sock->IsConnected());
1741 return request_info;
1745 TEST_F(SSLClientSocketCertRequestInfoTest, NoAuthorities) {
1746 SpawnedTestServer::SSLOptions ssl_options;
1747 ssl_options.request_client_certificate = true;
1748 scoped_refptr<SSLCertRequestInfo> request_info = GetCertRequest(ssl_options);
1749 ASSERT_TRUE(request_info.get());
1750 EXPECT_EQ(0u, request_info->cert_authorities.size());
1753 TEST_F(SSLClientSocketCertRequestInfoTest, TwoAuthorities) {
1754 const base::FilePath::CharType kThawteFile[] =
1755 FILE_PATH_LITERAL("thawte.single.pem");
1756 const unsigned char kThawteDN[] = {
1757 0x30, 0x4c, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
1758 0x02, 0x5a, 0x41, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0a,
1759 0x13, 0x1c, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x43, 0x6f, 0x6e,
1760 0x73, 0x75, 0x6c, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x28, 0x50, 0x74, 0x79,
1761 0x29, 0x20, 0x4c, 0x74, 0x64, 0x2e, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03,
1762 0x55, 0x04, 0x03, 0x13, 0x0d, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20,
1763 0x53, 0x47, 0x43, 0x20, 0x43, 0x41};
1764 const size_t kThawteLen = sizeof(kThawteDN);
1766 const base::FilePath::CharType kDiginotarFile[] =
1767 FILE_PATH_LITERAL("diginotar_root_ca.pem");
1768 const unsigned char kDiginotarDN[] = {
1769 0x30, 0x5f, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
1770 0x02, 0x4e, 0x4c, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0a,
1771 0x13, 0x09, 0x44, 0x69, 0x67, 0x69, 0x4e, 0x6f, 0x74, 0x61, 0x72, 0x31,
1772 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x44, 0x69,
1773 0x67, 0x69, 0x4e, 0x6f, 0x74, 0x61, 0x72, 0x20, 0x52, 0x6f, 0x6f, 0x74,
1774 0x20, 0x43, 0x41, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x09, 0x2a, 0x86, 0x48,
1775 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x11, 0x69, 0x6e, 0x66, 0x6f,
1776 0x40, 0x64, 0x69, 0x67, 0x69, 0x6e, 0x6f, 0x74, 0x61, 0x72, 0x2e, 0x6e,
1777 0x6c};
1778 const size_t kDiginotarLen = sizeof(kDiginotarDN);
1780 SpawnedTestServer::SSLOptions ssl_options;
1781 ssl_options.request_client_certificate = true;
1782 ssl_options.client_authorities.push_back(
1783 GetTestClientCertsDirectory().Append(kThawteFile));
1784 ssl_options.client_authorities.push_back(
1785 GetTestClientCertsDirectory().Append(kDiginotarFile));
1786 scoped_refptr<SSLCertRequestInfo> request_info = GetCertRequest(ssl_options);
1787 ASSERT_TRUE(request_info.get());
1788 ASSERT_EQ(2u, request_info->cert_authorities.size());
1789 EXPECT_EQ(std::string(reinterpret_cast<const char*>(kThawteDN), kThawteLen),
1790 request_info->cert_authorities[0]);
1791 EXPECT_EQ(
1792 std::string(reinterpret_cast<const char*>(kDiginotarDN), kDiginotarLen),
1793 request_info->cert_authorities[1]);
1796 } // namespace
1798 } // namespace net