| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 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 #include "chrome/browser/ssl/connection_security.h" | 5 #include "chrome/browser/ssl/connection_security.h" |
| 6 | 6 |
| 7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "base/metrics/field_trial.h" | 8 #include "base/metrics/field_trial.h" |
| 9 #include "base/metrics/histogram_macros.h" | 9 #include "base/metrics/histogram_macros.h" |
| 10 #include "base/prefs/pref_service.h" | 10 #include "base/prefs/pref_service.h" |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 64 level = connection_security::SECURITY_ERROR; | 64 level = connection_security::SECURITY_ERROR; |
| 65 } else { | 65 } else { |
| 66 status = NEUTRAL; | 66 status = NEUTRAL; |
| 67 level = connection_security::NONE; | 67 level = connection_security::NONE; |
| 68 } | 68 } |
| 69 | 69 |
| 70 UMA_HISTOGRAM_ENUMERATION(kEnumeration, status, LAST_STATUS); | 70 UMA_HISTOGRAM_ENUMERATION(kEnumeration, status, LAST_STATUS); |
| 71 return level; | 71 return level; |
| 72 } | 72 } |
| 73 | 73 |
| 74 scoped_refptr<net::X509Certificate> GetCertForSSLStatus( |
| 75 const content::SSLStatus& ssl) { |
| 76 scoped_refptr<net::X509Certificate> cert; |
| 77 return content::CertStore::GetInstance()->RetrieveCert(ssl.cert_id, &cert) |
| 78 ? cert |
| 79 : nullptr; |
| 80 } |
| 81 |
| 82 connection_security::SHA1DeprecationStatus GetSHA1DeprecationStatus( |
| 83 scoped_refptr<net::X509Certificate> cert, |
| 84 const content::SSLStatus& ssl) { |
| 85 if (!cert || !(ssl.cert_status & net::CERT_STATUS_SHA1_SIGNATURE_PRESENT)) |
| 86 return connection_security::NO_DEPRECATED_SHA1; |
| 87 |
| 88 // The internal representation of the dates for UI treatment of SHA-1. |
| 89 // See http://crbug.com/401365 for details. |
| 90 static const int64_t kJanuary2017 = INT64_C(13127702400000000); |
| 91 if (cert->valid_expiry() >= base::Time::FromInternalValue(kJanuary2017)) |
| 92 return connection_security::DEPRECATED_SHA1_BROKEN; |
| 93 // kJanuary2016 needs to be kept in sync with |
| 94 // ToolbarModelAndroid::IsDeprecatedSHA1Present(). |
| 95 static const int64_t kJanuary2016 = INT64_C(13096080000000000); |
| 96 if (cert->valid_expiry() >= base::Time::FromInternalValue(kJanuary2016)) |
| 97 return connection_security::DEPRECATED_SHA1_WARNING; |
| 98 |
| 99 return connection_security::NO_DEPRECATED_SHA1; |
| 100 } |
| 101 |
| 102 connection_security::MixedContentStatus GetMixedContentStatus( |
| 103 const content::SSLStatus& ssl) { |
| 104 if (ssl.content_status & content::SSLStatus::RAN_INSECURE_CONTENT) |
| 105 return connection_security::RAN_MIXED_CONTENT; |
| 106 if (ssl.content_status & content::SSLStatus::DISPLAYED_INSECURE_CONTENT) |
| 107 return connection_security::DISPLAYED_MIXED_CONTENT; |
| 108 return connection_security::NO_MIXED_CONTENT; |
| 109 } |
| 110 |
| 74 } // namespace | 111 } // namespace |
| 75 | 112 |
| 76 namespace connection_security { | 113 namespace connection_security { |
| 77 | 114 |
| 78 SecurityLevel GetSecurityLevelForWebContents( | 115 SecurityLevel GetSecurityLevelForWebContents( |
| 79 const content::WebContents* web_contents) { | 116 const content::WebContents* web_contents) { |
| 80 if (!web_contents) | 117 if (!web_contents) |
| 81 return NONE; | 118 return NONE; |
| 82 | 119 |
| 83 content::NavigationEntry* entry = | 120 content::NavigationEntry* entry = |
| (...skipping 22 matching lines...) Expand all Loading... |
| 106 // authenticated-but-with-errors cases. A policy cert is a strong | 143 // authenticated-but-with-errors cases. A policy cert is a strong |
| 107 // indicator of a MITM being present (the enterprise), while the | 144 // indicator of a MITM being present (the enterprise), while the |
| 108 // other authenticated-but-with-errors indicate something may | 145 // other authenticated-but-with-errors indicate something may |
| 109 // be wrong, or may be wrong in the future, but is unclear now. | 146 // be wrong, or may be wrong in the future, but is unclear now. |
| 110 policy::PolicyCertService* service = | 147 policy::PolicyCertService* service = |
| 111 policy::PolicyCertServiceFactory::GetForProfile( | 148 policy::PolicyCertServiceFactory::GetForProfile( |
| 112 Profile::FromBrowserContext(web_contents->GetBrowserContext())); | 149 Profile::FromBrowserContext(web_contents->GetBrowserContext())); |
| 113 if (service && service->UsedPolicyCertificates()) | 150 if (service && service->UsedPolicyCertificates()) |
| 114 return SECURITY_POLICY_WARNING; | 151 return SECURITY_POLICY_WARNING; |
| 115 #endif | 152 #endif |
| 116 scoped_refptr<net::X509Certificate> cert; | 153 |
| 117 if (content::CertStore::GetInstance()->RetrieveCert(ssl.cert_id, &cert) && | 154 scoped_refptr<net::X509Certificate> cert = GetCertForSSLStatus(ssl); |
| 118 (ssl.cert_status & net::CERT_STATUS_SHA1_SIGNATURE_PRESENT)) { | 155 SHA1DeprecationStatus sha1_status = GetSHA1DeprecationStatus(cert, ssl); |
| 119 // The internal representation of the dates for UI treatment of SHA-1. | 156 if (sha1_status == DEPRECATED_SHA1_BROKEN) |
| 120 // See http://crbug.com/401365 for details. | 157 return SECURITY_ERROR; |
| 121 static const int64_t kJanuary2017 = INT64_C(13127702400000000); | 158 if (sha1_status == DEPRECATED_SHA1_WARNING) |
| 122 // kJanuary2016 needs to be kept in sync with | |
| 123 // ToolbarModelAndroid::IsDeprecatedSHA1Present(). | |
| 124 static const int64_t kJanuary2016 = INT64_C(13096080000000000); | |
| 125 if (cert->valid_expiry() >= | |
| 126 base::Time::FromInternalValue(kJanuary2017)) { | |
| 127 return SECURITY_ERROR; | |
| 128 } | |
| 129 if (cert->valid_expiry() >= | |
| 130 base::Time::FromInternalValue(kJanuary2016)) { | |
| 131 return SECURITY_WARNING; | |
| 132 } | |
| 133 } | |
| 134 if (ssl.content_status & content::SSLStatus::DISPLAYED_INSECURE_CONTENT) | |
| 135 return SECURITY_WARNING; | 159 return SECURITY_WARNING; |
| 160 |
| 161 MixedContentStatus mixed_content_status = GetMixedContentStatus(ssl); |
| 162 // Active mixed content is downgraded to the BROKEN style and |
| 163 // handled above. |
| 164 DCHECK_NE(RAN_MIXED_CONTENT, mixed_content_status); |
| 165 if (mixed_content_status == DISPLAYED_MIXED_CONTENT) |
| 166 return SECURITY_WARNING; |
| 167 |
| 136 if (net::IsCertStatusError(ssl.cert_status)) { | 168 if (net::IsCertStatusError(ssl.cert_status)) { |
| 137 DCHECK(net::IsCertStatusMinorError(ssl.cert_status)); | 169 DCHECK(net::IsCertStatusMinorError(ssl.cert_status)); |
| 138 return SECURITY_WARNING; | 170 return SECURITY_WARNING; |
| 139 } | 171 } |
| 140 if (net::SSLConnectionStatusToVersion(ssl.connection_status) == | 172 if (net::SSLConnectionStatusToVersion(ssl.connection_status) == |
| 141 net::SSL_CONNECTION_VERSION_SSL3) { | 173 net::SSL_CONNECTION_VERSION_SSL3) { |
| 142 // SSLv3 will be removed in the future. | 174 // SSLv3 will be removed in the future. |
| 143 return SECURITY_WARNING; | 175 return SECURITY_WARNING; |
| 144 } | 176 } |
| 145 if ((ssl.cert_status & net::CERT_STATUS_IS_EV) && cert) | 177 if ((ssl.cert_status & net::CERT_STATUS_IS_EV) && cert) |
| 146 return EV_SECURE; | 178 return EV_SECURE; |
| 147 return SECURE; | 179 return SECURE; |
| 148 } | 180 } |
| 149 | 181 |
| 150 default: | 182 default: |
| 151 NOTREACHED(); | 183 NOTREACHED(); |
| 152 return NONE; | 184 return NONE; |
| 153 } | 185 } |
| 154 } | 186 } |
| 155 | 187 |
| 156 content::SecurityStyle GetSecurityStyleForWebContents( | 188 void GetSecurityInfoForWebContents(const content::WebContents* web_contents, |
| 157 const content::WebContents* web_contents) { | 189 SecurityInfo* security_info) { |
| 190 content::NavigationEntry* entry = |
| 191 web_contents ? web_contents->GetController().GetVisibleEntry() : nullptr; |
| 192 if (!entry) { |
| 193 security_info->security_style = content::SECURITY_STYLE_UNKNOWN; |
| 194 return; |
| 195 } |
| 196 |
| 158 SecurityLevel security_level = GetSecurityLevelForWebContents(web_contents); | 197 SecurityLevel security_level = GetSecurityLevelForWebContents(web_contents); |
| 159 | |
| 160 switch (security_level) { | 198 switch (security_level) { |
| 161 case NONE: | 199 case NONE: |
| 162 return content::SECURITY_STYLE_UNAUTHENTICATED; | 200 security_info->security_style = content::SECURITY_STYLE_UNAUTHENTICATED; |
| 201 break; |
| 163 case EV_SECURE: | 202 case EV_SECURE: |
| 164 case SECURE: | 203 case SECURE: |
| 165 return content::SECURITY_STYLE_AUTHENTICATED; | 204 security_info->security_style = content::SECURITY_STYLE_AUTHENTICATED; |
| 205 break; |
| 166 case SECURITY_WARNING: | 206 case SECURITY_WARNING: |
| 167 case SECURITY_POLICY_WARNING: | 207 case SECURITY_POLICY_WARNING: |
| 168 return content::SECURITY_STYLE_WARNING; | 208 security_info->security_style = content::SECURITY_STYLE_WARNING; |
| 209 break; |
| 169 case SECURITY_ERROR: | 210 case SECURITY_ERROR: |
| 170 return content::SECURITY_STYLE_AUTHENTICATION_BROKEN; | 211 security_info->security_style = |
| 212 content::SECURITY_STYLE_AUTHENTICATION_BROKEN; |
| 213 break; |
| 171 } | 214 } |
| 172 | 215 |
| 173 NOTREACHED(); | 216 const content::SSLStatus& ssl = entry->GetSSL(); |
| 174 return content::SECURITY_STYLE_UNKNOWN; | 217 scoped_refptr<net::X509Certificate> cert = GetCertForSSLStatus(ssl); |
| 218 security_info->sha1_deprecation_status = GetSHA1DeprecationStatus(cert, ssl); |
| 219 security_info->mixed_content_status = GetMixedContentStatus(ssl); |
| 220 security_info->cert_status = ssl.cert_status; |
| 175 } | 221 } |
| 176 | 222 |
| 177 } // namespace connection_security | 223 } // namespace connection_security |
| OLD | NEW |