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 500e54d3898b5ee9ffcfc45bf62bc58342a130a8..4feea73cd1f2583b66da90bca017b7e6b7489381 100644 |
| --- a/net/socket/ssl_client_socket_openssl.cc |
| +++ b/net/socket/ssl_client_socket_openssl.cc |
| @@ -38,6 +38,7 @@ |
| #include "net/ssl/ssl_cert_request_info.h" |
| #include "net/ssl/ssl_client_session_cache_openssl.h" |
| #include "net/ssl/ssl_connection_status_flags.h" |
| +#include "net/ssl/ssl_failure_state.h" |
| #include "net/ssl/ssl_info.h" |
| #if defined(OS_WIN) |
| @@ -371,6 +372,7 @@ SSLClientSocketOpenSSL::SSLClientSocketOpenSSL( |
| channel_id_sent_(false), |
| handshake_completed_(false), |
| certificate_verified_(false), |
| + ssl_failure_state_(kSSLFailureNone), |
| transport_security_state_(context.transport_security_state), |
| policy_enforcer_(context.cert_policy_enforcer), |
| net_log_(transport_->socket()->NetLog()), |
| @@ -400,6 +402,10 @@ SSLClientSocketOpenSSL::GetChannelIDService() const { |
| return channel_id_service_; |
| } |
| +SSLFailureState SSLClientSocketOpenSSL::GetSSLFailureState() const { |
| + return ssl_failure_state_; |
|
Ryan Sleevi
2015/05/13 22:26:36
BUG: You never reset this in Disconnect()
DOUBLE
davidben
2015/05/14 23:24:34
Done.
|
| +} |
| + |
| int SSLClientSocketOpenSSL::ExportKeyingMaterial( |
| const base::StringPiece& label, |
| bool has_context, const base::StringPiece& context, |
| @@ -940,6 +946,31 @@ int SSLClientSocketOpenSSL::DoHandshake() { |
| net_log_.AddEvent( |
| NetLog::TYPE_SSL_HANDSHAKE_ERROR, |
| CreateNetLogOpenSSLErrorCallback(net_error, ssl_error, error_info)); |
| + |
| + // Classify the handshake failure. This is used to determine causes of the |
| + // TLS version fallback. |
| + |
| + // |cipher| is the current outgoing cipher suite, so it is non-null iff |
| + // ChangeCipherSpec was sent. |
| + const SSL_CIPHER* cipher = SSL_get_current_cipher(ssl_); |
| + if (SSL_get_state(ssl_) == SSL3_ST_CR_SRVR_HELLO_A) { |
| + ssl_failure_state_ = kSSLFailureClientHello; |
| + } else if (cipher && (SSL_CIPHER_get_id(cipher) == |
| + TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256 || |
| + SSL_CIPHER_get_id(cipher) == |
| + TLS1_CK_RSA_WITH_AES_128_GCM_SHA256)) { |
| + ssl_failure_state_ = kSSLFailureBuggyGCM; |
| + } else if (cipher && ssl_config_.send_client_cert) { |
| + ssl_failure_state_ = kSSLFailureClientAuth; |
| + } else if (ERR_GET_LIB(error_info.error_code) == ERR_LIB_SSL && |
| + ERR_GET_REASON(error_info.error_code) == |
| + SSL_R_OLD_SESSION_VERSION_NOT_RETURNED) { |
| + ssl_failure_state_ = kSSLFailureSessionMismatch; |
| + } else if (cipher && npn_status_ != kNextProtoUnsupported) { |
| + ssl_failure_state_ = kSSLFailureNextProto; |
| + } else { |
| + ssl_failure_state_ = kSSLFailureUnknown; |
| + } |
| } |
| GotoState(STATE_HANDSHAKE_COMPLETE); |