Chromium Code Reviews| Index: net/socket/ssl_client_socket_openssl.cc |
| diff --git a/net/socket/ssl_client_socket_openssl.cc b/net/socket/ssl_client_socket_openssl.cc |
| index a6f5caf188d96dac7c1a339e732990cb05ebd6f3..4d108fc92782f156390dcded83b4be3eaaba2ad9 100644 |
| --- a/net/socket/ssl_client_socket_openssl.cc |
| +++ b/net/socket/ssl_client_socket_openssl.cc |
| @@ -363,6 +363,8 @@ SSLClientSocketOpenSSL::SSLClientSocketOpenSSL( |
| next_handshake_state_(STATE_NONE), |
| npn_status_(kNextProtoUnsupported), |
| channel_id_xtn_negotiated_(false), |
| + ran_handshake_finished_callback_(false), |
| + marked_session_as_good_(false), |
| net_log_(transport_->socket()->NetLog()) { |
| } |
| @@ -435,14 +437,6 @@ int SSLClientSocketOpenSSL::Connect(const CompletionCallback& callback) { |
| return rv; |
| } |
| - if (!handshake_completion_callback_.is_null()) { |
| - SSLContext* context = SSLContext::GetInstance(); |
| - context->session_cache()->SetSessionAddedCallback( |
| - ssl_, |
| - base::Bind(&SSLClientSocketOpenSSL::OnHandshakeCompletion, |
| - base::Unretained(this))); |
| - } |
| - |
| // Set SSL to client mode. Handshake happens in the loop below. |
| SSL_set_connect_state(ssl_); |
| @@ -465,8 +459,6 @@ void SSLClientSocketOpenSSL::Disconnect() { |
| // completed, this is a no-op. |
| OnHandshakeCompletion(); |
| if (ssl_) { |
| - SSLContext* context = SSLContext::GetInstance(); |
| - context->session_cache()->RemoveSessionAddedCallback(ssl_); |
| // Calling SSL_shutdown prevents the session from being marked as |
| // unresumable. |
| SSL_shutdown(ssl_); |
| @@ -687,6 +679,18 @@ int SSLClientSocketOpenSSL::SetSendBufferSize(int32 size) { |
| return transport_->socket()->SetSendBufferSize(size); |
| } |
| +// static |
| +void SSLClientSocketOpenSSL::InfoCallback(const SSL* ssl, |
| + int result, |
| + int /*unused*/) { |
|
wtc
2014/08/07 20:04:04
The second parameter should be named "type". The t
|
| + SSLClientSocketOpenSSL* ssl_socket = |
| + SSLContext::GetInstance()->GetClientSocketFromSSL(ssl); |
|
wtc
2014/08/07 20:04:03
Move this into the if block because it is only use
|
| + if (result == SSL_CB_HANDSHAKE_DONE) { |
| + ssl_socket->ran_handshake_finished_callback_ = true; |
| + ssl_socket->CheckIfHandshakeFinished(); |
| + } |
| +} |
| + |
| int SSLClientSocketOpenSSL::Init() { |
| DCHECK(!ssl_); |
| DCHECK(!transport_bio_); |
| @@ -701,6 +705,9 @@ int SSLClientSocketOpenSSL::Init() { |
| if (!SSL_set_tlsext_host_name(ssl_, host_and_port_.host().c_str())) |
| return ERR_UNEXPECTED; |
| + // Set an OpenSSL callback to monitor this SSL*'s connection. |
| + SSL_set_info_callback(ssl_, &InfoCallback); |
| + |
| trying_cached_session_ = context->session_cache()->SetSSLSessionWithKey( |
| ssl_, GetSessionCacheKey()); |
| @@ -1032,6 +1039,8 @@ int SSLClientSocketOpenSSL::DoVerifyCertComplete(int result) { |
| // TODO(joth): Work out if we need to remember the intermediate CA certs |
| // when the server sends them to us, and do so here. |
| SSLContext::GetInstance()->session_cache()->MarkSSLSessionAsGood(ssl_); |
| + marked_session_as_good_ = true; |
| + CheckIfHandshakeFinished(); |
| } else { |
| DVLOG(1) << "DoVerifyCertComplete error " << ErrorToString(result) |
| << " (" << result << ")"; |
| @@ -1577,6 +1586,19 @@ long SSLClientSocketOpenSSL::MaybeReplayTransportError( |
| return retvalue; |
| } |
| +// Determines if the session for |ssl_| is in the cache, and calls the |
|
wtc
2014/08/07 20:04:03
"the session for |ssl_| is in the cache" is not tr
|
| +// handshake completion callback if that is the case. |
| +// |
| +// CheckIfHandshakeFinished is called twice per connection: once after |
| +// MarkSSLSessionAsGood, when the certificate has been verified, and |
| +// once via an OpenSSL callback when the handshake has completed. On the |
| +// second call, when the certificate has been verified and the handshake |
| +// has completed, the connection's handshake completion callback is run. |
| +void SSLClientSocketOpenSSL::CheckIfHandshakeFinished() { |
|
wtc
2014/08/07 20:04:03
Nit: to match the declaration order in the .h file
|
| + if (ran_handshake_finished_callback_ && marked_session_as_good_) |
| + OnHandshakeCompletion(); |
| +} |
| + |
| // static |
| long SSLClientSocketOpenSSL::BIOCallback( |
| BIO *bio, |