OLD | NEW |
(Empty) | |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "components/security_state/security_state_model.h" |
| 6 |
| 7 #include "base/command_line.h" |
| 8 #include "base/metrics/field_trial.h" |
| 9 #include "base/metrics/histogram_macros.h" |
| 10 #include "base/prefs/pref_service.h" |
| 11 #include "components/security_state/security_state_model_delegate.h" |
| 12 #include "net/ssl/ssl_cipher_suite_names.h" |
| 13 #include "net/ssl/ssl_connection_status_flags.h" |
| 14 #include "url/gurl.h" |
| 15 |
| 16 namespace security_state { |
| 17 |
| 18 namespace { |
| 19 |
| 20 SHA1DeprecationStatus GetSHA1DeprecationStatus( |
| 21 scoped_refptr<net::X509Certificate> cert, |
| 22 net::CertStatus cert_status) { |
| 23 if (!cert || !(cert_status & net::CERT_STATUS_SHA1_SIGNATURE_PRESENT)) |
| 24 return NO_DEPRECATED_SHA1; |
| 25 |
| 26 // The internal representation of the dates for UI treatment of SHA-1. |
| 27 // See http://crbug.com/401365 for details. |
| 28 static const int64_t kJanuary2017 = INT64_C(13127702400000000); |
| 29 if (cert->valid_expiry() >= base::Time::FromInternalValue(kJanuary2017)) |
| 30 return DEPRECATED_SHA1_MAJOR; |
| 31 static const int64_t kJanuary2016 = INT64_C(13096080000000000); |
| 32 if (cert->valid_expiry() >= base::Time::FromInternalValue(kJanuary2016)) |
| 33 return DEPRECATED_SHA1_MINOR; |
| 34 |
| 35 return NO_DEPRECATED_SHA1; |
| 36 } |
| 37 |
| 38 MixedContentStatus GetMixedContentStatus(bool displayed_insecure_content, |
| 39 bool ran_insecure_content) { |
| 40 if (ran_insecure_content && displayed_insecure_content) |
| 41 return RAN_AND_DISPLAYED_MIXED_CONTENT; |
| 42 if (ran_insecure_content) |
| 43 return RAN_MIXED_CONTENT; |
| 44 if (displayed_insecure_content) |
| 45 return DISPLAYED_MIXED_CONTENT; |
| 46 |
| 47 return NO_MIXED_CONTENT; |
| 48 } |
| 49 |
| 50 SecurityLevel GetSecurityLevelForRequest( |
| 51 const GURL& url, |
| 52 SecurityStateModelDelegate* delegate, |
| 53 net::CertStatus cert_status, |
| 54 int connection_status, |
| 55 scoped_refptr<net::X509Certificate> cert, |
| 56 SHA1DeprecationStatus sha1_status, |
| 57 MixedContentStatus mixed_content_status) { |
| 58 SecurityLevel security_level = delegate->GetInitialSecurityLevel(); |
| 59 switch (security_level) { |
| 60 case NONE: |
| 61 return delegate->GetSecurityLevelForNonSecure(url); |
| 62 case SECURITY_ERROR: |
| 63 case SECURITY_POLICY_WARNING: |
| 64 case SECURITY_WARNING: |
| 65 return security_level; |
| 66 case EV_SECURE: |
| 67 case SECURE: { |
| 68 // Report if there is a MITM cert first, before reporting any other |
| 69 // authenticated-but-with-errors cases. Such a cert is a strong |
| 70 // indicator of a MITM being present (the enterprise), while the |
| 71 // other authenticated-but-with-errors indicate something may |
| 72 // be wrong, or may be wrong in the future, but is unclear now. |
| 73 if (delegate->UsedKnownMITMCertificate()) |
| 74 return SECURITY_POLICY_WARNING; |
| 75 |
| 76 if (sha1_status == DEPRECATED_SHA1_MAJOR) |
| 77 return SECURITY_ERROR; |
| 78 if (sha1_status == DEPRECATED_SHA1_MINOR) |
| 79 return NONE; |
| 80 |
| 81 switch (mixed_content_status) { |
| 82 case RAN_MIXED_CONTENT: |
| 83 case RAN_AND_DISPLAYED_MIXED_CONTENT: |
| 84 // Active mixed content would usually be downgraded to the ERROR level |
| 85 // and |
| 86 // handled above, but don't assume that embedders enforce that. |
| 87 return SecurityStateModel::kRanInsecureContentLevel; |
| 88 case DISPLAYED_MIXED_CONTENT: |
| 89 return SecurityStateModel::kDisplayedInsecureContentLevel; |
| 90 case NO_MIXED_CONTENT: |
| 91 break; |
| 92 } |
| 93 |
| 94 if (net::IsCertStatusError(cert_status)) { |
| 95 if (net::IsCertStatusMinorError(cert_status)) |
| 96 return NONE; |
| 97 // As with active mixed content, embedders would usually |
| 98 // downgrade this to the ERROR level already, but don't assume. |
| 99 return SECURITY_ERROR; |
| 100 } |
| 101 |
| 102 if (net::SSLConnectionStatusToVersion(connection_status) == |
| 103 net::SSL_CONNECTION_VERSION_SSL3) { |
| 104 // SSLv3 will be removed in the future. |
| 105 return SECURITY_WARNING; |
| 106 } |
| 107 if ((cert_status & net::CERT_STATUS_IS_EV) && cert) |
| 108 return EV_SECURE; |
| 109 return SECURE; |
| 110 } |
| 111 } |
| 112 |
| 113 return NONE; |
| 114 } |
| 115 |
| 116 } // namespace |
| 117 |
| 118 const SecurityLevel SecurityStateModel::kDisplayedInsecureContentLevel = NONE; |
| 119 const SecurityLevel SecurityStateModel::kRanInsecureContentLevel = |
| 120 SECURITY_ERROR; |
| 121 |
| 122 SecurityInfo::SecurityInfo() |
| 123 : security_level(NONE), |
| 124 sha1_deprecation_status(NO_DEPRECATED_SHA1), |
| 125 mixed_content_status(NO_MIXED_CONTENT), |
| 126 scheme_is_cryptographic(false), |
| 127 cert_status(0), |
| 128 cert_id(0), |
| 129 security_bits(-1), |
| 130 connection_status(0), |
| 131 is_secure_protocol_and_ciphersuite(false) {} |
| 132 |
| 133 SecurityInfo::~SecurityInfo() {} |
| 134 |
| 135 SecurityStateModel::SecurityStateModel() {} |
| 136 SecurityStateModel::~SecurityStateModel() {} |
| 137 |
| 138 void SecurityStateModel::SetDelegate(SecurityStateModelDelegate* delegate) { |
| 139 delegate_ = delegate; |
| 140 } |
| 141 |
| 142 const SecurityInfo& SecurityStateModel::GetSecurityInfo() const { |
| 143 DCHECK(delegate_); |
| 144 scoped_refptr<net::X509Certificate> cert; |
| 145 if (!delegate_->VisibleSecurityStateChanged()) { |
| 146 // A cert must be present in the CertStore in order for the |
| 147 // page/request to be considered EV_SECURE, and the cert might have |
| 148 // been removed since the security level was last computed. |
| 149 if (security_info_.security_level == EV_SECURE && |
| 150 !delegate_->RetrieveCert(&cert)) { |
| 151 security_info_.security_level = SECURE; |
| 152 } |
| 153 return security_info_; |
| 154 } |
| 155 |
| 156 delegate_->RetrieveCert(&cert); |
| 157 security_info_.cert_id = delegate_->GetCertId(); |
| 158 security_info_.cert_status = delegate_->GetCertStatus(); |
| 159 security_info_.sha1_deprecation_status = |
| 160 GetSHA1DeprecationStatus(cert, security_info_.cert_status); |
| 161 security_info_.mixed_content_status = GetMixedContentStatus( |
| 162 delegate_->DisplayedMixedContent(), delegate_->RanMixedContent()); |
| 163 security_info_.security_bits = delegate_->GetSecurityBits(); |
| 164 security_info_.connection_status = delegate_->GetConnectionStatus(); |
| 165 security_info_.scheme_is_cryptographic = |
| 166 delegate_->GetURL().SchemeIsCryptographic(); |
| 167 security_info_.is_secure_protocol_and_ciphersuite = |
| 168 (net::SSLConnectionStatusToVersion(security_info_.connection_status) >= |
| 169 net::SSL_CONNECTION_VERSION_TLS1_2 && |
| 170 net::IsSecureTLSCipherSuite(net::SSLConnectionStatusToCipherSuite( |
| 171 security_info_.connection_status))); |
| 172 |
| 173 security_info_.sct_verify_statuses.clear(); |
| 174 delegate_->GetSCTVerifyStatuses(&security_info_.sct_verify_statuses); |
| 175 |
| 176 security_info_.security_level = GetSecurityLevelForRequest( |
| 177 delegate_->GetURL(), delegate_, security_info_.cert_status, |
| 178 security_info_.connection_status, cert, |
| 179 security_info_.sha1_deprecation_status, |
| 180 security_info_.mixed_content_status); |
| 181 |
| 182 return security_info_; |
| 183 } |
| 184 |
| 185 } // namespace security_state |
OLD | NEW |