File: error_classification.h

package info (click to toggle)
chromium 120.0.6099.224-1~deb11u1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 6,112,112 kB
  • sloc: cpp: 32,907,025; ansic: 8,148,123; javascript: 3,679,536; python: 2,031,248; asm: 959,718; java: 804,675; xml: 617,256; sh: 111,417; objc: 100,835; perl: 88,443; cs: 53,032; makefile: 29,579; fortran: 24,137; php: 21,162; tcl: 21,147; sql: 20,809; ruby: 17,735; pascal: 12,864; yacc: 8,045; lisp: 3,388; lex: 1,323; ada: 727; awk: 329; jsp: 267; csh: 117; exp: 43; sed: 37
file content (196 lines) | stat: -rw-r--r-- 7,679 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef COMPONENTS_SSL_ERRORS_ERROR_CLASSIFICATION_H_
#define COMPONENTS_SSL_ERRORS_ERROR_CLASSIFICATION_H_

#include <string>
#include <vector>

namespace base {
class Time;
}

class GURL;

namespace net {
class X509Certificate;
}

namespace network_time {
class NetworkTimeTracker;
}

namespace ssl_errors {

typedef std::vector<std::string> HostnameTokens;

// Methods for identifying specific error causes. ------------------------------

// These values are written to logs. New enum values can be added, but existing
// enums must never be renumbered or deleted and reused.
enum SSLInterstitialCause {
  CLOCK_PAST = 0,
  CLOCK_FUTURE = 1,
  WWW_SUBDOMAIN_MATCH = 2,         // Deprecated in M59.
  SUBDOMAIN_MATCH = 3,             // Deprecated in M59.
  SUBDOMAIN_INVERSE_MATCH = 4,     // Deprecated in M59.
  SUBDOMAIN_OUTSIDE_WILDCARD = 5,  // Deprecated in M59.
  HOST_NAME_NOT_KNOWN_TLD = 6,
  LIKELY_MULTI_TENANT_HOSTING = 7,  // Deprecated in M59.
  LOCALHOST = 8,
  PRIVATE_URL = 9,
  AUTHORITY_ERROR_CAPTIVE_PORTAL = 10,  // Deprecated in M47.
  SELF_SIGNED = 11,
  EXPIRED_RECENTLY = 12,
  LIKELY_SAME_DOMAIN = 13,  // Deprecated in M59.
  NO_SUBJECT_ALT_NAME = 14,
  WWW_SUBDOMAIN_MATCH2 = 15,
  SUBDOMAIN_MATCH2 = 16,
  SUBDOMAIN_INVERSE_MATCH2 = 17,
  SUBDOMAIN_OUTSIDE_WILDCARD2 = 18,
  LIKELY_MULTI_TENANT_HOSTING2 = 19,
  LIKELY_SAME_DOMAIN2 = 20,
  SSL_INTERSTITIAL_CAUSE_MAX
};

// What is known about the accuracy of system clock.  Do not change or
// reorder; these values are used in an UMA histogram.
enum ClockState {
  // Not known whether system clock is close enough.
  CLOCK_STATE_UNKNOWN,

  // System clock is "close enough", per network time.
  CLOCK_STATE_OK,

  // System clock is behind.
  CLOCK_STATE_PAST,

  // System clock is ahead.
  CLOCK_STATE_FUTURE,

  CLOCK_STATE_MAX,
};

// Describes the result of getting network time and if it was
// unavailable, why it was unavailable. This enum is being histogrammed
// so do not reorder or remove values.
//
// Exposed for testing.
enum NetworkClockState {
  // Value 0 was NETWORK_CLOCK_STATE_UNKNOWN_NO_SYNC, which is obsolete
  // in favor of the finer-grained values below.

