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