Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 872 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 883 return network_moved; | 883 return network_moved; |
| 884 } | 884 } |
| 885 | 885 |
| 886 // TODO(cbentzel): Remove including "base/threading/thread_local.h" and | 886 // TODO(cbentzel): Remove including "base/threading/thread_local.h" and |
| 887 // g_first_run_completed once crbug.com/424386 is fixed. | 887 // g_first_run_completed once crbug.com/424386 is fixed. |
| 888 base::LazyInstance<base::ThreadLocalBoolean>::Leaky g_first_run_completed = | 888 base::LazyInstance<base::ThreadLocalBoolean>::Leaky g_first_run_completed = |
| 889 LAZY_INSTANCE_INITIALIZER; | 889 LAZY_INSTANCE_INITIALIZER; |
| 890 | 890 |
| 891 int SSLClientSocketOpenSSL::DoHandshake() { | 891 int SSLClientSocketOpenSSL::DoHandshake() { |
| 892 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); | 892 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); |
| 893 int net_error = OK; | |
| 894 | 893 |
| 895 int rv; | 894 int rv; |
| 896 | 895 |
| 897 // TODO(cbentzel): Leave only 1 call to SSL_do_handshake once crbug.com/424386 | 896 // TODO(cbentzel): Leave only 1 call to SSL_do_handshake once crbug.com/424386 |
| 898 // is fixed. | 897 // is fixed. |
| 899 if (ssl_config_.send_client_cert && ssl_config_.client_cert.get()) { | 898 if (ssl_config_.send_client_cert && ssl_config_.client_cert.get()) { |
| 900 rv = SSL_do_handshake(ssl_); | 899 rv = SSL_do_handshake(ssl_); |
| 901 } else { | 900 } else { |
| 902 if (g_first_run_completed.Get().Get()) { | 901 if (g_first_run_completed.Get().Get()) { |
| 903 // TODO(cbentzel): Remove ScopedTracker below once crbug.com/424386 is | 902 // TODO(cbentzel): Remove ScopedTracker below once crbug.com/424386 is |
| 904 // fixed. | 903 // fixed. |
| 905 tracked_objects::ScopedTracker tracking_profile( | 904 tracked_objects::ScopedTracker tracking_profile( |
| 906 FROM_HERE_WITH_EXPLICIT_FUNCTION("424386 SSL_do_handshake()")); | 905 FROM_HERE_WITH_EXPLICIT_FUNCTION("424386 SSL_do_handshake()")); |
| 907 | 906 |
| 908 rv = SSL_do_handshake(ssl_); | 907 rv = SSL_do_handshake(ssl_); |
| 909 } else { | 908 } else { |
| 910 g_first_run_completed.Get().Set(true); | 909 g_first_run_completed.Get().Set(true); |
| 911 rv = SSL_do_handshake(ssl_); | 910 rv = SSL_do_handshake(ssl_); |
| 912 } | 911 } |
| 913 } | 912 } |
| 914 | 913 |
| 915 if (rv == 1) { | 914 int net_error = OK; |
| 916 if (ssl_config_.version_fallback && | 915 if (rv <= 0) { |
| 917 ssl_config_.version_max < ssl_config_.version_fallback_min) { | |
| 918 return ERR_SSL_FALLBACK_BEYOND_MINIMUM_VERSION; | |
| 919 } | |
| 920 | |
| 921 // SSL handshake is completed. If NPN wasn't negotiated, see if ALPN was. | |
| 922 if (npn_status_ == kNextProtoUnsupported) { | |
| 923 const uint8_t* alpn_proto = NULL; | |
| 924 unsigned alpn_len = 0; | |
| 925 SSL_get0_alpn_selected(ssl_, &alpn_proto, &alpn_len); | |
| 926 if (alpn_len > 0) { | |
| 927 npn_proto_.assign(reinterpret_cast<const char*>(alpn_proto), alpn_len); | |
| 928 npn_status_ = kNextProtoNegotiated; | |
| 929 set_negotiation_extension(kExtensionALPN); | |
| 930 } | |
| 931 } | |
| 932 | |
| 933 RecordNegotiationExtension(); | |
| 934 RecordChannelIDSupport(channel_id_service_, channel_id_sent_, | |
| 935 ssl_config_.channel_id_enabled, | |
| 936 crypto::ECPrivateKey::IsSupported()); | |
| 937 | |
| 938 // Only record OCSP histograms if OCSP was requested. | |
| 939 if (ssl_config_.signed_cert_timestamps_enabled || | |
| 940 cert_verifier_->SupportsOCSPStapling()) { | |
| 941 const uint8_t* ocsp_response; | |
| 942 size_t ocsp_response_len; | |
| 943 SSL_get0_ocsp_response(ssl_, &ocsp_response, &ocsp_response_len); | |
| 944 | |
| 945 set_stapled_ocsp_response_received(ocsp_response_len != 0); | |
| 946 UMA_HISTOGRAM_BOOLEAN("Net.OCSPResponseStapled", ocsp_response_len != 0); | |
| 947 } | |
| 948 | |
| 949 const uint8_t* sct_list; | |
| 950 size_t sct_list_len; | |
| 951 SSL_get0_signed_cert_timestamp_list(ssl_, &sct_list, &sct_list_len); | |
| 952 set_signed_cert_timestamps_received(sct_list_len != 0); | |
| 953 | |
| 954 if (IsRenegotiationAllowed()) | |
| 955 SSL_set_reject_peer_renegotiations(ssl_, 0); | |
| 956 | |
| 957 // Verify the certificate. | |
| 958 UpdateServerCert(); | |
| 959 GotoState(STATE_VERIFY_CERT); | |
| 960 } else { | |
| 961 int ssl_error = SSL_get_error(ssl_, rv); | 916 int ssl_error = SSL_get_error(ssl_, rv); |
| 962 if (ssl_error == SSL_ERROR_WANT_CHANNEL_ID_LOOKUP) { | 917 if (ssl_error == SSL_ERROR_WANT_CHANNEL_ID_LOOKUP) { |
| 963 // The server supports channel ID. Stop to look one up before returning to | 918 // The server supports channel ID. Stop to look one up before returning to |
| 964 // the handshake. | 919 // the handshake. |
| 965 GotoState(STATE_CHANNEL_ID_LOOKUP); | 920 GotoState(STATE_CHANNEL_ID_LOOKUP); |
| 966 return OK; | 921 return OK; |
| 967 } | 922 } |
| 968 if (ssl_error == SSL_ERROR_WANT_X509_LOOKUP && | 923 if (ssl_error == SSL_ERROR_WANT_X509_LOOKUP && |
| 969 !ssl_config_.send_client_cert) { | 924 !ssl_config_.send_client_cert) { |
| 970 return ERR_SSL_CLIENT_AUTH_CERT_NEEDED; | 925 return ERR_SSL_CLIENT_AUTH_CERT_NEEDED; |
| 971 } | 926 } |
| 972 | 927 |
| 973 OpenSSLErrorInfo error_info; | 928 OpenSSLErrorInfo error_info; |
| 974 net_error = MapOpenSSLErrorWithDetails(ssl_error, err_tracer, &error_info); | 929 net_error = MapOpenSSLErrorWithDetails(ssl_error, err_tracer, &error_info); |
| 930 if (net_error == ERR_IO_PENDING) { | |
| 931 // If not done, stay in this state | |
| 932 GotoState(STATE_HANDSHAKE); | |
| 933 return ERR_IO_PENDING; | |
| 934 } | |
| 975 | 935 |
| 976 // If not done, stay in this state | 936 LOG(ERROR) << "handshake failed; returned " << rv << ", SSL error code " |
| 977 if (net_error == ERR_IO_PENDING) { | 937 << ssl_error << ", net_error " << net_error; |
| 978 GotoState(STATE_HANDSHAKE); | 938 net_log_.AddEvent( |
| 979 } else { | 939 NetLog::TYPE_SSL_HANDSHAKE_ERROR, |
| 980 LOG(ERROR) << "handshake failed; returned " << rv | 940 CreateNetLogOpenSSLErrorCallback(net_error, ssl_error, error_info)); |
| 981 << ", SSL error code " << ssl_error | 941 } |
| 982 << ", net_error " << net_error; | 942 |
| 983 net_log_.AddEvent( | 943 GotoState(STATE_HANDSHAKE_COMPLETE); |
|
davidben
2015/05/08 22:29:16
TBH, this transition is kinda pointless in the fai
| |
| 984 NetLog::TYPE_SSL_HANDSHAKE_ERROR, | 944 return net_error; |
| 985 CreateNetLogOpenSSLErrorCallback(net_error, ssl_error, error_info)); | 945 } |
| 946 | |
| 947 int SSLClientSocketOpenSSL::DoHandshakeComplete(int result) { | |
| 948 if (result < 0) | |
| 949 return result; | |
| 950 | |
| 951 if (ssl_config_.version_fallback && | |
| 952 ssl_config_.version_max < ssl_config_.version_fallback_min) { | |
| 953 return ERR_SSL_FALLBACK_BEYOND_MINIMUM_VERSION; | |
| 954 } | |
| 955 | |
| 956 // SSL handshake is completed. If NPN wasn't negotiated, see if ALPN was. | |
| 957 if (npn_status_ == kNextProtoUnsupported) { | |
| 958 const uint8_t* alpn_proto = NULL; | |
| 959 unsigned alpn_len = 0; | |
| 960 SSL_get0_alpn_selected(ssl_, &alpn_proto, &alpn_len); | |
| 961 if (alpn_len > 0) { | |
| 962 npn_proto_.assign(reinterpret_cast<const char*>(alpn_proto), alpn_len); | |
| 963 npn_status_ = kNextProtoNegotiated; | |
| 964 set_negotiation_extension(kExtensionALPN); | |
| 986 } | 965 } |
| 987 } | 966 } |
| 988 return net_error; | 967 |
| 968 RecordNegotiationExtension(); | |
| 969 RecordChannelIDSupport(channel_id_service_, channel_id_sent_, | |
| 970 ssl_config_.channel_id_enabled, | |
| 971 crypto::ECPrivateKey::IsSupported()); | |
| 972 | |
| 973 // Only record OCSP histograms if OCSP was requested. | |
| 974 if (ssl_config_.signed_cert_timestamps_enabled || | |
| 975 cert_verifier_->SupportsOCSPStapling()) { | |
| 976 const uint8_t* ocsp_response; | |
| 977 size_t ocsp_response_len; | |
| 978 SSL_get0_ocsp_response(ssl_, &ocsp_response, &ocsp_response_len); | |
| 979 | |
| 980 set_stapled_ocsp_response_received(ocsp_response_len != 0); | |
| 981 UMA_HISTOGRAM_BOOLEAN("Net.OCSPResponseStapled", ocsp_response_len != 0); | |
| 982 } | |
| 983 | |
| 984 const uint8_t* sct_list; | |
| 985 size_t sct_list_len; | |
| 986 SSL_get0_signed_cert_timestamp_list(ssl_, &sct_list, &sct_list_len); | |
| 987 set_signed_cert_timestamps_received(sct_list_len != 0); | |
| 988 | |
| 989 if (IsRenegotiationAllowed()) | |
| 990 SSL_set_reject_peer_renegotiations(ssl_, 0); | |
| 991 | |
| 992 // Verify the certificate. | |
| 993 UpdateServerCert(); | |
| 994 GotoState(STATE_VERIFY_CERT); | |
| 995 return OK; | |
| 989 } | 996 } |
| 990 | 997 |
| 991 int SSLClientSocketOpenSSL::DoChannelIDLookup() { | 998 int SSLClientSocketOpenSSL::DoChannelIDLookup() { |
| 992 net_log_.AddEvent(NetLog::TYPE_SSL_CHANNEL_ID_REQUESTED); | 999 net_log_.AddEvent(NetLog::TYPE_SSL_CHANNEL_ID_REQUESTED); |
| 993 GotoState(STATE_CHANNEL_ID_LOOKUP_COMPLETE); | 1000 GotoState(STATE_CHANNEL_ID_LOOKUP_COMPLETE); |
| 994 return channel_id_service_->GetOrCreateChannelID( | 1001 return channel_id_service_->GetOrCreateChannelID( |
| 995 host_and_port_.host(), | 1002 host_and_port_.host(), |
| 996 &channel_id_private_key_, | 1003 &channel_id_private_key_, |
| 997 &channel_id_cert_, | 1004 &channel_id_cert_, |
| 998 base::Bind(&SSLClientSocketOpenSSL::OnHandshakeIOComplete, | 1005 base::Bind(&SSLClientSocketOpenSSL::OnHandshakeIOComplete, |
| (...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1290 // (This is a quirk carried over from the windows | 1297 // (This is a quirk carried over from the windows |
| 1291 // implementation. It makes reading the logs a bit harder.) | 1298 // implementation. It makes reading the logs a bit harder.) |
| 1292 // State handlers can and often do call GotoState just | 1299 // State handlers can and often do call GotoState just |
| 1293 // to stay in the current state. | 1300 // to stay in the current state. |
| 1294 State state = next_handshake_state_; | 1301 State state = next_handshake_state_; |
| 1295 GotoState(STATE_NONE); | 1302 GotoState(STATE_NONE); |
| 1296 switch (state) { | 1303 switch (state) { |
| 1297 case STATE_HANDSHAKE: | 1304 case STATE_HANDSHAKE: |
| 1298 rv = DoHandshake(); | 1305 rv = DoHandshake(); |
| 1299 break; | 1306 break; |
| 1307 case STATE_HANDSHAKE_COMPLETE: | |
| 1308 rv = DoHandshakeComplete(rv); | |
| 1309 break; | |
| 1300 case STATE_CHANNEL_ID_LOOKUP: | 1310 case STATE_CHANNEL_ID_LOOKUP: |
| 1301 DCHECK_EQ(OK, rv); | 1311 DCHECK_EQ(OK, rv); |
| 1302 rv = DoChannelIDLookup(); | 1312 rv = DoChannelIDLookup(); |
| 1303 break; | 1313 break; |
| 1304 case STATE_CHANNEL_ID_LOOKUP_COMPLETE: | 1314 case STATE_CHANNEL_ID_LOOKUP_COMPLETE: |
| 1305 rv = DoChannelIDLookupComplete(rv); | 1315 rv = DoChannelIDLookupComplete(rv); |
| 1306 break; | 1316 break; |
| 1307 case STATE_VERIFY_CERT: | 1317 case STATE_VERIFY_CERT: |
| 1308 DCHECK_EQ(OK, rv); | 1318 DCHECK_EQ(OK, rv); |
| 1309 rv = DoVerifyCert(rv); | 1319 rv = DoVerifyCert(rv); |
| (...skipping 593 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1903 } | 1913 } |
| 1904 return false; | 1914 return false; |
| 1905 } | 1915 } |
| 1906 | 1916 |
| 1907 scoped_refptr<X509Certificate> | 1917 scoped_refptr<X509Certificate> |
| 1908 SSLClientSocketOpenSSL::GetUnverifiedServerCertificateChain() const { | 1918 SSLClientSocketOpenSSL::GetUnverifiedServerCertificateChain() const { |
| 1909 return server_cert_; | 1919 return server_cert_; |
| 1910 } | 1920 } |
| 1911 | 1921 |
| 1912 } // namespace net | 1922 } // namespace net |
| OLD | NEW |