1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "components/security_state/core/security_state.h"
6 
7 #include <stdint.h>
8 #include <memory>
9 #include <utility>
10 
11 #include "base/bind.h"
12 #include "base/command_line.h"
13 #include "base/test/metrics/histogram_tester.h"
14 #include "base/test/scoped_feature_list.h"
15 #include "components/security_state/core/features.h"
16 #include "components/security_state/core/insecure_input_event_data.h"
17 #include "components/security_state/core/security_state.h"
18 #include "net/cert/x509_certificate.h"
19 #include "net/ssl/ssl_cipher_suite_names.h"
20 #include "net/ssl/ssl_connection_status_flags.h"
21 #include "net/test/cert_test_util.h"
22 #include "net/test/test_certificate_data.h"
23 #include "net/test/test_data_directory.h"
24 #include "testing/gtest/include/gtest/gtest.h"
25 
26 namespace security_state {
27 
28 namespace {
29 
30 const char kHttpsUrl[] = "https://foo.test/";
31 const char kHttpUrl[] = "http://foo.test/";
32 const char kLocalhostUrl[] = "http://localhost";
33 const char kFileOrigin[] = "file://example_file";
34 const char kWssUrl[] = "wss://foo.test/";
35 const char kFtpUrl[] = "ftp://example.test/";
36 const char kDataUrl[] = "data:text/html,<html>test</html>";
37 
38 // This list doesn't include data: URL, as data: URLs will be explicitly marked
39 // as not secure.
40 const char* const kPseudoUrls[] = {
41     "blob:http://test/some-guid", "filesystem:http://test/some-guid",
42 };
43 
44 class TestSecurityStateHelper {
45  public:
TestSecurityStateHelper()46   TestSecurityStateHelper()
47       : url_(kHttpsUrl),
48         cert_(net::ImportCertFromFile(net::GetTestCertsDirectory(),
49                                       "sha1_2016.pem")),
50         connection_status_(net::SSL_CONNECTION_VERSION_TLS1_2
51                            << net::SSL_CONNECTION_VERSION_SHIFT),
52         cert_status_(net::CERT_STATUS_SHA1_SIGNATURE_PRESENT),
53         displayed_mixed_content_(false),
54         contained_mixed_form_(false),
55         ran_mixed_content_(false),
56         malicious_content_status_(MALICIOUS_CONTENT_STATUS_NONE),
57         is_error_page_(false),
58         is_view_source_(false),
59         has_policy_certificate_(false),
60         safety_tip_info_({security_state::SafetyTipStatus::kUnknown, GURL()}) {}
~TestSecurityStateHelper()61   virtual ~TestSecurityStateHelper() {}
62 
SetCertificate(scoped_refptr<net::X509Certificate> cert)63   void SetCertificate(scoped_refptr<net::X509Certificate> cert) {
64     cert_ = std::move(cert);
65   }
set_connection_status(int connection_status)66   void set_connection_status(int connection_status) {
67     connection_status_ = connection_status;
68   }
SetCipherSuite(uint16_t ciphersuite)69   void SetCipherSuite(uint16_t ciphersuite) {
70     net::SSLConnectionStatusSetCipherSuite(ciphersuite, &connection_status_);
71   }
AddCertStatus(net::CertStatus cert_status)72   void AddCertStatus(net::CertStatus cert_status) {
73     cert_status_ |= cert_status;
74   }
set_cert_status(net::CertStatus cert_status)75   void set_cert_status(net::CertStatus cert_status) {
76     cert_status_ = cert_status;
77   }
set_displayed_mixed_content(bool displayed_mixed_content)78   void set_displayed_mixed_content(bool displayed_mixed_content) {
79     displayed_mixed_content_ = displayed_mixed_content;
80   }
set_contained_mixed_form(bool contained_mixed_form)81   void set_contained_mixed_form(bool contained_mixed_form) {
82     contained_mixed_form_ = contained_mixed_form;
83   }
set_ran_mixed_content(bool ran_mixed_content)84   void set_ran_mixed_content(bool ran_mixed_content) {
85     ran_mixed_content_ = ran_mixed_content;
86   }
set_malicious_content_status(MaliciousContentStatus malicious_content_status)87   void set_malicious_content_status(
88       MaliciousContentStatus malicious_content_status) {
89     malicious_content_status_ = malicious_content_status;
90   }
91 
set_is_error_page(bool is_error_page)92   void set_is_error_page(bool is_error_page) { is_error_page_ = is_error_page; }
93 
set_is_view_source(bool is_view_source)94   void set_is_view_source(bool is_view_source) {
95     is_view_source_ = is_view_source;
96   }
97 
set_insecure_field_edit(bool insecure_field_edit)98   void set_insecure_field_edit(bool insecure_field_edit) {
99     insecure_input_events_.insecure_field_edited = insecure_field_edit;
100   }
set_has_policy_certificate(bool has_policy_cert)101   void set_has_policy_certificate(bool has_policy_cert) {
102     has_policy_certificate_ = has_policy_cert;
103   }
SetUrl(const GURL & url)104   void SetUrl(const GURL& url) { url_ = url; }
105 
set_safety_tip_status(security_state::SafetyTipStatus safety_tip_status)106   void set_safety_tip_status(
107       security_state::SafetyTipStatus safety_tip_status) {
108     safety_tip_info_.status = safety_tip_status;
109   }
110 
GetVisibleSecurityState() const111   std::unique_ptr<VisibleSecurityState> GetVisibleSecurityState() const {
112     auto state = std::make_unique<VisibleSecurityState>();
113     state->connection_info_initialized = true;
114     state->url = url_;
115     state->certificate = cert_;
116     state->cert_status = cert_status_;
117     state->connection_status = connection_status_;
118     state->displayed_mixed_content = displayed_mixed_content_;
119     state->contained_mixed_form = contained_mixed_form_;
120     state->ran_mixed_content = ran_mixed_content_;
121     state->malicious_content_status = malicious_content_status_;
122     state->is_error_page = is_error_page_;
123     state->is_view_source = is_view_source_;
124     state->insecure_input_events = insecure_input_events_;
125     state->safety_tip_info = safety_tip_info_;
126     return state;
127   }
128 
GetSecurityLevel() const129   security_state::SecurityLevel GetSecurityLevel() const {
130     return security_state::GetSecurityLevel(*GetVisibleSecurityState(),
131                                             has_policy_certificate_);
132   }
133 
HasMajorCertificateError() const134   bool HasMajorCertificateError() const {
135     return security_state::HasMajorCertificateError(*GetVisibleSecurityState());
136   }
137 
138  private:
139   GURL url_;
140   scoped_refptr<net::X509Certificate> cert_;
141   int connection_status_;
142   net::CertStatus cert_status_;
143   bool displayed_mixed_content_;
144   bool contained_mixed_form_;
145   bool ran_mixed_content_;
146   MaliciousContentStatus malicious_content_status_;
147   bool is_error_page_;
148   bool is_view_source_;
149   bool has_policy_certificate_;
150   InsecureInputEventData insecure_input_events_;
151   security_state::SafetyTipInfo safety_tip_info_;
152 };
153 
154 }  // namespace
155 
156 // Tests that SHA1-signed certificates, when not allowed by policy, downgrade
157 // the security state of the page to DANGEROUS.
TEST(SecurityStateTest,SHA1Blocked)158 TEST(SecurityStateTest, SHA1Blocked) {
159   TestSecurityStateHelper helper;
160   helper.AddCertStatus(net::CERT_STATUS_WEAK_SIGNATURE_ALGORITHM);
161   helper.AddCertStatus(net::CERT_STATUS_SHA1_SIGNATURE_PRESENT);
162   EXPECT_TRUE(security_state::IsSHA1InChain(*helper.GetVisibleSecurityState()));
163   EXPECT_EQ(DANGEROUS, helper.GetSecurityLevel());
164 
165   // Ensure that policy-installed certificates do not interfere.
166   helper.set_has_policy_certificate(true);
167   EXPECT_TRUE(security_state::IsSHA1InChain(*helper.GetVisibleSecurityState()));
168   EXPECT_EQ(DANGEROUS, helper.GetSecurityLevel());
169 }
170 
171 // Tests that SHA1-signed certificates, when allowed by policy, downgrade the
172 // security state of the page to NONE.
TEST(SecurityStateTest,SHA1Warning)173 TEST(SecurityStateTest, SHA1Warning) {
174   TestSecurityStateHelper helper;
175   EXPECT_TRUE(security_state::IsSHA1InChain(*helper.GetVisibleSecurityState()));
176   EXPECT_EQ(NONE, helper.GetSecurityLevel());
177 
178   // Ensure that policy-installed certificates do not interfere.
179   helper.set_has_policy_certificate(true);
180   EXPECT_TRUE(security_state::IsSHA1InChain(*helper.GetVisibleSecurityState()));
181   EXPECT_EQ(NONE, helper.GetSecurityLevel());
182 }
183 
184 // Tests that SHA1-signed certificates, when allowed by policy, don't interfere
185 // with the handling of mixed content.
TEST(SecurityStateTest,SHA1WarningMixedContent)186 TEST(SecurityStateTest, SHA1WarningMixedContent) {
187   TestSecurityStateHelper helper;
188   helper.set_displayed_mixed_content(true);
189   EXPECT_TRUE(security_state::IsSHA1InChain(*helper.GetVisibleSecurityState()));
190   EXPECT_EQ(NONE, helper.GetSecurityLevel());
191 
192   helper.set_displayed_mixed_content(false);
193   helper.set_ran_mixed_content(true);
194   EXPECT_TRUE(security_state::IsSHA1InChain(*helper.GetVisibleSecurityState()));
195   EXPECT_EQ(DANGEROUS, helper.GetSecurityLevel());
196 }
197 
198 // Tests that SHA1-signed certificates, when allowed by policy,
199 // don't interfere with the handling of major cert errors.
TEST(SecurityStateTest,SHA1WarningBrokenHTTPS)200 TEST(SecurityStateTest, SHA1WarningBrokenHTTPS) {
201   TestSecurityStateHelper helper;
202   helper.AddCertStatus(net::CERT_STATUS_DATE_INVALID);
203   EXPECT_TRUE(security_state::IsSHA1InChain(*helper.GetVisibleSecurityState()));
204   EXPECT_EQ(DANGEROUS, helper.GetSecurityLevel());
205 }
206 
207 // Tests that the malware/phishing status overrides valid HTTPS.
TEST(SecurityStateTest,MalwareOverride)208 TEST(SecurityStateTest, MalwareOverride) {
209   TestSecurityStateHelper helper;
210   // TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 from
211   // http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-4
212   const uint16_t ciphersuite = 0xc02f;
213   helper.set_connection_status(net::SSL_CONNECTION_VERSION_TLS1_2
214                                << net::SSL_CONNECTION_VERSION_SHIFT);
215   helper.SetCipherSuite(ciphersuite);
216 
217   helper.set_malicious_content_status(MALICIOUS_CONTENT_STATUS_MALWARE);
218 
219   EXPECT_EQ(DANGEROUS, helper.GetSecurityLevel());
220 }
221 
222 // Tests that the malware/phishing status is set, even if other connection info
223 // is not available.
TEST(SecurityStateTest,MalwareWithoutConnectionState)224 TEST(SecurityStateTest, MalwareWithoutConnectionState) {
225   TestSecurityStateHelper helper;
226   helper.set_malicious_content_status(
227       MALICIOUS_CONTENT_STATUS_SOCIAL_ENGINEERING);
228   EXPECT_EQ(DANGEROUS, helper.GetSecurityLevel());
229 }
230 
231 // Tests that pseudo URLs always cause an WARNING to be shown.
TEST(SecurityStateTest,AlwaysWarnOnDataUrls)232 TEST(SecurityStateTest, AlwaysWarnOnDataUrls) {
233   TestSecurityStateHelper helper;
234   helper.SetUrl(GURL(kDataUrl));
235   EXPECT_EQ(WARNING, helper.GetSecurityLevel());
236 }
237 
238 // Tests that FTP URLs always cause an WARNING to be shown.
TEST(SecurityStateTest,AlwaysWarnOnFtpUrls)239 TEST(SecurityStateTest, AlwaysWarnOnFtpUrls) {
240   TestSecurityStateHelper helper;
241   helper.SetUrl(GURL(kFtpUrl));
242   EXPECT_EQ(WARNING, helper.GetSecurityLevel());
243 }
244 
245 // Tests that the security level is downgraded to WARNING on
246 // pseudo URLs.
TEST(SecurityStateTest,WarningOnPseudoUrls)247 TEST(SecurityStateTest, WarningOnPseudoUrls) {
248   for (const char* const url : kPseudoUrls) {
249     TestSecurityStateHelper helper;
250     helper.SetUrl(GURL(url));
251     EXPECT_EQ(WARNING, helper.GetSecurityLevel());
252   }
253 }
254 
255 // Tests that if |is_view_source| is set, NONE is returned for a secure site.
TEST(SecurityStateTest,ViewSourceRemovesSecure)256 TEST(SecurityStateTest, ViewSourceRemovesSecure) {
257   TestSecurityStateHelper helper;
258   helper.set_cert_status(0);
259   EXPECT_EQ(SECURE, helper.GetSecurityLevel());
260   helper.set_is_view_source(true);
261   EXPECT_EQ(NONE, helper.GetSecurityLevel());
262 }
263 
264 // Tests that if |is_view_source| is set, DANGEROUS is still returned for a site
265 // flagged by SafeBrowsing.
TEST(SecurityStateTest,ViewSourceKeepsWarning)266 TEST(SecurityStateTest, ViewSourceKeepsWarning) {
267   TestSecurityStateHelper helper;
268   helper.set_malicious_content_status(
269       MALICIOUS_CONTENT_STATUS_SOCIAL_ENGINEERING);
270   helper.set_is_view_source(true);
271   EXPECT_EQ(DANGEROUS, helper.GetSecurityLevel());
272 }
273 
274 // Tests that a mixed form is reflected in the security level.
TEST(SecurityStateTest,MixedForm)275 TEST(SecurityStateTest, MixedForm) {
276   TestSecurityStateHelper helper;
277   helper.set_contained_mixed_form(true);
278 
279   // Verify that a mixed form downgrades the security level.
280   EXPECT_EQ(NONE, helper.GetSecurityLevel());
281 
282   // Ensure that active mixed content trumps the mixed form warning.
283   helper.set_ran_mixed_content(true);
284   EXPECT_EQ(DANGEROUS, helper.GetSecurityLevel());
285 }
286 
287 // Tests that policy-installed-certificates do not interfere with mixed content
288 // notifications.
TEST(SecurityStateTest,MixedContentWithPolicyCertificate)289 TEST(SecurityStateTest, MixedContentWithPolicyCertificate) {
290   TestSecurityStateHelper helper;
291 
292   helper.set_has_policy_certificate(true);
293   helper.set_cert_status(0);
294 
295   // Verify that if no mixed content is present, the policy-installed
296   // certificate is recorded.
297   EXPECT_EQ(SECURE_WITH_POLICY_INSTALLED_CERT, helper.GetSecurityLevel());
298 
299   // Verify that a mixed form downgrades the security level.
300   helper.set_contained_mixed_form(true);
301   EXPECT_EQ(NONE, helper.GetSecurityLevel());
302 
303   // Verify that passive mixed content downgrades the security level.
304   helper.set_contained_mixed_form(false);
305   helper.set_displayed_mixed_content(true);
306   SecurityLevel expected_passive_level =
307       base::FeatureList::IsEnabled(features::kPassiveMixedContentWarning)
308           ? WARNING
309           : NONE;
310   EXPECT_EQ(expected_passive_level, helper.GetSecurityLevel());
311 
312   // Ensure that active mixed content downgrades the security level.
313   helper.set_contained_mixed_form(false);
314   helper.set_displayed_mixed_content(false);
315   helper.set_ran_mixed_content(true);
316   EXPECT_EQ(DANGEROUS, helper.GetSecurityLevel());
317 }
318 
319 // Tests that WARNING is set on normal http pages but DANGEROUS on
320 // form edits with default feature enabled.
TEST(SecurityStateTest,WarningAndDangerousOnFormEditsWhenFeatureEnabled)321 TEST(SecurityStateTest, WarningAndDangerousOnFormEditsWhenFeatureEnabled) {
322   TestSecurityStateHelper helper;
323   helper.SetUrl(GURL(kHttpUrl));
324   base::test::ScopedFeatureList scoped_feature_list;
325   scoped_feature_list.InitAndEnableFeature(
326       security_state::features::kMarkHttpAsFeature);
327 
328   EXPECT_EQ(security_state::WARNING, helper.GetSecurityLevel());
329 
330   helper.set_insecure_field_edit(true);
331   EXPECT_EQ(DANGEROUS, helper.GetSecurityLevel());
332 }
333 
334 // Tests that WARNING is set on normal http pages but DANGEROUS on
335 // form edits with default feature disabled.
TEST(SecurityStateTest,WarningAndDangerousOnFormEditsWhenFeatureDisabled)336 TEST(SecurityStateTest, WarningAndDangerousOnFormEditsWhenFeatureDisabled) {
337   TestSecurityStateHelper helper;
338   helper.SetUrl(GURL(kHttpUrl));
339   base::test::ScopedFeatureList scoped_feature_list;
340   scoped_feature_list.InitAndDisableFeature(
341       security_state::features::kMarkHttpAsFeature);
342 
343   EXPECT_EQ(WARNING, helper.GetSecurityLevel());
344 
345   helper.set_insecure_field_edit(true);
346   EXPECT_EQ(DANGEROUS, helper.GetSecurityLevel());
347 }
348 
349 // Tests that WARNING is set on normal http pages regardless of form edits
350 // when kMarkHttpAsFeature is set to mark non-secure connections with grey
351 // triangle icon.
TEST(SecurityStateTest,AlwaysWarningWhenFeatureMarksWithTriangleWarning)352 TEST(SecurityStateTest, AlwaysWarningWhenFeatureMarksWithTriangleWarning) {
353   TestSecurityStateHelper helper;
354   helper.SetUrl(GURL(kHttpUrl));
355   base::test::ScopedFeatureList scoped_feature_list;
356   scoped_feature_list.InitAndEnableFeatureWithParameters(
357       security_state::features::kMarkHttpAsFeature,
358       {{security_state::features::kMarkHttpAsFeatureParameterName,
359         security_state::features::kMarkHttpAsParameterDangerWarning}});
360 
361   EXPECT_EQ(WARNING, helper.GetSecurityLevel());
362 
363   helper.set_insecure_field_edit(true);
364   EXPECT_EQ(WARNING, helper.GetSecurityLevel());
365 }
366 
367 // Tests that DANGEROUS is set on normal http pages regardless of form edits
368 // when kMarkHttpAsFeature is set to always DANGEROUS
TEST(SecurityStateTest,AlwaysDangerousWhenFeatureMarksAllAsDangerous)369 TEST(SecurityStateTest, AlwaysDangerousWhenFeatureMarksAllAsDangerous) {
370   TestSecurityStateHelper helper;
371   helper.SetUrl(GURL(kHttpUrl));
372   base::test::ScopedFeatureList scoped_feature_list;
373   scoped_feature_list.InitAndEnableFeatureWithParameters(
374       security_state::features::kMarkHttpAsFeature,
375       {{security_state::features::kMarkHttpAsFeatureParameterName,
376         security_state::features::kMarkHttpAsParameterDangerous}});
377 
378   EXPECT_EQ(DANGEROUS, helper.GetSecurityLevel());
379 
380   helper.set_insecure_field_edit(true);
381   EXPECT_EQ(DANGEROUS, helper.GetSecurityLevel());
382 }
383 
384 // Tests that |safety_tip_status| effects security level appropriately.
TEST(SecurityStateTest,SafetyTipSometimesRemovesSecure)385 TEST(SecurityStateTest, SafetyTipSometimesRemovesSecure) {
386   using security_state::SafetyTipStatus;
387 
388   struct SafetyTipCase {
389     SafetyTipStatus safety_tip_status;
390     security_state::SecurityLevel expected_level;
391   };
392 
393   const SafetyTipCase kTestCases[] = {
394       {SafetyTipStatus::kUnknown, SECURE},
395       {SafetyTipStatus::kNone, SECURE},
396       {SafetyTipStatus::kBadReputation, NONE},
397       {SafetyTipStatus::kLookalike, SECURE},
398       {SafetyTipStatus::kBadKeyword, SECURE},
399   };
400 
401   base::test::ScopedFeatureList scoped_feature_list;
402   scoped_feature_list.InitAndEnableFeature(
403       security_state::features::kSafetyTipUI);
404 
405   for (auto testcase : kTestCases) {
406     TestSecurityStateHelper helper;
407     helper.set_cert_status(0);
408     EXPECT_EQ(SECURE, helper.GetSecurityLevel());
409     helper.set_safety_tip_status(testcase.safety_tip_status);
410     EXPECT_EQ(testcase.expected_level, helper.GetSecurityLevel());
411   }
412 }
413 
414 // Tests IsSchemeCryptographic function.
TEST(SecurityStateTest,CryptographicSchemeUrl)415 TEST(SecurityStateTest, CryptographicSchemeUrl) {
416   // HTTPS is a cryptographic scheme.
417   EXPECT_TRUE(IsSchemeCryptographic(GURL(kHttpsUrl)));
418   // WSS is a cryptographic scheme.
419   EXPECT_TRUE(IsSchemeCryptographic(GURL(kWssUrl)));
420   // HTTP is not a cryptographic scheme.
421   EXPECT_FALSE(IsSchemeCryptographic(GURL(kHttpUrl)));
422   // Return true only for valid |url|
423   EXPECT_FALSE(IsSchemeCryptographic(GURL("https://")));
424 }
425 
426 // Tests IsOriginLocalhostOrFile function.
TEST(SecurityStateTest,LocalhostOrFileUrl)427 TEST(SecurityStateTest, LocalhostOrFileUrl) {
428   EXPECT_TRUE(IsOriginLocalhostOrFile(GURL(kLocalhostUrl)));
429   EXPECT_TRUE(IsOriginLocalhostOrFile(GURL(kFileOrigin)));
430   EXPECT_FALSE(IsOriginLocalhostOrFile(GURL(kHttpsUrl)));
431 }
432 
433 // Tests IsSslCertificateValid function.
TEST(SecurityStateTest,SslCertificateValid)434 TEST(SecurityStateTest, SslCertificateValid) {
435   EXPECT_TRUE(IsSslCertificateValid(SecurityLevel::SECURE));
436   EXPECT_TRUE(IsSslCertificateValid(SecurityLevel::EV_SECURE));
437   EXPECT_TRUE(
438       IsSslCertificateValid(SecurityLevel::SECURE_WITH_POLICY_INSTALLED_CERT));
439 
440   EXPECT_FALSE(IsSslCertificateValid(SecurityLevel::NONE));
441   EXPECT_FALSE(IsSslCertificateValid(SecurityLevel::DANGEROUS));
442   EXPECT_FALSE(IsSslCertificateValid(SecurityLevel::WARNING));
443 }
444 
445 // Tests GetLegacyTLSWarningStatus function.
TEST(SecurityStateTest,LegacyTLSWarningStatus)446 TEST(SecurityStateTest, LegacyTLSWarningStatus) {
447   const struct {
448     bool connection_used_legacy_tls;
449     bool should_suppress_legacy_tls_warning;
450     bool expected_legacy_tls_warning_status;
451   } kTestCases[] = {
452       {true, false, true},
453       {true, true, false},
454       {false, false, false},
455       {false, true, false},
456   };
457   for (auto testcase : kTestCases) {
458     auto state = VisibleSecurityState();
459     state.connection_used_legacy_tls = testcase.connection_used_legacy_tls;
460     state.should_suppress_legacy_tls_warning =
461         testcase.should_suppress_legacy_tls_warning;
462     EXPECT_EQ(testcase.expected_legacy_tls_warning_status,
463               GetLegacyTLSWarningStatus(state));
464   }
465 }
466 
467 // Tests that WARNING is not set for error pages.
TEST(SecurityStateTest,ErrorPage)468 TEST(SecurityStateTest, ErrorPage) {
469   TestSecurityStateHelper helper;
470   helper.SetUrl(GURL("http://nonexistent.test"));
471   helper.set_is_error_page(true);
472   EXPECT_EQ(SecurityLevel::NONE, helper.GetSecurityLevel());
473 
474   // Sanity-check that if it's not an error page, the security level is
475   // downgraded.
476   helper.set_is_error_page(false);
477   EXPECT_EQ(SecurityLevel::WARNING, helper.GetSecurityLevel());
478 }
479 
480 // Tests that the billing status is set, and it overrides valid HTTPS.
TEST(SecurityStateTest,BillingOverridesValidHTTPS)481 TEST(SecurityStateTest, BillingOverridesValidHTTPS) {
482   TestSecurityStateHelper helper;
483   // TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 from
484   // http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-4
485   const uint16_t ciphersuite = 0xc02f;
486   helper.set_connection_status(net::SSL_CONNECTION_VERSION_TLS1_2
487                                << net::SSL_CONNECTION_VERSION_SHIFT);
488   helper.SetCipherSuite(ciphersuite);
489 
490   helper.set_malicious_content_status(MALICIOUS_CONTENT_STATUS_BILLING);
491 
492   EXPECT_EQ(DANGEROUS, helper.GetSecurityLevel());
493 }
494 
495 // Tests that the billing status overrides HTTP warnings.
TEST(SecurityStateTest,BillingOverridesHTTPWarning)496 TEST(SecurityStateTest, BillingOverridesHTTPWarning) {
497   TestSecurityStateHelper helper;
498   helper.SetUrl(GURL(kHttpUrl));
499 
500   // Expect to see a warning for HTTP first.
501   EXPECT_EQ(security_state::WARNING, helper.GetSecurityLevel());
502 
503   // Now mark the URL as matching the billing list.
504   helper.set_malicious_content_status(MALICIOUS_CONTENT_STATUS_BILLING);
505   // Expect to see a warning for billing now.
506   EXPECT_EQ(DANGEROUS, helper.GetSecurityLevel());
507 }
508 
509 // Tests that non-cryptographic schemes are handled as having no certificate
510 // errors.
TEST(SecurityStateTest,NonCryptoHasNoCertificateErrors)511 TEST(SecurityStateTest, NonCryptoHasNoCertificateErrors) {
512   TestSecurityStateHelper helper;
513   helper.set_cert_status(net::CERT_STATUS_SHA1_SIGNATURE_PRESENT |
514                          net::CERT_STATUS_REVOKED);
515 
516   helper.SetUrl(GURL(kHttpUrl));
517   EXPECT_FALSE(helper.HasMajorCertificateError());
518 
519   helper.SetUrl(GURL(kFtpUrl));
520   EXPECT_FALSE(helper.HasMajorCertificateError());
521 
522   helper.SetUrl(GURL(kDataUrl));
523   EXPECT_FALSE(helper.HasMajorCertificateError());
524 }
525 
526 // Tests that cryptographic schemes without certificate errors are acceptable.
TEST(SecurityStateTest,CryptoWithNoCertificateErrors)527 TEST(SecurityStateTest, CryptoWithNoCertificateErrors) {
528   TestSecurityStateHelper helper;
529   EXPECT_FALSE(helper.HasMajorCertificateError());
530 
531   helper.set_cert_status(0);
532   EXPECT_FALSE(helper.HasMajorCertificateError());
533 
534   helper.SetCertificate(nullptr);
535   EXPECT_FALSE(helper.HasMajorCertificateError());
536 }
537 
538 // Tests that major certificate errors are detected.
TEST(SecurityStateTest,MajorCertificateErrors)539 TEST(SecurityStateTest, MajorCertificateErrors) {
540   TestSecurityStateHelper helper;
541   helper.set_cert_status(net::CERT_STATUS_SHA1_SIGNATURE_PRESENT |
542                          net::CERT_STATUS_UNABLE_TO_CHECK_REVOCATION);
543   EXPECT_TRUE(helper.HasMajorCertificateError());
544 
545   helper.set_cert_status(net::CERT_STATUS_SHA1_SIGNATURE_PRESENT |
546                          net::CERT_STATUS_NO_REVOCATION_MECHANISM);
547   EXPECT_TRUE(helper.HasMajorCertificateError());
548 
549   helper.set_cert_status(net::CERT_STATUS_SHA1_SIGNATURE_PRESENT |
550                          net::CERT_STATUS_REVOKED);
551   EXPECT_TRUE(helper.HasMajorCertificateError());
552 
553   helper.set_cert_status(net::CERT_STATUS_SHA1_SIGNATURE_PRESENT |
554                          net::CERT_STATUS_WEAK_SIGNATURE_ALGORITHM);
555   EXPECT_TRUE(helper.HasMajorCertificateError());
556 
557   helper.set_cert_status(net::CERT_STATUS_SHA1_SIGNATURE_PRESENT |
558                          net::CERT_STATUS_PINNED_KEY_MISSING);
559   EXPECT_TRUE(helper.HasMajorCertificateError());
560 }
561 
562 }  // namespace security_state
563