Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(316)

Side by Side Diff: net/socket/ssl_client_socket_mac.cc

Issue 2870030: Implement SSLClientSocketPool. (Closed)
Patch Set: Rebase and fix mac compile error Created 10 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698