| Index: components/security_state/security_state_model.cc
|
| diff --git a/components/security_state/security_state_model.cc b/components/security_state/security_state_model.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..308663f4c529f8151434e7d349f5bbff9c35ccde
|
| --- /dev/null
|
| +++ b/components/security_state/security_state_model.cc
|
| @@ -0,0 +1,185 @@
|
| +// Copyright 2015 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "components/security_state/security_state_model.h"
|
| +
|
| +#include "base/command_line.h"
|
| +#include "base/metrics/field_trial.h"
|
| +#include "base/metrics/histogram_macros.h"
|
| +#include "base/prefs/pref_service.h"
|
| +#include "components/security_state/security_state_model_delegate.h"
|
| +#include "net/ssl/ssl_cipher_suite_names.h"
|
| +#include "net/ssl/ssl_connection_status_flags.h"
|
| +#include "url/gurl.h"
|
| +
|
| +namespace security_state {
|
| +
|
| +namespace {
|
| +
|
| +SHA1DeprecationStatus GetSHA1DeprecationStatus(
|
| + scoped_refptr<net::X509Certificate> cert,
|
| + net::CertStatus cert_status) {
|
| + if (!cert || !(cert_status & net::CERT_STATUS_SHA1_SIGNATURE_PRESENT))
|
| + return NO_DEPRECATED_SHA1;
|
| +
|
| + // The internal representation of the dates for UI treatment of SHA-1.
|
| + // See http://crbug.com/401365 for details.
|
| + static const int64_t kJanuary2017 = INT64_C(13127702400000000);
|
| + if (cert->valid_expiry() >= base::Time::FromInternalValue(kJanuary2017))
|
| + return DEPRECATED_SHA1_MAJOR;
|
| + static const int64_t kJanuary2016 = INT64_C(13096080000000000);
|
| + if (cert->valid_expiry() >= base::Time::FromInternalValue(kJanuary2016))
|
| + return DEPRECATED_SHA1_MINOR;
|
| +
|
| + return NO_DEPRECATED_SHA1;
|
| +}
|
| +
|
| +MixedContentStatus GetMixedContentStatus(bool displayed_insecure_content,
|
| + bool ran_insecure_content) {
|
| + if (ran_insecure_content && displayed_insecure_content)
|
| + return RAN_AND_DISPLAYED_MIXED_CONTENT;
|
| + if (ran_insecure_content)
|
| + return RAN_MIXED_CONTENT;
|
| + if (displayed_insecure_content)
|
| + return DISPLAYED_MIXED_CONTENT;
|
| +
|
| + return NO_MIXED_CONTENT;
|
| +}
|
| +
|
| +SecurityLevel GetSecurityLevelForRequest(
|
| + const GURL& url,
|
| + SecurityStateModelDelegate* delegate,
|
| + net::CertStatus cert_status,
|
| + int connection_status,
|
| + scoped_refptr<net::X509Certificate> cert,
|
| + SHA1DeprecationStatus sha1_status,
|
| + MixedContentStatus mixed_content_status) {
|
| + SecurityLevel security_level = delegate->GetInitialSecurityLevel();
|
| + switch (security_level) {
|
| + case NONE:
|
| + return delegate->GetSecurityLevelForNonSecure(url);
|
| + case SECURITY_ERROR:
|
| + case SECURITY_POLICY_WARNING:
|
| + case SECURITY_WARNING:
|
| + return security_level;
|
| + case EV_SECURE:
|
| + case SECURE: {
|
| + // Report if there is a MITM cert first, before reporting any other
|
| + // authenticated-but-with-errors cases. Such a cert is a strong
|
| + // indicator of a MITM being present (the enterprise), while the
|
| + // other authenticated-but-with-errors indicate something may
|
| + // be wrong, or may be wrong in the future, but is unclear now.
|
| + if (delegate->UsedKnownMITMCertificate())
|
| + return SECURITY_POLICY_WARNING;
|
| +
|
| + if (sha1_status == DEPRECATED_SHA1_MAJOR)
|
| + return SECURITY_ERROR;
|
| + if (sha1_status == DEPRECATED_SHA1_MINOR)
|
| + return NONE;
|
| +
|
| + switch (mixed_content_status) {
|
| + case RAN_MIXED_CONTENT:
|
| + case RAN_AND_DISPLAYED_MIXED_CONTENT:
|
| + // Active mixed content would usually be downgraded to the ERROR level
|
| + // and
|
| + // handled above, but don't assume that embedders enforce that.
|
| + return SecurityStateModel::kRanInsecureContentLevel;
|
| + case DISPLAYED_MIXED_CONTENT:
|
| + return SecurityStateModel::kDisplayedInsecureContentLevel;
|
| + case NO_MIXED_CONTENT:
|
| + break;
|
| + }
|
| +
|
| + if (net::IsCertStatusError(cert_status)) {
|
| + if (net::IsCertStatusMinorError(cert_status))
|
| + return NONE;
|
| + // As with active mixed content, embedders would usually
|
| + // downgrade this to the ERROR level already, but don't assume.
|
| + return SECURITY_ERROR;
|
| + }
|
| +
|
| + if (net::SSLConnectionStatusToVersion(connection_status) ==
|
| + net::SSL_CONNECTION_VERSION_SSL3) {
|
| + // SSLv3 will be removed in the future.
|
| + return SECURITY_WARNING;
|
| + }
|
| + if ((cert_status & net::CERT_STATUS_IS_EV) && cert)
|
| + return EV_SECURE;
|
| + return SECURE;
|
| + }
|
| + }
|
| +
|
| + return NONE;
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +const SecurityLevel SecurityStateModel::kDisplayedInsecureContentLevel = NONE;
|
| +const SecurityLevel SecurityStateModel::kRanInsecureContentLevel =
|
| + SECURITY_ERROR;
|
| +
|
| +SecurityInfo::SecurityInfo()
|
| + : security_level(NONE),
|
| + sha1_deprecation_status(NO_DEPRECATED_SHA1),
|
| + mixed_content_status(NO_MIXED_CONTENT),
|
| + scheme_is_cryptographic(false),
|
| + cert_status(0),
|
| + cert_id(0),
|
| + security_bits(-1),
|
| + connection_status(0),
|
| + is_secure_protocol_and_ciphersuite(false) {}
|
| +
|
| +SecurityInfo::~SecurityInfo() {}
|
| +
|
| +SecurityStateModel::SecurityStateModel() {}
|
| +SecurityStateModel::~SecurityStateModel() {}
|
| +
|
| +void SecurityStateModel::SetDelegate(SecurityStateModelDelegate* delegate) {
|
| + delegate_ = delegate;
|
| +}
|
| +
|
| +const SecurityInfo& SecurityStateModel::GetSecurityInfo() const {
|
| + DCHECK(delegate_);
|
| + scoped_refptr<net::X509Certificate> cert;
|
| + if (!delegate_->VisibleSecurityStateChanged()) {
|
| + // A cert must be present in the CertStore in order for the
|
| + // page/request to be considered EV_SECURE, and the cert might have
|
| + // been removed since the security level was last computed.
|
| + if (security_info_.security_level == EV_SECURE &&
|
| + !delegate_->RetrieveCert(&cert)) {
|
| + security_info_.security_level = SECURE;
|
| + }
|
| + return security_info_;
|
| + }
|
| +
|
| + delegate_->RetrieveCert(&cert);
|
| + security_info_.cert_id = delegate_->GetCertId();
|
| + security_info_.cert_status = delegate_->GetCertStatus();
|
| + security_info_.sha1_deprecation_status =
|
| + GetSHA1DeprecationStatus(cert, security_info_.cert_status);
|
| + security_info_.mixed_content_status = GetMixedContentStatus(
|
| + delegate_->DisplayedMixedContent(), delegate_->RanMixedContent());
|
| + security_info_.security_bits = delegate_->GetSecurityBits();
|
| + security_info_.connection_status = delegate_->GetConnectionStatus();
|
| + security_info_.scheme_is_cryptographic =
|
| + delegate_->GetURL().SchemeIsCryptographic();
|
| + security_info_.is_secure_protocol_and_ciphersuite =
|
| + (net::SSLConnectionStatusToVersion(security_info_.connection_status) >=
|
| + net::SSL_CONNECTION_VERSION_TLS1_2 &&
|
| + net::IsSecureTLSCipherSuite(net::SSLConnectionStatusToCipherSuite(
|
| + security_info_.connection_status)));
|
| +
|
| + security_info_.sct_verify_statuses.clear();
|
| + delegate_->GetSCTVerifyStatuses(&security_info_.sct_verify_statuses);
|
| +
|
| + security_info_.security_level = GetSecurityLevelForRequest(
|
| + delegate_->GetURL(), delegate_, security_info_.cert_status,
|
| + security_info_.connection_status, cert,
|
| + security_info_.sha1_deprecation_status,
|
| + security_info_.mixed_content_status);
|
| +
|
| + return security_info_;
|
| +}
|
| +
|
| +} // namespace security_state
|
|
|