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

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

Issue 135373002: Added SSLHostInfo. Storing of server host info to our standard disk cache. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fixed wtc's comments Created 6 years, 11 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 | Annotate | Revision Log
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 // This file includes code SSLClientSocketNSS::DoVerifyCertComplete() derived 5 // This file includes code SSLClientSocketNSS::DoVerifyCertComplete() derived
6 // from AuthCertificateCallback() in 6 // from AuthCertificateCallback() in
7 // mozilla/security/manager/ssl/src/nsNSSCallbacks.cpp. 7 // mozilla/security/manager/ssl/src/nsNSSCallbacks.cpp.
8 8
9 /* ***** BEGIN LICENSE BLOCK ***** 9 /* ***** BEGIN LICENSE BLOCK *****
10 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 10 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
99 #include "net/cert/scoped_nss_types.h" 99 #include "net/cert/scoped_nss_types.h"
100 #include "net/cert/sct_status_flags.h" 100 #include "net/cert/sct_status_flags.h"
101 #include "net/cert/single_request_cert_verifier.h" 101 #include "net/cert/single_request_cert_verifier.h"
102 #include "net/cert/x509_certificate_net_log_param.h" 102 #include "net/cert/x509_certificate_net_log_param.h"
103 #include "net/cert/x509_util.h" 103 #include "net/cert/x509_util.h"
104 #include "net/http/transport_security_state.h" 104 #include "net/http/transport_security_state.h"
105 #include "net/ocsp/nss_ocsp.h" 105 #include "net/ocsp/nss_ocsp.h"
106 #include "net/socket/client_socket_handle.h" 106 #include "net/socket/client_socket_handle.h"
107 #include "net/socket/nss_ssl_util.h" 107 #include "net/socket/nss_ssl_util.h"
108 #include "net/socket/ssl_error_params.h" 108 #include "net/socket/ssl_error_params.h"
109 #include "net/socket/ssl_host_info.h"
109 #include "net/ssl/ssl_cert_request_info.h" 110 #include "net/ssl/ssl_cert_request_info.h"
110 #include "net/ssl/ssl_connection_status_flags.h" 111 #include "net/ssl/ssl_connection_status_flags.h"
111 #include "net/ssl/ssl_info.h" 112 #include "net/ssl/ssl_info.h"
112 113
113 #if defined(OS_WIN) 114 #if defined(OS_WIN)
114 #include <windows.h> 115 #include <windows.h>
115 #include <wincrypt.h> 116 #include <wincrypt.h>
116 117
117 #include "base/win/windows_version.h" 118 #include "base/win/windows_version.h"
118 #elif defined(OS_MACOSX) 119 #elif defined(OS_MACOSX)
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after
406 struct HandshakeState { 407 struct HandshakeState {
407 HandshakeState() { Reset(); } 408 HandshakeState() { Reset(); }
408 409
409 void Reset() { 410 void Reset() {
410 next_proto_status = SSLClientSocket::kNextProtoUnsupported; 411 next_proto_status = SSLClientSocket::kNextProtoUnsupported;
411 next_proto.clear(); 412 next_proto.clear();
412 server_protos.clear(); 413 server_protos.clear();
413 channel_id_sent = false; 414 channel_id_sent = false;
414 server_cert_chain.Reset(NULL); 415 server_cert_chain.Reset(NULL);
415 server_cert = NULL; 416 server_cert = NULL;
417 predicted_cert_chain_correct = false;
416 sct_list_from_tls_extension.clear(); 418 sct_list_from_tls_extension.clear();
417 stapled_ocsp_response.clear(); 419 stapled_ocsp_response.clear();
418 resumed_handshake = false; 420 resumed_handshake = false;
419 ssl_connection_status = 0; 421 ssl_connection_status = 0;
420 } 422 }
421 423
422 // Set to kNextProtoNegotiated if NPN was successfully negotiated, with the 424 // Set to kNextProtoNegotiated if NPN was successfully negotiated, with the
423 // negotiated protocol stored in |next_proto|. 425 // negotiated protocol stored in |next_proto|.
424 SSLClientSocket::NextProtoStatus next_proto_status; 426 SSLClientSocket::NextProtoStatus next_proto_status;
425 std::string next_proto; 427 std::string next_proto;
(...skipping 11 matching lines...) Expand all
437 // 439 //
438 // The server certificate is first received from NSS as an NSS certificate 440 // The server certificate is first received from NSS as an NSS certificate
439 // chain (|server_cert_chain|) and then converted into a platform-specific 441 // chain (|server_cert_chain|) and then converted into a platform-specific
440 // X509Certificate object (|server_cert|). It's possible for some 442 // X509Certificate object (|server_cert|). It's possible for some
441 // certificates to be successfully parsed by NSS, and not by the platform 443 // certificates to be successfully parsed by NSS, and not by the platform
442 // libraries (i.e.: when running within a sandbox, different parsing 444 // libraries (i.e.: when running within a sandbox, different parsing
443 // algorithms, etc), so it's not safe to assume that |server_cert| will 445 // algorithms, etc), so it's not safe to assume that |server_cert| will
444 // always be non-NULL. 446 // always be non-NULL.
445 PeerCertificateChain server_cert_chain; 447 PeerCertificateChain server_cert_chain;
446 scoped_refptr<X509Certificate> server_cert; 448 scoped_refptr<X509Certificate> server_cert;
449 // True if we predicted a certificate chain (via
450 // Core::SetPredictedCertificates) and that prediction matched what the
451 // server sent.
452 bool predicted_cert_chain_correct;
447 // SignedCertificateTimestampList received via TLS extension (RFC 6962). 453 // SignedCertificateTimestampList received via TLS extension (RFC 6962).
448 std::string sct_list_from_tls_extension; 454 std::string sct_list_from_tls_extension;
449 // Stapled OCSP response received. 455 // Stapled OCSP response received.
450 std::string stapled_ocsp_response; 456 std::string stapled_ocsp_response;
451 457
452 // True if the current handshake was the result of TLS session resumption. 458 // True if the current handshake was the result of TLS session resumption.
453 bool resumed_handshake; 459 bool resumed_handshake;
454 460
455 // The negotiated security parameters (TLS version, cipher, extensions) of 461 // The negotiated security parameters (TLS version, cipher, extensions) of
456 // the SSL connection. 462 // the SSL connection.
(...skipping 1189 matching lines...) Expand 10 before | Expand all | Expand 10 after
1646 nss_handshake_state_.resumed_handshake = false; 1652 nss_handshake_state_.resumed_handshake = false;
1647 } 1653 }
1648 1654
1649 RecordChannelIDSupportOnNSSTaskRunner(); 1655 RecordChannelIDSupportOnNSSTaskRunner();
1650 UpdateServerCert(); 1656 UpdateServerCert();
1651 UpdateSignedCertTimestamps(); 1657 UpdateSignedCertTimestamps();
1652 UpdateStapledOCSPResponse(); 1658 UpdateStapledOCSPResponse();
1653 UpdateConnectionStatus(); 1659 UpdateConnectionStatus();
1654 UpdateNextProto(); 1660 UpdateNextProto();
1655 1661
1662 // We need to see if the predicted certificate chain (from
1663 // SetPredictedCertificates) matches the actual certificate chain.
1664 nss_handshake_state_.predicted_cert_chain_correct = false;
1665 if (!predicted_certs_.empty()) {
1666 PeerCertificateChain& certs = nss_handshake_state_.server_cert_chain;
1667 nss_handshake_state_.predicted_cert_chain_correct =
1668 certs.size() == predicted_certs_.size();
1669
1670 if (nss_handshake_state_.predicted_cert_chain_correct) {
1671 for (unsigned i = 0; i < certs.size(); i++) {
1672 if (certs[i]->derCert.len != predicted_certs_[i].size() ||
1673 memcmp(certs[i]->derCert.data, predicted_certs_[i].data(),
1674 certs[i]->derCert.len) != 0) {
1675 nss_handshake_state_.predicted_cert_chain_correct = false;
1676 break;
1677 }
1678 }
1679 }
1680 }
1681
1656 // Update the network task runners view of the handshake state whenever 1682 // Update the network task runners view of the handshake state whenever
1657 // a handshake has completed. 1683 // a handshake has completed.
1658 PostOrRunCallback( 1684 PostOrRunCallback(
1659 FROM_HERE, base::Bind(&Core::OnHandshakeStateUpdated, this, 1685 FROM_HERE, base::Bind(&Core::OnHandshakeStateUpdated, this,
1660 nss_handshake_state_)); 1686 nss_handshake_state_));
1661 } 1687 }
1662 1688
1663 int SSLClientSocketNSS::Core::HandleNSSError(PRErrorCode nss_error, 1689 int SSLClientSocketNSS::Core::HandleNSSError(PRErrorCode nss_error,
1664 bool handshake_error) { 1690 bool handshake_error) {
1665 DCHECK(OnNSSTaskRunner()); 1691 DCHECK(OnNSSTaskRunner());
(...skipping 725 matching lines...) Expand 10 before | Expand all | Expand 10 after
2391 SSL_PeerStapledOCSPResponses(nss_fd_); 2417 SSL_PeerStapledOCSPResponses(nss_fd_);
2392 if (!ocsp_responses || !ocsp_responses->len) 2418 if (!ocsp_responses || !ocsp_responses->len)
2393 return; 2419 return;
2394 2420
2395 nss_handshake_state_.stapled_ocsp_response = std::string( 2421 nss_handshake_state_.stapled_ocsp_response = std::string(
2396 reinterpret_cast<char*>(ocsp_responses->items[0].data), 2422 reinterpret_cast<char*>(ocsp_responses->items[0].data),
2397 ocsp_responses->items[0].len); 2423 ocsp_responses->items[0].len);
2398 2424
2399 // TODO(agl): figure out how to plumb an OCSP response into the Mac 2425 // TODO(agl): figure out how to plumb an OCSP response into the Mac
2400 // system library and update IsOCSPStaplingSupported for Mac. 2426 // system library and update IsOCSPStaplingSupported for Mac.
2401 if (IsOCSPStaplingSupported()) { 2427 if (!nss_handshake_state_.predicted_cert_chain_correct &&
2428 IsOCSPStaplingSupported()) {
2402 #if defined(OS_WIN) 2429 #if defined(OS_WIN)
2403 if (nss_handshake_state_.server_cert) { 2430 if (nss_handshake_state_.server_cert) {
2404 CRYPT_DATA_BLOB ocsp_response_blob; 2431 CRYPT_DATA_BLOB ocsp_response_blob;
2405 ocsp_response_blob.cbData = ocsp_responses->items[0].len; 2432 ocsp_response_blob.cbData = ocsp_responses->items[0].len;
2406 ocsp_response_blob.pbData = ocsp_responses->items[0].data; 2433 ocsp_response_blob.pbData = ocsp_responses->items[0].data;
2407 BOOL ok = CertSetCertificateContextProperty( 2434 BOOL ok = CertSetCertificateContextProperty(
2408 nss_handshake_state_.server_cert->os_cert_handle(), 2435 nss_handshake_state_.server_cert->os_cert_handle(),
2409 CERT_OCSP_RESPONSE_PROP_ID, 2436 CERT_OCSP_RESPONSE_PROP_ID,
2410 CERT_SET_PROPERTY_IGNORE_PERSIST_ERROR_FLAG, 2437 CERT_SET_PROPERTY_IGNORE_PERSIST_ERROR_FLAG,
2411 &ocsp_response_blob); 2438 &ocsp_response_blob);
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after
2762 PostOrRunCallback( 2789 PostOrRunCallback(
2763 FROM_HERE, base::Bind(&Core::OnHandshakeStateUpdated, this, 2790 FROM_HERE, base::Bind(&Core::OnHandshakeStateUpdated, this,
2764 nss_handshake_state_)); 2791 nss_handshake_state_));
2765 } 2792 }
2766 2793
2767 SSLClientSocketNSS::SSLClientSocketNSS( 2794 SSLClientSocketNSS::SSLClientSocketNSS(
2768 base::SequencedTaskRunner* nss_task_runner, 2795 base::SequencedTaskRunner* nss_task_runner,
2769 scoped_ptr<ClientSocketHandle> transport_socket, 2796 scoped_ptr<ClientSocketHandle> transport_socket,
2770 const HostPortPair& host_and_port, 2797 const HostPortPair& host_and_port,
2771 const SSLConfig& ssl_config, 2798 const SSLConfig& ssl_config,
2799 SSLHostInfo* ssl_host_info,
2772 const SSLClientSocketContext& context) 2800 const SSLClientSocketContext& context)
2773 : nss_task_runner_(nss_task_runner), 2801 : nss_task_runner_(nss_task_runner),
2774 transport_(transport_socket.Pass()), 2802 transport_(transport_socket.Pass()),
2775 host_and_port_(host_and_port), 2803 host_and_port_(host_and_port),
2776 ssl_config_(ssl_config), 2804 ssl_config_(ssl_config),
2805 server_cert_verify_result_(NULL),
2777 cert_verifier_(context.cert_verifier), 2806 cert_verifier_(context.cert_verifier),
2778 cert_transparency_verifier_(context.cert_transparency_verifier), 2807 cert_transparency_verifier_(context.cert_transparency_verifier),
2779 server_bound_cert_service_(context.server_bound_cert_service), 2808 server_bound_cert_service_(context.server_bound_cert_service),
2780 ssl_session_cache_shard_(context.ssl_session_cache_shard), 2809 ssl_session_cache_shard_(context.ssl_session_cache_shard),
2781 completed_handshake_(false), 2810 completed_handshake_(false),
2782 next_handshake_state_(STATE_NONE), 2811 next_handshake_state_(STATE_NONE),
2783 nss_fd_(NULL), 2812 nss_fd_(NULL),
2784 net_log_(transport_->socket()->NetLog()), 2813 net_log_(transport_->socket()->NetLog()),
2814 ssl_host_info_(ssl_host_info),
2785 transport_security_state_(context.transport_security_state), 2815 transport_security_state_(context.transport_security_state),
2786 valid_thread_id_(base::kInvalidThreadId) { 2816 valid_thread_id_(base::kInvalidThreadId) {
2787 EnterFunction(""); 2817 EnterFunction("");
2788 InitCore(); 2818 InitCore();
2789 LeaveFunction(""); 2819 LeaveFunction("");
2790 } 2820 }
2791 2821
2792 SSLClientSocketNSS::~SSLClientSocketNSS() { 2822 SSLClientSocketNSS::~SSLClientSocketNSS() {
2793 EnterFunction(""); 2823 EnterFunction("");
2794 Disconnect(); 2824 Disconnect();
(...skipping 11 matching lines...) Expand all
2806 } 2836 }
2807 2837
2808 bool SSLClientSocketNSS::GetSSLInfo(SSLInfo* ssl_info) { 2838 bool SSLClientSocketNSS::GetSSLInfo(SSLInfo* ssl_info) {
2809 EnterFunction(""); 2839 EnterFunction("");
2810 ssl_info->Reset(); 2840 ssl_info->Reset();
2811 if (core_->state().server_cert_chain.empty() || 2841 if (core_->state().server_cert_chain.empty() ||
2812 !core_->state().server_cert_chain[0]) { 2842 !core_->state().server_cert_chain[0]) {
2813 return false; 2843 return false;
2814 } 2844 }
2815 2845
2816 ssl_info->cert_status = server_cert_verify_result_.cert_status; 2846 ssl_info->cert_status = server_cert_verify_result_->cert_status;
2817 ssl_info->cert = server_cert_verify_result_.verified_cert; 2847 ssl_info->cert = server_cert_verify_result_->verified_cert;
2818 2848
2819 AddSCTInfoToSSLInfo(ssl_info); 2849 AddSCTInfoToSSLInfo(ssl_info);
2820 2850
2821 ssl_info->connection_status = 2851 ssl_info->connection_status =
2822 core_->state().ssl_connection_status; 2852 core_->state().ssl_connection_status;
2823 ssl_info->public_key_hashes = server_cert_verify_result_.public_key_hashes; 2853 ssl_info->public_key_hashes = server_cert_verify_result_->public_key_hashes;
2824 ssl_info->is_issued_by_known_root = 2854 ssl_info->is_issued_by_known_root =
2825 server_cert_verify_result_.is_issued_by_known_root; 2855 server_cert_verify_result_->is_issued_by_known_root;
2826 ssl_info->client_cert_sent = 2856 ssl_info->client_cert_sent =
2827 ssl_config_.send_client_cert && ssl_config_.client_cert.get(); 2857 ssl_config_.send_client_cert && ssl_config_.client_cert.get();
2828 ssl_info->channel_id_sent = WasChannelIDSent(); 2858 ssl_info->channel_id_sent = WasChannelIDSent();
2829 2859
2830 PRUint16 cipher_suite = SSLConnectionStatusToCipherSuite( 2860 PRUint16 cipher_suite = SSLConnectionStatusToCipherSuite(
2831 core_->state().ssl_connection_status); 2861 core_->state().ssl_connection_status);
2832 SSLCipherSuiteInfo cipher_info; 2862 SSLCipherSuiteInfo cipher_info;
2833 SECStatus ok = SSL_GetCipherSuiteInfo(cipher_suite, 2863 SECStatus ok = SSL_GetCipherSuiteInfo(cipher_suite,
2834 &cipher_info, sizeof(cipher_info)); 2864 &cipher_info, sizeof(cipher_info));
2835 if (ok == SECSuccess) { 2865 if (ok == SECSuccess) {
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
2925 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_CONNECT, rv); 2955 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_CONNECT, rv);
2926 return rv; 2956 return rv;
2927 } 2957 }
2928 2958
2929 rv = InitializeSSLPeerName(); 2959 rv = InitializeSSLPeerName();
2930 if (rv != OK) { 2960 if (rv != OK) {
2931 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_CONNECT, rv); 2961 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_CONNECT, rv);
2932 return rv; 2962 return rv;
2933 } 2963 }
2934 2964
2935 GotoState(STATE_HANDSHAKE); 2965 if (ssl_host_info_.get()) {
2966 GotoState(STATE_LOAD_SSL_HOST_INFO);
2967 } else {
2968 GotoState(STATE_HANDSHAKE);
2969 }
2936 2970
2937 rv = DoHandshakeLoop(OK); 2971 rv = DoHandshakeLoop(OK);
2938 if (rv == ERR_IO_PENDING) { 2972 if (rv == ERR_IO_PENDING) {
2939 user_connect_callback_ = callback; 2973 user_connect_callback_ = callback;
2940 } else { 2974 } else {
2941 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_CONNECT, rv); 2975 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_CONNECT, rv);
2942 } 2976 }
2943 2977
2944 LeaveFunction(""); 2978 LeaveFunction("");
2945 return rv > OK ? OK : rv; 2979 return rv > OK ? OK : rv;
2946 } 2980 }
2947 2981
2948 void SSLClientSocketNSS::Disconnect() { 2982 void SSLClientSocketNSS::Disconnect() {
2949 EnterFunction(""); 2983 EnterFunction("");
2950 2984
2951 CHECK(CalledOnValidThread()); 2985 CHECK(CalledOnValidThread());
2952 2986
2953 // Shut down anything that may call us back. 2987 // Shut down anything that may call us back.
2954 core_->Detach(); 2988 core_->Detach();
2955 verifier_.reset(); 2989 verifier_.reset();
2956 transport_->socket()->Disconnect(); 2990 transport_->socket()->Disconnect();
2957 2991
2958 // Reset object state. 2992 // Reset object state.
2959 user_connect_callback_.Reset(); 2993 user_connect_callback_.Reset();
2960 server_cert_verify_result_.Reset(); 2994 local_server_cert_verify_result_.Reset();
2995 server_cert_verify_result_ = NULL;
2961 completed_handshake_ = false; 2996 completed_handshake_ = false;
2962 start_cert_verification_time_ = base::TimeTicks(); 2997 start_cert_verification_time_ = base::TimeTicks();
2963 InitCore(); 2998 InitCore();
2964 2999
2965 LeaveFunction(""); 3000 LeaveFunction("");
2966 } 3001 }
2967 3002
2968 bool SSLClientSocketNSS::IsConnected() const { 3003 bool SSLClientSocketNSS::IsConnected() const {
2969 EnterFunction(""); 3004 EnterFunction("");
2970 bool ret = completed_handshake_ && 3005 bool ret = completed_handshake_ &&
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after
3279 void SSLClientSocketNSS::OnHandshakeIOComplete(int result) { 3314 void SSLClientSocketNSS::OnHandshakeIOComplete(int result) {
3280 EnterFunction(result); 3315 EnterFunction(result);
3281 int rv = DoHandshakeLoop(result); 3316 int rv = DoHandshakeLoop(result);
3282 if (rv != ERR_IO_PENDING) { 3317 if (rv != ERR_IO_PENDING) {
3283 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_CONNECT, rv); 3318 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_CONNECT, rv);
3284 DoConnectCallback(rv); 3319 DoConnectCallback(rv);
3285 } 3320 }
3286 LeaveFunction(""); 3321 LeaveFunction("");
3287 } 3322 }
3288 3323
3324 void SSLClientSocketNSS::LoadSSLHostInfo() {
3325 const SSLHostInfo::State& state(ssl_host_info_->state());
3326
3327 if (state.certs.empty())
3328 return;
3329
3330 /* TODO(rtenneti): Implement the following */
3331 // const std::vector<std::string>& certs_in = state.certs;
3332 // core_->SetPredictedCertificates(certs_in);
3333 }
3334
3335 int SSLClientSocketNSS::DoLoadSSLHostInfo() {
3336 EnterFunction("");
3337 int rv = ssl_host_info_->WaitForDataReady(
3338 base::Bind(&SSLClientSocketNSS::OnHandshakeIOComplete,
3339 base::Unretained(this)));
3340 GotoState(STATE_HANDSHAKE);
3341
3342 if (rv == OK) {
3343 LoadSSLHostInfo();
3344 } else {
3345 DCHECK_EQ(ERR_IO_PENDING, rv);
3346 GotoState(STATE_LOAD_SSL_HOST_INFO);
3347 }
3348
3349 LeaveFunction("");
3350 return rv;
3351 }
3352
3289 int SSLClientSocketNSS::DoHandshakeLoop(int last_io_result) { 3353 int SSLClientSocketNSS::DoHandshakeLoop(int last_io_result) {
3290 EnterFunction(last_io_result); 3354 EnterFunction(last_io_result);
3291 int rv = last_io_result; 3355 int rv = last_io_result;
3292 do { 3356 do {
3293 // Default to STATE_NONE for next state. 3357 // Default to STATE_NONE for next state.
3294 // (This is a quirk carried over from the windows 3358 // (This is a quirk carried over from the windows
3295 // implementation. It makes reading the logs a bit harder.) 3359 // implementation. It makes reading the logs a bit harder.)
3296 // State handlers can and often do call GotoState just 3360 // State handlers can and often do call GotoState just
3297 // to stay in the current state. 3361 // to stay in the current state.
3298 State state = next_handshake_state_; 3362 State state = next_handshake_state_;
3299 GotoState(STATE_NONE); 3363 GotoState(STATE_NONE);
3300 switch (state) { 3364 switch (state) {
3365 case STATE_LOAD_SSL_HOST_INFO:
3366 DCHECK(rv == OK || rv == ERR_IO_PENDING);
3367 rv = DoLoadSSLHostInfo();
3368 break;
3301 case STATE_HANDSHAKE: 3369 case STATE_HANDSHAKE:
3302 rv = DoHandshake(); 3370 rv = DoHandshake();
3303 break; 3371 break;
3304 case STATE_HANDSHAKE_COMPLETE: 3372 case STATE_HANDSHAKE_COMPLETE:
3305 rv = DoHandshakeComplete(rv); 3373 rv = DoHandshakeComplete(rv);
3306 break; 3374 break;
3307 case STATE_VERIFY_CERT: 3375 case STATE_VERIFY_CERT:
3308 DCHECK(rv == OK); 3376 DCHECK(rv == OK);
3309 rv = DoVerifyCert(rv); 3377 rv = DoVerifyCert(rv);
3310 break; 3378 break;
(...skipping 19 matching lines...) Expand all
3330 GotoState(STATE_HANDSHAKE_COMPLETE); 3398 GotoState(STATE_HANDSHAKE_COMPLETE);
3331 3399
3332 LeaveFunction(rv); 3400 LeaveFunction(rv);
3333 return rv; 3401 return rv;
3334 } 3402 }
3335 3403
3336 int SSLClientSocketNSS::DoHandshakeComplete(int result) { 3404 int SSLClientSocketNSS::DoHandshakeComplete(int result) {
3337 EnterFunction(result); 3405 EnterFunction(result);
3338 3406
3339 if (result == OK) { 3407 if (result == OK) {
3408 SaveSSLHostInfo();
3340 // SSL handshake is completed. Let's verify the certificate. 3409 // SSL handshake is completed. Let's verify the certificate.
3341 GotoState(STATE_VERIFY_CERT); 3410 GotoState(STATE_VERIFY_CERT);
3342 // Done! 3411 // Done!
3343 } 3412 }
3344 set_channel_id_sent(core_->state().channel_id_sent); 3413 set_channel_id_sent(core_->state().channel_id_sent);
3345 set_signed_cert_timestamps_received( 3414 set_signed_cert_timestamps_received(
3346 !core_->state().sct_list_from_tls_extension.empty()); 3415 !core_->state().sct_list_from_tls_extension.empty());
3347 set_stapled_ocsp_response_received( 3416 set_stapled_ocsp_response_received(
3348 !core_->state().stapled_ocsp_response.empty()); 3417 !core_->state().stapled_ocsp_response.empty());
3349 3418
(...skipping 10 matching lines...) Expand all
3360 // If the certificate is expected to be bad we can use the expectation as 3429 // If the certificate is expected to be bad we can use the expectation as
3361 // the cert status. 3430 // the cert status.
3362 base::StringPiece der_cert( 3431 base::StringPiece der_cert(
3363 reinterpret_cast<char*>( 3432 reinterpret_cast<char*>(
3364 core_->state().server_cert_chain[0]->derCert.data), 3433 core_->state().server_cert_chain[0]->derCert.data),
3365 core_->state().server_cert_chain[0]->derCert.len); 3434 core_->state().server_cert_chain[0]->derCert.len);
3366 CertStatus cert_status; 3435 CertStatus cert_status;
3367 if (ssl_config_.IsAllowedBadCert(der_cert, &cert_status)) { 3436 if (ssl_config_.IsAllowedBadCert(der_cert, &cert_status)) {
3368 DCHECK(start_cert_verification_time_.is_null()); 3437 DCHECK(start_cert_verification_time_.is_null());
3369 VLOG(1) << "Received an expected bad cert with status: " << cert_status; 3438 VLOG(1) << "Received an expected bad cert with status: " << cert_status;
3370 server_cert_verify_result_.Reset(); 3439 server_cert_verify_result_ = &local_server_cert_verify_result_;
3371 server_cert_verify_result_.cert_status = cert_status; 3440 local_server_cert_verify_result_.Reset();
3372 server_cert_verify_result_.verified_cert = core_->state().server_cert; 3441 local_server_cert_verify_result_.cert_status = cert_status;
3442 local_server_cert_verify_result_.verified_cert =
3443 core_->state().server_cert;
3373 return OK; 3444 return OK;
3374 } 3445 }
3375 3446
3376 // We may have failed to create X509Certificate object if we are 3447 // We may have failed to create X509Certificate object if we are
3377 // running inside sandbox. 3448 // running inside sandbox.
3378 if (!core_->state().server_cert.get()) { 3449 if (!core_->state().server_cert.get()) {
3379 server_cert_verify_result_.Reset(); 3450 server_cert_verify_result_ = &local_server_cert_verify_result_;
3380 server_cert_verify_result_.cert_status = CERT_STATUS_INVALID; 3451 local_server_cert_verify_result_.Reset();
3452 local_server_cert_verify_result_.cert_status = CERT_STATUS_INVALID;
3381 return ERR_CERT_INVALID; 3453 return ERR_CERT_INVALID;
3382 } 3454 }
3383 3455
3384 start_cert_verification_time_ = base::TimeTicks::Now(); 3456 start_cert_verification_time_ = base::TimeTicks::Now();
3385 3457
3458 if (ssl_host_info_.get() && !ssl_host_info_->state().certs.empty() &&
3459 core_->state().predicted_cert_chain_correct) {
3460 // If the SSLHostInfo had a prediction for the certificate chain of this
3461 // server then it will have optimistically started a verification of that
3462 // chain. So, if the prediction was correct, we should wait for that
3463 // verification to finish rather than start our own.
3464 net_log_.AddEvent(NetLog::TYPE_SSL_VERIFICATION_MERGED);
3465 UMA_HISTOGRAM_ENUMERATION("Net.SSLVerificationMerged", 1 /* true */, 2);
3466 base::TimeTicks end_time = ssl_host_info_->verification_end_time();
3467 if (end_time.is_null())
3468 end_time = base::TimeTicks::Now();
3469 UMA_HISTOGRAM_TIMES("Net.SSLVerificationMergedMsSaved",
3470 end_time - ssl_host_info_->verification_start_time());
3471 server_cert_verify_result_ = &ssl_host_info_->cert_verify_result();
3472 return ssl_host_info_->WaitForCertVerification(
3473 base::Bind(&SSLClientSocketNSS::OnHandshakeIOComplete,
3474 base::Unretained(this)));
3475 } else {
3476 UMA_HISTOGRAM_ENUMERATION("Net.SSLVerificationMerged", 0 /* false */, 2);
3477 }
3478
3386 int flags = 0; 3479 int flags = 0;
3387 if (ssl_config_.rev_checking_enabled) 3480 if (ssl_config_.rev_checking_enabled)
3388 flags |= CertVerifier::VERIFY_REV_CHECKING_ENABLED; 3481 flags |= CertVerifier::VERIFY_REV_CHECKING_ENABLED;
3389 if (ssl_config_.verify_ev_cert) 3482 if (ssl_config_.verify_ev_cert)
3390 flags |= CertVerifier::VERIFY_EV_CERT; 3483 flags |= CertVerifier::VERIFY_EV_CERT;
3391 if (ssl_config_.cert_io_enabled) 3484 if (ssl_config_.cert_io_enabled)
3392 flags |= CertVerifier::VERIFY_CERT_IO_ENABLED; 3485 flags |= CertVerifier::VERIFY_CERT_IO_ENABLED;
3393 if (ssl_config_.rev_checking_required_local_anchors) 3486 if (ssl_config_.rev_checking_required_local_anchors)
3394 flags |= CertVerifier::VERIFY_REV_CHECKING_REQUIRED_LOCAL_ANCHORS; 3487 flags |= CertVerifier::VERIFY_REV_CHECKING_REQUIRED_LOCAL_ANCHORS;
3395 verifier_.reset(new SingleRequestCertVerifier(cert_verifier_)); 3488 verifier_.reset(new SingleRequestCertVerifier(cert_verifier_));
3489 server_cert_verify_result_ = &local_server_cert_verify_result_;
3396 return verifier_->Verify( 3490 return verifier_->Verify(
3397 core_->state().server_cert.get(), 3491 core_->state().server_cert.get(),
3398 host_and_port_.host(), 3492 host_and_port_.host(),
3399 flags, 3493 flags,
3400 SSLConfigService::GetCRLSet().get(), 3494 SSLConfigService::GetCRLSet().get(),
3401 &server_cert_verify_result_, 3495 &local_server_cert_verify_result_,
3402 base::Bind(&SSLClientSocketNSS::OnHandshakeIOComplete, 3496 base::Bind(&SSLClientSocketNSS::OnHandshakeIOComplete,
3403 base::Unretained(this)), 3497 base::Unretained(this)),
3404 net_log_); 3498 net_log_);
3405 } 3499 }
3406 3500
3407 // Derived from AuthCertificateCallback() in 3501 // Derived from AuthCertificateCallback() in
3408 // mozilla/source/security/manager/ssl/src/nsNSSCallbacks.cpp. 3502 // mozilla/source/security/manager/ssl/src/nsNSSCallbacks.cpp.
3409 int SSLClientSocketNSS::DoVerifyCertComplete(int result) { 3503 int SSLClientSocketNSS::DoVerifyCertComplete(int result) {
3410 verifier_.reset(); 3504 verifier_.reset();
3411 3505
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
3447 // Perform pin validation if, and only if, all these conditions obtain: 3541 // Perform pin validation if, and only if, all these conditions obtain:
3448 // 3542 //
3449 // * a TransportSecurityState object is available; 3543 // * a TransportSecurityState object is available;
3450 // * the server's certificate chain is valid (or suffers from only a minor 3544 // * the server's certificate chain is valid (or suffers from only a minor
3451 // error); 3545 // error);
3452 // * the server's certificate chain chains up to a known root (i.e. not a 3546 // * the server's certificate chain chains up to a known root (i.e. not a
3453 // user-installed trust anchor); and 3547 // user-installed trust anchor); and
3454 // * the build is recent (very old builds should fail open so that users 3548 // * the build is recent (very old builds should fail open so that users
3455 // have some chance to recover). 3549 // have some chance to recover).
3456 // 3550 //
3457 const CertStatus cert_status = server_cert_verify_result_.cert_status; 3551 const CertStatus cert_status = server_cert_verify_result_->cert_status;
3458 if (transport_security_state_ && 3552 if (transport_security_state_ &&
3459 (result == OK || 3553 (result == OK ||
3460 (IsCertificateError(result) && IsCertStatusMinorError(cert_status))) && 3554 (IsCertificateError(result) && IsCertStatusMinorError(cert_status))) &&
3461 server_cert_verify_result_.is_issued_by_known_root && 3555 server_cert_verify_result_->is_issued_by_known_root &&
3462 TransportSecurityState::IsBuildTimely()) { 3556 TransportSecurityState::IsBuildTimely()) {
3463 bool sni_available = 3557 bool sni_available =
3464 ssl_config_.version_max >= SSL_PROTOCOL_VERSION_TLS1 || 3558 ssl_config_.version_max >= SSL_PROTOCOL_VERSION_TLS1 ||
3465 ssl_config_.version_fallback; 3559 ssl_config_.version_fallback;
3466 const std::string& host = host_and_port_.host(); 3560 const std::string& host = host_and_port_.host();
3467 3561
3468 TransportSecurityState::DomainState domain_state; 3562 TransportSecurityState::DomainState domain_state;
3469 if (transport_security_state_->GetDomainState(host, sni_available, 3563 if (transport_security_state_->GetDomainState(host, sni_available,
3470 &domain_state) && 3564 &domain_state) &&
3471 domain_state.HasPublicKeyPins()) { 3565 domain_state.HasPublicKeyPins()) {
3472 if (!domain_state.CheckPublicKeyPins( 3566 if (!domain_state.CheckPublicKeyPins(
3473 server_cert_verify_result_.public_key_hashes)) { 3567 server_cert_verify_result_->public_key_hashes)) {
3474 result = ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN; 3568 result = ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN;
3475 UMA_HISTOGRAM_BOOLEAN("Net.PublicKeyPinSuccess", false); 3569 UMA_HISTOGRAM_BOOLEAN("Net.PublicKeyPinSuccess", false);
3476 TransportSecurityState::ReportUMAOnPinFailure(host); 3570 TransportSecurityState::ReportUMAOnPinFailure(host);
3477 } else { 3571 } else {
3478 UMA_HISTOGRAM_BOOLEAN("Net.PublicKeyPinSuccess", true); 3572 UMA_HISTOGRAM_BOOLEAN("Net.PublicKeyPinSuccess", true);
3479 } 3573 }
3480 } 3574 }
3481 } 3575 }
3482 #endif 3576 #endif
3483 3577
(...skipping 14 matching lines...) Expand all
3498 } 3592 }
3499 3593
3500 void SSLClientSocketNSS::VerifyCT() { 3594 void SSLClientSocketNSS::VerifyCT() {
3501 if (!cert_transparency_verifier_) 3595 if (!cert_transparency_verifier_)
3502 return; 3596 return;
3503 3597
3504 // Note that this is a completely synchronous operation: The CT Log Verifier 3598 // Note that this is a completely synchronous operation: The CT Log Verifier
3505 // gets all the data it needs for SCT verification and does not do any 3599 // gets all the data it needs for SCT verification and does not do any
3506 // external communication. 3600 // external communication.
3507 int result = cert_transparency_verifier_->Verify( 3601 int result = cert_transparency_verifier_->Verify(
3508 server_cert_verify_result_.verified_cert, 3602 server_cert_verify_result_->verified_cert,
3509 core_->state().stapled_ocsp_response, 3603 core_->state().stapled_ocsp_response,
3510 core_->state().sct_list_from_tls_extension, 3604 core_->state().sct_list_from_tls_extension,
3511 &ct_verify_result_, 3605 &ct_verify_result_,
3512 net_log_); 3606 net_log_);
3513 // TODO(ekasper): wipe stapled_ocsp_response and sct_list_from_tls_extension 3607 // TODO(ekasper): wipe stapled_ocsp_response and sct_list_from_tls_extension
3514 // from the state after verification is complete, to conserve memory. 3608 // from the state after verification is complete, to conserve memory.
3515 3609
3516 VLOG(1) << "CT Verification complete: result " << result 3610 VLOG(1) << "CT Verification complete: result " << result
3517 << " Invalid scts: " << ct_verify_result_.invalid_scts.size() 3611 << " Invalid scts: " << ct_verify_result_.invalid_scts.size()
3518 << " Verified scts: " << ct_verify_result_.verified_scts.size() 3612 << " Verified scts: " << ct_verify_result_.verified_scts.size()
(...skipping 17 matching lines...) Expand all
3536 break; 3630 break;
3537 case SSL_CONNECTION_VERSION_TLS1_1: 3631 case SSL_CONNECTION_VERSION_TLS1_1:
3538 UpdateConnectionTypeHistograms(CONNECTION_SSL_TLS1_1); 3632 UpdateConnectionTypeHistograms(CONNECTION_SSL_TLS1_1);
3539 break; 3633 break;
3540 case SSL_CONNECTION_VERSION_TLS1_2: 3634 case SSL_CONNECTION_VERSION_TLS1_2:
3541 UpdateConnectionTypeHistograms(CONNECTION_SSL_TLS1_2); 3635 UpdateConnectionTypeHistograms(CONNECTION_SSL_TLS1_2);
3542 break; 3636 break;
3543 }; 3637 };
3544 } 3638 }
3545 3639
3640 // SaveSSLHostInfo saves the certificate chain of the connection so that we can
3641 // start verification faster in the future.
3642 void SSLClientSocketNSS::SaveSSLHostInfo() {
3643 if (!ssl_host_info_.get())
3644 return;
3645
3646 // If the SSLHostInfo hasn't managed to load from disk yet then we can't save
3647 // anything.
3648 if (ssl_host_info_->WaitForDataReady(net::CompletionCallback()) != OK)
3649 return;
3650
3651 SSLHostInfo::State* state = ssl_host_info_->mutable_state();
3652
3653 state->certs.clear();
3654 const PeerCertificateChain& certs = core_->state().server_cert_chain;
3655 for (unsigned i = 0; i < certs.size(); i++) {
3656 if (certs[i] == NULL ||
3657 certs[i]->derCert.len > std::numeric_limits<uint16>::max()) {
3658 return;
3659 }
3660
3661 state->certs.push_back(std::string(
3662 reinterpret_cast<char*>(certs[i]->derCert.data),
3663 certs[i]->derCert.len));
3664 }
3665
3666 ssl_host_info_->Persist();
3667 }
3668
3546 void SSLClientSocketNSS::EnsureThreadIdAssigned() const { 3669 void SSLClientSocketNSS::EnsureThreadIdAssigned() const {
3547 base::AutoLock auto_lock(lock_); 3670 base::AutoLock auto_lock(lock_);
3548 if (valid_thread_id_ != base::kInvalidThreadId) 3671 if (valid_thread_id_ != base::kInvalidThreadId)
3549 return; 3672 return;
3550 valid_thread_id_ = base::PlatformThread::CurrentId(); 3673 valid_thread_id_ = base::PlatformThread::CurrentId();
3551 } 3674 }
3552 3675
3553 bool SSLClientSocketNSS::CalledOnValidThread() const { 3676 bool SSLClientSocketNSS::CalledOnValidThread() const {
3554 EnsureThreadIdAssigned(); 3677 EnsureThreadIdAssigned();
3555 base::AutoLock auto_lock(lock_); 3678 base::AutoLock auto_lock(lock_);
(...skipping 20 matching lines...) Expand all
3576 SignedCertificateTimestampAndStatus(*iter, 3699 SignedCertificateTimestampAndStatus(*iter,
3577 ct::SCT_STATUS_LOG_UNKNOWN)); 3700 ct::SCT_STATUS_LOG_UNKNOWN));
3578 } 3701 }
3579 } 3702 }
3580 3703
3581 ServerBoundCertService* SSLClientSocketNSS::GetServerBoundCertService() const { 3704 ServerBoundCertService* SSLClientSocketNSS::GetServerBoundCertService() const {
3582 return server_bound_cert_service_; 3705 return server_bound_cert_service_;
3583 } 3706 }
3584 3707
3585 } // namespace net 3708 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698