| 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 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 138 sk_X509_push(stack.get(), x509.release()); | 138 sk_X509_push(stack.get(), x509.release()); |
| 139 } | 139 } |
| 140 return stack.Pass(); | 140 return stack.Pass(); |
| 141 } | 141 } |
| 142 | 142 |
| 143 int LogErrorCallback(const char* str, size_t len, void* context) { | 143 int LogErrorCallback(const char* str, size_t len, void* context) { |
| 144 LOG(ERROR) << base::StringPiece(str, len); | 144 LOG(ERROR) << base::StringPiece(str, len); |
| 145 return 1; | 145 return 1; |
| 146 } | 146 } |
| 147 | 147 |
| 148 bool IsOCSPStaplingSupported() { | |
| 149 #if defined(OS_WIN) | |
| 150 // CERT_OCSP_RESPONSE_PROP_ID is only implemented on Vista+, but it can be | |
| 151 // set on Windows XP without error. There is some overhead from the server | |
| 152 // sending the OCSP response if it supports the extension, for the subset of | |
| 153 // XP clients who will request it but be unable to use it, but this is an | |
| 154 // acceptable trade-off for simplicity of implementation. | |
| 155 return true; | |
| 156 #else | |
| 157 return false; | |
| 158 #endif | |
| 159 } | |
| 160 | |
| 161 } // namespace | 148 } // namespace |
| 162 | 149 |
| 163 class SSLClientSocketOpenSSL::SSLContext { | 150 class SSLClientSocketOpenSSL::SSLContext { |
| 164 public: | 151 public: |
| 165 static SSLContext* GetInstance() { return Singleton<SSLContext>::get(); } | 152 static SSLContext* GetInstance() { return Singleton<SSLContext>::get(); } |
| 166 SSL_CTX* ssl_ctx() { return ssl_ctx_.get(); } | 153 SSL_CTX* ssl_ctx() { return ssl_ctx_.get(); } |
| 167 SSLClientSessionCacheOpenSSL* session_cache() { return &session_cache_; } | 154 SSLClientSessionCacheOpenSSL* session_cache() { return &session_cache_; } |
| 168 | 155 |
| 169 SSLClientSocketOpenSSL* GetClientSocketFromSSL(const SSL* ssl) { | 156 SSLClientSocketOpenSSL* GetClientSocketFromSSL(const SSL* ssl) { |
| 170 DCHECK(ssl); | 157 DCHECK(ssl); |
| (...skipping 668 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 839 IsTLSVersionAdequateForHTTP2(ssl_config_)); | 826 IsTLSVersionAdequateForHTTP2(ssl_config_)); |
| 840 SSL_set_alpn_protos(ssl_, wire_protos.empty() ? NULL : &wire_protos[0], | 827 SSL_set_alpn_protos(ssl_, wire_protos.empty() ? NULL : &wire_protos[0], |
| 841 wire_protos.size()); | 828 wire_protos.size()); |
| 842 } | 829 } |
| 843 | 830 |
| 844 if (ssl_config_.signed_cert_timestamps_enabled) { | 831 if (ssl_config_.signed_cert_timestamps_enabled) { |
| 845 SSL_enable_signed_cert_timestamps(ssl_); | 832 SSL_enable_signed_cert_timestamps(ssl_); |
| 846 SSL_enable_ocsp_stapling(ssl_); | 833 SSL_enable_ocsp_stapling(ssl_); |
| 847 } | 834 } |
| 848 | 835 |
| 849 if (IsOCSPStaplingSupported()) | 836 if (cert_verifier_ && cert_verifier_->SupportsOCSPStapling()) |
| 850 SSL_enable_ocsp_stapling(ssl_); | 837 SSL_enable_ocsp_stapling(ssl_); |
| 851 | 838 |
| 852 // Enable fastradio padding. | 839 // Enable fastradio padding. |
| 853 SSL_enable_fastradio_padding(ssl_, | 840 SSL_enable_fastradio_padding(ssl_, |
| 854 ssl_config_.fastradio_padding_enabled && | 841 ssl_config_.fastradio_padding_enabled && |
| 855 ssl_config_.fastradio_padding_eligible); | 842 ssl_config_.fastradio_padding_eligible); |
| 856 | 843 |
| 857 return OK; | 844 return OK; |
| 858 } | 845 } |
| 859 | 846 |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 939 } | 926 } |
| 940 } | 927 } |
| 941 | 928 |
| 942 RecordChannelIDSupport(channel_id_service_, | 929 RecordChannelIDSupport(channel_id_service_, |
| 943 channel_id_xtn_negotiated_, | 930 channel_id_xtn_negotiated_, |
| 944 ssl_config_.channel_id_enabled, | 931 ssl_config_.channel_id_enabled, |
| 945 crypto::ECPrivateKey::IsSupported()); | 932 crypto::ECPrivateKey::IsSupported()); |
| 946 | 933 |
| 947 // Only record OCSP histograms if OCSP was requested. | 934 // Only record OCSP histograms if OCSP was requested. |
| 948 if (ssl_config_.signed_cert_timestamps_enabled || | 935 if (ssl_config_.signed_cert_timestamps_enabled || |
| 949 IsOCSPStaplingSupported()) { | 936 (cert_verifier_ && cert_verifier_->SupportsOCSPStapling())) { |
| 950 const uint8_t* ocsp_response; | 937 const uint8_t* ocsp_response; |
| 951 size_t ocsp_response_len; | 938 size_t ocsp_response_len; |
| 952 SSL_get0_ocsp_response(ssl_, &ocsp_response, &ocsp_response_len); | 939 SSL_get0_ocsp_response(ssl_, &ocsp_response, &ocsp_response_len); |
| 953 | 940 |
| 954 set_stapled_ocsp_response_received(ocsp_response_len != 0); | 941 set_stapled_ocsp_response_received(ocsp_response_len != 0); |
| 955 UMA_HISTOGRAM_BOOLEAN("Net.OCSPResponseStapled", ocsp_response_len != 0); | 942 UMA_HISTOGRAM_BOOLEAN("Net.OCSPResponseStapled", ocsp_response_len != 0); |
| 956 } | 943 } |
| 957 | 944 |
| 958 const uint8_t* sct_list; | 945 const uint8_t* sct_list; |
| 959 size_t sct_list_len; | 946 size_t sct_list_len; |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1078 server_cert_verify_result_.cert_status = CERT_STATUS_INVALID; | 1065 server_cert_verify_result_.cert_status = CERT_STATUS_INVALID; |
| 1079 return ERR_CERT_INVALID; | 1066 return ERR_CERT_INVALID; |
| 1080 } | 1067 } |
| 1081 | 1068 |
| 1082 if (!cert_verifier_) { | 1069 if (!cert_verifier_) { |
| 1083 // Without a CertVerifier, all certificates are invalid. | 1070 // Without a CertVerifier, all certificates are invalid. |
| 1084 server_cert_verify_result_.cert_status = CERT_STATUS_INVALID; | 1071 server_cert_verify_result_.cert_status = CERT_STATUS_INVALID; |
| 1085 return ERR_CERT_INVALID; | 1072 return ERR_CERT_INVALID; |
| 1086 } | 1073 } |
| 1087 | 1074 |
| 1075 std::string ocsp_response; |
| 1076 if (cert_verifier_ && cert_verifier_->SupportsOCSPStapling()) { |
| 1077 const uint8_t* ocsp_response_raw; |
| 1078 size_t ocsp_response_len; |
| 1079 SSL_get0_ocsp_response(ssl_, &ocsp_response_raw, &ocsp_response_len); |
| 1080 ocsp_response.assign(reinterpret_cast<const char*>(ocsp_response_raw), |
| 1081 ocsp_response_len); |
| 1082 } |
| 1083 |
| 1088 start_cert_verification_time_ = base::TimeTicks::Now(); | 1084 start_cert_verification_time_ = base::TimeTicks::Now(); |
| 1089 | 1085 |
| 1090 int flags = 0; | 1086 int flags = 0; |
| 1091 if (ssl_config_.rev_checking_enabled) | 1087 if (ssl_config_.rev_checking_enabled) |
| 1092 flags |= CertVerifier::VERIFY_REV_CHECKING_ENABLED; | 1088 flags |= CertVerifier::VERIFY_REV_CHECKING_ENABLED; |
| 1093 if (ssl_config_.verify_ev_cert) | 1089 if (ssl_config_.verify_ev_cert) |
| 1094 flags |= CertVerifier::VERIFY_EV_CERT; | 1090 flags |= CertVerifier::VERIFY_EV_CERT; |
| 1095 if (ssl_config_.cert_io_enabled) | 1091 if (ssl_config_.cert_io_enabled) |
| 1096 flags |= CertVerifier::VERIFY_CERT_IO_ENABLED; | 1092 flags |= CertVerifier::VERIFY_CERT_IO_ENABLED; |
| 1097 if (ssl_config_.rev_checking_required_local_anchors) | 1093 if (ssl_config_.rev_checking_required_local_anchors) |
| 1098 flags |= CertVerifier::VERIFY_REV_CHECKING_REQUIRED_LOCAL_ANCHORS; | 1094 flags |= CertVerifier::VERIFY_REV_CHECKING_REQUIRED_LOCAL_ANCHORS; |
| 1099 verifier_.reset(new SingleRequestCertVerifier(cert_verifier_)); | 1095 verifier_.reset(new SingleRequestCertVerifier(cert_verifier_)); |
| 1100 return verifier_->Verify( | 1096 return verifier_->Verify( |
| 1101 server_cert_.get(), | 1097 server_cert_.get(), host_and_port_.host(), ocsp_response, flags, |
| 1102 host_and_port_.host(), | |
| 1103 flags, | |
| 1104 // TODO(davidben): Route the CRLSet through SSLConfig so | 1098 // TODO(davidben): Route the CRLSet through SSLConfig so |
| 1105 // SSLClientSocket doesn't depend on SSLConfigService. | 1099 // SSLClientSocket doesn't depend on SSLConfigService. |
| 1106 SSLConfigService::GetCRLSet().get(), | 1100 SSLConfigService::GetCRLSet().get(), &server_cert_verify_result_, |
| 1107 &server_cert_verify_result_, | |
| 1108 base::Bind(&SSLClientSocketOpenSSL::OnHandshakeIOComplete, | 1101 base::Bind(&SSLClientSocketOpenSSL::OnHandshakeIOComplete, |
| 1109 base::Unretained(this)), | 1102 base::Unretained(this)), |
| 1110 net_log_); | 1103 net_log_); |
| 1111 } | 1104 } |
| 1112 | 1105 |
| 1113 int SSLClientSocketOpenSSL::DoVerifyCertComplete(int result) { | 1106 int SSLClientSocketOpenSSL::DoVerifyCertComplete(int result) { |
| 1114 verifier_.reset(); | 1107 verifier_.reset(); |
| 1115 | 1108 |
| 1116 if (!start_cert_verification_time_.is_null()) { | 1109 if (!start_cert_verification_time_.is_null()) { |
| 1117 base::TimeDelta verify_time = | 1110 base::TimeDelta verify_time = |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1173 } | 1166 } |
| 1174 | 1167 |
| 1175 void SSLClientSocketOpenSSL::UpdateServerCert() { | 1168 void SSLClientSocketOpenSSL::UpdateServerCert() { |
| 1176 server_cert_chain_->Reset(SSL_get_peer_cert_chain(ssl_)); | 1169 server_cert_chain_->Reset(SSL_get_peer_cert_chain(ssl_)); |
| 1177 server_cert_ = server_cert_chain_->AsOSChain(); | 1170 server_cert_ = server_cert_chain_->AsOSChain(); |
| 1178 if (server_cert_.get()) { | 1171 if (server_cert_.get()) { |
| 1179 net_log_.AddEvent( | 1172 net_log_.AddEvent( |
| 1180 NetLog::TYPE_SSL_CERTIFICATES_RECEIVED, | 1173 NetLog::TYPE_SSL_CERTIFICATES_RECEIVED, |
| 1181 base::Bind(&NetLogX509CertificateCallback, | 1174 base::Bind(&NetLogX509CertificateCallback, |
| 1182 base::Unretained(server_cert_.get()))); | 1175 base::Unretained(server_cert_.get()))); |
| 1183 | |
| 1184 // TODO(rsleevi): Plumb an OCSP response into the Mac system library and | |
| 1185 // update IsOCSPStaplingSupported for Mac. https://crbug.com/430714 | |
| 1186 if (IsOCSPStaplingSupported()) { | |
| 1187 #if defined(OS_WIN) | |
| 1188 const uint8_t* ocsp_response_raw; | |
| 1189 size_t ocsp_response_len; | |
| 1190 SSL_get0_ocsp_response(ssl_, &ocsp_response_raw, &ocsp_response_len); | |
| 1191 | |
| 1192 CRYPT_DATA_BLOB ocsp_response_blob; | |
| 1193 ocsp_response_blob.cbData = ocsp_response_len; | |
| 1194 ocsp_response_blob.pbData = const_cast<BYTE*>(ocsp_response_raw); | |
| 1195 BOOL ok = CertSetCertificateContextProperty( | |
| 1196 server_cert_->os_cert_handle(), | |
| 1197 CERT_OCSP_RESPONSE_PROP_ID, | |
| 1198 CERT_SET_PROPERTY_IGNORE_PERSIST_ERROR_FLAG, | |
| 1199 &ocsp_response_blob); | |
| 1200 if (!ok) { | |
| 1201 VLOG(1) << "Failed to set OCSP response property: " | |
| 1202 << GetLastError(); | |
| 1203 } | |
| 1204 #else | |
| 1205 // TODO(davidben): Support OCSP stapling when NSS is the system | |
| 1206 // certificate verifier. https://crbug.com/479034. | |
| 1207 NOTREACHED(); | |
| 1208 #endif | |
| 1209 } | |
| 1210 } | 1176 } |
| 1211 } | 1177 } |
| 1212 | 1178 |
| 1213 void SSLClientSocketOpenSSL::VerifyCT() { | 1179 void SSLClientSocketOpenSSL::VerifyCT() { |
| 1214 if (!cert_transparency_verifier_) | 1180 if (!cert_transparency_verifier_) |
| 1215 return; | 1181 return; |
| 1216 | 1182 |
| 1217 const uint8_t* ocsp_response_raw; | 1183 const uint8_t* ocsp_response_raw; |
| 1218 size_t ocsp_response_len; | 1184 size_t ocsp_response_len; |
| 1219 SSL_get0_ocsp_response(ssl_, &ocsp_response_raw, &ocsp_response_len); | 1185 SSL_get0_ocsp_response(ssl_, &ocsp_response_raw, &ocsp_response_len); |
| (...skipping 704 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1924 | 1890 |
| 1925 return result; | 1891 return result; |
| 1926 } | 1892 } |
| 1927 | 1893 |
| 1928 scoped_refptr<X509Certificate> | 1894 scoped_refptr<X509Certificate> |
| 1929 SSLClientSocketOpenSSL::GetUnverifiedServerCertificateChain() const { | 1895 SSLClientSocketOpenSSL::GetUnverifiedServerCertificateChain() const { |
| 1930 return server_cert_; | 1896 return server_cert_; |
| 1931 } | 1897 } |
| 1932 | 1898 |
| 1933 } // namespace net | 1899 } // namespace net |
| OLD | NEW |