  // The clock state relative to network time is unknown because the
  // user's clock has fallen out of sync with the latest information
  // from the network (due to e.g. suspend/resume).
  NETWORK_CLOCK_STATE_UNKNOWN_SYNC_LOST = 1,
  // The clock is "close enough" to the network time.
  NETWORK_CLOCK_STATE_OK,
  // The clock is in the past relative to network time.
  NETWORK_CLOCK_STATE_CLOCK_IN_PAST,
  // The clock is in the future relative to network time.
  NETWORK_CLOCK_STATE_CLOCK_IN_FUTURE,
  // The clock state relative to network time is unknown because no sync
  // attempt has been made yet.
  NETWORK_CLOCK_STATE_UNKNOWN_NO_SYNC_ATTEMPT,
  // The clock state relative to network time is unknown because one or
  // more sync attempts has failed.
  NETWORK_CLOCK_STATE_UNKNOWN_NO_SUCCESSFUL_SYNC,
  // The clock state relative to network time is unknown because the
  // first sync attempt is still pending.
  NETWORK_CLOCK_STATE_UNKNOWN_FIRST_SYNC_PENDING,
  // The clock state relative to network time is unknown because one or
  // more time query attempts have failed, and a subsequent sync attempt
  // is still pending.
  NETWORK_CLOCK_STATE_UNKNOWN_SUBSEQUENT_SYNC_PENDING,
  NETWORK_CLOCK_STATE_MAX
};

// Compares |now_system| to the build time and to the current network time, and
// returns an inference about the state of the system clock.  A result from
// network time, if available, will always be preferred to a result from the
// build time.  Calling this function records UMA statistics: it's assumed that
// it's called in the course of handling an SSL error.
ClockState GetClockState(
    const base::Time& now_system,
    const network_time::NetworkTimeTracker* network_time_tracker);

// Returns true if |hostname| is too broad for the scope of a wildcard
// certificate. E.g.:
//     a.b.example.com ~ *.example.com --> true
//     b.example.com ~ *.example.com --> false
bool IsSubDomainOutsideWildcard(const GURL& request_url,
                                const net::X509Certificate& cert);

// Returns true if the certificate is a shared certificate. Note - This
// function should be used with caution (only for UMA histogram) as an
// attacker could easily get a certificate with more than 5 names in the SAN
// fields.
bool IsCertLikelyFromMultiTenantHosting(const GURL& request_url,
                                        const net::X509Certificate& cert);

// Returns true if the hostname in |request_url_| has the same domain
// (effective TLD + 1 label) as at least one of the subject
// alternative names in |cert_|.
bool IsCertLikelyFromSameDomain(const GURL& request_url,
                                const net::X509Certificate& cert);

// Returns true if the site's hostname differs from one of the DNS names in
// |dns_names| only by the presence or absence of the single-label prefix "www".
// The matching name from the certificate is returned in |www_match_host_name|.
bool GetWWWSubDomainMatch(const GURL& request_url,
                          const std::vector<std::string>& dns_names,
                          std::string* www_match_host_name);

// Method for recording results. -----------------------------------------------

void RecordUMAStatistics(bool overridable,
                         const base::Time& current_time,
                         const GURL& request_url,
                         int cert_error,
                         const net::X509Certificate& cert);

// Specialization of |RecordUMAStatistics| to be used when the bad clock
// interstitial is shown.  |cert_error| is required only for sanity-checking: it
// must always be |ssl_errors::ErrorInfo::CERT_DATE_INVALID|.
void RecordUMAStatisticsForClockInterstitial(bool overridable,
                                             ssl_errors::ClockState clock_state,
                                             int cert_error);

// Helper methods for classification. ------------------------------------------

// Tokenize DNS names and hostnames.
HostnameTokens Tokenize(const std::string& name);

// Sets a clock for browser tests that check the build time. Used by
// GetClockState().
void SetBuildTimeForTesting(const base::Time& testing_time);

// Returns true if the hostname has a known Top Level Domain.
bool HostNameHasKnownTLD(const std::string& host_name);

// Returns true if any one of the following conditions hold:
// 1.|hostname| is an IP Address in an IANA-reserved range.
// 2.|hostname| is a not-yet-assigned by ICANN gTLD.
// 3.|hostname| is a dotless domain.
bool IsHostnameNonUniqueOrDotless(const std::string& hostname);

// Returns true if |child| is a subdomain of any of the |potential_parents|.
bool NameUnderAnyNames(const HostnameTokens& child,
                       const std::vector<HostnameTokens>& potential_parents);

// Returns true if any of the |potential_children| is a subdomain of the
// |parent|. The inverse case should be treated carefully as this is most
// likely a MITM attack. We don't want foo.appspot.com to be able to MITM for
// appspot.com.
bool AnyNamesUnderName(const std::vector<HostnameTokens>& potential_children,
                       const HostnameTokens& parent);

// Exposed for teshting.
size_t GetLevenshteinDistance(const std::string& str1, const std::string& str2);

}  // namespace ssl_errors

#endif  // COMPONENTS_SSL_ERRORS_ERROR_CLASSIFICATION_H_