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 |