| 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> |
| 11 #include <openssl/bio.h> | 11 #include <openssl/bio.h> |
| 12 #include <openssl/bytestring.h> | 12 #include <openssl/bytestring.h> |
| 13 #include <openssl/err.h> | 13 #include <openssl/err.h> |
| 14 #include <openssl/evp.h> | 14 #include <openssl/evp.h> |
| 15 #include <openssl/mem.h> | 15 #include <openssl/mem.h> |
| 16 #include <openssl/ssl.h> | 16 #include <openssl/ssl.h> |
| 17 #include <string.h> | 17 #include <string.h> |
| 18 | 18 |
| 19 #include "base/bind.h" | 19 #include "base/bind.h" |
| 20 #include "base/callback_helpers.h" | 20 #include "base/callback_helpers.h" |
| 21 #include "base/lazy_instance.h" | 21 #include "base/lazy_instance.h" |
| 22 #include "base/macros.h" |
| 22 #include "base/memory/singleton.h" | 23 #include "base/memory/singleton.h" |
| 23 #include "base/metrics/histogram_macros.h" | 24 #include "base/metrics/histogram_macros.h" |
| 24 #include "base/metrics/sparse_histogram.h" | 25 #include "base/metrics/sparse_histogram.h" |
| 25 #include "base/profiler/scoped_tracker.h" | 26 #include "base/profiler/scoped_tracker.h" |
| 26 #include "base/strings/string_piece.h" | 27 #include "base/strings/string_piece.h" |
| 27 #include "base/synchronization/lock.h" | 28 #include "base/synchronization/lock.h" |
| 28 #include "base/threading/thread_local.h" | 29 #include "base/threading/thread_local.h" |
| 29 #include "base/values.h" | 30 #include "base/values.h" |
| 30 #include "crypto/ec_private_key.h" | 31 #include "crypto/ec_private_key.h" |
| 31 #include "crypto/openssl_util.h" | 32 #include "crypto/openssl_util.h" |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 92 const uint8_t kTbMinProtocolVersionMajor = 0; | 93 const uint8_t kTbMinProtocolVersionMajor = 0; |
| 93 const uint8_t kTbMinProtocolVersionMinor = 2; | 94 const uint8_t kTbMinProtocolVersionMinor = 2; |
| 94 | 95 |
| 95 void FreeX509Stack(STACK_OF(X509)* ptr) { | 96 void FreeX509Stack(STACK_OF(X509)* ptr) { |
| 96 sk_X509_pop_free(ptr, X509_free); | 97 sk_X509_pop_free(ptr, X509_free); |
| 97 } | 98 } |
| 98 | 99 |
| 99 using ScopedX509Stack = crypto::ScopedOpenSSL<STACK_OF(X509), FreeX509Stack>; | 100 using ScopedX509Stack = crypto::ScopedOpenSSL<STACK_OF(X509), FreeX509Stack>; |
| 100 | 101 |
| 101 // Used for encoding the |connection_status| field of an SSLInfo object. | 102 // Used for encoding the |connection_status| field of an SSLInfo object. |
| 102 int EncodeSSLConnectionStatus(uint16 cipher_suite, | 103 int EncodeSSLConnectionStatus(uint16_t cipher_suite, |
| 103 int compression, | 104 int compression, |
| 104 int version) { | 105 int version) { |
| 105 return cipher_suite | | 106 return cipher_suite | |
| 106 ((compression & SSL_CONNECTION_COMPRESSION_MASK) << | 107 ((compression & SSL_CONNECTION_COMPRESSION_MASK) << |
| 107 SSL_CONNECTION_COMPRESSION_SHIFT) | | 108 SSL_CONNECTION_COMPRESSION_SHIFT) | |
| 108 ((version & SSL_CONNECTION_VERSION_MASK) << | 109 ((version & SSL_CONNECTION_VERSION_MASK) << |
| 109 SSL_CONNECTION_VERSION_SHIFT); | 110 SSL_CONNECTION_VERSION_SHIFT); |
| 110 } | 111 } |
| 111 | 112 |
| 112 // Returns the net SSL version number (see ssl_connection_status_flags.h) for | 113 // Returns the net SSL version number (see ssl_connection_status_flags.h) for |
| (...skipping 645 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 758 | 759 |
| 759 AddSCTInfoToSSLInfo(ssl_info); | 760 AddSCTInfoToSSLInfo(ssl_info); |
| 760 | 761 |
| 761 const SSL_CIPHER* cipher = SSL_get_current_cipher(ssl_); | 762 const SSL_CIPHER* cipher = SSL_get_current_cipher(ssl_); |
| 762 CHECK(cipher); | 763 CHECK(cipher); |
| 763 ssl_info->security_bits = SSL_CIPHER_get_bits(cipher, NULL); | 764 ssl_info->security_bits = SSL_CIPHER_get_bits(cipher, NULL); |
| 764 ssl_info->key_exchange_info = | 765 ssl_info->key_exchange_info = |
| 765 SSL_SESSION_get_key_exchange_info(SSL_get_session(ssl_)); | 766 SSL_SESSION_get_key_exchange_info(SSL_get_session(ssl_)); |
| 766 | 767 |
| 767 ssl_info->connection_status = EncodeSSLConnectionStatus( | 768 ssl_info->connection_status = EncodeSSLConnectionStatus( |
| 768 static_cast<uint16>(SSL_CIPHER_get_id(cipher)), 0 /* no compression */, | 769 static_cast<uint16_t>(SSL_CIPHER_get_id(cipher)), 0 /* no compression */, |
| 769 GetNetSSLVersion(ssl_)); | 770 GetNetSSLVersion(ssl_)); |
| 770 | 771 |
| 771 if (!SSL_get_secure_renegotiation_support(ssl_)) | 772 if (!SSL_get_secure_renegotiation_support(ssl_)) |
| 772 ssl_info->connection_status |= SSL_CONNECTION_NO_RENEGOTIATION_EXTENSION; | 773 ssl_info->connection_status |= SSL_CONNECTION_NO_RENEGOTIATION_EXTENSION; |
| 773 | 774 |
| 774 if (ssl_config_.version_fallback) | 775 if (ssl_config_.version_fallback) |
| 775 ssl_info->connection_status |= SSL_CONNECTION_VERSION_FALLBACK; | 776 ssl_info->connection_status |= SSL_CONNECTION_VERSION_FALLBACK; |
| 776 | 777 |
| 777 ssl_info->handshake_type = SSL_session_reused(ssl_) ? | 778 ssl_info->handshake_type = SSL_session_reused(ssl_) ? |
| 778 SSLInfo::HANDSHAKE_RESUME : SSLInfo::HANDSHAKE_FULL; | 779 SSLInfo::HANDSHAKE_RESUME : SSLInfo::HANDSHAKE_FULL; |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 826 } else { | 827 } else { |
| 827 if (rv > 0) | 828 if (rv > 0) |
| 828 was_ever_used_ = true; | 829 was_ever_used_ = true; |
| 829 user_write_buf_ = NULL; | 830 user_write_buf_ = NULL; |
| 830 user_write_buf_len_ = 0; | 831 user_write_buf_len_ = 0; |
| 831 } | 832 } |
| 832 | 833 |
| 833 return rv; | 834 return rv; |
| 834 } | 835 } |
| 835 | 836 |
| 836 int SSLClientSocketOpenSSL::SetReceiveBufferSize(int32 size) { | 837 int SSLClientSocketOpenSSL::SetReceiveBufferSize(int32_t size) { |
| 837 return transport_->socket()->SetReceiveBufferSize(size); | 838 return transport_->socket()->SetReceiveBufferSize(size); |
| 838 } | 839 } |
| 839 | 840 |
| 840 int SSLClientSocketOpenSSL::SetSendBufferSize(int32 size) { | 841 int SSLClientSocketOpenSSL::SetSendBufferSize(int32_t size) { |
| 841 return transport_->socket()->SetSendBufferSize(size); | 842 return transport_->socket()->SetSendBufferSize(size); |
| 842 } | 843 } |
| 843 | 844 |
| 844 int SSLClientSocketOpenSSL::Init() { | 845 int SSLClientSocketOpenSSL::Init() { |
| 845 DCHECK(!ssl_); | 846 DCHECK(!ssl_); |
| 846 DCHECK(!transport_bio_); | 847 DCHECK(!transport_bio_); |
| 847 | 848 |
| 848 #if defined(USE_NSS_CERTS) || defined(OS_IOS) | 849 #if defined(USE_NSS_CERTS) || defined(OS_IOS) |
| 849 if (ssl_config_.cert_io_enabled) { | 850 if (ssl_config_.cert_io_enabled) { |
| 850 // TODO(davidben): Move this out of SSLClientSocket. See | 851 // TODO(davidben): Move this out of SSLClientSocket. See |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 980 | 981 |
| 981 // TLS channel ids. | 982 // TLS channel ids. |
| 982 if (IsChannelIDEnabled(ssl_config_, channel_id_service_)) { | 983 if (IsChannelIDEnabled(ssl_config_, channel_id_service_)) { |
| 983 SSL_enable_tls_channel_id(ssl_); | 984 SSL_enable_tls_channel_id(ssl_); |
| 984 } | 985 } |
| 985 | 986 |
| 986 if (!ssl_config_.alpn_protos.empty()) { | 987 if (!ssl_config_.alpn_protos.empty()) { |
| 987 // Get list of ciphers that are enabled. | 988 // Get list of ciphers that are enabled. |
| 988 STACK_OF(SSL_CIPHER)* enabled_ciphers = SSL_get_ciphers(ssl_); | 989 STACK_OF(SSL_CIPHER)* enabled_ciphers = SSL_get_ciphers(ssl_); |
| 989 DCHECK(enabled_ciphers); | 990 DCHECK(enabled_ciphers); |
| 990 std::vector<uint16> enabled_ciphers_vector; | 991 std::vector<uint16_t> enabled_ciphers_vector; |
| 991 for (size_t i = 0; i < sk_SSL_CIPHER_num(enabled_ciphers); ++i) { | 992 for (size_t i = 0; i < sk_SSL_CIPHER_num(enabled_ciphers); ++i) { |
| 992 const SSL_CIPHER* cipher = sk_SSL_CIPHER_value(enabled_ciphers, i); | 993 const SSL_CIPHER* cipher = sk_SSL_CIPHER_value(enabled_ciphers, i); |
| 993 const uint16 id = static_cast<uint16>(SSL_CIPHER_get_id(cipher)); | 994 const uint16_t id = static_cast<uint16_t>(SSL_CIPHER_get_id(cipher)); |
| 994 enabled_ciphers_vector.push_back(id); | 995 enabled_ciphers_vector.push_back(id); |
| 995 } | 996 } |
| 996 | 997 |
| 997 NextProtoVector alpn_protos = ssl_config_.alpn_protos; | 998 NextProtoVector alpn_protos = ssl_config_.alpn_protos; |
| 998 if (!HasCipherAdequateForHTTP2(enabled_ciphers_vector) || | 999 if (!HasCipherAdequateForHTTP2(enabled_ciphers_vector) || |
| 999 !IsTLSVersionAdequateForHTTP2(ssl_config_)) { | 1000 !IsTLSVersionAdequateForHTTP2(ssl_config_)) { |
| 1000 DisableHTTP2(&alpn_protos); | 1001 DisableHTTP2(&alpn_protos); |
| 1001 } | 1002 } |
| 1002 std::vector<uint8_t> wire_protos = SerializeNextProtos(alpn_protos); | 1003 std::vector<uint8_t> wire_protos = SerializeNextProtos(alpn_protos); |
| 1003 SSL_set_alpn_protos(ssl_, wire_protos.empty() ? NULL : &wire_protos[0], | 1004 SSL_set_alpn_protos(ssl_, wire_protos.empty() ? NULL : &wire_protos[0], |
| (...skipping 927 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1931 | 1932 |
| 1932 // SelectNextProtoCallback is called by OpenSSL during the handshake. If the | 1933 // SelectNextProtoCallback is called by OpenSSL during the handshake. If the |
| 1933 // server supports NPN, selects a protocol from the list that the server | 1934 // server supports NPN, selects a protocol from the list that the server |
| 1934 // provides. According to third_party/openssl/openssl/ssl/ssl_lib.c, the | 1935 // provides. According to third_party/openssl/openssl/ssl/ssl_lib.c, the |
| 1935 // callback can assume that |in| is syntactically valid. | 1936 // callback can assume that |in| is syntactically valid. |
| 1936 int SSLClientSocketOpenSSL::SelectNextProtoCallback(unsigned char** out, | 1937 int SSLClientSocketOpenSSL::SelectNextProtoCallback(unsigned char** out, |
| 1937 unsigned char* outlen, | 1938 unsigned char* outlen, |
| 1938 const unsigned char* in, | 1939 const unsigned char* in, |
| 1939 unsigned int inlen) { | 1940 unsigned int inlen) { |
| 1940 if (ssl_config_.npn_protos.empty()) { | 1941 if (ssl_config_.npn_protos.empty()) { |
| 1941 *out = reinterpret_cast<uint8*>( | 1942 *out = reinterpret_cast<uint8_t*>( |
| 1942 const_cast<char*>(kDefaultSupportedNPNProtocol)); | 1943 const_cast<char*>(kDefaultSupportedNPNProtocol)); |
| 1943 *outlen = arraysize(kDefaultSupportedNPNProtocol) - 1; | 1944 *outlen = arraysize(kDefaultSupportedNPNProtocol) - 1; |
| 1944 npn_status_ = kNextProtoUnsupported; | 1945 npn_status_ = kNextProtoUnsupported; |
| 1945 return SSL_TLSEXT_ERR_OK; | 1946 return SSL_TLSEXT_ERR_OK; |
| 1946 } | 1947 } |
| 1947 | 1948 |
| 1948 // Assume there's no overlap between our protocols and the server's list. | 1949 // Assume there's no overlap between our protocols and the server's list. |
| 1949 npn_status_ = kNextProtoNoOverlap; | 1950 npn_status_ = kNextProtoNoOverlap; |
| 1950 | 1951 |
| 1951 // For each protocol in server preference order, see if we support it. | 1952 // For each protocol in server preference order, see if we support it. |
| (...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2264 tb_was_negotiated_ = true; | 2265 tb_was_negotiated_ = true; |
| 2265 return 1; | 2266 return 1; |
| 2266 } | 2267 } |
| 2267 } | 2268 } |
| 2268 | 2269 |
| 2269 *out_alert_value = SSL_AD_ILLEGAL_PARAMETER; | 2270 *out_alert_value = SSL_AD_ILLEGAL_PARAMETER; |
| 2270 return 0; | 2271 return 0; |
| 2271 } | 2272 } |
| 2272 | 2273 |
| 2273 } // namespace net | 2274 } // namespace net |
| OLD | NEW |