| 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 | 
|---|