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 |