| 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_mac.h" | 5 #include "net/socket/ssl_client_socket_mac.h" |
| 6 | 6 |
| 7 #include <CoreServices/CoreServices.h> | 7 #include <CoreServices/CoreServices.h> |
| 8 #include <netdb.h> | 8 #include <netdb.h> |
| 9 #include <sys/socket.h> | 9 #include <sys/socket.h> |
| 10 #include <sys/types.h> | 10 #include <sys/types.h> |
| 11 | 11 |
| 12 #include "base/scoped_cftyperef.h" | 12 #include "base/scoped_cftyperef.h" |
| 13 #include "base/singleton.h" | 13 #include "base/singleton.h" |
| 14 #include "base/string_util.h" | 14 #include "base/string_util.h" |
| 15 #include "net/base/address_list.h" | 15 #include "net/base/address_list.h" |
| 16 #include "net/base/cert_verifier.h" | 16 #include "net/base/cert_verifier.h" |
| 17 #include "net/base/io_buffer.h" | 17 #include "net/base/io_buffer.h" |
| 18 #include "net/base/net_errors.h" | 18 #include "net/base/net_errors.h" |
| 19 #include "net/base/net_log.h" | 19 #include "net/base/net_log.h" |
| 20 #include "net/base/ssl_cert_request_info.h" | 20 #include "net/base/ssl_cert_request_info.h" |
| 21 #include "net/base/ssl_info.h" | 21 #include "net/base/ssl_info.h" |
| 22 #include "net/socket/client_socket_handle.h" |
| 22 | 23 |
| 23 // Welcome to Mac SSL. We've been waiting for you. | 24 // Welcome to Mac SSL. We've been waiting for you. |
| 24 // | 25 // |
| 25 // The Mac SSL implementation is, like the Windows and NSS implementations, a | 26 // The Mac SSL implementation is, like the Windows and NSS implementations, a |
| 26 // giant state machine. This design constraint is due to the asynchronous nature | 27 // giant state machine. This design constraint is due to the asynchronous nature |
| 27 // of our underlying transport mechanism. We can call down to read/write on the | 28 // of our underlying transport mechanism. We can call down to read/write on the |
| 28 // network, but what happens is that either it completes immediately or returns | 29 // network, but what happens is that either it completes immediately or returns |
| 29 // saying that we'll get a callback sometime in the future. In that case, we | 30 // saying that we'll get a callback sometime in the future. In that case, we |
| 30 // have to return to our caller but pick up where we left off when we | 31 // have to return to our caller but pick up where we left off when we |
| 31 // resume. Thus the fun. | 32 // resume. Thus the fun. |
| (...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 489 for (size_t i = 0; i < num_supported_ciphers; ++i) { | 490 for (size_t i = 0; i < num_supported_ciphers; ++i) { |
| 490 if (ShouldEnableCipherSuite(supported_ciphers[i])) | 491 if (ShouldEnableCipherSuite(supported_ciphers[i])) |
| 491 ciphers_.push_back(supported_ciphers[i]); | 492 ciphers_.push_back(supported_ciphers[i]); |
| 492 } | 493 } |
| 493 } | 494 } |
| 494 | 495 |
| 495 } // namespace | 496 } // namespace |
| 496 | 497 |
| 497 //----------------------------------------------------------------------------- | 498 //----------------------------------------------------------------------------- |
| 498 | 499 |
| 499 SSLClientSocketMac::SSLClientSocketMac(ClientSocket* transport_socket, | 500 SSLClientSocketMac::SSLClientSocketMac(ClientSocketHandle* transport_socket, |
| 500 const std::string& hostname, | 501 const std::string& hostname, |
| 501 const SSLConfig& ssl_config) | 502 const SSLConfig& ssl_config) |
| 502 : handshake_io_callback_(this, &SSLClientSocketMac::OnHandshakeIOComplete), | 503 : handshake_io_callback_(this, &SSLClientSocketMac::OnHandshakeIOComplete), |
| 503 transport_read_callback_(this, | 504 transport_read_callback_(this, |
| 504 &SSLClientSocketMac::OnTransportReadComplete), | 505 &SSLClientSocketMac::OnTransportReadComplete), |
| 505 transport_write_callback_(this, | 506 transport_write_callback_(this, |
| 506 &SSLClientSocketMac::OnTransportWriteComplete), | 507 &SSLClientSocketMac::OnTransportWriteComplete), |
| 507 transport_(transport_socket), | 508 transport_(transport_socket), |
| 508 hostname_(hostname), | 509 hostname_(hostname), |
| 509 ssl_config_(ssl_config), | 510 ssl_config_(ssl_config), |
| 510 user_connect_callback_(NULL), | 511 user_connect_callback_(NULL), |
| 511 user_read_callback_(NULL), | 512 user_read_callback_(NULL), |
| 512 user_write_callback_(NULL), | 513 user_write_callback_(NULL), |
| 513 user_read_buf_len_(0), | 514 user_read_buf_len_(0), |
| 514 user_write_buf_len_(0), | 515 user_write_buf_len_(0), |
| 515 next_handshake_state_(STATE_NONE), | 516 next_handshake_state_(STATE_NONE), |
| 516 completed_handshake_(false), | 517 completed_handshake_(false), |
| 517 handshake_interrupted_(false), | 518 handshake_interrupted_(false), |
| 518 client_cert_requested_(false), | 519 client_cert_requested_(false), |
| 519 ssl_context_(NULL), | 520 ssl_context_(NULL), |
| 520 pending_send_error_(OK), | 521 pending_send_error_(OK), |
| 521 net_log_(transport_socket->NetLog()) { | 522 net_log_(transport_socket->socket()->NetLog()) { |
| 522 } | 523 } |
| 523 | 524 |
| 524 SSLClientSocketMac::~SSLClientSocketMac() { | 525 SSLClientSocketMac::~SSLClientSocketMac() { |
| 525 Disconnect(); | 526 Disconnect(); |
| 526 } | 527 } |
| 527 | 528 |
| 528 int SSLClientSocketMac::Connect(CompletionCallback* callback) { | 529 int SSLClientSocketMac::Connect(CompletionCallback* callback) { |
| 529 DCHECK(transport_.get()); | 530 DCHECK(transport_.get()); |
| 530 DCHECK(next_handshake_state_ == STATE_NONE); | 531 DCHECK(next_handshake_state_ == STATE_NONE); |
| 531 DCHECK(!user_connect_callback_); | 532 DCHECK(!user_connect_callback_); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 553 | 554 |
| 554 if (ssl_context_) { | 555 if (ssl_context_) { |
| 555 SSLClose(ssl_context_); | 556 SSLClose(ssl_context_); |
| 556 SSLDisposeContext(ssl_context_); | 557 SSLDisposeContext(ssl_context_); |
| 557 ssl_context_ = NULL; | 558 ssl_context_ = NULL; |
| 558 SSL_LOG << "----- Disposed SSLContext"; | 559 SSL_LOG << "----- Disposed SSLContext"; |
| 559 } | 560 } |
| 560 | 561 |
| 561 // Shut down anything that may call us back. | 562 // Shut down anything that may call us back. |
| 562 verifier_.reset(); | 563 verifier_.reset(); |
| 563 transport_->Disconnect(); | 564 transport_->socket()->Disconnect(); |
| 564 } | 565 } |
| 565 | 566 |
| 566 bool SSLClientSocketMac::IsConnected() const { | 567 bool SSLClientSocketMac::IsConnected() const { |
| 567 // Ideally, we should also check if we have received the close_notify alert | 568 // Ideally, we should also check if we have received the close_notify alert |
| 568 // message from the server, and return false in that case. We're not doing | 569 // message from the server, and return false in that case. We're not doing |
| 569 // that, so this function may return a false positive. Since the upper | 570 // that, so this function may return a false positive. Since the upper |
| 570 // layer (HttpNetworkTransaction) needs to handle a persistent connection | 571 // layer (HttpNetworkTransaction) needs to handle a persistent connection |
| 571 // closed by the server when we send a request anyway, a false positive in | 572 // closed by the server when we send a request anyway, a false positive in |
| 572 // exchange for simpler code is a good trade-off. | 573 // exchange for simpler code is a good trade-off. |
| 573 return completed_handshake_ && transport_->IsConnected(); | 574 return completed_handshake_ && transport_->socket()->IsConnected(); |
| 574 } | 575 } |
| 575 | 576 |
| 576 bool SSLClientSocketMac::IsConnectedAndIdle() const { | 577 bool SSLClientSocketMac::IsConnectedAndIdle() const { |
| 577 // Unlike IsConnected, this method doesn't return a false positive. | 578 // Unlike IsConnected, this method doesn't return a false positive. |
| 578 // | 579 // |
| 579 // Strictly speaking, we should check if we have received the close_notify | 580 // Strictly speaking, we should check if we have received the close_notify |
| 580 // alert message from the server, and return false in that case. Although | 581 // alert message from the server, and return false in that case. Although |
| 581 // the close_notify alert message means EOF in the SSL layer, it is just | 582 // the close_notify alert message means EOF in the SSL layer, it is just |
| 582 // bytes to the transport layer below, so transport_->IsConnectedAndIdle() | 583 // bytes to the transport layer below, so |
| 583 // returns the desired false when we receive close_notify. | 584 // transport_->socket()->IsConnectedAndIdle() returns the desired false |
| 584 return completed_handshake_ && transport_->IsConnectedAndIdle(); | 585 // when we receive close_notify. |
| 586 return completed_handshake_ && transport_->socket()->IsConnectedAndIdle(); |
| 585 } | 587 } |
| 586 | 588 |
| 587 int SSLClientSocketMac::GetPeerAddress(AddressList* address) const { | 589 int SSLClientSocketMac::GetPeerAddress(AddressList* address) const { |
| 588 return transport_->GetPeerAddress(address); | 590 return transport_->socket()->GetPeerAddress(address); |
| 589 } | 591 } |
| 590 | 592 |
| 591 int SSLClientSocketMac::Read(IOBuffer* buf, int buf_len, | 593 int SSLClientSocketMac::Read(IOBuffer* buf, int buf_len, |
| 592 CompletionCallback* callback) { | 594 CompletionCallback* callback) { |
| 593 DCHECK(completed_handshake_); | 595 DCHECK(completed_handshake_); |
| 594 DCHECK(!user_read_callback_); | 596 DCHECK(!user_read_callback_); |
| 595 DCHECK(!user_read_buf_); | 597 DCHECK(!user_read_buf_); |
| 596 | 598 |
| 597 user_read_buf_ = buf; | 599 user_read_buf_ = buf; |
| 598 user_read_buf_len_ = buf_len; | 600 user_read_buf_len_ = buf_len; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 620 if (rv == ERR_IO_PENDING) { | 622 if (rv == ERR_IO_PENDING) { |
| 621 user_write_callback_ = callback; | 623 user_write_callback_ = callback; |
| 622 } else { | 624 } else { |
| 623 user_write_buf_ = NULL; | 625 user_write_buf_ = NULL; |
| 624 user_write_buf_len_ = 0; | 626 user_write_buf_len_ = 0; |
| 625 } | 627 } |
| 626 return rv; | 628 return rv; |
| 627 } | 629 } |
| 628 | 630 |
| 629 bool SSLClientSocketMac::SetReceiveBufferSize(int32 size) { | 631 bool SSLClientSocketMac::SetReceiveBufferSize(int32 size) { |
| 630 return transport_->SetReceiveBufferSize(size); | 632 return transport_->socket()->SetReceiveBufferSize(size); |
| 631 } | 633 } |
| 632 | 634 |
| 633 bool SSLClientSocketMac::SetSendBufferSize(int32 size) { | 635 bool SSLClientSocketMac::SetSendBufferSize(int32 size) { |
| 634 return transport_->SetSendBufferSize(size); | 636 return transport_->socket()->SetSendBufferSize(size); |
| 635 } | 637 } |
| 636 | 638 |
| 637 void SSLClientSocketMac::GetSSLInfo(SSLInfo* ssl_info) { | 639 void SSLClientSocketMac::GetSSLInfo(SSLInfo* ssl_info) { |
| 638 ssl_info->Reset(); | 640 ssl_info->Reset(); |
| 639 if (!server_cert_) { | 641 if (!server_cert_) { |
| 640 NOTREACHED(); | 642 NOTREACHED(); |
| 641 return; | 643 return; |
| 642 } | 644 } |
| 643 | 645 |
| 644 // set cert | 646 // set cert |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 798 // the session would be cached before we verified the certificate, leaving | 800 // the session would be cached before we verified the certificate, leaving |
| 799 // the potential for a session in which the certificate failed to validate | 801 // the potential for a session in which the certificate failed to validate |
| 800 // to still be able to be resumed. | 802 // to still be able to be resumed. |
| 801 | 803 |
| 802 // Concatenate the hostname and peer address to use as the peer ID. To | 804 // Concatenate the hostname and peer address to use as the peer ID. To |
| 803 // resume a session, we must connect to the same server on the same port | 805 // resume a session, we must connect to the same server on the same port |
| 804 // using the same hostname (i.e., localhost and 127.0.0.1 are considered | 806 // using the same hostname (i.e., localhost and 127.0.0.1 are considered |
| 805 // different peers, which puts us through certificate validation again | 807 // different peers, which puts us through certificate validation again |
| 806 // and catches hostname/certificate name mismatches. | 808 // and catches hostname/certificate name mismatches. |
| 807 AddressList address; | 809 AddressList address; |
| 808 int rv = transport_->GetPeerAddress(&address); | 810 int rv = transport_->socket()->GetPeerAddress(&address); |
| 809 if (rv != OK) | 811 if (rv != OK) |
| 810 return rv; | 812 return rv; |
| 811 const struct addrinfo* ai = address.head(); | 813 const struct addrinfo* ai = address.head(); |
| 812 std::string peer_id(hostname_); | 814 std::string peer_id(hostname_); |
| 813 peer_id += std::string(reinterpret_cast<char*>(ai->ai_addr), | 815 peer_id += std::string(reinterpret_cast<char*>(ai->ai_addr), |
| 814 ai->ai_addrlen); | 816 ai->ai_addrlen); |
| 815 | 817 |
| 816 // SSLSetPeerID() treats peer_id as a binary blob, and makes its | 818 // SSLSetPeerID() treats peer_id as a binary blob, and makes its |
| 817 // own copy. | 819 // own copy. |
| 818 status = SSLSetPeerID(ssl_context_, peer_id.data(), peer_id.length()); | 820 status = SSLSetPeerID(ssl_context_, peer_id.data(), peer_id.length()); |
| (...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1210 // existing callback to do so. | 1212 // existing callback to do so. |
| 1211 *data_length = 0; | 1213 *data_length = 0; |
| 1212 return errSSLWouldBlock; | 1214 return errSSLWouldBlock; |
| 1213 } | 1215 } |
| 1214 | 1216 |
| 1215 size_t total_read = us->recv_buffer_.size(); | 1217 size_t total_read = us->recv_buffer_.size(); |
| 1216 | 1218 |
| 1217 int rv = 1; // any old value to spin the loop below | 1219 int rv = 1; // any old value to spin the loop below |
| 1218 while (rv > 0 && total_read < *data_length) { | 1220 while (rv > 0 && total_read < *data_length) { |
| 1219 us->read_io_buf_ = new IOBuffer(*data_length - total_read); | 1221 us->read_io_buf_ = new IOBuffer(*data_length - total_read); |
| 1220 rv = us->transport_->Read(us->read_io_buf_, | 1222 rv = us->transport_->socket()->Read(us->read_io_buf_, |
| 1221 *data_length - total_read, | 1223 *data_length - total_read, |
| 1222 &us->transport_read_callback_); | 1224 &us->transport_read_callback_); |
| 1223 | 1225 |
| 1224 if (rv >= 0) { | 1226 if (rv >= 0) { |
| 1225 us->recv_buffer_.insert(us->recv_buffer_.end(), | 1227 us->recv_buffer_.insert(us->recv_buffer_.end(), |
| 1226 us->read_io_buf_->data(), | 1228 us->read_io_buf_->data(), |
| 1227 us->read_io_buf_->data() + rv); | 1229 us->read_io_buf_->data() + rv); |
| 1228 us->read_io_buf_ = NULL; | 1230 us->read_io_buf_ = NULL; |
| 1229 total_read += rv; | 1231 total_read += rv; |
| 1230 } | 1232 } |
| 1231 } | 1233 } |
| 1232 | 1234 |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1272 // new data when it sees that data remains in the buffer after removing the | 1274 // new data when it sees that data remains in the buffer after removing the |
| 1273 // sent data. As always, lie to our caller. | 1275 // sent data. As always, lie to our caller. |
| 1274 return noErr; | 1276 return noErr; |
| 1275 } | 1277 } |
| 1276 | 1278 |
| 1277 int rv; | 1279 int rv; |
| 1278 do { | 1280 do { |
| 1279 us->write_io_buf_ = new IOBuffer(us->send_buffer_.size()); | 1281 us->write_io_buf_ = new IOBuffer(us->send_buffer_.size()); |
| 1280 memcpy(us->write_io_buf_->data(), &us->send_buffer_[0], | 1282 memcpy(us->write_io_buf_->data(), &us->send_buffer_[0], |
| 1281 us->send_buffer_.size()); | 1283 us->send_buffer_.size()); |
| 1282 rv = us->transport_->Write(us->write_io_buf_, | 1284 rv = us->transport_->socket()->Write(us->write_io_buf_, |
| 1283 us->send_buffer_.size(), | 1285 us->send_buffer_.size(), |
| 1284 &us->transport_write_callback_); | 1286 &us->transport_write_callback_); |
| 1285 if (rv > 0) { | 1287 if (rv > 0) { |
| 1286 us->send_buffer_.erase(us->send_buffer_.begin(), | 1288 us->send_buffer_.erase(us->send_buffer_.begin(), |
| 1287 us->send_buffer_.begin() + rv); | 1289 us->send_buffer_.begin() + rv); |
| 1288 us->write_io_buf_ = NULL; | 1290 us->write_io_buf_ = NULL; |
| 1289 } | 1291 } |
| 1290 } while (rv > 0 && !us->send_buffer_.empty()); | 1292 } while (rv > 0 && !us->send_buffer_.empty()); |
| 1291 | 1293 |
| 1292 if (rv < 0 && rv != ERR_IO_PENDING) { | 1294 if (rv < 0 && rv != ERR_IO_PENDING) { |
| 1293 us->write_io_buf_ = NULL; | 1295 us->write_io_buf_ = NULL; |
| 1294 return OSStatusFromNetError(rv); | 1296 return OSStatusFromNetError(rv); |
| 1295 } | 1297 } |
| 1296 | 1298 |
| 1297 // always lie to our caller | 1299 // always lie to our caller |
| 1298 return noErr; | 1300 return noErr; |
| 1299 } | 1301 } |
| 1300 | 1302 |
| 1301 } // namespace net | 1303 } // namespace net |
| OLD | NEW |