Chromium Code Reviews| 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 |