Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(425)

Side by Side Diff: components/ssl_errors/error_classification.cc

Issue 1772143002: Use network time for bad clock interstitial. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: pass "gn check out/Default" Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 "components/ssl_errors/error_classification.h" 5 #include "components/ssl_errors/error_classification.h"
6 6
7 #include <limits.h> 7 #include <limits.h>
8 #include <stddef.h> 8 #include <stddef.h>
9 9
10 #include <vector> 10 #include <vector>
11 11
12 #include "base/build_time.h" 12 #include "base/build_time.h"
13 #include "base/lazy_instance.h" 13 #include "base/lazy_instance.h"
14 #include "base/metrics/histogram_macros.h" 14 #include "base/metrics/histogram_macros.h"
15 #include "base/strings/string_split.h" 15 #include "base/strings/string_split.h"
16 #include "base/strings/utf_string_conversions.h" 16 #include "base/strings/utf_string_conversions.h"
17 #include "base/time/time.h" 17 #include "base/time/time.h"
18 #include "build/build_config.h" 18 #include "build/build_config.h"
19 #include "components/network_time/network_time_tracker.h"
19 #include "components/ssl_errors/error_info.h" 20 #include "components/ssl_errors/error_info.h"
20 #include "components/url_formatter/url_formatter.h" 21 #include "components/url_formatter/url_formatter.h"
21 #include "net/base/network_change_notifier.h" 22 #include "net/base/network_change_notifier.h"
22 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" 23 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
23 #include "net/base/url_util.h" 24 #include "net/base/url_util.h"
24 #include "net/cert/x509_cert_types.h" 25 #include "net/cert/x509_cert_types.h"
25 #include "net/cert/x509_certificate.h" 26 #include "net/cert/x509_certificate.h"
26 #include "url/gurl.h" 27 #include "url/gurl.h"
27 28
28 #if defined(OS_WIN) 29 #if defined(OS_WIN)
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
110 std::vector<std::string> dns_names; 111 std::vector<std::string> dns_names;
111 cert.GetDNSNames(&dns_names); 112 cert.GetDNSNames(&dns_names);
112 return GetWWWSubDomainMatch(request_url, dns_names, &www_host); 113 return GetWWWSubDomainMatch(request_url, dns_names, &www_host);
113 } 114 }
114 115
115 // The time to use when doing build time operations in browser tests. 116 // The time to use when doing build time operations in browser tests.
116 base::LazyInstance<base::Time> g_testing_build_time = LAZY_INSTANCE_INITIALIZER; 117 base::LazyInstance<base::Time> g_testing_build_time = LAZY_INSTANCE_INITIALIZER;
117 118
118 } // namespace 119 } // namespace
119 120
121 static ssl_errors::ErrorInfo::ErrorType RecordErrorType(int cert_error) {
122 ssl_errors::ErrorInfo::ErrorType error_type =
123 ssl_errors::ErrorInfo::NetErrorToErrorType(cert_error);
124 UMA_HISTOGRAM_ENUMERATION("interstitial.ssl_error_type", error_type,
125 ssl_errors::ErrorInfo::END_OF_ENUM);
126 UMA_HISTOGRAM_ENUMERATION("interstitial.ssl.connection_type",
127 net::NetworkChangeNotifier::GetConnectionType(),
128 net::NetworkChangeNotifier::CONNECTION_LAST);
129 return error_type;
130 }
131
120 void RecordUMAStatistics(bool overridable, 132 void RecordUMAStatistics(bool overridable,
121 const base::Time& current_time, 133 const base::Time& current_time,
122 const GURL& request_url, 134 const GURL& request_url,
123 int cert_error, 135 int cert_error,
124 const net::X509Certificate& cert) { 136 const net::X509Certificate& cert) {
125 ssl_errors::ErrorInfo::ErrorType type = 137 ssl_errors::ErrorInfo::ErrorType error_type = RecordErrorType(cert_error);
126 ssl_errors::ErrorInfo::NetErrorToErrorType(cert_error); 138
127 UMA_HISTOGRAM_ENUMERATION("interstitial.ssl_error_type", type, 139 switch (error_type) {
128 ssl_errors::ErrorInfo::END_OF_ENUM);
129 switch (type) {
130 case ssl_errors::ErrorInfo::CERT_DATE_INVALID: { 140 case ssl_errors::ErrorInfo::CERT_DATE_INVALID: {
131 if (IsUserClockInThePast(base::Time::NowFromSystemTime())) { 141 // Note: not reached when displaying the bad clock interstitial.
132 RecordSSLInterstitialCause(overridable, CLOCK_PAST); 142 // See |RecordUMAStatisticsForClockInterstitial| below.
133 } else if (IsUserClockInTheFuture(base::Time::NowFromSystemTime())) { 143 if (cert.HasExpired() &&
134 RecordSSLInterstitialCause(overridable, CLOCK_FUTURE); 144 (current_time - cert.valid_expiry()).InDays() < 28) {
135 } else if (cert.HasExpired() &&
136 (current_time - cert.valid_expiry()).InDays() < 28) {
137 RecordSSLInterstitialCause(overridable, EXPIRED_RECENTLY); 145 RecordSSLInterstitialCause(overridable, EXPIRED_RECENTLY);
138 } 146 }
139 break; 147 break;
140 } 148 }
141 case ssl_errors::ErrorInfo::CERT_COMMON_NAME_INVALID: { 149 case ssl_errors::ErrorInfo::CERT_COMMON_NAME_INVALID: {
142 std::string host_name = request_url.host(); 150 std::string host_name = request_url.host();
143 if (IsHostNameKnownTLD(host_name)) { 151 if (IsHostNameKnownTLD(host_name)) {
144 HostnameTokens host_name_tokens = Tokenize(host_name); 152 HostnameTokens host_name_tokens = Tokenize(host_name);
145 if (IsWWWSubDomainMatch(request_url, cert)) 153 if (IsWWWSubDomainMatch(request_url, cert))
146 RecordSSLInterstitialCause(overridable, WWW_SUBDOMAIN_MATCH); 154 RecordSSLInterstitialCause(overridable, WWW_SUBDOMAIN_MATCH);
(...skipping 22 matching lines...) Expand all
169 RecordSSLInterstitialCause(overridable, LOCALHOST); 177 RecordSSLInterstitialCause(overridable, LOCALHOST);
170 if (IsHostnameNonUniqueOrDotless(hostname)) 178 if (IsHostnameNonUniqueOrDotless(hostname))
171 RecordSSLInterstitialCause(overridable, PRIVATE_URL); 179 RecordSSLInterstitialCause(overridable, PRIVATE_URL);
172 if (net::X509Certificate::IsSelfSigned(cert.os_cert_handle())) 180 if (net::X509Certificate::IsSelfSigned(cert.os_cert_handle()))
173 RecordSSLInterstitialCause(overridable, SELF_SIGNED); 181 RecordSSLInterstitialCause(overridable, SELF_SIGNED);
174 break; 182 break;
175 } 183 }
176 default: 184 default:
177 break; 185 break;
178 } 186 }
179 UMA_HISTOGRAM_ENUMERATION("interstitial.ssl.connection_type",
180 net::NetworkChangeNotifier::GetConnectionType(),
181 net::NetworkChangeNotifier::CONNECTION_LAST);
182 } 187 }
183 188
184 bool IsUserClockInThePast(const base::Time& time_now) { 189 void RecordUMAStatisticsForClockInterstitial(bool overridable,
185 base::Time build_time; 190 ssl_errors::ClockState clock_state,
186 if (!g_testing_build_time.Get().is_null()) { 191 int cert_error) {
187 build_time = g_testing_build_time.Get(); 192 ssl_errors::ErrorInfo::ErrorType error_type = RecordErrorType(cert_error);
193 DCHECK(error_type == ssl_errors::ErrorInfo::CERT_DATE_INVALID);
194
195 if (clock_state == ssl_errors::CLOCK_STATE_FUTURE) {
196 RecordSSLInterstitialCause(overridable, CLOCK_FUTURE);
197 } else if (clock_state == ssl_errors::CLOCK_STATE_PAST) {
198 RecordSSLInterstitialCause(overridable, CLOCK_PAST);
188 } else { 199 } else {
189 build_time = base::GetBuildTime(); 200 NOTREACHED();
201 }
202 }
203
204 ClockState GetClockState(
205 const base::Time& now_system,
206 const network_time::NetworkTimeTracker* network_time_tracker) {
207 base::Time now_network;
208 base::TimeDelta uncertainty;
209 const base::TimeDelta kNetworkTimeFudge = base::TimeDelta::FromMinutes(5);
210 ClockState network_state = CLOCK_STATE_UNKNOWN;
211 if (network_time_tracker->GetNetworkTime(&now_network, &uncertainty)) {
212 if (now_system < now_network - uncertainty - kNetworkTimeFudge) {
213 network_state = CLOCK_STATE_PAST;
214 } else if (now_system > now_network + uncertainty + kNetworkTimeFudge) {
215 network_state = CLOCK_STATE_FUTURE;
216 } else {
217 network_state = CLOCK_STATE_OK;
218 }
190 } 219 }
191 220
192 if (time_now < build_time - base::TimeDelta::FromDays(2)) 221 ClockState build_time_state = CLOCK_STATE_UNKNOWN;
193 return true; 222 base::Time build_time = g_testing_build_time.Get().is_null()
194 return false; 223 ? base::GetBuildTime()
195 } 224 : g_testing_build_time.Get();
196 225 if (now_system < build_time - base::TimeDelta::FromDays(2)) {
197 bool IsUserClockInTheFuture(const base::Time& time_now) { 226 build_time_state = CLOCK_STATE_PAST;
198 base::Time build_time; 227 } else if (now_system > build_time + base::TimeDelta::FromDays(365)) {
199 if (!g_testing_build_time.Get().is_null()) { 228 build_time_state = CLOCK_STATE_FUTURE;
200 build_time = g_testing_build_time.Get();
201 } else {
202 build_time = base::GetBuildTime();
203 } 229 }
204 230
205 if (time_now > build_time + base::TimeDelta::FromDays(365)) 231 UMA_HISTOGRAM_ENUMERATION("interstitial.ssl.clockstate.network",
206 return true; 232 network_state, CLOCK_STATE_MAX);
207 return false; 233 UMA_HISTOGRAM_ENUMERATION("interstitial.ssl.clockstate.build_time",
234 build_time_state, CLOCK_STATE_MAX);
235
236 return network_state == CLOCK_STATE_UNKNOWN ? build_time_state
237 : network_state;
208 } 238 }
209 239
210 void SetBuildTimeForTesting(const base::Time& testing_time) { 240 void SetBuildTimeForTesting(const base::Time& testing_time) {
211 g_testing_build_time.Get() = testing_time; 241 g_testing_build_time.Get() = testing_time;
212 } 242 }
213 243
214 bool IsHostNameKnownTLD(const std::string& host_name) { 244 bool IsHostNameKnownTLD(const std::string& host_name) {
215 size_t tld_length = net::registry_controlled_domains::GetRegistryLength( 245 size_t tld_length = net::registry_controlled_domains::GetRegistryLength(
216 host_name, net::registry_controlled_domains::EXCLUDE_UNKNOWN_REGISTRIES, 246 host_name, net::registry_controlled_domains::EXCLUDE_UNKNOWN_REGISTRIES,
217 net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES); 247 net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES);
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
412 return std::find(dns_names_domain.begin(), dns_names_domain.end() - 1, 442 return std::find(dns_names_domain.begin(), dns_names_domain.end() - 1,
413 host_name_domain) != dns_names_domain.end() - 1; 443 host_name_domain) != dns_names_domain.end() - 1;
414 } 444 }
415 445
416 bool IsHostnameNonUniqueOrDotless(const std::string& hostname) { 446 bool IsHostnameNonUniqueOrDotless(const std::string& hostname) {
417 return net::IsHostnameNonUnique(hostname) || 447 return net::IsHostnameNonUnique(hostname) ||
418 hostname.find('.') == std::string::npos; 448 hostname.find('.') == std::string::npos;
419 } 449 }
420 450
421 } // namespace ssl_errors 451 } // namespace ssl_errors
OLDNEW
« no previous file with comments | « components/ssl_errors/error_classification.h ('k') | components/ssl_errors/error_classification_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698