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