error_classification.h 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  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. #ifndef COMPONENTS_SSL_ERRORS_ERROR_CLASSIFICATION_H_
  5. #define COMPONENTS_SSL_ERRORS_ERROR_CLASSIFICATION_H_
  6. #include <string>
  7. #include <vector>
  8. namespace base {
  9. class Time;
  10. }
  11. class GURL;
  12. namespace net {
  13. class X509Certificate;
  14. }
  15. namespace network_time {
  16. class NetworkTimeTracker;
  17. }
  18. namespace ssl_errors {
  19. typedef std::vector<std::string> HostnameTokens;
  20. // Methods for identifying specific error causes. ------------------------------
  21. // These values are written to logs. New enum values can be added, but existing
  22. // enums must never be renumbered or deleted and reused.
  23. enum SSLInterstitialCause {
  24. CLOCK_PAST = 0,
  25. CLOCK_FUTURE = 1,
  26. WWW_SUBDOMAIN_MATCH = 2, // Deprecated in M59.
  27. SUBDOMAIN_MATCH = 3, // Deprecated in M59.
  28. SUBDOMAIN_INVERSE_MATCH = 4, // Deprecated in M59.
  29. SUBDOMAIN_OUTSIDE_WILDCARD = 5, // Deprecated in M59.
  30. HOST_NAME_NOT_KNOWN_TLD = 6,
  31. LIKELY_MULTI_TENANT_HOSTING = 7, // Deprecated in M59.
  32. LOCALHOST = 8,
  33. PRIVATE_URL = 9,
  34. AUTHORITY_ERROR_CAPTIVE_PORTAL = 10, // Deprecated in M47.
  35. SELF_SIGNED = 11,
  36. EXPIRED_RECENTLY = 12,
  37. LIKELY_SAME_DOMAIN = 13, // Deprecated in M59.
  38. NO_SUBJECT_ALT_NAME = 14,
  39. WWW_SUBDOMAIN_MATCH2 = 15,
  40. SUBDOMAIN_MATCH2 = 16,
  41. SUBDOMAIN_INVERSE_MATCH2 = 17,
  42. SUBDOMAIN_OUTSIDE_WILDCARD2 = 18,
  43. LIKELY_MULTI_TENANT_HOSTING2 = 19,
  44. LIKELY_SAME_DOMAIN2 = 20,
  45. SSL_INTERSTITIAL_CAUSE_MAX
  46. };
  47. // What is known about the accuracy of system clock. Do not change or
  48. // reorder; these values are used in an UMA histogram.
  49. enum ClockState {
  50. // Not known whether system clock is close enough.
  51. CLOCK_STATE_UNKNOWN,
  52. // System clock is "close enough", per network time.
  53. CLOCK_STATE_OK,
  54. // System clock is behind.
  55. CLOCK_STATE_PAST,
  56. // System clock is ahead.
  57. CLOCK_STATE_FUTURE,
  58. CLOCK_STATE_MAX,
  59. };
  60. // Describes the result of getting network time and if it was
  61. // unavailable, why it was unavailable. This enum is being histogrammed
  62. // so do not reorder or remove values.
  63. //
  64. // Exposed for testing.
  65. enum NetworkClockState {
  66. // Value 0 was NETWORK_CLOCK_STATE_UNKNOWN_NO_SYNC, which is obsolete
  67. // in favor of the finer-grained values below.
  68. // The clock state relative to network time is unknown because the
  69. // user's clock has fallen out of sync with the latest information
  70. // from the network (due to e.g. suspend/resume).
  71. NETWORK_CLOCK_STATE_UNKNOWN_SYNC_LOST = 1,
  72. // The clock is "close enough" to the network time.
  73. NETWORK_CLOCK_STATE_OK,
  74. // The clock is in the past relative to network time.
  75. NETWORK_CLOCK_STATE_CLOCK_IN_PAST,
  76. // The clock is in the future relative to network time.
  77. NETWORK_CLOCK_STATE_CLOCK_IN_FUTURE,
  78. // The clock state relative to network time is unknown because no sync
  79. // attempt has been made yet.
  80. NETWORK_CLOCK_STATE_UNKNOWN_NO_SYNC_ATTEMPT,
  81. // The clock state relative to network time is unknown because one or
  82. // more sync attempts has failed.
  83. NETWORK_CLOCK_STATE_UNKNOWN_NO_SUCCESSFUL_SYNC,
  84. // The clock state relative to network time is unknown because the
  85. // first sync attempt is still pending.
  86. NETWORK_CLOCK_STATE_UNKNOWN_FIRST_SYNC_PENDING,
  87. // The clock state relative to network time is unknown because one or
  88. // more time query attempts have failed, and a subsequent sync attempt
  89. // is still pending.
  90. NETWORK_CLOCK_STATE_UNKNOWN_SUBSEQUENT_SYNC_PENDING,
  91. NETWORK_CLOCK_STATE_MAX
  92. };
  93. // Compares |now_system| to the build time and to the current network time, and
  94. // returns an inference about the state of the system clock. A result from
  95. // network time, if available, will always be preferred to a result from the
  96. // build time. Calling this function records UMA statistics: it's assumed that
  97. // it's called in the course of handling an SSL error.
  98. ClockState GetClockState(
  99. const base::Time& now_system,
  100. const network_time::NetworkTimeTracker* network_time_tracker);
  101. // Returns true if |hostname| is too broad for the scope of a wildcard
  102. // certificate. E.g.:
  103. // a.b.example.com ~ *.example.com --> true
  104. // b.example.com ~ *.example.com --> false
  105. bool IsSubDomainOutsideWildcard(const GURL& request_url,
  106. const net::X509Certificate& cert);
  107. // Returns true if the certificate is a shared certificate. Note - This
  108. // function should be used with caution (only for UMA histogram) as an
  109. // attacker could easily get a certificate with more than 5 names in the SAN
  110. // fields.
  111. bool IsCertLikelyFromMultiTenantHosting(const GURL& request_url,
  112. const net::X509Certificate& cert);
  113. // Returns true if the hostname in |request_url_| has the same domain
  114. // (effective TLD + 1 label) as at least one of the subject
  115. // alternative names in |cert_|.
  116. bool IsCertLikelyFromSameDomain(const GURL& request_url,
  117. const net::X509Certificate& cert);
  118. // Returns true if the site's hostname differs from one of the DNS names in
  119. // |dns_names| only by the presence or absence of the single-label prefix "www".
  120. // The matching name from the certificate is returned in |www_match_host_name|.
  121. bool GetWWWSubDomainMatch(const GURL& request_url,
  122. const std::vector<std::string>& dns_names,
  123. std::string* www_match_host_name);
  124. // Method for recording results. -----------------------------------------------
  125. void RecordUMAStatistics(bool overridable,
  126. const base::Time& current_time,
  127. const GURL& request_url,
  128. int cert_error,
  129. const net::X509Certificate& cert);
  130. // Specialization of |RecordUMAStatistics| to be used when the bad clock
  131. // interstitial is shown. |cert_error| is required only for sanity-checking: it
  132. // must always be |ssl_errors::ErrorInfo::CERT_DATE_INVALID|.
  133. void RecordUMAStatisticsForClockInterstitial(bool overridable,
  134. ssl_errors::ClockState clock_state,
  135. int cert_error);
  136. // Helper methods for classification. ------------------------------------------
  137. // Tokenize DNS names and hostnames.
  138. HostnameTokens Tokenize(const std::string& name);
  139. // Sets a clock for browser tests that check the build time. Used by
  140. // GetClockState().
  141. void SetBuildTimeForTesting(const base::Time& testing_time);
  142. // Returns true if the hostname has a known Top Level Domain.
  143. bool HostNameHasKnownTLD(const std::string& host_name);
  144. // Returns true if any one of the following conditions hold:
  145. // 1.|hostname| is an IP Address in an IANA-reserved range.
  146. // 2.|hostname| is a not-yet-assigned by ICANN gTLD.
  147. // 3.|hostname| is a dotless domain.
  148. bool IsHostnameNonUniqueOrDotless(const std::string& hostname);
  149. // Returns true if |child| is a subdomain of any of the |potential_parents|.
  150. bool NameUnderAnyNames(const HostnameTokens& child,
  151. const std::vector<HostnameTokens>& potential_parents);
  152. // Returns true if any of the |potential_children| is a subdomain of the
  153. // |parent|. The inverse case should be treated carefully as this is most
  154. // likely a MITM attack. We don't want foo.appspot.com to be able to MITM for
  155. // appspot.com.
  156. bool AnyNamesUnderName(const std::vector<HostnameTokens>& potential_children,
  157. const HostnameTokens& parent);
  158. // Exposed for teshting.
  159. size_t GetLevenshteinDistance(const std::string& str1, const std::string& str2);
  160. } // namespace ssl_errors
  161. #endif // COMPONENTS_SSL_ERRORS_ERROR_CLASSIFICATION_H_