diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-01-29 16:35:13 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-02-01 15:33:35 +0000 |
commit | c8c2d1901aec01e934adf561a9fdf0cc776cdef8 (patch) | |
tree | 9157c3d9815e5870799e070b113813bec53e0535 /chromium/net/socket/ssl_client_socket_impl.cc | |
parent | abefd5095b41dac94ca451d784ab6e27372e981a (diff) | |
download | qtwebengine-chromium-c8c2d1901aec01e934adf561a9fdf0cc776cdef8.tar.gz |
BASELINE: Update Chromium to 64.0.3282.139
Change-Id: I1cae68fe9c94ff7608b26b8382fc19862cdb293a
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'chromium/net/socket/ssl_client_socket_impl.cc')
-rw-r--r-- | chromium/net/socket/ssl_client_socket_impl.cc | 203 |
1 files changed, 85 insertions, 118 deletions
diff --git a/chromium/net/socket/ssl_client_socket_impl.cc b/chromium/net/socket/ssl_client_socket_impl.cc index 44570a14468..54c0c560c96 100644 --- a/chromium/net/socket/ssl_client_socket_impl.cc +++ b/chromium/net/socket/ssl_client_socket_impl.cc @@ -12,6 +12,7 @@ #include "base/bind.h" #include "base/callback_helpers.h" +#include "base/containers/span.h" #include "base/lazy_instance.h" #include "base/macros.h" #include "base/memory/singleton.h" @@ -83,52 +84,12 @@ const uint8_t kTbProtocolVersionMinor = 13; const uint8_t kTbMinProtocolVersionMajor = 0; const uint8_t kTbMinProtocolVersionMinor = 10; -bool EVP_MDToPrivateKeyHash(const EVP_MD* md, SSLPrivateKey::Hash* hash) { - switch (EVP_MD_type(md)) { - case NID_md5_sha1: - *hash = SSLPrivateKey::Hash::MD5_SHA1; - return true; - case NID_sha1: - *hash = SSLPrivateKey::Hash::SHA1; - return true; - case NID_sha256: - *hash = SSLPrivateKey::Hash::SHA256; - return true; - case NID_sha384: - *hash = SSLPrivateKey::Hash::SHA384; - return true; - case NID_sha512: - *hash = SSLPrivateKey::Hash::SHA512; - return true; - default: - return false; - } -} - std::unique_ptr<base::Value> NetLogPrivateKeyOperationCallback( - SSLPrivateKey::Hash hash, + uint16_t algorithm, NetLogCaptureMode mode) { - std::string hash_str; - switch (hash) { - case SSLPrivateKey::Hash::MD5_SHA1: - hash_str = "MD5_SHA1"; - break; - case SSLPrivateKey::Hash::SHA1: - hash_str = "SHA1"; - break; - case SSLPrivateKey::Hash::SHA256: - hash_str = "SHA256"; - break; - case SSLPrivateKey::Hash::SHA384: - hash_str = "SHA384"; - break; - case SSLPrivateKey::Hash::SHA512: - hash_str = "SHA512"; - break; - } - std::unique_ptr<base::DictionaryValue> value(new base::DictionaryValue); - value->SetString("hash", hash_str); + value->SetString("algorithm", SSL_get_signature_algorithm_name( + algorithm, 0 /* exclude curve */)); return std::move(value); } @@ -353,17 +314,16 @@ class SSLClientSocketImpl::SSLContext { return socket->NewSessionCallback(session); } - static ssl_private_key_result_t PrivateKeySignDigestCallback( - SSL* ssl, - uint8_t* out, - size_t* out_len, - size_t max_out, - const EVP_MD* md, - const uint8_t* in, - size_t in_len) { + static ssl_private_key_result_t PrivateKeySignCallback(SSL* ssl, + uint8_t* out, + size_t* out_len, + size_t max_out, + uint16_t algorithm, + const uint8_t* in, + size_t in_len) { SSLClientSocketImpl* socket = GetInstance()->GetClientSocketFromSSL(ssl); - return socket->PrivateKeySignDigestCallback(out, out_len, max_out, md, in, - in_len); + return socket->PrivateKeySignCallback(out, out_len, max_out, algorithm, in, + in_len); } static ssl_private_key_result_t PrivateKeyCompleteCallback(SSL* ssl, @@ -409,13 +369,9 @@ class SSLClientSocketImpl::SSLContext { SSLClientSessionCache session_cache_; }; -// TODO(davidben): Switch from sign_digest to sign. const SSL_PRIVATE_KEY_METHOD SSLClientSocketImpl::SSLContext::kPrivateKeyMethod = { - nullptr /* type (unused) */, - nullptr /* max_signature_len (unused) */, - nullptr /* sign */, - &SSLClientSocketImpl::SSLContext::PrivateKeySignDigestCallback, + &SSLClientSocketImpl::SSLContext::PrivateKeySignCallback, nullptr /* decrypt */, &SSLClientSocketImpl::SSLContext::PrivateKeyCompleteCallback, }; @@ -1542,40 +1498,73 @@ int SSLClientSocketImpl::VerifyCT() { server_cert_verify_result_.verified_cert.get(), ocsp_response, sct_list, &ct_verify_result_.scts, net_log_); - ct_verify_result_.ct_policies_applied = true; - SCTList verified_scts = ct::SCTsMatchingStatus(ct_verify_result_.scts, ct::SCT_STATUS_OK); - ct_verify_result_.cert_policy_compliance = - policy_enforcer_->DoesConformToCertPolicy( - server_cert_verify_result_.verified_cert.get(), verified_scts, - net_log_); - if ((server_cert_verify_result_.cert_status & CERT_STATUS_IS_EV) && - (ct_verify_result_.cert_policy_compliance != - ct::CertPolicyCompliance::CERT_POLICY_COMPLIES_VIA_SCTS)) { - server_cert_verify_result_.cert_status |= CERT_STATUS_CT_COMPLIANCE_FAILED; - server_cert_verify_result_.cert_status &= ~CERT_STATUS_IS_EV; + ct_verify_result_.policy_compliance = policy_enforcer_->CheckCompliance( + server_cert_verify_result_.verified_cert.get(), verified_scts, net_log_); + if (server_cert_verify_result_.cert_status & CERT_STATUS_IS_EV) { + if (ct_verify_result_.policy_compliance != + ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS) { + server_cert_verify_result_.cert_status |= + CERT_STATUS_CT_COMPLIANCE_FAILED; + server_cert_verify_result_.cert_status &= ~CERT_STATUS_IS_EV; + } + + // Record the CT compliance status for connections with EV certificates, to + // distinguish how often EV status is being dropped due to failing CT + // compliance. + if (server_cert_verify_result_.is_issued_by_known_root) { + UMA_HISTOGRAM_ENUMERATION("Net.CertificateTransparency.EVCompliance2.SSL", + ct_verify_result_.policy_compliance, + ct::CTPolicyCompliance::CT_POLICY_MAX); + } } - UMA_HISTOGRAM_ENUMERATION( - "Net.CertificateTransparency.ConnectionComplianceStatus.SSL", - ct_verify_result_.cert_policy_compliance, - ct::CertPolicyCompliance::CERT_POLICY_MAX); + // Record the CT compliance of every connection to get an overall picture of + // how many connections are CT-compliant. + if (server_cert_verify_result_.is_issued_by_known_root) { + UMA_HISTOGRAM_ENUMERATION( + "Net.CertificateTransparency.ConnectionComplianceStatus2.SSL", + ct_verify_result_.policy_compliance, + ct::CTPolicyCompliance::CT_POLICY_MAX); + } - if (transport_security_state_->CheckCTRequirements( + TransportSecurityState::CTRequirementsStatus ct_requirement_status = + transport_security_state_->CheckCTRequirements( host_and_port_, server_cert_verify_result_.is_issued_by_known_root, server_cert_verify_result_.public_key_hashes, server_cert_verify_result_.verified_cert.get(), server_cert_.get(), ct_verify_result_.scts, TransportSecurityState::ENABLE_EXPECT_CT_REPORTS, - ct_verify_result_.cert_policy_compliance) != - TransportSecurityState::CT_REQUIREMENTS_MET) { - server_cert_verify_result_.cert_status |= - CERT_STATUS_CERTIFICATE_TRANSPARENCY_REQUIRED; - return ERR_CERTIFICATE_TRANSPARENCY_REQUIRED; + ct_verify_result_.policy_compliance); + if (ct_requirement_status != TransportSecurityState::CT_NOT_REQUIRED) { + ct_verify_result_.policy_compliance_required = true; + if (server_cert_verify_result_.is_issued_by_known_root) { + // Record the CT compliance of connections for which compliance is + // required; this helps answer the question: "Of all connections that are + // supposed to be serving valid CT information, how many fail to do so?" + UMA_HISTOGRAM_ENUMERATION( + "Net.CertificateTransparency.CTRequiredConnectionComplianceStatus2." + "SSL", + ct_verify_result_.policy_compliance, + ct::CTPolicyCompliance::CT_POLICY_MAX); + } + } else { + ct_verify_result_.policy_compliance_required = false; } + switch (ct_requirement_status) { + case TransportSecurityState::CT_REQUIREMENTS_NOT_MET: + server_cert_verify_result_.cert_status |= + CERT_STATUS_CERTIFICATE_TRANSPARENCY_REQUIRED; + return ERR_CERTIFICATE_TRANSPARENCY_REQUIRED; + case TransportSecurityState::CT_REQUIREMENTS_MET: + case TransportSecurityState::CT_NOT_REQUIRED: + return OK; + } + + NOTREACHED(); return OK; } @@ -1615,33 +1604,10 @@ int SSLClientSocketImpl::ClientCertRequestCallback(SSL* ssl) { return -1; } - std::vector<SSLPrivateKey::Hash> digest_prefs = - ssl_config_.client_private_key->GetDigestPreferences(); - - size_t digests_len = digest_prefs.size(); - std::vector<int> digests; - for (size_t i = 0; i < digests_len; i++) { - switch (digest_prefs[i]) { - case SSLPrivateKey::Hash::SHA1: - digests.push_back(NID_sha1); - break; - case SSLPrivateKey::Hash::SHA256: - digests.push_back(NID_sha256); - break; - case SSLPrivateKey::Hash::SHA384: - digests.push_back(NID_sha384); - break; - case SSLPrivateKey::Hash::SHA512: - digests.push_back(NID_sha512); - break; - case SSLPrivateKey::Hash::MD5_SHA1: - // MD5-SHA1 is not used in TLS 1.2. - break; - } - } - - SSL_set_private_key_digest_prefs(ssl_.get(), digests.data(), - digests.size()); + std::vector<uint16_t> preferences = + ssl_config_.client_private_key->GetAlgorithmPreferences(); + SSL_set_signing_algorithm_prefs(ssl_.get(), preferences.data(), + preferences.size()); net_log_.AddEvent( NetLogEventType::SSL_CLIENT_CERT_PROVIDED, @@ -1716,29 +1682,24 @@ bool SSLClientSocketImpl::IsRenegotiationAllowed() const { return false; } -ssl_private_key_result_t SSLClientSocketImpl::PrivateKeySignDigestCallback( +ssl_private_key_result_t SSLClientSocketImpl::PrivateKeySignCallback( uint8_t* out, size_t* out_len, size_t max_out, - const EVP_MD* md, + uint16_t algorithm, const uint8_t* in, size_t in_len) { DCHECK_EQ(kNoPendingResult, signature_result_); DCHECK(signature_.empty()); DCHECK(ssl_config_.client_private_key); - SSLPrivateKey::Hash hash; - if (!EVP_MDToPrivateKeyHash(md, &hash)) { - OpenSSLPutNetError(FROM_HERE, ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED); - return ssl_private_key_failure; - } - - net_log_.BeginEvent(NetLogEventType::SSL_PRIVATE_KEY_OP, - base::Bind(&NetLogPrivateKeyOperationCallback, hash)); + net_log_.BeginEvent( + NetLogEventType::SSL_PRIVATE_KEY_OP, + base::Bind(&NetLogPrivateKeyOperationCallback, algorithm)); signature_result_ = ERR_IO_PENDING; - ssl_config_.client_private_key->SignDigest( - hash, base::StringPiece(reinterpret_cast<const char*>(in), in_len), + ssl_config_.client_private_key->Sign( + algorithm, base::make_span(in, in_len), base::Bind(&SSLClientSocketImpl::OnPrivateKeyComplete, weak_factory_.GetWeakPtr())); return ssl_private_key_retry; @@ -1968,6 +1929,12 @@ int SSLClientSocketImpl::MapLastOpenSSLError( !certificate_requested_) { net_error = ERR_SSL_PROTOCOL_ERROR; } + + // This error is specific to the client, so map it here. + if (ERR_GET_REASON(info->error_code) == + SSL_R_NO_COMMON_SIGNATURE_ALGORITHMS) { + net_error = ERR_SSL_CLIENT_AUTH_NO_COMMON_ALGORITHMS; + } } return net_error; |