OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "net/socket/ssl_client_socket.h" | |
6 | |
7 #include "base/callback_helpers.h" | |
8 #include "base/memory/ref_counted.h" | |
9 #include "base/run_loop.h" | |
10 #include "base/time/time.h" | |
11 #include "net/base/address_list.h" | |
12 #include "net/base/io_buffer.h" | |
13 #include "net/base/net_errors.h" | |
14 #include "net/base/net_log.h" | |
15 #include "net/base/net_log_unittest.h" | |
16 #include "net/base/test_completion_callback.h" | |
17 #include "net/base/test_data_directory.h" | |
18 #include "net/cert/asn1_util.h" | |
19 #include "net/cert/ct_verifier.h" | |
20 #include "net/cert/mock_cert_verifier.h" | |
21 #include "net/cert/test_root_certs.h" | |
22 #include "net/dns/host_resolver.h" | |
23 #include "net/http/transport_security_state.h" | |
24 #include "net/socket/client_socket_factory.h" | |
25 #include "net/socket/client_socket_handle.h" | |
26 #include "net/socket/socket_test_util.h" | |
27 #include "net/socket/tcp_client_socket.h" | |
28 #include "net/ssl/channel_id_service.h" | |
29 #include "net/ssl/default_channel_id_store.h" | |
30 #include "net/ssl/ssl_cert_request_info.h" | |
31 #include "net/ssl/ssl_config_service.h" | |
32 #include "net/test/cert_test_util.h" | |
33 #include "net/test/spawned_test_server/spawned_test_server.h" | |
34 #include "testing/gmock/include/gmock/gmock.h" | |
35 #include "testing/gtest/include/gtest/gtest.h" | |
36 #include "testing/platform_test.h" | |
37 | |
38 //----------------------------------------------------------------------------- | |
39 | |
40 using testing::_; | |
41 using testing::Return; | |
42 using testing::Truly; | |
43 | |
44 namespace net { | |
45 | |
46 namespace { | |
47 | |
48 // WrappedStreamSocket is a base class that wraps an existing StreamSocket, | |
49 // forwarding the Socket and StreamSocket interfaces to the underlying | |
50 // transport. | |
51 // This is to provide a common base class for subclasses to override specific | |
52 // StreamSocket methods for testing, while still communicating with a 'real' | |
53 // StreamSocket. | |
54 class WrappedStreamSocket : public StreamSocket { | |
55 public: | |
56 explicit WrappedStreamSocket(scoped_ptr<StreamSocket> transport) | |
57 : transport_(transport.Pass()) {} | |
58 ~WrappedStreamSocket() override {} | |
59 | |
60 // StreamSocket implementation: | |
61 int Connect(const CompletionCallback& callback) override { | |
62 return transport_->Connect(callback); | |
63 } | |
64 void Disconnect() override { transport_->Disconnect(); } | |
65 bool IsConnected() const override { return transport_->IsConnected(); } | |
66 bool IsConnectedAndIdle() const override { | |
67 return transport_->IsConnectedAndIdle(); | |
68 } | |
69 int GetPeerAddress(IPEndPoint* address) const override { | |
70 return transport_->GetPeerAddress(address); | |
71 } | |
72 int GetLocalAddress(IPEndPoint* address) const override { | |
73 return transport_->GetLocalAddress(address); | |
74 } | |
75 const BoundNetLog& NetLog() const override { return transport_->NetLog(); } | |
76 void SetSubresourceSpeculation() override { | |
77 transport_->SetSubresourceSpeculation(); | |
78 } | |
79 void SetOmniboxSpeculation() override { transport_->SetOmniboxSpeculation(); } | |
80 bool WasEverUsed() const override { return transport_->WasEverUsed(); } | |
81 bool UsingTCPFastOpen() const override { | |
82 return transport_->UsingTCPFastOpen(); | |
83 } | |
84 bool WasNpnNegotiated() const override { | |
85 return transport_->WasNpnNegotiated(); | |
86 } | |
87 NextProto GetNegotiatedProtocol() const override { | |
88 return transport_->GetNegotiatedProtocol(); | |
89 } | |
90 bool GetSSLInfo(SSLInfo* ssl_info) override { | |
91 return transport_->GetSSLInfo(ssl_info); | |
92 } | |
93 | |
94 // Socket implementation: | |
95 int Read(IOBuffer* buf, | |
96 int buf_len, | |
97 const CompletionCallback& callback) override { | |
98 return transport_->Read(buf, buf_len, callback); | |
99 } | |
100 int Write(IOBuffer* buf, | |
101 int buf_len, | |
102 const CompletionCallback& callback) override { | |
103 return transport_->Write(buf, buf_len, callback); | |
104 } | |
105 int SetReceiveBufferSize(int32 size) override { | |
106 return transport_->SetReceiveBufferSize(size); | |
107 } | |
108 int SetSendBufferSize(int32 size) override { | |
109 return transport_->SetSendBufferSize(size); | |
110 } | |
111 | |
112 protected: | |
113 scoped_ptr<StreamSocket> transport_; | |
114 }; | |
115 | |
116 // ReadBufferingStreamSocket is a wrapper for an existing StreamSocket that | |
117 // will ensure a certain amount of data is internally buffered before | |
118 // satisfying a Read() request. It exists to mimic OS-level internal | |
119 // buffering, but in a way to guarantee that X number of bytes will be | |
120 // returned to callers of Read(), regardless of how quickly the OS receives | |
121 // them from the TestServer. | |
122 class ReadBufferingStreamSocket : public WrappedStreamSocket { | |
123 public: | |
124 explicit ReadBufferingStreamSocket(scoped_ptr<StreamSocket> transport); | |
125 ~ReadBufferingStreamSocket() override {} | |
126 | |
127 // Socket implementation: | |
128 int Read(IOBuffer* buf, | |
129 int buf_len, | |
130 const CompletionCallback& callback) override; | |
131 | |
132 // Sets the internal buffer to |size|. This must not be greater than | |
133 // the largest value supplied to Read() - that is, it does not handle | |
134 // having "leftovers" at the end of Read(). | |
135 // Each call to Read() will be prevented from completion until at least | |
136 // |size| data has been read. | |
137 // Set to 0 to turn off buffering, causing Read() to transparently | |
138 // read via the underlying transport. | |
139 void SetBufferSize(int size); | |
140 | |
141 private: | |
142 enum State { | |
143 STATE_NONE, | |
144 STATE_READ, | |
145 STATE_READ_COMPLETE, | |
146 }; | |
147 | |
148 int DoLoop(int result); | |
149 int DoRead(); | |
150 int DoReadComplete(int result); | |
151 void OnReadCompleted(int result); | |
152 | |
153 State state_; | |
154 scoped_refptr<GrowableIOBuffer> read_buffer_; | |
155 int buffer_size_; | |
156 | |
157 scoped_refptr<IOBuffer> user_read_buf_; | |
158 CompletionCallback user_read_callback_; | |
159 }; | |
160 | |
161 ReadBufferingStreamSocket::ReadBufferingStreamSocket( | |
162 scoped_ptr<StreamSocket> transport) | |
163 : WrappedStreamSocket(transport.Pass()), | |
164 read_buffer_(new GrowableIOBuffer()), | |
165 buffer_size_(0) {} | |
166 | |
167 void ReadBufferingStreamSocket::SetBufferSize(int size) { | |
168 DCHECK(!user_read_buf_.get()); | |
169 buffer_size_ = size; | |
170 read_buffer_->SetCapacity(size); | |
171 } | |
172 | |
173 int ReadBufferingStreamSocket::Read(IOBuffer* buf, | |
174 int buf_len, | |
175 const CompletionCallback& callback) { | |
176 if (buffer_size_ == 0) | |
177 return transport_->Read(buf, buf_len, callback); | |
178 | |
179 if (buf_len < buffer_size_) | |
180 return ERR_UNEXPECTED; | |
181 | |
182 state_ = STATE_READ; | |
183 user_read_buf_ = buf; | |
184 int result = DoLoop(OK); | |
185 if (result == ERR_IO_PENDING) | |
186 user_read_callback_ = callback; | |
187 else | |
188 user_read_buf_ = NULL; | |
189 return result; | |
190 } | |
191 | |
192 int ReadBufferingStreamSocket::DoLoop(int result) { | |
193 int rv = result; | |
194 do { | |
195 State current_state = state_; | |
196 state_ = STATE_NONE; | |
197 switch (current_state) { | |
198 case STATE_READ: | |
199 rv = DoRead(); | |
200 break; | |
201 case STATE_READ_COMPLETE: | |
202 rv = DoReadComplete(rv); | |
203 break; | |
204 case STATE_NONE: | |
205 default: | |
206 NOTREACHED() << "Unexpected state: " << current_state; | |
207 rv = ERR_UNEXPECTED; | |
208 break; | |
209 } | |
210 } while (rv != ERR_IO_PENDING && state_ != STATE_NONE); | |
211 return rv; | |
212 } | |
213 | |
214 int ReadBufferingStreamSocket::DoRead() { | |
215 state_ = STATE_READ_COMPLETE; | |
216 int rv = | |
217 transport_->Read(read_buffer_.get(), | |
218 read_buffer_->RemainingCapacity(), | |
219 base::Bind(&ReadBufferingStreamSocket::OnReadCompleted, | |
220 base::Unretained(this))); | |
221 return rv; | |
222 } | |
223 | |
224 int ReadBufferingStreamSocket::DoReadComplete(int result) { | |
225 state_ = STATE_NONE; | |
226 if (result <= 0) | |
227 return result; | |
228 | |
229 read_buffer_->set_offset(read_buffer_->offset() + result); | |
230 if (read_buffer_->RemainingCapacity() > 0) { | |
231 state_ = STATE_READ; | |
232 return OK; | |
233 } | |
234 | |
235 memcpy(user_read_buf_->data(), | |
236 read_buffer_->StartOfBuffer(), | |
237 read_buffer_->capacity()); | |
238 read_buffer_->set_offset(0); | |
239 return read_buffer_->capacity(); | |
240 } | |
241 | |
242 void ReadBufferingStreamSocket::OnReadCompleted(int result) { | |
243 result = DoLoop(result); | |
244 if (result == ERR_IO_PENDING) | |
245 return; | |
246 | |
247 user_read_buf_ = NULL; | |
248 base::ResetAndReturn(&user_read_callback_).Run(result); | |
249 } | |
250 | |
251 // Simulates synchronously receiving an error during Read() or Write() | |
252 class SynchronousErrorStreamSocket : public WrappedStreamSocket { | |
253 public: | |
254 explicit SynchronousErrorStreamSocket(scoped_ptr<StreamSocket> transport); | |
255 ~SynchronousErrorStreamSocket() override {} | |
256 | |
257 // Socket implementation: | |
258 int Read(IOBuffer* buf, | |
259 int buf_len, | |
260 const CompletionCallback& callback) override; | |
261 int Write(IOBuffer* buf, | |
262 int buf_len, | |
263 const CompletionCallback& callback) override; | |
264 | |
265 // Sets the next Read() call and all future calls to return |error|. | |
266 // If there is already a pending asynchronous read, the configured error | |
267 // will not be returned until that asynchronous read has completed and Read() | |
268 // is called again. | |
269 void SetNextReadError(int error) { | |
270 DCHECK_GE(0, error); | |
271 have_read_error_ = true; | |
272 pending_read_error_ = error; | |
273 } | |
274 | |
275 // Sets the next Write() call and all future calls to return |error|. | |
276 // If there is already a pending asynchronous write, the configured error | |
277 // will not be returned until that asynchronous write has completed and | |
278 // Write() is called again. | |
279 void SetNextWriteError(int error) { | |
280 DCHECK_GE(0, error); | |
281 have_write_error_ = true; | |
282 pending_write_error_ = error; | |
283 } | |
284 | |
285 private: | |
286 bool have_read_error_; | |
287 int pending_read_error_; | |
288 | |
289 bool have_write_error_; | |
290 int pending_write_error_; | |
291 | |
292 DISALLOW_COPY_AND_ASSIGN(SynchronousErrorStreamSocket); | |
293 }; | |
294 | |
295 SynchronousErrorStreamSocket::SynchronousErrorStreamSocket( | |
296 scoped_ptr<StreamSocket> transport) | |
297 : WrappedStreamSocket(transport.Pass()), | |
298 have_read_error_(false), | |
299 pending_read_error_(OK), | |
300 have_write_error_(false), | |
301 pending_write_error_(OK) {} | |
302 | |
303 int SynchronousErrorStreamSocket::Read(IOBuffer* buf, | |
304 int buf_len, | |
305 const CompletionCallback& callback) { | |
306 if (have_read_error_) | |
307 return pending_read_error_; | |
308 return transport_->Read(buf, buf_len, callback); | |
309 } | |
310 | |
311 int SynchronousErrorStreamSocket::Write(IOBuffer* buf, | |
312 int buf_len, | |
313 const CompletionCallback& callback) { | |
314 if (have_write_error_) | |
315 return pending_write_error_; | |
316 return transport_->Write(buf, buf_len, callback); | |
317 } | |
318 | |
319 // FakeBlockingStreamSocket wraps an existing StreamSocket and simulates the | |
320 // underlying transport needing to complete things asynchronously in a | |
321 // deterministic manner (e.g.: independent of the TestServer and the OS's | |
322 // semantics). | |
323 class FakeBlockingStreamSocket : public WrappedStreamSocket { | |
324 public: | |
325 explicit FakeBlockingStreamSocket(scoped_ptr<StreamSocket> transport); | |
326 ~FakeBlockingStreamSocket() override {} | |
327 | |
328 // Socket implementation: | |
329 int Read(IOBuffer* buf, | |
330 int buf_len, | |
331 const CompletionCallback& callback) override; | |
332 int Write(IOBuffer* buf, | |
333 int buf_len, | |
334 const CompletionCallback& callback) override; | |
335 | |
336 // Blocks read results on the socket. Reads will not complete until | |
337 // UnblockReadResult() has been called and a result is ready from the | |
338 // underlying transport. Note: if BlockReadResult() is called while there is a | |
339 // hanging asynchronous Read(), that Read is blocked. | |
340 void BlockReadResult(); | |
341 void UnblockReadResult(); | |
342 | |
343 // Waits for the blocked Read() call to be complete at the underlying | |
344 // transport. | |
345 void WaitForReadResult(); | |
346 | |
347 // Causes the next call to Write() to return ERR_IO_PENDING, not beginning the | |
348 // underlying transport until UnblockWrite() has been called. Note: if there | |
349 // is a pending asynchronous write, it is NOT blocked. For purposes of | |
350 // blocking writes, data is considered to have reached the underlying | |
351 // transport as soon as Write() is called. | |
352 void BlockWrite(); | |
353 void UnblockWrite(); | |
354 | |
355 // Waits for the blocked Write() call to be scheduled. | |
356 void WaitForWrite(); | |
357 | |
358 // Returns the wrapped stream socket. | |
359 StreamSocket* transport() { return transport_.get(); } | |
360 | |
361 private: | |
362 // Handles completion from the underlying transport read. | |
363 void OnReadCompleted(int result); | |
364 | |
365 // True if read callbacks are blocked. | |
366 bool should_block_read_; | |
367 | |
368 // The user callback for the pending read call. | |
369 CompletionCallback pending_read_callback_; | |
370 | |
371 // The result for the blocked read callback, or ERR_IO_PENDING if not | |
372 // completed. | |
373 int pending_read_result_; | |
374 | |
375 // WaitForReadResult() wait loop. | |
376 scoped_ptr<base::RunLoop> read_loop_; | |
377 | |
378 // True if write calls are blocked. | |
379 bool should_block_write_; | |
380 | |
381 // The buffer for the pending write, or NULL if not scheduled. | |
382 scoped_refptr<IOBuffer> pending_write_buf_; | |
383 | |
384 // The callback for the pending write call. | |
385 CompletionCallback pending_write_callback_; | |
386 | |
387 // The length for the pending write, or -1 if not scheduled. | |
388 int pending_write_len_; | |
389 | |
390 // WaitForWrite() wait loop. | |
391 scoped_ptr<base::RunLoop> write_loop_; | |
392 }; | |
393 | |
394 FakeBlockingStreamSocket::FakeBlockingStreamSocket( | |
395 scoped_ptr<StreamSocket> transport) | |
396 : WrappedStreamSocket(transport.Pass()), | |
397 should_block_read_(false), | |
398 pending_read_result_(ERR_IO_PENDING), | |
399 should_block_write_(false), | |
400 pending_write_len_(-1) {} | |
401 | |
402 int FakeBlockingStreamSocket::Read(IOBuffer* buf, | |
403 int len, | |
404 const CompletionCallback& callback) { | |
405 DCHECK(pending_read_callback_.is_null()); | |
406 DCHECK_EQ(ERR_IO_PENDING, pending_read_result_); | |
407 DCHECK(!callback.is_null()); | |
408 | |
409 int rv = transport_->Read(buf, len, base::Bind( | |
410 &FakeBlockingStreamSocket::OnReadCompleted, base::Unretained(this))); | |
411 if (rv == ERR_IO_PENDING) { | |
412 // Save the callback to be called later. | |
413 pending_read_callback_ = callback; | |
414 } else if (should_block_read_) { | |
415 // Save the callback and read result to be called later. | |
416 pending_read_callback_ = callback; | |
417 OnReadCompleted(rv); | |
418 rv = ERR_IO_PENDING; | |
419 } | |
420 return rv; | |
421 } | |
422 | |
423 int FakeBlockingStreamSocket::Write(IOBuffer* buf, | |
424 int len, | |
425 const CompletionCallback& callback) { | |
426 DCHECK(buf); | |
427 DCHECK_LE(0, len); | |
428 | |
429 if (!should_block_write_) | |
430 return transport_->Write(buf, len, callback); | |
431 | |
432 // Schedule the write, but do nothing. | |
433 DCHECK(!pending_write_buf_.get()); | |
434 DCHECK_EQ(-1, pending_write_len_); | |
435 DCHECK(pending_write_callback_.is_null()); | |
436 DCHECK(!callback.is_null()); | |
437 pending_write_buf_ = buf; | |
438 pending_write_len_ = len; | |
439 pending_write_callback_ = callback; | |
440 | |
441 // Stop the write loop, if any. | |
442 if (write_loop_) | |
443 write_loop_->Quit(); | |
444 return ERR_IO_PENDING; | |
445 } | |
446 | |
447 void FakeBlockingStreamSocket::BlockReadResult() { | |
448 DCHECK(!should_block_read_); | |
449 should_block_read_ = true; | |
450 } | |
451 | |
452 void FakeBlockingStreamSocket::UnblockReadResult() { | |
453 DCHECK(should_block_read_); | |
454 should_block_read_ = false; | |
455 | |
456 // If the operation is still pending in the underlying transport, immediately | |
457 // return - OnReadCompleted() will handle invoking the callback once the | |
458 // transport has completed. | |
459 if (pending_read_result_ == ERR_IO_PENDING) | |
460 return; | |
461 int result = pending_read_result_; | |
462 pending_read_result_ = ERR_IO_PENDING; | |
463 base::ResetAndReturn(&pending_read_callback_).Run(result); | |
464 } | |
465 | |
466 void FakeBlockingStreamSocket::WaitForReadResult() { | |
467 DCHECK(should_block_read_); | |
468 DCHECK(!read_loop_); | |
469 | |
470 if (pending_read_result_ != ERR_IO_PENDING) | |
471 return; | |
472 read_loop_.reset(new base::RunLoop); | |
473 read_loop_->Run(); | |
474 read_loop_.reset(); | |
475 DCHECK_NE(ERR_IO_PENDING, pending_read_result_); | |
476 } | |
477 | |
478 void FakeBlockingStreamSocket::BlockWrite() { | |
479 DCHECK(!should_block_write_); | |
480 should_block_write_ = true; | |
481 } | |
482 | |
483 void FakeBlockingStreamSocket::UnblockWrite() { | |
484 DCHECK(should_block_write_); | |
485 should_block_write_ = false; | |
486 | |
487 // Do nothing if UnblockWrite() was called after BlockWrite(), | |
488 // without a Write() in between. | |
489 if (!pending_write_buf_.get()) | |
490 return; | |
491 | |
492 int rv = transport_->Write( | |
493 pending_write_buf_.get(), pending_write_len_, pending_write_callback_); | |
494 pending_write_buf_ = NULL; | |
495 pending_write_len_ = -1; | |
496 if (rv == ERR_IO_PENDING) { | |
497 pending_write_callback_.Reset(); | |
498 } else { | |
499 base::ResetAndReturn(&pending_write_callback_).Run(rv); | |
500 } | |
501 } | |
502 | |
503 void FakeBlockingStreamSocket::WaitForWrite() { | |
504 DCHECK(should_block_write_); | |
505 DCHECK(!write_loop_); | |
506 | |
507 if (pending_write_buf_.get()) | |
508 return; | |
509 write_loop_.reset(new base::RunLoop); | |
510 write_loop_->Run(); | |
511 write_loop_.reset(); | |
512 DCHECK(pending_write_buf_.get()); | |
513 } | |
514 | |
515 void FakeBlockingStreamSocket::OnReadCompleted(int result) { | |
516 DCHECK_EQ(ERR_IO_PENDING, pending_read_result_); | |
517 DCHECK(!pending_read_callback_.is_null()); | |
518 | |
519 if (should_block_read_) { | |
520 // Store the result so that the callback can be invoked once Unblock() is | |
521 // called. | |
522 pending_read_result_ = result; | |
523 | |
524 // Stop the WaitForReadResult() call if any. | |
525 if (read_loop_) | |
526 read_loop_->Quit(); | |
527 } else { | |
528 // Either the Read() was never blocked or UnblockReadResult() was called | |
529 // before the Read() completed. Either way, run the callback. | |
530 base::ResetAndReturn(&pending_read_callback_).Run(result); | |
531 } | |
532 } | |
533 | |
534 // CountingStreamSocket wraps an existing StreamSocket and maintains a count of | |
535 // reads and writes on the socket. | |
536 class CountingStreamSocket : public WrappedStreamSocket { | |
537 public: | |
538 explicit CountingStreamSocket(scoped_ptr<StreamSocket> transport) | |
539 : WrappedStreamSocket(transport.Pass()), | |
540 read_count_(0), | |
541 write_count_(0) {} | |
542 ~CountingStreamSocket() override {} | |
543 | |
544 // Socket implementation: | |
545 int Read(IOBuffer* buf, | |
546 int buf_len, | |
547 const CompletionCallback& callback) override { | |
548 read_count_++; | |
549 return transport_->Read(buf, buf_len, callback); | |
550 } | |
551 int Write(IOBuffer* buf, | |
552 int buf_len, | |
553 const CompletionCallback& callback) override { | |
554 write_count_++; | |
555 return transport_->Write(buf, buf_len, callback); | |
556 } | |
557 | |
558 int read_count() const { return read_count_; } | |
559 int write_count() const { return write_count_; } | |
560 | |
561 private: | |
562 int read_count_; | |
563 int write_count_; | |
564 }; | |
565 | |
566 // CompletionCallback that will delete the associated StreamSocket when | |
567 // the callback is invoked. | |
568 class DeleteSocketCallback : public TestCompletionCallbackBase { | |
569 public: | |
570 explicit DeleteSocketCallback(StreamSocket* socket) | |
571 : socket_(socket), | |
572 callback_(base::Bind(&DeleteSocketCallback::OnComplete, | |
573 base::Unretained(this))) {} | |
574 ~DeleteSocketCallback() override {} | |
575 | |
576 const CompletionCallback& callback() const { return callback_; } | |
577 | |
578 private: | |
579 void OnComplete(int result) { | |
580 if (socket_) { | |
581 delete socket_; | |
582 socket_ = NULL; | |
583 } else { | |
584 ADD_FAILURE() << "Deleting socket twice"; | |
585 } | |
586 SetResult(result); | |
587 } | |
588 | |
589 StreamSocket* socket_; | |
590 CompletionCallback callback_; | |
591 | |
592 DISALLOW_COPY_AND_ASSIGN(DeleteSocketCallback); | |
593 }; | |
594 | |
595 // A ChannelIDStore that always returns an error when asked for a | |
596 // channel id. | |
597 class FailingChannelIDStore : public ChannelIDStore { | |
598 int GetChannelID(const std::string& server_identifier, | |
599 base::Time* expiration_time, | |
600 std::string* private_key_result, | |
601 std::string* cert_result, | |
602 const GetChannelIDCallback& callback) override { | |
603 return ERR_UNEXPECTED; | |
604 } | |
605 void SetChannelID(const std::string& server_identifier, | |
606 base::Time creation_time, | |
607 base::Time expiration_time, | |
608 const std::string& private_key, | |
609 const std::string& cert) override {} | |
610 void DeleteChannelID(const std::string& server_identifier, | |
611 const base::Closure& completion_callback) override {} | |
612 void DeleteAllCreatedBetween( | |
613 base::Time delete_begin, | |
614 base::Time delete_end, | |
615 const base::Closure& completion_callback) override {} | |
616 void DeleteAll(const base::Closure& completion_callback) override {} | |
617 void GetAllChannelIDs(const GetChannelIDListCallback& callback) override {} | |
618 int GetChannelIDCount() override { return 0; } | |
619 void SetForceKeepSessionState() override {} | |
620 }; | |
621 | |
622 // A ChannelIDStore that asynchronously returns an error when asked for a | |
623 // channel id. | |
624 class AsyncFailingChannelIDStore : public ChannelIDStore { | |
625 int GetChannelID(const std::string& server_identifier, | |
626 base::Time* expiration_time, | |
627 std::string* private_key_result, | |
628 std::string* cert_result, | |
629 const GetChannelIDCallback& callback) override { | |
630 base::MessageLoop::current()->PostTask( | |
631 FROM_HERE, base::Bind(callback, ERR_UNEXPECTED, | |
632 server_identifier, base::Time(), "", "")); | |
633 return ERR_IO_PENDING; | |
634 } | |
635 void SetChannelID(const std::string& server_identifier, | |
636 base::Time creation_time, | |
637 base::Time expiration_time, | |
638 const std::string& private_key, | |
639 const std::string& cert) override {} | |
640 void DeleteChannelID(const std::string& server_identifier, | |
641 const base::Closure& completion_callback) override {} | |
642 void DeleteAllCreatedBetween( | |
643 base::Time delete_begin, | |
644 base::Time delete_end, | |
645 const base::Closure& completion_callback) override {} | |
646 void DeleteAll(const base::Closure& completion_callback) override {} | |
647 void GetAllChannelIDs(const GetChannelIDListCallback& callback) override {} | |
648 int GetChannelIDCount() override { return 0; } | |
649 void SetForceKeepSessionState() override {} | |
650 }; | |
651 | |
652 // A mock CTVerifier that records every call to Verify but doesn't verify | |
653 // anything. | |
654 class MockCTVerifier : public CTVerifier { | |
655 public: | |
656 MOCK_METHOD5(Verify, int(X509Certificate*, | |
657 const std::string&, | |
658 const std::string&, | |
659 ct::CTVerifyResult*, | |
660 const BoundNetLog&)); | |
661 }; | |
662 | |
663 class SSLClientSocketTest : public PlatformTest { | |
664 public: | |
665 SSLClientSocketTest() | |
666 : socket_factory_(ClientSocketFactory::GetDefaultFactory()), | |
667 cert_verifier_(new MockCertVerifier), | |
668 transport_security_state_(new TransportSecurityState), | |
669 ran_handshake_completion_callback_(false) { | |
670 cert_verifier_->set_default_result(OK); | |
671 context_.cert_verifier = cert_verifier_.get(); | |
672 context_.transport_security_state = transport_security_state_.get(); | |
673 } | |
674 | |
675 void RecordCompletedHandshake() { ran_handshake_completion_callback_ = true; } | |
676 | |
677 protected: | |
678 // The address of the spawned test server, after calling StartTestServer(). | |
679 const AddressList& addr() const { return addr_; } | |
680 | |
681 // The SpawnedTestServer object, after calling StartTestServer(). | |
682 const SpawnedTestServer* test_server() const { return test_server_.get(); } | |
683 | |
684 void SetCTVerifier(CTVerifier* ct_verifier) { | |
685 context_.cert_transparency_verifier = ct_verifier; | |
686 } | |
687 | |
688 // Starts the test server with SSL configuration |ssl_options|. Returns true | |
689 // on success. | |
690 bool StartTestServer(const SpawnedTestServer::SSLOptions& ssl_options) { | |
691 test_server_.reset(new SpawnedTestServer( | |
692 SpawnedTestServer::TYPE_HTTPS, ssl_options, base::FilePath())); | |
693 if (!test_server_->Start()) { | |
694 LOG(ERROR) << "Could not start SpawnedTestServer"; | |
695 return false; | |
696 } | |
697 | |
698 if (!test_server_->GetAddressList(&addr_)) { | |
699 LOG(ERROR) << "Could not get SpawnedTestServer address list"; | |
700 return false; | |
701 } | |
702 return true; | |
703 } | |
704 | |
705 // Sets up a TCP connection to a HTTPS server. To actually do the SSL | |
706 // handshake, follow up with call to CreateAndConnectSSLClientSocket() below. | |
707 bool ConnectToTestServer(const SpawnedTestServer::SSLOptions& ssl_options) { | |
708 if (!StartTestServer(ssl_options)) | |
709 return false; | |
710 | |
711 transport_.reset(new TCPClientSocket(addr_, &log_, NetLog::Source())); | |
712 int rv = callback_.GetResult(transport_->Connect(callback_.callback())); | |
713 if (rv != OK) { | |
714 LOG(ERROR) << "Could not connect to SpawnedTestServer"; | |
715 return false; | |
716 } | |
717 return true; | |
718 } | |
719 | |
720 scoped_ptr<SSLClientSocket> CreateSSLClientSocket( | |
721 scoped_ptr<StreamSocket> transport_socket, | |
722 const HostPortPair& host_and_port, | |
723 const SSLConfig& ssl_config) { | |
724 scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle); | |
725 connection->SetSocket(transport_socket.Pass()); | |
726 return socket_factory_->CreateSSLClientSocket( | |
727 connection.Pass(), host_and_port, ssl_config, context_); | |
728 } | |
729 | |
730 // Create an SSLClientSocket object and use it to connect to a test | |
731 // server, then wait for connection results. This must be called after | |
732 // a successful ConnectToTestServer() call. | |
733 // |ssl_config| the SSL configuration to use. | |
734 // |result| will retrieve the ::Connect() result value. | |
735 // Returns true on success, false otherwise. Success means that the socket | |
736 // could be created and its Connect() was called, not that the connection | |
737 // itself was a success. | |
738 bool CreateAndConnectSSLClientSocket(SSLConfig& ssl_config, int* result) { | |
739 sock_ = CreateSSLClientSocket( | |
740 transport_.Pass(), test_server_->host_port_pair(), ssl_config); | |
741 | |
742 if (sock_->IsConnected()) { | |
743 LOG(ERROR) << "SSL Socket prematurely connected"; | |
744 return false; | |
745 } | |
746 | |
747 *result = callback_.GetResult(sock_->Connect(callback_.callback())); | |
748 return true; | |
749 } | |
750 | |
751 ClientSocketFactory* socket_factory_; | |
752 scoped_ptr<MockCertVerifier> cert_verifier_; | |
753 scoped_ptr<TransportSecurityState> transport_security_state_; | |
754 SSLClientSocketContext context_; | |
755 scoped_ptr<SSLClientSocket> sock_; | |
756 CapturingNetLog log_; | |
757 bool ran_handshake_completion_callback_; | |
758 | |
759 private: | |
760 scoped_ptr<StreamSocket> transport_; | |
761 scoped_ptr<SpawnedTestServer> test_server_; | |
762 TestCompletionCallback callback_; | |
763 AddressList addr_; | |
764 }; | |
765 | |
766 // Verifies the correctness of GetSSLCertRequestInfo. | |
767 class SSLClientSocketCertRequestInfoTest : public SSLClientSocketTest { | |
768 protected: | |
769 // Creates a test server with the given SSLOptions, connects to it and returns | |
770 // the SSLCertRequestInfo reported by the socket. | |
771 scoped_refptr<SSLCertRequestInfo> GetCertRequest( | |
772 SpawnedTestServer::SSLOptions ssl_options) { | |
773 SpawnedTestServer test_server( | |
774 SpawnedTestServer::TYPE_HTTPS, ssl_options, base::FilePath()); | |
775 if (!test_server.Start()) | |
776 return NULL; | |
777 | |
778 AddressList addr; | |
779 if (!test_server.GetAddressList(&addr)) | |
780 return NULL; | |
781 | |
782 TestCompletionCallback callback; | |
783 CapturingNetLog log; | |
784 scoped_ptr<StreamSocket> transport( | |
785 new TCPClientSocket(addr, &log, NetLog::Source())); | |
786 int rv = transport->Connect(callback.callback()); | |
787 if (rv == ERR_IO_PENDING) | |
788 rv = callback.WaitForResult(); | |
789 EXPECT_EQ(OK, rv); | |
790 | |
791 scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket( | |
792 transport.Pass(), test_server.host_port_pair(), SSLConfig())); | |
793 EXPECT_FALSE(sock->IsConnected()); | |
794 | |
795 rv = sock->Connect(callback.callback()); | |
796 if (rv == ERR_IO_PENDING) | |
797 rv = callback.WaitForResult(); | |
798 scoped_refptr<SSLCertRequestInfo> request_info = new SSLCertRequestInfo(); | |
799 sock->GetSSLCertRequestInfo(request_info.get()); | |
800 sock->Disconnect(); | |
801 EXPECT_FALSE(sock->IsConnected()); | |
802 EXPECT_TRUE( | |
803 test_server.host_port_pair().Equals(request_info->host_and_port)); | |
804 | |
805 return request_info; | |
806 } | |
807 }; | |
808 | |
809 class SSLClientSocketFalseStartTest : public SSLClientSocketTest { | |
810 public: | |
811 SSLClientSocketFalseStartTest() | |
812 : monitor_handshake_callback_(false), | |
813 fail_handshake_after_false_start_(false) {} | |
814 | |
815 protected: | |
816 // Creates an SSLClientSocket with |client_config| attached to a | |
817 // FakeBlockingStreamSocket, returning both in |*out_raw_transport| and | |
818 // |*out_sock|. The FakeBlockingStreamSocket is owned by the SSLClientSocket, | |
819 // so |*out_raw_transport| is a raw pointer. | |
820 // | |
821 // The client socket will begin a connect using |callback| but stop before the | |
822 // server's finished message is received. The finished message will be blocked | |
823 // in |*out_raw_transport|. To complete the handshake and successfully read | |
824 // data, the caller must unblock reads on |*out_raw_transport|. (Note that, if | |
825 // the client successfully false started, |callback.WaitForResult()| will | |
826 // return OK without unblocking transport reads. But Read() will still block.) | |
827 // | |
828 // Must be called after StartTestServer is called. | |
829 void CreateAndConnectUntilServerFinishedReceived( | |
830 const SSLConfig& client_config, | |
831 TestCompletionCallback* callback, | |
832 FakeBlockingStreamSocket** out_raw_transport, | |
833 scoped_ptr<SSLClientSocket>* out_sock) { | |
834 CHECK(test_server()); | |
835 | |
836 scoped_ptr<StreamSocket> real_transport(scoped_ptr<StreamSocket>( | |
837 new TCPClientSocket(addr(), NULL, NetLog::Source()))); | |
838 real_transport.reset( | |
839 new SynchronousErrorStreamSocket(real_transport.Pass())); | |
840 | |
841 scoped_ptr<FakeBlockingStreamSocket> transport( | |
842 new FakeBlockingStreamSocket(real_transport.Pass())); | |
843 int rv = callback->GetResult(transport->Connect(callback->callback())); | |
844 EXPECT_EQ(OK, rv); | |
845 | |
846 FakeBlockingStreamSocket* raw_transport = transport.get(); | |
847 scoped_ptr<SSLClientSocket> sock = CreateSSLClientSocket( | |
848 transport.Pass(), test_server()->host_port_pair(), client_config); | |
849 | |
850 if (monitor_handshake_callback_) { | |
851 sock->SetHandshakeCompletionCallback( | |
852 base::Bind(&SSLClientSocketTest::RecordCompletedHandshake, | |
853 base::Unretained(this))); | |
854 } | |
855 | |
856 // Connect. Stop before the client processes the first server leg | |
857 // (ServerHello, etc.) | |
858 raw_transport->BlockReadResult(); | |
859 rv = sock->Connect(callback->callback()); | |
860 EXPECT_EQ(ERR_IO_PENDING, rv); | |
861 raw_transport->WaitForReadResult(); | |
862 | |
863 // Release the ServerHello and wait for the client to write | |
864 // ClientKeyExchange, etc. (A proxy for waiting for the entirety of the | |
865 // server's leg to complete, since it may span multiple reads.) | |
866 EXPECT_FALSE(callback->have_result()); | |
867 raw_transport->BlockWrite(); | |
868 raw_transport->UnblockReadResult(); | |
869 raw_transport->WaitForWrite(); | |
870 | |
871 if (fail_handshake_after_false_start_) { | |
872 SynchronousErrorStreamSocket* error_socket = | |
873 static_cast<SynchronousErrorStreamSocket*>( | |
874 raw_transport->transport()); | |
875 error_socket->SetNextReadError(ERR_CONNECTION_RESET); | |
876 } | |
877 // And, finally, release that and block the next server leg | |
878 // (ChangeCipherSpec, Finished). | |
879 raw_transport->BlockReadResult(); | |
880 raw_transport->UnblockWrite(); | |
881 | |
882 *out_raw_transport = raw_transport; | |
883 *out_sock = sock.Pass(); | |
884 } | |
885 | |
886 void TestFalseStart(const SpawnedTestServer::SSLOptions& server_options, | |
887 const SSLConfig& client_config, | |
888 bool expect_false_start) { | |
889 ASSERT_TRUE(StartTestServer(server_options)); | |
890 | |
891 TestCompletionCallback callback; | |
892 FakeBlockingStreamSocket* raw_transport = NULL; | |
893 scoped_ptr<SSLClientSocket> sock; | |
894 | |
895 ASSERT_NO_FATAL_FAILURE(CreateAndConnectUntilServerFinishedReceived( | |
896 client_config, &callback, &raw_transport, &sock)); | |
897 | |
898 if (expect_false_start) { | |
899 // When False Starting, the handshake should complete before receiving the | |
900 // Change Cipher Spec and Finished messages. | |
901 // | |
902 // Note: callback.have_result() may not be true without waiting. The NSS | |
903 // state machine sometimes lives on a separate thread, so this thread may | |
904 // not yet have processed the signal that the handshake has completed. | |
905 int rv = callback.WaitForResult(); | |
906 EXPECT_EQ(OK, rv); | |
907 EXPECT_TRUE(sock->IsConnected()); | |
908 | |
909 const char request_text[] = "GET / HTTP/1.0\r\n\r\n"; | |
910 static const int kRequestTextSize = | |
911 static_cast<int>(arraysize(request_text) - 1); | |
912 scoped_refptr<IOBuffer> request_buffer(new IOBuffer(kRequestTextSize)); | |
913 memcpy(request_buffer->data(), request_text, kRequestTextSize); | |
914 | |
915 // Write the request. | |
916 rv = callback.GetResult(sock->Write(request_buffer.get(), | |
917 kRequestTextSize, | |
918 callback.callback())); | |
919 EXPECT_EQ(kRequestTextSize, rv); | |
920 | |
921 // The read will hang; it's waiting for the peer to complete the | |
922 // handshake, and the handshake is still blocked. | |
923 scoped_refptr<IOBuffer> buf(new IOBuffer(4096)); | |
924 rv = sock->Read(buf.get(), 4096, callback.callback()); | |
925 | |
926 // After releasing reads, the connection proceeds. | |
927 raw_transport->UnblockReadResult(); | |
928 rv = callback.GetResult(rv); | |
929 if (fail_handshake_after_false_start_) | |
930 EXPECT_EQ(ERR_CONNECTION_RESET, rv); | |
931 else | |
932 EXPECT_LT(0, rv); | |
933 } else { | |
934 // False Start is not enabled, so the handshake will not complete because | |
935 // the server second leg is blocked. | |
936 base::RunLoop().RunUntilIdle(); | |
937 EXPECT_FALSE(callback.have_result()); | |
938 } | |
939 } | |
940 | |
941 // Indicates that the socket's handshake completion callback should | |
942 // be monitored. | |
943 bool monitor_handshake_callback_; | |
944 // Indicates that this test's handshake should fail after the client | |
945 // "finished" message is sent. | |
946 bool fail_handshake_after_false_start_; | |
947 }; | |
948 | |
949 class SSLClientSocketChannelIDTest : public SSLClientSocketTest { | |
950 protected: | |
951 void EnableChannelID() { | |
952 channel_id_service_.reset( | |
953 new ChannelIDService(new DefaultChannelIDStore(NULL), | |
954 base::MessageLoopProxy::current())); | |
955 context_.channel_id_service = channel_id_service_.get(); | |
956 } | |
957 | |
958 void EnableFailingChannelID() { | |
959 channel_id_service_.reset(new ChannelIDService( | |
960 new FailingChannelIDStore(), base::MessageLoopProxy::current())); | |
961 context_.channel_id_service = channel_id_service_.get(); | |
962 } | |
963 | |
964 void EnableAsyncFailingChannelID() { | |
965 channel_id_service_.reset(new ChannelIDService( | |
966 new AsyncFailingChannelIDStore(), | |
967 base::MessageLoopProxy::current())); | |
968 context_.channel_id_service = channel_id_service_.get(); | |
969 } | |
970 | |
971 private: | |
972 scoped_ptr<ChannelIDService> channel_id_service_; | |
973 }; | |
974 | |
975 //----------------------------------------------------------------------------- | |
976 | |
977 // LogContainsSSLConnectEndEvent returns true if the given index in the given | |
978 // log is an SSL connect end event. The NSS sockets will cork in an attempt to | |
979 // merge the first application data record with the Finished message when false | |
980 // starting. However, in order to avoid the server timing out the handshake, | |
981 // they'll give up waiting for application data and send the Finished after a | |
982 // timeout. This means that an SSL connect end event may appear as a socket | |
983 // write. | |
984 static bool LogContainsSSLConnectEndEvent( | |
985 const CapturingNetLog::CapturedEntryList& log, | |
986 int i) { | |
987 return LogContainsEndEvent(log, i, NetLog::TYPE_SSL_CONNECT) || | |
988 LogContainsEvent( | |
989 log, i, NetLog::TYPE_SOCKET_BYTES_SENT, NetLog::PHASE_NONE); | |
990 } | |
991 | |
992 } // namespace | |
993 | |
994 TEST_F(SSLClientSocketTest, Connect) { | |
995 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, | |
996 SpawnedTestServer::kLocalhost, | |
997 base::FilePath()); | |
998 ASSERT_TRUE(test_server.Start()); | |
999 | |
1000 AddressList addr; | |
1001 ASSERT_TRUE(test_server.GetAddressList(&addr)); | |
1002 | |
1003 TestCompletionCallback callback; | |
1004 CapturingNetLog log; | |
1005 scoped_ptr<StreamSocket> transport( | |
1006 new TCPClientSocket(addr, &log, NetLog::Source())); | |
1007 int rv = transport->Connect(callback.callback()); | |
1008 if (rv == ERR_IO_PENDING) | |
1009 rv = callback.WaitForResult(); | |
1010 EXPECT_EQ(OK, rv); | |
1011 | |
1012 scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket( | |
1013 transport.Pass(), test_server.host_port_pair(), SSLConfig())); | |
1014 | |
1015 EXPECT_FALSE(sock->IsConnected()); | |
1016 | |
1017 rv = sock->Connect(callback.callback()); | |
1018 | |
1019 CapturingNetLog::CapturedEntryList entries; | |
1020 log.GetEntries(&entries); | |
1021 EXPECT_TRUE(LogContainsBeginEvent(entries, 5, NetLog::TYPE_SSL_CONNECT)); | |
1022 if (rv == ERR_IO_PENDING) | |
1023 rv = callback.WaitForResult(); | |
1024 EXPECT_EQ(OK, rv); | |
1025 EXPECT_TRUE(sock->IsConnected()); | |
1026 log.GetEntries(&entries); | |
1027 EXPECT_TRUE(LogContainsSSLConnectEndEvent(entries, -1)); | |
1028 | |
1029 sock->Disconnect(); | |
1030 EXPECT_FALSE(sock->IsConnected()); | |
1031 } | |
1032 | |
1033 TEST_F(SSLClientSocketTest, ConnectExpired) { | |
1034 SpawnedTestServer::SSLOptions ssl_options( | |
1035 SpawnedTestServer::SSLOptions::CERT_EXPIRED); | |
1036 SpawnedTestServer test_server( | |
1037 SpawnedTestServer::TYPE_HTTPS, ssl_options, base::FilePath()); | |
1038 ASSERT_TRUE(test_server.Start()); | |
1039 | |
1040 cert_verifier_->set_default_result(ERR_CERT_DATE_INVALID); | |
1041 | |
1042 AddressList addr; | |
1043 ASSERT_TRUE(test_server.GetAddressList(&addr)); | |
1044 | |
1045 TestCompletionCallback callback; | |
1046 CapturingNetLog log; | |
1047 scoped_ptr<StreamSocket> transport( | |
1048 new TCPClientSocket(addr, &log, NetLog::Source())); | |
1049 int rv = transport->Connect(callback.callback()); | |
1050 if (rv == ERR_IO_PENDING) | |
1051 rv = callback.WaitForResult(); | |
1052 EXPECT_EQ(OK, rv); | |
1053 | |
1054 scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket( | |
1055 transport.Pass(), test_server.host_port_pair(), SSLConfig())); | |
1056 | |
1057 EXPECT_FALSE(sock->IsConnected()); | |
1058 | |
1059 rv = sock->Connect(callback.callback()); | |
1060 | |
1061 CapturingNetLog::CapturedEntryList entries; | |
1062 log.GetEntries(&entries); | |
1063 EXPECT_TRUE(LogContainsBeginEvent(entries, 5, NetLog::TYPE_SSL_CONNECT)); | |
1064 if (rv == ERR_IO_PENDING) | |
1065 rv = callback.WaitForResult(); | |
1066 | |
1067 EXPECT_EQ(ERR_CERT_DATE_INVALID, rv); | |
1068 | |
1069 // Rather than testing whether or not the underlying socket is connected, | |
1070 // test that the handshake has finished. This is because it may be | |
1071 // desirable to disconnect the socket before showing a user prompt, since | |
1072 // the user may take indefinitely long to respond. | |
1073 log.GetEntries(&entries); | |
1074 EXPECT_TRUE(LogContainsSSLConnectEndEvent(entries, -1)); | |
1075 } | |
1076 | |
1077 TEST_F(SSLClientSocketTest, ConnectMismatched) { | |
1078 SpawnedTestServer::SSLOptions ssl_options( | |
1079 SpawnedTestServer::SSLOptions::CERT_MISMATCHED_NAME); | |
1080 SpawnedTestServer test_server( | |
1081 SpawnedTestServer::TYPE_HTTPS, ssl_options, base::FilePath()); | |
1082 ASSERT_TRUE(test_server.Start()); | |
1083 | |
1084 cert_verifier_->set_default_result(ERR_CERT_COMMON_NAME_INVALID); | |
1085 | |
1086 AddressList addr; | |
1087 ASSERT_TRUE(test_server.GetAddressList(&addr)); | |
1088 | |
1089 TestCompletionCallback callback; | |
1090 CapturingNetLog log; | |
1091 scoped_ptr<StreamSocket> transport( | |
1092 new TCPClientSocket(addr, &log, NetLog::Source())); | |
1093 int rv = transport->Connect(callback.callback()); | |
1094 if (rv == ERR_IO_PENDING) | |
1095 rv = callback.WaitForResult(); | |
1096 EXPECT_EQ(OK, rv); | |
1097 | |
1098 scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket( | |
1099 transport.Pass(), test_server.host_port_pair(), SSLConfig())); | |
1100 | |
1101 EXPECT_FALSE(sock->IsConnected()); | |
1102 | |
1103 rv = sock->Connect(callback.callback()); | |
1104 | |
1105 CapturingNetLog::CapturedEntryList entries; | |
1106 log.GetEntries(&entries); | |
1107 EXPECT_TRUE(LogContainsBeginEvent(entries, 5, NetLog::TYPE_SSL_CONNECT)); | |
1108 if (rv == ERR_IO_PENDING) | |
1109 rv = callback.WaitForResult(); | |
1110 | |
1111 EXPECT_EQ(ERR_CERT_COMMON_NAME_INVALID, rv); | |
1112 | |
1113 // Rather than testing whether or not the underlying socket is connected, | |
1114 // test that the handshake has finished. This is because it may be | |
1115 // desirable to disconnect the socket before showing a user prompt, since | |
1116 // the user may take indefinitely long to respond. | |
1117 log.GetEntries(&entries); | |
1118 EXPECT_TRUE(LogContainsSSLConnectEndEvent(entries, -1)); | |
1119 } | |
1120 | |
1121 // Attempt to connect to a page which requests a client certificate. It should | |
1122 // return an error code on connect. | |
1123 TEST_F(SSLClientSocketTest, ConnectClientAuthCertRequested) { | |
1124 SpawnedTestServer::SSLOptions ssl_options; | |
1125 ssl_options.request_client_certificate = true; | |
1126 SpawnedTestServer test_server( | |
1127 SpawnedTestServer::TYPE_HTTPS, ssl_options, base::FilePath()); | |
1128 ASSERT_TRUE(test_server.Start()); | |
1129 | |
1130 AddressList addr; | |
1131 ASSERT_TRUE(test_server.GetAddressList(&addr)); | |
1132 | |
1133 TestCompletionCallback callback; | |
1134 CapturingNetLog log; | |
1135 scoped_ptr<StreamSocket> transport( | |
1136 new TCPClientSocket(addr, &log, NetLog::Source())); | |
1137 int rv = transport->Connect(callback.callback()); | |
1138 if (rv == ERR_IO_PENDING) | |
1139 rv = callback.WaitForResult(); | |
1140 EXPECT_EQ(OK, rv); | |
1141 | |
1142 scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket( | |
1143 transport.Pass(), test_server.host_port_pair(), SSLConfig())); | |
1144 | |
1145 EXPECT_FALSE(sock->IsConnected()); | |
1146 | |
1147 rv = sock->Connect(callback.callback()); | |
1148 | |
1149 CapturingNetLog::CapturedEntryList entries; | |
1150 log.GetEntries(&entries); | |
1151 EXPECT_TRUE(LogContainsBeginEvent(entries, 5, NetLog::TYPE_SSL_CONNECT)); | |
1152 if (rv == ERR_IO_PENDING) | |
1153 rv = callback.WaitForResult(); | |
1154 | |
1155 log.GetEntries(&entries); | |
1156 // Because we prematurely kill the handshake at CertificateRequest, | |
1157 // the server may still send data (notably the ServerHelloDone) | |
1158 // after the error is returned. As a result, the SSL_CONNECT may not | |
1159 // be the last entry. See http://crbug.com/54445. We use | |
1160 // ExpectLogContainsSomewhere instead of | |
1161 // LogContainsSSLConnectEndEvent to avoid assuming, e.g., only one | |
1162 // extra read instead of two. This occurs before the handshake ends, | |
1163 // so the corking logic of LogContainsSSLConnectEndEvent isn't | |
1164 // necessary. | |
1165 // | |
1166 // TODO(davidben): When SSL_RestartHandshakeAfterCertReq in NSS is | |
1167 // fixed and we can respond to the first CertificateRequest | |
1168 // without closing the socket, add a unit test for sending the | |
1169 // certificate. This test may still be useful as we'll want to close | |
1170 // the socket on a timeout if the user takes a long time to pick a | |
1171 // cert. Related bug: https://bugzilla.mozilla.org/show_bug.cgi?id=542832 | |
1172 ExpectLogContainsSomewhere( | |
1173 entries, 0, NetLog::TYPE_SSL_CONNECT, NetLog::PHASE_END); | |
1174 EXPECT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv); | |
1175 EXPECT_FALSE(sock->IsConnected()); | |
1176 } | |
1177 | |
1178 // Connect to a server requesting optional client authentication. Send it a | |
1179 // null certificate. It should allow the connection. | |
1180 // | |
1181 // TODO(davidben): Also test providing an actual certificate. | |
1182 TEST_F(SSLClientSocketTest, ConnectClientAuthSendNullCert) { | |
1183 SpawnedTestServer::SSLOptions ssl_options; | |
1184 ssl_options.request_client_certificate = true; | |
1185 SpawnedTestServer test_server( | |
1186 SpawnedTestServer::TYPE_HTTPS, ssl_options, base::FilePath()); | |
1187 ASSERT_TRUE(test_server.Start()); | |
1188 | |
1189 AddressList addr; | |
1190 ASSERT_TRUE(test_server.GetAddressList(&addr)); | |
1191 | |
1192 TestCompletionCallback callback; | |
1193 CapturingNetLog log; | |
1194 scoped_ptr<StreamSocket> transport( | |
1195 new TCPClientSocket(addr, &log, NetLog::Source())); | |
1196 int rv = transport->Connect(callback.callback()); | |
1197 if (rv == ERR_IO_PENDING) | |
1198 rv = callback.WaitForResult(); | |
1199 EXPECT_EQ(OK, rv); | |
1200 | |
1201 SSLConfig ssl_config; | |
1202 ssl_config.send_client_cert = true; | |
1203 ssl_config.client_cert = NULL; | |
1204 | |
1205 scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket( | |
1206 transport.Pass(), test_server.host_port_pair(), ssl_config)); | |
1207 | |
1208 EXPECT_FALSE(sock->IsConnected()); | |
1209 | |
1210 // Our test server accepts certificate-less connections. | |
1211 // TODO(davidben): Add a test which requires them and verify the error. | |
1212 rv = sock->Connect(callback.callback()); | |
1213 | |
1214 CapturingNetLog::CapturedEntryList entries; | |
1215 log.GetEntries(&entries); | |
1216 EXPECT_TRUE(LogContainsBeginEvent(entries, 5, NetLog::TYPE_SSL_CONNECT)); | |
1217 if (rv == ERR_IO_PENDING) | |
1218 rv = callback.WaitForResult(); | |
1219 | |
1220 EXPECT_EQ(OK, rv); | |
1221 EXPECT_TRUE(sock->IsConnected()); | |
1222 log.GetEntries(&entries); | |
1223 EXPECT_TRUE(LogContainsSSLConnectEndEvent(entries, -1)); | |
1224 | |
1225 // We responded to the server's certificate request with a Certificate | |
1226 // message with no client certificate in it. ssl_info.client_cert_sent | |
1227 // should be false in this case. | |
1228 SSLInfo ssl_info; | |
1229 sock->GetSSLInfo(&ssl_info); | |
1230 EXPECT_FALSE(ssl_info.client_cert_sent); | |
1231 | |
1232 sock->Disconnect(); | |
1233 EXPECT_FALSE(sock->IsConnected()); | |
1234 } | |
1235 | |
1236 // TODO(wtc): Add unit tests for IsConnectedAndIdle: | |
1237 // - Server closes an SSL connection (with a close_notify alert message). | |
1238 // - Server closes the underlying TCP connection directly. | |
1239 // - Server sends data unexpectedly. | |
1240 | |
1241 TEST_F(SSLClientSocketTest, Read) { | |
1242 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, | |
1243 SpawnedTestServer::kLocalhost, | |
1244 base::FilePath()); | |
1245 ASSERT_TRUE(test_server.Start()); | |
1246 | |
1247 AddressList addr; | |
1248 ASSERT_TRUE(test_server.GetAddressList(&addr)); | |
1249 | |
1250 TestCompletionCallback callback; | |
1251 scoped_ptr<StreamSocket> transport( | |
1252 new TCPClientSocket(addr, NULL, NetLog::Source())); | |
1253 int rv = transport->Connect(callback.callback()); | |
1254 if (rv == ERR_IO_PENDING) | |
1255 rv = callback.WaitForResult(); | |
1256 EXPECT_EQ(OK, rv); | |
1257 | |
1258 scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket( | |
1259 transport.Pass(), test_server.host_port_pair(), SSLConfig())); | |
1260 | |
1261 rv = sock->Connect(callback.callback()); | |
1262 if (rv == ERR_IO_PENDING) | |
1263 rv = callback.WaitForResult(); | |
1264 EXPECT_EQ(OK, rv); | |
1265 EXPECT_TRUE(sock->IsConnected()); | |
1266 | |
1267 const char request_text[] = "GET / HTTP/1.0\r\n\r\n"; | |
1268 scoped_refptr<IOBuffer> request_buffer( | |
1269 new IOBuffer(arraysize(request_text) - 1)); | |
1270 memcpy(request_buffer->data(), request_text, arraysize(request_text) - 1); | |
1271 | |
1272 rv = sock->Write( | |
1273 request_buffer.get(), arraysize(request_text) - 1, callback.callback()); | |
1274 EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING); | |
1275 | |
1276 if (rv == ERR_IO_PENDING) | |
1277 rv = callback.WaitForResult(); | |
1278 EXPECT_EQ(static_cast<int>(arraysize(request_text) - 1), rv); | |
1279 | |
1280 scoped_refptr<IOBuffer> buf(new IOBuffer(4096)); | |
1281 for (;;) { | |
1282 rv = sock->Read(buf.get(), 4096, callback.callback()); | |
1283 EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING); | |
1284 | |
1285 if (rv == ERR_IO_PENDING) | |
1286 rv = callback.WaitForResult(); | |
1287 | |
1288 EXPECT_GE(rv, 0); | |
1289 if (rv <= 0) | |
1290 break; | |
1291 } | |
1292 } | |
1293 | |
1294 // Tests that SSLClientSocket properly handles when the underlying transport | |
1295 // synchronously fails a transport read in during the handshake. The error code | |
1296 // should be preserved so SSLv3 fallback logic can condition on it. | |
1297 TEST_F(SSLClientSocketTest, Connect_WithSynchronousError) { | |
1298 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, | |
1299 SpawnedTestServer::kLocalhost, | |
1300 base::FilePath()); | |
1301 ASSERT_TRUE(test_server.Start()); | |
1302 | |
1303 AddressList addr; | |
1304 ASSERT_TRUE(test_server.GetAddressList(&addr)); | |
1305 | |
1306 TestCompletionCallback callback; | |
1307 scoped_ptr<StreamSocket> real_transport( | |
1308 new TCPClientSocket(addr, NULL, NetLog::Source())); | |
1309 scoped_ptr<SynchronousErrorStreamSocket> transport( | |
1310 new SynchronousErrorStreamSocket(real_transport.Pass())); | |
1311 int rv = callback.GetResult(transport->Connect(callback.callback())); | |
1312 EXPECT_EQ(OK, rv); | |
1313 | |
1314 // Disable TLS False Start to avoid handshake non-determinism. | |
1315 SSLConfig ssl_config; | |
1316 ssl_config.false_start_enabled = false; | |
1317 | |
1318 SynchronousErrorStreamSocket* raw_transport = transport.get(); | |
1319 scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket( | |
1320 transport.Pass(), test_server.host_port_pair(), ssl_config)); | |
1321 | |
1322 raw_transport->SetNextWriteError(ERR_CONNECTION_RESET); | |
1323 | |
1324 rv = callback.GetResult(sock->Connect(callback.callback())); | |
1325 EXPECT_EQ(ERR_CONNECTION_RESET, rv); | |
1326 EXPECT_FALSE(sock->IsConnected()); | |
1327 } | |
1328 | |
1329 // Tests that the SSLClientSocket properly handles when the underlying transport | |
1330 // synchronously returns an error code - such as if an intermediary terminates | |
1331 // the socket connection uncleanly. | |
1332 // This is a regression test for http://crbug.com/238536 | |
1333 TEST_F(SSLClientSocketTest, Read_WithSynchronousError) { | |
1334 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, | |
1335 SpawnedTestServer::kLocalhost, | |
1336 base::FilePath()); | |
1337 ASSERT_TRUE(test_server.Start()); | |
1338 | |
1339 AddressList addr; | |
1340 ASSERT_TRUE(test_server.GetAddressList(&addr)); | |
1341 | |
1342 TestCompletionCallback callback; | |
1343 scoped_ptr<StreamSocket> real_transport( | |
1344 new TCPClientSocket(addr, NULL, NetLog::Source())); | |
1345 scoped_ptr<SynchronousErrorStreamSocket> transport( | |
1346 new SynchronousErrorStreamSocket(real_transport.Pass())); | |
1347 int rv = callback.GetResult(transport->Connect(callback.callback())); | |
1348 EXPECT_EQ(OK, rv); | |
1349 | |
1350 // Disable TLS False Start to avoid handshake non-determinism. | |
1351 SSLConfig ssl_config; | |
1352 ssl_config.false_start_enabled = false; | |
1353 | |
1354 SynchronousErrorStreamSocket* raw_transport = transport.get(); | |
1355 scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket( | |
1356 transport.Pass(), test_server.host_port_pair(), ssl_config)); | |
1357 | |
1358 rv = callback.GetResult(sock->Connect(callback.callback())); | |
1359 EXPECT_EQ(OK, rv); | |
1360 EXPECT_TRUE(sock->IsConnected()); | |
1361 | |
1362 const char request_text[] = "GET / HTTP/1.0\r\n\r\n"; | |
1363 static const int kRequestTextSize = | |
1364 static_cast<int>(arraysize(request_text) - 1); | |
1365 scoped_refptr<IOBuffer> request_buffer(new IOBuffer(kRequestTextSize)); | |
1366 memcpy(request_buffer->data(), request_text, kRequestTextSize); | |
1367 | |
1368 rv = callback.GetResult( | |
1369 sock->Write(request_buffer.get(), kRequestTextSize, callback.callback())); | |
1370 EXPECT_EQ(kRequestTextSize, rv); | |
1371 | |
1372 // Simulate an unclean/forcible shutdown. | |
1373 raw_transport->SetNextReadError(ERR_CONNECTION_RESET); | |
1374 | |
1375 scoped_refptr<IOBuffer> buf(new IOBuffer(4096)); | |
1376 | |
1377 // Note: This test will hang if this bug has regressed. Simply checking that | |
1378 // rv != ERR_IO_PENDING is insufficient, as ERR_IO_PENDING is a legitimate | |
1379 // result when using a dedicated task runner for NSS. | |
1380 rv = callback.GetResult(sock->Read(buf.get(), 4096, callback.callback())); | |
1381 EXPECT_EQ(ERR_CONNECTION_RESET, rv); | |
1382 } | |
1383 | |
1384 // Tests that the SSLClientSocket properly handles when the underlying transport | |
1385 // asynchronously returns an error code while writing data - such as if an | |
1386 // intermediary terminates the socket connection uncleanly. | |
1387 // This is a regression test for http://crbug.com/249848 | |
1388 TEST_F(SSLClientSocketTest, Write_WithSynchronousError) { | |
1389 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, | |
1390 SpawnedTestServer::kLocalhost, | |
1391 base::FilePath()); | |
1392 ASSERT_TRUE(test_server.Start()); | |
1393 | |
1394 AddressList addr; | |
1395 ASSERT_TRUE(test_server.GetAddressList(&addr)); | |
1396 | |
1397 TestCompletionCallback callback; | |
1398 scoped_ptr<StreamSocket> real_transport( | |
1399 new TCPClientSocket(addr, NULL, NetLog::Source())); | |
1400 // Note: |error_socket|'s ownership is handed to |transport|, but a pointer | |
1401 // is retained in order to configure additional errors. | |
1402 scoped_ptr<SynchronousErrorStreamSocket> error_socket( | |
1403 new SynchronousErrorStreamSocket(real_transport.Pass())); | |
1404 SynchronousErrorStreamSocket* raw_error_socket = error_socket.get(); | |
1405 scoped_ptr<FakeBlockingStreamSocket> transport( | |
1406 new FakeBlockingStreamSocket(error_socket.Pass())); | |
1407 FakeBlockingStreamSocket* raw_transport = transport.get(); | |
1408 int rv = callback.GetResult(transport->Connect(callback.callback())); | |
1409 EXPECT_EQ(OK, rv); | |
1410 | |
1411 // Disable TLS False Start to avoid handshake non-determinism. | |
1412 SSLConfig ssl_config; | |
1413 ssl_config.false_start_enabled = false; | |
1414 | |
1415 scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket( | |
1416 transport.Pass(), test_server.host_port_pair(), ssl_config)); | |
1417 | |
1418 rv = callback.GetResult(sock->Connect(callback.callback())); | |
1419 EXPECT_EQ(OK, rv); | |
1420 EXPECT_TRUE(sock->IsConnected()); | |
1421 | |
1422 const char request_text[] = "GET / HTTP/1.0\r\n\r\n"; | |
1423 static const int kRequestTextSize = | |
1424 static_cast<int>(arraysize(request_text) - 1); | |
1425 scoped_refptr<IOBuffer> request_buffer(new IOBuffer(kRequestTextSize)); | |
1426 memcpy(request_buffer->data(), request_text, kRequestTextSize); | |
1427 | |
1428 // Simulate an unclean/forcible shutdown on the underlying socket. | |
1429 // However, simulate this error asynchronously. | |
1430 raw_error_socket->SetNextWriteError(ERR_CONNECTION_RESET); | |
1431 raw_transport->BlockWrite(); | |
1432 | |
1433 // This write should complete synchronously, because the TLS ciphertext | |
1434 // can be created and placed into the outgoing buffers independent of the | |
1435 // underlying transport. | |
1436 rv = callback.GetResult( | |
1437 sock->Write(request_buffer.get(), kRequestTextSize, callback.callback())); | |
1438 EXPECT_EQ(kRequestTextSize, rv); | |
1439 | |
1440 scoped_refptr<IOBuffer> buf(new IOBuffer(4096)); | |
1441 | |
1442 rv = sock->Read(buf.get(), 4096, callback.callback()); | |
1443 EXPECT_EQ(ERR_IO_PENDING, rv); | |
1444 | |
1445 // Now unblock the outgoing request, having it fail with the connection | |
1446 // being reset. | |
1447 raw_transport->UnblockWrite(); | |
1448 | |
1449 // Note: This will cause an inifite loop if this bug has regressed. Simply | |
1450 // checking that rv != ERR_IO_PENDING is insufficient, as ERR_IO_PENDING | |
1451 // is a legitimate result when using a dedicated task runner for NSS. | |
1452 rv = callback.GetResult(rv); | |
1453 EXPECT_EQ(ERR_CONNECTION_RESET, rv); | |
1454 } | |
1455 | |
1456 // If there is a Write failure at the transport with no follow-up Read, although | |
1457 // the write error will not be returned to the client until a future Read or | |
1458 // Write operation, SSLClientSocket should not spin attempting to re-write on | |
1459 // the socket. This is a regression test for part of https://crbug.com/381160. | |
1460 TEST_F(SSLClientSocketTest, Write_WithSynchronousErrorNoRead) { | |
1461 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, | |
1462 SpawnedTestServer::kLocalhost, | |
1463 base::FilePath()); | |
1464 ASSERT_TRUE(test_server.Start()); | |
1465 | |
1466 AddressList addr; | |
1467 ASSERT_TRUE(test_server.GetAddressList(&addr)); | |
1468 | |
1469 TestCompletionCallback callback; | |
1470 scoped_ptr<StreamSocket> real_transport( | |
1471 new TCPClientSocket(addr, NULL, NetLog::Source())); | |
1472 // Note: intermediate sockets' ownership are handed to |sock|, but a pointer | |
1473 // is retained in order to query them. | |
1474 scoped_ptr<SynchronousErrorStreamSocket> error_socket( | |
1475 new SynchronousErrorStreamSocket(real_transport.Pass())); | |
1476 SynchronousErrorStreamSocket* raw_error_socket = error_socket.get(); | |
1477 scoped_ptr<CountingStreamSocket> counting_socket( | |
1478 new CountingStreamSocket(error_socket.Pass())); | |
1479 CountingStreamSocket* raw_counting_socket = counting_socket.get(); | |
1480 int rv = callback.GetResult(counting_socket->Connect(callback.callback())); | |
1481 ASSERT_EQ(OK, rv); | |
1482 | |
1483 // Disable TLS False Start to avoid handshake non-determinism. | |
1484 SSLConfig ssl_config; | |
1485 ssl_config.false_start_enabled = false; | |
1486 | |
1487 scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket( | |
1488 counting_socket.Pass(), test_server.host_port_pair(), ssl_config)); | |
1489 | |
1490 rv = callback.GetResult(sock->Connect(callback.callback())); | |
1491 ASSERT_EQ(OK, rv); | |
1492 ASSERT_TRUE(sock->IsConnected()); | |
1493 | |
1494 // Simulate an unclean/forcible shutdown on the underlying socket. | |
1495 raw_error_socket->SetNextWriteError(ERR_CONNECTION_RESET); | |
1496 | |
1497 const char request_text[] = "GET / HTTP/1.0\r\n\r\n"; | |
1498 static const int kRequestTextSize = | |
1499 static_cast<int>(arraysize(request_text) - 1); | |
1500 scoped_refptr<IOBuffer> request_buffer(new IOBuffer(kRequestTextSize)); | |
1501 memcpy(request_buffer->data(), request_text, kRequestTextSize); | |
1502 | |
1503 // This write should complete synchronously, because the TLS ciphertext | |
1504 // can be created and placed into the outgoing buffers independent of the | |
1505 // underlying transport. | |
1506 rv = callback.GetResult( | |
1507 sock->Write(request_buffer.get(), kRequestTextSize, callback.callback())); | |
1508 ASSERT_EQ(kRequestTextSize, rv); | |
1509 | |
1510 // Let the event loop spin for a little bit of time. Even on platforms where | |
1511 // pumping the state machine involve thread hops, there should be no further | |
1512 // writes on the transport socket. | |
1513 // | |
1514 // TODO(davidben): Avoid the arbitrary timeout? | |
1515 int old_write_count = raw_counting_socket->write_count(); | |
1516 base::RunLoop loop; | |
1517 base::MessageLoop::current()->PostDelayedTask( | |
1518 FROM_HERE, loop.QuitClosure(), base::TimeDelta::FromMilliseconds(100)); | |
1519 loop.Run(); | |
1520 EXPECT_EQ(old_write_count, raw_counting_socket->write_count()); | |
1521 } | |
1522 | |
1523 // Test the full duplex mode, with Read and Write pending at the same time. | |
1524 // This test also serves as a regression test for http://crbug.com/29815. | |
1525 TEST_F(SSLClientSocketTest, Read_FullDuplex) { | |
1526 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, | |
1527 SpawnedTestServer::kLocalhost, | |
1528 base::FilePath()); | |
1529 ASSERT_TRUE(test_server.Start()); | |
1530 | |
1531 AddressList addr; | |
1532 ASSERT_TRUE(test_server.GetAddressList(&addr)); | |
1533 | |
1534 TestCompletionCallback callback; // Used for everything except Write. | |
1535 | |
1536 scoped_ptr<StreamSocket> transport( | |
1537 new TCPClientSocket(addr, NULL, NetLog::Source())); | |
1538 int rv = transport->Connect(callback.callback()); | |
1539 if (rv == ERR_IO_PENDING) | |
1540 rv = callback.WaitForResult(); | |
1541 EXPECT_EQ(OK, rv); | |
1542 | |
1543 scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket( | |
1544 transport.Pass(), test_server.host_port_pair(), SSLConfig())); | |
1545 | |
1546 rv = sock->Connect(callback.callback()); | |
1547 if (rv == ERR_IO_PENDING) | |
1548 rv = callback.WaitForResult(); | |
1549 EXPECT_EQ(OK, rv); | |
1550 EXPECT_TRUE(sock->IsConnected()); | |
1551 | |
1552 // Issue a "hanging" Read first. | |
1553 scoped_refptr<IOBuffer> buf(new IOBuffer(4096)); | |
1554 rv = sock->Read(buf.get(), 4096, callback.callback()); | |
1555 // We haven't written the request, so there should be no response yet. | |
1556 ASSERT_EQ(ERR_IO_PENDING, rv); | |
1557 | |
1558 // Write the request. | |
1559 // The request is padded with a User-Agent header to a size that causes the | |
1560 // memio circular buffer (4k bytes) in SSLClientSocketNSS to wrap around. | |
1561 // This tests the fix for http://crbug.com/29815. | |
1562 std::string request_text = "GET / HTTP/1.1\r\nUser-Agent: long browser name "; | |
1563 for (int i = 0; i < 3770; ++i) | |
1564 request_text.push_back('*'); | |
1565 request_text.append("\r\n\r\n"); | |
1566 scoped_refptr<IOBuffer> request_buffer(new StringIOBuffer(request_text)); | |
1567 | |
1568 TestCompletionCallback callback2; // Used for Write only. | |
1569 rv = sock->Write( | |
1570 request_buffer.get(), request_text.size(), callback2.callback()); | |
1571 EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING); | |
1572 | |
1573 if (rv == ERR_IO_PENDING) | |
1574 rv = callback2.WaitForResult(); | |
1575 EXPECT_EQ(static_cast<int>(request_text.size()), rv); | |
1576 | |
1577 // Now get the Read result. | |
1578 rv = callback.WaitForResult(); | |
1579 EXPECT_GT(rv, 0); | |
1580 } | |
1581 | |
1582 // Attempts to Read() and Write() from an SSLClientSocketNSS in full duplex | |
1583 // mode when the underlying transport is blocked on sending data. When the | |
1584 // underlying transport completes due to an error, it should invoke both the | |
1585 // Read() and Write() callbacks. If the socket is deleted by the Read() | |
1586 // callback, the Write() callback should not be invoked. | |
1587 // Regression test for http://crbug.com/232633 | |
1588 TEST_F(SSLClientSocketTest, Read_DeleteWhilePendingFullDuplex) { | |
1589 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, | |
1590 SpawnedTestServer::kLocalhost, | |
1591 base::FilePath()); | |
1592 ASSERT_TRUE(test_server.Start()); | |
1593 | |
1594 AddressList addr; | |
1595 ASSERT_TRUE(test_server.GetAddressList(&addr)); | |
1596 | |
1597 TestCompletionCallback callback; | |
1598 scoped_ptr<StreamSocket> real_transport( | |
1599 new TCPClientSocket(addr, NULL, NetLog::Source())); | |
1600 // Note: |error_socket|'s ownership is handed to |transport|, but a pointer | |
1601 // is retained in order to configure additional errors. | |
1602 scoped_ptr<SynchronousErrorStreamSocket> error_socket( | |
1603 new SynchronousErrorStreamSocket(real_transport.Pass())); | |
1604 SynchronousErrorStreamSocket* raw_error_socket = error_socket.get(); | |
1605 scoped_ptr<FakeBlockingStreamSocket> transport( | |
1606 new FakeBlockingStreamSocket(error_socket.Pass())); | |
1607 FakeBlockingStreamSocket* raw_transport = transport.get(); | |
1608 | |
1609 int rv = callback.GetResult(transport->Connect(callback.callback())); | |
1610 EXPECT_EQ(OK, rv); | |
1611 | |
1612 // Disable TLS False Start to avoid handshake non-determinism. | |
1613 SSLConfig ssl_config; | |
1614 ssl_config.false_start_enabled = false; | |
1615 | |
1616 scoped_ptr<SSLClientSocket> sock = CreateSSLClientSocket( | |
1617 transport.Pass(), test_server.host_port_pair(), ssl_config); | |
1618 | |
1619 rv = callback.GetResult(sock->Connect(callback.callback())); | |
1620 EXPECT_EQ(OK, rv); | |
1621 EXPECT_TRUE(sock->IsConnected()); | |
1622 | |
1623 std::string request_text = "GET / HTTP/1.1\r\nUser-Agent: long browser name "; | |
1624 request_text.append(20 * 1024, '*'); | |
1625 request_text.append("\r\n\r\n"); | |
1626 scoped_refptr<DrainableIOBuffer> request_buffer(new DrainableIOBuffer( | |
1627 new StringIOBuffer(request_text), request_text.size())); | |
1628 | |
1629 // Simulate errors being returned from the underlying Read() and Write() ... | |
1630 raw_error_socket->SetNextReadError(ERR_CONNECTION_RESET); | |
1631 raw_error_socket->SetNextWriteError(ERR_CONNECTION_RESET); | |
1632 // ... but have those errors returned asynchronously. Because the Write() will | |
1633 // return first, this will trigger the error. | |
1634 raw_transport->BlockReadResult(); | |
1635 raw_transport->BlockWrite(); | |
1636 | |
1637 // Enqueue a Read() before calling Write(), which should "hang" due to | |
1638 // the ERR_IO_PENDING caused by SetReadShouldBlock() and thus return. | |
1639 SSLClientSocket* raw_sock = sock.get(); | |
1640 DeleteSocketCallback read_callback(sock.release()); | |
1641 scoped_refptr<IOBuffer> read_buf(new IOBuffer(4096)); | |
1642 rv = raw_sock->Read(read_buf.get(), 4096, read_callback.callback()); | |
1643 | |
1644 // Ensure things didn't complete synchronously, otherwise |sock| is invalid. | |
1645 ASSERT_EQ(ERR_IO_PENDING, rv); | |
1646 ASSERT_FALSE(read_callback.have_result()); | |
1647 | |
1648 #if !defined(USE_OPENSSL) | |
1649 // NSS follows a pattern where a call to PR_Write will only consume as | |
1650 // much data as it can encode into application data records before the | |
1651 // internal memio buffer is full, which should only fill if writing a large | |
1652 // amount of data and the underlying transport is blocked. Once this happens, | |
1653 // NSS will return (total size of all application data records it wrote) - 1, | |
1654 // with the caller expected to resume with the remaining unsent data. | |
1655 // | |
1656 // This causes SSLClientSocketNSS::Write to return that it wrote some data | |
1657 // before it will return ERR_IO_PENDING, so make an extra call to Write() to | |
1658 // get the socket in the state needed for the test below. | |
1659 // | |
1660 // This is not needed for OpenSSL, because for OpenSSL, | |
1661 // SSL_MODE_ENABLE_PARTIAL_WRITE is not specified - thus | |
1662 // SSLClientSocketOpenSSL::Write() will not return until all of | |
1663 // |request_buffer| has been written to the underlying BIO (although not | |
1664 // necessarily the underlying transport). | |
1665 rv = callback.GetResult(raw_sock->Write(request_buffer.get(), | |
1666 request_buffer->BytesRemaining(), | |
1667 callback.callback())); | |
1668 ASSERT_LT(0, rv); | |
1669 request_buffer->DidConsume(rv); | |
1670 | |
1671 // Guard to ensure that |request_buffer| was larger than all of the internal | |
1672 // buffers (transport, memio, NSS) along the way - otherwise the next call | |
1673 // to Write() will crash with an invalid buffer. | |
1674 ASSERT_LT(0, request_buffer->BytesRemaining()); | |
1675 #endif | |
1676 | |
1677 // Attempt to write the remaining data. NSS will not be able to consume the | |
1678 // application data because the internal buffers are full, while OpenSSL will | |
1679 // return that its blocked because the underlying transport is blocked. | |
1680 rv = raw_sock->Write(request_buffer.get(), | |
1681 request_buffer->BytesRemaining(), | |
1682 callback.callback()); | |
1683 ASSERT_EQ(ERR_IO_PENDING, rv); | |
1684 ASSERT_FALSE(callback.have_result()); | |
1685 | |
1686 // Now unblock Write(), which will invoke OnSendComplete and (eventually) | |
1687 // call the Read() callback, deleting the socket and thus aborting calling | |
1688 // the Write() callback. | |
1689 raw_transport->UnblockWrite(); | |
1690 | |
1691 rv = read_callback.WaitForResult(); | |
1692 EXPECT_EQ(ERR_CONNECTION_RESET, rv); | |
1693 | |
1694 // The Write callback should not have been called. | |
1695 EXPECT_FALSE(callback.have_result()); | |
1696 } | |
1697 | |
1698 // Tests that the SSLClientSocket does not crash if data is received on the | |
1699 // transport socket after a failing write. This can occur if we have a Write | |
1700 // error in a SPDY socket. | |
1701 // Regression test for http://crbug.com/335557 | |
1702 TEST_F(SSLClientSocketTest, Read_WithWriteError) { | |
1703 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, | |
1704 SpawnedTestServer::kLocalhost, | |
1705 base::FilePath()); | |
1706 ASSERT_TRUE(test_server.Start()); | |
1707 | |
1708 AddressList addr; | |
1709 ASSERT_TRUE(test_server.GetAddressList(&addr)); | |
1710 | |
1711 TestCompletionCallback callback; | |
1712 scoped_ptr<StreamSocket> real_transport( | |
1713 new TCPClientSocket(addr, NULL, NetLog::Source())); | |
1714 // Note: |error_socket|'s ownership is handed to |transport|, but a pointer | |
1715 // is retained in order to configure additional errors. | |
1716 scoped_ptr<SynchronousErrorStreamSocket> error_socket( | |
1717 new SynchronousErrorStreamSocket(real_transport.Pass())); | |
1718 SynchronousErrorStreamSocket* raw_error_socket = error_socket.get(); | |
1719 scoped_ptr<FakeBlockingStreamSocket> transport( | |
1720 new FakeBlockingStreamSocket(error_socket.Pass())); | |
1721 FakeBlockingStreamSocket* raw_transport = transport.get(); | |
1722 | |
1723 int rv = callback.GetResult(transport->Connect(callback.callback())); | |
1724 EXPECT_EQ(OK, rv); | |
1725 | |
1726 // Disable TLS False Start to avoid handshake non-determinism. | |
1727 SSLConfig ssl_config; | |
1728 ssl_config.false_start_enabled = false; | |
1729 | |
1730 scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket( | |
1731 transport.Pass(), test_server.host_port_pair(), ssl_config)); | |
1732 | |
1733 rv = callback.GetResult(sock->Connect(callback.callback())); | |
1734 EXPECT_EQ(OK, rv); | |
1735 EXPECT_TRUE(sock->IsConnected()); | |
1736 | |
1737 // Send a request so there is something to read from the socket. | |
1738 const char request_text[] = "GET / HTTP/1.0\r\n\r\n"; | |
1739 static const int kRequestTextSize = | |
1740 static_cast<int>(arraysize(request_text) - 1); | |
1741 scoped_refptr<IOBuffer> request_buffer(new IOBuffer(kRequestTextSize)); | |
1742 memcpy(request_buffer->data(), request_text, kRequestTextSize); | |
1743 | |
1744 rv = callback.GetResult( | |
1745 sock->Write(request_buffer.get(), kRequestTextSize, callback.callback())); | |
1746 EXPECT_EQ(kRequestTextSize, rv); | |
1747 | |
1748 // Start a hanging read. | |
1749 TestCompletionCallback read_callback; | |
1750 raw_transport->BlockReadResult(); | |
1751 scoped_refptr<IOBuffer> buf(new IOBuffer(4096)); | |
1752 rv = sock->Read(buf.get(), 4096, read_callback.callback()); | |
1753 EXPECT_EQ(ERR_IO_PENDING, rv); | |
1754 | |
1755 // Perform another write, but have it fail. Write a request larger than the | |
1756 // internal socket buffers so that the request hits the underlying transport | |
1757 // socket and detects the error. | |
1758 std::string long_request_text = | |
1759 "GET / HTTP/1.1\r\nUser-Agent: long browser name "; | |
1760 long_request_text.append(20 * 1024, '*'); | |
1761 long_request_text.append("\r\n\r\n"); | |
1762 scoped_refptr<DrainableIOBuffer> long_request_buffer(new DrainableIOBuffer( | |
1763 new StringIOBuffer(long_request_text), long_request_text.size())); | |
1764 | |
1765 raw_error_socket->SetNextWriteError(ERR_CONNECTION_RESET); | |
1766 | |
1767 // Write as much data as possible until hitting an error. This is necessary | |
1768 // for NSS. PR_Write will only consume as much data as it can encode into | |
1769 // application data records before the internal memio buffer is full, which | |
1770 // should only fill if writing a large amount of data and the underlying | |
1771 // transport is blocked. Once this happens, NSS will return (total size of all | |
1772 // application data records it wrote) - 1, with the caller expected to resume | |
1773 // with the remaining unsent data. | |
1774 do { | |
1775 rv = callback.GetResult(sock->Write(long_request_buffer.get(), | |
1776 long_request_buffer->BytesRemaining(), | |
1777 callback.callback())); | |
1778 if (rv > 0) { | |
1779 long_request_buffer->DidConsume(rv); | |
1780 // Abort if the entire buffer is ever consumed. | |
1781 ASSERT_LT(0, long_request_buffer->BytesRemaining()); | |
1782 } | |
1783 } while (rv > 0); | |
1784 | |
1785 EXPECT_EQ(ERR_CONNECTION_RESET, rv); | |
1786 | |
1787 // Release the read. | |
1788 raw_transport->UnblockReadResult(); | |
1789 rv = read_callback.WaitForResult(); | |
1790 | |
1791 #if defined(USE_OPENSSL) | |
1792 // Should still read bytes despite the write error. | |
1793 EXPECT_LT(0, rv); | |
1794 #else | |
1795 // NSS attempts to flush the write buffer in PR_Read on an SSL socket before | |
1796 // pumping the read state machine, unless configured with SSL_ENABLE_FDX, so | |
1797 // the write error stops future reads. | |
1798 EXPECT_EQ(ERR_CONNECTION_RESET, rv); | |
1799 #endif | |
1800 } | |
1801 | |
1802 // Tests that SSLClientSocket fails the handshake if the underlying | |
1803 // transport is cleanly closed. | |
1804 TEST_F(SSLClientSocketTest, Connect_WithZeroReturn) { | |
1805 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, | |
1806 SpawnedTestServer::kLocalhost, | |
1807 base::FilePath()); | |
1808 ASSERT_TRUE(test_server.Start()); | |
1809 | |
1810 AddressList addr; | |
1811 ASSERT_TRUE(test_server.GetAddressList(&addr)); | |
1812 | |
1813 TestCompletionCallback callback; | |
1814 scoped_ptr<StreamSocket> real_transport( | |
1815 new TCPClientSocket(addr, NULL, NetLog::Source())); | |
1816 scoped_ptr<SynchronousErrorStreamSocket> transport( | |
1817 new SynchronousErrorStreamSocket(real_transport.Pass())); | |
1818 int rv = callback.GetResult(transport->Connect(callback.callback())); | |
1819 EXPECT_EQ(OK, rv); | |
1820 | |
1821 SynchronousErrorStreamSocket* raw_transport = transport.get(); | |
1822 scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket( | |
1823 transport.Pass(), test_server.host_port_pair(), SSLConfig())); | |
1824 | |
1825 raw_transport->SetNextReadError(0); | |
1826 | |
1827 rv = callback.GetResult(sock->Connect(callback.callback())); | |
1828 EXPECT_EQ(ERR_CONNECTION_CLOSED, rv); | |
1829 EXPECT_FALSE(sock->IsConnected()); | |
1830 } | |
1831 | |
1832 // Tests that SSLClientSocket cleanly returns a Read of size 0 if the | |
1833 // underlying socket is cleanly closed. | |
1834 // This is a regression test for https://crbug.com/422246 | |
1835 TEST_F(SSLClientSocketTest, Read_WithZeroReturn) { | |
1836 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, | |
1837 SpawnedTestServer::kLocalhost, | |
1838 base::FilePath()); | |
1839 ASSERT_TRUE(test_server.Start()); | |
1840 | |
1841 AddressList addr; | |
1842 ASSERT_TRUE(test_server.GetAddressList(&addr)); | |
1843 | |
1844 TestCompletionCallback callback; | |
1845 scoped_ptr<StreamSocket> real_transport( | |
1846 new TCPClientSocket(addr, NULL, NetLog::Source())); | |
1847 scoped_ptr<SynchronousErrorStreamSocket> transport( | |
1848 new SynchronousErrorStreamSocket(real_transport.Pass())); | |
1849 int rv = callback.GetResult(transport->Connect(callback.callback())); | |
1850 EXPECT_EQ(OK, rv); | |
1851 | |
1852 // Disable TLS False Start to ensure the handshake has completed. | |
1853 SSLConfig ssl_config; | |
1854 ssl_config.false_start_enabled = false; | |
1855 | |
1856 SynchronousErrorStreamSocket* raw_transport = transport.get(); | |
1857 scoped_ptr<SSLClientSocket> sock( | |
1858 CreateSSLClientSocket(transport.Pass(), | |
1859 test_server.host_port_pair(), | |
1860 ssl_config)); | |
1861 | |
1862 rv = callback.GetResult(sock->Connect(callback.callback())); | |
1863 EXPECT_EQ(OK, rv); | |
1864 EXPECT_TRUE(sock->IsConnected()); | |
1865 | |
1866 raw_transport->SetNextReadError(0); | |
1867 scoped_refptr<IOBuffer> buf(new IOBuffer(4096)); | |
1868 rv = callback.GetResult(sock->Read(buf.get(), 4096, callback.callback())); | |
1869 EXPECT_EQ(0, rv); | |
1870 } | |
1871 | |
1872 // Tests that SSLClientSocket cleanly returns a Read of size 0 if the | |
1873 // underlying socket is cleanly closed asynchronously. | |
1874 // This is a regression test for https://crbug.com/422246 | |
1875 TEST_F(SSLClientSocketTest, Read_WithAsyncZeroReturn) { | |
1876 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, | |
1877 SpawnedTestServer::kLocalhost, | |
1878 base::FilePath()); | |
1879 ASSERT_TRUE(test_server.Start()); | |
1880 | |
1881 AddressList addr; | |
1882 ASSERT_TRUE(test_server.GetAddressList(&addr)); | |
1883 | |
1884 TestCompletionCallback callback; | |
1885 scoped_ptr<StreamSocket> real_transport( | |
1886 new TCPClientSocket(addr, NULL, NetLog::Source())); | |
1887 scoped_ptr<SynchronousErrorStreamSocket> error_socket( | |
1888 new SynchronousErrorStreamSocket(real_transport.Pass())); | |
1889 SynchronousErrorStreamSocket* raw_error_socket = error_socket.get(); | |
1890 scoped_ptr<FakeBlockingStreamSocket> transport( | |
1891 new FakeBlockingStreamSocket(error_socket.Pass())); | |
1892 FakeBlockingStreamSocket* raw_transport = transport.get(); | |
1893 int rv = callback.GetResult(transport->Connect(callback.callback())); | |
1894 EXPECT_EQ(OK, rv); | |
1895 | |
1896 // Disable TLS False Start to ensure the handshake has completed. | |
1897 SSLConfig ssl_config; | |
1898 ssl_config.false_start_enabled = false; | |
1899 | |
1900 scoped_ptr<SSLClientSocket> sock( | |
1901 CreateSSLClientSocket(transport.Pass(), | |
1902 test_server.host_port_pair(), | |
1903 ssl_config)); | |
1904 | |
1905 rv = callback.GetResult(sock->Connect(callback.callback())); | |
1906 EXPECT_EQ(OK, rv); | |
1907 EXPECT_TRUE(sock->IsConnected()); | |
1908 | |
1909 raw_error_socket->SetNextReadError(0); | |
1910 raw_transport->BlockReadResult(); | |
1911 scoped_refptr<IOBuffer> buf(new IOBuffer(4096)); | |
1912 rv = sock->Read(buf.get(), 4096, callback.callback()); | |
1913 EXPECT_EQ(ERR_IO_PENDING, rv); | |
1914 | |
1915 raw_transport->UnblockReadResult(); | |
1916 rv = callback.GetResult(rv); | |
1917 EXPECT_EQ(0, rv); | |
1918 } | |
1919 | |
1920 TEST_F(SSLClientSocketTest, Read_SmallChunks) { | |
1921 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, | |
1922 SpawnedTestServer::kLocalhost, | |
1923 base::FilePath()); | |
1924 ASSERT_TRUE(test_server.Start()); | |
1925 | |
1926 AddressList addr; | |
1927 ASSERT_TRUE(test_server.GetAddressList(&addr)); | |
1928 | |
1929 TestCompletionCallback callback; | |
1930 scoped_ptr<StreamSocket> transport( | |
1931 new TCPClientSocket(addr, NULL, NetLog::Source())); | |
1932 int rv = transport->Connect(callback.callback()); | |
1933 if (rv == ERR_IO_PENDING) | |
1934 rv = callback.WaitForResult(); | |
1935 EXPECT_EQ(OK, rv); | |
1936 | |
1937 scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket( | |
1938 transport.Pass(), test_server.host_port_pair(), SSLConfig())); | |
1939 | |
1940 rv = sock->Connect(callback.callback()); | |
1941 if (rv == ERR_IO_PENDING) | |
1942 rv = callback.WaitForResult(); | |
1943 EXPECT_EQ(OK, rv); | |
1944 | |
1945 const char request_text[] = "GET / HTTP/1.0\r\n\r\n"; | |
1946 scoped_refptr<IOBuffer> request_buffer( | |
1947 new IOBuffer(arraysize(request_text) - 1)); | |
1948 memcpy(request_buffer->data(), request_text, arraysize(request_text) - 1); | |
1949 | |
1950 rv = sock->Write( | |
1951 request_buffer.get(), arraysize(request_text) - 1, callback.callback()); | |
1952 EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING); | |
1953 | |
1954 if (rv == ERR_IO_PENDING) | |
1955 rv = callback.WaitForResult(); | |
1956 EXPECT_EQ(static_cast<int>(arraysize(request_text) - 1), rv); | |
1957 | |
1958 scoped_refptr<IOBuffer> buf(new IOBuffer(1)); | |
1959 for (;;) { | |
1960 rv = sock->Read(buf.get(), 1, callback.callback()); | |
1961 EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING); | |
1962 | |
1963 if (rv == ERR_IO_PENDING) | |
1964 rv = callback.WaitForResult(); | |
1965 | |
1966 EXPECT_GE(rv, 0); | |
1967 if (rv <= 0) | |
1968 break; | |
1969 } | |
1970 } | |
1971 | |
1972 TEST_F(SSLClientSocketTest, Read_ManySmallRecords) { | |
1973 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, | |
1974 SpawnedTestServer::kLocalhost, | |
1975 base::FilePath()); | |
1976 ASSERT_TRUE(test_server.Start()); | |
1977 | |
1978 AddressList addr; | |
1979 ASSERT_TRUE(test_server.GetAddressList(&addr)); | |
1980 | |
1981 TestCompletionCallback callback; | |
1982 | |
1983 scoped_ptr<StreamSocket> real_transport( | |
1984 new TCPClientSocket(addr, NULL, NetLog::Source())); | |
1985 scoped_ptr<ReadBufferingStreamSocket> transport( | |
1986 new ReadBufferingStreamSocket(real_transport.Pass())); | |
1987 ReadBufferingStreamSocket* raw_transport = transport.get(); | |
1988 int rv = callback.GetResult(transport->Connect(callback.callback())); | |
1989 ASSERT_EQ(OK, rv); | |
1990 | |
1991 scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket( | |
1992 transport.Pass(), test_server.host_port_pair(), SSLConfig())); | |
1993 | |
1994 rv = callback.GetResult(sock->Connect(callback.callback())); | |
1995 ASSERT_EQ(OK, rv); | |
1996 ASSERT_TRUE(sock->IsConnected()); | |
1997 | |
1998 const char request_text[] = "GET /ssl-many-small-records HTTP/1.0\r\n\r\n"; | |
1999 scoped_refptr<IOBuffer> request_buffer( | |
2000 new IOBuffer(arraysize(request_text) - 1)); | |
2001 memcpy(request_buffer->data(), request_text, arraysize(request_text) - 1); | |
2002 | |
2003 rv = callback.GetResult(sock->Write( | |
2004 request_buffer.get(), arraysize(request_text) - 1, callback.callback())); | |
2005 ASSERT_GT(rv, 0); | |
2006 ASSERT_EQ(static_cast<int>(arraysize(request_text) - 1), rv); | |
2007 | |
2008 // Note: This relies on SSLClientSocketNSS attempting to read up to 17K of | |
2009 // data (the max SSL record size) at a time. Ensure that at least 15K worth | |
2010 // of SSL data is buffered first. The 15K of buffered data is made up of | |
2011 // many smaller SSL records (the TestServer writes along 1350 byte | |
2012 // plaintext boundaries), although there may also be a few records that are | |
2013 // smaller or larger, due to timing and SSL False Start. | |
2014 // 15K was chosen because 15K is smaller than the 17K (max) read issued by | |
2015 // the SSLClientSocket implementation, and larger than the minimum amount | |
2016 // of ciphertext necessary to contain the 8K of plaintext requested below. | |
2017 raw_transport->SetBufferSize(15000); | |
2018 | |
2019 scoped_refptr<IOBuffer> buffer(new IOBuffer(8192)); | |
2020 rv = callback.GetResult(sock->Read(buffer.get(), 8192, callback.callback())); | |
2021 ASSERT_EQ(rv, 8192); | |
2022 } | |
2023 | |
2024 TEST_F(SSLClientSocketTest, Read_Interrupted) { | |
2025 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, | |
2026 SpawnedTestServer::kLocalhost, | |
2027 base::FilePath()); | |
2028 ASSERT_TRUE(test_server.Start()); | |
2029 | |
2030 AddressList addr; | |
2031 ASSERT_TRUE(test_server.GetAddressList(&addr)); | |
2032 | |
2033 TestCompletionCallback callback; | |
2034 scoped_ptr<StreamSocket> transport( | |
2035 new TCPClientSocket(addr, NULL, NetLog::Source())); | |
2036 int rv = transport->Connect(callback.callback()); | |
2037 if (rv == ERR_IO_PENDING) | |
2038 rv = callback.WaitForResult(); | |
2039 EXPECT_EQ(OK, rv); | |
2040 | |
2041 scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket( | |
2042 transport.Pass(), test_server.host_port_pair(), SSLConfig())); | |
2043 | |
2044 rv = sock->Connect(callback.callback()); | |
2045 if (rv == ERR_IO_PENDING) | |
2046 rv = callback.WaitForResult(); | |
2047 EXPECT_EQ(OK, rv); | |
2048 | |
2049 const char request_text[] = "GET / HTTP/1.0\r\n\r\n"; | |
2050 scoped_refptr<IOBuffer> request_buffer( | |
2051 new IOBuffer(arraysize(request_text) - 1)); | |
2052 memcpy(request_buffer->data(), request_text, arraysize(request_text) - 1); | |
2053 | |
2054 rv = sock->Write( | |
2055 request_buffer.get(), arraysize(request_text) - 1, callback.callback()); | |
2056 EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING); | |
2057 | |
2058 if (rv == ERR_IO_PENDING) | |
2059 rv = callback.WaitForResult(); | |
2060 EXPECT_EQ(static_cast<int>(arraysize(request_text) - 1), rv); | |
2061 | |
2062 // Do a partial read and then exit. This test should not crash! | |
2063 scoped_refptr<IOBuffer> buf(new IOBuffer(512)); | |
2064 rv = sock->Read(buf.get(), 512, callback.callback()); | |
2065 EXPECT_TRUE(rv > 0 || rv == ERR_IO_PENDING); | |
2066 | |
2067 if (rv == ERR_IO_PENDING) | |
2068 rv = callback.WaitForResult(); | |
2069 | |
2070 EXPECT_GT(rv, 0); | |
2071 } | |
2072 | |
2073 TEST_F(SSLClientSocketTest, Read_FullLogging) { | |
2074 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, | |
2075 SpawnedTestServer::kLocalhost, | |
2076 base::FilePath()); | |
2077 ASSERT_TRUE(test_server.Start()); | |
2078 | |
2079 AddressList addr; | |
2080 ASSERT_TRUE(test_server.GetAddressList(&addr)); | |
2081 | |
2082 TestCompletionCallback callback; | |
2083 CapturingNetLog log; | |
2084 log.SetLogLevel(NetLog::LOG_ALL); | |
2085 scoped_ptr<StreamSocket> transport( | |
2086 new TCPClientSocket(addr, &log, NetLog::Source())); | |
2087 int rv = transport->Connect(callback.callback()); | |
2088 if (rv == ERR_IO_PENDING) | |
2089 rv = callback.WaitForResult(); | |
2090 EXPECT_EQ(OK, rv); | |
2091 | |
2092 scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket( | |
2093 transport.Pass(), test_server.host_port_pair(), SSLConfig())); | |
2094 | |
2095 rv = sock->Connect(callback.callback()); | |
2096 if (rv == ERR_IO_PENDING) | |
2097 rv = callback.WaitForResult(); | |
2098 EXPECT_EQ(OK, rv); | |
2099 EXPECT_TRUE(sock->IsConnected()); | |
2100 | |
2101 const char request_text[] = "GET / HTTP/1.0\r\n\r\n"; | |
2102 scoped_refptr<IOBuffer> request_buffer( | |
2103 new IOBuffer(arraysize(request_text) - 1)); | |
2104 memcpy(request_buffer->data(), request_text, arraysize(request_text) - 1); | |
2105 | |
2106 rv = sock->Write( | |
2107 request_buffer.get(), arraysize(request_text) - 1, callback.callback()); | |
2108 EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING); | |
2109 | |
2110 if (rv == ERR_IO_PENDING) | |
2111 rv = callback.WaitForResult(); | |
2112 EXPECT_EQ(static_cast<int>(arraysize(request_text) - 1), rv); | |
2113 | |
2114 CapturingNetLog::CapturedEntryList entries; | |
2115 log.GetEntries(&entries); | |
2116 size_t last_index = ExpectLogContainsSomewhereAfter( | |
2117 entries, 5, NetLog::TYPE_SSL_SOCKET_BYTES_SENT, NetLog::PHASE_NONE); | |
2118 | |
2119 scoped_refptr<IOBuffer> buf(new IOBuffer(4096)); | |
2120 for (;;) { | |
2121 rv = sock->Read(buf.get(), 4096, callback.callback()); | |
2122 EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING); | |
2123 | |
2124 if (rv == ERR_IO_PENDING) | |
2125 rv = callback.WaitForResult(); | |
2126 | |
2127 EXPECT_GE(rv, 0); | |
2128 if (rv <= 0) | |
2129 break; | |
2130 | |
2131 log.GetEntries(&entries); | |
2132 last_index = | |
2133 ExpectLogContainsSomewhereAfter(entries, | |
2134 last_index + 1, | |
2135 NetLog::TYPE_SSL_SOCKET_BYTES_RECEIVED, | |
2136 NetLog::PHASE_NONE); | |
2137 } | |
2138 } | |
2139 | |
2140 // Regression test for http://crbug.com/42538 | |
2141 TEST_F(SSLClientSocketTest, PrematureApplicationData) { | |
2142 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, | |
2143 SpawnedTestServer::kLocalhost, | |
2144 base::FilePath()); | |
2145 ASSERT_TRUE(test_server.Start()); | |
2146 | |
2147 AddressList addr; | |
2148 TestCompletionCallback callback; | |
2149 | |
2150 static const unsigned char application_data[] = { | |
2151 0x17, 0x03, 0x01, 0x00, 0x4a, 0x02, 0x00, 0x00, 0x46, 0x03, 0x01, 0x4b, | |
2152 0xc2, 0xf8, 0xb2, 0xc1, 0x56, 0x42, 0xb9, 0x57, 0x7f, 0xde, 0x87, 0x46, | |
2153 0xf7, 0xa3, 0x52, 0x42, 0x21, 0xf0, 0x13, 0x1c, 0x9c, 0x83, 0x88, 0xd6, | |
2154 0x93, 0x0c, 0xf6, 0x36, 0x30, 0x05, 0x7e, 0x20, 0xb5, 0xb5, 0x73, 0x36, | |
2155 0x53, 0x83, 0x0a, 0xfc, 0x17, 0x63, 0xbf, 0xa0, 0xe4, 0x42, 0x90, 0x0d, | |
2156 0x2f, 0x18, 0x6d, 0x20, 0xd8, 0x36, 0x3f, 0xfc, 0xe6, 0x01, 0xfa, 0x0f, | |
2157 0xa5, 0x75, 0x7f, 0x09, 0x00, 0x04, 0x00, 0x16, 0x03, 0x01, 0x11, 0x57, | |
2158 0x0b, 0x00, 0x11, 0x53, 0x00, 0x11, 0x50, 0x00, 0x06, 0x22, 0x30, 0x82, | |
2159 0x06, 0x1e, 0x30, 0x82, 0x05, 0x06, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, | |
2160 0x0a}; | |
2161 | |
2162 // All reads and writes complete synchronously (async=false). | |
2163 MockRead data_reads[] = { | |
2164 MockRead(SYNCHRONOUS, | |
2165 reinterpret_cast<const char*>(application_data), | |
2166 arraysize(application_data)), | |
2167 MockRead(SYNCHRONOUS, OK), }; | |
2168 | |
2169 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); | |
2170 | |
2171 scoped_ptr<StreamSocket> transport( | |
2172 new MockTCPClientSocket(addr, NULL, &data)); | |
2173 int rv = transport->Connect(callback.callback()); | |
2174 if (rv == ERR_IO_PENDING) | |
2175 rv = callback.WaitForResult(); | |
2176 EXPECT_EQ(OK, rv); | |
2177 | |
2178 scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket( | |
2179 transport.Pass(), test_server.host_port_pair(), SSLConfig())); | |
2180 | |
2181 rv = sock->Connect(callback.callback()); | |
2182 if (rv == ERR_IO_PENDING) | |
2183 rv = callback.WaitForResult(); | |
2184 EXPECT_EQ(ERR_SSL_PROTOCOL_ERROR, rv); | |
2185 } | |
2186 | |
2187 TEST_F(SSLClientSocketTest, CipherSuiteDisables) { | |
2188 // Rather than exhaustively disabling every RC4 ciphersuite defined at | |
2189 // http://www.iana.org/assignments/tls-parameters/tls-parameters.xml, | |
2190 // only disabling those cipher suites that the test server actually | |
2191 // implements. | |
2192 const uint16 kCiphersToDisable[] = {0x0005, // TLS_RSA_WITH_RC4_128_SHA | |
2193 }; | |
2194 | |
2195 SpawnedTestServer::SSLOptions ssl_options; | |
2196 // Enable only RC4 on the test server. | |
2197 ssl_options.bulk_ciphers = SpawnedTestServer::SSLOptions::BULK_CIPHER_RC4; | |
2198 SpawnedTestServer test_server( | |
2199 SpawnedTestServer::TYPE_HTTPS, ssl_options, base::FilePath()); | |
2200 ASSERT_TRUE(test_server.Start()); | |
2201 | |
2202 AddressList addr; | |
2203 ASSERT_TRUE(test_server.GetAddressList(&addr)); | |
2204 | |
2205 TestCompletionCallback callback; | |
2206 CapturingNetLog log; | |
2207 scoped_ptr<StreamSocket> transport( | |
2208 new TCPClientSocket(addr, &log, NetLog::Source())); | |
2209 int rv = transport->Connect(callback.callback()); | |
2210 if (rv == ERR_IO_PENDING) | |
2211 rv = callback.WaitForResult(); | |
2212 EXPECT_EQ(OK, rv); | |
2213 | |
2214 SSLConfig ssl_config; | |
2215 for (size_t i = 0; i < arraysize(kCiphersToDisable); ++i) | |
2216 ssl_config.disabled_cipher_suites.push_back(kCiphersToDisable[i]); | |
2217 | |
2218 scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket( | |
2219 transport.Pass(), test_server.host_port_pair(), ssl_config)); | |
2220 | |
2221 EXPECT_FALSE(sock->IsConnected()); | |
2222 | |
2223 rv = sock->Connect(callback.callback()); | |
2224 CapturingNetLog::CapturedEntryList entries; | |
2225 log.GetEntries(&entries); | |
2226 EXPECT_TRUE(LogContainsBeginEvent(entries, 5, NetLog::TYPE_SSL_CONNECT)); | |
2227 | |
2228 // NSS has special handling that maps a handshake_failure alert received | |
2229 // immediately after a client_hello to be a mismatched cipher suite error, | |
2230 // leading to ERR_SSL_VERSION_OR_CIPHER_MISMATCH. When using OpenSSL or | |
2231 // Secure Transport (OS X), the handshake_failure is bubbled up without any | |
2232 // interpretation, leading to ERR_SSL_PROTOCOL_ERROR. Either way, a failure | |
2233 // indicates that no cipher suite was negotiated with the test server. | |
2234 if (rv == ERR_IO_PENDING) | |
2235 rv = callback.WaitForResult(); | |
2236 EXPECT_TRUE(rv == ERR_SSL_VERSION_OR_CIPHER_MISMATCH || | |
2237 rv == ERR_SSL_PROTOCOL_ERROR); | |
2238 // The exact ordering differs between SSLClientSocketNSS (which issues an | |
2239 // extra read) and SSLClientSocketMac (which does not). Just make sure the | |
2240 // error appears somewhere in the log. | |
2241 log.GetEntries(&entries); | |
2242 ExpectLogContainsSomewhere( | |
2243 entries, 0, NetLog::TYPE_SSL_HANDSHAKE_ERROR, NetLog::PHASE_NONE); | |
2244 | |
2245 // We cannot test sock->IsConnected(), as the NSS implementation disconnects | |
2246 // the socket when it encounters an error, whereas other implementations | |
2247 // leave it connected. | |
2248 // Because this an error that the test server is mutually aware of, as opposed | |
2249 // to being an error such as a certificate name mismatch, which is | |
2250 // client-only, the exact index of the SSL connect end depends on how | |
2251 // quickly the test server closes the underlying socket. If the test server | |
2252 // closes before the IO message loop pumps messages, there may be a 0-byte | |
2253 // Read event in the NetLog due to TCPClientSocket picking up the EOF. As a | |
2254 // result, the SSL connect end event will be the second-to-last entry, | |
2255 // rather than the last entry. | |
2256 EXPECT_TRUE(LogContainsSSLConnectEndEvent(entries, -1) || | |
2257 LogContainsSSLConnectEndEvent(entries, -2)); | |
2258 } | |
2259 | |
2260 // When creating an SSLClientSocket, it is allowed to pass in a | |
2261 // ClientSocketHandle that is not obtained from a client socket pool. | |
2262 // Here we verify that such a simple ClientSocketHandle, not associated with any | |
2263 // client socket pool, can be destroyed safely. | |
2264 TEST_F(SSLClientSocketTest, ClientSocketHandleNotFromPool) { | |
2265 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, | |
2266 SpawnedTestServer::kLocalhost, | |
2267 base::FilePath()); | |
2268 ASSERT_TRUE(test_server.Start()); | |
2269 | |
2270 AddressList addr; | |
2271 ASSERT_TRUE(test_server.GetAddressList(&addr)); | |
2272 | |
2273 TestCompletionCallback callback; | |
2274 scoped_ptr<StreamSocket> transport( | |
2275 new TCPClientSocket(addr, NULL, NetLog::Source())); | |
2276 int rv = transport->Connect(callback.callback()); | |
2277 if (rv == ERR_IO_PENDING) | |
2278 rv = callback.WaitForResult(); | |
2279 EXPECT_EQ(OK, rv); | |
2280 | |
2281 scoped_ptr<ClientSocketHandle> socket_handle(new ClientSocketHandle()); | |
2282 socket_handle->SetSocket(transport.Pass()); | |
2283 | |
2284 scoped_ptr<SSLClientSocket> sock(socket_factory_->CreateSSLClientSocket( | |
2285 socket_handle.Pass(), test_server.host_port_pair(), SSLConfig(), | |
2286 context_)); | |
2287 | |
2288 EXPECT_FALSE(sock->IsConnected()); | |
2289 rv = sock->Connect(callback.callback()); | |
2290 if (rv == ERR_IO_PENDING) | |
2291 rv = callback.WaitForResult(); | |
2292 EXPECT_EQ(OK, rv); | |
2293 } | |
2294 | |
2295 // Verifies that SSLClientSocket::ExportKeyingMaterial return a success | |
2296 // code and different keying label results in different keying material. | |
2297 TEST_F(SSLClientSocketTest, ExportKeyingMaterial) { | |
2298 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, | |
2299 SpawnedTestServer::kLocalhost, | |
2300 base::FilePath()); | |
2301 ASSERT_TRUE(test_server.Start()); | |
2302 | |
2303 AddressList addr; | |
2304 ASSERT_TRUE(test_server.GetAddressList(&addr)); | |
2305 | |
2306 TestCompletionCallback callback; | |
2307 | |
2308 scoped_ptr<StreamSocket> transport( | |
2309 new TCPClientSocket(addr, NULL, NetLog::Source())); | |
2310 int rv = transport->Connect(callback.callback()); | |
2311 if (rv == ERR_IO_PENDING) | |
2312 rv = callback.WaitForResult(); | |
2313 EXPECT_EQ(OK, rv); | |
2314 | |
2315 scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket( | |
2316 transport.Pass(), test_server.host_port_pair(), SSLConfig())); | |
2317 | |
2318 rv = sock->Connect(callback.callback()); | |
2319 if (rv == ERR_IO_PENDING) | |
2320 rv = callback.WaitForResult(); | |
2321 EXPECT_EQ(OK, rv); | |
2322 EXPECT_TRUE(sock->IsConnected()); | |
2323 | |
2324 const int kKeyingMaterialSize = 32; | |
2325 const char kKeyingLabel1[] = "client-socket-test-1"; | |
2326 const char kKeyingContext[] = ""; | |
2327 unsigned char client_out1[kKeyingMaterialSize]; | |
2328 memset(client_out1, 0, sizeof(client_out1)); | |
2329 rv = sock->ExportKeyingMaterial( | |
2330 kKeyingLabel1, false, kKeyingContext, client_out1, sizeof(client_out1)); | |
2331 EXPECT_EQ(rv, OK); | |
2332 | |
2333 const char kKeyingLabel2[] = "client-socket-test-2"; | |
2334 unsigned char client_out2[kKeyingMaterialSize]; | |
2335 memset(client_out2, 0, sizeof(client_out2)); | |
2336 rv = sock->ExportKeyingMaterial( | |
2337 kKeyingLabel2, false, kKeyingContext, client_out2, sizeof(client_out2)); | |
2338 EXPECT_EQ(rv, OK); | |
2339 EXPECT_NE(memcmp(client_out1, client_out2, kKeyingMaterialSize), 0); | |
2340 } | |
2341 | |
2342 // Verifies that SSLClientSocket::ClearSessionCache can be called without | |
2343 // explicit NSS initialization. | |
2344 TEST(SSLClientSocket, ClearSessionCache) { | |
2345 SSLClientSocket::ClearSessionCache(); | |
2346 } | |
2347 | |
2348 TEST(SSLClientSocket, SerializeNextProtos) { | |
2349 NextProtoVector next_protos; | |
2350 next_protos.push_back(kProtoHTTP11); | |
2351 next_protos.push_back(kProtoSPDY31); | |
2352 static std::vector<uint8_t> serialized = | |
2353 SSLClientSocket::SerializeNextProtos(next_protos, true); | |
2354 ASSERT_EQ(18u, serialized.size()); | |
2355 EXPECT_EQ(8, serialized[0]); // length("http/1.1") | |
2356 EXPECT_EQ('h', serialized[1]); | |
2357 EXPECT_EQ('t', serialized[2]); | |
2358 EXPECT_EQ('t', serialized[3]); | |
2359 EXPECT_EQ('p', serialized[4]); | |
2360 EXPECT_EQ('/', serialized[5]); | |
2361 EXPECT_EQ('1', serialized[6]); | |
2362 EXPECT_EQ('.', serialized[7]); | |
2363 EXPECT_EQ('1', serialized[8]); | |
2364 EXPECT_EQ(8, serialized[9]); // length("spdy/3.1") | |
2365 EXPECT_EQ('s', serialized[10]); | |
2366 EXPECT_EQ('p', serialized[11]); | |
2367 EXPECT_EQ('d', serialized[12]); | |
2368 EXPECT_EQ('y', serialized[13]); | |
2369 EXPECT_EQ('/', serialized[14]); | |
2370 EXPECT_EQ('3', serialized[15]); | |
2371 EXPECT_EQ('.', serialized[16]); | |
2372 EXPECT_EQ('1', serialized[17]); | |
2373 } | |
2374 | |
2375 // Test that the server certificates are properly retrieved from the underlying | |
2376 // SSL stack. | |
2377 TEST_F(SSLClientSocketTest, VerifyServerChainProperlyOrdered) { | |
2378 // The connection does not have to be successful. | |
2379 cert_verifier_->set_default_result(ERR_CERT_INVALID); | |
2380 | |
2381 // Set up a test server with CERT_CHAIN_WRONG_ROOT. | |
2382 // This makes the server present redundant-server-chain.pem, which contains | |
2383 // intermediate certificates. | |
2384 SpawnedTestServer::SSLOptions ssl_options( | |
2385 SpawnedTestServer::SSLOptions::CERT_CHAIN_WRONG_ROOT); | |
2386 SpawnedTestServer test_server( | |
2387 SpawnedTestServer::TYPE_HTTPS, ssl_options, base::FilePath()); | |
2388 ASSERT_TRUE(test_server.Start()); | |
2389 | |
2390 AddressList addr; | |
2391 ASSERT_TRUE(test_server.GetAddressList(&addr)); | |
2392 | |
2393 TestCompletionCallback callback; | |
2394 scoped_ptr<StreamSocket> transport( | |
2395 new TCPClientSocket(addr, NULL, NetLog::Source())); | |
2396 int rv = transport->Connect(callback.callback()); | |
2397 rv = callback.GetResult(rv); | |
2398 EXPECT_EQ(OK, rv); | |
2399 | |
2400 scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket( | |
2401 transport.Pass(), test_server.host_port_pair(), SSLConfig())); | |
2402 EXPECT_FALSE(sock->IsConnected()); | |
2403 rv = sock->Connect(callback.callback()); | |
2404 rv = callback.GetResult(rv); | |
2405 | |
2406 EXPECT_EQ(ERR_CERT_INVALID, rv); | |
2407 EXPECT_TRUE(sock->IsConnected()); | |
2408 | |
2409 // When given option CERT_CHAIN_WRONG_ROOT, SpawnedTestServer will present | |
2410 // certs from redundant-server-chain.pem. | |
2411 CertificateList server_certs = | |
2412 CreateCertificateListFromFile(GetTestCertsDirectory(), | |
2413 "redundant-server-chain.pem", | |
2414 X509Certificate::FORMAT_AUTO); | |
2415 | |
2416 // Get the server certificate as received client side. | |
2417 scoped_refptr<X509Certificate> server_certificate = | |
2418 sock->GetUnverifiedServerCertificateChain(); | |
2419 | |
2420 // Get the intermediates as received client side. | |
2421 const X509Certificate::OSCertHandles& server_intermediates = | |
2422 server_certificate->GetIntermediateCertificates(); | |
2423 | |
2424 // Check that the unverified server certificate chain is properly retrieved | |
2425 // from the underlying ssl stack. | |
2426 ASSERT_EQ(4U, server_certs.size()); | |
2427 | |
2428 EXPECT_TRUE(X509Certificate::IsSameOSCert( | |
2429 server_certificate->os_cert_handle(), server_certs[0]->os_cert_handle())); | |
2430 | |
2431 ASSERT_EQ(3U, server_intermediates.size()); | |
2432 | |
2433 EXPECT_TRUE(X509Certificate::IsSameOSCert(server_intermediates[0], | |
2434 server_certs[1]->os_cert_handle())); | |
2435 EXPECT_TRUE(X509Certificate::IsSameOSCert(server_intermediates[1], | |
2436 server_certs[2]->os_cert_handle())); | |
2437 EXPECT_TRUE(X509Certificate::IsSameOSCert(server_intermediates[2], | |
2438 server_certs[3]->os_cert_handle())); | |
2439 | |
2440 sock->Disconnect(); | |
2441 EXPECT_FALSE(sock->IsConnected()); | |
2442 } | |
2443 | |
2444 // This tests that SSLInfo contains a properly re-constructed certificate | |
2445 // chain. That, in turn, verifies that GetSSLInfo is giving us the chain as | |
2446 // verified, not the chain as served by the server. (They may be different.) | |
2447 // | |
2448 // CERT_CHAIN_WRONG_ROOT is redundant-server-chain.pem. It contains A | |
2449 // (end-entity) -> B -> C, and C is signed by D. redundant-validated-chain.pem | |
2450 // contains a chain of A -> B -> C2, where C2 is the same public key as C, but | |
2451 // a self-signed root. Such a situation can occur when a new root (C2) is | |
2452 // cross-certified by an old root (D) and has two different versions of its | |
2453 // floating around. Servers may supply C2 as an intermediate, but the | |
2454 // SSLClientSocket should return the chain that was verified, from | |
2455 // verify_result, instead. | |
2456 TEST_F(SSLClientSocketTest, VerifyReturnChainProperlyOrdered) { | |
2457 // By default, cause the CertVerifier to treat all certificates as | |
2458 // expired. | |
2459 cert_verifier_->set_default_result(ERR_CERT_DATE_INVALID); | |
2460 | |
2461 // We will expect SSLInfo to ultimately contain this chain. | |
2462 CertificateList certs = | |
2463 CreateCertificateListFromFile(GetTestCertsDirectory(), | |
2464 "redundant-validated-chain.pem", | |
2465 X509Certificate::FORMAT_AUTO); | |
2466 ASSERT_EQ(3U, certs.size()); | |
2467 | |
2468 X509Certificate::OSCertHandles temp_intermediates; | |
2469 temp_intermediates.push_back(certs[1]->os_cert_handle()); | |
2470 temp_intermediates.push_back(certs[2]->os_cert_handle()); | |
2471 | |
2472 CertVerifyResult verify_result; | |
2473 verify_result.verified_cert = X509Certificate::CreateFromHandle( | |
2474 certs[0]->os_cert_handle(), temp_intermediates); | |
2475 | |
2476 // Add a rule that maps the server cert (A) to the chain of A->B->C2 | |
2477 // rather than A->B->C. | |
2478 cert_verifier_->AddResultForCert(certs[0].get(), verify_result, OK); | |
2479 | |
2480 // Load and install the root for the validated chain. | |
2481 scoped_refptr<X509Certificate> root_cert = ImportCertFromFile( | |
2482 GetTestCertsDirectory(), "redundant-validated-chain-root.pem"); | |
2483 ASSERT_NE(static_cast<X509Certificate*>(NULL), root_cert.get()); | |
2484 ScopedTestRoot scoped_root(root_cert.get()); | |
2485 | |
2486 // Set up a test server with CERT_CHAIN_WRONG_ROOT. | |
2487 SpawnedTestServer::SSLOptions ssl_options( | |
2488 SpawnedTestServer::SSLOptions::CERT_CHAIN_WRONG_ROOT); | |
2489 SpawnedTestServer test_server( | |
2490 SpawnedTestServer::TYPE_HTTPS, | |
2491 ssl_options, | |
2492 base::FilePath(FILE_PATH_LITERAL("net/data/ssl"))); | |
2493 ASSERT_TRUE(test_server.Start()); | |
2494 | |
2495 AddressList addr; | |
2496 ASSERT_TRUE(test_server.GetAddressList(&addr)); | |
2497 | |
2498 TestCompletionCallback callback; | |
2499 CapturingNetLog log; | |
2500 scoped_ptr<StreamSocket> transport( | |
2501 new TCPClientSocket(addr, &log, NetLog::Source())); | |
2502 int rv = transport->Connect(callback.callback()); | |
2503 if (rv == ERR_IO_PENDING) | |
2504 rv = callback.WaitForResult(); | |
2505 EXPECT_EQ(OK, rv); | |
2506 | |
2507 scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket( | |
2508 transport.Pass(), test_server.host_port_pair(), SSLConfig())); | |
2509 EXPECT_FALSE(sock->IsConnected()); | |
2510 rv = sock->Connect(callback.callback()); | |
2511 | |
2512 CapturingNetLog::CapturedEntryList entries; | |
2513 log.GetEntries(&entries); | |
2514 EXPECT_TRUE(LogContainsBeginEvent(entries, 5, NetLog::TYPE_SSL_CONNECT)); | |
2515 if (rv == ERR_IO_PENDING) | |
2516 rv = callback.WaitForResult(); | |
2517 | |
2518 EXPECT_EQ(OK, rv); | |
2519 EXPECT_TRUE(sock->IsConnected()); | |
2520 log.GetEntries(&entries); | |
2521 EXPECT_TRUE(LogContainsSSLConnectEndEvent(entries, -1)); | |
2522 | |
2523 SSLInfo ssl_info; | |
2524 sock->GetSSLInfo(&ssl_info); | |
2525 | |
2526 // Verify that SSLInfo contains the corrected re-constructed chain A -> B | |
2527 // -> C2. | |
2528 const X509Certificate::OSCertHandles& intermediates = | |
2529 ssl_info.cert->GetIntermediateCertificates(); | |
2530 ASSERT_EQ(2U, intermediates.size()); | |
2531 EXPECT_TRUE(X509Certificate::IsSameOSCert(ssl_info.cert->os_cert_handle(), | |
2532 certs[0]->os_cert_handle())); | |
2533 EXPECT_TRUE(X509Certificate::IsSameOSCert(intermediates[0], | |
2534 certs[1]->os_cert_handle())); | |
2535 EXPECT_TRUE(X509Certificate::IsSameOSCert(intermediates[1], | |
2536 certs[2]->os_cert_handle())); | |
2537 | |
2538 sock->Disconnect(); | |
2539 EXPECT_FALSE(sock->IsConnected()); | |
2540 } | |
2541 | |
2542 TEST_F(SSLClientSocketCertRequestInfoTest, NoAuthorities) { | |
2543 SpawnedTestServer::SSLOptions ssl_options; | |
2544 ssl_options.request_client_certificate = true; | |
2545 scoped_refptr<SSLCertRequestInfo> request_info = GetCertRequest(ssl_options); | |
2546 ASSERT_TRUE(request_info.get()); | |
2547 EXPECT_EQ(0u, request_info->cert_authorities.size()); | |
2548 } | |
2549 | |
2550 TEST_F(SSLClientSocketCertRequestInfoTest, TwoAuthorities) { | |
2551 const base::FilePath::CharType kThawteFile[] = | |
2552 FILE_PATH_LITERAL("thawte.single.pem"); | |
2553 const unsigned char kThawteDN[] = { | |
2554 0x30, 0x4c, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, | |
2555 0x02, 0x5a, 0x41, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0a, | |
2556 0x13, 0x1c, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x43, 0x6f, 0x6e, | |
2557 0x73, 0x75, 0x6c, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x28, 0x50, 0x74, 0x79, | |
2558 0x29, 0x20, 0x4c, 0x74, 0x64, 0x2e, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, | |
2559 0x55, 0x04, 0x03, 0x13, 0x0d, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, | |
2560 0x53, 0x47, 0x43, 0x20, 0x43, 0x41}; | |
2561 const size_t kThawteLen = sizeof(kThawteDN); | |
2562 | |
2563 const base::FilePath::CharType kDiginotarFile[] = | |
2564 FILE_PATH_LITERAL("diginotar_root_ca.pem"); | |
2565 const unsigned char kDiginotarDN[] = { | |
2566 0x30, 0x5f, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, | |
2567 0x02, 0x4e, 0x4c, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0a, | |
2568 0x13, 0x09, 0x44, 0x69, 0x67, 0x69, 0x4e, 0x6f, 0x74, 0x61, 0x72, 0x31, | |
2569 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x44, 0x69, | |
2570 0x67, 0x69, 0x4e, 0x6f, 0x74, 0x61, 0x72, 0x20, 0x52, 0x6f, 0x6f, 0x74, | |
2571 0x20, 0x43, 0x41, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x09, 0x2a, 0x86, 0x48, | |
2572 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x11, 0x69, 0x6e, 0x66, 0x6f, | |
2573 0x40, 0x64, 0x69, 0x67, 0x69, 0x6e, 0x6f, 0x74, 0x61, 0x72, 0x2e, 0x6e, | |
2574 0x6c}; | |
2575 const size_t kDiginotarLen = sizeof(kDiginotarDN); | |
2576 | |
2577 SpawnedTestServer::SSLOptions ssl_options; | |
2578 ssl_options.request_client_certificate = true; | |
2579 ssl_options.client_authorities.push_back( | |
2580 GetTestClientCertsDirectory().Append(kThawteFile)); | |
2581 ssl_options.client_authorities.push_back( | |
2582 GetTestClientCertsDirectory().Append(kDiginotarFile)); | |
2583 scoped_refptr<SSLCertRequestInfo> request_info = GetCertRequest(ssl_options); | |
2584 ASSERT_TRUE(request_info.get()); | |
2585 ASSERT_EQ(2u, request_info->cert_authorities.size()); | |
2586 EXPECT_EQ(std::string(reinterpret_cast<const char*>(kThawteDN), kThawteLen), | |
2587 request_info->cert_authorities[0]); | |
2588 EXPECT_EQ( | |
2589 std::string(reinterpret_cast<const char*>(kDiginotarDN), kDiginotarLen), | |
2590 request_info->cert_authorities[1]); | |
2591 } | |
2592 | |
2593 // cert_key_types is currently only populated on OpenSSL. | |
2594 #if defined(USE_OPENSSL) | |
2595 TEST_F(SSLClientSocketCertRequestInfoTest, CertKeyTypes) { | |
2596 SpawnedTestServer::SSLOptions ssl_options; | |
2597 ssl_options.request_client_certificate = true; | |
2598 ssl_options.client_cert_types.push_back(CLIENT_CERT_RSA_SIGN); | |
2599 ssl_options.client_cert_types.push_back(CLIENT_CERT_ECDSA_SIGN); | |
2600 scoped_refptr<SSLCertRequestInfo> request_info = GetCertRequest(ssl_options); | |
2601 ASSERT_TRUE(request_info.get()); | |
2602 ASSERT_EQ(2u, request_info->cert_key_types.size()); | |
2603 EXPECT_EQ(CLIENT_CERT_RSA_SIGN, request_info->cert_key_types[0]); | |
2604 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, request_info->cert_key_types[1]); | |
2605 } | |
2606 #endif // defined(USE_OPENSSL) | |
2607 | |
2608 TEST_F(SSLClientSocketTest, ConnectSignedCertTimestampsEnabledTLSExtension) { | |
2609 SpawnedTestServer::SSLOptions ssl_options; | |
2610 ssl_options.signed_cert_timestamps_tls_ext = "test"; | |
2611 | |
2612 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, | |
2613 ssl_options, | |
2614 base::FilePath()); | |
2615 ASSERT_TRUE(test_server.Start()); | |
2616 | |
2617 AddressList addr; | |
2618 ASSERT_TRUE(test_server.GetAddressList(&addr)); | |
2619 | |
2620 TestCompletionCallback callback; | |
2621 scoped_ptr<StreamSocket> transport( | |
2622 new TCPClientSocket(addr, &log_, NetLog::Source())); | |
2623 int rv = callback.GetResult(transport->Connect(callback.callback())); | |
2624 EXPECT_EQ(OK, rv); | |
2625 | |
2626 SSLConfig ssl_config; | |
2627 ssl_config.signed_cert_timestamps_enabled = true; | |
2628 | |
2629 MockCTVerifier ct_verifier; | |
2630 SetCTVerifier(&ct_verifier); | |
2631 | |
2632 // Check that the SCT list is extracted as expected. | |
2633 EXPECT_CALL(ct_verifier, Verify(_, "", "test", _, _)).WillRepeatedly( | |
2634 Return(ERR_CT_NO_SCTS_VERIFIED_OK)); | |
2635 | |
2636 scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket( | |
2637 transport.Pass(), test_server.host_port_pair(), ssl_config)); | |
2638 rv = callback.GetResult(sock->Connect(callback.callback())); | |
2639 EXPECT_EQ(OK, rv); | |
2640 | |
2641 EXPECT_TRUE(sock->signed_cert_timestamps_received_); | |
2642 } | |
2643 | |
2644 namespace { | |
2645 | |
2646 bool IsValidOCSPResponse(const base::StringPiece& input) { | |
2647 base::StringPiece ocsp_response = input; | |
2648 base::StringPiece sequence, response_status, response_bytes; | |
2649 return asn1::GetElement(&ocsp_response, asn1::kSEQUENCE, &sequence) && | |
2650 ocsp_response.empty() && | |
2651 asn1::GetElement(&sequence, asn1::kENUMERATED, &response_status) && | |
2652 asn1::GetElement(&sequence, | |
2653 asn1::kContextSpecific | asn1::kConstructed | 0, | |
2654 &response_status) && | |
2655 sequence.empty(); | |
2656 } | |
2657 | |
2658 } // namespace | |
2659 | |
2660 // Test that enabling Signed Certificate Timestamps enables OCSP stapling. | |
2661 TEST_F(SSLClientSocketTest, ConnectSignedCertTimestampsEnabledOCSP) { | |
2662 SpawnedTestServer::SSLOptions ssl_options; | |
2663 ssl_options.staple_ocsp_response = true; | |
2664 // The test server currently only knows how to generate OCSP responses | |
2665 // for a freshly minted certificate. | |
2666 ssl_options.server_certificate = SpawnedTestServer::SSLOptions::CERT_AUTO; | |
2667 | |
2668 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, | |
2669 ssl_options, | |
2670 base::FilePath()); | |
2671 ASSERT_TRUE(test_server.Start()); | |
2672 | |
2673 AddressList addr; | |
2674 ASSERT_TRUE(test_server.GetAddressList(&addr)); | |
2675 | |
2676 TestCompletionCallback callback; | |
2677 scoped_ptr<StreamSocket> transport( | |
2678 new TCPClientSocket(addr, &log_, NetLog::Source())); | |
2679 int rv = callback.GetResult(transport->Connect(callback.callback())); | |
2680 EXPECT_EQ(OK, rv); | |
2681 | |
2682 SSLConfig ssl_config; | |
2683 // Enabling Signed Cert Timestamps ensures we request OCSP stapling for | |
2684 // Certificate Transparency verification regardless of whether the platform | |
2685 // is able to process the OCSP status itself. | |
2686 ssl_config.signed_cert_timestamps_enabled = true; | |
2687 | |
2688 MockCTVerifier ct_verifier; | |
2689 SetCTVerifier(&ct_verifier); | |
2690 | |
2691 // Check that the OCSP response is extracted and well-formed. It should be the | |
2692 // DER encoding of an OCSPResponse (RFC 2560), so check that it consists of a | |
2693 // SEQUENCE of an ENUMERATED type and an element tagged with [0] EXPLICIT. In | |
2694 // particular, it should not include the overall two-byte length prefix from | |
2695 // TLS. | |
2696 EXPECT_CALL(ct_verifier, | |
2697 Verify(_, Truly(IsValidOCSPResponse), "", _, _)).WillRepeatedly( | |
2698 Return(ERR_CT_NO_SCTS_VERIFIED_OK)); | |
2699 | |
2700 scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket( | |
2701 transport.Pass(), test_server.host_port_pair(), ssl_config)); | |
2702 rv = callback.GetResult(sock->Connect(callback.callback())); | |
2703 EXPECT_EQ(OK, rv); | |
2704 | |
2705 EXPECT_TRUE(sock->stapled_ocsp_response_received_); | |
2706 } | |
2707 | |
2708 TEST_F(SSLClientSocketTest, ConnectSignedCertTimestampsDisabled) { | |
2709 SpawnedTestServer::SSLOptions ssl_options; | |
2710 ssl_options.signed_cert_timestamps_tls_ext = "test"; | |
2711 | |
2712 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, | |
2713 ssl_options, | |
2714 base::FilePath()); | |
2715 ASSERT_TRUE(test_server.Start()); | |
2716 | |
2717 AddressList addr; | |
2718 ASSERT_TRUE(test_server.GetAddressList(&addr)); | |
2719 | |
2720 TestCompletionCallback callback; | |
2721 scoped_ptr<StreamSocket> transport( | |
2722 new TCPClientSocket(addr, &log_, NetLog::Source())); | |
2723 int rv = callback.GetResult(transport->Connect(callback.callback())); | |
2724 EXPECT_EQ(OK, rv); | |
2725 | |
2726 SSLConfig ssl_config; | |
2727 ssl_config.signed_cert_timestamps_enabled = false; | |
2728 | |
2729 scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket( | |
2730 transport.Pass(), test_server.host_port_pair(), ssl_config)); | |
2731 rv = callback.GetResult(sock->Connect(callback.callback())); | |
2732 EXPECT_EQ(OK, rv); | |
2733 | |
2734 EXPECT_FALSE(sock->signed_cert_timestamps_received_); | |
2735 } | |
2736 | |
2737 // Tests that IsConnectedAndIdle and WasEverUsed behave as expected. | |
2738 TEST_F(SSLClientSocketTest, ReuseStates) { | |
2739 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, | |
2740 SpawnedTestServer::kLocalhost, | |
2741 base::FilePath()); | |
2742 ASSERT_TRUE(test_server.Start()); | |
2743 | |
2744 AddressList addr; | |
2745 ASSERT_TRUE(test_server.GetAddressList(&addr)); | |
2746 | |
2747 TestCompletionCallback callback; | |
2748 scoped_ptr<StreamSocket> transport( | |
2749 new TCPClientSocket(addr, NULL, NetLog::Source())); | |
2750 int rv = transport->Connect(callback.callback()); | |
2751 if (rv == ERR_IO_PENDING) | |
2752 rv = callback.WaitForResult(); | |
2753 EXPECT_EQ(OK, rv); | |
2754 | |
2755 scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket( | |
2756 transport.Pass(), test_server.host_port_pair(), SSLConfig())); | |
2757 | |
2758 rv = sock->Connect(callback.callback()); | |
2759 if (rv == ERR_IO_PENDING) | |
2760 rv = callback.WaitForResult(); | |
2761 EXPECT_EQ(OK, rv); | |
2762 | |
2763 // The socket was just connected. It should be idle because it is speaking | |
2764 // HTTP. Although the transport has been used for the handshake, WasEverUsed() | |
2765 // returns false. | |
2766 EXPECT_TRUE(sock->IsConnected()); | |
2767 EXPECT_TRUE(sock->IsConnectedAndIdle()); | |
2768 EXPECT_FALSE(sock->WasEverUsed()); | |
2769 | |
2770 const char kRequestText[] = "GET / HTTP/1.0\r\n\r\n"; | |
2771 const size_t kRequestLen = arraysize(kRequestText) - 1; | |
2772 scoped_refptr<IOBuffer> request_buffer(new IOBuffer(kRequestLen)); | |
2773 memcpy(request_buffer->data(), kRequestText, kRequestLen); | |
2774 | |
2775 rv = sock->Write(request_buffer.get(), kRequestLen, callback.callback()); | |
2776 EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING); | |
2777 | |
2778 if (rv == ERR_IO_PENDING) | |
2779 rv = callback.WaitForResult(); | |
2780 EXPECT_EQ(static_cast<int>(kRequestLen), rv); | |
2781 | |
2782 // The socket has now been used. | |
2783 EXPECT_TRUE(sock->WasEverUsed()); | |
2784 | |
2785 // TODO(davidben): Read one byte to ensure the test server has responded and | |
2786 // then assert IsConnectedAndIdle is false. This currently doesn't work | |
2787 // because neither SSLClientSocketNSS nor SSLClientSocketOpenSSL check their | |
2788 // SSL implementation's internal buffers. Either call PR_Available and | |
2789 // SSL_pending, although the former isn't actually implemented or perhaps | |
2790 // attempt to read one byte extra. | |
2791 } | |
2792 | |
2793 #if defined(USE_OPENSSL) | |
2794 | |
2795 TEST_F(SSLClientSocketTest, HandshakeCallbackIsRun_WithFailure) { | |
2796 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, | |
2797 SpawnedTestServer::kLocalhost, | |
2798 base::FilePath()); | |
2799 ASSERT_TRUE(test_server.Start()); | |
2800 | |
2801 AddressList addr; | |
2802 ASSERT_TRUE(test_server.GetAddressList(&addr)); | |
2803 | |
2804 TestCompletionCallback callback; | |
2805 scoped_ptr<StreamSocket> real_transport( | |
2806 new TCPClientSocket(addr, NULL, NetLog::Source())); | |
2807 scoped_ptr<SynchronousErrorStreamSocket> transport( | |
2808 new SynchronousErrorStreamSocket(real_transport.Pass())); | |
2809 int rv = callback.GetResult(transport->Connect(callback.callback())); | |
2810 EXPECT_EQ(OK, rv); | |
2811 | |
2812 // Disable TLS False Start to avoid handshake non-determinism. | |
2813 SSLConfig ssl_config; | |
2814 ssl_config.false_start_enabled = false; | |
2815 | |
2816 SynchronousErrorStreamSocket* raw_transport = transport.get(); | |
2817 scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket( | |
2818 transport.Pass(), test_server.host_port_pair(), ssl_config)); | |
2819 | |
2820 sock->SetHandshakeCompletionCallback(base::Bind( | |
2821 &SSLClientSocketTest::RecordCompletedHandshake, base::Unretained(this))); | |
2822 | |
2823 raw_transport->SetNextWriteError(ERR_CONNECTION_RESET); | |
2824 | |
2825 rv = callback.GetResult(sock->Connect(callback.callback())); | |
2826 EXPECT_EQ(ERR_CONNECTION_RESET, rv); | |
2827 EXPECT_FALSE(sock->IsConnected()); | |
2828 | |
2829 EXPECT_TRUE(ran_handshake_completion_callback_); | |
2830 } | |
2831 | |
2832 // Tests that the completion callback is run when an SSL connection | |
2833 // completes successfully. | |
2834 TEST_F(SSLClientSocketTest, HandshakeCallbackIsRun_WithSuccess) { | |
2835 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, | |
2836 SpawnedTestServer::kLocalhost, | |
2837 base::FilePath()); | |
2838 ASSERT_TRUE(test_server.Start()); | |
2839 | |
2840 AddressList addr; | |
2841 ASSERT_TRUE(test_server.GetAddressList(&addr)); | |
2842 | |
2843 scoped_ptr<StreamSocket> transport( | |
2844 new TCPClientSocket(addr, NULL, NetLog::Source())); | |
2845 | |
2846 TestCompletionCallback callback; | |
2847 int rv = transport->Connect(callback.callback()); | |
2848 if (rv == ERR_IO_PENDING) | |
2849 rv = callback.WaitForResult(); | |
2850 EXPECT_EQ(OK, rv); | |
2851 | |
2852 SSLConfig ssl_config; | |
2853 ssl_config.false_start_enabled = false; | |
2854 | |
2855 scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket( | |
2856 transport.Pass(), test_server.host_port_pair(), ssl_config)); | |
2857 | |
2858 sock->SetHandshakeCompletionCallback(base::Bind( | |
2859 &SSLClientSocketTest::RecordCompletedHandshake, base::Unretained(this))); | |
2860 | |
2861 rv = callback.GetResult(sock->Connect(callback.callback())); | |
2862 | |
2863 EXPECT_EQ(OK, rv); | |
2864 EXPECT_TRUE(sock->IsConnected()); | |
2865 EXPECT_TRUE(ran_handshake_completion_callback_); | |
2866 } | |
2867 | |
2868 // Tests that the completion callback is run with a server that doesn't cache | |
2869 // sessions. | |
2870 TEST_F(SSLClientSocketTest, HandshakeCallbackIsRun_WithDisabledSessionCache) { | |
2871 SpawnedTestServer::SSLOptions ssl_options; | |
2872 ssl_options.disable_session_cache = true; | |
2873 SpawnedTestServer test_server( | |
2874 SpawnedTestServer::TYPE_HTTPS, ssl_options, base::FilePath()); | |
2875 ASSERT_TRUE(test_server.Start()); | |
2876 | |
2877 AddressList addr; | |
2878 ASSERT_TRUE(test_server.GetAddressList(&addr)); | |
2879 | |
2880 scoped_ptr<StreamSocket> transport( | |
2881 new TCPClientSocket(addr, NULL, NetLog::Source())); | |
2882 | |
2883 TestCompletionCallback callback; | |
2884 int rv = transport->Connect(callback.callback()); | |
2885 if (rv == ERR_IO_PENDING) | |
2886 rv = callback.WaitForResult(); | |
2887 EXPECT_EQ(OK, rv); | |
2888 | |
2889 SSLConfig ssl_config; | |
2890 ssl_config.false_start_enabled = false; | |
2891 | |
2892 scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket( | |
2893 transport.Pass(), test_server.host_port_pair(), ssl_config)); | |
2894 | |
2895 sock->SetHandshakeCompletionCallback(base::Bind( | |
2896 &SSLClientSocketTest::RecordCompletedHandshake, base::Unretained(this))); | |
2897 | |
2898 rv = callback.GetResult(sock->Connect(callback.callback())); | |
2899 | |
2900 EXPECT_EQ(OK, rv); | |
2901 EXPECT_TRUE(sock->IsConnected()); | |
2902 EXPECT_TRUE(ran_handshake_completion_callback_); | |
2903 } | |
2904 | |
2905 TEST_F(SSLClientSocketFalseStartTest, | |
2906 HandshakeCallbackIsRun_WithFalseStartFailure) { | |
2907 // False Start requires NPN and a forward-secret cipher suite. | |
2908 SpawnedTestServer::SSLOptions server_options; | |
2909 server_options.key_exchanges = | |
2910 SpawnedTestServer::SSLOptions::KEY_EXCHANGE_DHE_RSA; | |
2911 server_options.enable_npn = true; | |
2912 SSLConfig client_config; | |
2913 client_config.next_protos.push_back(kProtoHTTP11); | |
2914 monitor_handshake_callback_ = true; | |
2915 fail_handshake_after_false_start_ = true; | |
2916 ASSERT_NO_FATAL_FAILURE(TestFalseStart(server_options, client_config, true)); | |
2917 ASSERT_TRUE(ran_handshake_completion_callback_); | |
2918 } | |
2919 | |
2920 TEST_F(SSLClientSocketFalseStartTest, | |
2921 HandshakeCallbackIsRun_WithFalseStartSuccess) { | |
2922 // False Start requires NPN and a forward-secret cipher suite. | |
2923 SpawnedTestServer::SSLOptions server_options; | |
2924 server_options.key_exchanges = | |
2925 SpawnedTestServer::SSLOptions::KEY_EXCHANGE_DHE_RSA; | |
2926 server_options.enable_npn = true; | |
2927 SSLConfig client_config; | |
2928 client_config.next_protos.push_back(kProtoHTTP11); | |
2929 monitor_handshake_callback_ = true; | |
2930 ASSERT_NO_FATAL_FAILURE(TestFalseStart(server_options, client_config, true)); | |
2931 ASSERT_TRUE(ran_handshake_completion_callback_); | |
2932 } | |
2933 #endif // defined(USE_OPENSSL) | |
2934 | |
2935 TEST_F(SSLClientSocketFalseStartTest, FalseStartEnabled) { | |
2936 // False Start requires NPN and a forward-secret cipher suite. | |
2937 SpawnedTestServer::SSLOptions server_options; | |
2938 server_options.key_exchanges = | |
2939 SpawnedTestServer::SSLOptions::KEY_EXCHANGE_DHE_RSA; | |
2940 server_options.enable_npn = true; | |
2941 SSLConfig client_config; | |
2942 client_config.next_protos.push_back(kProtoHTTP11); | |
2943 ASSERT_NO_FATAL_FAILURE( | |
2944 TestFalseStart(server_options, client_config, true)); | |
2945 } | |
2946 | |
2947 // Test that False Start is disabled without NPN. | |
2948 TEST_F(SSLClientSocketFalseStartTest, NoNPN) { | |
2949 SpawnedTestServer::SSLOptions server_options; | |
2950 server_options.key_exchanges = | |
2951 SpawnedTestServer::SSLOptions::KEY_EXCHANGE_DHE_RSA; | |
2952 SSLConfig client_config; | |
2953 client_config.next_protos.clear(); | |
2954 ASSERT_NO_FATAL_FAILURE( | |
2955 TestFalseStart(server_options, client_config, false)); | |
2956 } | |
2957 | |
2958 // Test that False Start is disabled without a forward-secret cipher suite. | |
2959 TEST_F(SSLClientSocketFalseStartTest, NoForwardSecrecy) { | |
2960 SpawnedTestServer::SSLOptions server_options; | |
2961 server_options.key_exchanges = | |
2962 SpawnedTestServer::SSLOptions::KEY_EXCHANGE_RSA; | |
2963 server_options.enable_npn = true; | |
2964 SSLConfig client_config; | |
2965 client_config.next_protos.push_back(kProtoHTTP11); | |
2966 ASSERT_NO_FATAL_FAILURE( | |
2967 TestFalseStart(server_options, client_config, false)); | |
2968 } | |
2969 | |
2970 // Test that sessions are resumable after receiving the server Finished message. | |
2971 TEST_F(SSLClientSocketFalseStartTest, SessionResumption) { | |
2972 // Start a server. | |
2973 SpawnedTestServer::SSLOptions server_options; | |
2974 server_options.key_exchanges = | |
2975 SpawnedTestServer::SSLOptions::KEY_EXCHANGE_DHE_RSA; | |
2976 server_options.enable_npn = true; | |
2977 SSLConfig client_config; | |
2978 client_config.next_protos.push_back(kProtoHTTP11); | |
2979 | |
2980 // Let a full handshake complete with False Start. | |
2981 ASSERT_NO_FATAL_FAILURE( | |
2982 TestFalseStart(server_options, client_config, true)); | |
2983 | |
2984 // Make a second connection. | |
2985 TestCompletionCallback callback; | |
2986 scoped_ptr<StreamSocket> transport2( | |
2987 new TCPClientSocket(addr(), &log_, NetLog::Source())); | |
2988 EXPECT_EQ(OK, callback.GetResult(transport2->Connect(callback.callback()))); | |
2989 scoped_ptr<SSLClientSocket> sock2 = CreateSSLClientSocket( | |
2990 transport2.Pass(), test_server()->host_port_pair(), client_config); | |
2991 ASSERT_TRUE(sock2.get()); | |
2992 EXPECT_EQ(OK, callback.GetResult(sock2->Connect(callback.callback()))); | |
2993 | |
2994 // It should resume the session. | |
2995 SSLInfo ssl_info; | |
2996 EXPECT_TRUE(sock2->GetSSLInfo(&ssl_info)); | |
2997 EXPECT_EQ(SSLInfo::HANDSHAKE_RESUME, ssl_info.handshake_type); | |
2998 } | |
2999 | |
3000 // Test that sessions are not resumable before receiving the server Finished | |
3001 // message. | |
3002 TEST_F(SSLClientSocketFalseStartTest, NoSessionResumptionBeforeFinish) { | |
3003 // Start a server. | |
3004 SpawnedTestServer::SSLOptions server_options; | |
3005 server_options.key_exchanges = | |
3006 SpawnedTestServer::SSLOptions::KEY_EXCHANGE_DHE_RSA; | |
3007 server_options.enable_npn = true; | |
3008 ASSERT_TRUE(StartTestServer(server_options)); | |
3009 | |
3010 SSLConfig client_config; | |
3011 client_config.next_protos.push_back(kProtoHTTP11); | |
3012 | |
3013 // Start a handshake up to the server Finished message. | |
3014 TestCompletionCallback callback; | |
3015 FakeBlockingStreamSocket* raw_transport1; | |
3016 scoped_ptr<SSLClientSocket> sock1; | |
3017 ASSERT_NO_FATAL_FAILURE(CreateAndConnectUntilServerFinishedReceived( | |
3018 client_config, &callback, &raw_transport1, &sock1)); | |
3019 // Although raw_transport1 has the server Finished blocked, the handshake | |
3020 // still completes. | |
3021 EXPECT_EQ(OK, callback.WaitForResult()); | |
3022 | |
3023 // Drop the old socket. This is needed because the Python test server can't | |
3024 // service two sockets in parallel. | |
3025 sock1.reset(); | |
3026 | |
3027 // Start a second connection. | |
3028 scoped_ptr<StreamSocket> transport2( | |
3029 new TCPClientSocket(addr(), &log_, NetLog::Source())); | |
3030 EXPECT_EQ(OK, callback.GetResult(transport2->Connect(callback.callback()))); | |
3031 scoped_ptr<SSLClientSocket> sock2 = CreateSSLClientSocket( | |
3032 transport2.Pass(), test_server()->host_port_pair(), client_config); | |
3033 EXPECT_EQ(OK, callback.GetResult(sock2->Connect(callback.callback()))); | |
3034 | |
3035 // No session resumption because the first connection never received a server | |
3036 // Finished message. | |
3037 SSLInfo ssl_info; | |
3038 EXPECT_TRUE(sock2->GetSSLInfo(&ssl_info)); | |
3039 EXPECT_EQ(SSLInfo::HANDSHAKE_FULL, ssl_info.handshake_type); | |
3040 } | |
3041 | |
3042 // Connect to a server using channel id. It should allow the connection. | |
3043 TEST_F(SSLClientSocketChannelIDTest, SendChannelID) { | |
3044 SpawnedTestServer::SSLOptions ssl_options; | |
3045 | |
3046 ASSERT_TRUE(ConnectToTestServer(ssl_options)); | |
3047 | |
3048 EnableChannelID(); | |
3049 SSLConfig ssl_config; | |
3050 ssl_config.channel_id_enabled = true; | |
3051 | |
3052 int rv; | |
3053 ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv)); | |
3054 | |
3055 EXPECT_EQ(OK, rv); | |
3056 EXPECT_TRUE(sock_->IsConnected()); | |
3057 EXPECT_TRUE(sock_->WasChannelIDSent()); | |
3058 | |
3059 sock_->Disconnect(); | |
3060 EXPECT_FALSE(sock_->IsConnected()); | |
3061 } | |
3062 | |
3063 // Connect to a server using Channel ID but failing to look up the Channel | |
3064 // ID. It should fail. | |
3065 TEST_F(SSLClientSocketChannelIDTest, FailingChannelID) { | |
3066 SpawnedTestServer::SSLOptions ssl_options; | |
3067 | |
3068 ASSERT_TRUE(ConnectToTestServer(ssl_options)); | |
3069 | |
3070 EnableFailingChannelID(); | |
3071 SSLConfig ssl_config; | |
3072 ssl_config.channel_id_enabled = true; | |
3073 | |
3074 int rv; | |
3075 ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv)); | |
3076 | |
3077 // TODO(haavardm@opera.com): Due to differences in threading, Linux returns | |
3078 // ERR_UNEXPECTED while Mac and Windows return ERR_PROTOCOL_ERROR. Accept all | |
3079 // error codes for now. | |
3080 // http://crbug.com/373670 | |
3081 EXPECT_NE(OK, rv); | |
3082 EXPECT_FALSE(sock_->IsConnected()); | |
3083 } | |
3084 | |
3085 // Connect to a server using Channel ID but asynchronously failing to look up | |
3086 // the Channel ID. It should fail. | |
3087 TEST_F(SSLClientSocketChannelIDTest, FailingChannelIDAsync) { | |
3088 SpawnedTestServer::SSLOptions ssl_options; | |
3089 | |
3090 ASSERT_TRUE(ConnectToTestServer(ssl_options)); | |
3091 | |
3092 EnableAsyncFailingChannelID(); | |
3093 SSLConfig ssl_config; | |
3094 ssl_config.channel_id_enabled = true; | |
3095 | |
3096 int rv; | |
3097 ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv)); | |
3098 | |
3099 EXPECT_EQ(ERR_UNEXPECTED, rv); | |
3100 EXPECT_FALSE(sock_->IsConnected()); | |
3101 } | |
3102 | |
3103 } // namespace net | |
OLD | NEW |