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.
4 
5 #include "components/security_interstitials/content/ssl_error_handler.h"
6 
7 #include <memory>
8 
9 #include "base/bind.h"
10 #include "base/callback.h"
11 #include "base/macros.h"
12 #include "base/metrics/field_trial.h"
13 #include "base/run_loop.h"
14 #include "base/task/post_task.h"
15 #include "base/test/metrics/histogram_tester.h"
16 #include "base/test/scoped_feature_list.h"
17 #include "base/test/simple_test_clock.h"
18 #include "base/test/simple_test_tick_clock.h"
19 #include "base/time/time.h"
20 #include "build/build_config.h"
21 #include "build/chromecast_buildflags.h"
22 #include "components/captive_portal/content/captive_portal_service.h"
23 #include "components/captive_portal/core/buildflags.h"
24 #include "components/captive_portal/core/captive_portal_testing_utils.h"
25 #include "components/embedder_support/pref_names.h"
26 #include "components/network_time/network_time_test_utils.h"
27 #include "components/network_time/network_time_tracker.h"
28 #include "components/prefs/pref_registry_simple.h"
29 #include "components/prefs/testing_pref_service.h"
30 #include "components/security_interstitials/content/common_name_mismatch_handler.h"
31 #include "components/security_interstitials/content/ssl_error_assistant.h"
32 #include "components/security_interstitials/content/ssl_error_assistant.pb.h"
33 #include "components/security_interstitials/content/ssl_error_handler.h"
34 #include "components/security_interstitials/core/ssl_error_options_mask.h"
35 #include "components/security_interstitials/core/ssl_error_ui.h"
36 #include "content/public/browser/browser_task_traits.h"
37 #include "content/public/browser/browser_thread.h"
38 #include "content/public/test/test_renderer_host.h"
39 #include "net/base/net_errors.h"
40 #include "net/cert/cert_status_flags.h"
41 #include "net/cert/x509_certificate.h"
42 #include "net/http/http_response_headers.h"
43 #include "net/ssl/ssl_info.h"
44 #include "net/test/cert_test_util.h"
45 #include "net/test/embedded_test_server/embedded_test_server.h"
46 #include "net/test/embedded_test_server/http_response.h"
47 #include "net/test/test_certificate_data.h"
48 #include "net/test/test_data_directory.h"
49 #include "net/url_request/url_request_test_util.h"
50 #include "services/network/test/test_shared_url_loader_factory.h"
51 #include "testing/gtest/include/gtest/gtest.h"
52 
53 namespace {
54 
55 const char kCertDateErrorHistogram[] =
56     "interstitial.ssl_error_handler.cert_date_error_delay";
57 
58 const net::SHA256HashValue kCertPublicKeyHashValue = {{0x01, 0x02}};
59 
60 const char kOkayCertName[] = "ok_cert.pem";
61 
62 const uint32_t kLargeVersionId = 0xFFFFFFu;
63 
64 // These certificates are self signed certificates with relevant issuer common
65 // names generated using the following openssl command:
66 //  openssl req -new -x509 -keyout server.pem -out server.pem -days 365 -nodes
67 
68 // Common name: "Misconfigured Firewall_4GHPOS5412EF"
69 // Organization name: "Misconfigured Firewall"
70 const char kMisconfiguredFirewallCert[] =
71     "-----BEGIN CERTIFICATE-----\n"
72     "MIIEKTCCAxGgAwIBAgIJAOxA1g2otzdHMA0GCSqGSIb3DQEBCwUAMIGqMQswCQYD\n"
73     "VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5j\n"
74     "aXNjbzEfMB0GA1UECgwWTWlzY29uZmlndXJlZCBGaXJld2FsbDEsMCoGA1UEAwwj\n"
75     "TWlzY29uZmlndXJlZCBGaXJld2FsbF80R0hQT1M1NDEyRUYxHzAdBgkqhkiG9w0B\n"
76     "CQEWEHRlc3RAZXhhbXBsZS5jb20wHhcNMTcwODE4MjM1MjI4WhcNMTgwODE4MjM1\n"
77     "MjI4WjCBqjELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNV\n"
78     "BAcMDVNhbiBGcmFuY2lzY28xHzAdBgNVBAoMFk1pc2NvbmZpZ3VyZWQgRmlyZXdh\n"
79     "bGwxLDAqBgNVBAMMI01pc2NvbmZpZ3VyZWQgRmlyZXdhbGxfNEdIUE9TNTQxMkVG\n"
80     "MR8wHQYJKoZIhvcNAQkBFhB0ZXN0QGV4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0B\n"
81     "AQEFAAOCAQ8AMIIBCgKCAQEAtxh4PZ9dbqeXubutRBFSL4FschunDX/vRFzhlQdz\n"
82     "3fqzIfmN2PjvwBsoX1oDaWdTTefCLad7pX08UVyX2pS0UeqYwUJL+ihXuupW0pBV\n"
83     "M2VZ/soDgze7Vl9dUU43NLoODOzwvKt92QdyfS7toPEEmwFLrI4/UnzxX+QlS8qq\n"
84     "naWD5ny2XZOZdNizBX1UQlvkvfYJM0wUmBZ/VUj/QQxxNHZaEBcl64t3h5jHiq1c\n"
85     "gWDgp0zeYy+PbJk/LMSvF64qqMFDtujUQcniYC6HwWJ9YT7PFX2b7X9Mq4b3gtpV\n"
86     "6jGXXUJqg+SfLW7XisZcWVMfHZDaVfdd35vNm61XY4sg1wIDAQABo1AwTjAdBgNV\n"
87     "HQ4EFgQUmUhF2RL+A4QAEel9JiEYNbPyU+AwHwYDVR0jBBgwFoAUmUhF2RL+A4QA\n"
88     "Eel9JiEYNbPyU+AwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAO+kk\n"
89     "Uin9uKD2iTkUtuoAckt+kcctmvHcP3zLe+J0m25f9HOyrjhutgIYZDwt2LiAnOTA\n"
90     "CQHg3t5YyDQHove39M6I1vWhoAy9jOi0Qn+lTKkVu5H4g5ZiauO3coneqFw/dPe+\n"
91     "kYye/bPKV4jNlhEYXF5+Pa7PYde0sxf7AmlDJb9NZh01xRKNFt6ScDpirhJIFdzg\n"
92     "ZKram+yJyIbcZI+yd7mjzu9dSCS0NbnsZDL7xqThFFZsbhZyO98kzdDS+crip6y5\n"
93     "rz3+AJpJvlGcf898Y4ibAPmeX62j6pug55TGfAdsqSVUiaQX1HcwwbmlSOYrhYTm\n"
94     "lMEx5QP9TqgGU0nGwQ==\n"
95     "-----END CERTIFICATE-----";
96 
97 // Common name: None
98 // Organization name: None
99 const char kCertWithoutOrganizationOrCommonName[] =
100     "-----BEGIN CERTIFICATE-----\n"
101     "MIIDzzCCAregAwIBAgIJAJfHNOMLXbc4MA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNV\n"
102     "BAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4gRnJhbmNp\n"
103     "c2NvMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxHzAdBgkqhkiG\n"
104     "9w0BCQEWEHRlc3RAZXhhbXBsZS5jb20wHhcNMTcwODE5MDAwNTMyWhcNMTgwODE5\n"
105     "MDAwNTMyWjB+MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQG\n"
106     "A1UEBwwNU2FuIEZyYW5jaXNjbzEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQ\n"
107     "dHkgTHRkMR8wHQYJKoZIhvcNAQkBFhB0ZXN0QGV4YW1wbGUuY29tMIIBIjANBgkq\n"
108     "hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA28iX7cIS5XS+hU/0OreJXfVmEWDPVRX1\n"
109     "n05AlX+ETRunnYevZOAhbSFuUeJi2cGgW4cpD6fGKrf05PpNM9GQ4yswIPlVsemR\n"
110     "ickSmg8vVemPs/Hz3y0dYnRoTwzzVESh4OIVGe+rrhCUdWVHE+/HOdmHAXoBI6m1\n"
111     "OhN2GgtvnEEMYzTaMRGNqb5VhRKYHwLNp8zqLtrHIbo61mi8Wl7E4NZdaVk4cTNK\n"
112     "w93Y8RqlwzzpbWT9RH74JPCM+wSg0rCK+h59sa86W4yPvhXyYIGXM8WhWkMW68Ej\n"
113     "jqfE0lQlEuxKPeCYZn6oC+AVRLxHCwncVxZaUtGUovMzBdV3WzsLPwIDAQABo1Aw\n"
114     "TjAdBgNVHQ4EFgQUlkC11ZD66sKrb25g4mH4sob4e3MwHwYDVR0jBBgwFoAUlkC1\n"
115     "1ZD66sKrb25g4mH4sob4e3MwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOC\n"
116     "AQEAUHQZmeZdAV86TIWviPNWNqhPD+/OEGnOwgjUrBmSrQkc5hPZUhQ8the7ewNE\n"
117     "V/eGjDNF72tiQqPQP7Zrhdf7i1p1Q3ufcDHpOOFbEdKd6m2DeCLg83jOLqLr/jTB\n"
118     "CC7GyyWOyt+CFVRGC0yovSl3+Vxaso6DZjelO3IP5K7bT5U1f3cUZnYTpYfslh1t\n"
119     "dUmxh9/MaKxnRaHkr0HDVGpWS4ZMoZUyyC6D9ZfCQ5aGJJubQEPxADc2tXHXOL73\n"
120     "dspwZ8CTOlcXnfdeRIjvgxnMZLax+OFEMJdY8sgyrI9c+rk2EfOUj5JVqFDvcsYy\n"
121     "ejdBhjdieIv5dTbSjIXz+ljOOA==\n"
122     "-----END CERTIFICATE-----";
123 
124 // Runs |quit_closure| on the UI thread once a URL request has been
125 // seen. Returns a request that hangs.
WaitForRequest(const base::Closure & quit_closure,const net::test_server::HttpRequest & request)126 std::unique_ptr<net::test_server::HttpResponse> WaitForRequest(
127     const base::Closure& quit_closure,
128     const net::test_server::HttpRequest& request) {
129   base::PostTask(FROM_HERE, {content::BrowserThread::UI}, quit_closure);
130   return std::make_unique<net::test_server::HungResponse>();
131 }
132 
133 class TestSSLErrorHandler : public SSLErrorHandler {
134  public:
TestSSLErrorHandler(std::unique_ptr<Delegate> delegate,content::WebContents * web_contents,int cert_error,const net::SSLInfo & ssl_info,network_time::NetworkTimeTracker * network_time_tracker,const GURL & request_url,captive_portal::CaptivePortalService * captive_portal_service)135   TestSSLErrorHandler(
136       std::unique_ptr<Delegate> delegate,
137       content::WebContents* web_contents,
138       int cert_error,
139       const net::SSLInfo& ssl_info,
140       network_time::NetworkTimeTracker* network_time_tracker,
141       const GURL& request_url,
142       captive_portal::CaptivePortalService* captive_portal_service)
143       : SSLErrorHandler(std::move(delegate),
144                         web_contents,
145                         cert_error,
146                         ssl_info,
147                         network_time_tracker,
148                         captive_portal_service,
149                         request_url) {}
150 
151   using SSLErrorHandler::StartHandlingError;
152 };
153 
154 class TestSSLErrorHandlerDelegate : public SSLErrorHandler::Delegate {
155  public:
TestSSLErrorHandlerDelegate(content::WebContents * web_contents,const net::SSLInfo & ssl_info)156   TestSSLErrorHandlerDelegate(content::WebContents* web_contents,
157                               const net::SSLInfo& ssl_info)
158       : captive_portal_checked_(false),
159         os_reports_captive_portal_(false),
160         suggested_url_exists_(false),
161         suggested_url_checked_(false),
162         ssl_interstitial_shown_(false),
163         bad_clock_interstitial_shown_(false),
164         captive_portal_interstitial_shown_(false),
165         mitm_software_interstitial_shown_(false),
166         blocked_interception_interstitial_shown_(false),
167         redirected_to_suggested_url_(false),
168         is_overridable_error_(true),
169         has_blocked_interception_(false),
170         legacy_tls_interstitial_shown_(false) {}
171 
SendSuggestedUrlCheckResult(const CommonNameMismatchHandler::SuggestedUrlCheckResult & result,const GURL & suggested_url)172   void SendSuggestedUrlCheckResult(
173       const CommonNameMismatchHandler::SuggestedUrlCheckResult& result,
174       const GURL& suggested_url) {
175     suggested_url_callback_.Run(result, suggested_url);
176   }
177 
captive_portal_checked() const178   int captive_portal_checked() const { return captive_portal_checked_; }
ssl_interstitial_shown() const179   int ssl_interstitial_shown() const { return ssl_interstitial_shown_; }
captive_portal_interstitial_shown() const180   int captive_portal_interstitial_shown() const {
181     return captive_portal_interstitial_shown_;
182   }
mitm_software_interstitial_shown() const183   int mitm_software_interstitial_shown() const {
184     return mitm_software_interstitial_shown_;
185   }
bad_clock_interstitial_shown() const186   bool bad_clock_interstitial_shown() const {
187     return bad_clock_interstitial_shown_;
188   }
blocked_interception_interstitial_shown() const189   bool blocked_interception_interstitial_shown() const {
190     return blocked_interception_interstitial_shown_;
191   }
suggested_url_checked() const192   bool suggested_url_checked() const { return suggested_url_checked_; }
redirected_to_suggested_url() const193   bool redirected_to_suggested_url() const {
194     return redirected_to_suggested_url_;
195   }
legacy_tls_interstitial_shown() const196   bool legacy_tls_interstitial_shown() const {
197     return legacy_tls_interstitial_shown_;
198   }
199 
set_suggested_url_exists()200   void set_suggested_url_exists() { suggested_url_exists_ = true; }
set_non_overridable_error()201   void set_non_overridable_error() { is_overridable_error_ = false; }
set_os_reports_captive_portal()202   void set_os_reports_captive_portal() { os_reports_captive_portal_ = true; }
set_has_blocked_interception()203   void set_has_blocked_interception() { has_blocked_interception_ = true; }
set_has_legacy_tls()204   void set_has_legacy_tls() { has_legacy_tls_ = true; }
205 
ClearSeenOperations()206   void ClearSeenOperations() {
207     captive_portal_checked_ = false;
208     os_reports_captive_portal_ = false;
209     suggested_url_exists_ = false;
210     suggested_url_checked_ = false;
211     ssl_interstitial_shown_ = false;
212     bad_clock_interstitial_shown_ = false;
213     captive_portal_interstitial_shown_ = false;
214     mitm_software_interstitial_shown_ = false;
215     redirected_to_suggested_url_ = false;
216     has_blocked_interception_ = false;
217     legacy_tls_interstitial_shown_ = false;
218     has_legacy_tls_ = false;
219   }
220 
221  private:
CheckForCaptivePortal()222   void CheckForCaptivePortal() override { captive_portal_checked_ = true; }
223 
DoesOSReportCaptivePortal()224   bool DoesOSReportCaptivePortal() override {
225     return os_reports_captive_portal_;
226   }
227 
GetSuggestedUrl(const std::vector<std::string> & dns_names,GURL * suggested_url) const228   bool GetSuggestedUrl(const std::vector<std::string>& dns_names,
229                        GURL* suggested_url) const override {
230     if (!suggested_url_exists_)
231       return false;
232     *suggested_url = GURL("www.example.com");
233     return true;
234   }
235 
ShowSSLInterstitial(const GURL & support_url=GURL ())236   void ShowSSLInterstitial(const GURL& support_url = GURL()) override {
237     ssl_interstitial_shown_ = true;
238   }
239 
ShowBadClockInterstitial(const base::Time & now,ssl_errors::ClockState clock_state)240   void ShowBadClockInterstitial(const base::Time& now,
241                                 ssl_errors::ClockState clock_state) override {
242     bad_clock_interstitial_shown_ = true;
243   }
244 
ShowCaptivePortalInterstitial(const GURL & landing_url)245   void ShowCaptivePortalInterstitial(const GURL& landing_url) override {
246     captive_portal_interstitial_shown_ = true;
247   }
248 
ShowMITMSoftwareInterstitial(const std::string & mitm_software_name)249   void ShowMITMSoftwareInterstitial(
250       const std::string& mitm_software_name) override {
251     mitm_software_interstitial_shown_ = true;
252   }
253 
ShowBlockedInterceptionInterstitial()254   void ShowBlockedInterceptionInterstitial() override {
255     blocked_interception_interstitial_shown_ = true;
256   }
257 
ShowLegacyTLSInterstitial()258   void ShowLegacyTLSInterstitial() override {
259     legacy_tls_interstitial_shown_ = true;
260   }
261 
CheckSuggestedUrl(const GURL & suggested_url,const CommonNameMismatchHandler::CheckUrlCallback & callback)262   void CheckSuggestedUrl(
263       const GURL& suggested_url,
264       const CommonNameMismatchHandler::CheckUrlCallback& callback) override {
265     DCHECK(suggested_url_callback_.is_null());
266     suggested_url_checked_ = true;
267     suggested_url_callback_ = callback;
268   }
269 
NavigateToSuggestedURL(const GURL & suggested_url)270   void NavigateToSuggestedURL(const GURL& suggested_url) override {
271     redirected_to_suggested_url_ = true;
272   }
273 
IsErrorOverridable() const274   bool IsErrorOverridable() const override { return is_overridable_error_; }
275 
ReportNetworkConnectivity(base::OnceClosure callback)276   void ReportNetworkConnectivity(base::OnceClosure callback) override {}
277 
HasBlockedInterception() const278   bool HasBlockedInterception() const override {
279     return has_blocked_interception_;
280   }
281 
HasLegacyTLS() const282   bool HasLegacyTLS() const override { return has_legacy_tls_; }
283 
284   bool captive_portal_checked_;
285   bool os_reports_captive_portal_;
286   bool suggested_url_exists_;
287   bool suggested_url_checked_;
288   bool ssl_interstitial_shown_;
289   bool bad_clock_interstitial_shown_;
290   bool captive_portal_interstitial_shown_;
291   bool mitm_software_interstitial_shown_;
292   bool blocked_interception_interstitial_shown_;
293   bool redirected_to_suggested_url_;
294   bool is_overridable_error_;
295   bool has_blocked_interception_;
296   bool legacy_tls_interstitial_shown_;
297   bool has_legacy_tls_;
298   CommonNameMismatchHandler::CheckUrlCallback suggested_url_callback_;
299 
300   DISALLOW_COPY_AND_ASSIGN(TestSSLErrorHandlerDelegate);
301 };
302 
303 }  // namespace
304 
305 // A class to test name mismatch errors. Creates an error handler with a name
306 // mismatch error.
307 class SSLErrorHandlerNameMismatchTest
308     : public content::RenderViewHostTestHarness {
309  public:
SSLErrorHandlerNameMismatchTest()310   SSLErrorHandlerNameMismatchTest() {}
~SSLErrorHandlerNameMismatchTest()311   ~SSLErrorHandlerNameMismatchTest() override {}
312 
SetUp()313   void SetUp() override {
314     content::RenderViewHostTestHarness::SetUp();
315     SSLErrorHandler::ResetConfigForTesting();
316     SSLErrorHandler::SetInterstitialDelayForTesting(base::TimeDelta());
317     ssl_info_.cert = GetCertificate();
318     ssl_info_.cert_status = net::CERT_STATUS_COMMON_NAME_INVALID;
319     ssl_info_.public_key_hashes.push_back(
320         net::HashValue(kCertPublicKeyHashValue));
321 
322 #if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION)
323     pref_service_.registry()->RegisterBooleanPref(
324         embedder_support::kAlternateErrorPagesEnabled, true);
325     captive_portal_service_ =
326         std::make_unique<captive_portal::CaptivePortalService>(
327             web_contents()->GetBrowserContext(), &pref_service_);
328 #endif
329 
330     delegate_ = new TestSSLErrorHandlerDelegate(web_contents(), ssl_info_);
331     error_handler_.reset(new TestSSLErrorHandler(
332         std::unique_ptr<SSLErrorHandler::Delegate>(delegate_), web_contents(),
333         net::MapCertStatusToNetError(ssl_info_.cert_status), ssl_info_,
334         /*network_time_tracker=*/nullptr, GURL() /*request_url*/,
335         captive_portal_service_.get()));
336   }
337 
TearDown()338   void TearDown() override {
339     EXPECT_FALSE(error_handler()->IsTimerRunningForTesting());
340     captive_portal_service_.reset();
341     error_handler_.reset(nullptr);
342     SSLErrorHandler::ResetConfigForTesting();
343     content::RenderViewHostTestHarness::TearDown();
344   }
345 
error_handler()346   TestSSLErrorHandler* error_handler() { return error_handler_.get(); }
delegate()347   TestSSLErrorHandlerDelegate* delegate() { return delegate_; }
348 
ssl_info()349   const net::SSLInfo& ssl_info() { return ssl_info_; }
350 
351  private:
352   // Returns a certificate for the test. Virtual to allow derived fixtures to
353   // use a certificate with different characteristics.
GetCertificate()354   virtual scoped_refptr<net::X509Certificate> GetCertificate() {
355     return net::ImportCertFromFile(net::GetTestCertsDirectory(),
356                                    "subjectAltName_www_example_com.pem");
357   }
358 
359   net::SSLInfo ssl_info_;
360   TestingPrefServiceSimple pref_service_;
361   std::unique_ptr<captive_portal::CaptivePortalService> captive_portal_service_;
362   std::unique_ptr<TestSSLErrorHandler> error_handler_;
363   TestSSLErrorHandlerDelegate* delegate_;
364 
365   DISALLOW_COPY_AND_ASSIGN(SSLErrorHandlerNameMismatchTest);
366 };
367 
368 // A class to test name mismatch errors, where the certificate lacks a
369 // SubjectAltName. Creates an error handler with a name mismatch error.
370 class SSLErrorHandlerNameMismatchNoSANTest
371     : public SSLErrorHandlerNameMismatchTest {
372  public:
SSLErrorHandlerNameMismatchNoSANTest()373   SSLErrorHandlerNameMismatchNoSANTest() {}
374 
375  private:
376   // Return a certificate that contains no SubjectAltName field.
GetCertificate()377   scoped_refptr<net::X509Certificate> GetCertificate() override {
378     return net::ImportCertFromFile(net::GetTestCertsDirectory(), "ok_cert.pem");
379   }
380 
381   DISALLOW_COPY_AND_ASSIGN(SSLErrorHandlerNameMismatchNoSANTest);
382 };
383 
384 // A class to test the captive portal certificate list feature. Creates an error
385 // handler with a name mismatch error by default. The error handler can be
386 // recreated by calling ResetErrorHandler() with an appropriate cert status.
387 class SSLErrorAssistantProtoTest : public content::RenderViewHostTestHarness {
388  public:
SetUp()389   void SetUp() override {
390     content::RenderViewHostTestHarness::SetUp();
391 
392     pref_service_.registry()->RegisterBooleanPref(
393         embedder_support::kAlternateErrorPagesEnabled, true);
394 
395     SSLErrorHandler::ResetConfigForTesting();
396     SSLErrorHandler::SetErrorAssistantProto(
397         SSLErrorAssistant::GetErrorAssistantProtoFromResourceBundle());
398 
399     SSLErrorHandler::SetInterstitialDelayForTesting(base::TimeDelta());
400     ResetErrorHandlerFromFile(kOkayCertName,
401                               net::CERT_STATUS_COMMON_NAME_INVALID);
402   }
403 
TearDown()404   void TearDown() override {
405     EXPECT_FALSE(error_handler()->IsTimerRunningForTesting());
406     captive_portal_service_.reset();
407     error_handler_.reset(nullptr);
408     SSLErrorHandler::ResetConfigForTesting();
409     content::RenderViewHostTestHarness::TearDown();
410   }
411 
error_handler()412   TestSSLErrorHandler* error_handler() { return error_handler_.get(); }
delegate()413   TestSSLErrorHandlerDelegate* delegate() { return delegate_; }
414 
ssl_info()415   const net::SSLInfo& ssl_info() { return ssl_info_; }
416 
417  protected:
SSLErrorAssistantProtoTest()418   SSLErrorAssistantProtoTest() {}
~SSLErrorAssistantProtoTest()419   ~SSLErrorAssistantProtoTest() override {}
420 
SetCaptivePortalFeatureEnabled(bool enabled)421   void SetCaptivePortalFeatureEnabled(bool enabled) {
422     if (enabled)
423       scoped_feature_list_.InitAndEnableFeature(kCaptivePortalCertificateList);
424     else
425       scoped_feature_list_.InitAndDisableFeature(kCaptivePortalCertificateList);
426   }
427 
SetMITMSoftwareFeatureEnabled(bool enabled)428   void SetMITMSoftwareFeatureEnabled(bool enabled) {
429     if (enabled)
430       scoped_feature_list_.InitAndEnableFeature(kMITMSoftwareInterstitial);
431     else
432       scoped_feature_list_.InitAndDisableFeature(kMITMSoftwareInterstitial);
433   }
434 
ResetErrorHandlerFromString(const std::string & cert_data,net::CertStatus cert_status)435   void ResetErrorHandlerFromString(const std::string& cert_data,
436                                    net::CertStatus cert_status) {
437     net::CertificateList certs =
438         net::X509Certificate::CreateCertificateListFromBytes(
439             cert_data.data(), cert_data.size(),
440             net::X509Certificate::FORMAT_AUTO);
441     ASSERT_FALSE(certs.empty());
442     ResetErrorHandler(certs[0], cert_status);
443   }
444 
ResetErrorHandlerFromFile(const std::string & cert_name,net::CertStatus cert_status)445   void ResetErrorHandlerFromFile(const std::string& cert_name,
446                                  net::CertStatus cert_status) {
447     ResetErrorHandler(
448         net::ImportCertFromFile(net::GetTestCertsDirectory(), cert_name),
449         cert_status);
450   }
451 
452   // Set up an error assistant proto with mock captive portal hash data and
453   // begin handling the certificate error.
RunCaptivePortalTest()454   void RunCaptivePortalTest() {
455     EXPECT_FALSE(error_handler()->IsTimerRunningForTesting());
456     EXPECT_EQ(1u, ssl_info().public_key_hashes.size());
457 
458     auto config_proto =
459         std::make_unique<chrome_browser_ssl::SSLErrorAssistantConfig>();
460     config_proto->set_version_id(kLargeVersionId);
461 
462     config_proto->add_captive_portal_cert()->set_sha256_hash(
463         "sha256/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
464     config_proto->add_captive_portal_cert()->set_sha256_hash(
465         ssl_info().public_key_hashes[0].ToString());
466     config_proto->add_captive_portal_cert()->set_sha256_hash(
467         "sha256/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
468     SSLErrorHandler::SetErrorAssistantProto(std::move(config_proto));
469 
470     error_handler()->StartHandlingError();
471   }
472 
TestNoCaptivePortalInterstitial()473   void TestNoCaptivePortalInterstitial() {
474     base::HistogramTester histograms;
475 
476     RunCaptivePortalTest();
477 
478 #if !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMECAST)
479     // On platforms where captive portal detection is enabled, timer should
480     // start for captive portal detection.
481     EXPECT_TRUE(error_handler()->IsTimerRunningForTesting());
482     EXPECT_TRUE(delegate()->captive_portal_checked());
483     EXPECT_FALSE(delegate()->ssl_interstitial_shown());
484     EXPECT_FALSE(delegate()->captive_portal_interstitial_shown());
485     EXPECT_FALSE(delegate()->suggested_url_checked());
486 
487     base::RunLoop().RunUntilIdle();
488 
489     EXPECT_FALSE(error_handler()->IsTimerRunningForTesting());
490 
491     // Captive portal should be checked on non-Android platforms.
492     EXPECT_TRUE(delegate()->captive_portal_checked());
493     EXPECT_TRUE(delegate()->ssl_interstitial_shown());
494     EXPECT_FALSE(delegate()->captive_portal_interstitial_shown());
495     EXPECT_FALSE(delegate()->suggested_url_checked());
496 #else
497     // On Android and Chromecast there is no custom captive portal detection
498     // logic, so the timer should not start and an SSL interstitial should be
499     // shown immediately.
500     EXPECT_FALSE(error_handler()->IsTimerRunningForTesting());
501     EXPECT_FALSE(delegate()->captive_portal_checked());
502     EXPECT_TRUE(delegate()->ssl_interstitial_shown());
503     EXPECT_FALSE(delegate()->captive_portal_interstitial_shown());
504     EXPECT_FALSE(delegate()->suggested_url_checked());
505 
506     base::RunLoop().RunUntilIdle();
507 
508     EXPECT_FALSE(error_handler()->IsTimerRunningForTesting());
509     EXPECT_FALSE(delegate()->captive_portal_checked());
510     EXPECT_TRUE(delegate()->ssl_interstitial_shown());
511     EXPECT_FALSE(delegate()->captive_portal_interstitial_shown());
512     EXPECT_FALSE(delegate()->suggested_url_checked());
513 #endif
514 
515     // Check that the histogram for the captive portal cert was recorded.
516     histograms.ExpectTotalCount(SSLErrorHandler::GetHistogramNameForTesting(),
517                                 2);
518     histograms.ExpectBucketCount(SSLErrorHandler::GetHistogramNameForTesting(),
519                                  SSLErrorHandler::HANDLE_ALL, 1);
520     histograms.ExpectBucketCount(
521         SSLErrorHandler::GetHistogramNameForTesting(),
522         SSLErrorHandler::SHOW_SSL_INTERSTITIAL_OVERRIDABLE, 1);
523   }
524 
525   // Set up a mock SSL Error Assistant config with regexes that match the
526   // outdated antivirus and misconfigured firewall certificate.
InitMITMSoftwareList()527   void InitMITMSoftwareList() {
528     auto config_proto =
529         std::make_unique<chrome_browser_ssl::SSLErrorAssistantConfig>();
530     config_proto->set_version_id(kLargeVersionId);
531 
532     chrome_browser_ssl::MITMSoftware* filter =
533         config_proto->add_mitm_software();
534     filter->set_name("Misconfigured Firewall");
535     filter->set_issuer_common_name_regex("Misconfigured Firewall_[A-Z0-9]+");
536     filter->set_issuer_organization_regex("Misconfigured Firewall");
537 
538     SSLErrorHandler::SetErrorAssistantProto(std::move(config_proto));
539   }
540 
TestMITMSoftwareInterstitial()541   void TestMITMSoftwareInterstitial() {
542     base::HistogramTester histograms;
543 
544     delegate()->set_non_overridable_error();
545     error_handler()->StartHandlingError();
546     base::RunLoop().RunUntilIdle();
547 
548     EXPECT_FALSE(delegate()->ssl_interstitial_shown());
549     EXPECT_TRUE(delegate()->mitm_software_interstitial_shown());
550     EXPECT_FALSE(delegate()->suggested_url_checked());
551 
552     histograms.ExpectTotalCount(SSLErrorHandler::GetHistogramNameForTesting(),
553                                 2);
554     histograms.ExpectBucketCount(SSLErrorHandler::GetHistogramNameForTesting(),
555                                  SSLErrorHandler::HANDLE_ALL, 1);
556     histograms.ExpectBucketCount(
557         SSLErrorHandler::GetHistogramNameForTesting(),
558         SSLErrorHandler::SHOW_SSL_INTERSTITIAL_NONOVERRIDABLE, 0);
559     histograms.ExpectBucketCount(
560         SSLErrorHandler::GetHistogramNameForTesting(),
561         SSLErrorHandler::SHOW_SSL_INTERSTITIAL_OVERRIDABLE, 0);
562     histograms.ExpectBucketCount(
563         SSLErrorHandler::GetHistogramNameForTesting(),
564         SSLErrorHandler::SHOW_MITM_SOFTWARE_INTERSTITIAL, 1);
565   }
566 
TestNoMITMSoftwareInterstitial()567   void TestNoMITMSoftwareInterstitial() {
568     base::HistogramTester histograms;
569 
570     delegate()->set_non_overridable_error();
571     error_handler()->StartHandlingError();
572     base::RunLoop().RunUntilIdle();
573 
574     EXPECT_FALSE(error_handler()->IsTimerRunningForTesting());
575     EXPECT_TRUE(delegate()->ssl_interstitial_shown());
576     EXPECT_FALSE(delegate()->mitm_software_interstitial_shown());
577     EXPECT_FALSE(delegate()->suggested_url_checked());
578 
579     histograms.ExpectTotalCount(SSLErrorHandler::GetHistogramNameForTesting(),
580                                 2);
581     histograms.ExpectBucketCount(SSLErrorHandler::GetHistogramNameForTesting(),
582                                  SSLErrorHandler::HANDLE_ALL, 1);
583     histograms.ExpectBucketCount(
584         SSLErrorHandler::GetHistogramNameForTesting(),
585         SSLErrorHandler::SHOW_SSL_INTERSTITIAL_NONOVERRIDABLE, 1);
586     histograms.ExpectBucketCount(
587         SSLErrorHandler::GetHistogramNameForTesting(),
588         SSLErrorHandler::SHOW_MITM_SOFTWARE_INTERSTITIAL, 0);
589   }
590 
591  private:
ResetErrorHandler(scoped_refptr<net::X509Certificate> cert,net::CertStatus cert_status)592   void ResetErrorHandler(scoped_refptr<net::X509Certificate> cert,
593                          net::CertStatus cert_status) {
594     ssl_info_.Reset();
595     ssl_info_.cert = cert;
596     ssl_info_.cert_status = cert_status;
597     ssl_info_.public_key_hashes.push_back(
598         net::HashValue(kCertPublicKeyHashValue));
599 
600 #if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION)
601     captive_portal_service_ =
602         std::make_unique<captive_portal::CaptivePortalService>(
603             web_contents()->GetBrowserContext(), &pref_service_);
604 #endif
605 
606     delegate_ = new TestSSLErrorHandlerDelegate(web_contents(), ssl_info_);
607     error_handler_.reset(new TestSSLErrorHandler(
608         std::unique_ptr<SSLErrorHandler::Delegate>(delegate_), web_contents(),
609         net::MapCertStatusToNetError(ssl_info_.cert_status), ssl_info_,
610         /*network_time_tracker=*/nullptr, GURL() /*request_url*/,
611         captive_portal_service_.get()));
612   }
613 
614   net::SSLInfo ssl_info_;
615   TestingPrefServiceSimple pref_service_;
616   std::unique_ptr<captive_portal::CaptivePortalService> captive_portal_service_;
617   std::unique_ptr<TestSSLErrorHandler> error_handler_;
618   TestSSLErrorHandlerDelegate* delegate_;
619   base::test::ScopedFeatureList scoped_feature_list_;
620 
621   DISALLOW_COPY_AND_ASSIGN(SSLErrorAssistantProtoTest);
622 };
623 
624 class SSLErrorHandlerDateInvalidTest
625     : public content::RenderViewHostTestHarness {
626  public:
SSLErrorHandlerDateInvalidTest()627   SSLErrorHandlerDateInvalidTest()
628       : content::RenderViewHostTestHarness(
629             content::BrowserTaskEnvironment::REAL_IO_THREAD),
630         field_trial_test_(new network_time::FieldTrialTest()),
631         clock_(new base::SimpleTestClock),
632         tick_clock_(new base::SimpleTestTickClock),
633         test_server_(new net::EmbeddedTestServer) {
634     network_time::NetworkTimeTracker::RegisterPrefs(pref_service_.registry());
635 
636     field_trial_test()->SetNetworkQueriesWithVariationsService(
637         false, 0.0,
638         network_time::NetworkTimeTracker::FETCHES_IN_BACKGROUND_ONLY);
639   }
640 
SetUp()641   void SetUp() override {
642     content::RenderViewHostTestHarness::SetUp();
643     SSLErrorHandler::ResetConfigForTesting();
644 
645     base::RunLoop run_loop;
646     std::unique_ptr<network::PendingSharedURLLoaderFactory>
647         pending_url_loader_factory;
648     base::PostTaskAndReply(
649         FROM_HERE, {content::BrowserThread::IO},
650         base::BindOnce(CreateURLLoaderFactory, &pending_url_loader_factory),
651         run_loop.QuitClosure());
652     run_loop.Run();
653 
654     shared_url_loader_factory_ = network::SharedURLLoaderFactory::Create(
655         std::move(pending_url_loader_factory));
656 
657     tracker_.reset(new network_time::NetworkTimeTracker(
658         std::unique_ptr<base::Clock>(clock_),
659         std::unique_ptr<base::TickClock>(tick_clock_), &pref_service_,
660         shared_url_loader_factory_));
661     // Do this to be sure that |is_null| returns false.
662     clock_->Advance(base::TimeDelta::FromDays(111));
663     tick_clock_->Advance(base::TimeDelta::FromDays(222));
664 
665     SSLErrorHandler::SetInterstitialDelayForTesting(base::TimeDelta());
666     ssl_info_.cert =
667         net::ImportCertFromFile(net::GetTestCertsDirectory(), "ok_cert.pem");
668     ssl_info_.cert_status = net::CERT_STATUS_DATE_INVALID;
669 
670     delegate_ = new TestSSLErrorHandlerDelegate(web_contents(), ssl_info_);
671     error_handler_.reset(new TestSSLErrorHandler(
672         std::unique_ptr<SSLErrorHandler::Delegate>(delegate_), web_contents(),
673         net::MapCertStatusToNetError(ssl_info_.cert_status), ssl_info_,
674         tracker_.get(), GURL() /*request_url*/,
675         /*captive_portal_service=*/nullptr));
676 
677     // Fix flakiness in case system time is off and triggers a bad clock
678     // interstitial. https://crbug.com/666821#c50
679     ssl_errors::SetBuildTimeForTesting(base::Time::Now());
680   }
681 
TearDown()682   void TearDown() override {
683     // Release the reference on TestSharedURLLoaderFactory before the test
684     // thread bundle flushes the IO thread so that it's destructed.
685     shared_url_loader_factory_ = nullptr;
686 
687     if (error_handler()) {
688       EXPECT_FALSE(error_handler()->IsTimerRunningForTesting());
689       error_handler_.reset(nullptr);
690     }
691     SSLErrorHandler::ResetConfigForTesting();
692 
693     // content::RenderViewHostTestHarness::TearDown() simulates shutdown and as
694     // such destroys parts of the task environment required in these
695     // destructors.
696     test_server_.reset();
697     tracker_.reset();
698 
699     content::RenderViewHostTestHarness::TearDown();
700   }
701 
error_handler()702   TestSSLErrorHandler* error_handler() { return error_handler_.get(); }
delegate()703   TestSSLErrorHandlerDelegate* delegate() { return delegate_; }
704 
field_trial_test()705   network_time::FieldTrialTest* field_trial_test() {
706     return field_trial_test_.get();
707   }
708 
tracker()709   network_time::NetworkTimeTracker* tracker() { return tracker_.get(); }
710 
test_server()711   net::EmbeddedTestServer* test_server() { return test_server_.get(); }
712 
ClearErrorHandler()713   void ClearErrorHandler() { error_handler_.reset(nullptr); }
714 
715  private:
CreateURLLoaderFactory(std::unique_ptr<network::PendingSharedURLLoaderFactory> * pending_url_loader_factory)716   static void CreateURLLoaderFactory(
717       std::unique_ptr<network::PendingSharedURLLoaderFactory>*
718           pending_url_loader_factory) {
719     scoped_refptr<network::TestSharedURLLoaderFactory> factory =
720         base::MakeRefCounted<network::TestSharedURLLoaderFactory>();
721     // Holds a reference to |factory|.
722     *pending_url_loader_factory = factory->Clone();
723   }
724 
725   net::SSLInfo ssl_info_;
726   std::unique_ptr<TestSSLErrorHandler> error_handler_;
727   TestSSLErrorHandlerDelegate* delegate_;
728 
729   std::unique_ptr<network_time::FieldTrialTest> field_trial_test_;
730   base::SimpleTestClock* clock_;
731   base::SimpleTestTickClock* tick_clock_;
732   TestingPrefServiceSimple pref_service_;
733   scoped_refptr<network::SharedURLLoaderFactory> shared_url_loader_factory_;
734   std::unique_ptr<network_time::NetworkTimeTracker> tracker_;
735   std::unique_ptr<net::EmbeddedTestServer> test_server_;
736 
737   DISALLOW_COPY_AND_ASSIGN(SSLErrorHandlerDateInvalidTest);
738 };
739 
740 #if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION)
741 
TEST_F(SSLErrorHandlerNameMismatchTest,ShouldShowSSLInterstitialOnTimerExpired)742 TEST_F(SSLErrorHandlerNameMismatchTest,
743        ShouldShowSSLInterstitialOnTimerExpired) {
744   base::HistogramTester histograms;
745   EXPECT_FALSE(error_handler()->IsTimerRunningForTesting());
746   error_handler()->StartHandlingError();
747 
748   EXPECT_TRUE(error_handler()->IsTimerRunningForTesting());
749   EXPECT_TRUE(delegate()->captive_portal_checked());
750   EXPECT_FALSE(delegate()->ssl_interstitial_shown());
751   EXPECT_FALSE(delegate()->captive_portal_interstitial_shown());
752 
753   delegate()->ClearSeenOperations();
754   base::RunLoop().RunUntilIdle();
755 
756   EXPECT_FALSE(error_handler()->IsTimerRunningForTesting());
757   EXPECT_FALSE(delegate()->captive_portal_checked());
758   EXPECT_TRUE(delegate()->ssl_interstitial_shown());
759   EXPECT_FALSE(delegate()->captive_portal_interstitial_shown());
760 
761   histograms.ExpectTotalCount(SSLErrorHandler::GetHistogramNameForTesting(), 2);
762   histograms.ExpectBucketCount(SSLErrorHandler::GetHistogramNameForTesting(),
763                                SSLErrorHandler::HANDLE_ALL, 1);
764   histograms.ExpectBucketCount(
765       SSLErrorHandler::GetHistogramNameForTesting(),
766       SSLErrorHandler::SHOW_SSL_INTERSTITIAL_OVERRIDABLE, 1);
767 }
768 
TEST_F(SSLErrorHandlerNameMismatchTest,ShouldShowCustomInterstitialOnCaptivePortalResult)769 TEST_F(SSLErrorHandlerNameMismatchTest,
770        ShouldShowCustomInterstitialOnCaptivePortalResult) {
771   base::HistogramTester histograms;
772   EXPECT_FALSE(error_handler()->IsTimerRunningForTesting());
773   error_handler()->StartHandlingError();
774 
775   EXPECT_TRUE(error_handler()->IsTimerRunningForTesting());
776   EXPECT_TRUE(delegate()->captive_portal_checked());
777   EXPECT_FALSE(delegate()->ssl_interstitial_shown());
778   EXPECT_FALSE(delegate()->captive_portal_interstitial_shown());
779   // Fake a captive portal result.
780   delegate()->ClearSeenOperations();
781 
782   captive_portal::CaptivePortalService::Results results;
783   results.previous_result = captive_portal::RESULT_INTERNET_CONNECTED;
784   results.result = captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL;
785 
786   error_handler()->Observe(results);
787   base::RunLoop().RunUntilIdle();
788 
789   EXPECT_FALSE(error_handler()->IsTimerRunningForTesting());
790   EXPECT_FALSE(delegate()->captive_portal_checked());
791   EXPECT_FALSE(delegate()->ssl_interstitial_shown());
792   EXPECT_TRUE(delegate()->captive_portal_interstitial_shown());
793 
794   histograms.ExpectTotalCount(SSLErrorHandler::GetHistogramNameForTesting(), 2);
795   histograms.ExpectBucketCount(SSLErrorHandler::GetHistogramNameForTesting(),
796                                SSLErrorHandler::HANDLE_ALL, 1);
797   histograms.ExpectBucketCount(
798       SSLErrorHandler::GetHistogramNameForTesting(),
799       SSLErrorHandler::SHOW_CAPTIVE_PORTAL_INTERSTITIAL_OVERRIDABLE, 1);
800 }
801 
TEST_F(SSLErrorHandlerNameMismatchTest,ShouldShowSSLInterstitialOnNoCaptivePortalResult)802 TEST_F(SSLErrorHandlerNameMismatchTest,
803        ShouldShowSSLInterstitialOnNoCaptivePortalResult) {
804   base::HistogramTester histograms;
805   EXPECT_FALSE(error_handler()->IsTimerRunningForTesting());
806   error_handler()->StartHandlingError();
807 
808   EXPECT_TRUE(error_handler()->IsTimerRunningForTesting());
809   EXPECT_TRUE(delegate()->captive_portal_checked());
810   EXPECT_FALSE(delegate()->ssl_interstitial_shown());
811   EXPECT_FALSE(delegate()->captive_portal_interstitial_shown());
812   // Fake a "connected to internet" result for the captive portal check.
813   // This should immediately trigger an SSL interstitial without waiting for
814   // the timer to expire.
815   delegate()->ClearSeenOperations();
816 
817   captive_portal::CaptivePortalService::Results results;
818   results.previous_result = captive_portal::RESULT_INTERNET_CONNECTED;
819   results.result = captive_portal::RESULT_INTERNET_CONNECTED;
820 
821   error_handler()->Observe(results);
822   base::RunLoop().RunUntilIdle();
823 
824   EXPECT_FALSE(error_handler()->IsTimerRunningForTesting());
825   EXPECT_FALSE(delegate()->captive_portal_checked());
826   EXPECT_TRUE(delegate()->ssl_interstitial_shown());
827   EXPECT_FALSE(delegate()->captive_portal_interstitial_shown());
828 
829   histograms.ExpectTotalCount(SSLErrorHandler::GetHistogramNameForTesting(), 2);
830   histograms.ExpectBucketCount(SSLErrorHandler::GetHistogramNameForTesting(),
831                                SSLErrorHandler::HANDLE_ALL, 1);
832   histograms.ExpectBucketCount(
833       SSLErrorHandler::GetHistogramNameForTesting(),
834       SSLErrorHandler::SHOW_SSL_INTERSTITIAL_OVERRIDABLE, 1);
835 }
836 
TEST_F(SSLErrorHandlerNameMismatchTest,ShouldNotCheckSuggestedUrlIfNoSuggestedUrl)837 TEST_F(SSLErrorHandlerNameMismatchTest,
838        ShouldNotCheckSuggestedUrlIfNoSuggestedUrl) {
839   base::HistogramTester histograms;
840   error_handler()->StartHandlingError();
841 
842   EXPECT_TRUE(delegate()->captive_portal_checked());
843   EXPECT_TRUE(error_handler()->IsTimerRunningForTesting());
844   EXPECT_FALSE(delegate()->suggested_url_checked());
845   base::RunLoop().RunUntilIdle();
846 
847   EXPECT_FALSE(error_handler()->IsTimerRunningForTesting());
848   EXPECT_TRUE(delegate()->ssl_interstitial_shown());
849 
850   histograms.ExpectTotalCount(SSLErrorHandler::GetHistogramNameForTesting(), 2);
851   histograms.ExpectBucketCount(SSLErrorHandler::GetHistogramNameForTesting(),
852                                SSLErrorHandler::HANDLE_ALL, 1);
853   histograms.ExpectBucketCount(
854       SSLErrorHandler::GetHistogramNameForTesting(),
855       SSLErrorHandler::SHOW_SSL_INTERSTITIAL_OVERRIDABLE, 1);
856 }
857 
TEST_F(SSLErrorHandlerNameMismatchTest,ShouldNotCheckCaptivePortalIfSuggestedUrlExists)858 TEST_F(SSLErrorHandlerNameMismatchTest,
859        ShouldNotCheckCaptivePortalIfSuggestedUrlExists) {
860   base::HistogramTester histograms;
861   EXPECT_FALSE(error_handler()->IsTimerRunningForTesting());
862   delegate()->set_suggested_url_exists();
863   error_handler()->StartHandlingError();
864 
865   EXPECT_TRUE(error_handler()->IsTimerRunningForTesting());
866   EXPECT_TRUE(delegate()->suggested_url_checked());
867   EXPECT_FALSE(delegate()->captive_portal_checked());
868   base::RunLoop().RunUntilIdle();
869 
870   EXPECT_FALSE(error_handler()->IsTimerRunningForTesting());
871   EXPECT_TRUE(delegate()->ssl_interstitial_shown());
872 
873   // Note that the suggested URL check is never completed, so there is no entry
874   // for WWW_MISMATCH_URL_AVAILABLE or WWW_MISMATCH_URL_NOT_AVAILABLE.
875   histograms.ExpectTotalCount(SSLErrorHandler::GetHistogramNameForTesting(), 3);
876   histograms.ExpectBucketCount(SSLErrorHandler::GetHistogramNameForTesting(),
877                                SSLErrorHandler::HANDLE_ALL, 1);
878   histograms.ExpectBucketCount(SSLErrorHandler::GetHistogramNameForTesting(),
879                                SSLErrorHandler::WWW_MISMATCH_FOUND_IN_SAN, 1);
880   histograms.ExpectBucketCount(
881       SSLErrorHandler::GetHistogramNameForTesting(),
882       SSLErrorHandler::SHOW_SSL_INTERSTITIAL_OVERRIDABLE, 1);
883 }
884 
TEST_F(SSLErrorHandlerNameMismatchTest,ShouldNotHandleNameMismatchOnNonOverridableError)885 TEST_F(SSLErrorHandlerNameMismatchTest,
886        ShouldNotHandleNameMismatchOnNonOverridableError) {
887   base::HistogramTester histograms;
888   delegate()->set_non_overridable_error();
889   delegate()->set_suggested_url_exists();
890   error_handler()->StartHandlingError();
891 
892   EXPECT_FALSE(delegate()->suggested_url_checked());
893   EXPECT_TRUE(delegate()->captive_portal_checked());
894   EXPECT_TRUE(error_handler()->IsTimerRunningForTesting());
895   base::RunLoop().RunUntilIdle();
896 
897   EXPECT_FALSE(error_handler()->IsTimerRunningForTesting());
898   EXPECT_TRUE(delegate()->ssl_interstitial_shown());
899 
900   histograms.ExpectTotalCount(SSLErrorHandler::GetHistogramNameForTesting(), 2);
901   histograms.ExpectBucketCount(SSLErrorHandler::GetHistogramNameForTesting(),
902                                SSLErrorHandler::HANDLE_ALL, 1);
903   histograms.ExpectBucketCount(
904       SSLErrorHandler::GetHistogramNameForTesting(),
905       SSLErrorHandler::SHOW_SSL_INTERSTITIAL_NONOVERRIDABLE, 1);
906 }
907 
908 #else  // #if !BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION)
909 
TEST_F(SSLErrorHandlerNameMismatchTest,ShouldShowSSLInterstitialOnCaptivePortalDetectionDisabled)910 TEST_F(SSLErrorHandlerNameMismatchTest,
911        ShouldShowSSLInterstitialOnCaptivePortalDetectionDisabled) {
912   base::HistogramTester histograms;
913   EXPECT_FALSE(error_handler()->IsTimerRunningForTesting());
914   error_handler()->StartHandlingError();
915   EXPECT_FALSE(error_handler()->IsTimerRunningForTesting());
916   EXPECT_FALSE(delegate()->captive_portal_checked());
917   EXPECT_TRUE(delegate()->ssl_interstitial_shown());
918   EXPECT_FALSE(delegate()->captive_portal_interstitial_shown());
919 
920   histograms.ExpectTotalCount(SSLErrorHandler::GetHistogramNameForTesting(), 2);
921   histograms.ExpectBucketCount(SSLErrorHandler::GetHistogramNameForTesting(),
922                                SSLErrorHandler::HANDLE_ALL, 1);
923   histograms.ExpectBucketCount(
924       SSLErrorHandler::GetHistogramNameForTesting(),
925       SSLErrorHandler::SHOW_SSL_INTERSTITIAL_OVERRIDABLE, 1);
926 }
927 
928 #endif  // BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION)
929 
930 // Test that a captive portal interstitial is shown if the OS reports a portal.
TEST_F(SSLErrorHandlerNameMismatchTest,OSReportsCaptivePortal)931 TEST_F(SSLErrorHandlerNameMismatchTest, OSReportsCaptivePortal) {
932   base::HistogramTester histograms;
933   delegate()->set_os_reports_captive_portal();
934 
935   EXPECT_FALSE(error_handler()->IsTimerRunningForTesting());
936   error_handler()->StartHandlingError();
937   EXPECT_FALSE(error_handler()->IsTimerRunningForTesting());
938   EXPECT_FALSE(delegate()->captive_portal_checked());
939   EXPECT_FALSE(delegate()->ssl_interstitial_shown());
940   EXPECT_TRUE(delegate()->captive_portal_interstitial_shown());
941 
942   histograms.ExpectTotalCount(SSLErrorHandler::GetHistogramNameForTesting(), 3);
943   histograms.ExpectBucketCount(SSLErrorHandler::GetHistogramNameForTesting(),
944                                SSLErrorHandler::HANDLE_ALL, 1);
945   histograms.ExpectBucketCount(
946       SSLErrorHandler::GetHistogramNameForTesting(),
947       SSLErrorHandler::SHOW_CAPTIVE_PORTAL_INTERSTITIAL_OVERRIDABLE, 1);
948   histograms.ExpectBucketCount(SSLErrorHandler::GetHistogramNameForTesting(),
949                                SSLErrorHandler::OS_REPORTS_CAPTIVE_PORTAL, 1);
950 }
951 
952 // Test that a captive portal interstitial isn't shown if the OS reports a
953 // portal but CaptivePortalInterstitial feature is disabled.
TEST_F(SSLErrorHandlerNameMismatchTest,OSReportsCaptivePortal_FeatureDisabled)954 TEST_F(SSLErrorHandlerNameMismatchTest,
955        OSReportsCaptivePortal_FeatureDisabled) {
956   base::test::ScopedFeatureList scoped_feature_list;
957   scoped_feature_list.InitAndDisableFeature(kCaptivePortalInterstitial);
958 
959   base::HistogramTester histograms;
960   delegate()->set_os_reports_captive_portal();
961 
962   EXPECT_FALSE(error_handler()->IsTimerRunningForTesting());
963   error_handler()->StartHandlingError();
964   EXPECT_FALSE(error_handler()->IsTimerRunningForTesting());
965   EXPECT_FALSE(delegate()->captive_portal_checked());
966   EXPECT_TRUE(delegate()->ssl_interstitial_shown());
967   EXPECT_FALSE(delegate()->captive_portal_interstitial_shown());
968 
969   histograms.ExpectTotalCount(SSLErrorHandler::GetHistogramNameForTesting(), 2);
970   histograms.ExpectBucketCount(SSLErrorHandler::GetHistogramNameForTesting(),
971                                SSLErrorHandler::HANDLE_ALL, 1);
972   histograms.ExpectBucketCount(
973       SSLErrorHandler::GetHistogramNameForTesting(),
974       SSLErrorHandler::SHOW_SSL_INTERSTITIAL_OVERRIDABLE, 1);
975   histograms.ExpectBucketCount(SSLErrorHandler::GetHistogramNameForTesting(),
976                                SSLErrorHandler::OS_REPORTS_CAPTIVE_PORTAL, 0);
977 }
978 
TEST_F(SSLErrorHandlerNameMismatchTest,ShouldShowSSLInterstitialOnTimerExpiredWhenSuggestedUrlExists)979 TEST_F(SSLErrorHandlerNameMismatchTest,
980        ShouldShowSSLInterstitialOnTimerExpiredWhenSuggestedUrlExists) {
981   base::HistogramTester histograms;
982   delegate()->set_suggested_url_exists();
983   error_handler()->StartHandlingError();
984 
985   EXPECT_TRUE(error_handler()->IsTimerRunningForTesting());
986   EXPECT_TRUE(delegate()->suggested_url_checked());
987   EXPECT_FALSE(delegate()->ssl_interstitial_shown());
988   EXPECT_FALSE(delegate()->redirected_to_suggested_url());
989 
990   base::RunLoop().RunUntilIdle();
991 
992   EXPECT_FALSE(error_handler()->IsTimerRunningForTesting());
993   EXPECT_TRUE(delegate()->ssl_interstitial_shown());
994   EXPECT_FALSE(delegate()->redirected_to_suggested_url());
995 
996   // Note that the suggested URL check is never completed, so there is no entry
997   // for WWW_MISMATCH_URL_AVAILABLE or WWW_MISMATCH_URL_NOT_AVAILABLE.
998   histograms.ExpectTotalCount(SSLErrorHandler::GetHistogramNameForTesting(), 3);
999   histograms.ExpectBucketCount(SSLErrorHandler::GetHistogramNameForTesting(),
1000                                SSLErrorHandler::HANDLE_ALL, 1);
1001   histograms.ExpectBucketCount(SSLErrorHandler::GetHistogramNameForTesting(),
1002                                SSLErrorHandler::WWW_MISMATCH_FOUND_IN_SAN, 1);
1003   histograms.ExpectBucketCount(
1004       SSLErrorHandler::GetHistogramNameForTesting(),
1005       SSLErrorHandler::SHOW_SSL_INTERSTITIAL_OVERRIDABLE, 1);
1006 }
1007 
TEST_F(SSLErrorHandlerNameMismatchTest,ShouldRedirectOnSuggestedUrlCheckResult)1008 TEST_F(SSLErrorHandlerNameMismatchTest,
1009        ShouldRedirectOnSuggestedUrlCheckResult) {
1010   base::HistogramTester histograms;
1011   delegate()->set_suggested_url_exists();
1012   error_handler()->StartHandlingError();
1013 
1014   EXPECT_TRUE(error_handler()->IsTimerRunningForTesting());
1015   EXPECT_TRUE(delegate()->suggested_url_checked());
1016   EXPECT_FALSE(delegate()->ssl_interstitial_shown());
1017   EXPECT_FALSE(delegate()->redirected_to_suggested_url());
1018   // Fake a valid suggested URL check result.
1019   // The URL returned by |SuggestedUrlCheckResult| can be different from
1020   // |suggested_url|, if there is a redirect.
1021   delegate()->SendSuggestedUrlCheckResult(
1022       CommonNameMismatchHandler::SuggestedUrlCheckResult::
1023           SUGGESTED_URL_AVAILABLE,
1024       GURL("https://random.example.com"));
1025 
1026   EXPECT_FALSE(error_handler()->IsTimerRunningForTesting());
1027   EXPECT_FALSE(delegate()->ssl_interstitial_shown());
1028   EXPECT_TRUE(delegate()->redirected_to_suggested_url());
1029 
1030   histograms.ExpectTotalCount(SSLErrorHandler::GetHistogramNameForTesting(), 3);
1031   histograms.ExpectBucketCount(SSLErrorHandler::GetHistogramNameForTesting(),
1032                                SSLErrorHandler::HANDLE_ALL, 1);
1033   histograms.ExpectBucketCount(SSLErrorHandler::GetHistogramNameForTesting(),
1034                                SSLErrorHandler::WWW_MISMATCH_FOUND_IN_SAN, 1);
1035   histograms.ExpectBucketCount(SSLErrorHandler::GetHistogramNameForTesting(),
1036                                SSLErrorHandler::WWW_MISMATCH_URL_AVAILABLE, 1);
1037 }
1038 
1039 // No suggestions should be requested if certificate lacks a SubjectAltName.
TEST_F(SSLErrorHandlerNameMismatchNoSANTest,SSLCommonNameMismatchHandlingRequiresSubjectAltName)1040 TEST_F(SSLErrorHandlerNameMismatchNoSANTest,
1041        SSLCommonNameMismatchHandlingRequiresSubjectAltName) {
1042   base::HistogramTester histograms;
1043   EXPECT_FALSE(error_handler()->IsTimerRunningForTesting());
1044   delegate()->set_suggested_url_exists();
1045   error_handler()->StartHandlingError();
1046 
1047   EXPECT_FALSE(delegate()->suggested_url_checked());
1048   base::RunLoop().RunUntilIdle();
1049 
1050   EXPECT_TRUE(delegate()->ssl_interstitial_shown());
1051   EXPECT_FALSE(delegate()->redirected_to_suggested_url());
1052 
1053   histograms.ExpectTotalCount(SSLErrorHandler::GetHistogramNameForTesting(), 2);
1054   histograms.ExpectBucketCount(SSLErrorHandler::GetHistogramNameForTesting(),
1055                                SSLErrorHandler::HANDLE_ALL, 1);
1056   histograms.ExpectBucketCount(SSLErrorHandler::GetHistogramNameForTesting(),
1057                                SSLErrorHandler::WWW_MISMATCH_FOUND_IN_SAN, 0);
1058   histograms.ExpectBucketCount(
1059       SSLErrorHandler::GetHistogramNameForTesting(),
1060       SSLErrorHandler::SHOW_SSL_INTERSTITIAL_OVERRIDABLE, 1);
1061 }
1062 
TEST_F(SSLErrorHandlerNameMismatchTest,ShouldShowSSLInterstitialOnInvalidUrlCheckResult)1063 TEST_F(SSLErrorHandlerNameMismatchTest,
1064        ShouldShowSSLInterstitialOnInvalidUrlCheckResult) {
1065   base::HistogramTester histograms;
1066   delegate()->set_suggested_url_exists();
1067   error_handler()->StartHandlingError();
1068 
1069   EXPECT_TRUE(error_handler()->IsTimerRunningForTesting());
1070   EXPECT_TRUE(delegate()->suggested_url_checked());
1071   EXPECT_FALSE(delegate()->ssl_interstitial_shown());
1072   EXPECT_FALSE(delegate()->redirected_to_suggested_url());
1073   // Fake an Invalid Suggested URL Check result.
1074   delegate()->SendSuggestedUrlCheckResult(
1075       CommonNameMismatchHandler::SuggestedUrlCheckResult::
1076           SUGGESTED_URL_NOT_AVAILABLE,
1077       GURL());
1078 
1079   EXPECT_FALSE(error_handler()->IsTimerRunningForTesting());
1080   EXPECT_TRUE(delegate()->ssl_interstitial_shown());
1081   EXPECT_FALSE(delegate()->redirected_to_suggested_url());
1082 
1083   histograms.ExpectTotalCount(SSLErrorHandler::GetHistogramNameForTesting(), 4);
1084   histograms.ExpectBucketCount(SSLErrorHandler::GetHistogramNameForTesting(),
1085                                SSLErrorHandler::HANDLE_ALL, 1);
1086   histograms.ExpectBucketCount(SSLErrorHandler::GetHistogramNameForTesting(),
1087                                SSLErrorHandler::WWW_MISMATCH_FOUND_IN_SAN, 1);
1088   histograms.ExpectBucketCount(SSLErrorHandler::GetHistogramNameForTesting(),
1089                                SSLErrorHandler::WWW_MISMATCH_URL_NOT_AVAILABLE,
1090                                1);
1091   histograms.ExpectBucketCount(
1092       SSLErrorHandler::GetHistogramNameForTesting(),
1093       SSLErrorHandler::SHOW_SSL_INTERSTITIAL_OVERRIDABLE, 1);
1094 }
1095 
1096 // Flakily fails on linux_chromium_tsan_rel_ng. http://crbug.com/989128
1097 #if defined(OS_LINUX) && defined(THREAD_SANITIZER)
1098 #define MAYBE_TimeQueryStarted DISABLED_TimeQueryStarted
1099 #else
1100 #define MAYBE_TimeQueryStarted TimeQueryStarted
1101 #endif
TEST_F(SSLErrorHandlerDateInvalidTest,MAYBE_TimeQueryStarted)1102 TEST_F(SSLErrorHandlerDateInvalidTest, MAYBE_TimeQueryStarted) {
1103   base::HistogramTester histograms;
1104   base::Time network_time;
1105   base::TimeDelta uncertainty;
1106   SSLErrorHandler::SetInterstitialDelayForTesting(
1107       base::TimeDelta::FromHours(1));
1108   EXPECT_EQ(network_time::NetworkTimeTracker::NETWORK_TIME_NO_SYNC_ATTEMPT,
1109             tracker()->GetNetworkTime(&network_time, &uncertainty));
1110 
1111   // Enable network time queries and handle the error. A bad clock interstitial
1112   // should be shown.
1113   test_server()->RegisterRequestHandler(
1114       base::Bind(&network_time::GoodTimeResponseHandler));
1115   EXPECT_TRUE(test_server()->Start());
1116   tracker()->SetTimeServerURLForTesting(test_server()->GetURL("/"));
1117   field_trial_test()->SetNetworkQueriesWithVariationsService(
1118       true, 0.0, network_time::NetworkTimeTracker::FETCHES_ON_DEMAND_ONLY);
1119   error_handler()->StartHandlingError();
1120 
1121   EXPECT_TRUE(error_handler()->IsTimerRunningForTesting());
1122   tracker()->WaitForFetchForTesting(123123123);
1123   base::RunLoop().RunUntilIdle();
1124 
1125   EXPECT_TRUE(delegate()->bad_clock_interstitial_shown());
1126   EXPECT_FALSE(error_handler()->IsTimerRunningForTesting());
1127   // Check that the histogram for the delay was recorded.
1128   histograms.ExpectTotalCount(kCertDateErrorHistogram, 1);
1129 }
1130 
1131 // Tests that an SSL interstitial is shown if the accuracy of the system
1132 // clock can't be determined because network time is unavailable.
1133 
1134 // Flakily fails on linux_chromium_tsan_rel_ng. http://crbug.com/989225
1135 #if defined(OS_LINUX) && defined(THREAD_SANITIZER)
1136 #define MAYBE_NoTimeQueries DISABLED_NoTimeQueries
1137 #else
1138 #define MAYBE_NoTimeQueries NoTimeQueries
1139 #endif
TEST_F(SSLErrorHandlerDateInvalidTest,MAYBE_NoTimeQueries)1140 TEST_F(SSLErrorHandlerDateInvalidTest, MAYBE_NoTimeQueries) {
1141   base::HistogramTester histograms;
1142   base::Time network_time;
1143   base::TimeDelta uncertainty;
1144   EXPECT_EQ(network_time::NetworkTimeTracker::NETWORK_TIME_NO_SYNC_ATTEMPT,
1145             tracker()->GetNetworkTime(&network_time, &uncertainty));
1146 
1147   // Handle the error without enabling time queries. A bad clock interstitial
1148   // should not be shown.
1149   error_handler()->StartHandlingError();
1150 
1151   EXPECT_FALSE(error_handler()->IsTimerRunningForTesting());
1152   EXPECT_FALSE(delegate()->bad_clock_interstitial_shown());
1153   EXPECT_TRUE(delegate()->ssl_interstitial_shown());
1154   // Check that the histogram for the delay was recorded.
1155   histograms.ExpectTotalCount(kCertDateErrorHistogram, 1);
1156 }
1157 
1158 // Tests that an SSL interstitial is shown if determing the accuracy of
1159 // the system clock times out (e.g. because a network time query hangs).
1160 
1161 // Flakily fails on linux_chromium_tsan_rel_ng. http://crbug.com/989289
1162 #if defined(OS_LINUX) && defined(THREAD_SANITIZER)
1163 #define MAYBE_TimeQueryHangs DISABLED_TimeQueryHangs
1164 #else
1165 #define MAYBE_TimeQueryHangs TimeQueryHangs
1166 #endif
TEST_F(SSLErrorHandlerDateInvalidTest,MAYBE_TimeQueryHangs)1167 TEST_F(SSLErrorHandlerDateInvalidTest, MAYBE_TimeQueryHangs) {
1168   base::HistogramTester histograms;
1169   base::Time network_time;
1170   base::TimeDelta uncertainty;
1171   EXPECT_EQ(network_time::NetworkTimeTracker::NETWORK_TIME_NO_SYNC_ATTEMPT,
1172             tracker()->GetNetworkTime(&network_time, &uncertainty));
1173 
1174   // Enable network time queries and handle the error. Because the
1175   // network time cannot be determined before the timer elapses, an SSL
1176   // interstitial should be shown.
1177   base::RunLoop wait_for_time_query_loop;
1178   test_server()->RegisterRequestHandler(
1179       base::Bind(&WaitForRequest, wait_for_time_query_loop.QuitClosure()));
1180   EXPECT_TRUE(test_server()->Start());
1181   tracker()->SetTimeServerURLForTesting(test_server()->GetURL("/"));
1182   field_trial_test()->SetNetworkQueriesWithVariationsService(
1183       true, 0.0, network_time::NetworkTimeTracker::FETCHES_ON_DEMAND_ONLY);
1184   error_handler()->StartHandlingError();
1185   EXPECT_TRUE(error_handler()->IsTimerRunningForTesting());
1186   wait_for_time_query_loop.Run();
1187   base::RunLoop().RunUntilIdle();
1188 
1189   EXPECT_FALSE(delegate()->bad_clock_interstitial_shown());
1190   EXPECT_TRUE(delegate()->ssl_interstitial_shown());
1191   EXPECT_FALSE(error_handler()->IsTimerRunningForTesting());
1192 
1193   // Check that the histogram for the delay was recorded.
1194   histograms.ExpectTotalCount(kCertDateErrorHistogram, 1);
1195 
1196   // Clear the error handler to test that, when the request completes,
1197   // it doesn't try to call a callback on a deleted SSLErrorHandler.
1198   ClearErrorHandler();
1199 
1200   // Shut down the server to cancel the pending request.
1201   ASSERT_TRUE(test_server()->ShutdownAndWaitUntilComplete());
1202 }
1203 
1204 // Tests that a certificate marked as a known captive portal certificate causes
1205 // the captive portal interstitial to be shown.
TEST_F(SSLErrorAssistantProtoTest,CaptivePortal_FeatureEnabled)1206 TEST_F(SSLErrorAssistantProtoTest, CaptivePortal_FeatureEnabled) {
1207   SetCaptivePortalFeatureEnabled(true);
1208 
1209   base::HistogramTester histograms;
1210 
1211   RunCaptivePortalTest();
1212 
1213   // Timer shouldn't start for a known captive portal certificate.
1214   EXPECT_FALSE(error_handler()->IsTimerRunningForTesting());
1215   EXPECT_FALSE(delegate()->captive_portal_checked());
1216   EXPECT_FALSE(delegate()->ssl_interstitial_shown());
1217   EXPECT_TRUE(delegate()->captive_portal_interstitial_shown());
1218   EXPECT_FALSE(delegate()->suggested_url_checked());
1219 
1220   // A buggy SSL error handler might have incorrectly started the timer. Run
1221   // to completion to ensure the timer is expired.
1222   base::RunLoop().RunUntilIdle();
1223 
1224   EXPECT_FALSE(error_handler()->IsTimerRunningForTesting());
1225   EXPECT_FALSE(delegate()->captive_portal_checked());
1226   EXPECT_FALSE(delegate()->ssl_interstitial_shown());
1227   EXPECT_TRUE(delegate()->captive_portal_interstitial_shown());
1228   EXPECT_FALSE(delegate()->suggested_url_checked());
1229 
1230   // Check that the histogram for the captive portal cert was recorded.
1231   histograms.ExpectTotalCount(SSLErrorHandler::GetHistogramNameForTesting(), 3);
1232   histograms.ExpectBucketCount(SSLErrorHandler::GetHistogramNameForTesting(),
1233                                SSLErrorHandler::HANDLE_ALL, 1);
1234   histograms.ExpectBucketCount(
1235       SSLErrorHandler::GetHistogramNameForTesting(),
1236       SSLErrorHandler::SHOW_CAPTIVE_PORTAL_INTERSTITIAL_OVERRIDABLE, 1);
1237   histograms.ExpectBucketCount(SSLErrorHandler::GetHistogramNameForTesting(),
1238                                SSLErrorHandler::CAPTIVE_PORTAL_CERT_FOUND, 1);
1239 }
1240 
1241 // Tests that a certificate marked as a known captive portal certificate does
1242 // not cause the captive portal interstitial to be shown, if the feature is
1243 // disabled.
TEST_F(SSLErrorAssistantProtoTest,CaptivePortal_FeatureDisabled)1244 TEST_F(SSLErrorAssistantProtoTest, CaptivePortal_FeatureDisabled) {
1245   SetCaptivePortalFeatureEnabled(false);
1246 
1247   // Default error for SSLErrorHandlerNameMismatchTest tests is name mismatch.
1248   TestNoCaptivePortalInterstitial();
1249 }
1250 
1251 // Tests that an error other than name mismatch does not cause a captive portal
1252 // interstitial to be shown, even if the certificate is marked as a known
1253 // captive portal certificate.
TEST_F(SSLErrorAssistantProtoTest,CaptivePortal_AuthorityInvalidError_NoInterstitial)1254 TEST_F(SSLErrorAssistantProtoTest,
1255        CaptivePortal_AuthorityInvalidError_NoInterstitial) {
1256   SetCaptivePortalFeatureEnabled(true);
1257 
1258   ResetErrorHandlerFromFile(kOkayCertName, net::CERT_STATUS_AUTHORITY_INVALID);
1259   TestNoCaptivePortalInterstitial();
1260 }
1261 
1262 // Tests that an authority invalid error in addition to name mismatch error does
1263 // not cause a captive portal interstitial to be shown, even if the certificate
1264 // is marked as a known captive portal certificate. The resulting error is
1265 // authority-invalid.
TEST_F(SSLErrorAssistantProtoTest,CaptivePortal_TwoErrors_NoInterstitial)1266 TEST_F(SSLErrorAssistantProtoTest, CaptivePortal_TwoErrors_NoInterstitial) {
1267   SetCaptivePortalFeatureEnabled(true);
1268 
1269   const net::CertStatus cert_status =
1270       net::CERT_STATUS_COMMON_NAME_INVALID | net::CERT_STATUS_AUTHORITY_INVALID;
1271   // Sanity check that AUTHORITY_INVALID is seen as the net error.
1272   ASSERT_EQ(net::ERR_CERT_AUTHORITY_INVALID,
1273             net::MapCertStatusToNetError(cert_status));
1274   ResetErrorHandlerFromFile(kOkayCertName, cert_status);
1275   TestNoCaptivePortalInterstitial();
1276 }
1277 
1278 // Tests that another error in addition to name mismatch error does not cause a
1279 // captive portal interstitial to be shown, even if the certificate is marked as
1280 // a known captive portal certificate. Similar to
1281 // NameMismatchAndAuthorityInvalid, except the resulting error is name mismatch.
TEST_F(SSLErrorAssistantProtoTest,CaptivePortal_TwoErrorsIncludingNameMismatch_NoInterstitial)1282 TEST_F(SSLErrorAssistantProtoTest,
1283        CaptivePortal_TwoErrorsIncludingNameMismatch_NoInterstitial) {
1284   SetCaptivePortalFeatureEnabled(true);
1285 
1286   const net::CertStatus cert_status =
1287       net::CERT_STATUS_COMMON_NAME_INVALID | net::CERT_STATUS_WEAK_KEY;
1288   // Sanity check that COMMON_NAME_INVALID is seen as the net error, since the
1289   // test is designed to verify that SSLErrorHandler notices other errors in the
1290   // CertStatus even when COMMON_NAME_INVALID is the net error.
1291   ASSERT_EQ(net::ERR_CERT_COMMON_NAME_INVALID,
1292             net::MapCertStatusToNetError(cert_status));
1293   ResetErrorHandlerFromFile(kOkayCertName, cert_status);
1294   TestNoCaptivePortalInterstitial();
1295 }
1296 
1297 // Tests that if a certificate matches the issuer common name regex of a MITM
1298 // software entry but not the issuer organization name a MITM software
1299 // interstitial will not be displayed.
TEST_F(SSLErrorAssistantProtoTest,MITMSoftware_CertificateDoesNotMatchOrganizationName_NoInterstitial)1300 TEST_F(SSLErrorAssistantProtoTest,
1301        MITMSoftware_CertificateDoesNotMatchOrganizationName_NoInterstitial) {
1302   SetMITMSoftwareFeatureEnabled(true);
1303 
1304   ResetErrorHandlerFromString(kMisconfiguredFirewallCert,
1305                               net::CERT_STATUS_AUTHORITY_INVALID);
1306 
1307   auto config_proto =
1308       std::make_unique<chrome_browser_ssl::SSLErrorAssistantConfig>();
1309   config_proto->set_version_id(kLargeVersionId);
1310 
1311   chrome_browser_ssl::MITMSoftware* filter = config_proto->add_mitm_software();
1312   filter->set_name("Misconfigured Firewall");
1313   filter->set_issuer_common_name_regex("Misconfigured Firewall_[A-Z0-9]+");
1314   filter->set_issuer_organization_regex("Non-Matching Organization Name");
1315   SSLErrorHandler::SetErrorAssistantProto(std::move(config_proto));
1316   TestNoMITMSoftwareInterstitial();
1317 }
1318 
1319 // Tests that if a certificate matches the issuer organization name regex of a
1320 // MITM software entry but not the issuer common name a MITM software
1321 // interstitial will not be displayed.
TEST_F(SSLErrorAssistantProtoTest,MITMSoftware_CertificateDoesNotMatchCommonName_NoInterstitial)1322 TEST_F(SSLErrorAssistantProtoTest,
1323        MITMSoftware_CertificateDoesNotMatchCommonName_NoInterstitial) {
1324   SetMITMSoftwareFeatureEnabled(true);
1325 
1326   ResetErrorHandlerFromString(kMisconfiguredFirewallCert,
1327                               net::CERT_STATUS_AUTHORITY_INVALID);
1328 
1329   auto config_proto =
1330       std::make_unique<chrome_browser_ssl::SSLErrorAssistantConfig>();
1331   config_proto->set_version_id(kLargeVersionId);
1332 
1333   chrome_browser_ssl::MITMSoftware* filter = config_proto->add_mitm_software();
1334   filter->set_name("Misconfigured Firewall");
1335   filter->set_issuer_common_name_regex("Non-Matching Issuer Common Name");
1336   filter->set_issuer_organization_regex("Misconfigured Firewall");
1337   SSLErrorHandler::SetErrorAssistantProto(std::move(config_proto));
1338   TestNoMITMSoftwareInterstitial();
1339 }
1340 
1341 // Tests that a certificate with no organization name or common name will not
1342 // trigger a MITM software interstitial.
TEST_F(SSLErrorAssistantProtoTest,MITMSoftware_CertificateWithNoOrganizationOrCommonName_NoInterstitial)1343 TEST_F(SSLErrorAssistantProtoTest,
1344        MITMSoftware_CertificateWithNoOrganizationOrCommonName_NoInterstitial) {
1345   SetMITMSoftwareFeatureEnabled(true);
1346 
1347   ResetErrorHandlerFromString(kCertWithoutOrganizationOrCommonName,
1348                               net::CERT_STATUS_AUTHORITY_INVALID);
1349   InitMITMSoftwareList();
1350   TestNoMITMSoftwareInterstitial();
1351 }
1352 
1353 // Tests that when everything else is in order, a matching MITM software
1354 // certificate will trigger the MITM software interstitial.
TEST_F(SSLErrorAssistantProtoTest,MITMSoftware_CertificateMatchesCommonNameAndOrganizationName)1355 TEST_F(SSLErrorAssistantProtoTest,
1356        MITMSoftware_CertificateMatchesCommonNameAndOrganizationName) {
1357   SetMITMSoftwareFeatureEnabled(true);
1358 
1359   ResetErrorHandlerFromString(kMisconfiguredFirewallCert,
1360                               net::CERT_STATUS_AUTHORITY_INVALID);
1361   InitMITMSoftwareList();
1362   TestMITMSoftwareInterstitial();
1363 }
1364 
1365 // Tests that a known MITM software entry in the SSL error assistant proto that
1366 // has a common name regex but not an organization name regex can still trigger
1367 // a MITM software interstitial.
TEST_F(SSLErrorAssistantProtoTest,MITMSoftware_CertificateMatchesCommonName)1368 TEST_F(SSLErrorAssistantProtoTest, MITMSoftware_CertificateMatchesCommonName) {
1369   SetMITMSoftwareFeatureEnabled(true);
1370   ResetErrorHandlerFromString(kMisconfiguredFirewallCert,
1371                               net::CERT_STATUS_AUTHORITY_INVALID);
1372   // Register a MITM Software entry in the SSL error assistant proto that has a
1373   // common name regex but not an organization name regex.
1374   auto config_proto =
1375       std::make_unique<chrome_browser_ssl::SSLErrorAssistantConfig>();
1376   config_proto->set_version_id(kLargeVersionId);
1377 
1378   chrome_browser_ssl::MITMSoftware* filter = config_proto->add_mitm_software();
1379   filter->set_name("Misconfigured Firewall");
1380   filter->set_issuer_common_name_regex("Misconfigured Firewall_[A-Z0-9]+");
1381   SSLErrorHandler::SetErrorAssistantProto(std::move(config_proto));
1382   TestMITMSoftwareInterstitial();
1383 }
1384 
1385 // Tests that a known MITM software entry in the SSL error assistant proto that
1386 // has an organization name regex but not a common name name regex can still
1387 // trigger a MITM software interstitial.
TEST_F(SSLErrorAssistantProtoTest,MITMSoftware_CertificateMatchesOrganizationName)1388 TEST_F(SSLErrorAssistantProtoTest,
1389        MITMSoftware_CertificateMatchesOrganizationName) {
1390   SetMITMSoftwareFeatureEnabled(true);
1391   ResetErrorHandlerFromString(kMisconfiguredFirewallCert,
1392                               net::CERT_STATUS_AUTHORITY_INVALID);
1393   // Register a MITM Software entry in the SSL error assistant proto that has an
1394   // organization name regex, but not a common name regex.
1395   auto config_proto =
1396       std::make_unique<chrome_browser_ssl::SSLErrorAssistantConfig>();
1397   config_proto->set_version_id(kLargeVersionId);
1398 
1399   chrome_browser_ssl::MITMSoftware* filter = config_proto->add_mitm_software();
1400   filter->set_name("Misconfigured Firewall");
1401   filter->set_issuer_organization_regex("Misconfigured Firewall");
1402   SSLErrorHandler::SetErrorAssistantProto(std::move(config_proto));
1403   TestMITMSoftwareInterstitial();
1404 }
1405 
1406 // Tests that only a full regex match will trigger the MITM software
1407 // interstitial. For example, a common name regex "Match" should not trigger the
1408 // MITM software interstitial on a certificate that's common name is
1409 // "Full Match".
TEST_F(SSLErrorAssistantProtoTest,MITMSoftware_PartialRegexMatch_NoInterstitial)1410 TEST_F(SSLErrorAssistantProtoTest,
1411        MITMSoftware_PartialRegexMatch_NoInterstitial) {
1412   SetMITMSoftwareFeatureEnabled(true);
1413   ResetErrorHandlerFromString(kMisconfiguredFirewallCert,
1414                               net::CERT_STATUS_AUTHORITY_INVALID);
1415   // Register a MITM software entry with common name and organization name
1416   // regexes that will match part of each the certificate's common name and
1417   // organization name fields but not the entire field.
1418   auto config_proto =
1419       std::make_unique<chrome_browser_ssl::SSLErrorAssistantConfig>();
1420   config_proto->set_version_id(kLargeVersionId);
1421 
1422   chrome_browser_ssl::MITMSoftware* filter = config_proto->add_mitm_software();
1423   filter->set_name("Misconfigured Firewall");
1424   filter->set_issuer_common_name_regex("Misconfigured");
1425   filter->set_issuer_organization_regex("Misconfigured");
1426   SSLErrorHandler::SetErrorAssistantProto(std::move(config_proto));
1427   TestNoMITMSoftwareInterstitial();
1428 }
1429 
1430 // Tests that a MITM software interstitial is not triggered when neither the
1431 // common name or the organization name match.
TEST_F(SSLErrorAssistantProtoTest,MITMSoftware_NonMatchingCertificate_NoInterstitial)1432 TEST_F(SSLErrorAssistantProtoTest,
1433        MITMSoftware_NonMatchingCertificate_NoInterstitial) {
1434   SetMITMSoftwareFeatureEnabled(true);
1435 
1436   ResetErrorHandlerFromFile(kOkayCertName, net::CERT_STATUS_AUTHORITY_INVALID);
1437   InitMITMSoftwareList();
1438   TestNoMITMSoftwareInterstitial();
1439 }
1440 
1441 // Tests that the MITM software interstitial is not triggered when the feature
1442 // is disabled by Finch.
TEST_F(SSLErrorAssistantProtoTest,MITMSoftware_FeatureDisabled)1443 TEST_F(SSLErrorAssistantProtoTest, MITMSoftware_FeatureDisabled) {
1444   SetMITMSoftwareFeatureEnabled(false);
1445 
1446   ResetErrorHandlerFromString(kMisconfiguredFirewallCert,
1447                               net::CERT_STATUS_AUTHORITY_INVALID);
1448   InitMITMSoftwareList();
1449   TestNoMITMSoftwareInterstitial();
1450 }
1451 
1452 // Tests that the MITM software interstitial is not triggered when an error
1453 // other than net::CERT_STATUS_AUTHORITY_INVALID is thrown.
TEST_F(SSLErrorAssistantProtoTest,MITMSoftware_WrongError_NoInterstitial)1454 TEST_F(SSLErrorAssistantProtoTest, MITMSoftware_WrongError_NoInterstitial) {
1455   SetMITMSoftwareFeatureEnabled(true);
1456 
1457   ResetErrorHandlerFromString(kMisconfiguredFirewallCert,
1458                               net::CERT_STATUS_COMMON_NAME_INVALID);
1459   InitMITMSoftwareList();
1460   TestNoMITMSoftwareInterstitial();
1461 }
1462 
1463 // Tests that the MITM software interstitial is not triggered when more than one
1464 // error is thrown.
TEST_F(SSLErrorAssistantProtoTest,MITMSoftware_TwoErrors_NoInterstitial)1465 TEST_F(SSLErrorAssistantProtoTest, MITMSoftware_TwoErrors_NoInterstitial) {
1466   SetMITMSoftwareFeatureEnabled(true);
1467 
1468   ResetErrorHandlerFromString(kMisconfiguredFirewallCert,
1469                               net::CERT_STATUS_AUTHORITY_INVALID |
1470                                   net::CERT_STATUS_COMMON_NAME_INVALID);
1471   InitMITMSoftwareList();
1472   TestNoMITMSoftwareInterstitial();
1473 }
1474 
1475 // Tests that the MITM software interstitial is not triggered if the error
1476 // thrown is overridable.
TEST_F(SSLErrorAssistantProtoTest,MITMSoftware_Overridable_NoInterstitial)1477 TEST_F(SSLErrorAssistantProtoTest, MITMSoftware_Overridable_NoInterstitial) {
1478   base::HistogramTester histograms;
1479 
1480   SetMITMSoftwareFeatureEnabled(true);
1481   ResetErrorHandlerFromString(kMisconfiguredFirewallCert,
1482                               net::CERT_STATUS_AUTHORITY_INVALID);
1483   InitMITMSoftwareList();
1484   error_handler()->StartHandlingError();
1485   base::RunLoop().RunUntilIdle();
1486 
1487   EXPECT_TRUE(delegate()->ssl_interstitial_shown());
1488   EXPECT_FALSE(delegate()->mitm_software_interstitial_shown());
1489   EXPECT_FALSE(delegate()->suggested_url_checked());
1490 
1491   histograms.ExpectTotalCount(SSLErrorHandler::GetHistogramNameForTesting(), 2);
1492   histograms.ExpectBucketCount(SSLErrorHandler::GetHistogramNameForTesting(),
1493                                SSLErrorHandler::HANDLE_ALL, 1);
1494   histograms.ExpectBucketCount(
1495       SSLErrorHandler::GetHistogramNameForTesting(),
1496       SSLErrorHandler::SHOW_SSL_INTERSTITIAL_NONOVERRIDABLE, 0);
1497   histograms.ExpectBucketCount(
1498       SSLErrorHandler::GetHistogramNameForTesting(),
1499       SSLErrorHandler::SHOW_SSL_INTERSTITIAL_OVERRIDABLE, 1);
1500   histograms.ExpectBucketCount(SSLErrorHandler::GetHistogramNameForTesting(),
1501                                SSLErrorHandler::SHOW_MITM_SOFTWARE_INTERSTITIAL,
1502                                0);
1503 }
1504 
TEST_F(SSLErrorAssistantProtoTest,MITMSoftware_IgnoreDynamicUpdateWithSmallVersionId)1505 TEST_F(SSLErrorAssistantProtoTest,
1506        MITMSoftware_IgnoreDynamicUpdateWithSmallVersionId) {
1507   SetMITMSoftwareFeatureEnabled(true);
1508   ResetErrorHandlerFromString(kMisconfiguredFirewallCert,
1509                               net::CERT_STATUS_AUTHORITY_INVALID);
1510 
1511   // Register a MITM Software entry in the SSL error assistant proto that has a
1512   // common name regex but not an organization name regex. This should normally
1513   // trigger a MITM software interstitial, but the version_id is zero which is
1514   // less than the version_id of the local resource bundle, so the dynamic
1515   // update will be ignored.
1516   auto config_proto =
1517       std::make_unique<chrome_browser_ssl::SSLErrorAssistantConfig>();
1518   config_proto->set_version_id(0u);
1519 
1520   chrome_browser_ssl::MITMSoftware* filter = config_proto->add_mitm_software();
1521   filter->set_name("Misconfigured Firewall");
1522   filter->set_issuer_common_name_regex("Misconfigured Firewall_[A-Z0-9]+");
1523   SSLErrorHandler::SetErrorAssistantProto(std::move(config_proto));
1524 
1525   TestNoMITMSoftwareInterstitial();
1526 }
1527 
1528 using SSLErrorHandlerTest = content::RenderViewHostTestHarness;
1529 
1530 // Test that a blocked interception interstitial is shown. It would be nicer to
1531 // set the SSLInfo properly so that the cert is blocked at net level rather than
1532 // because of set_has_blocked_interception(), but that code path is already
1533 // executed in net unit tests and SSL browser tests. This test mainly checks
1534 // histogram accuracy.
TEST_F(SSLErrorHandlerTest,BlockedInterceptionInterstitial)1535 TEST_F(SSLErrorHandlerTest, BlockedInterceptionInterstitial) {
1536   net::SSLInfo ssl_info;
1537   ssl_info.cert =
1538       net::ImportCertFromFile(net::GetTestCertsDirectory(), kOkayCertName);
1539   ssl_info.cert_status = net::CERT_STATUS_COMMON_NAME_INVALID;
1540   ssl_info.public_key_hashes.push_back(net::HashValue(kCertPublicKeyHashValue));
1541 
1542   std::unique_ptr<TestSSLErrorHandlerDelegate> delegate(
1543       new TestSSLErrorHandlerDelegate(web_contents(), ssl_info));
1544 
1545   TestSSLErrorHandlerDelegate* delegate_ptr = delegate.get();
1546   TestSSLErrorHandler error_handler(
1547       std::move(delegate), web_contents(),
1548       net::MapCertStatusToNetError(ssl_info.cert_status), ssl_info,
1549       /*network_time_tracker=*/nullptr, GURL() /*request_url*/,
1550       /*captive_portal_service=*/nullptr);
1551 
1552   base::HistogramTester histograms;
1553   delegate_ptr->set_has_blocked_interception();
1554 
1555   EXPECT_FALSE(error_handler.IsTimerRunningForTesting());
1556   error_handler.StartHandlingError();
1557   EXPECT_FALSE(error_handler.IsTimerRunningForTesting());
1558   EXPECT_FALSE(delegate_ptr->captive_portal_checked());
1559   EXPECT_FALSE(delegate_ptr->ssl_interstitial_shown());
1560   EXPECT_FALSE(delegate_ptr->captive_portal_interstitial_shown());
1561   EXPECT_TRUE(delegate_ptr->blocked_interception_interstitial_shown());
1562 
1563   histograms.ExpectTotalCount(SSLErrorHandler::GetHistogramNameForTesting(), 2);
1564   histograms.ExpectBucketCount(SSLErrorHandler::GetHistogramNameForTesting(),
1565                                SSLErrorHandler::HANDLE_ALL, 1);
1566   histograms.ExpectBucketCount(
1567       SSLErrorHandler::GetHistogramNameForTesting(),
1568       SSLErrorHandler::SHOW_BLOCKED_INTERCEPTION_INTERSTITIAL, 1);
1569 }
1570 
1571 // Tests that a legacy TLS interstitial is shown. This test mainly checks
1572 // histogram accuracy (see BlockedInterceptionInterstitial test above).
TEST_F(SSLErrorHandlerTest,LegacyTLSInterstitial)1573 TEST_F(SSLErrorHandlerTest, LegacyTLSInterstitial) {
1574   net::SSLInfo ssl_info;
1575   ssl_info.cert =
1576       net::ImportCertFromFile(net::GetTestCertsDirectory(), kOkayCertName);
1577   ssl_info.cert_status = net::CERT_STATUS_LEGACY_TLS;
1578   ssl_info.public_key_hashes.push_back(net::HashValue(kCertPublicKeyHashValue));
1579 
1580   std::unique_ptr<TestSSLErrorHandlerDelegate> delegate(
1581       new TestSSLErrorHandlerDelegate(web_contents(), ssl_info));
1582 
1583   TestSSLErrorHandlerDelegate* delegate_ptr = delegate.get();
1584   TestSSLErrorHandler error_handler(
1585       std::move(delegate), web_contents(),
1586       net::MapCertStatusToNetError(ssl_info.cert_status), ssl_info,
1587       /*network_time_tracker=*/nullptr, /*request_url=*/GURL(),
1588       /*captive_portal_service=*/nullptr);
1589 
1590   base::HistogramTester histograms;
1591   delegate_ptr->set_has_legacy_tls();
1592 
1593   EXPECT_FALSE(error_handler.IsTimerRunningForTesting());
1594   error_handler.StartHandlingError();
1595   EXPECT_FALSE(error_handler.IsTimerRunningForTesting());
1596   EXPECT_FALSE(delegate_ptr->captive_portal_checked());
1597   EXPECT_FALSE(delegate_ptr->ssl_interstitial_shown());
1598   EXPECT_FALSE(delegate_ptr->captive_portal_interstitial_shown());
1599   EXPECT_TRUE(delegate_ptr->legacy_tls_interstitial_shown());
1600 
1601   histograms.ExpectTotalCount(SSLErrorHandler::GetHistogramNameForTesting(), 2);
1602   histograms.ExpectBucketCount(SSLErrorHandler::GetHistogramNameForTesting(),
1603                                SSLErrorHandler::HANDLE_ALL, 1);
1604   histograms.ExpectBucketCount(SSLErrorHandler::GetHistogramNameForTesting(),
1605                                SSLErrorHandler::SHOW_LEGACY_TLS_INTERSTITIAL,
1606                                1);
1607 }
1608