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 24c5a55beee076afa6f0cf53f39d61a084f0809e..41343a51781ffd8c572b1c6fbb522cacce4a6408 100644 |
--- a/net/socket/ssl_client_socket_openssl.cc |
+++ b/net/socket/ssl_client_socket_openssl.cc |
@@ -890,7 +890,6 @@ base::LazyInstance<base::ThreadLocalBoolean>::Leaky g_first_run_completed = |
int SSLClientSocketOpenSSL::DoHandshake() { |
crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); |
- int net_error = OK; |
int rv; |
@@ -912,52 +911,8 @@ int SSLClientSocketOpenSSL::DoHandshake() { |
} |
} |
- if (rv == 1) { |
- if (ssl_config_.version_fallback && |
- ssl_config_.version_max < ssl_config_.version_fallback_min) { |
- return ERR_SSL_FALLBACK_BEYOND_MINIMUM_VERSION; |
- } |
- |
- // SSL handshake is completed. If NPN wasn't negotiated, see if ALPN was. |
- if (npn_status_ == kNextProtoUnsupported) { |
- const uint8_t* alpn_proto = NULL; |
- unsigned alpn_len = 0; |
- SSL_get0_alpn_selected(ssl_, &alpn_proto, &alpn_len); |
- if (alpn_len > 0) { |
- npn_proto_.assign(reinterpret_cast<const char*>(alpn_proto), alpn_len); |
- npn_status_ = kNextProtoNegotiated; |
- set_negotiation_extension(kExtensionALPN); |
- } |
- } |
- |
- RecordNegotiationExtension(); |
- RecordChannelIDSupport(channel_id_service_, channel_id_sent_, |
- ssl_config_.channel_id_enabled, |
- crypto::ECPrivateKey::IsSupported()); |
- |
- // Only record OCSP histograms if OCSP was requested. |
- if (ssl_config_.signed_cert_timestamps_enabled || |
- cert_verifier_->SupportsOCSPStapling()) { |
- const uint8_t* ocsp_response; |
- size_t ocsp_response_len; |
- SSL_get0_ocsp_response(ssl_, &ocsp_response, &ocsp_response_len); |
- |
- set_stapled_ocsp_response_received(ocsp_response_len != 0); |
- UMA_HISTOGRAM_BOOLEAN("Net.OCSPResponseStapled", ocsp_response_len != 0); |
- } |
- |
- const uint8_t* sct_list; |
- size_t sct_list_len; |
- SSL_get0_signed_cert_timestamp_list(ssl_, &sct_list, &sct_list_len); |
- set_signed_cert_timestamps_received(sct_list_len != 0); |
- |
- if (IsRenegotiationAllowed()) |
- SSL_set_reject_peer_renegotiations(ssl_, 0); |
- |
- // Verify the certificate. |
- UpdateServerCert(); |
- GotoState(STATE_VERIFY_CERT); |
- } else { |
+ int net_error = OK; |
+ if (rv <= 0) { |
int ssl_error = SSL_get_error(ssl_, rv); |
if (ssl_error == SSL_ERROR_WANT_CHANNEL_ID_LOOKUP) { |
// The server supports channel ID. Stop to look one up before returning to |
@@ -972,22 +927,74 @@ int SSLClientSocketOpenSSL::DoHandshake() { |
OpenSSLErrorInfo error_info; |
net_error = MapOpenSSLErrorWithDetails(ssl_error, err_tracer, &error_info); |
- |
- // If not done, stay in this state |
if (net_error == ERR_IO_PENDING) { |
+ // If not done, stay in this state |
GotoState(STATE_HANDSHAKE); |
- } else { |
- LOG(ERROR) << "handshake failed; returned " << rv |
- << ", SSL error code " << ssl_error |
- << ", net_error " << net_error; |
- net_log_.AddEvent( |
- NetLog::TYPE_SSL_HANDSHAKE_ERROR, |
- CreateNetLogOpenSSLErrorCallback(net_error, ssl_error, error_info)); |
+ return ERR_IO_PENDING; |
} |
+ |
+ LOG(ERROR) << "handshake failed; returned " << rv << ", SSL error code " |
+ << ssl_error << ", net_error " << net_error; |
+ net_log_.AddEvent( |
+ NetLog::TYPE_SSL_HANDSHAKE_ERROR, |
+ CreateNetLogOpenSSLErrorCallback(net_error, ssl_error, error_info)); |
} |
+ |
+ GotoState(STATE_HANDSHAKE_COMPLETE); |
davidben
2015/05/08 22:29:16
TBH, this transition is kinda pointless in the fai
|
return net_error; |
} |
+int SSLClientSocketOpenSSL::DoHandshakeComplete(int result) { |
+ if (result < 0) |
+ return result; |
+ |
+ if (ssl_config_.version_fallback && |
+ ssl_config_.version_max < ssl_config_.version_fallback_min) { |
+ return ERR_SSL_FALLBACK_BEYOND_MINIMUM_VERSION; |
+ } |
+ |
+ // SSL handshake is completed. If NPN wasn't negotiated, see if ALPN was. |
+ if (npn_status_ == kNextProtoUnsupported) { |
+ const uint8_t* alpn_proto = NULL; |
+ unsigned alpn_len = 0; |
+ SSL_get0_alpn_selected(ssl_, &alpn_proto, &alpn_len); |
+ if (alpn_len > 0) { |
+ npn_proto_.assign(reinterpret_cast<const char*>(alpn_proto), alpn_len); |
+ npn_status_ = kNextProtoNegotiated; |
+ set_negotiation_extension(kExtensionALPN); |
+ } |
+ } |
+ |
+ RecordNegotiationExtension(); |
+ RecordChannelIDSupport(channel_id_service_, channel_id_sent_, |
+ ssl_config_.channel_id_enabled, |
+ crypto::ECPrivateKey::IsSupported()); |
+ |
+ // Only record OCSP histograms if OCSP was requested. |
+ if (ssl_config_.signed_cert_timestamps_enabled || |
+ cert_verifier_->SupportsOCSPStapling()) { |
+ const uint8_t* ocsp_response; |
+ size_t ocsp_response_len; |
+ SSL_get0_ocsp_response(ssl_, &ocsp_response, &ocsp_response_len); |
+ |
+ set_stapled_ocsp_response_received(ocsp_response_len != 0); |
+ UMA_HISTOGRAM_BOOLEAN("Net.OCSPResponseStapled", ocsp_response_len != 0); |
+ } |
+ |
+ const uint8_t* sct_list; |
+ size_t sct_list_len; |
+ SSL_get0_signed_cert_timestamp_list(ssl_, &sct_list, &sct_list_len); |
+ set_signed_cert_timestamps_received(sct_list_len != 0); |
+ |
+ if (IsRenegotiationAllowed()) |
+ SSL_set_reject_peer_renegotiations(ssl_, 0); |
+ |
+ // Verify the certificate. |
+ UpdateServerCert(); |
+ GotoState(STATE_VERIFY_CERT); |
+ return OK; |
+} |
+ |
int SSLClientSocketOpenSSL::DoChannelIDLookup() { |
net_log_.AddEvent(NetLog::TYPE_SSL_CHANNEL_ID_REQUESTED); |
GotoState(STATE_CHANNEL_ID_LOOKUP_COMPLETE); |
@@ -1297,6 +1304,9 @@ int SSLClientSocketOpenSSL::DoHandshakeLoop(int last_io_result) { |
case STATE_HANDSHAKE: |
rv = DoHandshake(); |
break; |
+ case STATE_HANDSHAKE_COMPLETE: |
+ rv = DoHandshakeComplete(rv); |
+ break; |
case STATE_CHANNEL_ID_LOOKUP: |
DCHECK_EQ(OK, rv); |
rv = DoChannelIDLookup(); |