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> |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 27 #include "crypto/scoped_openssl_types.h" | 27 #include "crypto/scoped_openssl_types.h" |
| 28 #include "net/base/net_errors.h" | 28 #include "net/base/net_errors.h" |
| 29 #include "net/cert/cert_policy_enforcer.h" | 29 #include "net/cert/cert_policy_enforcer.h" |
| 30 #include "net/cert/cert_verifier.h" | 30 #include "net/cert/cert_verifier.h" |
| 31 #include "net/cert/ct_ev_whitelist.h" | 31 #include "net/cert/ct_ev_whitelist.h" |
| 32 #include "net/cert/ct_verifier.h" | 32 #include "net/cert/ct_verifier.h" |
| 33 #include "net/cert/single_request_cert_verifier.h" | 33 #include "net/cert/single_request_cert_verifier.h" |
| 34 #include "net/cert/x509_certificate_net_log_param.h" | 34 #include "net/cert/x509_certificate_net_log_param.h" |
| 35 #include "net/cert/x509_util_openssl.h" | 35 #include "net/cert/x509_util_openssl.h" |
| 36 #include "net/http/transport_security_state.h" | 36 #include "net/http/transport_security_state.h" |
| 37 #include "net/socket/ssl_session_cache_openssl.h" | |
| 38 #include "net/ssl/scoped_openssl_types.h" | 37 #include "net/ssl/scoped_openssl_types.h" |
| 39 #include "net/ssl/ssl_cert_request_info.h" | 38 #include "net/ssl/ssl_cert_request_info.h" |
| 39 #include "net/ssl/ssl_client_session_cache_openssl.h" | |
| 40 #include "net/ssl/ssl_connection_status_flags.h" | 40 #include "net/ssl/ssl_connection_status_flags.h" |
| 41 #include "net/ssl/ssl_info.h" | 41 #include "net/ssl/ssl_info.h" |
| 42 | 42 |
| 43 #if defined(OS_WIN) | 43 #if defined(OS_WIN) |
| 44 #include "base/win/windows_version.h" | 44 #include "base/win/windows_version.h" |
| 45 #endif | 45 #endif |
| 46 | 46 |
| 47 #if defined(USE_OPENSSL_CERTS) | 47 #if defined(USE_OPENSSL_CERTS) |
| 48 #include "net/ssl/openssl_client_key_store.h" | 48 #include "net/ssl/openssl_client_key_store.h" |
| 49 #else | 49 #else |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 157 return false; | 157 return false; |
| 158 #endif | 158 #endif |
| 159 } | 159 } |
| 160 | 160 |
| 161 } // namespace | 161 } // namespace |
| 162 | 162 |
| 163 class SSLClientSocketOpenSSL::SSLContext { | 163 class SSLClientSocketOpenSSL::SSLContext { |
| 164 public: | 164 public: |
| 165 static SSLContext* GetInstance() { return Singleton<SSLContext>::get(); } | 165 static SSLContext* GetInstance() { return Singleton<SSLContext>::get(); } |
| 166 SSL_CTX* ssl_ctx() { return ssl_ctx_.get(); } | 166 SSL_CTX* ssl_ctx() { return ssl_ctx_.get(); } |
| 167 SSLSessionCacheOpenSSL* session_cache() { return &session_cache_; } | 167 SSLClientSessionCacheOpenSSL* session_cache() { return &session_cache_; } |
| 168 | 168 |
| 169 SSLClientSocketOpenSSL* GetClientSocketFromSSL(const SSL* ssl) { | 169 SSLClientSocketOpenSSL* GetClientSocketFromSSL(const SSL* ssl) { |
| 170 DCHECK(ssl); | 170 DCHECK(ssl); |
| 171 SSLClientSocketOpenSSL* socket = static_cast<SSLClientSocketOpenSSL*>( | 171 SSLClientSocketOpenSSL* socket = static_cast<SSLClientSocketOpenSSL*>( |
| 172 SSL_get_ex_data(ssl, ssl_socket_data_index_)); | 172 SSL_get_ex_data(ssl, ssl_socket_data_index_)); |
| 173 DCHECK(socket); | 173 DCHECK(socket); |
| 174 return socket; | 174 return socket; |
| 175 } | 175 } |
| 176 | 176 |
| 177 bool SetClientSocketForSSL(SSL* ssl, SSLClientSocketOpenSSL* socket) { | 177 bool SetClientSocketForSSL(SSL* ssl, SSLClientSocketOpenSSL* socket) { |
| 178 return SSL_set_ex_data(ssl, ssl_socket_data_index_, socket) != 0; | 178 return SSL_set_ex_data(ssl, ssl_socket_data_index_, socket) != 0; |
| 179 } | 179 } |
| 180 | 180 |
| 181 private: | 181 private: |
| 182 friend struct DefaultSingletonTraits<SSLContext>; | 182 friend struct DefaultSingletonTraits<SSLContext>; |
| 183 | 183 |
| 184 SSLContext() { | 184 SSLContext() : session_cache_(SSLClientSessionCacheOpenSSL::Config()) { |
| 185 crypto::EnsureOpenSSLInit(); | 185 crypto::EnsureOpenSSLInit(); |
| 186 ssl_socket_data_index_ = SSL_get_ex_new_index(0, 0, 0, 0, 0); | 186 ssl_socket_data_index_ = SSL_get_ex_new_index(0, 0, 0, 0, 0); |
| 187 DCHECK_NE(ssl_socket_data_index_, -1); | 187 DCHECK_NE(ssl_socket_data_index_, -1); |
| 188 ssl_ctx_.reset(SSL_CTX_new(SSLv23_client_method())); | 188 ssl_ctx_.reset(SSL_CTX_new(SSLv23_client_method())); |
| 189 session_cache_.Reset(ssl_ctx_.get(), kDefaultSessionCacheConfig); | |
| 190 SSL_CTX_set_cert_verify_callback(ssl_ctx_.get(), CertVerifyCallback, NULL); | 189 SSL_CTX_set_cert_verify_callback(ssl_ctx_.get(), CertVerifyCallback, NULL); |
| 191 SSL_CTX_set_cert_cb(ssl_ctx_.get(), ClientCertRequestCallback, NULL); | 190 SSL_CTX_set_cert_cb(ssl_ctx_.get(), ClientCertRequestCallback, NULL); |
| 192 SSL_CTX_set_verify(ssl_ctx_.get(), SSL_VERIFY_PEER, NULL); | 191 SSL_CTX_set_verify(ssl_ctx_.get(), SSL_VERIFY_PEER, NULL); |
| 193 // This stops |SSL_shutdown| from generating the close_notify message, which | 192 // This stops |SSL_shutdown| from generating the close_notify message, which |
| 194 // is currently not sent on the network. | 193 // is currently not sent on the network. |
| 195 // TODO(haavardm): Remove setting quiet shutdown once 118366 is fixed. | 194 // TODO(haavardm): Remove setting quiet shutdown once 118366 is fixed. |
| 196 SSL_CTX_set_quiet_shutdown(ssl_ctx_.get(), 1); | 195 SSL_CTX_set_quiet_shutdown(ssl_ctx_.get(), 1); |
| 197 // TODO(kristianm): Only select this if ssl_config_.next_proto is not empty. | 196 // TODO(kristianm): Only select this if ssl_config_.next_proto is not empty. |
| 198 // It would be better if the callback were not a global setting, | 197 // It would be better if the callback were not a global setting, |
| 199 // but that is an OpenSSL issue. | 198 // but that is an OpenSSL issue. |
| 200 SSL_CTX_set_next_proto_select_cb(ssl_ctx_.get(), SelectNextProtoCallback, | 199 SSL_CTX_set_next_proto_select_cb(ssl_ctx_.get(), SelectNextProtoCallback, |
| 201 NULL); | 200 NULL); |
| 202 ssl_ctx_->tlsext_channel_id_enabled_new = 1; | 201 ssl_ctx_->tlsext_channel_id_enabled_new = 1; |
| 202 SSL_CTX_set_info_callback(ssl_ctx_.get(), InfoCallback); | |
| 203 | |
| 204 // Set up the session cache. NO_INTERNAL_STORE disables OpenSSL's builtin | |
| 205 // cache, and NO_AUTO_CLEAR disables the call to SSL_CTX_flush_sessions | |
| 206 // every 256 connections. | |
|
Ryan Sleevi
2015/03/24 23:47:21
Is there any automated pruning of expired sessions
davidben
2015/03/26 20:22:57
That comment and call is the same as the file from
| |
| 207 SSL_CTX_set_session_cache_mode(ssl_ctx_.get(), | |
| 208 SSL_SESS_CACHE_CLIENT | | |
| 209 SSL_SESS_CACHE_NO_INTERNAL_STORE | | |
| 210 SSL_SESS_CACHE_NO_AUTO_CLEAR); | |
| 203 | 211 |
| 204 scoped_ptr<base::Environment> env(base::Environment::Create()); | 212 scoped_ptr<base::Environment> env(base::Environment::Create()); |
| 205 std::string ssl_keylog_file; | 213 std::string ssl_keylog_file; |
| 206 if (env->GetVar("SSLKEYLOGFILE", &ssl_keylog_file) && | 214 if (env->GetVar("SSLKEYLOGFILE", &ssl_keylog_file) && |
| 207 !ssl_keylog_file.empty()) { | 215 !ssl_keylog_file.empty()) { |
| 208 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); | 216 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); |
| 209 BIO* bio = BIO_new_file(ssl_keylog_file.c_str(), "a"); | 217 BIO* bio = BIO_new_file(ssl_keylog_file.c_str(), "a"); |
| 210 if (!bio) { | 218 if (!bio) { |
| 211 LOG(ERROR) << "Failed to open " << ssl_keylog_file; | 219 LOG(ERROR) << "Failed to open " << ssl_keylog_file; |
| 212 ERR_print_errors_cb(&LogErrorCallback, NULL); | 220 ERR_print_errors_cb(&LogErrorCallback, NULL); |
| 213 } else { | 221 } else { |
| 214 SSL_CTX_set_keylog_bio(ssl_ctx_.get(), bio); | 222 SSL_CTX_set_keylog_bio(ssl_ctx_.get(), bio); |
| 215 } | 223 } |
| 216 } | 224 } |
| 217 } | 225 } |
| 218 | 226 |
| 219 static std::string GetSessionCacheKey(const SSL* ssl) { | |
| 220 SSLClientSocketOpenSSL* socket = GetInstance()->GetClientSocketFromSSL(ssl); | |
| 221 CHECK(socket); | |
| 222 return socket->GetSessionCacheKey(); | |
| 223 } | |
| 224 | |
| 225 static SSLSessionCacheOpenSSL::Config kDefaultSessionCacheConfig; | |
| 226 | |
| 227 static int ClientCertRequestCallback(SSL* ssl, void* arg) { | 227 static int ClientCertRequestCallback(SSL* ssl, void* arg) { |
| 228 SSLClientSocketOpenSSL* socket = GetInstance()->GetClientSocketFromSSL(ssl); | 228 SSLClientSocketOpenSSL* socket = GetInstance()->GetClientSocketFromSSL(ssl); |
| 229 DCHECK(socket); | 229 DCHECK(socket); |
| 230 return socket->ClientCertRequestCallback(ssl); | 230 return socket->ClientCertRequestCallback(ssl); |
| 231 } | 231 } |
| 232 | 232 |
| 233 static int CertVerifyCallback(X509_STORE_CTX *store_ctx, void *arg) { | 233 static int CertVerifyCallback(X509_STORE_CTX *store_ctx, void *arg) { |
| 234 SSL* ssl = reinterpret_cast<SSL*>(X509_STORE_CTX_get_ex_data( | 234 SSL* ssl = reinterpret_cast<SSL*>(X509_STORE_CTX_get_ex_data( |
| 235 store_ctx, SSL_get_ex_data_X509_STORE_CTX_idx())); | 235 store_ctx, SSL_get_ex_data_X509_STORE_CTX_idx())); |
| 236 SSLClientSocketOpenSSL* socket = GetInstance()->GetClientSocketFromSSL(ssl); | 236 SSLClientSocketOpenSSL* socket = GetInstance()->GetClientSocketFromSSL(ssl); |
| 237 CHECK(socket); | 237 CHECK(socket); |
| 238 | 238 |
| 239 return socket->CertVerifyCallback(store_ctx); | 239 return socket->CertVerifyCallback(store_ctx); |
| 240 } | 240 } |
| 241 | 241 |
| 242 static int SelectNextProtoCallback(SSL* ssl, | 242 static int SelectNextProtoCallback(SSL* ssl, |
| 243 unsigned char** out, unsigned char* outlen, | 243 unsigned char** out, unsigned char* outlen, |
| 244 const unsigned char* in, | 244 const unsigned char* in, |
| 245 unsigned int inlen, void* arg) { | 245 unsigned int inlen, void* arg) { |
| 246 SSLClientSocketOpenSSL* socket = GetInstance()->GetClientSocketFromSSL(ssl); | 246 SSLClientSocketOpenSSL* socket = GetInstance()->GetClientSocketFromSSL(ssl); |
| 247 return socket->SelectNextProtoCallback(out, outlen, in, inlen); | 247 return socket->SelectNextProtoCallback(out, outlen, in, inlen); |
| 248 } | 248 } |
| 249 | 249 |
| 250 static void InfoCallback(const SSL* ssl, int type, int val) { | |
| 251 SSLClientSocketOpenSSL* socket = GetInstance()->GetClientSocketFromSSL(ssl); | |
| 252 socket->InfoCallback(type, val); | |
| 253 } | |
| 254 | |
| 250 // This is the index used with SSL_get_ex_data to retrieve the owner | 255 // This is the index used with SSL_get_ex_data to retrieve the owner |
| 251 // SSLClientSocketOpenSSL object from an SSL instance. | 256 // SSLClientSocketOpenSSL object from an SSL instance. |
| 252 int ssl_socket_data_index_; | 257 int ssl_socket_data_index_; |
| 253 | 258 |
| 254 ScopedSSL_CTX ssl_ctx_; | 259 ScopedSSL_CTX ssl_ctx_; |
| 255 // |session_cache_| must be destroyed before |ssl_ctx_|. | 260 |
| 256 SSLSessionCacheOpenSSL session_cache_; | 261 // TODO(davidben): Use a separate cache per URLRequestContext. |
| 262 // https://crbug.com/458365 | |
| 263 // | |
| 264 // TODO(davidben): Sessions should be invalidated on fatal | |
| 265 // alerts. https://crbug.com/466352 | |
| 266 SSLClientSessionCacheOpenSSL session_cache_; | |
| 257 }; | 267 }; |
| 258 | 268 |
| 259 // PeerCertificateChain is a helper object which extracts the certificate | 269 // PeerCertificateChain is a helper object which extracts the certificate |
| 260 // chain, as given by the server, from an OpenSSL socket and performs the needed | 270 // chain, as given by the server, from an OpenSSL socket and performs the needed |
| 261 // resource management. The first element of the chain is the leaf certificate | 271 // resource management. The first element of the chain is the leaf certificate |
| 262 // and the other elements are in the order given by the server. | 272 // and the other elements are in the order given by the server. |
| 263 class SSLClientSocketOpenSSL::PeerCertificateChain { | 273 class SSLClientSocketOpenSSL::PeerCertificateChain { |
| 264 public: | 274 public: |
| 265 explicit PeerCertificateChain(STACK_OF(X509)* chain) { Reset(chain); } | 275 explicit PeerCertificateChain(STACK_OF(X509)* chain) { Reset(chain); } |
| 266 PeerCertificateChain(const PeerCertificateChain& other) { *this = other; } | 276 PeerCertificateChain(const PeerCertificateChain& other) { *this = other; } |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 331 if (!x509_util::GetDER(x, &der)) | 341 if (!x509_util::GetDER(x, &der)) |
| 332 return NULL; | 342 return NULL; |
| 333 der_chain.push_back(der); | 343 der_chain.push_back(der); |
| 334 } | 344 } |
| 335 | 345 |
| 336 return make_scoped_refptr(X509Certificate::CreateFromDERCertChain(der_chain)); | 346 return make_scoped_refptr(X509Certificate::CreateFromDERCertChain(der_chain)); |
| 337 #endif | 347 #endif |
| 338 } | 348 } |
| 339 | 349 |
| 340 // static | 350 // static |
| 341 SSLSessionCacheOpenSSL::Config | |
| 342 SSLClientSocketOpenSSL::SSLContext::kDefaultSessionCacheConfig = { | |
| 343 &GetSessionCacheKey, // key_func | |
| 344 1024, // max_entries | |
| 345 256, // expiration_check_count | |
| 346 60 * 60, // timeout_seconds | |
| 347 }; | |
| 348 | |
| 349 // static | |
| 350 void SSLClientSocket::ClearSessionCache() { | 351 void SSLClientSocket::ClearSessionCache() { |
| 351 SSLClientSocketOpenSSL::SSLContext* context = | 352 SSLClientSocketOpenSSL::SSLContext* context = |
| 352 SSLClientSocketOpenSSL::SSLContext::GetInstance(); | 353 SSLClientSocketOpenSSL::SSLContext::GetInstance(); |
| 353 context->session_cache()->Flush(); | 354 context->session_cache()->Flush(); |
| 354 } | 355 } |
| 355 | 356 |
| 356 // static | 357 // static |
| 357 uint16 SSLClientSocket::GetMaxSupportedSSLVersion() { | 358 uint16 SSLClientSocket::GetMaxSupportedSSLVersion() { |
| 358 return SSL_PROTOCOL_VERSION_TLS1_2; | 359 return SSL_PROTOCOL_VERSION_TLS1_2; |
| 359 } | 360 } |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 375 client_auth_cert_needed_(false), | 376 client_auth_cert_needed_(false), |
| 376 cert_verifier_(context.cert_verifier), | 377 cert_verifier_(context.cert_verifier), |
| 377 cert_transparency_verifier_(context.cert_transparency_verifier), | 378 cert_transparency_verifier_(context.cert_transparency_verifier), |
| 378 channel_id_service_(context.channel_id_service), | 379 channel_id_service_(context.channel_id_service), |
| 379 ssl_(NULL), | 380 ssl_(NULL), |
| 380 transport_bio_(NULL), | 381 transport_bio_(NULL), |
| 381 transport_(transport_socket.Pass()), | 382 transport_(transport_socket.Pass()), |
| 382 host_and_port_(host_and_port), | 383 host_and_port_(host_and_port), |
| 383 ssl_config_(ssl_config), | 384 ssl_config_(ssl_config), |
| 384 ssl_session_cache_shard_(context.ssl_session_cache_shard), | 385 ssl_session_cache_shard_(context.ssl_session_cache_shard), |
| 385 trying_cached_session_(false), | |
| 386 next_handshake_state_(STATE_NONE), | 386 next_handshake_state_(STATE_NONE), |
| 387 npn_status_(kNextProtoUnsupported), | 387 npn_status_(kNextProtoUnsupported), |
| 388 channel_id_xtn_negotiated_(false), | 388 channel_id_xtn_negotiated_(false), |
| 389 handshake_completed_(false), | |
| 390 certificate_verified_(false), | |
| 389 transport_security_state_(context.transport_security_state), | 391 transport_security_state_(context.transport_security_state), |
| 390 policy_enforcer_(context.cert_policy_enforcer), | 392 policy_enforcer_(context.cert_policy_enforcer), |
| 391 net_log_(transport_->socket()->NetLog()), | 393 net_log_(transport_->socket()->NetLog()), |
| 392 weak_factory_(this) { | 394 weak_factory_(this) { |
| 393 } | 395 } |
| 394 | 396 |
| 395 SSLClientSocketOpenSSL::~SSLClientSocketOpenSSL() { | 397 SSLClientSocketOpenSSL::~SSLClientSocketOpenSSL() { |
| 396 Disconnect(); | 398 Disconnect(); |
| 397 } | 399 } |
| 398 | 400 |
| (...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 692 SSLContext* context = SSLContext::GetInstance(); | 694 SSLContext* context = SSLContext::GetInstance(); |
| 693 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); | 695 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); |
| 694 | 696 |
| 695 ssl_ = SSL_new(context->ssl_ctx()); | 697 ssl_ = SSL_new(context->ssl_ctx()); |
| 696 if (!ssl_ || !context->SetClientSocketForSSL(ssl_, this)) | 698 if (!ssl_ || !context->SetClientSocketForSSL(ssl_, this)) |
| 697 return ERR_UNEXPECTED; | 699 return ERR_UNEXPECTED; |
| 698 | 700 |
| 699 if (!SSL_set_tlsext_host_name(ssl_, host_and_port_.host().c_str())) | 701 if (!SSL_set_tlsext_host_name(ssl_, host_and_port_.host().c_str())) |
| 700 return ERR_UNEXPECTED; | 702 return ERR_UNEXPECTED; |
| 701 | 703 |
| 702 trying_cached_session_ = context->session_cache()->SetSSLSessionWithKey( | 704 SSL_SESSION* session = context->session_cache()->Lookup(GetSessionCacheKey()); |
| 703 ssl_, GetSessionCacheKey()); | 705 if (session != nullptr) |
| 706 SSL_set_session(ssl_, session); | |
| 704 | 707 |
| 705 send_buffer_ = new GrowableIOBuffer(); | 708 send_buffer_ = new GrowableIOBuffer(); |
| 706 send_buffer_->SetCapacity(KDefaultOpenSSLBufferSize); | 709 send_buffer_->SetCapacity(KDefaultOpenSSLBufferSize); |
| 707 recv_buffer_ = new GrowableIOBuffer(); | 710 recv_buffer_ = new GrowableIOBuffer(); |
| 708 recv_buffer_->SetCapacity(KDefaultOpenSSLBufferSize); | 711 recv_buffer_->SetCapacity(KDefaultOpenSSLBufferSize); |
| 709 | 712 |
| 710 BIO* ssl_bio = NULL; | 713 BIO* ssl_bio = NULL; |
| 711 | 714 |
| 712 // SSLClientSocketOpenSSL retains ownership of the BIO buffers. | 715 // SSLClientSocketOpenSSL retains ownership of the BIO buffers. |
| 713 if (!BIO_new_bio_pair_external_buf( | 716 if (!BIO_new_bio_pair_external_buf( |
| (...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 945 int rv = SSL_CTX_remove_session(SSL_get_SSL_CTX(ssl_), session); | 948 int rv = SSL_CTX_remove_session(SSL_get_SSL_CTX(ssl_), session); |
| 946 LOG_IF(WARNING, !rv) << "Couldn't invalidate SSL session: " << session; | 949 LOG_IF(WARNING, !rv) << "Couldn't invalidate SSL session: " << session; |
| 947 } | 950 } |
| 948 } | 951 } |
| 949 } else if (rv == 1) { | 952 } else if (rv == 1) { |
| 950 // TODO(vadimt): Remove ScopedTracker below once crbug.com/424386 is fixed. | 953 // TODO(vadimt): Remove ScopedTracker below once crbug.com/424386 is fixed. |
| 951 tracked_objects::ScopedTracker tracking_profile3( | 954 tracked_objects::ScopedTracker tracking_profile3( |
| 952 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 955 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 953 "424386 SSLClientSocketOpenSSL::DoHandshake3")); | 956 "424386 SSLClientSocketOpenSSL::DoHandshake3")); |
| 954 | 957 |
| 955 if (trying_cached_session_ && logging::DEBUG_MODE) { | |
| 956 DVLOG(2) << "Result of session reuse for " << host_and_port_.ToString() | |
| 957 << " is: " << (SSL_session_reused(ssl_) ? "Success" : "Fail"); | |
| 958 } | |
| 959 | |
| 960 if (ssl_config_.version_fallback && | 958 if (ssl_config_.version_fallback && |
| 961 ssl_config_.version_max < ssl_config_.version_fallback_min) { | 959 ssl_config_.version_max < ssl_config_.version_fallback_min) { |
| 962 return ERR_SSL_FALLBACK_BEYOND_MINIMUM_VERSION; | 960 return ERR_SSL_FALLBACK_BEYOND_MINIMUM_VERSION; |
| 963 } | 961 } |
| 964 | 962 |
| 965 // SSL handshake is completed. If NPN wasn't negotiated, see if ALPN was. | 963 // SSL handshake is completed. If NPN wasn't negotiated, see if ALPN was. |
| 966 if (npn_status_ == kNextProtoUnsupported) { | 964 if (npn_status_ == kNextProtoUnsupported) { |
| 967 const uint8_t* alpn_proto = NULL; | 965 const uint8_t* alpn_proto = NULL; |
| 968 unsigned alpn_len = 0; | 966 unsigned alpn_len = 0; |
| 969 SSL_get0_alpn_selected(ssl_, &alpn_proto, &alpn_len); | 967 SSL_get0_alpn_selected(ssl_, &alpn_proto, &alpn_len); |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1174 server_cert_verify_result_.public_key_hashes, | 1172 server_cert_verify_result_.public_key_hashes, |
| 1175 &pinning_failure_log_)) { | 1173 &pinning_failure_log_)) { |
| 1176 result = ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN; | 1174 result = ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN; |
| 1177 } | 1175 } |
| 1178 | 1176 |
| 1179 if (result == OK) { | 1177 if (result == OK) { |
| 1180 // Only check Certificate Transparency if there were no other errors with | 1178 // Only check Certificate Transparency if there were no other errors with |
| 1181 // the connection. | 1179 // the connection. |
| 1182 VerifyCT(); | 1180 VerifyCT(); |
| 1183 | 1181 |
| 1184 // TODO(joth): Work out if we need to remember the intermediate CA certs | 1182 DCHECK(!certificate_verified_); |
| 1185 // when the server sends them to us, and do so here. | 1183 certificate_verified_ = true; |
| 1186 SSLContext::GetInstance()->session_cache()->MarkSSLSessionAsGood(ssl_); | 1184 MaybeCacheSession(); |
| 1187 } else { | 1185 } else { |
| 1188 DVLOG(1) << "DoVerifyCertComplete error " << ErrorToString(result) | 1186 DVLOG(1) << "DoVerifyCertComplete error " << ErrorToString(result) |
| 1189 << " (" << result << ")"; | 1187 << " (" << result << ")"; |
| 1190 } | 1188 } |
| 1191 | 1189 |
| 1192 completed_connect_ = true; | 1190 completed_connect_ = true; |
| 1193 // Exit DoHandshakeLoop and return the result to the caller to Connect. | 1191 // Exit DoHandshakeLoop and return the result to the caller to Connect. |
| 1194 DCHECK_EQ(STATE_NONE, next_handshake_state_); | 1192 DCHECK_EQ(STATE_NONE, next_handshake_state_); |
| 1195 return result; | 1193 return result; |
| 1196 } | 1194 } |
| (...skipping 718 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1915 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 1913 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 1916 "424386 SSLClientSocketOpenSSL::BIOCallback")); | 1914 "424386 SSLClientSocketOpenSSL::BIOCallback")); |
| 1917 | 1915 |
| 1918 SSLClientSocketOpenSSL* socket = reinterpret_cast<SSLClientSocketOpenSSL*>( | 1916 SSLClientSocketOpenSSL* socket = reinterpret_cast<SSLClientSocketOpenSSL*>( |
| 1919 BIO_get_callback_arg(bio)); | 1917 BIO_get_callback_arg(bio)); |
| 1920 CHECK(socket); | 1918 CHECK(socket); |
| 1921 return socket->MaybeReplayTransportError( | 1919 return socket->MaybeReplayTransportError( |
| 1922 bio, cmd, argp, argi, argl, retvalue); | 1920 bio, cmd, argp, argi, argl, retvalue); |
| 1923 } | 1921 } |
| 1924 | 1922 |
| 1923 void SSLClientSocketOpenSSL::MaybeCacheSession() { | |
| 1924 // Only cache the session once both the handshake has completed and the | |
| 1925 // certificate has been verified. | |
| 1926 if (!handshake_completed_ || !certificate_verified_ || | |
| 1927 SSL_session_reused(ssl_)) { | |
| 1928 return; | |
| 1929 } | |
| 1930 | |
| 1931 SSLContext::GetInstance()->session_cache()->Insert(GetSessionCacheKey(), | |
| 1932 SSL_get_session(ssl_)); | |
| 1933 } | |
| 1934 | |
| 1935 void SSLClientSocketOpenSSL::InfoCallback(int type, int val) { | |
| 1936 // TODO(vadimt): Remove ScopedTracker below once crbug.com/424386 is fixed. | |
| 1937 tracked_objects::ScopedTracker tracking_profile( | |
| 1938 FROM_HERE_WITH_EXPLICIT_FUNCTION( | |
| 1939 "424386 SSLClientSocketOpenSSL::InfoCallback")); | |
|
Ryan Sleevi
2015/03/24 23:47:22
Nuke this. Vadim orphaned the bug :(
davidben
2015/03/26 20:22:56
Done.
| |
| 1940 | |
| 1941 if (type == SSL_CB_HANDSHAKE_DONE) { | |
| 1942 // SSL_CB_HANDSHAKE_DONE may be signaled multiple times if the socket | |
| 1943 // renegotiates. | |
| 1944 if (!handshake_completed_) { | |
| 1945 handshake_completed_ = true; | |
| 1946 MaybeCacheSession(); | |
| 1947 } | |
| 1948 } | |
| 1949 } | |
| 1950 | |
| 1925 void SSLClientSocketOpenSSL::AddSCTInfoToSSLInfo(SSLInfo* ssl_info) const { | 1951 void SSLClientSocketOpenSSL::AddSCTInfoToSSLInfo(SSLInfo* ssl_info) const { |
| 1926 for (ct::SCTList::const_iterator iter = | 1952 for (ct::SCTList::const_iterator iter = |
| 1927 ct_verify_result_.verified_scts.begin(); | 1953 ct_verify_result_.verified_scts.begin(); |
| 1928 iter != ct_verify_result_.verified_scts.end(); ++iter) { | 1954 iter != ct_verify_result_.verified_scts.end(); ++iter) { |
| 1929 ssl_info->signed_certificate_timestamps.push_back( | 1955 ssl_info->signed_certificate_timestamps.push_back( |
| 1930 SignedCertificateTimestampAndStatus(*iter, ct::SCT_STATUS_OK)); | 1956 SignedCertificateTimestampAndStatus(*iter, ct::SCT_STATUS_OK)); |
| 1931 } | 1957 } |
| 1932 for (ct::SCTList::const_iterator iter = | 1958 for (ct::SCTList::const_iterator iter = |
| 1933 ct_verify_result_.invalid_scts.begin(); | 1959 ct_verify_result_.invalid_scts.begin(); |
| 1934 iter != ct_verify_result_.invalid_scts.end(); ++iter) { | 1960 iter != ct_verify_result_.invalid_scts.end(); ++iter) { |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1971 | 1997 |
| 1972 return result; | 1998 return result; |
| 1973 } | 1999 } |
| 1974 | 2000 |
| 1975 scoped_refptr<X509Certificate> | 2001 scoped_refptr<X509Certificate> |
| 1976 SSLClientSocketOpenSSL::GetUnverifiedServerCertificateChain() const { | 2002 SSLClientSocketOpenSSL::GetUnverifiedServerCertificateChain() const { |
| 1977 return server_cert_; | 2003 return server_cert_; |
| 1978 } | 2004 } |
| 1979 | 2005 |
| 1980 } // namespace net | 2006 } // namespace net |
| OLD | NEW |