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 |