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 // Disable the internal session cache. Session caching is handled | |
205 // externally. | |
Ryan Sleevi
2015/04/02 06:53:15
// externally (i.e. by SSLClientSessionCacheOpenSS
davidben
2015/04/02 19:05:10
Done.
| |
206 SSL_CTX_set_session_cache_mode( | |
207 ssl_ctx_.get(), SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_NO_INTERNAL); | |
203 | 208 |
204 scoped_ptr<base::Environment> env(base::Environment::Create()); | 209 scoped_ptr<base::Environment> env(base::Environment::Create()); |
205 std::string ssl_keylog_file; | 210 std::string ssl_keylog_file; |
206 if (env->GetVar("SSLKEYLOGFILE", &ssl_keylog_file) && | 211 if (env->GetVar("SSLKEYLOGFILE", &ssl_keylog_file) && |
207 !ssl_keylog_file.empty()) { | 212 !ssl_keylog_file.empty()) { |
208 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); | 213 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); |
209 BIO* bio = BIO_new_file(ssl_keylog_file.c_str(), "a"); | 214 BIO* bio = BIO_new_file(ssl_keylog_file.c_str(), "a"); |
210 if (!bio) { | 215 if (!bio) { |
211 LOG(ERROR) << "Failed to open " << ssl_keylog_file; | 216 LOG(ERROR) << "Failed to open " << ssl_keylog_file; |
212 ERR_print_errors_cb(&LogErrorCallback, NULL); | 217 ERR_print_errors_cb(&LogErrorCallback, NULL); |
213 } else { | 218 } else { |
214 SSL_CTX_set_keylog_bio(ssl_ctx_.get(), bio); | 219 SSL_CTX_set_keylog_bio(ssl_ctx_.get(), bio); |
215 } | 220 } |
216 } | 221 } |
217 } | 222 } |
218 | 223 |
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) { | 224 static int ClientCertRequestCallback(SSL* ssl, void* arg) { |
228 SSLClientSocketOpenSSL* socket = GetInstance()->GetClientSocketFromSSL(ssl); | 225 SSLClientSocketOpenSSL* socket = GetInstance()->GetClientSocketFromSSL(ssl); |
229 DCHECK(socket); | 226 DCHECK(socket); |
230 return socket->ClientCertRequestCallback(ssl); | 227 return socket->ClientCertRequestCallback(ssl); |
231 } | 228 } |
232 | 229 |
233 static int CertVerifyCallback(X509_STORE_CTX *store_ctx, void *arg) { | 230 static int CertVerifyCallback(X509_STORE_CTX *store_ctx, void *arg) { |
234 SSL* ssl = reinterpret_cast<SSL*>(X509_STORE_CTX_get_ex_data( | 231 SSL* ssl = reinterpret_cast<SSL*>(X509_STORE_CTX_get_ex_data( |
235 store_ctx, SSL_get_ex_data_X509_STORE_CTX_idx())); | 232 store_ctx, SSL_get_ex_data_X509_STORE_CTX_idx())); |
236 SSLClientSocketOpenSSL* socket = GetInstance()->GetClientSocketFromSSL(ssl); | 233 SSLClientSocketOpenSSL* socket = GetInstance()->GetClientSocketFromSSL(ssl); |
237 CHECK(socket); | 234 CHECK(socket); |
238 | 235 |
239 return socket->CertVerifyCallback(store_ctx); | 236 return socket->CertVerifyCallback(store_ctx); |
240 } | 237 } |
241 | 238 |
242 static int SelectNextProtoCallback(SSL* ssl, | 239 static int SelectNextProtoCallback(SSL* ssl, |
243 unsigned char** out, unsigned char* outlen, | 240 unsigned char** out, unsigned char* outlen, |
244 const unsigned char* in, | 241 const unsigned char* in, |
245 unsigned int inlen, void* arg) { | 242 unsigned int inlen, void* arg) { |
246 SSLClientSocketOpenSSL* socket = GetInstance()->GetClientSocketFromSSL(ssl); | 243 SSLClientSocketOpenSSL* socket = GetInstance()->GetClientSocketFromSSL(ssl); |
247 return socket->SelectNextProtoCallback(out, outlen, in, inlen); | 244 return socket->SelectNextProtoCallback(out, outlen, in, inlen); |
248 } | 245 } |
249 | 246 |
247 static void InfoCallback(const SSL* ssl, int type, int val) { | |
248 SSLClientSocketOpenSSL* socket = GetInstance()->GetClientSocketFromSSL(ssl); | |
249 socket->InfoCallback(type, val); | |
250 } | |
251 | |
250 // This is the index used with SSL_get_ex_data to retrieve the owner | 252 // This is the index used with SSL_get_ex_data to retrieve the owner |
251 // SSLClientSocketOpenSSL object from an SSL instance. | 253 // SSLClientSocketOpenSSL object from an SSL instance. |
252 int ssl_socket_data_index_; | 254 int ssl_socket_data_index_; |
253 | 255 |
254 ScopedSSL_CTX ssl_ctx_; | 256 ScopedSSL_CTX ssl_ctx_; |
255 // |session_cache_| must be destroyed before |ssl_ctx_|. | 257 |
256 SSLSessionCacheOpenSSL session_cache_; | 258 // TODO(davidben): Use a separate cache per URLRequestContext. |
259 // https://crbug.com/458365 | |
260 // | |
261 // TODO(davidben): Sessions should be invalidated on fatal | |
262 // alerts. https://crbug.com/466352 | |
263 SSLClientSessionCacheOpenSSL session_cache_; | |
257 }; | 264 }; |
258 | 265 |
259 // PeerCertificateChain is a helper object which extracts the certificate | 266 // PeerCertificateChain is a helper object which extracts the certificate |
260 // chain, as given by the server, from an OpenSSL socket and performs the needed | 267 // 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 | 268 // 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. | 269 // and the other elements are in the order given by the server. |
263 class SSLClientSocketOpenSSL::PeerCertificateChain { | 270 class SSLClientSocketOpenSSL::PeerCertificateChain { |
264 public: | 271 public: |
265 explicit PeerCertificateChain(STACK_OF(X509)* chain) { Reset(chain); } | 272 explicit PeerCertificateChain(STACK_OF(X509)* chain) { Reset(chain); } |
266 PeerCertificateChain(const PeerCertificateChain& other) { *this = other; } | 273 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)) | 338 if (!x509_util::GetDER(x, &der)) |
332 return NULL; | 339 return NULL; |
333 der_chain.push_back(der); | 340 der_chain.push_back(der); |
334 } | 341 } |
335 | 342 |
336 return make_scoped_refptr(X509Certificate::CreateFromDERCertChain(der_chain)); | 343 return make_scoped_refptr(X509Certificate::CreateFromDERCertChain(der_chain)); |
337 #endif | 344 #endif |
338 } | 345 } |
339 | 346 |
340 // static | 347 // 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() { | 348 void SSLClientSocket::ClearSessionCache() { |
351 SSLClientSocketOpenSSL::SSLContext* context = | 349 SSLClientSocketOpenSSL::SSLContext* context = |
352 SSLClientSocketOpenSSL::SSLContext::GetInstance(); | 350 SSLClientSocketOpenSSL::SSLContext::GetInstance(); |
353 context->session_cache()->Flush(); | 351 context->session_cache()->Flush(); |
354 } | 352 } |
355 | 353 |
356 // static | 354 // static |
357 uint16 SSLClientSocket::GetMaxSupportedSSLVersion() { | 355 uint16 SSLClientSocket::GetMaxSupportedSSLVersion() { |
358 return SSL_PROTOCOL_VERSION_TLS1_2; | 356 return SSL_PROTOCOL_VERSION_TLS1_2; |
359 } | 357 } |
(...skipping 15 matching lines...) Expand all Loading... | |
375 client_auth_cert_needed_(false), | 373 client_auth_cert_needed_(false), |
376 cert_verifier_(context.cert_verifier), | 374 cert_verifier_(context.cert_verifier), |
377 cert_transparency_verifier_(context.cert_transparency_verifier), | 375 cert_transparency_verifier_(context.cert_transparency_verifier), |
378 channel_id_service_(context.channel_id_service), | 376 channel_id_service_(context.channel_id_service), |
379 ssl_(NULL), | 377 ssl_(NULL), |
380 transport_bio_(NULL), | 378 transport_bio_(NULL), |
381 transport_(transport_socket.Pass()), | 379 transport_(transport_socket.Pass()), |
382 host_and_port_(host_and_port), | 380 host_and_port_(host_and_port), |
383 ssl_config_(ssl_config), | 381 ssl_config_(ssl_config), |
384 ssl_session_cache_shard_(context.ssl_session_cache_shard), | 382 ssl_session_cache_shard_(context.ssl_session_cache_shard), |
385 trying_cached_session_(false), | |
386 next_handshake_state_(STATE_NONE), | 383 next_handshake_state_(STATE_NONE), |
387 npn_status_(kNextProtoUnsupported), | 384 npn_status_(kNextProtoUnsupported), |
388 channel_id_xtn_negotiated_(false), | 385 channel_id_xtn_negotiated_(false), |
386 handshake_completed_(false), | |
387 certificate_verified_(false), | |
389 transport_security_state_(context.transport_security_state), | 388 transport_security_state_(context.transport_security_state), |
390 policy_enforcer_(context.cert_policy_enforcer), | 389 policy_enforcer_(context.cert_policy_enforcer), |
391 net_log_(transport_->socket()->NetLog()), | 390 net_log_(transport_->socket()->NetLog()), |
392 weak_factory_(this) { | 391 weak_factory_(this) { |
393 } | 392 } |
394 | 393 |
395 SSLClientSocketOpenSSL::~SSLClientSocketOpenSSL() { | 394 SSLClientSocketOpenSSL::~SSLClientSocketOpenSSL() { |
396 Disconnect(); | 395 Disconnect(); |
397 } | 396 } |
398 | 397 |
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
692 SSLContext* context = SSLContext::GetInstance(); | 691 SSLContext* context = SSLContext::GetInstance(); |
693 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); | 692 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); |
694 | 693 |
695 ssl_ = SSL_new(context->ssl_ctx()); | 694 ssl_ = SSL_new(context->ssl_ctx()); |
696 if (!ssl_ || !context->SetClientSocketForSSL(ssl_, this)) | 695 if (!ssl_ || !context->SetClientSocketForSSL(ssl_, this)) |
697 return ERR_UNEXPECTED; | 696 return ERR_UNEXPECTED; |
698 | 697 |
699 if (!SSL_set_tlsext_host_name(ssl_, host_and_port_.host().c_str())) | 698 if (!SSL_set_tlsext_host_name(ssl_, host_and_port_.host().c_str())) |
700 return ERR_UNEXPECTED; | 699 return ERR_UNEXPECTED; |
701 | 700 |
702 trying_cached_session_ = context->session_cache()->SetSSLSessionWithKey( | 701 SSL_SESSION* session = context->session_cache()->Lookup(GetSessionCacheKey()); |
703 ssl_, GetSessionCacheKey()); | 702 if (session != nullptr) |
703 SSL_set_session(ssl_, session); | |
704 | 704 |
705 send_buffer_ = new GrowableIOBuffer(); | 705 send_buffer_ = new GrowableIOBuffer(); |
706 send_buffer_->SetCapacity(KDefaultOpenSSLBufferSize); | 706 send_buffer_->SetCapacity(KDefaultOpenSSLBufferSize); |
707 recv_buffer_ = new GrowableIOBuffer(); | 707 recv_buffer_ = new GrowableIOBuffer(); |
708 recv_buffer_->SetCapacity(KDefaultOpenSSLBufferSize); | 708 recv_buffer_->SetCapacity(KDefaultOpenSSLBufferSize); |
709 | 709 |
710 BIO* ssl_bio = NULL; | 710 BIO* ssl_bio = NULL; |
711 | 711 |
712 // SSLClientSocketOpenSSL retains ownership of the BIO buffers. | 712 // SSLClientSocketOpenSSL retains ownership of the BIO buffers. |
713 if (!BIO_new_bio_pair_external_buf( | 713 if (!BIO_new_bio_pair_external_buf( |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
925 rv = SSL_do_handshake(ssl_); | 925 rv = SSL_do_handshake(ssl_); |
926 } | 926 } |
927 } | 927 } |
928 | 928 |
929 if (rv == 1) { | 929 if (rv == 1) { |
930 // TODO(vadimt): Remove ScopedTracker below once crbug.com/424386 is fixed. | 930 // TODO(vadimt): Remove ScopedTracker below once crbug.com/424386 is fixed. |
931 tracked_objects::ScopedTracker tracking_profile3( | 931 tracked_objects::ScopedTracker tracking_profile3( |
932 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 932 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
933 "424386 SSLClientSocketOpenSSL::DoHandshake3")); | 933 "424386 SSLClientSocketOpenSSL::DoHandshake3")); |
934 | 934 |
935 if (trying_cached_session_ && logging::DEBUG_MODE) { | |
936 DVLOG(2) << "Result of session reuse for " << host_and_port_.ToString() | |
937 << " is: " << (SSL_session_reused(ssl_) ? "Success" : "Fail"); | |
938 } | |
939 | |
940 if (ssl_config_.version_fallback && | 935 if (ssl_config_.version_fallback && |
941 ssl_config_.version_max < ssl_config_.version_fallback_min) { | 936 ssl_config_.version_max < ssl_config_.version_fallback_min) { |
942 return ERR_SSL_FALLBACK_BEYOND_MINIMUM_VERSION; | 937 return ERR_SSL_FALLBACK_BEYOND_MINIMUM_VERSION; |
943 } | 938 } |
944 | 939 |
945 // SSL handshake is completed. If NPN wasn't negotiated, see if ALPN was. | 940 // SSL handshake is completed. If NPN wasn't negotiated, see if ALPN was. |
946 if (npn_status_ == kNextProtoUnsupported) { | 941 if (npn_status_ == kNextProtoUnsupported) { |
947 const uint8_t* alpn_proto = NULL; | 942 const uint8_t* alpn_proto = NULL; |
948 unsigned alpn_len = 0; | 943 unsigned alpn_len = 0; |
949 SSL_get0_alpn_selected(ssl_, &alpn_proto, &alpn_len); | 944 SSL_get0_alpn_selected(ssl_, &alpn_proto, &alpn_len); |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1157 server_cert_verify_result_.public_key_hashes, | 1152 server_cert_verify_result_.public_key_hashes, |
1158 &pinning_failure_log_)) { | 1153 &pinning_failure_log_)) { |
1159 result = ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN; | 1154 result = ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN; |
1160 } | 1155 } |
1161 | 1156 |
1162 if (result == OK) { | 1157 if (result == OK) { |
1163 // Only check Certificate Transparency if there were no other errors with | 1158 // Only check Certificate Transparency if there were no other errors with |
1164 // the connection. | 1159 // the connection. |
1165 VerifyCT(); | 1160 VerifyCT(); |
1166 | 1161 |
1167 // TODO(joth): Work out if we need to remember the intermediate CA certs | 1162 DCHECK(!certificate_verified_); |
1168 // when the server sends them to us, and do so here. | 1163 certificate_verified_ = true; |
1169 SSLContext::GetInstance()->session_cache()->MarkSSLSessionAsGood(ssl_); | 1164 MaybeCacheSession(); |
1170 } else { | 1165 } else { |
1171 DVLOG(1) << "DoVerifyCertComplete error " << ErrorToString(result) | 1166 DVLOG(1) << "DoVerifyCertComplete error " << ErrorToString(result) |
1172 << " (" << result << ")"; | 1167 << " (" << result << ")"; |
1173 } | 1168 } |
1174 | 1169 |
1175 completed_connect_ = true; | 1170 completed_connect_ = true; |
1176 // Exit DoHandshakeLoop and return the result to the caller to Connect. | 1171 // Exit DoHandshakeLoop and return the result to the caller to Connect. |
1177 DCHECK_EQ(STATE_NONE, next_handshake_state_); | 1172 DCHECK_EQ(STATE_NONE, next_handshake_state_); |
1178 return result; | 1173 return result; |
1179 } | 1174 } |
(...skipping 711 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1891 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 1886 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
1892 "424386 SSLClientSocketOpenSSL::BIOCallback")); | 1887 "424386 SSLClientSocketOpenSSL::BIOCallback")); |
1893 | 1888 |
1894 SSLClientSocketOpenSSL* socket = reinterpret_cast<SSLClientSocketOpenSSL*>( | 1889 SSLClientSocketOpenSSL* socket = reinterpret_cast<SSLClientSocketOpenSSL*>( |
1895 BIO_get_callback_arg(bio)); | 1890 BIO_get_callback_arg(bio)); |
1896 CHECK(socket); | 1891 CHECK(socket); |
1897 return socket->MaybeReplayTransportError( | 1892 return socket->MaybeReplayTransportError( |
1898 bio, cmd, argp, argi, argl, retvalue); | 1893 bio, cmd, argp, argi, argl, retvalue); |
1899 } | 1894 } |
1900 | 1895 |
1896 void SSLClientSocketOpenSSL::MaybeCacheSession() { | |
1897 // Only cache the session once both the handshake has completed and the | |
1898 // certificate has been verified. | |
1899 if (!handshake_completed_ || !certificate_verified_ || | |
1900 SSL_session_reused(ssl_)) { | |
1901 return; | |
1902 } | |
1903 | |
1904 SSLContext::GetInstance()->session_cache()->Insert(GetSessionCacheKey(), | |
1905 SSL_get_session(ssl_)); | |
1906 } | |
1907 | |
1908 void SSLClientSocketOpenSSL::InfoCallback(int type, int val) { | |
1909 // Note that SSL_CB_HANDSHAKE_DONE may be signaled multiple times if the | |
1910 // socket renegotiates. | |
1911 if (type != SSL_CB_HANDSHAKE_DONE || handshake_completed_) | |
1912 return; | |
1913 | |
1914 handshake_completed_ = true; | |
1915 MaybeCacheSession(); | |
1916 } | |
1917 | |
1901 void SSLClientSocketOpenSSL::AddSCTInfoToSSLInfo(SSLInfo* ssl_info) const { | 1918 void SSLClientSocketOpenSSL::AddSCTInfoToSSLInfo(SSLInfo* ssl_info) const { |
1902 for (ct::SCTList::const_iterator iter = | 1919 for (ct::SCTList::const_iterator iter = |
1903 ct_verify_result_.verified_scts.begin(); | 1920 ct_verify_result_.verified_scts.begin(); |
1904 iter != ct_verify_result_.verified_scts.end(); ++iter) { | 1921 iter != ct_verify_result_.verified_scts.end(); ++iter) { |
1905 ssl_info->signed_certificate_timestamps.push_back( | 1922 ssl_info->signed_certificate_timestamps.push_back( |
1906 SignedCertificateTimestampAndStatus(*iter, ct::SCT_STATUS_OK)); | 1923 SignedCertificateTimestampAndStatus(*iter, ct::SCT_STATUS_OK)); |
1907 } | 1924 } |
1908 for (ct::SCTList::const_iterator iter = | 1925 for (ct::SCTList::const_iterator iter = |
1909 ct_verify_result_.invalid_scts.begin(); | 1926 ct_verify_result_.invalid_scts.begin(); |
1910 iter != ct_verify_result_.invalid_scts.end(); ++iter) { | 1927 iter != ct_verify_result_.invalid_scts.end(); ++iter) { |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1947 | 1964 |
1948 return result; | 1965 return result; |
1949 } | 1966 } |
1950 | 1967 |
1951 scoped_refptr<X509Certificate> | 1968 scoped_refptr<X509Certificate> |
1952 SSLClientSocketOpenSSL::GetUnverifiedServerCertificateChain() const { | 1969 SSLClientSocketOpenSSL::GetUnverifiedServerCertificateChain() const { |
1953 return server_cert_; | 1970 return server_cert_; |
1954 } | 1971 } |
1955 | 1972 |
1956 } // namespace net | 1973 } // namespace net |
OLD | NEW |