Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(23)

Side by Side Diff: net/socket/ssl_client_socket_openssl.cc

Issue 994263002: Rewrite session cache in OpenSSL ports. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: sleevi comments Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698