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

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

Issue 448293002: This CL is a follow up to https://codereview.chromium.org/416683002/. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixed nits Created 6 years, 4 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_openssl.h ('k') | net/socket/ssl_client_socket_unittest.cc » ('j') | 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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 // OpenSSL binding for SSLClientSocket. The class layout and general principle 5 // OpenSSL binding for SSLClientSocket. The class layout and general principle
6 // of operation is derived from SSLClientSocketNSS. 6 // of operation is derived from SSLClientSocketNSS.
7 7
8 #include "net/socket/ssl_client_socket_openssl.h" 8 #include "net/socket/ssl_client_socket_openssl.h"
9 9
10 #include <errno.h> 10 #include <errno.h>
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after
341 const HostPortPair& host_and_port, 341 const HostPortPair& host_and_port,
342 const SSLConfig& ssl_config, 342 const SSLConfig& ssl_config,
343 const SSLClientSocketContext& context) 343 const SSLClientSocketContext& context)
344 : transport_send_busy_(false), 344 : transport_send_busy_(false),
345 transport_recv_busy_(false), 345 transport_recv_busy_(false),
346 weak_factory_(this), 346 weak_factory_(this),
347 pending_read_error_(kNoPendingReadResult), 347 pending_read_error_(kNoPendingReadResult),
348 transport_read_error_(OK), 348 transport_read_error_(OK),
349 transport_write_error_(OK), 349 transport_write_error_(OK),
350 server_cert_chain_(new PeerCertificateChain(NULL)), 350 server_cert_chain_(new PeerCertificateChain(NULL)),
351 completed_handshake_(false), 351 completed_connect_(false),
352 was_ever_used_(false), 352 was_ever_used_(false),
353 client_auth_cert_needed_(false), 353 client_auth_cert_needed_(false),
354 cert_verifier_(context.cert_verifier), 354 cert_verifier_(context.cert_verifier),
355 channel_id_service_(context.channel_id_service), 355 channel_id_service_(context.channel_id_service),
356 ssl_(NULL), 356 ssl_(NULL),
357 transport_bio_(NULL), 357 transport_bio_(NULL),
358 transport_(transport_socket.Pass()), 358 transport_(transport_socket.Pass()),
359 host_and_port_(host_and_port), 359 host_and_port_(host_and_port),
360 ssl_config_(ssl_config), 360 ssl_config_(ssl_config),
361 ssl_session_cache_shard_(context.ssl_session_cache_shard), 361 ssl_session_cache_shard_(context.ssl_session_cache_shard),
362 trying_cached_session_(false), 362 trying_cached_session_(false),
363 next_handshake_state_(STATE_NONE), 363 next_handshake_state_(STATE_NONE),
364 npn_status_(kNextProtoUnsupported), 364 npn_status_(kNextProtoUnsupported),
365 channel_id_xtn_negotiated_(false), 365 channel_id_xtn_negotiated_(false),
366 ran_handshake_finished_callback_(false), 366 handshake_succeeded_(false),
367 marked_session_as_good_(false), 367 marked_session_as_good_(false),
368 net_log_(transport_->socket()->NetLog()) { 368 net_log_(transport_->socket()->NetLog()) {
369 } 369 }
370 370
371 SSLClientSocketOpenSSL::~SSLClientSocketOpenSSL() { 371 SSLClientSocketOpenSSL::~SSLClientSocketOpenSSL() {
372 Disconnect(); 372 Disconnect();
373 } 373 }
374 374
375 bool SSLClientSocketOpenSSL::InSessionCache() const { 375 bool SSLClientSocketOpenSSL::InSessionCache() const {
376 SSLContext* context = SSLContext::GetInstance(); 376 SSLContext* context = SSLContext::GetInstance();
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
486 user_read_buf_ = NULL; 486 user_read_buf_ = NULL;
487 user_read_buf_len_ = 0; 487 user_read_buf_len_ = 0;
488 user_write_buf_ = NULL; 488 user_write_buf_ = NULL;
489 user_write_buf_len_ = 0; 489 user_write_buf_len_ = 0;
490 490
491 pending_read_error_ = kNoPendingReadResult; 491 pending_read_error_ = kNoPendingReadResult;
492 transport_read_error_ = OK; 492 transport_read_error_ = OK;
493 transport_write_error_ = OK; 493 transport_write_error_ = OK;
494 494
495 server_cert_verify_result_.Reset(); 495 server_cert_verify_result_.Reset();
496 completed_handshake_ = false; 496 completed_connect_ = false;
497 497
498 cert_authorities_.clear(); 498 cert_authorities_.clear();
499 cert_key_types_.clear(); 499 cert_key_types_.clear();
500 client_auth_cert_needed_ = false; 500 client_auth_cert_needed_ = false;
501 501
502 npn_status_ = kNextProtoUnsupported; 502 npn_status_ = kNextProtoUnsupported;
503 npn_proto_.clear(); 503 npn_proto_.clear();
504 504
505 channel_id_xtn_negotiated_ = false; 505 channel_id_xtn_negotiated_ = false;
506 channel_id_request_handle_.Cancel(); 506 channel_id_request_handle_.Cancel();
507 } 507 }
508 508
509 bool SSLClientSocketOpenSSL::IsConnected() const { 509 bool SSLClientSocketOpenSSL::IsConnected() const {
510 // If the handshake has not yet completed. 510 // If the handshake has not yet completed.
511 if (!completed_handshake_) 511 if (!completed_connect_)
512 return false; 512 return false;
513 // If an asynchronous operation is still pending. 513 // If an asynchronous operation is still pending.
514 if (user_read_buf_.get() || user_write_buf_.get()) 514 if (user_read_buf_.get() || user_write_buf_.get())
515 return true; 515 return true;
516 516
517 return transport_->socket()->IsConnected(); 517 return transport_->socket()->IsConnected();
518 } 518 }
519 519
520 bool SSLClientSocketOpenSSL::IsConnectedAndIdle() const { 520 bool SSLClientSocketOpenSSL::IsConnectedAndIdle() const {
521 // If the handshake has not yet completed. 521 // If the handshake has not yet completed.
522 if (!completed_handshake_) 522 if (!completed_connect_)
523 return false; 523 return false;
524 // If an asynchronous operation is still pending. 524 // If an asynchronous operation is still pending.
525 if (user_read_buf_.get() || user_write_buf_.get()) 525 if (user_read_buf_.get() || user_write_buf_.get())
526 return false; 526 return false;
527 // If there is data waiting to be sent, or data read from the network that 527 // If there is data waiting to be sent, or data read from the network that
528 // has not yet been consumed. 528 // has not yet been consumed.
529 if (BIO_pending(transport_bio_) > 0 || 529 if (BIO_pending(transport_bio_) > 0 ||
530 BIO_wpending(transport_bio_) > 0) { 530 BIO_wpending(transport_bio_) > 0) {
531 return false; 531 return false;
532 } 532 }
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
672 } 672 }
673 673
674 int SSLClientSocketOpenSSL::SetReceiveBufferSize(int32 size) { 674 int SSLClientSocketOpenSSL::SetReceiveBufferSize(int32 size) {
675 return transport_->socket()->SetReceiveBufferSize(size); 675 return transport_->socket()->SetReceiveBufferSize(size);
676 } 676 }
677 677
678 int SSLClientSocketOpenSSL::SetSendBufferSize(int32 size) { 678 int SSLClientSocketOpenSSL::SetSendBufferSize(int32 size) {
679 return transport_->socket()->SetSendBufferSize(size); 679 return transport_->socket()->SetSendBufferSize(size);
680 } 680 }
681 681
682 // static
683 void SSLClientSocketOpenSSL::InfoCallback(const SSL* ssl,
684 int result,
685 int /*unused*/) {
686 SSLClientSocketOpenSSL* ssl_socket =
687 SSLContext::GetInstance()->GetClientSocketFromSSL(ssl);
688 if (result == SSL_CB_HANDSHAKE_DONE) {
689 ssl_socket->ran_handshake_finished_callback_ = true;
690 ssl_socket->CheckIfHandshakeFinished();
691 }
692 }
693
694 int SSLClientSocketOpenSSL::Init() { 682 int SSLClientSocketOpenSSL::Init() {
695 DCHECK(!ssl_); 683 DCHECK(!ssl_);
696 DCHECK(!transport_bio_); 684 DCHECK(!transport_bio_);
697 685
698 SSLContext* context = SSLContext::GetInstance(); 686 SSLContext* context = SSLContext::GetInstance();
699 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); 687 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
700 688
701 ssl_ = SSL_new(context->ssl_ctx()); 689 ssl_ = SSL_new(context->ssl_ctx());
702 if (!ssl_ || !context->SetClientSocketForSSL(ssl_, this)) 690 if (!ssl_ || !context->SetClientSocketForSSL(ssl_, this))
703 return ERR_UNEXPECTED; 691 return ERR_UNEXPECTED;
704 692
705 if (!SSL_set_tlsext_host_name(ssl_, host_and_port_.host().c_str())) 693 if (!SSL_set_tlsext_host_name(ssl_, host_and_port_.host().c_str()))
706 return ERR_UNEXPECTED; 694 return ERR_UNEXPECTED;
707 695
708 // Set an OpenSSL callback to monitor this SSL*'s connection. 696 // Set an OpenSSL callback to monitor this SSL*'s connection.
709 SSL_set_info_callback(ssl_, &InfoCallback); 697 SSL_set_info_callback(ssl_, &InfoCallback);
710 698
711 trying_cached_session_ = context->session_cache()->SetSSLSessionWithKey( 699 trying_cached_session_ = context->session_cache()->SetSSLSessionWithKey(
712 ssl_, GetSessionCacheKey()); 700 ssl_, GetSessionCacheKey());
713 701
714 BIO* ssl_bio = NULL; 702 BIO* ssl_bio = NULL;
715 // 0 => use default buffer sizes. 703 // 0 => use default buffer sizes.
716 if (!BIO_new_bio_pair(&ssl_bio, 0, &transport_bio_, 0)) 704 if (!BIO_new_bio_pair(&ssl_bio, 0, &transport_bio_, 0))
717 return ERR_UNEXPECTED; 705 return ERR_UNEXPECTED;
718 DCHECK(ssl_bio); 706 DCHECK(ssl_bio);
719 DCHECK(transport_bio_); 707 DCHECK(transport_bio_);
720 708
721 // Install a callback on OpenSSL's end to plumb transport errors through. 709 // Install a callback on OpenSSL's end to plumb transport errors through.
722 BIO_set_callback(ssl_bio, &SSLClientSocketOpenSSL::BIOCallback); 710 BIO_set_callback(ssl_bio, BIOCallback);
723 BIO_set_callback_arg(ssl_bio, reinterpret_cast<char*>(this)); 711 BIO_set_callback_arg(ssl_bio, reinterpret_cast<char*>(this));
724 712
725 SSL_set_bio(ssl_, ssl_bio, ssl_bio); 713 SSL_set_bio(ssl_, ssl_bio, ssl_bio);
726 714
727 // OpenSSL defaults some options to on, others to off. To avoid ambiguity, 715 // OpenSSL defaults some options to on, others to off. To avoid ambiguity,
728 // set everything we care about to an absolute value. 716 // set everything we care about to an absolute value.
729 SslSetClearMask options; 717 SslSetClearMask options;
730 options.ConfigureFlag(SSL_OP_NO_SSLv2, true); 718 options.ConfigureFlag(SSL_OP_NO_SSLv2, true);
731 bool ssl3_enabled = (ssl_config_.version_min == SSL_PROTOCOL_VERSION_SSL3); 719 bool ssl3_enabled = (ssl_config_.version_min == SSL_PROTOCOL_VERSION_SSL3);
732 options.ConfigureFlag(SSL_OP_NO_SSLv3, !ssl3_enabled); 720 options.ConfigureFlag(SSL_OP_NO_SSLv3, !ssl3_enabled);
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after
1039 // TODO(joth): Work out if we need to remember the intermediate CA certs 1027 // TODO(joth): Work out if we need to remember the intermediate CA certs
1040 // when the server sends them to us, and do so here. 1028 // when the server sends them to us, and do so here.
1041 SSLContext::GetInstance()->session_cache()->MarkSSLSessionAsGood(ssl_); 1029 SSLContext::GetInstance()->session_cache()->MarkSSLSessionAsGood(ssl_);
1042 marked_session_as_good_ = true; 1030 marked_session_as_good_ = true;
1043 CheckIfHandshakeFinished(); 1031 CheckIfHandshakeFinished();
1044 } else { 1032 } else {
1045 DVLOG(1) << "DoVerifyCertComplete error " << ErrorToString(result) 1033 DVLOG(1) << "DoVerifyCertComplete error " << ErrorToString(result)
1046 << " (" << result << ")"; 1034 << " (" << result << ")";
1047 } 1035 }
1048 1036
1049 completed_handshake_ = true; 1037 completed_connect_ = true;
1050 // Exit DoHandshakeLoop and return the result to the caller to Connect. 1038 // Exit DoHandshakeLoop and return the result to the caller to Connect.
1051 DCHECK_EQ(STATE_NONE, next_handshake_state_); 1039 DCHECK_EQ(STATE_NONE, next_handshake_state_);
1052 return result; 1040 return result;
1053 } 1041 }
1054 1042
1055 void SSLClientSocketOpenSSL::DoConnectCallback(int rv) { 1043 void SSLClientSocketOpenSSL::DoConnectCallback(int rv) {
1056 if (rv < OK) 1044 if (rv < OK)
1057 OnHandshakeCompletion(); 1045 OnHandshakeCompletion();
1058 if (!user_connect_callback_.is_null()) { 1046 if (!user_connect_callback_.is_null()) {
1059 CompletionCallback c = user_connect_callback_; 1047 CompletionCallback c = user_connect_callback_;
(...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after
1479 *pkey = privkey.release(); 1467 *pkey = privkey.release();
1480 return 1; 1468 return 1;
1481 } 1469 }
1482 #endif // defined(OS_IOS) 1470 #endif // defined(OS_IOS)
1483 1471
1484 // Send no client certificate. 1472 // Send no client certificate.
1485 return 0; 1473 return 0;
1486 } 1474 }
1487 1475
1488 int SSLClientSocketOpenSSL::CertVerifyCallback(X509_STORE_CTX* store_ctx) { 1476 int SSLClientSocketOpenSSL::CertVerifyCallback(X509_STORE_CTX* store_ctx) {
1489 if (!completed_handshake_) { 1477 if (!completed_connect_) {
1490 // If the first handshake hasn't completed then we accept any certificates 1478 // If the first handshake hasn't completed then we accept any certificates
1491 // because we verify after the handshake. 1479 // because we verify after the handshake.
1492 return 1; 1480 return 1;
1493 } 1481 }
1494 1482
1495 CHECK(server_cert_.get()); 1483 CHECK(server_cert_.get());
1496 1484
1497 PeerCertificateChain chain(store_ctx->untrusted); 1485 PeerCertificateChain chain(store_ctx->untrusted);
1498 if (chain.IsValid() && server_cert_->Equals(chain.AsOSChain())) 1486 if (chain.IsValid() && server_cert_->Equals(chain.AsOSChain()))
1499 return 1; 1487 return 1;
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
1579 // write payload. If the current payload fails to write, the error will be 1567 // write payload. If the current payload fails to write, the error will be
1580 // reported in a future write or read to |bio|. 1568 // reported in a future write or read to |bio|.
1581 if (transport_write_error_ != OK) { 1569 if (transport_write_error_ != OK) {
1582 OpenSSLPutNetError(FROM_HERE, transport_write_error_); 1570 OpenSSLPutNetError(FROM_HERE, transport_write_error_);
1583 return -1; 1571 return -1;
1584 } 1572 }
1585 } 1573 }
1586 return retvalue; 1574 return retvalue;
1587 } 1575 }
1588 1576
1589 // Determines if the session for |ssl_| is in the cache, and calls the
1590 // handshake completion callback if that is the case.
1591 //
1592 // CheckIfHandshakeFinished is called twice per connection: once after
1593 // MarkSSLSessionAsGood, when the certificate has been verified, and
1594 // once via an OpenSSL callback when the handshake has completed. On the
1595 // second call, when the certificate has been verified and the handshake
1596 // has completed, the connection's handshake completion callback is run.
1597 void SSLClientSocketOpenSSL::CheckIfHandshakeFinished() {
1598 if (ran_handshake_finished_callback_ && marked_session_as_good_)
1599 OnHandshakeCompletion();
1600 }
1601
1602 // static 1577 // static
1603 long SSLClientSocketOpenSSL::BIOCallback( 1578 long SSLClientSocketOpenSSL::BIOCallback(
1604 BIO *bio, 1579 BIO *bio,
1605 int cmd, 1580 int cmd,
1606 const char *argp, int argi, long argl, 1581 const char *argp, int argi, long argl,
1607 long retvalue) { 1582 long retvalue) {
1608 SSLClientSocketOpenSSL* socket = reinterpret_cast<SSLClientSocketOpenSSL*>( 1583 SSLClientSocketOpenSSL* socket = reinterpret_cast<SSLClientSocketOpenSSL*>(
1609 BIO_get_callback_arg(bio)); 1584 BIO_get_callback_arg(bio));
1610 CHECK(socket); 1585 CHECK(socket);
1611 return socket->MaybeReplayTransportError( 1586 return socket->MaybeReplayTransportError(
1612 bio, cmd, argp, argi, argl, retvalue); 1587 bio, cmd, argp, argi, argl, retvalue);
1613 } 1588 }
1614 1589
1590 // static
1591 void SSLClientSocketOpenSSL::InfoCallback(const SSL* ssl,
1592 int type,
1593 int /*val*/) {
1594 if (type == SSL_CB_HANDSHAKE_DONE) {
1595 SSLClientSocketOpenSSL* ssl_socket =
1596 SSLContext::GetInstance()->GetClientSocketFromSSL(ssl);
1597 ssl_socket->handshake_succeeded_ = true;
1598 ssl_socket->CheckIfHandshakeFinished();
1599 }
1600 }
1601
1602 // Determines if both the handshake and certificate verification have completed
1603 // successfully, and calls the handshake completion callback if that is the
1604 // case.
1605 //
1606 // CheckIfHandshakeFinished is called twice per connection: once after
1607 // MarkSSLSessionAsGood, when the certificate has been verified, and
1608 // once via an OpenSSL callback when the handshake has completed. On the
1609 // second call, when the certificate has been verified and the handshake
1610 // has completed, the connection's handshake completion callback is run.
1611 void SSLClientSocketOpenSSL::CheckIfHandshakeFinished() {
1612 if (handshake_succeeded_ && marked_session_as_good_)
1613 OnHandshakeCompletion();
1614 }
1615
1615 scoped_refptr<X509Certificate> 1616 scoped_refptr<X509Certificate>
1616 SSLClientSocketOpenSSL::GetUnverifiedServerCertificateChain() const { 1617 SSLClientSocketOpenSSL::GetUnverifiedServerCertificateChain() const {
1617 return server_cert_; 1618 return server_cert_;
1618 } 1619 }
1619 1620
1620 } // namespace net 1621 } // namespace net
OLDNEW
« no previous file with comments | « net/socket/ssl_client_socket_openssl.h ('k') | net/socket/ssl_client_socket_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698