1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "net/http/transport_security_state.h"
11 #include "base/base64.h"
12 #include "base/files/file_path.h"
13 #include "base/json/json_reader.h"
14 #include "base/rand_util.h"
15 #include "base/sha1.h"
16 #include "base/strings/string_piece.h"
17 #include "base/values.h"
18 #include "crypto/sha2.h"
19 #include "net/base/host_port_pair.h"
20 #include "net/base/net_errors.h"
21 #include "net/base/test_completion_callback.h"
22 #include "net/base/test_data_directory.h"
23 #include "net/cert/asn1_util.h"
24 #include "net/cert/cert_verifier.h"
25 #include "net/cert/cert_verify_result.h"
26 #include "net/cert/test_root_certs.h"
27 #include "net/cert/x509_cert_types.h"
28 #include "net/cert/x509_certificate.h"
29 #include "net/http/http_util.h"
30 #include "net/log/net_log.h"
31 #include "net/ssl/ssl_info.h"
32 #include "net/test/cert_test_util.h"
33 #include "testing/gtest/include/gtest/gtest.h"
35 #if defined(USE_OPENSSL)
36 #include "crypto/openssl_util.h"
38 #include "crypto/nss_util.h"
45 const char kReportUri
[] = "http://example.test/test";
47 // A mock ReportSender that just remembers the latest report
48 // URI and report to be sent.
49 class MockCertificateReportSender
50 : public TransportSecurityState::ReportSender
{
52 MockCertificateReportSender() {}
53 ~MockCertificateReportSender() override
{}
55 void Send(const GURL
& report_uri
, const std::string
& report
) override
{
56 latest_report_uri_
= report_uri
;
57 latest_report_
= report
;
60 const GURL
& latest_report_uri() { return latest_report_uri_
; }
61 const std::string
& latest_report() { return latest_report_
; }
64 GURL latest_report_uri_
;
65 std::string latest_report_
;
68 void CompareCertificateChainWithList(
69 const scoped_refptr
<X509Certificate
>& cert_chain
,
70 const base::ListValue
* cert_list
) {
71 ASSERT_TRUE(cert_chain
);
72 std::vector
<std::string
> pem_encoded_chain
;
73 cert_chain
->GetPEMEncodedChain(&pem_encoded_chain
);
74 EXPECT_EQ(pem_encoded_chain
.size(), cert_list
->GetSize());
76 for (size_t i
= 0; i
< pem_encoded_chain
.size(); i
++) {
77 std::string list_cert
;
78 ASSERT_TRUE(cert_list
->GetString(i
, &list_cert
));
79 EXPECT_EQ(pem_encoded_chain
[i
], list_cert
);
84 const std::string
& report
,
85 const HostPortPair
& host_port_pair
,
86 const base::Time
& expiry
,
87 bool include_subdomains
,
88 const std::string
& noted_hostname
,
89 const scoped_refptr
<X509Certificate
>& served_certificate_chain
,
90 const scoped_refptr
<X509Certificate
>& validated_certificate_chain
,
91 const HashValueVector
& known_pins
) {
92 // TODO(estark): check time in RFC3339 format.
94 scoped_ptr
<base::Value
> value(base::JSONReader::Read(report
));
96 ASSERT_TRUE(value
->IsType(base::Value::TYPE_DICTIONARY
));
98 base::DictionaryValue
* report_dict
;
99 ASSERT_TRUE(value
->GetAsDictionary(&report_dict
));
101 std::string report_hostname
;
102 EXPECT_TRUE(report_dict
->GetString("hostname", &report_hostname
));
103 EXPECT_EQ(host_port_pair
.host(), report_hostname
);
106 EXPECT_TRUE(report_dict
->GetInteger("port", &report_port
));
107 EXPECT_EQ(host_port_pair
.port(), report_port
);
109 bool report_include_subdomains
;
110 EXPECT_TRUE(report_dict
->GetBoolean("include-subdomains",
111 &report_include_subdomains
));
112 EXPECT_EQ(include_subdomains
, report_include_subdomains
);
114 std::string report_noted_hostname
;
115 EXPECT_TRUE(report_dict
->GetString("noted-hostname", &report_noted_hostname
));
116 EXPECT_EQ(noted_hostname
, report_noted_hostname
);
118 base::ListValue
* report_served_certificate_chain
;
119 EXPECT_TRUE(report_dict
->GetList("served-certificate-chain",
120 &report_served_certificate_chain
));
121 ASSERT_NO_FATAL_FAILURE(CompareCertificateChainWithList(
122 served_certificate_chain
, report_served_certificate_chain
));
124 base::ListValue
* report_validated_certificate_chain
;
125 EXPECT_TRUE(report_dict
->GetList("validated-certificate-chain",
126 &report_validated_certificate_chain
));
127 ASSERT_NO_FATAL_FAILURE(CompareCertificateChainWithList(
128 validated_certificate_chain
, report_validated_certificate_chain
));
133 class TransportSecurityStateTest
: public testing::Test
{
135 void SetUp() override
{
136 #if defined(USE_OPENSSL)
137 crypto::EnsureOpenSSLInit();
139 crypto::EnsureNSSInit();
143 static void DisableStaticPins(TransportSecurityState
* state
) {
144 state
->enable_static_pins_
= false;
147 static void EnableStaticPins(TransportSecurityState
* state
) {
148 state
->enable_static_pins_
= true;
151 static HashValueVector
GetSampleSPKIHashes() {
152 HashValueVector spki_hashes
;
153 HashValue
hash(HASH_VALUE_SHA1
);
154 memset(hash
.data(), 0, hash
.size());
155 spki_hashes
.push_back(hash
);
160 bool GetStaticDomainState(TransportSecurityState
* state
,
161 const std::string
& host
,
162 TransportSecurityState::STSState
* sts_result
,
163 TransportSecurityState::PKPState
* pkp_result
) {
164 return state
->GetStaticDomainState(host
, sts_result
, pkp_result
);
168 TEST_F(TransportSecurityStateTest
, DomainNameOddities
) {
169 TransportSecurityState state
;
170 const base::Time
current_time(base::Time::Now());
171 const base::Time expiry
= current_time
+ base::TimeDelta::FromSeconds(1000);
173 // DNS suffix search tests. Some DNS resolvers allow a terminal "." to
174 // indicate not perform DNS suffix searching. Ensure that regardless
175 // of how this is treated at the resolver layer, or at the URL/origin
176 // layer (that is, whether they are treated as equivalent or distinct),
177 // ensure that for policy matching, something lacking a terminal "."
178 // is equivalent to something with a terminal "."
179 EXPECT_FALSE(state
.ShouldUpgradeToSSL("example.com"));
181 state
.AddHSTS("example.com", expiry
, true /* include_subdomains */);
182 EXPECT_TRUE(state
.ShouldUpgradeToSSL("example.com"));
183 // Trailing '.' should be equivalent; it's just a resolver hint
184 EXPECT_TRUE(state
.ShouldUpgradeToSSL("example.com."));
185 // Leading '.' should be invalid
186 EXPECT_FALSE(state
.ShouldUpgradeToSSL(".example.com"));
187 // Subdomains should work regardless
188 EXPECT_TRUE(state
.ShouldUpgradeToSSL("sub.example.com"));
189 EXPECT_TRUE(state
.ShouldUpgradeToSSL("sub.example.com."));
190 // But invalid subdomains should be rejected
191 EXPECT_FALSE(state
.ShouldUpgradeToSSL("sub..example.com"));
192 EXPECT_FALSE(state
.ShouldUpgradeToSSL("sub..example.com."));
194 // Now try the inverse form
195 TransportSecurityState state2
;
196 state2
.AddHSTS("example.net.", expiry
, true /* include_subdomains */);
197 EXPECT_TRUE(state2
.ShouldUpgradeToSSL("example.net."));
198 EXPECT_TRUE(state2
.ShouldUpgradeToSSL("example.net"));
199 EXPECT_TRUE(state2
.ShouldUpgradeToSSL("sub.example.net."));
200 EXPECT_TRUE(state2
.ShouldUpgradeToSSL("sub.example.net"));
202 // Finally, test weird things
203 TransportSecurityState state3
;
204 state3
.AddHSTS("", expiry
, true /* include_subdomains */);
205 EXPECT_FALSE(state3
.ShouldUpgradeToSSL(""));
206 EXPECT_FALSE(state3
.ShouldUpgradeToSSL("."));
207 EXPECT_FALSE(state3
.ShouldUpgradeToSSL("..."));
208 // Make sure it didn't somehow apply HSTS to the world
209 EXPECT_FALSE(state3
.ShouldUpgradeToSSL("example.org"));
211 TransportSecurityState state4
;
212 state4
.AddHSTS(".", expiry
, true /* include_subdomains */);
213 EXPECT_FALSE(state4
.ShouldUpgradeToSSL(""));
214 EXPECT_FALSE(state4
.ShouldUpgradeToSSL("."));
215 EXPECT_FALSE(state4
.ShouldUpgradeToSSL("..."));
216 EXPECT_FALSE(state4
.ShouldUpgradeToSSL("example.org"));
218 // Now do the same for preloaded entries
219 TransportSecurityState state5
;
220 EXPECT_TRUE(state5
.ShouldUpgradeToSSL("accounts.google.com"));
221 EXPECT_TRUE(state5
.ShouldUpgradeToSSL("accounts.google.com."));
222 EXPECT_FALSE(state5
.ShouldUpgradeToSSL("accounts..google.com"));
223 EXPECT_FALSE(state5
.ShouldUpgradeToSSL("accounts..google.com."));
226 TEST_F(TransportSecurityStateTest
, SimpleMatches
) {
227 TransportSecurityState state
;
228 const base::Time
current_time(base::Time::Now());
229 const base::Time expiry
= current_time
+ base::TimeDelta::FromSeconds(1000);
231 EXPECT_FALSE(state
.ShouldUpgradeToSSL("example.com"));
232 bool include_subdomains
= false;
233 state
.AddHSTS("example.com", expiry
, include_subdomains
);
234 EXPECT_TRUE(state
.ShouldUpgradeToSSL("example.com"));
235 EXPECT_TRUE(state
.ShouldSSLErrorsBeFatal("example.com"));
236 EXPECT_FALSE(state
.ShouldUpgradeToSSL("foo.example.com"));
237 EXPECT_FALSE(state
.ShouldSSLErrorsBeFatal("foo.example.com"));
240 TEST_F(TransportSecurityStateTest
, MatchesCase1
) {
241 TransportSecurityState state
;
242 const base::Time
current_time(base::Time::Now());
243 const base::Time expiry
= current_time
+ base::TimeDelta::FromSeconds(1000);
245 EXPECT_FALSE(state
.ShouldUpgradeToSSL("example.com"));
246 bool include_subdomains
= false;
247 state
.AddHSTS("EXample.coM", expiry
, include_subdomains
);
248 EXPECT_TRUE(state
.ShouldUpgradeToSSL("example.com"));
251 TEST_F(TransportSecurityStateTest
, Fuzz
) {
252 TransportSecurityState state
;
253 TransportSecurityState::STSState sts_state
;
254 TransportSecurityState::PKPState pkp_state
;
256 EnableStaticPins(&state
);
258 for (size_t i
= 0; i
< 128; i
++) {
259 std::string hostname
;
262 if (base::RandInt(0, 16) == 7) {
265 if (i
> 0 && base::RandInt(0, 7) == 7) {
266 hostname
.append(1, '.');
268 hostname
.append(1, 'a' + base::RandInt(0, 25));
270 state
.GetStaticDomainState(hostname
, &sts_state
, &pkp_state
);
274 TEST_F(TransportSecurityStateTest
, MatchesCase2
) {
275 TransportSecurityState state
;
276 const base::Time
current_time(base::Time::Now());
277 const base::Time expiry
= current_time
+ base::TimeDelta::FromSeconds(1000);
279 // Check dynamic entries
280 EXPECT_FALSE(state
.ShouldUpgradeToSSL("EXample.coM"));
281 bool include_subdomains
= false;
282 state
.AddHSTS("example.com", expiry
, include_subdomains
);
283 EXPECT_TRUE(state
.ShouldUpgradeToSSL("EXample.coM"));
285 // Check static entries
286 EXPECT_TRUE(state
.ShouldUpgradeToSSL("AccounTs.GooGle.com"));
287 EXPECT_TRUE(state
.ShouldUpgradeToSSL("mail.google.COM"));
290 TEST_F(TransportSecurityStateTest
, SubdomainMatches
) {
291 TransportSecurityState state
;
292 const base::Time
current_time(base::Time::Now());
293 const base::Time expiry
= current_time
+ base::TimeDelta::FromSeconds(1000);
295 EXPECT_FALSE(state
.ShouldUpgradeToSSL("example.test"));
296 bool include_subdomains
= true;
297 state
.AddHSTS("example.test", expiry
, include_subdomains
);
298 EXPECT_TRUE(state
.ShouldUpgradeToSSL("example.test"));
299 EXPECT_TRUE(state
.ShouldUpgradeToSSL("foo.example.test"));
300 EXPECT_TRUE(state
.ShouldUpgradeToSSL("foo.bar.example.test"));
301 EXPECT_TRUE(state
.ShouldUpgradeToSSL("foo.bar.baz.example.test"));
302 EXPECT_FALSE(state
.ShouldUpgradeToSSL("test"));
303 EXPECT_FALSE(state
.ShouldUpgradeToSSL("notexample.test"));
306 // Tests that a more-specific HSTS or HPKP rule overrides a less-specific rule
307 // with it, regardless of the includeSubDomains bit. This is a regression test
308 // for https://crbug.com/469957.
309 TEST_F(TransportSecurityStateTest
, SubdomainCarveout
) {
310 const GURL
report_uri(kReportUri
);
311 TransportSecurityState state
;
312 const base::Time
current_time(base::Time::Now());
313 const base::Time expiry
= current_time
+ base::TimeDelta::FromSeconds(1000);
314 const base::Time older
= current_time
- base::TimeDelta::FromSeconds(1000);
316 state
.AddHSTS("example1.test", expiry
, true);
317 state
.AddHSTS("foo.example1.test", expiry
, false);
319 state
.AddHPKP("example2.test", expiry
, true, GetSampleSPKIHashes(),
321 state
.AddHPKP("foo.example2.test", expiry
, false, GetSampleSPKIHashes(),
324 EXPECT_TRUE(state
.ShouldUpgradeToSSL("example1.test"));
325 EXPECT_TRUE(state
.ShouldUpgradeToSSL("foo.example1.test"));
327 // The foo.example1.test rule overrides the example1.test rule, so
328 // bar.foo.example1.test has no HSTS state.
329 EXPECT_FALSE(state
.ShouldUpgradeToSSL("bar.foo.example1.test"));
330 EXPECT_FALSE(state
.ShouldSSLErrorsBeFatal("bar.foo.example1.test"));
332 EXPECT_TRUE(state
.HasPublicKeyPins("example2.test"));
333 EXPECT_TRUE(state
.HasPublicKeyPins("foo.example2.test"));
335 // The foo.example2.test rule overrides the example1.test rule, so
336 // bar.foo.example2.test has no HPKP state.
337 EXPECT_FALSE(state
.HasPublicKeyPins("bar.foo.example2.test"));
338 EXPECT_FALSE(state
.ShouldSSLErrorsBeFatal("bar.foo.example2.test"));
340 // Expire the foo.example*.test rules.
341 state
.AddHSTS("foo.example1.test", older
, false);
342 state
.AddHPKP("foo.example2.test", older
, false, GetSampleSPKIHashes(),
345 // Now the base example*.test rules apply to bar.foo.example*.test.
346 EXPECT_TRUE(state
.ShouldUpgradeToSSL("bar.foo.example1.test"));
347 EXPECT_TRUE(state
.ShouldSSLErrorsBeFatal("bar.foo.example1.test"));
348 EXPECT_TRUE(state
.HasPublicKeyPins("bar.foo.example2.test"));
349 EXPECT_TRUE(state
.ShouldSSLErrorsBeFatal("bar.foo.example2.test"));
352 TEST_F(TransportSecurityStateTest
, FatalSSLErrors
) {
353 const GURL
report_uri(kReportUri
);
354 TransportSecurityState state
;
355 const base::Time
current_time(base::Time::Now());
356 const base::Time expiry
= current_time
+ base::TimeDelta::FromSeconds(1000);
358 state
.AddHSTS("example1.test", expiry
, false);
359 state
.AddHPKP("example2.test", expiry
, false, GetSampleSPKIHashes(),
362 // The presense of either HSTS or HPKP is enough to make SSL errors fatal.
363 EXPECT_TRUE(state
.ShouldSSLErrorsBeFatal("example1.test"));
364 EXPECT_TRUE(state
.ShouldSSLErrorsBeFatal("example2.test"));
367 // Tests that HPKP and HSTS state both expire. Also tests that expired entries
369 TEST_F(TransportSecurityStateTest
, Expiration
) {
370 const GURL
report_uri(kReportUri
);
371 TransportSecurityState state
;
372 const base::Time
current_time(base::Time::Now());
373 const base::Time expiry
= current_time
+ base::TimeDelta::FromSeconds(1000);
374 const base::Time older
= current_time
- base::TimeDelta::FromSeconds(1000);
376 // Note: this test assumes that inserting an entry with an expiration time in
377 // the past works and is pruned on query.
378 state
.AddHSTS("example1.test", older
, false);
379 EXPECT_TRUE(TransportSecurityState::STSStateIterator(state
).HasNext());
380 EXPECT_FALSE(state
.ShouldUpgradeToSSL("example1.test"));
381 // Querying |state| for a domain should flush out expired entries.
382 EXPECT_FALSE(TransportSecurityState::STSStateIterator(state
).HasNext());
384 state
.AddHPKP("example1.test", older
, false, GetSampleSPKIHashes(),
386 EXPECT_TRUE(TransportSecurityState::PKPStateIterator(state
).HasNext());
387 EXPECT_FALSE(state
.HasPublicKeyPins("example1.test"));
388 // Querying |state| for a domain should flush out expired entries.
389 EXPECT_FALSE(TransportSecurityState::PKPStateIterator(state
).HasNext());
391 state
.AddHSTS("example1.test", older
, false);
392 state
.AddHPKP("example1.test", older
, false, GetSampleSPKIHashes(),
394 EXPECT_TRUE(TransportSecurityState::STSStateIterator(state
).HasNext());
395 EXPECT_TRUE(TransportSecurityState::PKPStateIterator(state
).HasNext());
396 EXPECT_FALSE(state
.ShouldSSLErrorsBeFatal("example1.test"));
397 // Querying |state| for a domain should flush out expired entries.
398 EXPECT_FALSE(TransportSecurityState::STSStateIterator(state
).HasNext());
399 EXPECT_FALSE(TransportSecurityState::PKPStateIterator(state
).HasNext());
401 // Test that HSTS can outlive HPKP.
402 state
.AddHSTS("example1.test", expiry
, false);
403 state
.AddHPKP("example1.test", older
, false, GetSampleSPKIHashes(),
405 EXPECT_TRUE(state
.ShouldUpgradeToSSL("example1.test"));
406 EXPECT_FALSE(state
.HasPublicKeyPins("example1.test"));
408 // Test that HPKP can outlive HSTS.
409 state
.AddHSTS("example2.test", older
, false);
410 state
.AddHPKP("example2.test", expiry
, false, GetSampleSPKIHashes(),
412 EXPECT_FALSE(state
.ShouldUpgradeToSSL("example2.test"));
413 EXPECT_TRUE(state
.HasPublicKeyPins("example2.test"));
416 TEST_F(TransportSecurityStateTest
, InvalidDomains
) {
417 TransportSecurityState state
;
418 const base::Time
current_time(base::Time::Now());
419 const base::Time expiry
= current_time
+ base::TimeDelta::FromSeconds(1000);
421 EXPECT_FALSE(state
.ShouldUpgradeToSSL("example.test"));
422 bool include_subdomains
= true;
423 state
.AddHSTS("example.test", expiry
, include_subdomains
);
424 EXPECT_TRUE(state
.ShouldUpgradeToSSL("www-.foo.example.test"));
425 EXPECT_TRUE(state
.ShouldUpgradeToSSL("2\x01.foo.example.test"));
428 // Tests that HPKP and HSTS state are queried independently for subdomain
430 TEST_F(TransportSecurityStateTest
, IndependentSubdomain
) {
431 const GURL
report_uri(kReportUri
);
432 TransportSecurityState state
;
433 const base::Time
current_time(base::Time::Now());
434 const base::Time expiry
= current_time
+ base::TimeDelta::FromSeconds(1000);
436 state
.AddHSTS("example1.test", expiry
, true);
437 state
.AddHPKP("example1.test", expiry
, false, GetSampleSPKIHashes(),
440 state
.AddHSTS("example2.test", expiry
, false);
441 state
.AddHPKP("example2.test", expiry
, true, GetSampleSPKIHashes(),
444 EXPECT_TRUE(state
.ShouldUpgradeToSSL("foo.example1.test"));
445 EXPECT_FALSE(state
.HasPublicKeyPins("foo.example1.test"));
446 EXPECT_FALSE(state
.ShouldUpgradeToSSL("foo.example2.test"));
447 EXPECT_TRUE(state
.HasPublicKeyPins("foo.example2.test"));
450 // Tests that HPKP and HSTS state are inserted and overridden independently.
451 TEST_F(TransportSecurityStateTest
, IndependentInsertion
) {
452 const GURL
report_uri(kReportUri
);
453 TransportSecurityState state
;
454 const base::Time
current_time(base::Time::Now());
455 const base::Time expiry
= current_time
+ base::TimeDelta::FromSeconds(1000);
457 // Place an includeSubdomains HSTS entry below a normal HPKP entry.
458 state
.AddHSTS("example1.test", expiry
, true);
459 state
.AddHPKP("foo.example1.test", expiry
, false, GetSampleSPKIHashes(),
462 EXPECT_TRUE(state
.ShouldUpgradeToSSL("foo.example1.test"));
463 EXPECT_TRUE(state
.HasPublicKeyPins("foo.example1.test"));
464 EXPECT_TRUE(state
.ShouldUpgradeToSSL("example1.test"));
465 EXPECT_FALSE(state
.HasPublicKeyPins("example1.test"));
467 // Drop the includeSubdomains from the HSTS entry.
468 state
.AddHSTS("example1.test", expiry
, false);
470 EXPECT_FALSE(state
.ShouldUpgradeToSSL("foo.example1.test"));
471 EXPECT_TRUE(state
.HasPublicKeyPins("foo.example1.test"));
473 // Place an includeSubdomains HPKP entry below a normal HSTS entry.
474 state
.AddHSTS("foo.example2.test", expiry
, false);
475 state
.AddHPKP("example2.test", expiry
, true, GetSampleSPKIHashes(),
478 EXPECT_TRUE(state
.ShouldUpgradeToSSL("foo.example2.test"));
479 EXPECT_TRUE(state
.HasPublicKeyPins("foo.example2.test"));
481 // Drop the includeSubdomains from the HSTS entry.
482 state
.AddHPKP("example2.test", expiry
, false, GetSampleSPKIHashes(),
485 EXPECT_TRUE(state
.ShouldUpgradeToSSL("foo.example2.test"));
486 EXPECT_FALSE(state
.HasPublicKeyPins("foo.example2.test"));
489 // Tests that GetDynamic[PKP|STS]State returns the correct data and that the
490 // states are not mixed together.
491 TEST_F(TransportSecurityStateTest
, DynamicDomainState
) {
492 const GURL
report_uri(kReportUri
);
493 TransportSecurityState state
;
494 const base::Time
current_time(base::Time::Now());
495 const base::Time expiry1
= current_time
+ base::TimeDelta::FromSeconds(1000);
496 const base::Time expiry2
= current_time
+ base::TimeDelta::FromSeconds(2000);
498 state
.AddHSTS("example.com", expiry1
, true);
499 state
.AddHPKP("foo.example.com", expiry2
, false, GetSampleSPKIHashes(),
502 TransportSecurityState::STSState sts_state
;
503 TransportSecurityState::PKPState pkp_state
;
504 ASSERT_TRUE(state
.GetDynamicSTSState("foo.example.com", &sts_state
));
505 ASSERT_TRUE(state
.GetDynamicPKPState("foo.example.com", &pkp_state
));
506 EXPECT_TRUE(sts_state
.ShouldUpgradeToSSL());
507 EXPECT_TRUE(pkp_state
.HasPublicKeyPins());
508 EXPECT_TRUE(sts_state
.include_subdomains
);
509 EXPECT_FALSE(pkp_state
.include_subdomains
);
510 EXPECT_EQ(expiry1
, sts_state
.expiry
);
511 EXPECT_EQ(expiry2
, pkp_state
.expiry
);
512 EXPECT_EQ("example.com", sts_state
.domain
);
513 EXPECT_EQ("foo.example.com", pkp_state
.domain
);
516 // Tests that new pins always override previous pins. This should be true for
517 // both pins at the same domain or includeSubdomains pins at a parent domain.
518 TEST_F(TransportSecurityStateTest
, NewPinsOverride
) {
519 const GURL
report_uri(kReportUri
);
520 TransportSecurityState state
;
521 TransportSecurityState::PKPState pkp_state
;
522 const base::Time
current_time(base::Time::Now());
523 const base::Time expiry
= current_time
+ base::TimeDelta::FromSeconds(1000);
524 HashValue
hash1(HASH_VALUE_SHA1
);
525 memset(hash1
.data(), 0x01, hash1
.size());
526 HashValue
hash2(HASH_VALUE_SHA1
);
527 memset(hash2
.data(), 0x02, hash1
.size());
528 HashValue
hash3(HASH_VALUE_SHA1
);
529 memset(hash3
.data(), 0x03, hash1
.size());
531 state
.AddHPKP("example.com", expiry
, true, HashValueVector(1, hash1
),
534 ASSERT_TRUE(state
.GetDynamicPKPState("foo.example.com", &pkp_state
));
535 ASSERT_EQ(1u, pkp_state
.spki_hashes
.size());
536 EXPECT_TRUE(pkp_state
.spki_hashes
[0].Equals(hash1
));
538 state
.AddHPKP("foo.example.com", expiry
, false, HashValueVector(1, hash2
),
541 ASSERT_TRUE(state
.GetDynamicPKPState("foo.example.com", &pkp_state
));
542 ASSERT_EQ(1u, pkp_state
.spki_hashes
.size());
543 EXPECT_TRUE(pkp_state
.spki_hashes
[0].Equals(hash2
));
545 state
.AddHPKP("foo.example.com", expiry
, false, HashValueVector(1, hash3
),
548 ASSERT_TRUE(state
.GetDynamicPKPState("foo.example.com", &pkp_state
));
549 ASSERT_EQ(1u, pkp_state
.spki_hashes
.size());
550 EXPECT_TRUE(pkp_state
.spki_hashes
[0].Equals(hash3
));
553 TEST_F(TransportSecurityStateTest
, DeleteAllDynamicDataSince
) {
554 TransportSecurityState state
;
555 const base::Time
current_time(base::Time::Now());
556 const base::Time expiry
= current_time
+ base::TimeDelta::FromSeconds(1000);
557 const base::Time older
= current_time
- base::TimeDelta::FromSeconds(1000);
559 EXPECT_FALSE(state
.ShouldUpgradeToSSL("example.com"));
560 EXPECT_FALSE(state
.HasPublicKeyPins("example.com"));
561 bool include_subdomains
= false;
562 state
.AddHSTS("example.com", expiry
, include_subdomains
);
563 state
.AddHPKP("example.com", expiry
, include_subdomains
,
564 GetSampleSPKIHashes(), GURL());
566 state
.DeleteAllDynamicDataSince(expiry
);
567 EXPECT_TRUE(state
.ShouldUpgradeToSSL("example.com"));
568 EXPECT_TRUE(state
.HasPublicKeyPins("example.com"));
569 state
.DeleteAllDynamicDataSince(older
);
570 EXPECT_FALSE(state
.ShouldUpgradeToSSL("example.com"));
571 EXPECT_FALSE(state
.HasPublicKeyPins("example.com"));
573 // STS and PKP data in |state| should be empty now.
574 EXPECT_FALSE(TransportSecurityState::STSStateIterator(state
).HasNext());
575 EXPECT_FALSE(TransportSecurityState::PKPStateIterator(state
).HasNext());
578 TEST_F(TransportSecurityStateTest
, DeleteDynamicDataForHost
) {
579 TransportSecurityState state
;
580 const base::Time
current_time(base::Time::Now());
581 const base::Time expiry
= current_time
+ base::TimeDelta::FromSeconds(1000);
582 bool include_subdomains
= false;
584 state
.AddHSTS("example1.test", expiry
, include_subdomains
);
585 state
.AddHPKP("example1.test", expiry
, include_subdomains
,
586 GetSampleSPKIHashes(), GURL());
588 EXPECT_TRUE(state
.ShouldUpgradeToSSL("example1.test"));
589 EXPECT_FALSE(state
.ShouldUpgradeToSSL("example2.test"));
590 EXPECT_TRUE(state
.HasPublicKeyPins("example1.test"));
591 EXPECT_FALSE(state
.HasPublicKeyPins("example2.test"));
592 EXPECT_TRUE(state
.DeleteDynamicDataForHost("example1.test"));
593 EXPECT_FALSE(state
.ShouldUpgradeToSSL("example1.test"));
594 EXPECT_FALSE(state
.HasPublicKeyPins("example1.test"));
597 TEST_F(TransportSecurityStateTest
, EnableStaticPins
) {
598 TransportSecurityState state
;
599 TransportSecurityState::STSState sts_state
;
600 TransportSecurityState::PKPState pkp_state
;
602 EnableStaticPins(&state
);
605 state
.GetStaticDomainState("chrome.google.com", &sts_state
, &pkp_state
));
606 EXPECT_FALSE(pkp_state
.spki_hashes
.empty());
609 TEST_F(TransportSecurityStateTest
, DisableStaticPins
) {
610 TransportSecurityState state
;
611 TransportSecurityState::STSState sts_state
;
612 TransportSecurityState::PKPState pkp_state
;
614 DisableStaticPins(&state
);
616 state
.GetStaticDomainState("chrome.google.com", &sts_state
, &pkp_state
));
617 EXPECT_TRUE(pkp_state
.spki_hashes
.empty());
620 TEST_F(TransportSecurityStateTest
, IsPreloaded
) {
621 const std::string paypal
= "paypal.com";
622 const std::string www_paypal
= "www.paypal.com";
623 const std::string foo_paypal
= "foo.paypal.com";
624 const std::string a_www_paypal
= "a.www.paypal.com";
625 const std::string abc_paypal
= "a.b.c.paypal.com";
626 const std::string example
= "example.com";
627 const std::string aypal
= "aypal.com";
628 const std::string google
= "google";
629 const std::string www_google
= "www.google";
631 TransportSecurityState state
;
632 TransportSecurityState::STSState sts_state
;
633 TransportSecurityState::PKPState pkp_state
;
635 EXPECT_TRUE(GetStaticDomainState(&state
, paypal
, &sts_state
, &pkp_state
));
636 EXPECT_TRUE(GetStaticDomainState(&state
, www_paypal
, &sts_state
, &pkp_state
));
637 EXPECT_FALSE(sts_state
.include_subdomains
);
638 EXPECT_TRUE(GetStaticDomainState(&state
, google
, &sts_state
, &pkp_state
));
639 EXPECT_TRUE(GetStaticDomainState(&state
, www_google
, &sts_state
, &pkp_state
));
641 GetStaticDomainState(&state
, a_www_paypal
, &sts_state
, &pkp_state
));
643 GetStaticDomainState(&state
, abc_paypal
, &sts_state
, &pkp_state
));
644 EXPECT_FALSE(GetStaticDomainState(&state
, example
, &sts_state
, &pkp_state
));
645 EXPECT_FALSE(GetStaticDomainState(&state
, aypal
, &sts_state
, &pkp_state
));
648 TEST_F(TransportSecurityStateTest
, PreloadedDomainSet
) {
649 TransportSecurityState state
;
650 TransportSecurityState::STSState sts_state
;
651 TransportSecurityState::PKPState pkp_state
;
653 // The domain wasn't being set, leading to a blank string in the
654 // chrome://net-internals/#hsts UI. So test that.
656 state
.GetStaticDomainState("market.android.com", &sts_state
, &pkp_state
));
657 EXPECT_EQ(sts_state
.domain
, "market.android.com");
658 EXPECT_EQ(pkp_state
.domain
, "market.android.com");
659 EXPECT_TRUE(state
.GetStaticDomainState("sub.market.android.com", &sts_state
,
661 EXPECT_EQ(sts_state
.domain
, "market.android.com");
662 EXPECT_EQ(pkp_state
.domain
, "market.android.com");
665 static bool StaticShouldRedirect(const char* hostname
) {
666 TransportSecurityState state
;
667 TransportSecurityState::STSState sts_state
;
668 TransportSecurityState::PKPState pkp_state
;
669 return state
.GetStaticDomainState(hostname
, &sts_state
, &pkp_state
) &&
670 sts_state
.ShouldUpgradeToSSL();
673 static bool HasStaticState(const char* hostname
) {
674 TransportSecurityState state
;
675 TransportSecurityState::STSState sts_state
;
676 TransportSecurityState::PKPState pkp_state
;
677 return state
.GetStaticDomainState(hostname
, &sts_state
, &pkp_state
);
680 static bool HasStaticPublicKeyPins(const char* hostname
) {
681 TransportSecurityState state
;
682 TransportSecurityStateTest::EnableStaticPins(&state
);
683 TransportSecurityState::STSState sts_state
;
684 TransportSecurityState::PKPState pkp_state
;
685 if (!state
.GetStaticDomainState(hostname
, &sts_state
, &pkp_state
))
688 return pkp_state
.HasPublicKeyPins();
691 static bool OnlyPinningInStaticState(const char* hostname
) {
692 TransportSecurityState state
;
693 TransportSecurityStateTest::EnableStaticPins(&state
);
694 TransportSecurityState::STSState sts_state
;
695 TransportSecurityState::PKPState pkp_state
;
696 if (!state
.GetStaticDomainState(hostname
, &sts_state
, &pkp_state
))
699 return (pkp_state
.spki_hashes
.size() > 0 ||
700 pkp_state
.bad_spki_hashes
.size() > 0) &&
701 !sts_state
.ShouldUpgradeToSSL();
704 TEST_F(TransportSecurityStateTest
, Preloaded
) {
705 TransportSecurityState state
;
706 TransportSecurityState::STSState sts_state
;
707 TransportSecurityState::PKPState pkp_state
;
709 // We do more extensive checks for the first domain.
711 state
.GetStaticDomainState("www.paypal.com", &sts_state
, &pkp_state
));
712 EXPECT_EQ(sts_state
.upgrade_mode
,
713 TransportSecurityState::STSState::MODE_FORCE_HTTPS
);
714 EXPECT_FALSE(sts_state
.include_subdomains
);
715 EXPECT_FALSE(pkp_state
.include_subdomains
);
717 EXPECT_TRUE(HasStaticState("paypal.com"));
718 EXPECT_FALSE(HasStaticState("www2.paypal.com"));
722 EXPECT_TRUE(StaticShouldRedirect("chrome.google.com"));
723 EXPECT_TRUE(StaticShouldRedirect("checkout.google.com"));
724 EXPECT_TRUE(StaticShouldRedirect("wallet.google.com"));
725 EXPECT_TRUE(StaticShouldRedirect("docs.google.com"));
726 EXPECT_TRUE(StaticShouldRedirect("sites.google.com"));
727 EXPECT_TRUE(StaticShouldRedirect("drive.google.com"));
728 EXPECT_TRUE(StaticShouldRedirect("spreadsheets.google.com"));
729 EXPECT_TRUE(StaticShouldRedirect("appengine.google.com"));
730 EXPECT_TRUE(StaticShouldRedirect("market.android.com"));
731 EXPECT_TRUE(StaticShouldRedirect("encrypted.google.com"));
732 EXPECT_TRUE(StaticShouldRedirect("accounts.google.com"));
733 EXPECT_TRUE(StaticShouldRedirect("profiles.google.com"));
734 EXPECT_TRUE(StaticShouldRedirect("mail.google.com"));
735 EXPECT_TRUE(StaticShouldRedirect("chatenabled.mail.google.com"));
736 EXPECT_TRUE(StaticShouldRedirect("talkgadget.google.com"));
737 EXPECT_TRUE(StaticShouldRedirect("hostedtalkgadget.google.com"));
738 EXPECT_TRUE(StaticShouldRedirect("talk.google.com"));
739 EXPECT_TRUE(StaticShouldRedirect("plus.google.com"));
740 EXPECT_TRUE(StaticShouldRedirect("groups.google.com"));
741 EXPECT_TRUE(StaticShouldRedirect("apis.google.com"));
742 EXPECT_FALSE(StaticShouldRedirect("chart.apis.google.com"));
743 EXPECT_TRUE(StaticShouldRedirect("ssl.google-analytics.com"));
744 EXPECT_TRUE(StaticShouldRedirect("google"));
745 EXPECT_TRUE(StaticShouldRedirect("foo.google"));
746 EXPECT_TRUE(StaticShouldRedirect("gmail.com"));
747 EXPECT_TRUE(StaticShouldRedirect("www.gmail.com"));
748 EXPECT_TRUE(StaticShouldRedirect("googlemail.com"));
749 EXPECT_TRUE(StaticShouldRedirect("www.googlemail.com"));
750 EXPECT_TRUE(StaticShouldRedirect("googleplex.com"));
751 EXPECT_TRUE(StaticShouldRedirect("www.googleplex.com"));
753 // These domains used to be only HSTS when SNI was available.
754 EXPECT_TRUE(state
.GetStaticDomainState("gmail.com", &sts_state
, &pkp_state
));
756 state
.GetStaticDomainState("www.gmail.com", &sts_state
, &pkp_state
));
758 state
.GetStaticDomainState("googlemail.com", &sts_state
, &pkp_state
));
760 state
.GetStaticDomainState("www.googlemail.com", &sts_state
, &pkp_state
));
764 EXPECT_TRUE(StaticShouldRedirect("aladdinschools.appspot.com"));
766 EXPECT_TRUE(StaticShouldRedirect("ottospora.nl"));
767 EXPECT_TRUE(StaticShouldRedirect("www.ottospora.nl"));
769 EXPECT_TRUE(StaticShouldRedirect("www.paycheckrecords.com"));
771 EXPECT_TRUE(StaticShouldRedirect("lastpass.com"));
772 EXPECT_TRUE(StaticShouldRedirect("www.lastpass.com"));
773 EXPECT_FALSE(HasStaticState("blog.lastpass.com"));
775 EXPECT_TRUE(StaticShouldRedirect("keyerror.com"));
776 EXPECT_TRUE(StaticShouldRedirect("www.keyerror.com"));
778 EXPECT_TRUE(StaticShouldRedirect("entropia.de"));
779 EXPECT_TRUE(StaticShouldRedirect("www.entropia.de"));
780 EXPECT_FALSE(HasStaticState("foo.entropia.de"));
782 EXPECT_TRUE(StaticShouldRedirect("www.elanex.biz"));
783 EXPECT_FALSE(HasStaticState("elanex.biz"));
784 EXPECT_FALSE(HasStaticState("foo.elanex.biz"));
786 EXPECT_TRUE(StaticShouldRedirect("sunshinepress.org"));
787 EXPECT_TRUE(StaticShouldRedirect("www.sunshinepress.org"));
788 EXPECT_TRUE(StaticShouldRedirect("a.b.sunshinepress.org"));
790 EXPECT_TRUE(StaticShouldRedirect("www.noisebridge.net"));
791 EXPECT_FALSE(HasStaticState("noisebridge.net"));
792 EXPECT_FALSE(HasStaticState("foo.noisebridge.net"));
794 EXPECT_TRUE(StaticShouldRedirect("neg9.org"));
795 EXPECT_FALSE(HasStaticState("www.neg9.org"));
797 EXPECT_TRUE(StaticShouldRedirect("riseup.net"));
798 EXPECT_TRUE(StaticShouldRedirect("foo.riseup.net"));
800 EXPECT_TRUE(StaticShouldRedirect("factor.cc"));
801 EXPECT_FALSE(HasStaticState("www.factor.cc"));
803 EXPECT_TRUE(StaticShouldRedirect("members.mayfirst.org"));
804 EXPECT_TRUE(StaticShouldRedirect("support.mayfirst.org"));
805 EXPECT_TRUE(StaticShouldRedirect("id.mayfirst.org"));
806 EXPECT_TRUE(StaticShouldRedirect("lists.mayfirst.org"));
807 EXPECT_FALSE(HasStaticState("www.mayfirst.org"));
809 EXPECT_TRUE(StaticShouldRedirect("romab.com"));
810 EXPECT_TRUE(StaticShouldRedirect("www.romab.com"));
811 EXPECT_TRUE(StaticShouldRedirect("foo.romab.com"));
813 EXPECT_TRUE(StaticShouldRedirect("logentries.com"));
814 EXPECT_TRUE(StaticShouldRedirect("www.logentries.com"));
815 EXPECT_FALSE(HasStaticState("foo.logentries.com"));
817 EXPECT_TRUE(StaticShouldRedirect("stripe.com"));
818 EXPECT_TRUE(StaticShouldRedirect("foo.stripe.com"));
820 EXPECT_TRUE(StaticShouldRedirect("cloudsecurityalliance.org"));
821 EXPECT_TRUE(StaticShouldRedirect("foo.cloudsecurityalliance.org"));
823 EXPECT_TRUE(StaticShouldRedirect("login.sapo.pt"));
824 EXPECT_TRUE(StaticShouldRedirect("foo.login.sapo.pt"));
826 EXPECT_TRUE(StaticShouldRedirect("mattmccutchen.net"));
827 EXPECT_TRUE(StaticShouldRedirect("foo.mattmccutchen.net"));
829 EXPECT_TRUE(StaticShouldRedirect("betnet.fr"));
830 EXPECT_TRUE(StaticShouldRedirect("foo.betnet.fr"));
832 EXPECT_TRUE(StaticShouldRedirect("uprotect.it"));
833 EXPECT_TRUE(StaticShouldRedirect("foo.uprotect.it"));
835 EXPECT_TRUE(StaticShouldRedirect("squareup.com"));
836 EXPECT_FALSE(HasStaticState("foo.squareup.com"));
838 EXPECT_TRUE(StaticShouldRedirect("cert.se"));
839 EXPECT_TRUE(StaticShouldRedirect("foo.cert.se"));
841 EXPECT_TRUE(StaticShouldRedirect("crypto.is"));
842 EXPECT_TRUE(StaticShouldRedirect("foo.crypto.is"));
844 EXPECT_TRUE(StaticShouldRedirect("simon.butcher.name"));
845 EXPECT_TRUE(StaticShouldRedirect("foo.simon.butcher.name"));
847 EXPECT_TRUE(StaticShouldRedirect("linx.net"));
848 EXPECT_TRUE(StaticShouldRedirect("foo.linx.net"));
850 EXPECT_TRUE(StaticShouldRedirect("dropcam.com"));
851 EXPECT_TRUE(StaticShouldRedirect("www.dropcam.com"));
852 EXPECT_FALSE(HasStaticState("foo.dropcam.com"));
854 EXPECT_TRUE(StaticShouldRedirect("ebanking.indovinabank.com.vn"));
855 EXPECT_TRUE(StaticShouldRedirect("foo.ebanking.indovinabank.com.vn"));
857 EXPECT_TRUE(StaticShouldRedirect("epoxate.com"));
858 EXPECT_FALSE(HasStaticState("foo.epoxate.com"));
860 EXPECT_FALSE(HasStaticState("foo.torproject.org"));
862 EXPECT_TRUE(StaticShouldRedirect("www.moneybookers.com"));
863 EXPECT_FALSE(HasStaticState("moneybookers.com"));
865 EXPECT_TRUE(StaticShouldRedirect("ledgerscope.net"));
866 EXPECT_TRUE(StaticShouldRedirect("www.ledgerscope.net"));
867 EXPECT_FALSE(HasStaticState("status.ledgerscope.net"));
869 EXPECT_TRUE(StaticShouldRedirect("foo.app.recurly.com"));
870 EXPECT_TRUE(StaticShouldRedirect("foo.api.recurly.com"));
872 EXPECT_TRUE(StaticShouldRedirect("greplin.com"));
873 EXPECT_TRUE(StaticShouldRedirect("www.greplin.com"));
874 EXPECT_FALSE(HasStaticState("foo.greplin.com"));
876 EXPECT_TRUE(StaticShouldRedirect("luneta.nearbuysystems.com"));
877 EXPECT_TRUE(StaticShouldRedirect("foo.luneta.nearbuysystems.com"));
879 EXPECT_TRUE(StaticShouldRedirect("ubertt.org"));
880 EXPECT_TRUE(StaticShouldRedirect("foo.ubertt.org"));
882 EXPECT_TRUE(StaticShouldRedirect("pixi.me"));
883 EXPECT_TRUE(StaticShouldRedirect("www.pixi.me"));
885 EXPECT_TRUE(StaticShouldRedirect("grepular.com"));
886 EXPECT_TRUE(StaticShouldRedirect("www.grepular.com"));
888 EXPECT_TRUE(StaticShouldRedirect("mydigipass.com"));
889 EXPECT_FALSE(StaticShouldRedirect("foo.mydigipass.com"));
890 EXPECT_TRUE(StaticShouldRedirect("www.mydigipass.com"));
891 EXPECT_FALSE(StaticShouldRedirect("foo.www.mydigipass.com"));
892 EXPECT_TRUE(StaticShouldRedirect("developer.mydigipass.com"));
893 EXPECT_FALSE(StaticShouldRedirect("foo.developer.mydigipass.com"));
894 EXPECT_TRUE(StaticShouldRedirect("www.developer.mydigipass.com"));
895 EXPECT_FALSE(StaticShouldRedirect("foo.www.developer.mydigipass.com"));
896 EXPECT_TRUE(StaticShouldRedirect("sandbox.mydigipass.com"));
897 EXPECT_FALSE(StaticShouldRedirect("foo.sandbox.mydigipass.com"));
898 EXPECT_TRUE(StaticShouldRedirect("www.sandbox.mydigipass.com"));
899 EXPECT_FALSE(StaticShouldRedirect("foo.www.sandbox.mydigipass.com"));
901 EXPECT_TRUE(StaticShouldRedirect("bigshinylock.minazo.net"));
902 EXPECT_TRUE(StaticShouldRedirect("foo.bigshinylock.minazo.net"));
904 EXPECT_TRUE(StaticShouldRedirect("crate.io"));
905 EXPECT_TRUE(StaticShouldRedirect("foo.crate.io"));
908 TEST_F(TransportSecurityStateTest
, PreloadedPins
) {
909 TransportSecurityState state
;
910 EnableStaticPins(&state
);
911 TransportSecurityState::STSState sts_state
;
912 TransportSecurityState::PKPState pkp_state
;
914 // We do more extensive checks for the first domain.
916 state
.GetStaticDomainState("www.paypal.com", &sts_state
, &pkp_state
));
917 EXPECT_EQ(sts_state
.upgrade_mode
,
918 TransportSecurityState::STSState::MODE_FORCE_HTTPS
);
919 EXPECT_FALSE(sts_state
.include_subdomains
);
920 EXPECT_FALSE(pkp_state
.include_subdomains
);
922 EXPECT_TRUE(OnlyPinningInStaticState("www.google.com"));
923 EXPECT_TRUE(OnlyPinningInStaticState("foo.google.com"));
924 EXPECT_TRUE(OnlyPinningInStaticState("google.com"));
925 EXPECT_TRUE(OnlyPinningInStaticState("www.youtube.com"));
926 EXPECT_TRUE(OnlyPinningInStaticState("youtube.com"));
927 EXPECT_TRUE(OnlyPinningInStaticState("i.ytimg.com"));
928 EXPECT_TRUE(OnlyPinningInStaticState("ytimg.com"));
929 EXPECT_TRUE(OnlyPinningInStaticState("googleusercontent.com"));
930 EXPECT_TRUE(OnlyPinningInStaticState("www.googleusercontent.com"));
931 EXPECT_TRUE(OnlyPinningInStaticState("www.google-analytics.com"));
932 EXPECT_TRUE(OnlyPinningInStaticState("googleapis.com"));
933 EXPECT_TRUE(OnlyPinningInStaticState("googleadservices.com"));
934 EXPECT_TRUE(OnlyPinningInStaticState("googlecode.com"));
935 EXPECT_TRUE(OnlyPinningInStaticState("appspot.com"));
936 EXPECT_TRUE(OnlyPinningInStaticState("googlesyndication.com"));
937 EXPECT_TRUE(OnlyPinningInStaticState("doubleclick.net"));
938 EXPECT_TRUE(OnlyPinningInStaticState("googlegroups.com"));
940 EXPECT_TRUE(HasStaticPublicKeyPins("torproject.org"));
941 EXPECT_TRUE(HasStaticPublicKeyPins("www.torproject.org"));
942 EXPECT_TRUE(HasStaticPublicKeyPins("check.torproject.org"));
943 EXPECT_TRUE(HasStaticPublicKeyPins("blog.torproject.org"));
944 EXPECT_FALSE(HasStaticState("foo.torproject.org"));
947 state
.GetStaticDomainState("torproject.org", &sts_state
, &pkp_state
));
948 EXPECT_FALSE(pkp_state
.spki_hashes
.empty());
950 state
.GetStaticDomainState("www.torproject.org", &sts_state
, &pkp_state
));
951 EXPECT_FALSE(pkp_state
.spki_hashes
.empty());
952 EXPECT_TRUE(state
.GetStaticDomainState("check.torproject.org", &sts_state
,
954 EXPECT_FALSE(pkp_state
.spki_hashes
.empty());
955 EXPECT_TRUE(state
.GetStaticDomainState("blog.torproject.org", &sts_state
,
957 EXPECT_FALSE(pkp_state
.spki_hashes
.empty());
959 EXPECT_TRUE(HasStaticPublicKeyPins("www.twitter.com"));
961 // Check that Facebook subdomains have pinning but not HSTS.
963 state
.GetStaticDomainState("facebook.com", &sts_state
, &pkp_state
));
964 EXPECT_FALSE(pkp_state
.spki_hashes
.empty());
965 EXPECT_TRUE(StaticShouldRedirect("facebook.com"));
968 state
.GetStaticDomainState("foo.facebook.com", &sts_state
, &pkp_state
));
971 state
.GetStaticDomainState("www.facebook.com", &sts_state
, &pkp_state
));
972 EXPECT_FALSE(pkp_state
.spki_hashes
.empty());
973 EXPECT_TRUE(StaticShouldRedirect("www.facebook.com"));
975 EXPECT_TRUE(state
.GetStaticDomainState("foo.www.facebook.com", &sts_state
,
977 EXPECT_FALSE(pkp_state
.spki_hashes
.empty());
978 EXPECT_TRUE(StaticShouldRedirect("foo.www.facebook.com"));
981 TEST_F(TransportSecurityStateTest
, LongNames
) {
982 TransportSecurityState state
;
983 const char kLongName
[] =
984 "lookupByWaveIdHashAndWaveIdIdAndWaveIdDomainAndWaveletIdIdAnd"
985 "WaveletIdDomainAndBlipBlipid";
986 TransportSecurityState::STSState sts_state
;
987 TransportSecurityState::PKPState pkp_state
;
988 // Just checks that we don't hit a NOTREACHED.
989 EXPECT_FALSE(state
.GetStaticDomainState(kLongName
, &sts_state
, &pkp_state
));
990 EXPECT_FALSE(state
.GetDynamicSTSState(kLongName
, &sts_state
));
991 EXPECT_FALSE(state
.GetDynamicPKPState(kLongName
, &pkp_state
));
994 TEST_F(TransportSecurityStateTest
, BuiltinCertPins
) {
995 TransportSecurityState state
;
996 EnableStaticPins(&state
);
997 TransportSecurityState::STSState sts_state
;
998 TransportSecurityState::PKPState pkp_state
;
1001 state
.GetStaticDomainState("chrome.google.com", &sts_state
, &pkp_state
));
1002 EXPECT_TRUE(HasStaticPublicKeyPins("chrome.google.com"));
1004 HashValueVector hashes
;
1005 std::string failure_log
;
1006 // Checks that a built-in list does exist.
1007 EXPECT_FALSE(pkp_state
.CheckPublicKeyPins(hashes
, &failure_log
));
1008 EXPECT_FALSE(HasStaticPublicKeyPins("www.paypal.com"));
1010 EXPECT_TRUE(HasStaticPublicKeyPins("docs.google.com"));
1011 EXPECT_TRUE(HasStaticPublicKeyPins("1.docs.google.com"));
1012 EXPECT_TRUE(HasStaticPublicKeyPins("sites.google.com"));
1013 EXPECT_TRUE(HasStaticPublicKeyPins("drive.google.com"));
1014 EXPECT_TRUE(HasStaticPublicKeyPins("spreadsheets.google.com"));
1015 EXPECT_TRUE(HasStaticPublicKeyPins("wallet.google.com"));
1016 EXPECT_TRUE(HasStaticPublicKeyPins("checkout.google.com"));
1017 EXPECT_TRUE(HasStaticPublicKeyPins("appengine.google.com"));
1018 EXPECT_TRUE(HasStaticPublicKeyPins("market.android.com"));
1019 EXPECT_TRUE(HasStaticPublicKeyPins("encrypted.google.com"));
1020 EXPECT_TRUE(HasStaticPublicKeyPins("accounts.google.com"));
1021 EXPECT_TRUE(HasStaticPublicKeyPins("profiles.google.com"));
1022 EXPECT_TRUE(HasStaticPublicKeyPins("mail.google.com"));
1023 EXPECT_TRUE(HasStaticPublicKeyPins("chatenabled.mail.google.com"));
1024 EXPECT_TRUE(HasStaticPublicKeyPins("talkgadget.google.com"));
1025 EXPECT_TRUE(HasStaticPublicKeyPins("hostedtalkgadget.google.com"));
1026 EXPECT_TRUE(HasStaticPublicKeyPins("talk.google.com"));
1027 EXPECT_TRUE(HasStaticPublicKeyPins("plus.google.com"));
1028 EXPECT_TRUE(HasStaticPublicKeyPins("groups.google.com"));
1029 EXPECT_TRUE(HasStaticPublicKeyPins("apis.google.com"));
1031 EXPECT_TRUE(HasStaticPublicKeyPins("ssl.gstatic.com"));
1032 EXPECT_TRUE(HasStaticPublicKeyPins("gstatic.com"));
1033 EXPECT_TRUE(HasStaticPublicKeyPins("www.gstatic.com"));
1034 EXPECT_TRUE(HasStaticPublicKeyPins("ssl.google-analytics.com"));
1035 EXPECT_TRUE(HasStaticPublicKeyPins("www.googleplex.com"));
1037 EXPECT_TRUE(HasStaticPublicKeyPins("twitter.com"));
1038 EXPECT_FALSE(HasStaticPublicKeyPins("foo.twitter.com"));
1039 EXPECT_TRUE(HasStaticPublicKeyPins("www.twitter.com"));
1040 EXPECT_TRUE(HasStaticPublicKeyPins("api.twitter.com"));
1041 EXPECT_TRUE(HasStaticPublicKeyPins("oauth.twitter.com"));
1042 EXPECT_TRUE(HasStaticPublicKeyPins("mobile.twitter.com"));
1043 EXPECT_TRUE(HasStaticPublicKeyPins("dev.twitter.com"));
1044 EXPECT_TRUE(HasStaticPublicKeyPins("business.twitter.com"));
1045 EXPECT_TRUE(HasStaticPublicKeyPins("platform.twitter.com"));
1046 EXPECT_TRUE(HasStaticPublicKeyPins("si0.twimg.com"));
1049 static bool AddHash(const std::string
& type_and_base64
,
1050 HashValueVector
* out
) {
1052 if (!hash
.FromString(type_and_base64
))
1055 out
->push_back(hash
);
1059 TEST_F(TransportSecurityStateTest
, PinValidationWithoutRejectedCerts
) {
1060 // kGoodPath is blog.torproject.org.
1061 static const char* const kGoodPath
[] = {
1062 "sha1/m9lHYJYke9k0GtVZ+bXSQYE8nDI=",
1063 "sha1/o5OZxATDsgmwgcIfIWIneMJ0jkw=",
1064 "sha1/wHqYaI2J+6sFZAwRfap9ZbjKzE4=",
1068 // kBadPath is plus.google.com via Trustcenter, which is utterly wrong for
1070 static const char* const kBadPath
[] = {
1071 "sha1/4BjDjn8v2lWeUFQnqSs0BgbIcrU=",
1072 "sha1/gzuEEAB/bkqdQS3EIjk2by7lW+k=",
1073 "sha1/SOZo+SvSspXXR9gjIBBPM5iQn9Q=",
1077 HashValueVector good_hashes
, bad_hashes
;
1079 for (size_t i
= 0; kGoodPath
[i
]; i
++) {
1080 EXPECT_TRUE(AddHash(kGoodPath
[i
], &good_hashes
));
1082 for (size_t i
= 0; kBadPath
[i
]; i
++) {
1083 EXPECT_TRUE(AddHash(kBadPath
[i
], &bad_hashes
));
1086 TransportSecurityState state
;
1087 EnableStaticPins(&state
);
1089 TransportSecurityState::STSState sts_state
;
1090 TransportSecurityState::PKPState pkp_state
;
1091 EXPECT_TRUE(state
.GetStaticDomainState("blog.torproject.org", &sts_state
,
1093 EXPECT_TRUE(pkp_state
.HasPublicKeyPins());
1095 std::string failure_log
;
1096 EXPECT_TRUE(pkp_state
.CheckPublicKeyPins(good_hashes
, &failure_log
));
1097 EXPECT_FALSE(pkp_state
.CheckPublicKeyPins(bad_hashes
, &failure_log
));
1100 TEST_F(TransportSecurityStateTest
, OptionalHSTSCertPins
) {
1101 TransportSecurityState state
;
1102 EnableStaticPins(&state
);
1104 EXPECT_FALSE(StaticShouldRedirect("www.google-analytics.com"));
1106 EXPECT_TRUE(HasStaticPublicKeyPins("www.google-analytics.com"));
1107 EXPECT_TRUE(HasStaticPublicKeyPins("google.com"));
1108 EXPECT_TRUE(HasStaticPublicKeyPins("www.google.com"));
1109 EXPECT_TRUE(HasStaticPublicKeyPins("mail-attachment.googleusercontent.com"));
1110 EXPECT_TRUE(HasStaticPublicKeyPins("www.youtube.com"));
1111 EXPECT_TRUE(HasStaticPublicKeyPins("i.ytimg.com"));
1112 EXPECT_TRUE(HasStaticPublicKeyPins("googleapis.com"));
1113 EXPECT_TRUE(HasStaticPublicKeyPins("ajax.googleapis.com"));
1114 EXPECT_TRUE(HasStaticPublicKeyPins("googleadservices.com"));
1115 EXPECT_TRUE(HasStaticPublicKeyPins("pagead2.googleadservices.com"));
1116 EXPECT_TRUE(HasStaticPublicKeyPins("googlecode.com"));
1117 EXPECT_TRUE(HasStaticPublicKeyPins("kibbles.googlecode.com"));
1118 EXPECT_TRUE(HasStaticPublicKeyPins("appspot.com"));
1119 EXPECT_TRUE(HasStaticPublicKeyPins("googlesyndication.com"));
1120 EXPECT_TRUE(HasStaticPublicKeyPins("doubleclick.net"));
1121 EXPECT_TRUE(HasStaticPublicKeyPins("ad.doubleclick.net"));
1122 EXPECT_FALSE(HasStaticPublicKeyPins("learn.doubleclick.net"));
1123 EXPECT_TRUE(HasStaticPublicKeyPins("a.googlegroups.com"));
1126 TEST_F(TransportSecurityStateTest
, OverrideBuiltins
) {
1127 EXPECT_TRUE(HasStaticPublicKeyPins("google.com"));
1128 EXPECT_FALSE(StaticShouldRedirect("google.com"));
1129 EXPECT_FALSE(StaticShouldRedirect("www.google.com"));
1131 TransportSecurityState state
;
1132 const base::Time
current_time(base::Time::Now());
1133 const base::Time expiry
= current_time
+ base::TimeDelta::FromSeconds(1000);
1134 state
.AddHSTS("www.google.com", expiry
, true);
1136 EXPECT_TRUE(state
.ShouldUpgradeToSSL("www.google.com"));
1139 TEST_F(TransportSecurityStateTest
, GooglePinnedProperties
) {
1140 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
1141 "www.example.com"));
1142 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
1144 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
1145 "mail.twitter.com"));
1146 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
1147 "www.google.com.int"));
1148 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
1150 // learn.doubleclick.net has a more specific match than
1151 // *.doubleclick.com, and has 0 or NULL for its required certs.
1152 // This test ensures that the exact-match-preferred behavior
1154 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
1155 "learn.doubleclick.net"));
1157 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
1158 "encrypted.google.com"));
1159 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
1160 "mail.google.com"));
1161 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
1162 "accounts.google.com"));
1163 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
1164 "doubleclick.net"));
1165 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
1166 "ad.doubleclick.net"));
1167 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
1169 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
1170 "www.profiles.google.com"));
1171 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
1172 "checkout.google.com"));
1173 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
1174 "googleadservices.com"));
1176 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
1177 "www.example.com"));
1178 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
1180 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
1181 "checkout.google.com"));
1182 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
1183 "googleadservices.com"));
1185 // Test some SNI hosts:
1186 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
1188 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
1189 "googlegroups.com"));
1190 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
1191 "www.googlegroups.com"));
1193 // These hosts used to only be HSTS when SNI was available.
1194 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
1196 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
1197 "googlegroups.com"));
1198 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
1199 "www.googlegroups.com"));
1202 TEST_F(TransportSecurityStateTest
, HPKPReporting
) {
1203 const char kHost
[] = "example.test";
1204 const char kSubdomain
[] = "foo.example.test";
1205 static const uint16_t kPort
= 443;
1206 HostPortPair
host_port_pair(kHost
, kPort
);
1207 HostPortPair
subdomain_host_port_pair(kSubdomain
, kPort
);
1208 GURL
report_uri("http://www.example.test/report");
1209 // Two dummy certs to use as the server-sent and validated chains. The
1210 // contents don't matter.
1211 scoped_refptr
<X509Certificate
> cert1
=
1212 ImportCertFromFile(GetTestCertsDirectory(), "test_mail_google_com.pem");
1213 scoped_refptr
<X509Certificate
> cert2
=
1214 ImportCertFromFile(GetTestCertsDirectory(), "expired_cert.pem");
1218 // kGoodPath is blog.torproject.org.
1219 static const char* const kGoodPath
[] = {
1220 "sha1/m9lHYJYke9k0GtVZ+bXSQYE8nDI=", "sha1/o5OZxATDsgmwgcIfIWIneMJ0jkw=",
1221 "sha1/wHqYaI2J+6sFZAwRfap9ZbjKzE4=", NULL
,
1224 // kBadPath is plus.google.com via Trustcenter, which is utterly wrong for
1226 static const char* const kBadPath
[] = {
1227 "sha1/4BjDjn8v2lWeUFQnqSs0BgbIcrU=", "sha1/gzuEEAB/bkqdQS3EIjk2by7lW+k=",
1228 "sha1/SOZo+SvSspXXR9gjIBBPM5iQn9Q=", NULL
,
1231 HashValueVector good_hashes
, bad_hashes
;
1233 for (size_t i
= 0; kGoodPath
[i
]; i
++)
1234 EXPECT_TRUE(AddHash(kGoodPath
[i
], &good_hashes
));
1235 for (size_t i
= 0; kBadPath
[i
]; i
++)
1236 EXPECT_TRUE(AddHash(kBadPath
[i
], &bad_hashes
));
1238 TransportSecurityState state
;
1239 MockCertificateReportSender mock_report_sender
;
1240 state
.SetReportSender(&mock_report_sender
);
1242 const base::Time current_time
= base::Time::Now();
1243 const base::Time expiry
= current_time
+ base::TimeDelta::FromSeconds(1000);
1244 state
.AddHPKP(kHost
, expiry
, true, good_hashes
, report_uri
);
1246 EXPECT_EQ(GURL(), mock_report_sender
.latest_report_uri());
1247 EXPECT_EQ(std::string(), mock_report_sender
.latest_report());
1249 std::string failure_log
;
1250 EXPECT_FALSE(state
.CheckPublicKeyPins(
1251 host_port_pair
, true, bad_hashes
, cert1
.get(), cert2
.get(),
1252 TransportSecurityState::DISABLE_PIN_REPORTS
, &failure_log
));
1254 // No report should have been sent because of the DISABLE_PIN_REPORTS
1256 EXPECT_EQ(GURL(), mock_report_sender
.latest_report_uri());
1257 EXPECT_EQ(std::string(), mock_report_sender
.latest_report());
1259 EXPECT_TRUE(state
.CheckPublicKeyPins(
1260 host_port_pair
, true, good_hashes
, cert1
.get(), cert2
.get(),
1261 TransportSecurityState::ENABLE_PIN_REPORTS
, &failure_log
));
1263 // No report should have been sent because there was no violation.
1264 EXPECT_EQ(GURL(), mock_report_sender
.latest_report_uri());
1265 EXPECT_EQ(std::string(), mock_report_sender
.latest_report());
1267 EXPECT_FALSE(state
.CheckPublicKeyPins(
1268 host_port_pair
, true, bad_hashes
, cert1
.get(), cert2
.get(),
1269 TransportSecurityState::ENABLE_PIN_REPORTS
, &failure_log
));
1271 // Now a report should have been sent. Check that it contains the
1272 // right information.
1273 EXPECT_EQ(report_uri
, mock_report_sender
.latest_report_uri());
1274 std::string report
= mock_report_sender
.latest_report();
1275 ASSERT_FALSE(report
.empty());
1276 ASSERT_NO_FATAL_FAILURE(CheckHPKPReport(report
, host_port_pair
, expiry
, true,
1277 kHost
, cert1
.get(), cert2
.get(),
1280 EXPECT_FALSE(state
.CheckPublicKeyPins(
1281 subdomain_host_port_pair
, true, bad_hashes
, cert1
.get(), cert2
.get(),
1282 TransportSecurityState::ENABLE_PIN_REPORTS
, &failure_log
));
1284 // Now a report should have been sent for the subdomain. Check that it
1285 // contains the right information.
1286 EXPECT_EQ(report_uri
, mock_report_sender
.latest_report_uri());
1287 report
= mock_report_sender
.latest_report();
1288 ASSERT_FALSE(report
.empty());
1289 ASSERT_NO_FATAL_FAILURE(CheckHPKPReport(report
, subdomain_host_port_pair
,
1290 expiry
, true, kHost
, cert1
.get(),
1291 cert2
.get(), good_hashes
));