Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / ssl / ssl_error_handler_unittest.cc
blob72be3e138d8989f77e7b9e8802782032f18c5fbe
1 // Copyright 2014 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.
5 #include "chrome/browser/ssl/ssl_error_handler.h"
7 #include "base/callback.h"
8 #include "base/message_loop/message_loop.h"
9 #include "base/metrics/field_trial.h"
10 #include "base/run_loop.h"
11 #include "base/time/time.h"
12 #include "chrome/browser/captive_portal/captive_portal_service.h"
13 #include "chrome/browser/profiles/profile.h"
14 #include "chrome/browser/ssl/common_name_mismatch_handler.h"
15 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
16 #include "chrome/test/base/testing_profile.h"
17 #include "components/captive_portal/captive_portal_testing_utils.h"
18 #include "content/public/browser/notification_service.h"
19 #include "net/base/net_errors.h"
20 #include "net/base/test_data_directory.h"
21 #include "net/cert/x509_certificate.h"
22 #include "net/ssl/ssl_info.h"
23 #include "net/test/cert_test_util.h"
24 #include "net/test/test_certificate_data.h"
25 #include "testing/gtest/include/gtest/gtest.h"
27 class SSLErrorHandlerForTest : public SSLErrorHandler {
28 public:
29 SSLErrorHandlerForTest(Profile* profile,
30 content::WebContents* web_contents,
31 const net::SSLInfo& ssl_info)
32 : SSLErrorHandler(web_contents,
33 net::ERR_CERT_COMMON_NAME_INVALID,
34 ssl_info,
35 GURL(),
37 nullptr,
38 base::Callback<void(bool)>()),
39 profile_(profile),
40 captive_portal_checked_(false),
41 suggested_url_exists_(false),
42 suggested_url_checked_(false),
43 ssl_interstitial_shown_(false),
44 captive_portal_interstitial_shown_(false),
45 redirected_to_suggested_url_(false),
46 is_overridable_error_(true) {}
48 using SSLErrorHandler::StartHandlingError;
50 void SendCaptivePortalNotification(
51 captive_portal::CaptivePortalResult result) {
52 CaptivePortalService::Results results;
53 results.previous_result = captive_portal::RESULT_INTERNET_CONNECTED;
54 results.result = result;
55 content::NotificationService::current()->Notify(
56 chrome::NOTIFICATION_CAPTIVE_PORTAL_CHECK_RESULT,
57 content::Source<Profile>(profile_),
58 content::Details<CaptivePortalService::Results>(&results));
61 void SendSuggestedUrlCheckResult(
62 const CommonNameMismatchHandler::SuggestedUrlCheckResult& result,
63 const GURL& suggested_url) {
64 CommonNameMismatchHandlerCallback(result, suggested_url);
67 bool IsTimerRunning() const { return get_timer().IsRunning(); }
68 int captive_portal_checked() const { return captive_portal_checked_; }
69 int ssl_interstitial_shown() const { return ssl_interstitial_shown_; }
70 int captive_portal_interstitial_shown() const {
71 return captive_portal_interstitial_shown_;
73 bool suggested_url_checked() const { return suggested_url_checked_; }
74 bool redirected_to_suggested_url() const {
75 return redirected_to_suggested_url_;
78 void set_suggested_url_exists() { suggested_url_exists_ = true; }
79 void set_non_overridable_error() { is_overridable_error_ = false; }
81 void ClearSeenOperations() {
82 captive_portal_checked_ = false;
83 suggested_url_exists_ = false;
84 suggested_url_checked_ = false;
85 ssl_interstitial_shown_ = false;
86 captive_portal_interstitial_shown_ = false;
87 redirected_to_suggested_url_ = false;
90 private:
91 void CheckForCaptivePortal() override {
92 captive_portal_checked_ = true;
95 bool GetSuggestedUrl(const std::vector<std::string>& dns_names,
96 GURL* suggested_url) const override {
97 if (!suggested_url_exists_)
98 return false;
99 *suggested_url = GURL("www.example.com");
100 return true;
103 void ShowSSLInterstitial() override { ssl_interstitial_shown_ = true; }
105 void ShowCaptivePortalInterstitial(const GURL& landing_url) override {
106 captive_portal_interstitial_shown_ = true;
109 void CheckSuggestedUrl(const GURL& suggested_url) override {
110 suggested_url_checked_ = true;
113 void NavigateToSuggestedURL(const GURL& suggested_url) override {
114 redirected_to_suggested_url_ = true;
117 bool IsErrorOverridable() const override { return is_overridable_error_; }
119 Profile* profile_;
120 bool captive_portal_checked_;
121 bool suggested_url_exists_;
122 bool suggested_url_checked_;
123 bool ssl_interstitial_shown_;
124 bool captive_portal_interstitial_shown_;
125 bool redirected_to_suggested_url_;
126 bool is_overridable_error_;
128 DISALLOW_COPY_AND_ASSIGN(SSLErrorHandlerForTest);
131 class SSLErrorHandlerTest : public ChromeRenderViewHostTestHarness {
132 public:
133 SSLErrorHandlerTest() : field_trial_list_(nullptr) {}
135 void SetUp() override {
136 ChromeRenderViewHostTestHarness::SetUp();
137 SSLErrorHandler::SetInterstitialDelayForTest(base::TimeDelta());
138 ssl_info_.cert =
139 net::ImportCertFromFile(net::GetTestCertsDirectory(), "ok_cert.pem");
140 ssl_info_.cert_status = net::CERT_STATUS_COMMON_NAME_INVALID;
141 error_handler_.reset(
142 new SSLErrorHandlerForTest(profile(), web_contents(), ssl_info_));
143 // Enable finch experiment for captive portal interstitials.
144 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
145 "CaptivePortalInterstitial", "Enabled"));
146 // Enable finch experiment for SSL common name mismatch handling.
147 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
148 "SSLCommonNameMismatchHandling", "Enabled"));
151 void TearDown() override {
152 EXPECT_FALSE(error_handler()->IsTimerRunning());
153 error_handler_.reset(nullptr);
154 ChromeRenderViewHostTestHarness::TearDown();
157 SSLErrorHandlerForTest* error_handler() { return error_handler_.get(); }
159 private:
160 net::SSLInfo ssl_info_;
161 scoped_ptr<SSLErrorHandlerForTest> error_handler_;
162 base::FieldTrialList field_trial_list_;
165 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION)
167 TEST_F(SSLErrorHandlerTest,
168 ShouldShowSSLInterstitialOnTimerExpired) {
169 EXPECT_FALSE(error_handler()->IsTimerRunning());
170 error_handler()->StartHandlingError();
172 EXPECT_TRUE(error_handler()->IsTimerRunning());
173 EXPECT_TRUE(error_handler()->captive_portal_checked());
174 EXPECT_FALSE(error_handler()->ssl_interstitial_shown());
175 EXPECT_FALSE(error_handler()->captive_portal_interstitial_shown());
177 error_handler()->ClearSeenOperations();
178 base::MessageLoop::current()->RunUntilIdle();
180 EXPECT_FALSE(error_handler()->IsTimerRunning());
181 EXPECT_FALSE(error_handler()->captive_portal_checked());
182 EXPECT_TRUE(error_handler()->ssl_interstitial_shown());
183 EXPECT_FALSE(error_handler()->captive_portal_interstitial_shown());
186 TEST_F(SSLErrorHandlerTest,
187 ShouldShowCustomInterstitialOnCaptivePortalResult) {
188 EXPECT_FALSE(error_handler()->IsTimerRunning());
189 error_handler()->StartHandlingError();
191 EXPECT_TRUE(error_handler()->IsTimerRunning());
192 EXPECT_TRUE(error_handler()->captive_portal_checked());
193 EXPECT_FALSE(error_handler()->ssl_interstitial_shown());
194 EXPECT_FALSE(error_handler()->captive_portal_interstitial_shown());
195 // Fake a captive portal result.
196 error_handler()->ClearSeenOperations();
197 error_handler()->SendCaptivePortalNotification(
198 captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL);
199 base::MessageLoop::current()->RunUntilIdle();
201 EXPECT_FALSE(error_handler()->IsTimerRunning());
202 EXPECT_FALSE(error_handler()->captive_portal_checked());
203 EXPECT_FALSE(error_handler()->ssl_interstitial_shown());
204 EXPECT_TRUE(error_handler()->captive_portal_interstitial_shown());
207 TEST_F(SSLErrorHandlerTest,
208 ShouldShowSSLInterstitialOnNoCaptivePortalResult) {
209 EXPECT_FALSE(error_handler()->IsTimerRunning());
210 error_handler()->StartHandlingError();
212 EXPECT_TRUE(error_handler()->IsTimerRunning());
213 EXPECT_TRUE(error_handler()->captive_portal_checked());
214 EXPECT_FALSE(error_handler()->ssl_interstitial_shown());
215 EXPECT_FALSE(error_handler()->captive_portal_interstitial_shown());
216 // Fake a "connected to internet" result for the captive portal check.
217 // This should immediately trigger an SSL interstitial without waiting for
218 // the timer to expire.
219 error_handler()->ClearSeenOperations();
220 error_handler()->SendCaptivePortalNotification(
221 captive_portal::RESULT_INTERNET_CONNECTED);
222 base::MessageLoop::current()->RunUntilIdle();
224 EXPECT_FALSE(error_handler()->IsTimerRunning());
225 EXPECT_FALSE(error_handler()->captive_portal_checked());
226 EXPECT_TRUE(error_handler()->ssl_interstitial_shown());
227 EXPECT_FALSE(error_handler()->captive_portal_interstitial_shown());
230 TEST_F(SSLErrorHandlerTest, ShouldNotCheckSuggestedUrlIfNoSuggestedUrl) {
231 error_handler()->StartHandlingError();
233 EXPECT_TRUE(error_handler()->captive_portal_checked());
234 EXPECT_TRUE(error_handler()->IsTimerRunning());
235 EXPECT_FALSE(error_handler()->suggested_url_checked());
236 base::RunLoop().RunUntilIdle();
238 EXPECT_FALSE(error_handler()->IsTimerRunning());
239 EXPECT_TRUE(error_handler()->ssl_interstitial_shown());
242 TEST_F(SSLErrorHandlerTest, ShouldNotCheckCaptivePortalIfSuggestedUrlExists) {
243 EXPECT_FALSE(error_handler()->IsTimerRunning());
244 error_handler()->set_suggested_url_exists();
245 error_handler()->StartHandlingError();
247 EXPECT_TRUE(error_handler()->IsTimerRunning());
248 EXPECT_TRUE(error_handler()->suggested_url_checked());
249 EXPECT_FALSE(error_handler()->captive_portal_checked());
250 base::RunLoop().RunUntilIdle();
252 EXPECT_FALSE(error_handler()->IsTimerRunning());
253 EXPECT_TRUE(error_handler()->ssl_interstitial_shown());
256 TEST_F(SSLErrorHandlerTest, ShouldNotHandleNameMismatchOnNonOverridableError) {
257 error_handler()->set_non_overridable_error();
258 error_handler()->set_suggested_url_exists();
259 error_handler()->StartHandlingError();
261 EXPECT_FALSE(error_handler()->suggested_url_checked());
262 EXPECT_TRUE(error_handler()->captive_portal_checked());
263 EXPECT_TRUE(error_handler()->IsTimerRunning());
264 base::RunLoop().RunUntilIdle();
266 EXPECT_FALSE(error_handler()->IsTimerRunning());
267 EXPECT_TRUE(error_handler()->ssl_interstitial_shown());
270 #else // #if !defined(ENABLE_CAPTIVE_PORTAL_DETECTION)
272 TEST_F(SSLErrorHandlerTest,
273 ShouldShowSSLInterstitialOnCaptivePortalDetectionDisabled) {
274 EXPECT_FALSE(error_handler()->IsTimerRunning());
275 error_handler()->StartHandlingError();
276 EXPECT_FALSE(error_handler()->IsTimerRunning());
277 EXPECT_FALSE(error_handler()->captive_portal_checked());
278 EXPECT_TRUE(error_handler()->ssl_interstitial_shown());
279 EXPECT_FALSE(error_handler()->captive_portal_interstitial_shown());
282 #endif // defined(ENABLE_CAPTIVE_PORTAL_DETECTION)
284 TEST_F(SSLErrorHandlerTest,
285 ShouldShowSSLInterstitialOnTimerExpiredWhenSuggestedUrlExists) {
286 error_handler()->set_suggested_url_exists();
287 error_handler()->StartHandlingError();
289 EXPECT_TRUE(error_handler()->IsTimerRunning());
290 EXPECT_TRUE(error_handler()->suggested_url_checked());
291 EXPECT_FALSE(error_handler()->ssl_interstitial_shown());
292 EXPECT_FALSE(error_handler()->redirected_to_suggested_url());
294 base::RunLoop().RunUntilIdle();
296 EXPECT_FALSE(error_handler()->IsTimerRunning());
297 EXPECT_TRUE(error_handler()->ssl_interstitial_shown());
298 EXPECT_FALSE(error_handler()->redirected_to_suggested_url());
301 TEST_F(SSLErrorHandlerTest, ShouldRedirectOnSuggestedUrlCheckResult) {
302 error_handler()->set_suggested_url_exists();
303 error_handler()->StartHandlingError();
305 EXPECT_TRUE(error_handler()->IsTimerRunning());
306 EXPECT_TRUE(error_handler()->suggested_url_checked());
307 EXPECT_FALSE(error_handler()->ssl_interstitial_shown());
308 EXPECT_FALSE(error_handler()->redirected_to_suggested_url());
309 // Fake a valid suggested URL check result.
310 // The URL returned by |SuggestedUrlCheckResult| can be different from
311 // |suggested_url|, if there is a redirect.
312 error_handler()->SendSuggestedUrlCheckResult(
313 CommonNameMismatchHandler::SuggestedUrlCheckResult::
314 SUGGESTED_URL_AVAILABLE,
315 GURL("https://random.example.com"));
317 EXPECT_FALSE(error_handler()->IsTimerRunning());
318 EXPECT_FALSE(error_handler()->ssl_interstitial_shown());
319 EXPECT_TRUE(error_handler()->redirected_to_suggested_url());
322 TEST_F(SSLErrorHandlerTest, ShouldShowSSLInterstitialOnInvalidUrlCheckResult) {
323 error_handler()->set_suggested_url_exists();
324 error_handler()->StartHandlingError();
326 EXPECT_TRUE(error_handler()->IsTimerRunning());
327 EXPECT_TRUE(error_handler()->suggested_url_checked());
328 EXPECT_FALSE(error_handler()->ssl_interstitial_shown());
329 EXPECT_FALSE(error_handler()->redirected_to_suggested_url());
330 // Fake an Invalid Suggested URL Check result.
331 error_handler()->SendSuggestedUrlCheckResult(
332 CommonNameMismatchHandler::SuggestedUrlCheckResult::
333 SUGGESTED_URL_NOT_AVAILABLE,
334 GURL());
336 EXPECT_FALSE(error_handler()->IsTimerRunning());
337 EXPECT_TRUE(error_handler()->ssl_interstitial_shown());
338 EXPECT_FALSE(error_handler()->redirected_to_suggested_url());