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/err.h> | 12 #include <openssl/err.h> |
13 #include <openssl/ssl.h> | 13 #include <openssl/ssl.h> |
14 | 14 |
15 #include "base/bind.h" | 15 #include "base/bind.h" |
16 #include "base/callback_helpers.h" | 16 #include "base/callback_helpers.h" |
17 #include "base/environment.h" | 17 #include "base/environment.h" |
18 #include "base/memory/singleton.h" | 18 #include "base/memory/singleton.h" |
19 #include "base/metrics/histogram.h" | 19 #include "base/metrics/histogram.h" |
20 #include "base/strings/string_piece.h" | 20 #include "base/strings/string_piece.h" |
21 #include "base/strings/string_util.h" | |
21 #include "base/synchronization/lock.h" | 22 #include "base/synchronization/lock.h" |
22 #include "crypto/ec_private_key.h" | 23 #include "crypto/ec_private_key.h" |
23 #include "crypto/openssl_util.h" | 24 #include "crypto/openssl_util.h" |
24 #include "crypto/scoped_openssl_types.h" | 25 #include "crypto/scoped_openssl_types.h" |
25 #include "net/base/net_errors.h" | 26 #include "net/base/net_errors.h" |
26 #include "net/cert/cert_verifier.h" | 27 #include "net/cert/cert_verifier.h" |
27 #include "net/cert/ct_verifier.h" | 28 #include "net/cert/ct_verifier.h" |
28 #include "net/cert/single_request_cert_verifier.h" | 29 #include "net/cert/single_request_cert_verifier.h" |
29 #include "net/cert/x509_certificate_net_log_param.h" | 30 #include "net/cert/x509_certificate_net_log_param.h" |
30 #include "net/http/transport_security_state.h" | 31 #include "net/http/transport_security_state.h" |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
127 ScopedX509Stack stack(sk_X509_new_null()); | 128 ScopedX509Stack stack(sk_X509_new_null()); |
128 for (size_t i = 0; i < os_handles.size(); i++) { | 129 for (size_t i = 0; i < os_handles.size(); i++) { |
129 ScopedX509 x509 = OSCertHandleToOpenSSL(os_handles[i]); | 130 ScopedX509 x509 = OSCertHandleToOpenSSL(os_handles[i]); |
130 if (!x509) | 131 if (!x509) |
131 return ScopedX509Stack(); | 132 return ScopedX509Stack(); |
132 sk_X509_push(stack.get(), x509.release()); | 133 sk_X509_push(stack.get(), x509.release()); |
133 } | 134 } |
134 return stack.Pass(); | 135 return stack.Pass(); |
135 } | 136 } |
136 | 137 |
138 // DER-encodes an OpenSSL X509 structure. Returns true on success. | |
139 bool GetDEREncodedX509(X509* x509, std::string* out_der) { | |
Ryan Sleevi
2014/09/18 01:34:39
This seems to defeat the purpose of https://code.g
davidben
2014/09/18 19:40:06
Hrm, that's a thought. It does bother me that we h
| |
140 int len = i2d_X509(x509, NULL); | |
141 if (len < 0) | |
142 return false; | |
143 | |
144 uint8_t* ptr = reinterpret_cast<uint8_t*>(WriteInto(out_der, len + 1)); | |
145 if (i2d_X509(x509, &ptr) < 0) { | |
146 NOTREACHED(); | |
147 out_der->clear(); | |
148 return false; | |
149 } | |
150 return true; | |
151 } | |
152 | |
137 int LogErrorCallback(const char* str, size_t len, void* context) { | 153 int LogErrorCallback(const char* str, size_t len, void* context) { |
138 LOG(ERROR) << base::StringPiece(str, len); | 154 LOG(ERROR) << base::StringPiece(str, len); |
139 return 1; | 155 return 1; |
140 } | 156 } |
141 | 157 |
142 } // namespace | 158 } // namespace |
143 | 159 |
144 class SSLClientSocketOpenSSL::SSLContext { | 160 class SSLClientSocketOpenSSL::SSLContext { |
145 public: | 161 public: |
146 static SSLContext* GetInstance() { return Singleton<SSLContext>::get(); } | 162 static SSLContext* GetInstance() { return Singleton<SSLContext>::get(); } |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
244 ~PeerCertificateChain() {} | 260 ~PeerCertificateChain() {} |
245 PeerCertificateChain& operator=(const PeerCertificateChain& other); | 261 PeerCertificateChain& operator=(const PeerCertificateChain& other); |
246 | 262 |
247 // Resets the PeerCertificateChain to the set of certificates in|chain|, | 263 // Resets the PeerCertificateChain to the set of certificates in|chain|, |
248 // which may be NULL, indicating to empty the store certificates. | 264 // which may be NULL, indicating to empty the store certificates. |
249 // Note: If an error occurs, such as being unable to parse the certificates, | 265 // Note: If an error occurs, such as being unable to parse the certificates, |
250 // this will behave as if Reset(NULL) was called. | 266 // this will behave as if Reset(NULL) was called. |
251 void Reset(STACK_OF(X509)* chain); | 267 void Reset(STACK_OF(X509)* chain); |
252 | 268 |
253 // Note that when USE_OPENSSL is defined, OSCertHandle is X509* | 269 // Note that when USE_OPENSSL is defined, OSCertHandle is X509* |
254 const scoped_refptr<X509Certificate>& AsOSChain() const { return os_chain_; } | 270 scoped_refptr<X509Certificate> AsOSChain() const; |
255 | 271 |
256 size_t size() const { | 272 size_t size() const { |
257 if (!openssl_chain_.get()) | 273 if (!openssl_chain_.get()) |
258 return 0; | 274 return 0; |
259 return sk_X509_num(openssl_chain_.get()); | 275 return sk_X509_num(openssl_chain_.get()); |
260 } | 276 } |
261 | 277 |
262 X509* operator[](size_t index) const { | 278 X509* Get(size_t index) const { |
263 DCHECK_LT(index, size()); | 279 DCHECK_LT(index, size()); |
264 return sk_X509_value(openssl_chain_.get(), index); | 280 return sk_X509_value(openssl_chain_.get(), index); |
265 } | 281 } |
266 | 282 |
267 bool IsValid() { return os_chain_.get() && openssl_chain_.get(); } | |
268 | |
269 private: | 283 private: |
270 ScopedX509Stack openssl_chain_; | 284 ScopedX509Stack openssl_chain_; |
271 | |
272 scoped_refptr<X509Certificate> os_chain_; | |
273 }; | 285 }; |
274 | 286 |
275 SSLClientSocketOpenSSL::PeerCertificateChain& | 287 SSLClientSocketOpenSSL::PeerCertificateChain& |
276 SSLClientSocketOpenSSL::PeerCertificateChain::operator=( | 288 SSLClientSocketOpenSSL::PeerCertificateChain::operator=( |
277 const PeerCertificateChain& other) { | 289 const PeerCertificateChain& other) { |
278 if (this == &other) | 290 if (this == &other) |
279 return *this; | 291 return *this; |
280 | 292 |
281 // os_chain_ is reference counted by scoped_refptr; | |
282 os_chain_ = other.os_chain_; | |
283 | |
284 openssl_chain_.reset(X509_chain_up_ref(other.openssl_chain_.get())); | 293 openssl_chain_.reset(X509_chain_up_ref(other.openssl_chain_.get())); |
285 | |
286 return *this; | 294 return *this; |
287 } | 295 } |
288 | 296 |
289 #if defined(USE_OPENSSL_CERTS) | |
290 // When OSCertHandle is typedef'ed to X509, this implementation does a short cut | |
291 // to avoid converting back and forth between der and X509 struct. | |
292 void SSLClientSocketOpenSSL::PeerCertificateChain::Reset( | 297 void SSLClientSocketOpenSSL::PeerCertificateChain::Reset( |
293 STACK_OF(X509)* chain) { | 298 STACK_OF(X509)* chain) { |
Ryan Sleevi
2014/09/18 01:34:39
You (accidentally?) nuked a NULL check & ability t
davidben
2014/09/18 19:40:06
I checked and X509_chain_up_ref will handle a NULL
| |
294 openssl_chain_.reset(NULL); | |
295 os_chain_ = NULL; | |
296 | |
297 if (!chain) | |
298 return; | |
299 | |
300 X509Certificate::OSCertHandles intermediates; | |
301 for (size_t i = 1; i < sk_X509_num(chain); ++i) | |
302 intermediates.push_back(sk_X509_value(chain, i)); | |
303 | |
304 os_chain_ = | |
305 X509Certificate::CreateFromHandle(sk_X509_value(chain, 0), intermediates); | |
306 | |
307 openssl_chain_.reset(X509_chain_up_ref(chain)); | 299 openssl_chain_.reset(X509_chain_up_ref(chain)); |
308 } | 300 } |
309 #else // !defined(USE_OPENSSL_CERTS) | |
310 void SSLClientSocketOpenSSL::PeerCertificateChain::Reset( | |
311 STACK_OF(X509)* chain) { | |
312 openssl_chain_.reset(NULL); | |
313 os_chain_ = NULL; | |
314 | 301 |
315 if (!chain) | 302 scoped_refptr<X509Certificate> |
316 return; | 303 SSLClientSocketOpenSSL::PeerCertificateChain::AsOSChain() const { |
304 #if defined(USE_OPENSSL_CERTS) | |
305 // When OSCertHandle is typedef'ed to X509, this implementation does a short | |
306 // cut to avoid converting back and forth between DER and the X509 struct. | |
307 X509Certificate::OSCertHandles intermediates; | |
308 for (size_t i = 1; i < sk_X509_num(openssl_chain_.get()); ++i) { | |
309 intermediates.push_back(sk_X509_value(openssl_chain_.get(), i)); | |
310 } | |
317 | 311 |
318 openssl_chain_.reset(X509_chain_up_ref(chain)); | 312 return make_scoped_refptr(X509Certificate::CreateFromHandle( |
319 | 313 sk_X509_value(openssl_chain_.get(), 0), intermediates)); |
314 #else | |
315 // DER-encode the chain and convert to a platform certificate handle. | |
320 std::vector<base::StringPiece> der_chain; | 316 std::vector<base::StringPiece> der_chain; |
317 std::vector<std::string> storage(sk_X509_num(openssl_chain_.get())); | |
321 for (size_t i = 0; i < sk_X509_num(openssl_chain_.get()); ++i) { | 318 for (size_t i = 0; i < sk_X509_num(openssl_chain_.get()); ++i) { |
322 X509* x = sk_X509_value(openssl_chain_.get(), i); | 319 X509* x = sk_X509_value(openssl_chain_.get(), i); |
323 | 320 if (!GetDEREncodedX509(x, &storage[i])) |
324 unsigned char* cert_data = NULL; | 321 return NULL; |
325 int cert_data_length = i2d_X509(x, &cert_data); | 322 der_chain.push_back(base::StringPiece(storage[i])); |
326 if (cert_data_length && cert_data) | |
327 der_chain.push_back(base::StringPiece(reinterpret_cast<char*>(cert_data), | |
328 cert_data_length)); | |
329 } | 323 } |
330 | 324 |
331 os_chain_ = X509Certificate::CreateFromDERCertChain(der_chain); | 325 return make_scoped_refptr(X509Certificate::CreateFromDERCertChain(der_chain)); |
332 | 326 #endif |
333 for (size_t i = 0; i < der_chain.size(); ++i) { | |
334 OPENSSL_free(const_cast<char*>(der_chain[i].data())); | |
335 } | |
336 | |
337 if (der_chain.size() != | |
338 static_cast<size_t>(sk_X509_num(openssl_chain_.get()))) { | |
339 openssl_chain_.reset(NULL); | |
340 os_chain_ = NULL; | |
341 } | |
342 } | 327 } |
343 #endif // defined(USE_OPENSSL_CERTS) | |
344 | 328 |
345 // static | 329 // static |
346 SSLSessionCacheOpenSSL::Config | 330 SSLSessionCacheOpenSSL::Config |
347 SSLClientSocketOpenSSL::SSLContext::kDefaultSessionCacheConfig = { | 331 SSLClientSocketOpenSSL::SSLContext::kDefaultSessionCacheConfig = { |
348 &GetSessionCacheKey, // key_func | 332 &GetSessionCacheKey, // key_func |
349 1024, // max_entries | 333 1024, // max_entries |
350 256, // expiration_check_count | 334 256, // expiration_check_count |
351 60 * 60, // timeout_seconds | 335 60 * 60, // timeout_seconds |
352 }; | 336 }; |
353 | 337 |
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
606 bool SSLClientSocketOpenSSL::UsingTCPFastOpen() const { | 590 bool SSLClientSocketOpenSSL::UsingTCPFastOpen() const { |
607 if (transport_.get() && transport_->socket()) | 591 if (transport_.get() && transport_->socket()) |
608 return transport_->socket()->UsingTCPFastOpen(); | 592 return transport_->socket()->UsingTCPFastOpen(); |
609 | 593 |
610 NOTREACHED(); | 594 NOTREACHED(); |
611 return false; | 595 return false; |
612 } | 596 } |
613 | 597 |
614 bool SSLClientSocketOpenSSL::GetSSLInfo(SSLInfo* ssl_info) { | 598 bool SSLClientSocketOpenSSL::GetSSLInfo(SSLInfo* ssl_info) { |
615 ssl_info->Reset(); | 599 ssl_info->Reset(); |
616 if (!server_cert_.get()) | 600 if (server_cert_chain_->size() == 0) |
617 return false; | 601 return false; |
618 | 602 |
619 ssl_info->cert = server_cert_verify_result_.verified_cert; | 603 ssl_info->cert = server_cert_verify_result_.verified_cert; |
620 ssl_info->cert_status = server_cert_verify_result_.cert_status; | 604 ssl_info->cert_status = server_cert_verify_result_.cert_status; |
621 ssl_info->is_issued_by_known_root = | 605 ssl_info->is_issued_by_known_root = |
622 server_cert_verify_result_.is_issued_by_known_root; | 606 server_cert_verify_result_.is_issued_by_known_root; |
623 ssl_info->public_key_hashes = | 607 ssl_info->public_key_hashes = |
624 server_cert_verify_result_.public_key_hashes; | 608 server_cert_verify_result_.public_key_hashes; |
625 ssl_info->client_cert_sent = | 609 ssl_info->client_cert_sent = |
626 ssl_config_.send_client_cert && ssl_config_.client_cert.get(); | 610 ssl_config_.send_client_cert && ssl_config_.client_cert.get(); |
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
954 size_t ocsp_response_len; | 938 size_t ocsp_response_len; |
955 SSL_get0_ocsp_response(ssl_, &ocsp_response, &ocsp_response_len); | 939 SSL_get0_ocsp_response(ssl_, &ocsp_response, &ocsp_response_len); |
956 set_stapled_ocsp_response_received(ocsp_response_len != 0); | 940 set_stapled_ocsp_response_received(ocsp_response_len != 0); |
957 | 941 |
958 uint8_t* sct_list; | 942 uint8_t* sct_list; |
959 size_t sct_list_len; | 943 size_t sct_list_len; |
960 SSL_get0_signed_cert_timestamp_list(ssl_, &sct_list, &sct_list_len); | 944 SSL_get0_signed_cert_timestamp_list(ssl_, &sct_list, &sct_list_len); |
961 set_signed_cert_timestamps_received(sct_list_len != 0); | 945 set_signed_cert_timestamps_received(sct_list_len != 0); |
962 | 946 |
963 // Verify the certificate. | 947 // Verify the certificate. |
964 const bool got_cert = !!UpdateServerCert(); | 948 UpdateServerCert(); |
965 DCHECK(got_cert); | |
966 net_log_.AddEvent( | |
967 NetLog::TYPE_SSL_CERTIFICATES_RECEIVED, | |
968 base::Bind(&NetLogX509CertificateCallback, | |
969 base::Unretained(server_cert_.get()))); | |
970 GotoState(STATE_VERIFY_CERT); | 949 GotoState(STATE_VERIFY_CERT); |
971 } else { | 950 } else { |
972 int ssl_error = SSL_get_error(ssl_, rv); | 951 int ssl_error = SSL_get_error(ssl_, rv); |
973 | 952 |
974 if (ssl_error == SSL_ERROR_WANT_CHANNEL_ID_LOOKUP) { | 953 if (ssl_error == SSL_ERROR_WANT_CHANNEL_ID_LOOKUP) { |
975 // The server supports channel ID. Stop to look one up before returning to | 954 // The server supports channel ID. Stop to look one up before returning to |
976 // the handshake. | 955 // the handshake. |
977 channel_id_xtn_negotiated_ = true; | 956 channel_id_xtn_negotiated_ = true; |
978 GotoState(STATE_CHANNEL_ID_LOOKUP); | 957 GotoState(STATE_CHANNEL_ID_LOOKUP); |
979 return OK; | 958 return OK; |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1042 return MapOpenSSLError(err, err_tracer); | 1021 return MapOpenSSLError(err, err_tracer); |
1043 } | 1022 } |
1044 | 1023 |
1045 // Return to the handshake. | 1024 // Return to the handshake. |
1046 set_channel_id_sent(true); | 1025 set_channel_id_sent(true); |
1047 GotoState(STATE_HANDSHAKE); | 1026 GotoState(STATE_HANDSHAKE); |
1048 return OK; | 1027 return OK; |
1049 } | 1028 } |
1050 | 1029 |
1051 int SSLClientSocketOpenSSL::DoVerifyCert(int result) { | 1030 int SSLClientSocketOpenSSL::DoVerifyCert(int result) { |
1052 DCHECK(server_cert_.get()); | 1031 DCHECK_NE(0u, server_cert_chain_->size()); |
1053 DCHECK(start_cert_verification_time_.is_null()); | 1032 DCHECK(start_cert_verification_time_.is_null()); |
1033 | |
1054 GotoState(STATE_VERIFY_CERT_COMPLETE); | 1034 GotoState(STATE_VERIFY_CERT_COMPLETE); |
1055 | 1035 |
1036 // If the certificate is expected to be bad we can use the expectation as | |
1037 // the cert status. | |
Ryan Sleevi
2014/09/18 01:34:39
Don't use we in comments
// If the certificate is
davidben
2014/09/18 19:40:06
Done. (I just pulled this from SSLClientSocketNSS.
| |
1038 std::string der_cert; | |
1039 if (!GetDEREncodedX509(server_cert_chain_->Get(0), &der_cert)) { | |
1040 NOTREACHED(); | |
1041 return ERR_CERT_INVALID; | |
1042 } | |
1056 CertStatus cert_status; | 1043 CertStatus cert_status; |
1057 if (ssl_config_.IsAllowedBadCert(server_cert_.get(), &cert_status)) { | 1044 if (ssl_config_.IsAllowedBadCert(der_cert, &cert_status)) { |
1058 VLOG(1) << "Received an expected bad cert with status: " << cert_status; | 1045 VLOG(1) << "Received an expected bad cert with status: " << cert_status; |
1059 server_cert_verify_result_.Reset(); | 1046 server_cert_verify_result_.Reset(); |
1060 server_cert_verify_result_.cert_status = cert_status; | 1047 server_cert_verify_result_.cert_status = cert_status; |
1061 server_cert_verify_result_.verified_cert = server_cert_; | 1048 server_cert_verify_result_.verified_cert = server_cert_; |
1062 return OK; | 1049 return OK; |
1063 } | 1050 } |
1064 | 1051 |
1052 // We may have failed to create X509Certificate object if we are | |
1053 // running inside sandbox. | |
Ryan Sleevi
2014/09/18 01:34:39
// When running in a sandbox, it may not be possib
davidben
2014/09/18 19:40:06
Done. (Also just pulled from NSS.)
| |
1054 if (!server_cert_.get()) { | |
1055 server_cert_verify_result_.Reset(); | |
1056 server_cert_verify_result_.cert_status = CERT_STATUS_INVALID; | |
1057 return ERR_CERT_INVALID; | |
1058 } | |
1059 | |
1065 start_cert_verification_time_ = base::TimeTicks::Now(); | 1060 start_cert_verification_time_ = base::TimeTicks::Now(); |
1066 | 1061 |
1067 int flags = 0; | 1062 int flags = 0; |
1068 if (ssl_config_.rev_checking_enabled) | 1063 if (ssl_config_.rev_checking_enabled) |
1069 flags |= CertVerifier::VERIFY_REV_CHECKING_ENABLED; | 1064 flags |= CertVerifier::VERIFY_REV_CHECKING_ENABLED; |
1070 if (ssl_config_.verify_ev_cert) | 1065 if (ssl_config_.verify_ev_cert) |
1071 flags |= CertVerifier::VERIFY_EV_CERT; | 1066 flags |= CertVerifier::VERIFY_EV_CERT; |
1072 if (ssl_config_.cert_io_enabled) | 1067 if (ssl_config_.cert_io_enabled) |
1073 flags |= CertVerifier::VERIFY_CERT_IO_ENABLED; | 1068 flags |= CertVerifier::VERIFY_CERT_IO_ENABLED; |
1074 if (ssl_config_.rev_checking_required_local_anchors) | 1069 if (ssl_config_.rev_checking_required_local_anchors) |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1140 void SSLClientSocketOpenSSL::DoConnectCallback(int rv) { | 1135 void SSLClientSocketOpenSSL::DoConnectCallback(int rv) { |
1141 if (rv < OK) | 1136 if (rv < OK) |
1142 OnHandshakeCompletion(); | 1137 OnHandshakeCompletion(); |
1143 if (!user_connect_callback_.is_null()) { | 1138 if (!user_connect_callback_.is_null()) { |
1144 CompletionCallback c = user_connect_callback_; | 1139 CompletionCallback c = user_connect_callback_; |
1145 user_connect_callback_.Reset(); | 1140 user_connect_callback_.Reset(); |
1146 c.Run(rv > OK ? OK : rv); | 1141 c.Run(rv > OK ? OK : rv); |
1147 } | 1142 } |
1148 } | 1143 } |
1149 | 1144 |
1150 X509Certificate* SSLClientSocketOpenSSL::UpdateServerCert() { | 1145 void SSLClientSocketOpenSSL::UpdateServerCert() { |
1151 server_cert_chain_->Reset(SSL_get_peer_cert_chain(ssl_)); | 1146 server_cert_chain_->Reset(SSL_get_peer_cert_chain(ssl_)); |
1152 server_cert_ = server_cert_chain_->AsOSChain(); | 1147 server_cert_ = server_cert_chain_->AsOSChain(); |
1153 | 1148 |
1154 if (!server_cert_chain_->IsValid()) | 1149 if (server_cert_.get()) { |
1155 DVLOG(1) << "UpdateServerCert received invalid certificate chain from peer"; | 1150 net_log_.AddEvent( |
1156 | 1151 NetLog::TYPE_SSL_CERTIFICATES_RECEIVED, |
1157 return server_cert_.get(); | 1152 base::Bind(&NetLogX509CertificateCallback, |
1153 base::Unretained(server_cert_.get()))); | |
1154 } | |
1158 } | 1155 } |
1159 | 1156 |
1160 void SSLClientSocketOpenSSL::VerifyCT() { | 1157 void SSLClientSocketOpenSSL::VerifyCT() { |
1161 if (!cert_transparency_verifier_) | 1158 if (!cert_transparency_verifier_) |
1162 return; | 1159 return; |
1163 | 1160 |
1164 uint8_t* ocsp_response_raw; | 1161 uint8_t* ocsp_response_raw; |
1165 size_t ocsp_response_len; | 1162 size_t ocsp_response_len; |
1166 SSL_get0_ocsp_response(ssl_, &ocsp_response_raw, &ocsp_response_len); | 1163 SSL_get0_ocsp_response(ssl_, &ocsp_response_raw, &ocsp_response_len); |
1167 std::string ocsp_response; | 1164 std::string ocsp_response; |
(...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1612 return 1; | 1609 return 1; |
1613 } | 1610 } |
1614 | 1611 |
1615 int SSLClientSocketOpenSSL::CertVerifyCallback(X509_STORE_CTX* store_ctx) { | 1612 int SSLClientSocketOpenSSL::CertVerifyCallback(X509_STORE_CTX* store_ctx) { |
1616 if (!completed_connect_) { | 1613 if (!completed_connect_) { |
1617 // If the first handshake hasn't completed then we accept any certificates | 1614 // If the first handshake hasn't completed then we accept any certificates |
1618 // because we verify after the handshake. | 1615 // because we verify after the handshake. |
1619 return 1; | 1616 return 1; |
1620 } | 1617 } |
1621 | 1618 |
1622 CHECK(server_cert_.get()); | 1619 // Disallow the server certificate to change in a renegotiation. |
1620 if (server_cert_chain_->size() < 1) { | |
Ryan Sleevi
2014/09/18 01:34:39
.empty() optimization?
davidben
2014/09/18 19:40:06
Added a empty() method (matches NSS too) if that's
| |
1621 LOG(ERROR) << "Received invalid certificate chain between handshakes"; | |
1622 return 0; | |
1623 } | |
1624 if (store_ctx->cert == NULL || | |
1625 X509_cmp(server_cert_chain_->Get(0), store_ctx->cert) != 0) { | |
1626 LOG(ERROR) << "Server certificate changed between handshakes"; | |
1627 return 0; | |
1628 } | |
1623 | 1629 |
1624 PeerCertificateChain chain(store_ctx->untrusted); | 1630 return 1; |
1625 if (chain.IsValid() && server_cert_->Equals(chain.AsOSChain().get())) | |
1626 return 1; | |
1627 | |
1628 if (!chain.IsValid()) | |
1629 LOG(ERROR) << "Received invalid certificate chain between handshakes"; | |
1630 else | |
1631 LOG(ERROR) << "Server certificate changed between handshakes"; | |
1632 return 0; | |
1633 } | 1631 } |
1634 | 1632 |
1635 // SelectNextProtoCallback is called by OpenSSL during the handshake. If the | 1633 // SelectNextProtoCallback is called by OpenSSL during the handshake. If the |
1636 // server supports NPN, selects a protocol from the list that the server | 1634 // server supports NPN, selects a protocol from the list that the server |
1637 // provides. According to third_party/openssl/openssl/ssl/ssl_lib.c, the | 1635 // provides. According to third_party/openssl/openssl/ssl/ssl_lib.c, the |
1638 // callback can assume that |in| is syntactically valid. | 1636 // callback can assume that |in| is syntactically valid. |
1639 int SSLClientSocketOpenSSL::SelectNextProtoCallback(unsigned char** out, | 1637 int SSLClientSocketOpenSSL::SelectNextProtoCallback(unsigned char** out, |
1640 unsigned char* outlen, | 1638 unsigned char* outlen, |
1641 const unsigned char* in, | 1639 const unsigned char* in, |
1642 unsigned int inlen) { | 1640 unsigned int inlen) { |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1773 ct::SCT_STATUS_LOG_UNKNOWN)); | 1771 ct::SCT_STATUS_LOG_UNKNOWN)); |
1774 } | 1772 } |
1775 } | 1773 } |
1776 | 1774 |
1777 scoped_refptr<X509Certificate> | 1775 scoped_refptr<X509Certificate> |
1778 SSLClientSocketOpenSSL::GetUnverifiedServerCertificateChain() const { | 1776 SSLClientSocketOpenSSL::GetUnverifiedServerCertificateChain() const { |
1779 return server_cert_; | 1777 return server_cert_; |
1780 } | 1778 } |
1781 | 1779 |
1782 } // namespace net | 1780 } // namespace net |
OLD | NEW |