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 "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> |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
60 void RecordSSLInterstitialCause(bool overridable, SSLInterstitialCause event) { | 60 void RecordSSLInterstitialCause(bool overridable, SSLInterstitialCause event) { |
61 if (overridable) { | 61 if (overridable) { |
62 UMA_HISTOGRAM_ENUMERATION("interstitial.ssl.cause.overridable", event, | 62 UMA_HISTOGRAM_ENUMERATION("interstitial.ssl.cause.overridable", event, |
63 UNUSED_INTERSTITIAL_CAUSE_ENTRY); | 63 UNUSED_INTERSTITIAL_CAUSE_ENTRY); |
64 } else { | 64 } else { |
65 UMA_HISTOGRAM_ENUMERATION("interstitial.ssl.cause.nonoverridable", event, | 65 UMA_HISTOGRAM_ENUMERATION("interstitial.ssl.cause.nonoverridable", event, |
66 UNUSED_INTERSTITIAL_CAUSE_ENTRY); | 66 UNUSED_INTERSTITIAL_CAUSE_ENTRY); |
67 } | 67 } |
68 } | 68 } |
69 | 69 |
70 // Returns the Levenshtein distance between |str1| and |str2|. | |
71 // Which is the minimum number of single-character edits (i.e. insertions, | |
72 // deletions or substitutions) required to change one word into the other. | |
73 // https://en.wikipedia.org/wiki/Levenshtein_distance | |
74 size_t GetLevenshteinDistance(const std::string& str1, | |
75 const std::string& str2) { | |
76 if (str1 == str2) | |
77 return 0; | |
78 if (str1.size() == 0) | |
79 return str2.size(); | |
80 if (str2.size() == 0) | |
81 return str1.size(); | |
82 std::vector<size_t> kFirstRow(str2.size() + 1, 0); | |
83 std::vector<size_t> kSecondRow(str2.size() + 1, 0); | |
84 | |
85 for (size_t i = 0; i < kFirstRow.size(); ++i) | |
86 kFirstRow[i] = i; | |
87 for (size_t i = 0; i < str1.size(); ++i) { | |
88 kSecondRow[0] = i + 1; | |
89 for (size_t j = 0; j < str2.size(); ++j) { | |
90 int cost = str1[i] == str2[j] ? 0 : 1; | |
91 kSecondRow[j + 1] = | |
92 std::min(std::min(kSecondRow[j] + 1, kFirstRow[j + 1] + 1), | |
93 kFirstRow[j] + cost); | |
94 } | |
95 for (size_t j = 0; j < kFirstRow.size(); j++) | |
96 kFirstRow[j] = kSecondRow[j]; | |
97 } | |
98 return kSecondRow[str2.size()]; | |
99 } | |
100 | |
101 std::vector<HostnameTokens> GetTokenizedDNSNames( | 70 std::vector<HostnameTokens> GetTokenizedDNSNames( |
102 const std::vector<std::string>& dns_names) { | 71 const std::vector<std::string>& dns_names) { |
103 std::vector<HostnameTokens> dns_name_tokens; | 72 std::vector<HostnameTokens> dns_name_tokens; |
104 for (const auto& dns_name : dns_names) { | 73 for (const auto& dns_name : dns_names) { |
105 HostnameTokens dns_name_token_single; | 74 HostnameTokens dns_name_token_single; |
106 if (dns_name.empty() || dns_name.find('\0') != std::string::npos || | 75 if (dns_name.empty() || dns_name.find('\0') != std::string::npos || |
107 !(IsHostNameKnownTLD(dns_name))) { | 76 !(IsHostNameKnownTLD(dns_name))) { |
108 dns_name_token_single.push_back(std::string()); | 77 dns_name_token_single.push_back(std::string()); |
109 } else { | 78 } else { |
110 dns_name_token_single = Tokenize(dns_name); | 79 dns_name_token_single = Tokenize(dns_name); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
142 std::vector<std::string> dns_names; | 111 std::vector<std::string> dns_names; |
143 cert.GetDNSNames(&dns_names); | 112 cert.GetDNSNames(&dns_names); |
144 return GetWWWSubDomainMatch(request_url, dns_names, &www_host); | 113 return GetWWWSubDomainMatch(request_url, dns_names, &www_host); |
145 } | 114 } |
146 | 115 |
147 // 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. |
148 base::LazyInstance<base::Time> g_testing_build_time = LAZY_INSTANCE_INITIALIZER; | 117 base::LazyInstance<base::Time> g_testing_build_time = LAZY_INSTANCE_INITIALIZER; |
149 | 118 |
150 } // namespace | 119 } // namespace |
151 | 120 |
| 121 // Returns the Levenshtein distance between |str1| and |str2|. |
| 122 // Which is the minimum number of single-character edits (i.e. insertions, |
| 123 // deletions or substitutions) required to change one word into the other. |
| 124 // https://en.wikipedia.org/wiki/Levenshtein_distance |
| 125 size_t GetLevenshteinDistance(const std::string& str1, |
| 126 const std::string& str2) { |
| 127 if (str1 == str2) |
| 128 return 0; |
| 129 if (str1.size() == 0) |
| 130 return str2.size(); |
| 131 if (str2.size() == 0) |
| 132 return str1.size(); |
| 133 |
| 134 std::vector<size_t> row(str2.size() + 1); |
| 135 for (size_t i = 0; i < row.size(); ++i) |
| 136 row[i] = i; |
| 137 |
| 138 for (size_t i = 0; i < str1.size(); ++i) { |
| 139 row[0] = i + 1; |
| 140 size_t previous = i; |
| 141 for (size_t j = 0; j < str2.size(); ++j) { |
| 142 size_t old_row = row[j + 1]; |
| 143 int cost = str1[i] == str2[j] ? 0 : 1; |
| 144 row[j + 1] = std::min(std::min(row[j], row[j + 1]) + 1, previous + cost); |
| 145 previous = old_row; |
| 146 } |
| 147 } |
| 148 return row[str2.size()]; |
| 149 } |
| 150 |
| 151 |
152 void RecordUMAStatistics(bool overridable, | 152 void RecordUMAStatistics(bool overridable, |
153 const base::Time& current_time, | 153 const base::Time& current_time, |
154 const GURL& request_url, | 154 const GURL& request_url, |
155 int cert_error, | 155 int cert_error, |
156 const net::X509Certificate& cert) { | 156 const net::X509Certificate& cert) { |
157 ssl_errors::ErrorInfo::ErrorType type = | 157 ssl_errors::ErrorInfo::ErrorType type = |
158 ssl_errors::ErrorInfo::NetErrorToErrorType(cert_error); | 158 ssl_errors::ErrorInfo::NetErrorToErrorType(cert_error); |
159 UMA_HISTOGRAM_ENUMERATION("interstitial.ssl_error_type", type, | 159 UMA_HISTOGRAM_ENUMERATION("interstitial.ssl_error_type", type, |
160 ssl_errors::ErrorInfo::END_OF_ENUM); | 160 ssl_errors::ErrorInfo::END_OF_ENUM); |
161 switch (type) { | 161 switch (type) { |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
381 static const int kDistinctNameThreshold = 5; | 381 static const int kDistinctNameThreshold = 5; |
382 if (dns_names_size > kDistinctNameThreshold) | 382 if (dns_names_size > kDistinctNameThreshold) |
383 return true; | 383 return true; |
384 | 384 |
385 // Heuristic - The edit distance between all the strings should be at least 5 | 385 // Heuristic - The edit distance between all the strings should be at least 5 |
386 // for it to be counted as a shared SSLCertificate. If even one pair of | 386 // for it to be counted as a shared SSLCertificate. If even one pair of |
387 // strings edit distance is below 5 then the certificate is no longer | 387 // strings edit distance is below 5 then the certificate is no longer |
388 // considered as a shared certificate. Include the host name in the URL also | 388 // considered as a shared certificate. Include the host name in the URL also |
389 // while comparing. | 389 // while comparing. |
390 dns_names.push_back(host_name); | 390 dns_names.push_back(host_name); |
391 static const size_t kMinimumEditDsitance = 5; | 391 static const size_t kMinimumEditDistance = 5; |
392 for (size_t i = 0; i < dns_names_size; ++i) { | 392 for (size_t i = 0; i < dns_names_size; ++i) { |
393 for (size_t j = i + 1; j < dns_names_size; ++j) { | 393 for (size_t j = i + 1; j < dns_names_size; ++j) { |
394 size_t edit_distance = GetLevenshteinDistance(dns_names[i], dns_names[j]); | 394 size_t edit_distance = GetLevenshteinDistance(dns_names[i], dns_names[j]); |
395 if (edit_distance < kMinimumEditDsitance) | 395 if (edit_distance < kMinimumEditDistance) |
396 return false; | 396 return false; |
397 } | 397 } |
398 } | 398 } |
399 return true; | 399 return true; |
400 } | 400 } |
401 | 401 |
402 bool IsCertLikelyFromSameDomain(const GURL& request_url, | 402 bool IsCertLikelyFromSameDomain(const GURL& request_url, |
403 const net::X509Certificate& cert) { | 403 const net::X509Certificate& cert) { |
404 std::string host_name = request_url.host(); | 404 std::string host_name = request_url.host(); |
405 std::vector<std::string> dns_names; | 405 std::vector<std::string> dns_names; |
(...skipping 16 matching lines...) Expand all Loading... |
422 return std::find(dns_names_domain.begin(), dns_names_domain.end() - 1, | 422 return std::find(dns_names_domain.begin(), dns_names_domain.end() - 1, |
423 host_name_domain) != dns_names_domain.end() - 1; | 423 host_name_domain) != dns_names_domain.end() - 1; |
424 } | 424 } |
425 | 425 |
426 bool IsHostnameNonUniqueOrDotless(const std::string& hostname) { | 426 bool IsHostnameNonUniqueOrDotless(const std::string& hostname) { |
427 return net::IsHostnameNonUnique(hostname) || | 427 return net::IsHostnameNonUnique(hostname) || |
428 hostname.find('.') == std::string::npos; | 428 hostname.find('.') == std::string::npos; |
429 } | 429 } |
430 | 430 |
431 } // namespace ssl_errors | 431 } // namespace ssl_errors |
OLD | NEW |