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 770 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
781 | 781 |
782 // Removing ciphers by ID from OpenSSL is a bit involved as we must use the | 782 // Removing ciphers by ID from OpenSSL is a bit involved as we must use the |
783 // textual name with SSL_set_cipher_list because there is no public API to | 783 // textual name with SSL_set_cipher_list because there is no public API to |
784 // directly remove a cipher by ID. | 784 // directly remove a cipher by ID. |
785 STACK_OF(SSL_CIPHER)* ciphers = SSL_get_ciphers(ssl_); | 785 STACK_OF(SSL_CIPHER)* ciphers = SSL_get_ciphers(ssl_); |
786 DCHECK(ciphers); | 786 DCHECK(ciphers); |
787 // See SSLConfig::disabled_cipher_suites for description of the suites | 787 // See SSLConfig::disabled_cipher_suites for description of the suites |
788 // disabled by default. Note that !SHA256 and !SHA384 only remove HMAC-SHA256 | 788 // disabled by default. Note that !SHA256 and !SHA384 only remove HMAC-SHA256 |
789 // and HMAC-SHA384 cipher suites, not GCM cipher suites with SHA256 or SHA384 | 789 // and HMAC-SHA384 cipher suites, not GCM cipher suites with SHA256 or SHA384 |
790 // as the handshake hash. | 790 // as the handshake hash. |
791 std::string command("DEFAULT:!NULL:!aNULL:!IDEA:!FZA:!SRP:!SHA256:!SHA384:" | 791 std::string command( |
792 "!aECDH:!AESGCM+AES256"); | 792 "DEFAULT:!NULL:!aNULL:!SHA256:!SHA384:!aECDH:!AESGCM+AES256:!aPSK"); |
793 // Walk through all the installed ciphers, seeing if any need to be | 793 // Walk through all the installed ciphers, seeing if any need to be |
794 // appended to the cipher removal |command|. | 794 // appended to the cipher removal |command|. |
795 for (size_t i = 0; i < sk_SSL_CIPHER_num(ciphers); ++i) { | 795 for (size_t i = 0; i < sk_SSL_CIPHER_num(ciphers); ++i) { |
796 const SSL_CIPHER* cipher = sk_SSL_CIPHER_value(ciphers, i); | 796 const SSL_CIPHER* cipher = sk_SSL_CIPHER_value(ciphers, i); |
797 const uint16 id = static_cast<uint16>(SSL_CIPHER_get_id(cipher)); | 797 const uint16 id = static_cast<uint16>(SSL_CIPHER_get_id(cipher)); |
798 // Remove any ciphers with a strength of less than 80 bits. Note the NSS | 798 // Remove any ciphers with a strength of less than 80 bits. Note the NSS |
799 // implementation uses "effective" bits here but OpenSSL does not provide | 799 // implementation uses "effective" bits here but OpenSSL does not provide |
800 // this detail. This only impacts Triple DES: reports 112 vs. 168 bits, | 800 // this detail. This only impacts Triple DES: reports 112 vs. 168 bits, |
801 // both of which are greater than 80 anyway. | 801 // both of which are greater than 80 anyway. |
802 bool disable = SSL_CIPHER_get_bits(cipher, NULL) < 80; | 802 bool disable = SSL_CIPHER_get_bits(cipher, NULL) < 80; |
(...skipping 28 matching lines...) Expand all Loading... |
831 | 831 |
832 if (ssl_config_.version_fallback) | 832 if (ssl_config_.version_fallback) |
833 SSL_enable_fallback_scsv(ssl_); | 833 SSL_enable_fallback_scsv(ssl_); |
834 | 834 |
835 // TLS channel ids. | 835 // TLS channel ids. |
836 if (IsChannelIDEnabled(ssl_config_, channel_id_service_)) { | 836 if (IsChannelIDEnabled(ssl_config_, channel_id_service_)) { |
837 SSL_enable_tls_channel_id(ssl_); | 837 SSL_enable_tls_channel_id(ssl_); |
838 } | 838 } |
839 | 839 |
840 if (!ssl_config_.next_protos.empty()) { | 840 if (!ssl_config_.next_protos.empty()) { |
| 841 // Get list of ciphers that are enabled. |
| 842 STACK_OF(SSL_CIPHER)* enabled_ciphers = SSL_get_ciphers(ssl_); |
| 843 DCHECK(enabled_ciphers); |
| 844 std::vector<uint16> enabled_ciphers_vector; |
| 845 for (size_t i = 0; i < sk_SSL_CIPHER_num(enabled_ciphers); ++i) { |
| 846 const SSL_CIPHER* cipher = sk_SSL_CIPHER_value(enabled_ciphers, i); |
| 847 const uint16 id = static_cast<uint16>(SSL_CIPHER_get_id(cipher)); |
| 848 enabled_ciphers_vector.push_back(id); |
| 849 } |
| 850 |
841 std::vector<uint8_t> wire_protos = | 851 std::vector<uint8_t> wire_protos = |
842 SerializeNextProtos(ssl_config_.next_protos); | 852 SerializeNextProtos(ssl_config_.next_protos, |
| 853 HasCipherAdequateForHTTP2(enabled_ciphers_vector) && |
| 854 IsTLSVersionAdequateForHTTP2(ssl_config_)); |
843 SSL_set_alpn_protos(ssl_, wire_protos.empty() ? NULL : &wire_protos[0], | 855 SSL_set_alpn_protos(ssl_, wire_protos.empty() ? NULL : &wire_protos[0], |
844 wire_protos.size()); | 856 wire_protos.size()); |
845 } | 857 } |
846 | 858 |
847 if (ssl_config_.signed_cert_timestamps_enabled) { | 859 if (ssl_config_.signed_cert_timestamps_enabled) { |
848 SSL_enable_signed_cert_timestamps(ssl_); | 860 SSL_enable_signed_cert_timestamps(ssl_); |
849 SSL_enable_ocsp_stapling(ssl_); | 861 SSL_enable_ocsp_stapling(ssl_); |
850 } | 862 } |
851 | 863 |
852 if (IsOCSPStaplingSupported()) | 864 if (IsOCSPStaplingSupported()) |
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1124 if (!start_cert_verification_time_.is_null()) { | 1136 if (!start_cert_verification_time_.is_null()) { |
1125 base::TimeDelta verify_time = | 1137 base::TimeDelta verify_time = |
1126 base::TimeTicks::Now() - start_cert_verification_time_; | 1138 base::TimeTicks::Now() - start_cert_verification_time_; |
1127 if (result == OK) { | 1139 if (result == OK) { |
1128 UMA_HISTOGRAM_TIMES("Net.SSLCertVerificationTime", verify_time); | 1140 UMA_HISTOGRAM_TIMES("Net.SSLCertVerificationTime", verify_time); |
1129 } else { | 1141 } else { |
1130 UMA_HISTOGRAM_TIMES("Net.SSLCertVerificationTimeError", verify_time); | 1142 UMA_HISTOGRAM_TIMES("Net.SSLCertVerificationTimeError", verify_time); |
1131 } | 1143 } |
1132 } | 1144 } |
1133 | 1145 |
1134 if (result == OK) | 1146 if (result == OK) { |
1135 RecordConnectionTypeMetrics(GetNetSSLVersion(ssl_)); | 1147 RecordConnectionTypeMetrics(GetNetSSLVersion(ssl_)); |
1136 | 1148 |
| 1149 if (SSL_session_reused(ssl_)) { |
| 1150 // Record whether or not the server tried to resume a session for a |
| 1151 // different version. See https://crbug.com/441456. |
| 1152 UMA_HISTOGRAM_BOOLEAN( |
| 1153 "Net.SSLSessionVersionMatch", |
| 1154 SSL_version(ssl_) == SSL_get_session(ssl_)->ssl_version); |
| 1155 } |
| 1156 } |
| 1157 |
1137 const CertStatus cert_status = server_cert_verify_result_.cert_status; | 1158 const CertStatus cert_status = server_cert_verify_result_.cert_status; |
1138 if (transport_security_state_ && | 1159 if (transport_security_state_ && |
1139 (result == OK || | 1160 (result == OK || |
1140 (IsCertificateError(result) && IsCertStatusMinorError(cert_status))) && | 1161 (IsCertificateError(result) && IsCertStatusMinorError(cert_status))) && |
1141 !transport_security_state_->CheckPublicKeyPins( | 1162 !transport_security_state_->CheckPublicKeyPins( |
1142 host_and_port_.host(), | 1163 host_and_port_.host(), |
1143 server_cert_verify_result_.is_issued_by_known_root, | 1164 server_cert_verify_result_.is_issued_by_known_root, |
1144 server_cert_verify_result_.public_key_hashes, | 1165 server_cert_verify_result_.public_key_hashes, |
1145 &pinning_failure_log_)) { | 1166 &pinning_failure_log_)) { |
1146 result = ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN; | 1167 result = ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN; |
(...skipping 628 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1775 *outlen = arraysize(kDefaultSupportedNPNProtocol) - 1; | 1796 *outlen = arraysize(kDefaultSupportedNPNProtocol) - 1; |
1776 npn_status_ = kNextProtoUnsupported; | 1797 npn_status_ = kNextProtoUnsupported; |
1777 return SSL_TLSEXT_ERR_OK; | 1798 return SSL_TLSEXT_ERR_OK; |
1778 } | 1799 } |
1779 | 1800 |
1780 // Assume there's no overlap between our protocols and the server's list. | 1801 // Assume there's no overlap between our protocols and the server's list. |
1781 npn_status_ = kNextProtoNoOverlap; | 1802 npn_status_ = kNextProtoNoOverlap; |
1782 | 1803 |
1783 // For each protocol in server preference order, see if we support it. | 1804 // For each protocol in server preference order, see if we support it. |
1784 for (unsigned int i = 0; i < inlen; i += in[i] + 1) { | 1805 for (unsigned int i = 0; i < inlen; i += in[i] + 1) { |
1785 for (std::vector<std::string>::const_iterator | 1806 for (NextProto next_proto : ssl_config_.next_protos) { |
1786 j = ssl_config_.next_protos.begin(); | 1807 const std::string proto = NextProtoToString(next_proto); |
1787 j != ssl_config_.next_protos.end(); ++j) { | 1808 if (in[i] == proto.size() && |
1788 if (in[i] == j->size() && | 1809 memcmp(&in[i + 1], proto.data(), in[i]) == 0) { |
1789 memcmp(&in[i + 1], j->data(), in[i]) == 0) { | |
1790 // We found a match. | 1810 // We found a match. |
1791 *out = const_cast<unsigned char*>(in) + i + 1; | 1811 *out = const_cast<unsigned char*>(in) + i + 1; |
1792 *outlen = in[i]; | 1812 *outlen = in[i]; |
1793 npn_status_ = kNextProtoNegotiated; | 1813 npn_status_ = kNextProtoNegotiated; |
1794 break; | 1814 break; |
1795 } | 1815 } |
1796 } | 1816 } |
1797 if (npn_status_ == kNextProtoNegotiated) | 1817 if (npn_status_ == kNextProtoNegotiated) |
1798 break; | 1818 break; |
1799 } | 1819 } |
1800 | 1820 |
1801 // If we didn't find a protocol, we select the first one from our list. | 1821 // If we didn't find a protocol, we select the first one from our list. |
1802 if (npn_status_ == kNextProtoNoOverlap) { | 1822 if (npn_status_ == kNextProtoNoOverlap) { |
1803 *out = reinterpret_cast<uint8*>(const_cast<char*>( | 1823 const std::string proto = NextProtoToString(ssl_config_.next_protos[0]); |
1804 ssl_config_.next_protos[0].data())); | 1824 *out = reinterpret_cast<uint8*>(const_cast<char*>(proto.data())); |
1805 *outlen = ssl_config_.next_protos[0].size(); | 1825 *outlen = proto.size(); |
1806 } | 1826 } |
1807 | 1827 |
1808 npn_proto_.assign(reinterpret_cast<const char*>(*out), *outlen); | 1828 npn_proto_.assign(reinterpret_cast<const char*>(*out), *outlen); |
1809 DVLOG(2) << "next protocol: '" << npn_proto_ << "' status: " << npn_status_; | 1829 DVLOG(2) << "next protocol: '" << npn_proto_ << "' status: " << npn_status_; |
1810 set_negotiation_extension(kExtensionNPN); | 1830 set_negotiation_extension(kExtensionNPN); |
1811 return SSL_TLSEXT_ERR_OK; | 1831 return SSL_TLSEXT_ERR_OK; |
1812 } | 1832 } |
1813 | 1833 |
1814 long SSLClientSocketOpenSSL::MaybeReplayTransportError( | 1834 long SSLClientSocketOpenSSL::MaybeReplayTransportError( |
1815 BIO *bio, | 1835 BIO *bio, |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1903 ct::SCT_STATUS_LOG_UNKNOWN)); | 1923 ct::SCT_STATUS_LOG_UNKNOWN)); |
1904 } | 1924 } |
1905 } | 1925 } |
1906 | 1926 |
1907 scoped_refptr<X509Certificate> | 1927 scoped_refptr<X509Certificate> |
1908 SSLClientSocketOpenSSL::GetUnverifiedServerCertificateChain() const { | 1928 SSLClientSocketOpenSSL::GetUnverifiedServerCertificateChain() const { |
1909 return server_cert_; | 1929 return server_cert_; |
1910 } | 1930 } |
1911 | 1931 |
1912 } // namespace net | 1932 } // namespace net |
OLD | NEW |