OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/socket/ssl_client_socket_win.h" | 5 #include "net/socket/ssl_client_socket_win.h" |
6 | 6 |
7 #include <schnlsp.h> | 7 #include <schnlsp.h> |
8 | 8 |
9 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
10 #include "base/lock.h" | 10 #include "base/lock.h" |
11 #include "base/singleton.h" | 11 #include "base/singleton.h" |
12 #include "base/stl_util-inl.h" | 12 #include "base/stl_util-inl.h" |
13 #include "base/string_util.h" | 13 #include "base/string_util.h" |
14 #include "net/base/cert_verifier.h" | 14 #include "net/base/cert_verifier.h" |
15 #include "net/base/connection_type_histograms.h" | 15 #include "net/base/connection_type_histograms.h" |
16 #include "net/base/io_buffer.h" | 16 #include "net/base/io_buffer.h" |
17 #include "net/base/net_log.h" | 17 #include "net/base/net_log.h" |
18 #include "net/base/net_errors.h" | 18 #include "net/base/net_errors.h" |
19 #include "net/base/ssl_cert_request_info.h" | 19 #include "net/base/ssl_cert_request_info.h" |
20 #include "net/base/ssl_info.h" | 20 #include "net/base/ssl_info.h" |
| 21 #include "net/socket/client_socket_handle.h" |
21 | 22 |
22 #pragma comment(lib, "secur32.lib") | 23 #pragma comment(lib, "secur32.lib") |
23 | 24 |
24 namespace net { | 25 namespace net { |
25 | 26 |
26 //----------------------------------------------------------------------------- | 27 //----------------------------------------------------------------------------- |
27 | 28 |
28 // TODO(wtc): See http://msdn.microsoft.com/en-us/library/aa377188(VS.85).aspx | 29 // TODO(wtc): See http://msdn.microsoft.com/en-us/library/aa377188(VS.85).aspx |
29 // for the other error codes we may need to map. | 30 // for the other error codes we may need to map. |
30 static int MapSecurityError(SECURITY_STATUS err) { | 31 static int MapSecurityError(SECURITY_STATUS err) { |
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
285 // Size of recv_buffer_ | 286 // Size of recv_buffer_ |
286 // | 287 // |
287 // Ciphertext is decrypted one SSL record at a time, so recv_buffer_ needs to | 288 // Ciphertext is decrypted one SSL record at a time, so recv_buffer_ needs to |
288 // have room for a full SSL record, with the header and trailer. Here is the | 289 // have room for a full SSL record, with the header and trailer. Here is the |
289 // breakdown of the size: | 290 // breakdown of the size: |
290 // 5: SSL record header | 291 // 5: SSL record header |
291 // 16K: SSL record maximum size | 292 // 16K: SSL record maximum size |
292 // 64: >= SSL record trailer (16 or 20 have been observed) | 293 // 64: >= SSL record trailer (16 or 20 have been observed) |
293 static const int kRecvBufferSize = (5 + 16*1024 + 64); | 294 static const int kRecvBufferSize = (5 + 16*1024 + 64); |
294 | 295 |
295 SSLClientSocketWin::SSLClientSocketWin(ClientSocket* transport_socket, | 296 SSLClientSocketWin::SSLClientSocketWin(ClientSocketHandle* transport_socket, |
296 const std::string& hostname, | 297 const std::string& hostname, |
297 const SSLConfig& ssl_config) | 298 const SSLConfig& ssl_config) |
298 : ALLOW_THIS_IN_INITIALIZER_LIST( | 299 : ALLOW_THIS_IN_INITIALIZER_LIST( |
299 handshake_io_callback_(this, | 300 handshake_io_callback_(this, |
300 &SSLClientSocketWin::OnHandshakeIOComplete)), | 301 &SSLClientSocketWin::OnHandshakeIOComplete)), |
301 ALLOW_THIS_IN_INITIALIZER_LIST( | 302 ALLOW_THIS_IN_INITIALIZER_LIST( |
302 read_callback_(this, &SSLClientSocketWin::OnReadComplete)), | 303 read_callback_(this, &SSLClientSocketWin::OnReadComplete)), |
303 ALLOW_THIS_IN_INITIALIZER_LIST( | 304 ALLOW_THIS_IN_INITIALIZER_LIST( |
304 write_callback_(this, &SSLClientSocketWin::OnWriteComplete)), | 305 write_callback_(this, &SSLClientSocketWin::OnWriteComplete)), |
305 transport_(transport_socket), | 306 transport_(transport_socket), |
(...skipping 10 matching lines...) Expand all Loading... |
316 payload_send_buffer_len_(0), | 317 payload_send_buffer_len_(0), |
317 bytes_sent_(0), | 318 bytes_sent_(0), |
318 decrypted_ptr_(NULL), | 319 decrypted_ptr_(NULL), |
319 bytes_decrypted_(0), | 320 bytes_decrypted_(0), |
320 received_ptr_(NULL), | 321 received_ptr_(NULL), |
321 bytes_received_(0), | 322 bytes_received_(0), |
322 writing_first_token_(false), | 323 writing_first_token_(false), |
323 ignore_ok_result_(false), | 324 ignore_ok_result_(false), |
324 renegotiating_(false), | 325 renegotiating_(false), |
325 need_more_data_(false), | 326 need_more_data_(false), |
326 net_log_(transport_socket->NetLog()) { | 327 net_log_(transport_socket->socket()->NetLog()) { |
327 memset(&stream_sizes_, 0, sizeof(stream_sizes_)); | 328 memset(&stream_sizes_, 0, sizeof(stream_sizes_)); |
328 memset(in_buffers_, 0, sizeof(in_buffers_)); | 329 memset(in_buffers_, 0, sizeof(in_buffers_)); |
329 memset(&send_buffer_, 0, sizeof(send_buffer_)); | 330 memset(&send_buffer_, 0, sizeof(send_buffer_)); |
330 memset(&ctxt_, 0, sizeof(ctxt_)); | 331 memset(&ctxt_, 0, sizeof(ctxt_)); |
331 } | 332 } |
332 | 333 |
333 SSLClientSocketWin::~SSLClientSocketWin() { | 334 SSLClientSocketWin::~SSLClientSocketWin() { |
334 Disconnect(); | 335 Disconnect(); |
335 } | 336 } |
336 | 337 |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
516 return OK; | 517 return OK; |
517 } | 518 } |
518 | 519 |
519 | 520 |
520 void SSLClientSocketWin::Disconnect() { | 521 void SSLClientSocketWin::Disconnect() { |
521 // TODO(wtc): Send SSL close_notify alert. | 522 // TODO(wtc): Send SSL close_notify alert. |
522 next_state_ = STATE_NONE; | 523 next_state_ = STATE_NONE; |
523 | 524 |
524 // Shut down anything that may call us back. | 525 // Shut down anything that may call us back. |
525 verifier_.reset(); | 526 verifier_.reset(); |
526 transport_->Disconnect(); | 527 transport_->socket()->Disconnect(); |
527 | 528 |
528 if (send_buffer_.pvBuffer) | 529 if (send_buffer_.pvBuffer) |
529 FreeSendBuffer(); | 530 FreeSendBuffer(); |
530 if (ctxt_.dwLower || ctxt_.dwUpper) { | 531 if (ctxt_.dwLower || ctxt_.dwUpper) { |
531 DeleteSecurityContext(&ctxt_); | 532 DeleteSecurityContext(&ctxt_); |
532 memset(&ctxt_, 0, sizeof(ctxt_)); | 533 memset(&ctxt_, 0, sizeof(ctxt_)); |
533 } | 534 } |
534 if (server_cert_) | 535 if (server_cert_) |
535 server_cert_ = NULL; | 536 server_cert_ = NULL; |
536 | 537 |
537 // TODO(wtc): reset more members? | 538 // TODO(wtc): reset more members? |
538 bytes_decrypted_ = 0; | 539 bytes_decrypted_ = 0; |
539 bytes_received_ = 0; | 540 bytes_received_ = 0; |
540 writing_first_token_ = false; | 541 writing_first_token_ = false; |
541 renegotiating_ = false; | 542 renegotiating_ = false; |
542 need_more_data_ = false; | 543 need_more_data_ = false; |
543 } | 544 } |
544 | 545 |
545 bool SSLClientSocketWin::IsConnected() const { | 546 bool SSLClientSocketWin::IsConnected() const { |
546 // Ideally, we should also check if we have received the close_notify alert | 547 // Ideally, we should also check if we have received the close_notify alert |
547 // message from the server, and return false in that case. We're not doing | 548 // message from the server, and return false in that case. We're not doing |
548 // that, so this function may return a false positive. Since the upper | 549 // that, so this function may return a false positive. Since the upper |
549 // layer (HttpNetworkTransaction) needs to handle a persistent connection | 550 // layer (HttpNetworkTransaction) needs to handle a persistent connection |
550 // closed by the server when we send a request anyway, a false positive in | 551 // closed by the server when we send a request anyway, a false positive in |
551 // exchange for simpler code is a good trade-off. | 552 // exchange for simpler code is a good trade-off. |
552 return completed_handshake() && transport_->IsConnected(); | 553 return completed_handshake() && transport_->socket()->IsConnected(); |
553 } | 554 } |
554 | 555 |
555 bool SSLClientSocketWin::IsConnectedAndIdle() const { | 556 bool SSLClientSocketWin::IsConnectedAndIdle() const { |
556 // Unlike IsConnected, this method doesn't return a false positive. | 557 // Unlike IsConnected, this method doesn't return a false positive. |
557 // | 558 // |
558 // Strictly speaking, we should check if we have received the close_notify | 559 // Strictly speaking, we should check if we have received the close_notify |
559 // alert message from the server, and return false in that case. Although | 560 // alert message from the server, and return false in that case. Although |
560 // the close_notify alert message means EOF in the SSL layer, it is just | 561 // the close_notify alert message means EOF in the SSL layer, it is just |
561 // bytes to the transport layer below, so transport_->IsConnectedAndIdle() | 562 // bytes to the transport layer below, so |
562 // returns the desired false when we receive close_notify. | 563 // transport_->socket()->IsConnectedAndIdle() returns the desired false |
563 return completed_handshake() && transport_->IsConnectedAndIdle(); | 564 // when we receive close_notify. |
| 565 return completed_handshake() && transport_->socket()->IsConnectedAndIdle(); |
564 } | 566 } |
565 | 567 |
566 int SSLClientSocketWin::GetPeerAddress(AddressList* address) const { | 568 int SSLClientSocketWin::GetPeerAddress(AddressList* address) const { |
567 return transport_->GetPeerAddress(address); | 569 return transport_->socket()->GetPeerAddress(address); |
568 } | 570 } |
569 | 571 |
570 int SSLClientSocketWin::Read(IOBuffer* buf, int buf_len, | 572 int SSLClientSocketWin::Read(IOBuffer* buf, int buf_len, |
571 CompletionCallback* callback) { | 573 CompletionCallback* callback) { |
572 DCHECK(completed_handshake()); | 574 DCHECK(completed_handshake()); |
573 DCHECK(!user_read_callback_); | 575 DCHECK(!user_read_callback_); |
574 | 576 |
575 // If we have surplus decrypted plaintext, satisfy the Read with it without | 577 // If we have surplus decrypted plaintext, satisfy the Read with it without |
576 // reading more ciphertext from the transport socket. | 578 // reading more ciphertext from the transport socket. |
577 if (bytes_decrypted_ != 0) { | 579 if (bytes_decrypted_ != 0) { |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
624 if (rv == ERR_IO_PENDING) { | 626 if (rv == ERR_IO_PENDING) { |
625 user_write_callback_ = callback; | 627 user_write_callback_ = callback; |
626 } else { | 628 } else { |
627 user_write_buf_ = NULL; | 629 user_write_buf_ = NULL; |
628 user_write_buf_len_ = 0; | 630 user_write_buf_len_ = 0; |
629 } | 631 } |
630 return rv; | 632 return rv; |
631 } | 633 } |
632 | 634 |
633 bool SSLClientSocketWin::SetReceiveBufferSize(int32 size) { | 635 bool SSLClientSocketWin::SetReceiveBufferSize(int32 size) { |
634 return transport_->SetReceiveBufferSize(size); | 636 return transport_->socket()->SetReceiveBufferSize(size); |
635 } | 637 } |
636 | 638 |
637 bool SSLClientSocketWin::SetSendBufferSize(int32 size) { | 639 bool SSLClientSocketWin::SetSendBufferSize(int32 size) { |
638 return transport_->SetSendBufferSize(size); | 640 return transport_->socket()->SetSendBufferSize(size); |
639 } | 641 } |
640 | 642 |
641 void SSLClientSocketWin::OnHandshakeIOComplete(int result) { | 643 void SSLClientSocketWin::OnHandshakeIOComplete(int result) { |
642 int rv = DoLoop(result); | 644 int rv = DoLoop(result); |
643 | 645 |
644 // The SSL handshake has some round trips. We need to notify the caller of | 646 // The SSL handshake has some round trips. We need to notify the caller of |
645 // success or any error, other than waiting for IO. | 647 // success or any error, other than waiting for IO. |
646 if (rv != ERR_IO_PENDING) { | 648 if (rv != ERR_IO_PENDING) { |
647 // If there is no connect callback available to call, we are renegotiating | 649 // If there is no connect callback available to call, we are renegotiating |
648 // (which occurs because we are in the middle of a Read when the | 650 // (which occurs because we are in the middle of a Read when the |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
743 int buf_len = kRecvBufferSize - bytes_received_; | 745 int buf_len = kRecvBufferSize - bytes_received_; |
744 | 746 |
745 if (buf_len <= 0) { | 747 if (buf_len <= 0) { |
746 NOTREACHED() << "Receive buffer is too small!"; | 748 NOTREACHED() << "Receive buffer is too small!"; |
747 return ERR_UNEXPECTED; | 749 return ERR_UNEXPECTED; |
748 } | 750 } |
749 | 751 |
750 DCHECK(!transport_read_buf_); | 752 DCHECK(!transport_read_buf_); |
751 transport_read_buf_ = new IOBuffer(buf_len); | 753 transport_read_buf_ = new IOBuffer(buf_len); |
752 | 754 |
753 return transport_->Read(transport_read_buf_, buf_len, | 755 return transport_->socket()->Read(transport_read_buf_, buf_len, |
754 &handshake_io_callback_); | 756 &handshake_io_callback_); |
755 } | 757 } |
756 | 758 |
757 int SSLClientSocketWin::DoHandshakeReadComplete(int result) { | 759 int SSLClientSocketWin::DoHandshakeReadComplete(int result) { |
758 if (result < 0) { | 760 if (result < 0) { |
759 transport_read_buf_ = NULL; | 761 transport_read_buf_ = NULL; |
760 return result; | 762 return result; |
761 } | 763 } |
762 | 764 |
763 if (transport_read_buf_) { | 765 if (transport_read_buf_) { |
764 // A transition to STATE_HANDSHAKE_READ_COMPLETE is set in multiple places, | 766 // A transition to STATE_HANDSHAKE_READ_COMPLETE is set in multiple places, |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
910 // We should have something to send. | 912 // We should have something to send. |
911 DCHECK(send_buffer_.pvBuffer); | 913 DCHECK(send_buffer_.pvBuffer); |
912 DCHECK(send_buffer_.cbBuffer > 0); | 914 DCHECK(send_buffer_.cbBuffer > 0); |
913 DCHECK(!transport_write_buf_); | 915 DCHECK(!transport_write_buf_); |
914 | 916 |
915 const char* buf = static_cast<char*>(send_buffer_.pvBuffer) + bytes_sent_; | 917 const char* buf = static_cast<char*>(send_buffer_.pvBuffer) + bytes_sent_; |
916 int buf_len = send_buffer_.cbBuffer - bytes_sent_; | 918 int buf_len = send_buffer_.cbBuffer - bytes_sent_; |
917 transport_write_buf_ = new IOBuffer(buf_len); | 919 transport_write_buf_ = new IOBuffer(buf_len); |
918 memcpy(transport_write_buf_->data(), buf, buf_len); | 920 memcpy(transport_write_buf_->data(), buf, buf_len); |
919 | 921 |
920 return transport_->Write(transport_write_buf_, buf_len, | 922 return transport_->socket()->Write(transport_write_buf_, buf_len, |
921 &handshake_io_callback_); | 923 &handshake_io_callback_); |
922 } | 924 } |
923 | 925 |
924 int SSLClientSocketWin::DoHandshakeWriteComplete(int result) { | 926 int SSLClientSocketWin::DoHandshakeWriteComplete(int result) { |
925 DCHECK(transport_write_buf_); | 927 DCHECK(transport_write_buf_); |
926 transport_write_buf_ = NULL; | 928 transport_write_buf_ = NULL; |
927 if (result < 0) | 929 if (result < 0) |
928 return result; | 930 return result; |
929 | 931 |
930 DCHECK(result != 0); | 932 DCHECK(result != 0); |
931 | 933 |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1005 return ERR_FAILED; | 1007 return ERR_FAILED; |
1006 } | 1008 } |
1007 | 1009 |
1008 int rv; | 1010 int rv; |
1009 // If bytes_received_, we have some data from a previous read still ready | 1011 // If bytes_received_, we have some data from a previous read still ready |
1010 // for decoding. Otherwise, we need to issue a real read. | 1012 // for decoding. Otherwise, we need to issue a real read. |
1011 if (!bytes_received_ || need_more_data_) { | 1013 if (!bytes_received_ || need_more_data_) { |
1012 DCHECK(!transport_read_buf_); | 1014 DCHECK(!transport_read_buf_); |
1013 transport_read_buf_ = new IOBuffer(buf_len); | 1015 transport_read_buf_ = new IOBuffer(buf_len); |
1014 | 1016 |
1015 rv = transport_->Read(transport_read_buf_, buf_len, &read_callback_); | 1017 rv = transport_->socket()->Read(transport_read_buf_, buf_len, |
| 1018 &read_callback_); |
1016 if (rv != ERR_IO_PENDING) | 1019 if (rv != ERR_IO_PENDING) |
1017 rv = DoPayloadReadComplete(rv); | 1020 rv = DoPayloadReadComplete(rv); |
1018 if (rv <= 0) | 1021 if (rv <= 0) |
1019 return rv; | 1022 return rv; |
1020 } | 1023 } |
1021 | 1024 |
1022 // Decode what we've read. If there is not enough data to decode yet, | 1025 // Decode what we've read. If there is not enough data to decode yet, |
1023 // this may return ERR_IO_PENDING still. | 1026 // this may return ERR_IO_PENDING still. |
1024 return DoPayloadDecrypt(); | 1027 return DoPayloadDecrypt(); |
1025 } | 1028 } |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1240 // We should have something to send. | 1243 // We should have something to send. |
1241 DCHECK(payload_send_buffer_.get()); | 1244 DCHECK(payload_send_buffer_.get()); |
1242 DCHECK(payload_send_buffer_len_ > 0); | 1245 DCHECK(payload_send_buffer_len_ > 0); |
1243 DCHECK(!transport_write_buf_); | 1246 DCHECK(!transport_write_buf_); |
1244 | 1247 |
1245 const char* buf = payload_send_buffer_.get() + bytes_sent_; | 1248 const char* buf = payload_send_buffer_.get() + bytes_sent_; |
1246 int buf_len = payload_send_buffer_len_ - bytes_sent_; | 1249 int buf_len = payload_send_buffer_len_ - bytes_sent_; |
1247 transport_write_buf_ = new IOBuffer(buf_len); | 1250 transport_write_buf_ = new IOBuffer(buf_len); |
1248 memcpy(transport_write_buf_->data(), buf, buf_len); | 1251 memcpy(transport_write_buf_->data(), buf, buf_len); |
1249 | 1252 |
1250 int rv = transport_->Write(transport_write_buf_, buf_len, &write_callback_); | 1253 int rv = transport_->socket()->Write(transport_write_buf_, buf_len, |
| 1254 &write_callback_); |
1251 if (rv != ERR_IO_PENDING) | 1255 if (rv != ERR_IO_PENDING) |
1252 rv = DoPayloadWriteComplete(rv); | 1256 rv = DoPayloadWriteComplete(rv); |
1253 return rv; | 1257 return rv; |
1254 } | 1258 } |
1255 | 1259 |
1256 int SSLClientSocketWin::DoPayloadWriteComplete(int result) { | 1260 int SSLClientSocketWin::DoPayloadWriteComplete(int result) { |
1257 DCHECK(transport_write_buf_); | 1261 DCHECK(transport_write_buf_); |
1258 transport_write_buf_ = NULL; | 1262 transport_write_buf_ = NULL; |
1259 if (result < 0) | 1263 if (result < 0) |
1260 return result; | 1264 return result; |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1343 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD2_CA); | 1347 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD2_CA); |
1344 } | 1348 } |
1345 | 1349 |
1346 void SSLClientSocketWin::FreeSendBuffer() { | 1350 void SSLClientSocketWin::FreeSendBuffer() { |
1347 SECURITY_STATUS status = FreeContextBuffer(send_buffer_.pvBuffer); | 1351 SECURITY_STATUS status = FreeContextBuffer(send_buffer_.pvBuffer); |
1348 DCHECK(status == SEC_E_OK); | 1352 DCHECK(status == SEC_E_OK); |
1349 memset(&send_buffer_, 0, sizeof(send_buffer_)); | 1353 memset(&send_buffer_, 0, sizeof(send_buffer_)); |
1350 } | 1354 } |
1351 | 1355 |
1352 } // namespace net | 1356 } // namespace net |
OLD | NEW |