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

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

Issue 2804883005: Update SSL error handling code to account for Subject CN deprecation (Closed)
Patch Set: Created 3 years, 8 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
« no previous file with comments | « components/ssl_errors/error_classification.cc ('k') | components/ssl_errors/error_info.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "base/files/file_path.h" 7 #include "base/files/file_path.h"
8 #include "base/memory/ptr_util.h" 8 #include "base/memory/ptr_util.h"
9 #include "base/message_loop/message_loop.h" 9 #include "base/message_loop/message_loop.h"
10 #include "base/strings/string_split.h" 10 #include "base/strings/string_split.h"
11 #include "base/test/histogram_tester.h" 11 #include "base/test/histogram_tester.h"
12 #include "base/test/simple_test_clock.h" 12 #include "base/test/simple_test_clock.h"
13 #include "base/test/simple_test_tick_clock.h" 13 #include "base/test/simple_test_tick_clock.h"
14 #include "base/threading/thread_task_runner_handle.h" 14 #include "base/threading/thread_task_runner_handle.h"
15 #include "base/time/default_clock.h" 15 #include "base/time/default_clock.h"
16 #include "base/time/default_tick_clock.h" 16 #include "base/time/default_tick_clock.h"
17 #include "components/network_time/network_time_test_utils.h" 17 #include "components/network_time/network_time_test_utils.h"
18 #include "components/network_time/network_time_tracker.h" 18 #include "components/network_time/network_time_tracker.h"
19 #include "components/prefs/testing_pref_service.h" 19 #include "components/prefs/testing_pref_service.h"
20 #include "net/base/net_errors.h" 20 #include "net/base/net_errors.h"
21 #include "net/cert/x509_cert_types.h" 21 #include "net/cert/x509_cert_types.h"
22 #include "net/cert/x509_certificate.h" 22 #include "net/cert/x509_certificate.h"
23 #include "net/test/cert_test_util.h" 23 #include "net/test/cert_test_util.h"
24 #include "net/test/embedded_test_server/embedded_test_server.h" 24 #include "net/test/embedded_test_server/embedded_test_server.h"
25 #include "net/test/embedded_test_server/http_response.h" 25 #include "net/test/embedded_test_server/http_response.h"
26 #include "net/test/test_certificate_data.h" 26 #include "net/test/test_certificate_data.h"
27 #include "net/test/test_data_directory.h" 27 #include "net/test/test_data_directory.h"
28 #include "net/url_request/url_request_test_util.h" 28 #include "net/url_request/url_request_test_util.h"
29 #include "testing/gmock/include/gmock/gmock.h"
29 #include "testing/gtest/include/gtest/gtest.h" 30 #include "testing/gtest/include/gtest/gtest.h"
30 #include "url/gurl.h" 31 #include "url/gurl.h"
31 32
33 using testing::ElementsAre;
34
32 namespace { 35 namespace {
33 const char kNetworkTimeHistogram[] = "interstitial.ssl.clockstate.network3"; 36 const char kNetworkTimeHistogram[] = "interstitial.ssl.clockstate.network3";
37 const char kSslErrorCauseHistogram[] = "interstitial.ssl.cause.overridable";
34 38
35 static std::unique_ptr<net::test_server::HttpResponse> 39 static std::unique_ptr<net::test_server::HttpResponse>
36 NetworkErrorResponseHandler(const net::test_server::HttpRequest& request) { 40 NetworkErrorResponseHandler(const net::test_server::HttpRequest& request) {
37 return std::unique_ptr<net::test_server::HttpResponse>( 41 return std::unique_ptr<net::test_server::HttpResponse>(
38 new net::test_server::RawHttpResponse("", "")); 42 new net::test_server::RawHttpResponse("", ""));
39 } 43 }
40 44
41 } // namespace 45 } // namespace
42 46
43 class SSLErrorClassificationTest : public ::testing::Test { 47 class SSLErrorClassificationTest : public ::testing::Test {
44 public: 48 public:
45 SSLErrorClassificationTest() 49 SSLErrorClassificationTest()
46 : field_trial_test_(new network_time::FieldTrialTest()) {} 50 : field_trial_test_(new network_time::FieldTrialTest()) {}
47 network_time::FieldTrialTest* field_trial_test() { 51 network_time::FieldTrialTest* field_trial_test() {
48 return field_trial_test_.get(); 52 return field_trial_test_.get();
49 } 53 }
50 54
51 private: 55 private:
52 std::unique_ptr<network_time::FieldTrialTest> field_trial_test_; 56 std::unique_ptr<network_time::FieldTrialTest> field_trial_test_;
53 }; 57 };
54 58
55 TEST_F(SSLErrorClassificationTest, TestNameMismatch) { 59 TEST_F(SSLErrorClassificationTest, TestNameMismatch) {
56 scoped_refptr<net::X509Certificate> google_cert( 60 scoped_refptr<net::X509Certificate> example_cert = net::ImportCertFromFile(
57 net::X509Certificate::CreateFromBytes( 61 net::GetTestCertsDirectory(), "subjectAltName_www_example_com.pem");
58 reinterpret_cast<const char*>(google_der), sizeof(google_der))); 62 ASSERT_TRUE(example_cert);
59 ASSERT_TRUE(google_cert.get()); 63 std::vector<std::string> dns_names_example;
60 std::vector<std::string> dns_names_google; 64 example_cert->GetSubjectAltName(&dns_names_example, nullptr);
61 google_cert->GetDNSNames(&dns_names_google); 65 ASSERT_THAT(dns_names_example, ElementsAre("www.example.com"));
62 ASSERT_EQ(1u, dns_names_google.size()); // ["www.google.com"] 66 std::vector<std::string> hostname_tokens_example =
63 std::vector<std::string> hostname_tokens_google = 67 ssl_errors::Tokenize(dns_names_example[0]);
64 ssl_errors::Tokenize(dns_names_google[0]); 68 ASSERT_THAT(hostname_tokens_example, ElementsAre("www", "example", "com"));
65 ASSERT_EQ(3u, hostname_tokens_google.size()); // ["www","google","com"] 69 std::vector<std::vector<std::string>> dns_name_tokens_example;
66 std::vector<std::vector<std::string>> dns_name_tokens_google; 70 dns_name_tokens_example.push_back(hostname_tokens_example);
67 dns_name_tokens_google.push_back(hostname_tokens_google); 71 ASSERT_EQ(1u, dns_name_tokens_example.size()); // [["www","example","com"]]
68 ASSERT_EQ(1u, dns_name_tokens_google.size()); // [["www","google","com"]] 72 ASSERT_THAT(dns_name_tokens_example[0], ElementsAre("www", "example", "com"));
69 73
70 { 74 {
71 GURL origin("https://google.com"); 75 GURL origin("https://example.com");
72 std::string www_host; 76 std::string www_host;
73 std::vector<std::string> host_name_tokens = base::SplitString( 77 std::vector<std::string> host_name_tokens = base::SplitString(
74 origin.host(), ".", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL); 78 origin.host(), ".", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
75 EXPECT_TRUE( 79 EXPECT_TRUE(
76 ssl_errors::GetWWWSubDomainMatch(origin, dns_names_google, &www_host)); 80 ssl_errors::GetWWWSubDomainMatch(origin, dns_names_example, &www_host));
77 EXPECT_EQ("www.google.com", www_host); 81 EXPECT_EQ("www.example.com", www_host);
78 EXPECT_FALSE(ssl_errors::NameUnderAnyNames(host_name_tokens, 82 EXPECT_FALSE(ssl_errors::NameUnderAnyNames(host_name_tokens,
79 dns_name_tokens_google)); 83 dns_name_tokens_example));
80 EXPECT_FALSE(ssl_errors::AnyNamesUnderName(dns_name_tokens_google, 84 EXPECT_FALSE(ssl_errors::AnyNamesUnderName(dns_name_tokens_example,
81 host_name_tokens)); 85 host_name_tokens));
82 EXPECT_FALSE(ssl_errors::IsSubDomainOutsideWildcard(origin, *google_cert)); 86 EXPECT_FALSE(ssl_errors::IsSubDomainOutsideWildcard(origin, *example_cert));
83 EXPECT_FALSE( 87 EXPECT_FALSE(
84 ssl_errors::IsCertLikelyFromMultiTenantHosting(origin, *google_cert)); 88 ssl_errors::IsCertLikelyFromMultiTenantHosting(origin, *example_cert));
85 EXPECT_TRUE(ssl_errors::IsCertLikelyFromSameDomain(origin, *google_cert)); 89 EXPECT_TRUE(ssl_errors::IsCertLikelyFromSameDomain(origin, *example_cert));
86 } 90 }
87 91
88 { 92 {
89 GURL origin("https://foo.blah.google.com"); 93 GURL origin("https://foo.blah.example.com");
90 std::string www_host; 94 std::string www_host;
91 std::vector<std::string> host_name_tokens = base::SplitString( 95 std::vector<std::string> host_name_tokens = base::SplitString(
92 origin.host(), ".", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL); 96 origin.host(), ".", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
93 EXPECT_FALSE( 97 EXPECT_FALSE(
94 ssl_errors::GetWWWSubDomainMatch(origin, dns_names_google, &www_host)); 98 ssl_errors::GetWWWSubDomainMatch(origin, dns_names_example, &www_host));
95 EXPECT_FALSE(ssl_errors::NameUnderAnyNames(host_name_tokens, 99 EXPECT_FALSE(ssl_errors::NameUnderAnyNames(host_name_tokens,
96 dns_name_tokens_google)); 100 dns_name_tokens_example));
97 EXPECT_FALSE(ssl_errors::AnyNamesUnderName(dns_name_tokens_google, 101 EXPECT_FALSE(ssl_errors::AnyNamesUnderName(dns_name_tokens_example,
98 host_name_tokens)); 102 host_name_tokens));
99 EXPECT_TRUE(ssl_errors::IsCertLikelyFromSameDomain(origin, *google_cert)); 103 EXPECT_TRUE(ssl_errors::IsCertLikelyFromSameDomain(origin, *example_cert));
100 } 104 }
101 105
102 { 106 {
103 GURL origin("https://foo.www.google.com"); 107 GURL origin("https://foo.www.example.com");
104 std::string www_host; 108 std::string www_host;
105 std::vector<std::string> host_name_tokens = base::SplitString( 109 std::vector<std::string> host_name_tokens = base::SplitString(
106 origin.host(), ".", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL); 110 origin.host(), ".", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
107 EXPECT_FALSE( 111 EXPECT_FALSE(
108 ssl_errors::GetWWWSubDomainMatch(origin, dns_names_google, &www_host)); 112 ssl_errors::GetWWWSubDomainMatch(origin, dns_names_example, &www_host));
109 EXPECT_TRUE(ssl_errors::NameUnderAnyNames(host_name_tokens, 113 EXPECT_TRUE(ssl_errors::NameUnderAnyNames(host_name_tokens,
110 dns_name_tokens_google)); 114 dns_name_tokens_example));
111 EXPECT_FALSE(ssl_errors::AnyNamesUnderName(dns_name_tokens_google, 115 EXPECT_FALSE(ssl_errors::AnyNamesUnderName(dns_name_tokens_example,
112 host_name_tokens)); 116 host_name_tokens));
113 EXPECT_TRUE(ssl_errors::IsCertLikelyFromSameDomain(origin, *google_cert)); 117 EXPECT_TRUE(ssl_errors::IsCertLikelyFromSameDomain(origin, *example_cert));
114 } 118 }
115 119
116 { 120 {
117 GURL origin("https://www.google.com.foo"); 121 GURL origin("https://www.example.com.foo");
118 std::string www_host; 122 std::string www_host;
119 std::vector<std::string> host_name_tokens = base::SplitString( 123 std::vector<std::string> host_name_tokens = base::SplitString(
120 origin.host(), ".", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL); 124 origin.host(), ".", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
121 EXPECT_FALSE( 125 EXPECT_FALSE(
122 ssl_errors::GetWWWSubDomainMatch(origin, dns_names_google, &www_host)); 126 ssl_errors::GetWWWSubDomainMatch(origin, dns_names_example, &www_host));
123 EXPECT_FALSE(ssl_errors::NameUnderAnyNames(host_name_tokens, 127 EXPECT_FALSE(ssl_errors::NameUnderAnyNames(host_name_tokens,
124 dns_name_tokens_google)); 128 dns_name_tokens_example));
125 EXPECT_FALSE(ssl_errors::AnyNamesUnderName(dns_name_tokens_google, 129 EXPECT_FALSE(ssl_errors::AnyNamesUnderName(dns_name_tokens_example,
126 host_name_tokens)); 130 host_name_tokens));
127 EXPECT_FALSE(ssl_errors::IsCertLikelyFromSameDomain(origin, *google_cert)); 131 EXPECT_FALSE(ssl_errors::IsCertLikelyFromSameDomain(origin, *example_cert));
128 } 132 }
129 133
130 { 134 {
131 GURL origin("https://www.foogoogle.com."); 135 GURL origin("https://www.fooexample.com.");
132 std::string www_host; 136 std::string www_host;
133 std::vector<std::string> host_name_tokens = base::SplitString( 137 std::vector<std::string> host_name_tokens = base::SplitString(
134 origin.host(), ".", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL); 138 origin.host(), ".", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
135 EXPECT_FALSE( 139 EXPECT_FALSE(
136 ssl_errors::GetWWWSubDomainMatch(origin, dns_names_google, &www_host)); 140 ssl_errors::GetWWWSubDomainMatch(origin, dns_names_example, &www_host));
137 EXPECT_FALSE(ssl_errors::NameUnderAnyNames(host_name_tokens, 141 EXPECT_FALSE(ssl_errors::NameUnderAnyNames(host_name_tokens,
138 dns_name_tokens_google)); 142 dns_name_tokens_example));
139 EXPECT_FALSE(ssl_errors::AnyNamesUnderName(dns_name_tokens_google, 143 EXPECT_FALSE(ssl_errors::AnyNamesUnderName(dns_name_tokens_example,
140 host_name_tokens)); 144 host_name_tokens));
141 EXPECT_FALSE(ssl_errors::IsCertLikelyFromSameDomain(origin, *google_cert)); 145 EXPECT_FALSE(ssl_errors::IsCertLikelyFromSameDomain(origin, *example_cert));
142 } 146 }
143 147
144 scoped_refptr<net::X509Certificate> webkit_cert( 148 // Ensure that a certificate with no SubjectAltName does not fall back to
145 net::X509Certificate::CreateFromBytes( 149 // the Subject CN when evaluating hostnames.
146 reinterpret_cast<const char*>(webkit_der), sizeof(webkit_der)));
147 ASSERT_TRUE(webkit_cert.get());
148 std::vector<std::string> dns_names_webkit;
149 webkit_cert->GetDNSNames(&dns_names_webkit);
150 ASSERT_EQ(2u, dns_names_webkit.size()); // ["*.webkit.org", "webkit.org"]
151 std::vector<std::string> hostname_tokens_webkit_0 =
152 ssl_errors::Tokenize(dns_names_webkit[0]);
153 ASSERT_EQ(3u, hostname_tokens_webkit_0.size()); // ["*", "webkit","org"]
154 std::vector<std::string> hostname_tokens_webkit_1 =
155 ssl_errors::Tokenize(dns_names_webkit[1]);
156 ASSERT_EQ(2u, hostname_tokens_webkit_1.size()); // ["webkit","org"]
157 std::vector<std::vector<std::string>> dns_name_tokens_webkit;
158 dns_name_tokens_webkit.push_back(hostname_tokens_webkit_0);
159 dns_name_tokens_webkit.push_back(hostname_tokens_webkit_1);
160 ASSERT_EQ(2u, dns_name_tokens_webkit.size());
161 { 150 {
151 scoped_refptr<net::X509Certificate> google_cert(
152 net::X509Certificate::CreateFromBytes(
153 reinterpret_cast<const char*>(google_der), sizeof(google_der)));
154 ASSERT_TRUE(google_cert);
155
156 GURL origin("https://google.com");
157
158 base::HistogramTester histograms;
159 ssl_errors::RecordUMAStatistics(true, base::Time::NowFromSystemTime(),
160 origin, net::ERR_CERT_COMMON_NAME_INVALID,
161 *google_cert);
162
163 // Verify that we recorded only NO_SUBJECT_ALT_NAME and no other causes.
164 histograms.ExpectUniqueSample(kSslErrorCauseHistogram,
165 ssl_errors::NO_SUBJECT_ALT_NAME, 1);
166 }
167
168 {
169 scoped_refptr<net::X509Certificate> webkit_cert(
170 net::X509Certificate::CreateFromBytes(
171 reinterpret_cast<const char*>(webkit_der), sizeof(webkit_der)));
172 ASSERT_TRUE(webkit_cert);
173 std::vector<std::string> dns_names_webkit;
174 webkit_cert->GetSubjectAltName(&dns_names_webkit, nullptr);
175 ASSERT_THAT(dns_names_webkit, ElementsAre("*.webkit.org", "webkit.org"));
176 std::vector<std::string> hostname_tokens_webkit_0 =
177 ssl_errors::Tokenize(dns_names_webkit[0]);
178 ASSERT_THAT(hostname_tokens_webkit_0, ElementsAre("*", "webkit", "org"));
179 std::vector<std::string> hostname_tokens_webkit_1 =
180 ssl_errors::Tokenize(dns_names_webkit[1]);
181 ASSERT_THAT(hostname_tokens_webkit_1, ElementsAre("webkit", "org"));
182 std::vector<std::vector<std::string>> dns_name_tokens_webkit;
183 dns_name_tokens_webkit.push_back(hostname_tokens_webkit_0);
184 dns_name_tokens_webkit.push_back(hostname_tokens_webkit_1);
185 ASSERT_EQ(2u, dns_name_tokens_webkit.size());
162 GURL origin("https://a.b.webkit.org"); 186 GURL origin("https://a.b.webkit.org");
163 std::string www_host; 187 std::string www_host;
164 std::vector<std::string> host_name_tokens = base::SplitString( 188 std::vector<std::string> host_name_tokens = base::SplitString(
165 origin.host(), ".", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL); 189 origin.host(), ".", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
166 EXPECT_FALSE( 190 EXPECT_FALSE(
167 ssl_errors::GetWWWSubDomainMatch(origin, dns_names_webkit, &www_host)); 191 ssl_errors::GetWWWSubDomainMatch(origin, dns_names_webkit, &www_host));
168 EXPECT_FALSE(ssl_errors::NameUnderAnyNames(host_name_tokens, 192 EXPECT_FALSE(ssl_errors::NameUnderAnyNames(host_name_tokens,
169 dns_name_tokens_webkit)); 193 dns_name_tokens_webkit));
170 EXPECT_FALSE(ssl_errors::AnyNamesUnderName(dns_name_tokens_webkit, 194 EXPECT_FALSE(ssl_errors::AnyNamesUnderName(dns_name_tokens_webkit,
171 host_name_tokens)); 195 host_name_tokens));
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after
446 clock->Advance(base::TimeDelta::FromDays(1)); 470 clock->Advance(base::TimeDelta::FromDays(1));
447 // GetClockState() will fall back to the build time heuristic. 471 // GetClockState() will fall back to the build time heuristic.
448 ssl_errors::GetClockState(clock->Now(), &network_time_tracker); 472 ssl_errors::GetClockState(clock->Now(), &network_time_tracker);
449 histograms.ExpectTotalCount(kNetworkTimeHistogram, 8); 473 histograms.ExpectTotalCount(kNetworkTimeHistogram, 8);
450 histograms.ExpectBucketCount( 474 histograms.ExpectBucketCount(
451 kNetworkTimeHistogram, ssl_errors::NETWORK_CLOCK_STATE_UNKNOWN_SYNC_LOST, 475 kNetworkTimeHistogram, ssl_errors::NETWORK_CLOCK_STATE_UNKNOWN_SYNC_LOST,
452 1); 476 1);
453 477
454 io_thread.Stop(); 478 io_thread.Stop();
455 } 479 }
OLDNEW
« no previous file with comments | « components/ssl_errors/error_classification.cc ('k') | components/ssl_errors/error_info.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698