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

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

Issue 266078: Make SSLClientSocketMac full-duplex (Closed)
Patch Set: cleanup OnTransportWriteComplete Created 11 years, 2 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
« no previous file with comments | « net/socket/ssl_client_socket_mac.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2008-2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2008-2009 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 "base/scoped_cftyperef.h" 7 #include "base/scoped_cftyperef.h"
8 #include "base/singleton.h" 8 #include "base/singleton.h"
9 #include "base/string_util.h" 9 #include "base/string_util.h"
10 #include "net/base/cert_verifier.h" 10 #include "net/base/cert_verifier.h"
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 // we wrote before we would have blocked. But with the asynchronous I/O, the 61 // we wrote before we would have blocked. But with the asynchronous I/O, the
62 // transport underneath us can tell us that it'll let us know sometime "later" 62 // transport underneath us can tell us that it'll let us know sometime "later"
63 // whether or not things succeeded, and how many bytes were written. What do we 63 // whether or not things succeeded, and how many bytes were written. What do we
64 // return to Secure Transport? We can't return a byte count, but we can't return 64 // return to Secure Transport? We can't return a byte count, but we can't return
65 // "later" as we're not guaranteed to be called in the future with the same data 65 // "later" as we're not guaranteed to be called in the future with the same data
66 // to write. 66 // to write.
67 // 67 //
68 // So, like in any good relationship, we're forced to lie. Whenever Secure 68 // So, like in any good relationship, we're forced to lie. Whenever Secure
69 // Transport asks for data to be written, we take it all and lie about it always 69 // Transport asks for data to be written, we take it all and lie about it always
70 // being written. We spin in a loop (see SSLWriteCallback() and 70 // being written. We spin in a loop (see SSLWriteCallback() and
71 // OnWriteComplete()) independent of the main state machine writing the data to 71 // OnTransportWriteComplete()) independent of the main state machine writing
72 // the network, and get the data out. The main consequence of this independence 72 // the data to he network, and get the data out. The main consequence of this
73 // from the state machine is that we require a full-duplex transport underneath 73 // independence from the state machine is that we require a full-duplex
74 // us since we can't use it to keep our reading and writing 74 // transport underneath us since we can't use it to keep our reading and
75 // straight. Fortunately, the NSS implementation also has this issue to deal 75 // writing straight. Fortunately, the NSS implementation also has this issue
76 // with, so we share the same Libevent-based full-duplex TCP socket. 76 // to deal with, so we share the same Libevent-based full-duplex TCP socket.
77 // 77 //
78 // A side comment on return values might be in order. Those who haven't taken 78 // A side comment on return values might be in order. Those who haven't taken
79 // the time to read the documentation (ahem, header comments) in our various 79 // the time to read the documentation (ahem, header comments) in our various
80 // files might be a bit surprised to see result values being treated as both 80 // files might be a bit surprised to see result values being treated as both
81 // lengths and errors. Like Shimmer, they are both. In both the case of 81 // lengths and errors. Like Shimmer, they are both. In both the case of
82 // immediate results as well as results returned in callbacks, a negative return 82 // immediate results as well as results returned in callbacks, a negative return
83 // value indicates an error, a zero return value indicates end-of-stream (for 83 // value indicates an error, a zero return value indicates end-of-stream (for
84 // reads), and a positive return value indicates the number of bytes read or 84 // reads), and a positive return value indicates the number of bytes read or
85 // written. Thus, many functions start off with |if (result < 0) return 85 // written. Thus, many functions start off with |if (result < 0) return
86 // result;|. That gets the error condition out of the way, and from that point 86 // result;|. That gets the error condition out of the way, and from that point
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
290 return x509_cert; 290 return x509_cert;
291 } 291 }
292 292
293 } // namespace 293 } // namespace
294 294
295 //----------------------------------------------------------------------------- 295 //-----------------------------------------------------------------------------
296 296
297 SSLClientSocketMac::SSLClientSocketMac(ClientSocket* transport_socket, 297 SSLClientSocketMac::SSLClientSocketMac(ClientSocket* transport_socket,
298 const std::string& hostname, 298 const std::string& hostname,
299 const SSLConfig& ssl_config) 299 const SSLConfig& ssl_config)
300 : io_callback_(this, &SSLClientSocketMac::OnIOComplete), 300 : handshake_io_callback_(this, &SSLClientSocketMac::OnHandshakeIOComplete),
301 write_callback_(this, &SSLClientSocketMac::OnWriteComplete), 301 transport_read_callback_(this,
302 &SSLClientSocketMac::OnTransportReadComplete),
303 transport_write_callback_(this,
304 &SSLClientSocketMac::OnTransportWriteComplete),
302 transport_(transport_socket), 305 transport_(transport_socket),
303 hostname_(hostname), 306 hostname_(hostname),
304 ssl_config_(ssl_config), 307 ssl_config_(ssl_config),
305 user_callback_(NULL), 308 user_connect_callback_(NULL),
306 next_state_(STATE_NONE), 309 user_read_callback_(NULL),
307 next_io_state_(STATE_NONE), 310 user_write_callback_(NULL),
311 user_read_buf_len_(0),
312 user_write_buf_len_(0),
313 next_handshake_state_(STATE_NONE),
308 completed_handshake_(false), 314 completed_handshake_(false),
309 handshake_interrupted_(false), 315 handshake_interrupted_(false),
310 ssl_context_(NULL), 316 ssl_context_(NULL),
311 pending_send_error_(OK), 317 pending_send_error_(OK),
312 recv_buffer_head_slop_(0), 318 recv_buffer_head_slop_(0),
313 recv_buffer_tail_slop_(0) { 319 recv_buffer_tail_slop_(0) {
314 } 320 }
315 321
316 SSLClientSocketMac::~SSLClientSocketMac() { 322 SSLClientSocketMac::~SSLClientSocketMac() {
317 Disconnect(); 323 Disconnect();
318 } 324 }
319 325
320 int SSLClientSocketMac::Connect(CompletionCallback* callback) { 326 int SSLClientSocketMac::Connect(CompletionCallback* callback) {
321 DCHECK(transport_.get()); 327 DCHECK(transport_.get());
322 DCHECK(next_state_ == STATE_NONE); 328 DCHECK(next_handshake_state_ == STATE_NONE);
323 DCHECK(!user_callback_); 329 DCHECK(!user_connect_callback_);
324 330
325 OSStatus status = noErr; 331 OSStatus status = noErr;
326 332
327 status = SSLNewContext(false, &ssl_context_); 333 status = SSLNewContext(false, &ssl_context_);
328 if (status) 334 if (status)
329 return NetErrorFromOSStatus(status); 335 return NetErrorFromOSStatus(status);
330 336
331 status = SSLSetProtocolVersionEnabled(ssl_context_, 337 status = SSLSetProtocolVersionEnabled(ssl_context_,
332 kSSLProtocol2, 338 kSSLProtocol2,
333 ssl_config_.ssl2_enabled); 339 ssl_config_.ssl2_enabled);
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
408 414
409 // SSLSetPeerID() treats peer_id as a binary blob, and makes its 415 // SSLSetPeerID() treats peer_id as a binary blob, and makes its
410 // own copy. 416 // own copy.
411 status = SSLSetPeerID(ssl_context_, &peer_id[0], peer_id.size()); 417 status = SSLSetPeerID(ssl_context_, &peer_id[0], peer_id.size());
412 if (status) 418 if (status)
413 return NetErrorFromOSStatus(status); 419 return NetErrorFromOSStatus(status);
414 } 420 }
415 } 421 }
416 } 422 }
417 423
418 next_state_ = STATE_HANDSHAKE_START; 424 next_handshake_state_ = STATE_HANDSHAKE_START;
419 int rv = DoLoop(OK); 425 int rv = DoHandshakeLoop(OK);
420 if (rv == ERR_IO_PENDING) 426 if (rv == ERR_IO_PENDING)
421 user_callback_ = callback; 427 user_connect_callback_ = callback;
422 return rv; 428 return rv;
423 } 429 }
424 430
425 void SSLClientSocketMac::Disconnect() { 431 void SSLClientSocketMac::Disconnect() {
426 completed_handshake_ = false; 432 completed_handshake_ = false;
427 433
428 if (ssl_context_) { 434 if (ssl_context_) {
429 SSLClose(ssl_context_); 435 SSLClose(ssl_context_);
430 SSLDisposeContext(ssl_context_); 436 SSLDisposeContext(ssl_context_);
431 ssl_context_ = NULL; 437 ssl_context_ = NULL;
(...skipping 21 matching lines...) Expand all
453 // alert message from the server, and return false in that case. Although 459 // alert message from the server, and return false in that case. Although
454 // the close_notify alert message means EOF in the SSL layer, it is just 460 // the close_notify alert message means EOF in the SSL layer, it is just
455 // bytes to the transport layer below, so transport_->IsConnectedAndIdle() 461 // bytes to the transport layer below, so transport_->IsConnectedAndIdle()
456 // returns the desired false when we receive close_notify. 462 // returns the desired false when we receive close_notify.
457 return completed_handshake_ && transport_->IsConnectedAndIdle(); 463 return completed_handshake_ && transport_->IsConnectedAndIdle();
458 } 464 }
459 465
460 int SSLClientSocketMac::Read(IOBuffer* buf, int buf_len, 466 int SSLClientSocketMac::Read(IOBuffer* buf, int buf_len,
461 CompletionCallback* callback) { 467 CompletionCallback* callback) {
462 DCHECK(completed_handshake_); 468 DCHECK(completed_handshake_);
463 DCHECK(next_state_ == STATE_NONE); 469 DCHECK(!user_read_callback_);
464 DCHECK(!user_callback_); 470 DCHECK(!user_read_buf_);
465 DCHECK(!user_buf_);
466 471
467 user_buf_ = buf; 472 user_read_buf_ = buf;
468 user_buf_len_ = buf_len; 473 user_read_buf_len_ = buf_len;
469 474
470 next_state_ = STATE_PAYLOAD_READ; 475 int rv = DoPayloadRead();
471 int rv = DoLoop(OK);
472 if (rv == ERR_IO_PENDING) { 476 if (rv == ERR_IO_PENDING) {
473 user_callback_ = callback; 477 user_read_callback_ = callback;
474 } else { 478 } else {
475 user_buf_ = NULL; 479 user_read_buf_ = NULL;
480 user_read_buf_len_ = 0;
476 } 481 }
477 return rv; 482 return rv;
478 } 483 }
479 484
480 int SSLClientSocketMac::Write(IOBuffer* buf, int buf_len, 485 int SSLClientSocketMac::Write(IOBuffer* buf, int buf_len,
481 CompletionCallback* callback) { 486 CompletionCallback* callback) {
482 DCHECK(completed_handshake_); 487 DCHECK(completed_handshake_);
483 DCHECK(next_state_ == STATE_NONE); 488 DCHECK(!user_write_callback_);
484 DCHECK(!user_callback_); 489 DCHECK(!user_write_buf_);
485 DCHECK(!user_buf_);
486 490
487 user_buf_ = buf; 491 user_write_buf_ = buf;
488 user_buf_len_ = buf_len; 492 user_write_buf_len_ = buf_len;
489 493
490 next_state_ = STATE_PAYLOAD_WRITE; 494 int rv = DoPayloadWrite();
491 int rv = DoLoop(OK);
492 if (rv == ERR_IO_PENDING) { 495 if (rv == ERR_IO_PENDING) {
493 user_callback_ = callback; 496 user_write_callback_ = callback;
494 } else { 497 } else {
495 user_buf_ = NULL; 498 user_write_buf_ = NULL;
499 user_write_buf_len_ = 0;
496 } 500 }
497 return rv; 501 return rv;
498 } 502 }
499 503
500 bool SSLClientSocketMac::SetReceiveBufferSize(int32 size) { 504 bool SSLClientSocketMac::SetReceiveBufferSize(int32 size) {
501 return transport_->SetReceiveBufferSize(size); 505 return transport_->SetReceiveBufferSize(size);
502 } 506 }
503 507
504 bool SSLClientSocketMac::SetSendBufferSize(int32 size) { 508 bool SSLClientSocketMac::SetSendBufferSize(int32 size) {
505 return transport_->SetSendBufferSize(size); 509 return transport_->SetSendBufferSize(size);
(...skipping 15 matching lines...) Expand all
521 OSStatus status = SSLGetNegotiatedCipher(ssl_context_, &suite); 525 OSStatus status = SSLGetNegotiatedCipher(ssl_context_, &suite);
522 if (!status) 526 if (!status)
523 ssl_info->security_bits = KeySizeOfCipherSuite(suite); 527 ssl_info->security_bits = KeySizeOfCipherSuite(suite);
524 } 528 }
525 529
526 void SSLClientSocketMac::GetSSLCertRequestInfo( 530 void SSLClientSocketMac::GetSSLCertRequestInfo(
527 SSLCertRequestInfo* cert_request_info) { 531 SSLCertRequestInfo* cert_request_info) {
528 // TODO(wtc): implement this. 532 // TODO(wtc): implement this.
529 } 533 }
530 534
531 void SSLClientSocketMac::DoCallback(int rv) { 535 void SSLClientSocketMac::DoConnectCallback(int rv) {
532 DCHECK(rv != ERR_IO_PENDING); 536 DCHECK(rv != ERR_IO_PENDING);
533 DCHECK(user_callback_); 537 DCHECK(user_connect_callback_);
538 DCHECK(next_handshake_state_ == STATE_NONE);
534 539
535 // since Run may result in Read being called, clear user_callback_ up front. 540 CompletionCallback* c = user_connect_callback_;
536 CompletionCallback* c = user_callback_; 541 user_connect_callback_ = NULL;
537 user_callback_ = NULL; 542 c->Run(rv > OK ? OK : rv);
538 user_buf_ = NULL; 543 }
544
545 void SSLClientSocketMac::DoReadCallback(int rv) {
546 DCHECK(rv != ERR_IO_PENDING);
547 DCHECK(user_read_callback_);
548
549 // Since Run may result in Read being called, clear user_read_callback_ up
550 // front.
551 CompletionCallback* c = user_read_callback_;
552 user_read_callback_ = NULL;
553 user_read_buf_ = NULL;
554 user_read_buf_len_ = 0;
539 c->Run(rv); 555 c->Run(rv);
540 } 556 }
541 557
542 void SSLClientSocketMac::OnIOComplete(int result) { 558 void SSLClientSocketMac::DoWriteCallback(int rv) {
543 if (next_io_state_ != STATE_NONE) { 559 DCHECK(rv != ERR_IO_PENDING);
544 State next_state = next_state_; 560 DCHECK(user_write_callback_);
545 next_state_ = next_io_state_; 561
546 next_io_state_ = STATE_NONE; 562 // Since Run may result in Write being called, clear user_write_callback_ up
547 result = DoLoop(result); 563 // front.
548 next_state_ = next_state; 564 CompletionCallback* c = user_write_callback_;
565 user_write_callback_ = NULL;
566 user_write_buf_ = NULL;
567 user_write_buf_len_ = 0;
568 c->Run(rv);
569 }
570
571 void SSLClientSocketMac::OnHandshakeIOComplete(int result) {
572 DCHECK(next_handshake_state_ != STATE_NONE);
573 int rv = DoHandshakeLoop(result);
574 if (rv != ERR_IO_PENDING)
575 DoConnectCallback(rv);
576 }
577
578 void SSLClientSocketMac::OnTransportReadComplete(int result) {
579 if (result > 0) {
580 char* buffer =
581 » &recv_buffer_[recv_buffer_.size() - recv_buffer_tail_slop_];
582 memcpy(buffer, read_io_buf_->data(), result);
583 recv_buffer_tail_slop_ -= result;
549 } 584 }
550 if (next_state_ != STATE_NONE) { 585 read_io_buf_ = NULL;
551 int rv = DoLoop(result); 586
587 if (next_handshake_state_ != STATE_NONE) {
588 int rv = DoHandshakeLoop(result);
552 if (rv != ERR_IO_PENDING) 589 if (rv != ERR_IO_PENDING)
553 DoCallback(rv); 590 DoConnectCallback(rv);
591 return;
554 } 592 }
593 if (user_read_buf_) {
594 if (result < 0) {
595 DoReadCallback(result);
596 return;
597 }
598 int rv = DoPayloadRead();
599 if (rv != ERR_IO_PENDING)
600 DoReadCallback(rv);
601 }
602 }
603
604 void SSLClientSocketMac::OnTransportWriteComplete(int result) {
605 if (result < 0) {
606 pending_send_error_ = result;
607 return;
608 }
609 send_buffer_.erase(send_buffer_.begin(),
610 send_buffer_.begin() + result);
611 if (!send_buffer_.empty())
612 SSLWriteCallback(this, NULL, NULL);
613
614 // Since SSLWriteCallback() lies to return noErr even if transport_->Write()
615 // returns ERR_IO_PENDING, we don't need to any callbacks here.
wtc 2009/10/22 22:06:44 Nit: add "call" or "do" after "need to".
555 } 616 }
556 617
557 // This is the main loop driving the state machine. Most calls coming from the 618 // This is the main loop driving the state machine. Most calls coming from the
558 // outside just set up a few variables and jump into here. 619 // outside just set up a few variables and jump into here.
559 int SSLClientSocketMac::DoLoop(int last_io_result) { 620 int SSLClientSocketMac::DoHandshakeLoop(int last_io_result) {
560 DCHECK(next_state_ != STATE_NONE); 621 DCHECK(next_handshake_state_ != STATE_NONE);
561 int rv = last_io_result; 622 int rv = last_io_result;
562 do { 623 do {
563 State state = next_state_; 624 State state = next_handshake_state_;
564 next_state_ = STATE_NONE; 625 next_handshake_state_ = STATE_NONE;
565 switch (state) { 626 switch (state) {
566 case STATE_HANDSHAKE_START: 627 case STATE_HANDSHAKE_START:
567 // Do the SSL/TLS handshake, up to the server certificate message. 628 // Do the SSL/TLS handshake, up to the server certificate message.
568 rv = DoHandshakeStart(); 629 rv = DoHandshakeStart();
569 break; 630 break;
570 case STATE_VERIFY_CERT: 631 case STATE_VERIFY_CERT:
571 // Kick off server certificate validation. 632 // Kick off server certificate validation.
572 rv = DoVerifyCert(); 633 rv = DoVerifyCert();
573 break; 634 break;
574 case STATE_VERIFY_CERT_COMPLETE: 635 case STATE_VERIFY_CERT_COMPLETE:
575 // Check the results of the server certificate validation. 636 // Check the results of the server certificate validation.
576 rv = DoVerifyCertComplete(rv); 637 rv = DoVerifyCertComplete(rv);
577 break; 638 break;
578 case STATE_HANDSHAKE_FINISH: 639 case STATE_HANDSHAKE_FINISH:
579 // Do the SSL/TLS handshake, after the server certificate message. 640 // Do the SSL/TLS handshake, after the server certificate message.
580 rv = DoHandshakeFinish(); 641 rv = DoHandshakeFinish();
581 break; 642 break;
582 case STATE_READ_COMPLETE:
583 // A read off the network is complete; do the paperwork.
584 rv = DoReadComplete(rv);
585 break;
586 case STATE_PAYLOAD_READ:
587 // Do a read of data from the network.
588 rv = DoPayloadRead();
589 break;
590 case STATE_PAYLOAD_WRITE:
591 // Do a write of data to the network.
592 rv = DoPayloadWrite();
593 break;
594 default: 643 default:
595 rv = ERR_UNEXPECTED; 644 rv = ERR_UNEXPECTED;
596 NOTREACHED() << "unexpected state"; 645 NOTREACHED() << "unexpected state";
597 break; 646 break;
598 } 647 }
599 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); 648 } while (rv != ERR_IO_PENDING && next_handshake_state_ != STATE_NONE);
600 return rv; 649 return rv;
601 } 650 }
602 651
603 int SSLClientSocketMac::DoHandshakeStart() { 652 int SSLClientSocketMac::DoHandshakeStart() {
604 OSStatus status = SSLHandshake(ssl_context_); 653 OSStatus status = SSLHandshake(ssl_context_);
605
606 if (status == errSSLWouldBlock) 654 if (status == errSSLWouldBlock)
607 next_state_ = STATE_HANDSHAKE_START; 655 next_handshake_state_ = STATE_HANDSHAKE_START;
608 656
609 server_cert_ = GetServerCert(ssl_context_); 657 server_cert_ = GetServerCert(ssl_context_);
610 658
611 if (status == noErr || status == errSSLServerAuthCompletedFlag) { 659 if (status == noErr || status == errSSLServerAuthCompletedFlag) {
612 if (!server_cert_) 660 if (!server_cert_)
613 return ERR_UNEXPECTED; 661 return ERR_UNEXPECTED;
614 662
615 // TODO(hawk): we verify the certificate chain even on resumed sessions 663 // TODO(hawk): we verify the certificate chain even on resumed sessions
616 // so that we have the certificate status (valid, expired but overridden 664 // so that we have the certificate status (valid, expired but overridden
617 // by the user, EV, etc.) available. Eliminate this step once we have 665 // by the user, EV, etc.) available. Eliminate this step once we have
618 // a certificate validation result cache. 666 // a certificate validation result cache.
619 next_state_ = STATE_VERIFY_CERT; 667 next_handshake_state_ = STATE_VERIFY_CERT;
620 if (status == errSSLServerAuthCompletedFlag) { 668 if (status == errSSLServerAuthCompletedFlag) {
621 // Override errSSLServerAuthCompletedFlag as it's not actually an error, 669 // Override errSSLServerAuthCompletedFlag as it's not actually an error,
622 // but rather an indication that we're only half way through the 670 // but rather an indication that we're only half way through the
623 // handshake. 671 // handshake.
624 handshake_interrupted_ = true; 672 handshake_interrupted_ = true;
625 status = noErr; 673 status = noErr;
626 } 674 }
627 } 675 }
628 676
629 return NetErrorFromOSStatus(status); 677 return NetErrorFromOSStatus(status);
630 } 678 }
631 679
632 int SSLClientSocketMac::DoVerifyCert() { 680 int SSLClientSocketMac::DoVerifyCert() {
633 next_state_ = STATE_VERIFY_CERT_COMPLETE; 681 next_handshake_state_ = STATE_VERIFY_CERT_COMPLETE;
634 682
635 if (!server_cert_) 683 if (!server_cert_)
636 return ERR_UNEXPECTED; 684 return ERR_UNEXPECTED;
637 685
638 int flags = 0; 686 int flags = 0;
639 if (ssl_config_.rev_checking_enabled) 687 if (ssl_config_.rev_checking_enabled)
640 flags |= X509Certificate::VERIFY_REV_CHECKING_ENABLED; 688 flags |= X509Certificate::VERIFY_REV_CHECKING_ENABLED;
641 if (ssl_config_.verify_ev_cert) 689 if (ssl_config_.verify_ev_cert)
642 flags |= X509Certificate::VERIFY_EV_CERT; 690 flags |= X509Certificate::VERIFY_EV_CERT;
643 verifier_.reset(new CertVerifier); 691 verifier_.reset(new CertVerifier);
644 return verifier_->Verify(server_cert_, hostname_, flags, 692 return verifier_->Verify(server_cert_, hostname_, flags,
645 &server_cert_verify_result_, &io_callback_); 693 &server_cert_verify_result_,
694 &handshake_io_callback_);
646 } 695 }
647 696
648 int SSLClientSocketMac::DoVerifyCertComplete(int result) { 697 int SSLClientSocketMac::DoVerifyCertComplete(int result) {
649 DCHECK(verifier_.get()); 698 DCHECK(verifier_.get());
650 verifier_.reset(); 699 verifier_.reset();
651 700
652 if (IsCertificateError(result) && ssl_config_.IsAllowedBadCert(server_cert_)) 701 if (IsCertificateError(result) && ssl_config_.IsAllowedBadCert(server_cert_))
653 result = OK; 702 result = OK;
654 703
655 if (handshake_interrupted_) { 704 if (handshake_interrupted_) {
656 // With session resumption enabled the full handshake (i.e., the handshake 705 // With session resumption enabled the full handshake (i.e., the handshake
657 // in a non-resumed session) occurs in two steps. Continue on to the second 706 // in a non-resumed session) occurs in two steps. Continue on to the second
658 // step if the certificate is OK. 707 // step if the certificate is OK.
659 if (result == OK) 708 if (result == OK)
660 next_state_ = STATE_HANDSHAKE_FINISH; 709 next_handshake_state_ = STATE_HANDSHAKE_FINISH;
661 } else { 710 } else {
662 // If the session was resumed or session resumption was disabled, we're 711 // If the session was resumed or session resumption was disabled, we're
663 // done with the handshake. 712 // done with the handshake.
664 completed_handshake_ = true; 713 completed_handshake_ = true;
665 DCHECK(next_state_ == STATE_NONE); 714 DCHECK(next_handshake_state_ == STATE_NONE);
666 } 715 }
667 716
668 return result; 717 return result;
669 } 718 }
670 719
671 int SSLClientSocketMac::DoHandshakeFinish() { 720 int SSLClientSocketMac::DoHandshakeFinish() {
672 OSStatus status = SSLHandshake(ssl_context_); 721 OSStatus status = SSLHandshake(ssl_context_);
673 722
674 if (status == errSSLWouldBlock) 723 if (status == errSSLWouldBlock)
675 next_state_ = STATE_HANDSHAKE_FINISH; 724 next_handshake_state_ = STATE_HANDSHAKE_FINISH;
676 725
677 if (status == noErr) 726 if (status == noErr) {
678 completed_handshake_ = true; 727 completed_handshake_ = true;
728 DCHECK(next_handshake_state_ == STATE_NONE);
729 }
679 730
680 return NetErrorFromOSStatus(status); 731 return NetErrorFromOSStatus(status);
681 } 732 }
682 733
683 int SSLClientSocketMac::DoReadComplete(int result) {
684 if (result < 0) {
685 read_io_buf_ = NULL;
686 return result;
687 }
688
689 char* buffer = &recv_buffer_[recv_buffer_.size() - recv_buffer_tail_slop_];
690 memcpy(buffer, read_io_buf_->data(), result);
691 read_io_buf_ = NULL;
692
693 recv_buffer_tail_slop_ -= result;
694
695 return result;
696 }
697
698 void SSLClientSocketMac::OnWriteComplete(int result) {
699 if (result < 0) {
700 pending_send_error_ = result;
701 return;
702 }
703
704 send_buffer_.erase(send_buffer_.begin(),
705 send_buffer_.begin() + result);
706
707 if (!send_buffer_.empty())
708 SSLWriteCallback(this, NULL, NULL);
709 }
710
711 int SSLClientSocketMac::DoPayloadRead() { 734 int SSLClientSocketMac::DoPayloadRead() {
712 size_t processed = 0; 735 size_t processed = 0;
713 OSStatus status = SSLRead(ssl_context_, 736 OSStatus status = SSLRead(ssl_context_,
714 user_buf_->data(), 737 user_read_buf_->data(),
715 user_buf_len_, 738 user_read_buf_len_,
716 &processed); 739 &processed);
717 740
718 // There's a subtle difference here in semantics of the "would block" errors. 741 // There's a subtle difference here in semantics of the "would block" errors.
719 // In our code, ERR_IO_PENDING means the whole operation is async, while 742 // In our code, ERR_IO_PENDING means the whole operation is async, while
720 // errSSLWouldBlock means that the stream isn't ending (and is often returned 743 // errSSLWouldBlock means that the stream isn't ending (and is often returned
721 // along with partial data). So even though "would block" is returned, if we 744 // along with partial data). So even though "would block" is returned, if we
722 // have data, let's just return it. 745 // have data, let's just return it.
723 746
724 if (processed > 0) 747 if (processed > 0)
725 return processed; 748 return processed;
726 749
727 if (status == errSSLClosedNoNotify) { 750 if (status == errSSLClosedNoNotify) {
728 // TODO(wtc): Unless we have received the close_notify alert, we need to 751 // TODO(wtc): Unless we have received the close_notify alert, we need to
729 // return an error code indicating that the SSL connection ended 752 // return an error code indicating that the SSL connection ended
730 // uncleanly, a potential truncation attack. See http://crbug.com/18586. 753 // uncleanly, a potential truncation attack. See http://crbug.com/18586.
731 return OK; 754 return OK;
732 } 755 }
733 756
734 if (status == errSSLWouldBlock)
735 next_state_ = STATE_PAYLOAD_READ;
736
737 return NetErrorFromOSStatus(status); 757 return NetErrorFromOSStatus(status);
738 } 758 }
739 759
740 int SSLClientSocketMac::DoPayloadWrite() { 760 int SSLClientSocketMac::DoPayloadWrite() {
741 size_t processed = 0; 761 size_t processed = 0;
742 OSStatus status = SSLWrite(ssl_context_, 762 OSStatus status = SSLWrite(ssl_context_,
743 user_buf_->data(), 763 user_write_buf_->data(),
744 user_buf_len_, 764 user_write_buf_len_,
745 &processed); 765 &processed);
746 766
747 if (processed > 0) 767 if (processed > 0)
748 return processed; 768 return processed;
749 769
750 return NetErrorFromOSStatus(status); 770 return NetErrorFromOSStatus(status);
751 } 771 }
752 772
753 // Handling the reading from the network is one of those things that should be 773 // Handling the reading from the network is one of those things that should be
754 // simpler than it is. Ideally, we'd have some kind of ring buffer. For now, a 774 // simpler than it is. Ideally, we'd have some kind of ring buffer. For now, a
(...skipping 21 matching lines...) Expand all
776 // extra space at the end as "tail slop." Slop is just space at the ends of the 796 // extra space at the end as "tail slop." Slop is just space at the ends of the
777 // buffer that's going to be used for data but isn't (yet). A diagram: 797 // buffer that's going to be used for data but isn't (yet). A diagram:
778 // 798 //
779 // +--------------------------------------+--------------------------------+ 799 // +--------------------------------------+--------------------------------+
780 // | existing good data ~~~~~~~~~~~~~~~~~ | tail slop area ~~~~~~~~~~~~~~~ | 800 // | existing good data ~~~~~~~~~~~~~~~~~ | tail slop area ~~~~~~~~~~~~~~~ |
781 // +--------------------------------------+--------------------------------+ 801 // +--------------------------------------+--------------------------------+
782 // 802 //
783 // When executing a read, we pass a pointer to the beginning of the tail slop 803 // When executing a read, we pass a pointer to the beginning of the tail slop
784 // area (guaranteed to be contiguous space because it's a vector, unlike, say, a 804 // area (guaranteed to be contiguous space because it's a vector, unlike, say, a
785 // deque (sigh)) and the size of the tail slop. When we get data (either here in 805 // deque (sigh)) and the size of the tail slop. When we get data (either here in
786 // SSLReadCallback() or above in DoReadComplete()) we subtract the number of 806 // SSLReadCallback() or above in OnTransportReadComplete()) we subtract the
787 // bytes received from the tail slop value. That moves those bytes 807 // number of bytes received from the tail slop value. That moves those bytes
788 // (conceptually, not physically) from the tail slop area to the area containing 808 // (conceptually, not physically) from the tail slop area to the area containing
789 // real data. 809 // real data.
790 // 810 //
791 // The idea is still pretty simple. We enlarge the tail slop, call our 811 // The idea is still pretty simple. We enlarge the tail slop, call our
792 // underlying network, get data, shrink the slop area to match, copy requested 812 // underlying network, get data, shrink the slop area to match, copy requested
793 // data back into our caller's buffer, and delete the data from the head of the 813 // data back into our caller's buffer, and delete the data from the head of the
794 // vector. 814 // vector.
795 // 815 //
796 // Except for a nasty little problem. Asynchronous I/O calls keep the buffer 816 // Except for a nasty little problem. Asynchronous I/O calls keep the buffer
797 // pointer. 817 // pointer.
(...skipping 29 matching lines...) Expand all
827 size_t* data_length) { 847 size_t* data_length) {
828 DCHECK(data); 848 DCHECK(data);
829 DCHECK(data_length); 849 DCHECK(data_length);
830 SSLClientSocketMac* us = 850 SSLClientSocketMac* us =
831 const_cast<SSLClientSocketMac*>( 851 const_cast<SSLClientSocketMac*>(
832 static_cast<const SSLClientSocketMac*>(connection)); 852 static_cast<const SSLClientSocketMac*>(connection));
833 853
834 // If we have I/O in flight, promise we'll get back to them and use the 854 // If we have I/O in flight, promise we'll get back to them and use the
835 // existing callback to do so 855 // existing callback to do so
836 856
837 if (us->next_io_state_ == STATE_READ_COMPLETE) { 857 if (us->read_io_buf_) {
838 *data_length = 0; 858 *data_length = 0;
839 return errSSLWouldBlock; 859 return errSSLWouldBlock;
840 } 860 }
841 861
842 // Start with what's in the buffer 862 // Start with what's in the buffer
843 863
844 size_t total_read = us->recv_buffer_.size() - us->recv_buffer_head_slop_ - 864 size_t total_read = us->recv_buffer_.size() - us->recv_buffer_head_slop_ -
845 us->recv_buffer_tail_slop_; 865 us->recv_buffer_tail_slop_;
846 866
847 // Resize the buffer if needed 867 // Resize the buffer if needed
848 868
849 if (us->recv_buffer_.size() - us->recv_buffer_head_slop_ < *data_length) { 869 if (us->recv_buffer_.size() - us->recv_buffer_head_slop_ < *data_length) {
850 us->recv_buffer_.resize(us->recv_buffer_head_slop_ + *data_length); 870 us->recv_buffer_.resize(us->recv_buffer_head_slop_ + *data_length);
851 us->recv_buffer_tail_slop_ = *data_length - total_read; 871 us->recv_buffer_tail_slop_ = *data_length - total_read;
852 } 872 }
853 873
854 int rv = 1; // any old value to spin the loop below 874 int rv = 1; // any old value to spin the loop below
855 while (rv > 0 && total_read < *data_length) { 875 while (rv > 0 && total_read < *data_length) {
856 char* buffer = &us->recv_buffer_[us->recv_buffer_head_slop_ + total_read]; 876 char* buffer = &us->recv_buffer_[us->recv_buffer_head_slop_ + total_read];
857 us->read_io_buf_ = new IOBuffer(*data_length - total_read); 877 us->read_io_buf_ = new IOBuffer(*data_length - total_read);
858 rv = us->transport_->Read(us->read_io_buf_, 878 rv = us->transport_->Read(us->read_io_buf_,
859 *data_length - total_read, 879 *data_length - total_read,
860 &us->io_callback_); 880 &us->transport_read_callback_);
861 881
862 if (rv >= 0) { 882 if (rv >= 0) {
863 memcpy(buffer, us->read_io_buf_->data(), rv); 883 memcpy(buffer, us->read_io_buf_->data(), rv);
864 us->read_io_buf_ = NULL; 884 us->read_io_buf_ = NULL;
865 total_read += rv; 885 total_read += rv;
866 us->recv_buffer_tail_slop_ -= rv; 886 us->recv_buffer_tail_slop_ -= rv;
867 } 887 }
868 } 888 }
869 889
870 *data_length = total_read; 890 *data_length = total_read;
871 if (total_read) { 891 if (total_read) {
872 memcpy(data, &us->recv_buffer_[us->recv_buffer_head_slop_], total_read); 892 memcpy(data, &us->recv_buffer_[us->recv_buffer_head_slop_], total_read);
873 if (rv == ERR_IO_PENDING) { 893 if (rv == ERR_IO_PENDING) {
874 // We have I/O in flight which is going to land in our buffer. We can't 894 // We have I/O in flight which is going to land in our buffer. We can't
875 // shuffle things around, so we need to just fiddle with pointers. 895 // shuffle things around, so we need to just fiddle with pointers.
876 us->recv_buffer_head_slop_ += total_read; 896 us->recv_buffer_head_slop_ += total_read;
877 } else { 897 } else {
878 us->recv_buffer_.erase(us->recv_buffer_.begin(), 898 us->recv_buffer_.erase(us->recv_buffer_.begin(),
879 us->recv_buffer_.begin() + 899 us->recv_buffer_.begin() +
880 total_read + 900 total_read +
881 us->recv_buffer_head_slop_); 901 us->recv_buffer_head_slop_);
882 us->recv_buffer_head_slop_ = 0; 902 us->recv_buffer_head_slop_ = 0;
883 } 903 }
884 } 904 }
885 905
886 if (rv == ERR_IO_PENDING) { 906 if (rv != ERR_IO_PENDING)
887 us->next_io_state_ = STATE_READ_COMPLETE;
888 } else {
889 us->read_io_buf_ = NULL; 907 us->read_io_buf_ = NULL;
890 }
891 908
892 if (rv < 0) 909 if (rv < 0)
893 return OSStatusFromNetError(rv); 910 return OSStatusFromNetError(rv);
894 else if (rv == 0) // stream closed 911 else if (rv == 0) // stream closed
895 return errSSLClosedGraceful; 912 return errSSLClosedGraceful;
896 else 913 else
897 return noErr; 914 return noErr;
898 } 915 }
899 916
900 // static 917 // static
(...skipping 24 matching lines...) Expand all
925 // sent data. As always, lie to our caller. 942 // sent data. As always, lie to our caller.
926 return noErr; 943 return noErr;
927 } 944 }
928 945
929 int rv; 946 int rv;
930 do { 947 do {
931 scoped_refptr<IOBuffer> buffer = new IOBuffer(us->send_buffer_.size()); 948 scoped_refptr<IOBuffer> buffer = new IOBuffer(us->send_buffer_.size());
932 memcpy(buffer->data(), &us->send_buffer_[0], us->send_buffer_.size()); 949 memcpy(buffer->data(), &us->send_buffer_[0], us->send_buffer_.size());
933 rv = us->transport_->Write(buffer, 950 rv = us->transport_->Write(buffer,
934 us->send_buffer_.size(), 951 us->send_buffer_.size(),
935 &us->write_callback_); 952 &us->transport_write_callback_);
936 if (rv > 0) { 953 if (rv > 0) {
937 us->send_buffer_.erase(us->send_buffer_.begin(), 954 us->send_buffer_.erase(us->send_buffer_.begin(),
938 us->send_buffer_.begin() + rv); 955 us->send_buffer_.begin() + rv);
939 } 956 }
940 } while (rv > 0 && !us->send_buffer_.empty()); 957 } while (rv > 0 && !us->send_buffer_.empty());
941 958
942 if (rv < 0 && rv != ERR_IO_PENDING) { 959 if (rv < 0 && rv != ERR_IO_PENDING) {
943 return OSStatusFromNetError(rv); 960 return OSStatusFromNetError(rv);
944 } 961 }
945 962
946 // always lie to our caller 963 // always lie to our caller
947 return noErr; 964 return noErr;
948 } 965 }
949 966
950 } // namespace net 967 } // namespace net
OLDNEW
« no previous file with comments | « net/socket/ssl_client_socket_mac.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698