| 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 17 matching lines...) Expand all Loading... |
| 101 return SECURITY_ERROR; | 138 return SECURITY_ERROR; |
| 102 | 139 |
| 103 case content::SECURITY_STYLE_AUTHENTICATED: { | 140 case content::SECURITY_STYLE_AUTHENTICATED: { |
| 104 #if defined(OS_CHROMEOS) | 141 #if defined(OS_CHROMEOS) |
| 105 policy::PolicyCertService* service = | 142 policy::PolicyCertService* service = |
| 106 policy::PolicyCertServiceFactory::GetForProfile( | 143 policy::PolicyCertServiceFactory::GetForProfile( |
| 107 Profile::FromBrowserContext(web_contents->GetBrowserContext())); | 144 Profile::FromBrowserContext(web_contents->GetBrowserContext())); |
| 108 if (service && service->UsedPolicyCertificates()) | 145 if (service && service->UsedPolicyCertificates()) |
| 109 return SECURITY_POLICY_WARNING; | 146 return SECURITY_POLICY_WARNING; |
| 110 #endif | 147 #endif |
| 111 scoped_refptr<net::X509Certificate> cert; | 148 |
| 112 if (content::CertStore::GetInstance()->RetrieveCert(ssl.cert_id, &cert) && | 149 scoped_refptr<net::X509Certificate> cert = GetCertForSSLStatus(ssl); |
| 113 (ssl.cert_status & net::CERT_STATUS_SHA1_SIGNATURE_PRESENT)) { | 150 SHA1DeprecationStatus sha1_status = GetSHA1DeprecationStatus(cert, ssl); |
| 114 // The internal representation of the dates for UI treatment of SHA-1. | 151 if (sha1_status == DEPRECATED_SHA1_BROKEN) |
| 115 // See http://crbug.com/401365 for details. | 152 return SECURITY_ERROR; |
| 116 static const int64_t kJanuary2017 = INT64_C(13127702400000000); | 153 if (sha1_status == DEPRECATED_SHA1_WARNING) |
| 117 // kJanuary2016 needs to be kept in sync with | |
| 118 // ToolbarModelAndroid::IsDeprecatedSHA1Present(). | |
| 119 static const int64_t kJanuary2016 = INT64_C(13096080000000000); | |
| 120 if (cert->valid_expiry() >= | |
| 121 base::Time::FromInternalValue(kJanuary2017)) { | |
| 122 return SECURITY_ERROR; | |
| 123 } | |
| 124 if (cert->valid_expiry() >= | |
| 125 base::Time::FromInternalValue(kJanuary2016)) { | |
| 126 return SECURITY_WARNING; | |
| 127 } | |
| 128 } | |
| 129 if (ssl.content_status & content::SSLStatus::DISPLAYED_INSECURE_CONTENT) | |
| 130 return SECURITY_WARNING; | 154 return SECURITY_WARNING; |
| 155 |
| 156 MixedContentStatus mixed_content_status = GetMixedContentStatus(ssl); |
| 157 // Active mixed content is downgraded to the BROKEN style and |
| 158 // handled above. |
| 159 DCHECK_NE(RAN_MIXED_CONTENT, mixed_content_status); |
| 160 if (mixed_content_status == DISPLAYED_MIXED_CONTENT) |
| 161 return SECURITY_WARNING; |
| 162 |
| 131 if (net::IsCertStatusError(ssl.cert_status)) { | 163 if (net::IsCertStatusError(ssl.cert_status)) { |
| 132 DCHECK(net::IsCertStatusMinorError(ssl.cert_status)); | 164 DCHECK(net::IsCertStatusMinorError(ssl.cert_status)); |
| 133 return SECURITY_WARNING; | 165 return SECURITY_WARNING; |
| 134 } | 166 } |
| 135 if (net::SSLConnectionStatusToVersion(ssl.connection_status) == | 167 if (net::SSLConnectionStatusToVersion(ssl.connection_status) == |
| 136 net::SSL_CONNECTION_VERSION_SSL3) { | 168 net::SSL_CONNECTION_VERSION_SSL3) { |
| 137 // SSLv3 will be removed in the future. | 169 // SSLv3 will be removed in the future. |
| 138 return SECURITY_WARNING; | 170 return SECURITY_WARNING; |
| 139 } | 171 } |
| 140 if ((ssl.cert_status & net::CERT_STATUS_IS_EV) && cert) | 172 if ((ssl.cert_status & net::CERT_STATUS_IS_EV) && cert) |
| 141 return EV_SECURE; | 173 return EV_SECURE; |
| 142 return SECURE; | 174 return SECURE; |
| 143 } | 175 } |
| 144 | 176 |
| 145 default: | 177 default: |
| 146 NOTREACHED(); | 178 NOTREACHED(); |
| 147 return NONE; | 179 return NONE; |
| 148 } | 180 } |
| 149 } | 181 } |
| 150 | 182 |
| 151 content::SecurityStyle GetSecurityStyleForWebContents( | 183 void GetSecurityInfoForWebContents(const content::WebContents* web_contents, |
| 152 const content::WebContents* web_contents) { | 184 SecurityInfo* security_info) { |
| 185 content::NavigationEntry* entry = |
| 186 web_contents ? web_contents->GetController().GetVisibleEntry() : nullptr; |
| 187 if (!entry) { |
| 188 security_info->security_style = content::SECURITY_STYLE_UNKNOWN; |
| 189 return; |
| 190 } |
| 191 |
| 153 SecurityLevel security_level = GetSecurityLevelForWebContents(web_contents); | 192 SecurityLevel security_level = GetSecurityLevelForWebContents(web_contents); |
| 154 | |
| 155 switch (security_level) { | 193 switch (security_level) { |
| 156 case NONE: | 194 case NONE: |
| 157 return content::SECURITY_STYLE_UNAUTHENTICATED; | 195 security_info->security_style = content::SECURITY_STYLE_UNAUTHENTICATED; |
| 196 break; |
| 158 case EV_SECURE: | 197 case EV_SECURE: |
| 159 case SECURE: | 198 case SECURE: |
| 160 return content::SECURITY_STYLE_AUTHENTICATED; | 199 security_info->security_style = content::SECURITY_STYLE_AUTHENTICATED; |
| 200 break; |
| 161 case SECURITY_WARNING: | 201 case SECURITY_WARNING: |
| 162 case SECURITY_POLICY_WARNING: | 202 case SECURITY_POLICY_WARNING: |
| 163 return content::SECURITY_STYLE_WARNING; | 203 security_info->security_style = content::SECURITY_STYLE_WARNING; |
| 204 break; |
| 164 case SECURITY_ERROR: | 205 case SECURITY_ERROR: |
| 165 return content::SECURITY_STYLE_AUTHENTICATION_BROKEN; | 206 security_info->security_style = |
| 207 content::SECURITY_STYLE_AUTHENTICATION_BROKEN; |
| 208 break; |
| 166 } | 209 } |
| 167 | 210 |
| 168 NOTREACHED(); | 211 const content::SSLStatus& ssl = entry->GetSSL(); |
| 169 return content::SECURITY_STYLE_UNKNOWN; | 212 scoped_refptr<net::X509Certificate> cert = GetCertForSSLStatus(ssl); |
| 213 security_info->sha1_deprecation_status = GetSHA1DeprecationStatus(cert, ssl); |
| 214 security_info->mixed_content_status = GetMixedContentStatus(ssl); |
| 215 security_info->cert_status = ssl.cert_status; |
| 170 } | 216 } |
| 171 | 217 |
| 172 } // namespace connection_security | 218 } // namespace connection_security |
| OLD | NEW |