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 kHost
[] = "example.test";
46 const char kSubdomain
[] = "foo.example.test";
47 const uint16_t kPort
= 443;
48 const char kReportUri
[] = "http://report-example.test/test";
50 // kGoodPath is blog.torproject.org.
51 const char* const kGoodPath
[] = {
52 "sha1/Yz4vayd/83rQfDXkDPn2yhzIScw=",
53 "sha1/3lKvjNsfmrn+WmfDhvr2iVh/yRs=",
54 "sha1/gzF+YoVCU9bXeDGQ7JGQVumRueM=",
55 "sha256/4osU79hfY3P2+WJGlT2mxmSL+5FIwLEVxTQcavyBNgQ=",
56 "sha256/k2v657xBsOVe1PQRwOsHsw3bsGT2VzIqz5K+59sNQws=",
57 "sha256/WoiWRyIOVNa9ihaBciRSC7XHjliYS9VwUGOIud4PB18=",
61 const char kGoodPin1
[] = "4osU79hfY3P2+WJGlT2mxmSL+5FIwLEVxTQcavyBNgQ=";
62 const char kGoodPin2
[] = "k2v657xBsOVe1PQRwOsHsw3bsGT2VzIqz5K+59sNQws=";
63 const char kGoodPin3
[] = "WoiWRyIOVNa9ihaBciRSC7XHjliYS9VwUGOIud4PB18=";
65 // kBadPath is plus.google.com via Trustcenter, which is utterly wrong for
67 const char* const kBadPath
[] = {
68 "sha1/111111111111111111111111111=",
69 "sha1/222222222222222222222222222=",
70 "sha1/333333333333333333333333333=",
71 "sha256/1111111111111111111111111111111111111111111=",
72 "sha256/2222222222222222222222222222222222222222222=",
73 "sha256/3333333333333333333333333333333333333333333=",
77 // A mock ReportSender that just remembers the latest report
78 // URI and report to be sent.
79 class MockCertificateReportSender
80 : public TransportSecurityState::ReportSender
{
82 MockCertificateReportSender() {}
83 ~MockCertificateReportSender() override
{}
85 void Send(const GURL
& report_uri
, const std::string
& report
) override
{
86 latest_report_uri_
= report_uri
;
87 latest_report_
= report
;
91 latest_report_uri_
= GURL();
92 latest_report_
= std::string();
95 const GURL
& latest_report_uri() { return latest_report_uri_
; }
96 const std::string
& latest_report() { return latest_report_
; }
99 GURL latest_report_uri_
;
100 std::string latest_report_
;
103 void CompareCertificateChainWithList(
104 const scoped_refptr
<X509Certificate
>& cert_chain
,
105 const base::ListValue
* cert_list
) {
106 ASSERT_TRUE(cert_chain
);
107 std::vector
<std::string
> pem_encoded_chain
;
108 cert_chain
->GetPEMEncodedChain(&pem_encoded_chain
);
109 EXPECT_EQ(pem_encoded_chain
.size(), cert_list
->GetSize());
111 for (size_t i
= 0; i
< pem_encoded_chain
.size(); i
++) {
112 std::string list_cert
;
113 ASSERT_TRUE(cert_list
->GetString(i
, &list_cert
));
114 EXPECT_EQ(pem_encoded_chain
[i
], list_cert
);
118 void CheckHPKPReport(
119 const std::string
& report
,
120 const HostPortPair
& host_port_pair
,
121 bool include_subdomains
,
122 const std::string
& noted_hostname
,
123 const scoped_refptr
<X509Certificate
>& served_certificate_chain
,
124 const scoped_refptr
<X509Certificate
>& validated_certificate_chain
,
125 const HashValueVector
& known_pins
) {
126 scoped_ptr
<base::Value
> value(base::JSONReader::Read(report
));
128 ASSERT_TRUE(value
->IsType(base::Value::TYPE_DICTIONARY
));
130 base::DictionaryValue
* report_dict
;
131 ASSERT_TRUE(value
->GetAsDictionary(&report_dict
));
133 std::string report_hostname
;
134 EXPECT_TRUE(report_dict
->GetString("hostname", &report_hostname
));
135 EXPECT_EQ(host_port_pair
.host(), report_hostname
);
138 EXPECT_TRUE(report_dict
->GetInteger("port", &report_port
));
139 EXPECT_EQ(host_port_pair
.port(), report_port
);
141 bool report_include_subdomains
;
142 EXPECT_TRUE(report_dict
->GetBoolean("include-subdomains",
143 &report_include_subdomains
));
144 EXPECT_EQ(include_subdomains
, report_include_subdomains
);
146 std::string report_noted_hostname
;
147 EXPECT_TRUE(report_dict
->GetString("noted-hostname", &report_noted_hostname
));
148 EXPECT_EQ(noted_hostname
, report_noted_hostname
);
150 // TODO(estark): check times in RFC3339 format.
152 std::string report_expiration
;
154 report_dict
->GetString("effective-expiration-date", &report_expiration
));
155 EXPECT_FALSE(report_expiration
.empty());
157 std::string report_date
;
158 EXPECT_TRUE(report_dict
->GetString("date-time", &report_date
));
159 EXPECT_FALSE(report_date
.empty());
161 base::ListValue
* report_served_certificate_chain
;
162 EXPECT_TRUE(report_dict
->GetList("served-certificate-chain",
163 &report_served_certificate_chain
));
164 ASSERT_NO_FATAL_FAILURE(CompareCertificateChainWithList(
165 served_certificate_chain
, report_served_certificate_chain
));
167 base::ListValue
* report_validated_certificate_chain
;
168 EXPECT_TRUE(report_dict
->GetList("validated-certificate-chain",
169 &report_validated_certificate_chain
));
170 ASSERT_NO_FATAL_FAILURE(CompareCertificateChainWithList(
171 validated_certificate_chain
, report_validated_certificate_chain
));
176 class TransportSecurityStateTest
: public testing::Test
{
178 void SetUp() override
{
179 #if defined(USE_OPENSSL)
180 crypto::EnsureOpenSSLInit();
182 crypto::EnsureNSSInit();
186 static void DisableStaticPins(TransportSecurityState
* state
) {
187 state
->enable_static_pins_
= false;
190 static void EnableStaticPins(TransportSecurityState
* state
) {
191 state
->enable_static_pins_
= true;
194 static HashValueVector
GetSampleSPKIHashes() {
195 HashValueVector spki_hashes
;
196 HashValue
hash(HASH_VALUE_SHA256
);
197 memset(hash
.data(), 0, hash
.size());
198 spki_hashes
.push_back(hash
);
203 bool GetStaticDomainState(TransportSecurityState
* state
,
204 const std::string
& host
,
205 TransportSecurityState::STSState
* sts_result
,
206 TransportSecurityState::PKPState
* pkp_result
) {
207 return state
->GetStaticDomainState(host
, sts_result
, pkp_result
);
211 TEST_F(TransportSecurityStateTest
, DomainNameOddities
) {
212 TransportSecurityState state
;
213 const base::Time
current_time(base::Time::Now());
214 const base::Time expiry
= current_time
+ base::TimeDelta::FromSeconds(1000);
216 // DNS suffix search tests. Some DNS resolvers allow a terminal "." to
217 // indicate not perform DNS suffix searching. Ensure that regardless
218 // of how this is treated at the resolver layer, or at the URL/origin
219 // layer (that is, whether they are treated as equivalent or distinct),
220 // ensure that for policy matching, something lacking a terminal "."
221 // is equivalent to something with a terminal "."
222 EXPECT_FALSE(state
.ShouldUpgradeToSSL("example.com"));
224 state
.AddHSTS("example.com", expiry
, true /* include_subdomains */);
225 EXPECT_TRUE(state
.ShouldUpgradeToSSL("example.com"));
226 // Trailing '.' should be equivalent; it's just a resolver hint
227 EXPECT_TRUE(state
.ShouldUpgradeToSSL("example.com."));
228 // Leading '.' should be invalid
229 EXPECT_FALSE(state
.ShouldUpgradeToSSL(".example.com"));
230 // Subdomains should work regardless
231 EXPECT_TRUE(state
.ShouldUpgradeToSSL("sub.example.com"));
232 EXPECT_TRUE(state
.ShouldUpgradeToSSL("sub.example.com."));
233 // But invalid subdomains should be rejected
234 EXPECT_FALSE(state
.ShouldUpgradeToSSL("sub..example.com"));
235 EXPECT_FALSE(state
.ShouldUpgradeToSSL("sub..example.com."));
237 // Now try the inverse form
238 TransportSecurityState state2
;
239 state2
.AddHSTS("example.net.", expiry
, true /* include_subdomains */);
240 EXPECT_TRUE(state2
.ShouldUpgradeToSSL("example.net."));
241 EXPECT_TRUE(state2
.ShouldUpgradeToSSL("example.net"));
242 EXPECT_TRUE(state2
.ShouldUpgradeToSSL("sub.example.net."));
243 EXPECT_TRUE(state2
.ShouldUpgradeToSSL("sub.example.net"));
245 // Finally, test weird things
246 TransportSecurityState state3
;
247 state3
.AddHSTS("", expiry
, true /* include_subdomains */);
248 EXPECT_FALSE(state3
.ShouldUpgradeToSSL(""));
249 EXPECT_FALSE(state3
.ShouldUpgradeToSSL("."));
250 EXPECT_FALSE(state3
.ShouldUpgradeToSSL("..."));
251 // Make sure it didn't somehow apply HSTS to the world
252 EXPECT_FALSE(state3
.ShouldUpgradeToSSL("example.org"));
254 TransportSecurityState state4
;
255 state4
.AddHSTS(".", expiry
, true /* include_subdomains */);
256 EXPECT_FALSE(state4
.ShouldUpgradeToSSL(""));
257 EXPECT_FALSE(state4
.ShouldUpgradeToSSL("."));
258 EXPECT_FALSE(state4
.ShouldUpgradeToSSL("..."));
259 EXPECT_FALSE(state4
.ShouldUpgradeToSSL("example.org"));
261 // Now do the same for preloaded entries
262 TransportSecurityState state5
;
263 EXPECT_TRUE(state5
.ShouldUpgradeToSSL("accounts.google.com"));
264 EXPECT_TRUE(state5
.ShouldUpgradeToSSL("accounts.google.com."));
265 EXPECT_FALSE(state5
.ShouldUpgradeToSSL("accounts..google.com"));
266 EXPECT_FALSE(state5
.ShouldUpgradeToSSL("accounts..google.com."));
269 TEST_F(TransportSecurityStateTest
, SimpleMatches
) {
270 TransportSecurityState state
;
271 const base::Time
current_time(base::Time::Now());
272 const base::Time expiry
= current_time
+ base::TimeDelta::FromSeconds(1000);
274 EXPECT_FALSE(state
.ShouldUpgradeToSSL("example.com"));
275 bool include_subdomains
= false;
276 state
.AddHSTS("example.com", expiry
, include_subdomains
);
277 EXPECT_TRUE(state
.ShouldUpgradeToSSL("example.com"));
278 EXPECT_TRUE(state
.ShouldSSLErrorsBeFatal("example.com"));
279 EXPECT_FALSE(state
.ShouldUpgradeToSSL("foo.example.com"));
280 EXPECT_FALSE(state
.ShouldSSLErrorsBeFatal("foo.example.com"));
283 TEST_F(TransportSecurityStateTest
, MatchesCase1
) {
284 TransportSecurityState state
;
285 const base::Time
current_time(base::Time::Now());
286 const base::Time expiry
= current_time
+ base::TimeDelta::FromSeconds(1000);
288 EXPECT_FALSE(state
.ShouldUpgradeToSSL("example.com"));
289 bool include_subdomains
= false;
290 state
.AddHSTS("EXample.coM", expiry
, include_subdomains
);
291 EXPECT_TRUE(state
.ShouldUpgradeToSSL("example.com"));
294 TEST_F(TransportSecurityStateTest
, Fuzz
) {
295 TransportSecurityState state
;
296 TransportSecurityState::STSState sts_state
;
297 TransportSecurityState::PKPState pkp_state
;
299 EnableStaticPins(&state
);
301 for (size_t i
= 0; i
< 128; i
++) {
302 std::string hostname
;
305 if (base::RandInt(0, 16) == 7) {
308 if (i
> 0 && base::RandInt(0, 7) == 7) {
309 hostname
.append(1, '.');
311 hostname
.append(1, 'a' + base::RandInt(0, 25));
313 state
.GetStaticDomainState(hostname
, &sts_state
, &pkp_state
);
317 TEST_F(TransportSecurityStateTest
, MatchesCase2
) {
318 TransportSecurityState state
;
319 const base::Time
current_time(base::Time::Now());
320 const base::Time expiry
= current_time
+ base::TimeDelta::FromSeconds(1000);
322 // Check dynamic entries
323 EXPECT_FALSE(state
.ShouldUpgradeToSSL("EXample.coM"));
324 bool include_subdomains
= false;
325 state
.AddHSTS("example.com", expiry
, include_subdomains
);
326 EXPECT_TRUE(state
.ShouldUpgradeToSSL("EXample.coM"));
328 // Check static entries
329 EXPECT_TRUE(state
.ShouldUpgradeToSSL("AccounTs.GooGle.com"));
330 EXPECT_TRUE(state
.ShouldUpgradeToSSL("mail.google.COM"));
333 TEST_F(TransportSecurityStateTest
, SubdomainMatches
) {
334 TransportSecurityState state
;
335 const base::Time
current_time(base::Time::Now());
336 const base::Time expiry
= current_time
+ base::TimeDelta::FromSeconds(1000);
338 EXPECT_FALSE(state
.ShouldUpgradeToSSL("example.test"));
339 bool include_subdomains
= true;
340 state
.AddHSTS("example.test", expiry
, include_subdomains
);
341 EXPECT_TRUE(state
.ShouldUpgradeToSSL("example.test"));
342 EXPECT_TRUE(state
.ShouldUpgradeToSSL("foo.example.test"));
343 EXPECT_TRUE(state
.ShouldUpgradeToSSL("foo.bar.example.test"));
344 EXPECT_TRUE(state
.ShouldUpgradeToSSL("foo.bar.baz.example.test"));
345 EXPECT_FALSE(state
.ShouldUpgradeToSSL("test"));
346 EXPECT_FALSE(state
.ShouldUpgradeToSSL("notexample.test"));
349 // Tests that a more-specific HSTS or HPKP rule overrides a less-specific rule
350 // with it, regardless of the includeSubDomains bit. This is a regression test
351 // for https://crbug.com/469957.
352 TEST_F(TransportSecurityStateTest
, SubdomainCarveout
) {
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);
357 const base::Time older
= current_time
- base::TimeDelta::FromSeconds(1000);
359 state
.AddHSTS("example1.test", expiry
, true);
360 state
.AddHSTS("foo.example1.test", expiry
, false);
362 state
.AddHPKP("example2.test", expiry
, true, GetSampleSPKIHashes(),
364 state
.AddHPKP("foo.example2.test", expiry
, false, GetSampleSPKIHashes(),
367 EXPECT_TRUE(state
.ShouldUpgradeToSSL("example1.test"));
368 EXPECT_TRUE(state
.ShouldUpgradeToSSL("foo.example1.test"));
370 // The foo.example1.test rule overrides the example1.test rule, so
371 // bar.foo.example1.test has no HSTS state.
372 EXPECT_FALSE(state
.ShouldUpgradeToSSL("bar.foo.example1.test"));
373 EXPECT_FALSE(state
.ShouldSSLErrorsBeFatal("bar.foo.example1.test"));
375 EXPECT_TRUE(state
.HasPublicKeyPins("example2.test"));
376 EXPECT_TRUE(state
.HasPublicKeyPins("foo.example2.test"));
378 // The foo.example2.test rule overrides the example1.test rule, so
379 // bar.foo.example2.test has no HPKP state.
380 EXPECT_FALSE(state
.HasPublicKeyPins("bar.foo.example2.test"));
381 EXPECT_FALSE(state
.ShouldSSLErrorsBeFatal("bar.foo.example2.test"));
383 // Expire the foo.example*.test rules.
384 state
.AddHSTS("foo.example1.test", older
, false);
385 state
.AddHPKP("foo.example2.test", older
, false, GetSampleSPKIHashes(),
388 // Now the base example*.test rules apply to bar.foo.example*.test.
389 EXPECT_TRUE(state
.ShouldUpgradeToSSL("bar.foo.example1.test"));
390 EXPECT_TRUE(state
.ShouldSSLErrorsBeFatal("bar.foo.example1.test"));
391 EXPECT_TRUE(state
.HasPublicKeyPins("bar.foo.example2.test"));
392 EXPECT_TRUE(state
.ShouldSSLErrorsBeFatal("bar.foo.example2.test"));
395 TEST_F(TransportSecurityStateTest
, FatalSSLErrors
) {
396 const GURL
report_uri(kReportUri
);
397 TransportSecurityState state
;
398 const base::Time
current_time(base::Time::Now());
399 const base::Time expiry
= current_time
+ base::TimeDelta::FromSeconds(1000);
401 state
.AddHSTS("example1.test", expiry
, false);
402 state
.AddHPKP("example2.test", expiry
, false, GetSampleSPKIHashes(),
405 // The presense of either HSTS or HPKP is enough to make SSL errors fatal.
406 EXPECT_TRUE(state
.ShouldSSLErrorsBeFatal("example1.test"));
407 EXPECT_TRUE(state
.ShouldSSLErrorsBeFatal("example2.test"));
410 // Tests that HPKP and HSTS state both expire. Also tests that expired entries
412 TEST_F(TransportSecurityStateTest
, Expiration
) {
413 const GURL
report_uri(kReportUri
);
414 TransportSecurityState state
;
415 const base::Time
current_time(base::Time::Now());
416 const base::Time expiry
= current_time
+ base::TimeDelta::FromSeconds(1000);
417 const base::Time older
= current_time
- base::TimeDelta::FromSeconds(1000);
419 // Note: this test assumes that inserting an entry with an expiration time in
420 // the past works and is pruned on query.
421 state
.AddHSTS("example1.test", older
, false);
422 EXPECT_TRUE(TransportSecurityState::STSStateIterator(state
).HasNext());
423 EXPECT_FALSE(state
.ShouldUpgradeToSSL("example1.test"));
424 // Querying |state| for a domain should flush out expired entries.
425 EXPECT_FALSE(TransportSecurityState::STSStateIterator(state
).HasNext());
427 state
.AddHPKP("example1.test", older
, false, GetSampleSPKIHashes(),
429 EXPECT_TRUE(TransportSecurityState::PKPStateIterator(state
).HasNext());
430 EXPECT_FALSE(state
.HasPublicKeyPins("example1.test"));
431 // Querying |state| for a domain should flush out expired entries.
432 EXPECT_FALSE(TransportSecurityState::PKPStateIterator(state
).HasNext());
434 state
.AddHSTS("example1.test", older
, false);
435 state
.AddHPKP("example1.test", older
, false, GetSampleSPKIHashes(),
437 EXPECT_TRUE(TransportSecurityState::STSStateIterator(state
).HasNext());
438 EXPECT_TRUE(TransportSecurityState::PKPStateIterator(state
).HasNext());
439 EXPECT_FALSE(state
.ShouldSSLErrorsBeFatal("example1.test"));
440 // Querying |state| for a domain should flush out expired entries.
441 EXPECT_FALSE(TransportSecurityState::STSStateIterator(state
).HasNext());
442 EXPECT_FALSE(TransportSecurityState::PKPStateIterator(state
).HasNext());
444 // Test that HSTS can outlive HPKP.
445 state
.AddHSTS("example1.test", expiry
, false);
446 state
.AddHPKP("example1.test", older
, false, GetSampleSPKIHashes(),
448 EXPECT_TRUE(state
.ShouldUpgradeToSSL("example1.test"));
449 EXPECT_FALSE(state
.HasPublicKeyPins("example1.test"));
451 // Test that HPKP can outlive HSTS.
452 state
.AddHSTS("example2.test", older
, false);
453 state
.AddHPKP("example2.test", expiry
, false, GetSampleSPKIHashes(),
455 EXPECT_FALSE(state
.ShouldUpgradeToSSL("example2.test"));
456 EXPECT_TRUE(state
.HasPublicKeyPins("example2.test"));
459 TEST_F(TransportSecurityStateTest
, InvalidDomains
) {
460 TransportSecurityState state
;
461 const base::Time
current_time(base::Time::Now());
462 const base::Time expiry
= current_time
+ base::TimeDelta::FromSeconds(1000);
464 EXPECT_FALSE(state
.ShouldUpgradeToSSL("example.test"));
465 bool include_subdomains
= true;
466 state
.AddHSTS("example.test", expiry
, include_subdomains
);
467 EXPECT_TRUE(state
.ShouldUpgradeToSSL("www-.foo.example.test"));
468 EXPECT_TRUE(state
.ShouldUpgradeToSSL("2\x01.foo.example.test"));
471 // Tests that HPKP and HSTS state are queried independently for subdomain
473 TEST_F(TransportSecurityStateTest
, IndependentSubdomain
) {
474 const GURL
report_uri(kReportUri
);
475 TransportSecurityState state
;
476 const base::Time
current_time(base::Time::Now());
477 const base::Time expiry
= current_time
+ base::TimeDelta::FromSeconds(1000);
479 state
.AddHSTS("example1.test", expiry
, true);
480 state
.AddHPKP("example1.test", expiry
, false, GetSampleSPKIHashes(),
483 state
.AddHSTS("example2.test", expiry
, false);
484 state
.AddHPKP("example2.test", expiry
, true, GetSampleSPKIHashes(),
487 EXPECT_TRUE(state
.ShouldUpgradeToSSL("foo.example1.test"));
488 EXPECT_FALSE(state
.HasPublicKeyPins("foo.example1.test"));
489 EXPECT_FALSE(state
.ShouldUpgradeToSSL("foo.example2.test"));
490 EXPECT_TRUE(state
.HasPublicKeyPins("foo.example2.test"));
493 // Tests that HPKP and HSTS state are inserted and overridden independently.
494 TEST_F(TransportSecurityStateTest
, IndependentInsertion
) {
495 const GURL
report_uri(kReportUri
);
496 TransportSecurityState state
;
497 const base::Time
current_time(base::Time::Now());
498 const base::Time expiry
= current_time
+ base::TimeDelta::FromSeconds(1000);
500 // Place an includeSubdomains HSTS entry below a normal HPKP entry.
501 state
.AddHSTS("example1.test", expiry
, true);
502 state
.AddHPKP("foo.example1.test", expiry
, false, GetSampleSPKIHashes(),
505 EXPECT_TRUE(state
.ShouldUpgradeToSSL("foo.example1.test"));
506 EXPECT_TRUE(state
.HasPublicKeyPins("foo.example1.test"));
507 EXPECT_TRUE(state
.ShouldUpgradeToSSL("example1.test"));
508 EXPECT_FALSE(state
.HasPublicKeyPins("example1.test"));
510 // Drop the includeSubdomains from the HSTS entry.
511 state
.AddHSTS("example1.test", expiry
, false);
513 EXPECT_FALSE(state
.ShouldUpgradeToSSL("foo.example1.test"));
514 EXPECT_TRUE(state
.HasPublicKeyPins("foo.example1.test"));
516 // Place an includeSubdomains HPKP entry below a normal HSTS entry.
517 state
.AddHSTS("foo.example2.test", expiry
, false);
518 state
.AddHPKP("example2.test", expiry
, true, GetSampleSPKIHashes(),
521 EXPECT_TRUE(state
.ShouldUpgradeToSSL("foo.example2.test"));
522 EXPECT_TRUE(state
.HasPublicKeyPins("foo.example2.test"));
524 // Drop the includeSubdomains from the HSTS entry.
525 state
.AddHPKP("example2.test", expiry
, false, GetSampleSPKIHashes(),
528 EXPECT_TRUE(state
.ShouldUpgradeToSSL("foo.example2.test"));
529 EXPECT_FALSE(state
.HasPublicKeyPins("foo.example2.test"));
532 // Tests that GetDynamic[PKP|STS]State returns the correct data and that the
533 // states are not mixed together.
534 TEST_F(TransportSecurityStateTest
, DynamicDomainState
) {
535 const GURL
report_uri(kReportUri
);
536 TransportSecurityState state
;
537 const base::Time
current_time(base::Time::Now());
538 const base::Time expiry1
= current_time
+ base::TimeDelta::FromSeconds(1000);
539 const base::Time expiry2
= current_time
+ base::TimeDelta::FromSeconds(2000);
541 state
.AddHSTS("example.com", expiry1
, true);
542 state
.AddHPKP("foo.example.com", expiry2
, false, GetSampleSPKIHashes(),
545 TransportSecurityState::STSState sts_state
;
546 TransportSecurityState::PKPState pkp_state
;
547 ASSERT_TRUE(state
.GetDynamicSTSState("foo.example.com", &sts_state
));
548 ASSERT_TRUE(state
.GetDynamicPKPState("foo.example.com", &pkp_state
));
549 EXPECT_TRUE(sts_state
.ShouldUpgradeToSSL());
550 EXPECT_TRUE(pkp_state
.HasPublicKeyPins());
551 EXPECT_TRUE(sts_state
.include_subdomains
);
552 EXPECT_FALSE(pkp_state
.include_subdomains
);
553 EXPECT_EQ(expiry1
, sts_state
.expiry
);
554 EXPECT_EQ(expiry2
, pkp_state
.expiry
);
555 EXPECT_EQ("example.com", sts_state
.domain
);
556 EXPECT_EQ("foo.example.com", pkp_state
.domain
);
559 // Tests that new pins always override previous pins. This should be true for
560 // both pins at the same domain or includeSubdomains pins at a parent domain.
561 TEST_F(TransportSecurityStateTest
, NewPinsOverride
) {
562 const GURL
report_uri(kReportUri
);
563 TransportSecurityState state
;
564 TransportSecurityState::PKPState pkp_state
;
565 const base::Time
current_time(base::Time::Now());
566 const base::Time expiry
= current_time
+ base::TimeDelta::FromSeconds(1000);
567 HashValue
hash1(HASH_VALUE_SHA256
);
568 memset(hash1
.data(), 0x01, hash1
.size());
569 HashValue
hash2(HASH_VALUE_SHA256
);
570 memset(hash2
.data(), 0x02, hash1
.size());
571 HashValue
hash3(HASH_VALUE_SHA256
);
572 memset(hash3
.data(), 0x03, hash1
.size());
574 state
.AddHPKP("example.com", expiry
, true, HashValueVector(1, hash1
),
577 ASSERT_TRUE(state
.GetDynamicPKPState("foo.example.com", &pkp_state
));
578 ASSERT_EQ(1u, pkp_state
.spki_hashes
.size());
579 EXPECT_TRUE(pkp_state
.spki_hashes
[0].Equals(hash1
));
581 state
.AddHPKP("foo.example.com", expiry
, false, HashValueVector(1, hash2
),
584 ASSERT_TRUE(state
.GetDynamicPKPState("foo.example.com", &pkp_state
));
585 ASSERT_EQ(1u, pkp_state
.spki_hashes
.size());
586 EXPECT_TRUE(pkp_state
.spki_hashes
[0].Equals(hash2
));
588 state
.AddHPKP("foo.example.com", expiry
, false, HashValueVector(1, hash3
),
591 ASSERT_TRUE(state
.GetDynamicPKPState("foo.example.com", &pkp_state
));
592 ASSERT_EQ(1u, pkp_state
.spki_hashes
.size());
593 EXPECT_TRUE(pkp_state
.spki_hashes
[0].Equals(hash3
));
596 TEST_F(TransportSecurityStateTest
, DeleteAllDynamicDataSince
) {
597 TransportSecurityState state
;
598 const base::Time
current_time(base::Time::Now());
599 const base::Time expiry
= current_time
+ base::TimeDelta::FromSeconds(1000);
600 const base::Time older
= current_time
- base::TimeDelta::FromSeconds(1000);
602 EXPECT_FALSE(state
.ShouldUpgradeToSSL("example.com"));
603 EXPECT_FALSE(state
.HasPublicKeyPins("example.com"));
604 bool include_subdomains
= false;
605 state
.AddHSTS("example.com", expiry
, include_subdomains
);
606 state
.AddHPKP("example.com", expiry
, include_subdomains
,
607 GetSampleSPKIHashes(), GURL());
609 state
.DeleteAllDynamicDataSince(expiry
);
610 EXPECT_TRUE(state
.ShouldUpgradeToSSL("example.com"));
611 EXPECT_TRUE(state
.HasPublicKeyPins("example.com"));
612 state
.DeleteAllDynamicDataSince(older
);
613 EXPECT_FALSE(state
.ShouldUpgradeToSSL("example.com"));
614 EXPECT_FALSE(state
.HasPublicKeyPins("example.com"));
616 // STS and PKP data in |state| should be empty now.
617 EXPECT_FALSE(TransportSecurityState::STSStateIterator(state
).HasNext());
618 EXPECT_FALSE(TransportSecurityState::PKPStateIterator(state
).HasNext());
621 TEST_F(TransportSecurityStateTest
, DeleteDynamicDataForHost
) {
622 TransportSecurityState state
;
623 const base::Time
current_time(base::Time::Now());
624 const base::Time expiry
= current_time
+ base::TimeDelta::FromSeconds(1000);
625 bool include_subdomains
= false;
627 state
.AddHSTS("example1.test", expiry
, include_subdomains
);
628 state
.AddHPKP("example1.test", expiry
, include_subdomains
,
629 GetSampleSPKIHashes(), GURL());
631 EXPECT_TRUE(state
.ShouldUpgradeToSSL("example1.test"));
632 EXPECT_FALSE(state
.ShouldUpgradeToSSL("example2.test"));
633 EXPECT_TRUE(state
.HasPublicKeyPins("example1.test"));
634 EXPECT_FALSE(state
.HasPublicKeyPins("example2.test"));
635 EXPECT_TRUE(state
.DeleteDynamicDataForHost("example1.test"));
636 EXPECT_FALSE(state
.ShouldUpgradeToSSL("example1.test"));
637 EXPECT_FALSE(state
.HasPublicKeyPins("example1.test"));
640 TEST_F(TransportSecurityStateTest
, EnableStaticPins
) {
641 TransportSecurityState state
;
642 TransportSecurityState::STSState sts_state
;
643 TransportSecurityState::PKPState pkp_state
;
645 EnableStaticPins(&state
);
648 state
.GetStaticDomainState("chrome.google.com", &sts_state
, &pkp_state
));
649 EXPECT_FALSE(pkp_state
.spki_hashes
.empty());
652 TEST_F(TransportSecurityStateTest
, DisableStaticPins
) {
653 TransportSecurityState state
;
654 TransportSecurityState::STSState sts_state
;
655 TransportSecurityState::PKPState pkp_state
;
657 DisableStaticPins(&state
);
659 state
.GetStaticDomainState("chrome.google.com", &sts_state
, &pkp_state
));
660 EXPECT_TRUE(pkp_state
.spki_hashes
.empty());
663 TEST_F(TransportSecurityStateTest
, IsPreloaded
) {
664 const std::string paypal
= "paypal.com";
665 const std::string www_paypal
= "www.paypal.com";
666 const std::string foo_paypal
= "foo.paypal.com";
667 const std::string a_www_paypal
= "a.www.paypal.com";
668 const std::string abc_paypal
= "a.b.c.paypal.com";
669 const std::string example
= "example.com";
670 const std::string aypal
= "aypal.com";
671 const std::string google
= "google";
672 const std::string www_google
= "www.google";
674 TransportSecurityState state
;
675 TransportSecurityState::STSState sts_state
;
676 TransportSecurityState::PKPState pkp_state
;
678 EXPECT_TRUE(GetStaticDomainState(&state
, paypal
, &sts_state
, &pkp_state
));
679 EXPECT_TRUE(GetStaticDomainState(&state
, www_paypal
, &sts_state
, &pkp_state
));
680 EXPECT_FALSE(sts_state
.include_subdomains
);
681 EXPECT_TRUE(GetStaticDomainState(&state
, google
, &sts_state
, &pkp_state
));
682 EXPECT_TRUE(GetStaticDomainState(&state
, www_google
, &sts_state
, &pkp_state
));
684 GetStaticDomainState(&state
, a_www_paypal
, &sts_state
, &pkp_state
));
686 GetStaticDomainState(&state
, abc_paypal
, &sts_state
, &pkp_state
));
687 EXPECT_FALSE(GetStaticDomainState(&state
, example
, &sts_state
, &pkp_state
));
688 EXPECT_FALSE(GetStaticDomainState(&state
, aypal
, &sts_state
, &pkp_state
));
691 TEST_F(TransportSecurityStateTest
, PreloadedDomainSet
) {
692 TransportSecurityState state
;
693 TransportSecurityState::STSState sts_state
;
694 TransportSecurityState::PKPState pkp_state
;
696 // The domain wasn't being set, leading to a blank string in the
697 // chrome://net-internals/#hsts UI. So test that.
699 state
.GetStaticDomainState("market.android.com", &sts_state
, &pkp_state
));
700 EXPECT_EQ(sts_state
.domain
, "market.android.com");
701 EXPECT_EQ(pkp_state
.domain
, "market.android.com");
702 EXPECT_TRUE(state
.GetStaticDomainState("sub.market.android.com", &sts_state
,
704 EXPECT_EQ(sts_state
.domain
, "market.android.com");
705 EXPECT_EQ(pkp_state
.domain
, "market.android.com");
708 static bool StaticShouldRedirect(const char* hostname
) {
709 TransportSecurityState state
;
710 TransportSecurityState::STSState sts_state
;
711 TransportSecurityState::PKPState pkp_state
;
712 return state
.GetStaticDomainState(hostname
, &sts_state
, &pkp_state
) &&
713 sts_state
.ShouldUpgradeToSSL();
716 static bool HasStaticState(const char* hostname
) {
717 TransportSecurityState state
;
718 TransportSecurityState::STSState sts_state
;
719 TransportSecurityState::PKPState pkp_state
;
720 return state
.GetStaticDomainState(hostname
, &sts_state
, &pkp_state
);
723 static bool HasStaticPublicKeyPins(const char* hostname
) {
724 TransportSecurityState state
;
725 TransportSecurityStateTest::EnableStaticPins(&state
);
726 TransportSecurityState::STSState sts_state
;
727 TransportSecurityState::PKPState pkp_state
;
728 if (!state
.GetStaticDomainState(hostname
, &sts_state
, &pkp_state
))
731 return pkp_state
.HasPublicKeyPins();
734 static bool OnlyPinningInStaticState(const char* hostname
) {
735 TransportSecurityState state
;
736 TransportSecurityStateTest::EnableStaticPins(&state
);
737 TransportSecurityState::STSState sts_state
;
738 TransportSecurityState::PKPState pkp_state
;
739 if (!state
.GetStaticDomainState(hostname
, &sts_state
, &pkp_state
))
742 return (pkp_state
.spki_hashes
.size() > 0 ||
743 pkp_state
.bad_spki_hashes
.size() > 0) &&
744 !sts_state
.ShouldUpgradeToSSL();
747 TEST_F(TransportSecurityStateTest
, Preloaded
) {
748 TransportSecurityState state
;
749 TransportSecurityState::STSState sts_state
;
750 TransportSecurityState::PKPState pkp_state
;
752 // We do more extensive checks for the first domain.
754 state
.GetStaticDomainState("www.paypal.com", &sts_state
, &pkp_state
));
755 EXPECT_EQ(sts_state
.upgrade_mode
,
756 TransportSecurityState::STSState::MODE_FORCE_HTTPS
);
757 EXPECT_FALSE(sts_state
.include_subdomains
);
758 EXPECT_FALSE(pkp_state
.include_subdomains
);
760 EXPECT_TRUE(HasStaticState("paypal.com"));
761 EXPECT_FALSE(HasStaticState("www2.paypal.com"));
765 EXPECT_TRUE(StaticShouldRedirect("chrome.google.com"));
766 EXPECT_TRUE(StaticShouldRedirect("checkout.google.com"));
767 EXPECT_TRUE(StaticShouldRedirect("wallet.google.com"));
768 EXPECT_TRUE(StaticShouldRedirect("docs.google.com"));
769 EXPECT_TRUE(StaticShouldRedirect("sites.google.com"));
770 EXPECT_TRUE(StaticShouldRedirect("drive.google.com"));
771 EXPECT_TRUE(StaticShouldRedirect("spreadsheets.google.com"));
772 EXPECT_TRUE(StaticShouldRedirect("appengine.google.com"));
773 EXPECT_TRUE(StaticShouldRedirect("market.android.com"));
774 EXPECT_TRUE(StaticShouldRedirect("encrypted.google.com"));
775 EXPECT_TRUE(StaticShouldRedirect("accounts.google.com"));
776 EXPECT_TRUE(StaticShouldRedirect("profiles.google.com"));
777 EXPECT_TRUE(StaticShouldRedirect("mail.google.com"));
778 EXPECT_TRUE(StaticShouldRedirect("chatenabled.mail.google.com"));
779 EXPECT_TRUE(StaticShouldRedirect("talkgadget.google.com"));
780 EXPECT_TRUE(StaticShouldRedirect("hostedtalkgadget.google.com"));
781 EXPECT_TRUE(StaticShouldRedirect("talk.google.com"));
782 EXPECT_TRUE(StaticShouldRedirect("plus.google.com"));
783 EXPECT_TRUE(StaticShouldRedirect("groups.google.com"));
784 EXPECT_TRUE(StaticShouldRedirect("apis.google.com"));
785 EXPECT_FALSE(StaticShouldRedirect("chart.apis.google.com"));
786 EXPECT_TRUE(StaticShouldRedirect("ssl.google-analytics.com"));
787 EXPECT_TRUE(StaticShouldRedirect("google"));
788 EXPECT_TRUE(StaticShouldRedirect("foo.google"));
789 EXPECT_TRUE(StaticShouldRedirect("gmail.com"));
790 EXPECT_TRUE(StaticShouldRedirect("www.gmail.com"));
791 EXPECT_TRUE(StaticShouldRedirect("googlemail.com"));
792 EXPECT_TRUE(StaticShouldRedirect("www.googlemail.com"));
793 EXPECT_TRUE(StaticShouldRedirect("googleplex.com"));
794 EXPECT_TRUE(StaticShouldRedirect("www.googleplex.com"));
796 // These domains used to be only HSTS when SNI was available.
797 EXPECT_TRUE(state
.GetStaticDomainState("gmail.com", &sts_state
, &pkp_state
));
799 state
.GetStaticDomainState("www.gmail.com", &sts_state
, &pkp_state
));
801 state
.GetStaticDomainState("googlemail.com", &sts_state
, &pkp_state
));
803 state
.GetStaticDomainState("www.googlemail.com", &sts_state
, &pkp_state
));
807 EXPECT_TRUE(StaticShouldRedirect("aladdinschools.appspot.com"));
809 EXPECT_TRUE(StaticShouldRedirect("ottospora.nl"));
810 EXPECT_TRUE(StaticShouldRedirect("www.ottospora.nl"));
812 EXPECT_TRUE(StaticShouldRedirect("www.paycheckrecords.com"));
814 EXPECT_TRUE(StaticShouldRedirect("lastpass.com"));
815 EXPECT_TRUE(StaticShouldRedirect("www.lastpass.com"));
816 EXPECT_FALSE(HasStaticState("blog.lastpass.com"));
818 EXPECT_TRUE(StaticShouldRedirect("keyerror.com"));
819 EXPECT_TRUE(StaticShouldRedirect("www.keyerror.com"));
821 EXPECT_TRUE(StaticShouldRedirect("entropia.de"));
822 EXPECT_TRUE(StaticShouldRedirect("www.entropia.de"));
823 EXPECT_FALSE(HasStaticState("foo.entropia.de"));
825 EXPECT_TRUE(StaticShouldRedirect("www.elanex.biz"));
826 EXPECT_FALSE(HasStaticState("elanex.biz"));
827 EXPECT_FALSE(HasStaticState("foo.elanex.biz"));
829 EXPECT_TRUE(StaticShouldRedirect("sunshinepress.org"));
830 EXPECT_TRUE(StaticShouldRedirect("www.sunshinepress.org"));
831 EXPECT_TRUE(StaticShouldRedirect("a.b.sunshinepress.org"));
833 EXPECT_TRUE(StaticShouldRedirect("www.noisebridge.net"));
834 EXPECT_FALSE(HasStaticState("noisebridge.net"));
835 EXPECT_FALSE(HasStaticState("foo.noisebridge.net"));
837 EXPECT_TRUE(StaticShouldRedirect("neg9.org"));
838 EXPECT_FALSE(HasStaticState("www.neg9.org"));
840 EXPECT_TRUE(StaticShouldRedirect("riseup.net"));
841 EXPECT_TRUE(StaticShouldRedirect("foo.riseup.net"));
843 EXPECT_TRUE(StaticShouldRedirect("factor.cc"));
844 EXPECT_FALSE(HasStaticState("www.factor.cc"));
846 EXPECT_TRUE(StaticShouldRedirect("members.mayfirst.org"));
847 EXPECT_TRUE(StaticShouldRedirect("support.mayfirst.org"));
848 EXPECT_TRUE(StaticShouldRedirect("id.mayfirst.org"));
849 EXPECT_TRUE(StaticShouldRedirect("lists.mayfirst.org"));
850 EXPECT_FALSE(HasStaticState("www.mayfirst.org"));
852 EXPECT_TRUE(StaticShouldRedirect("romab.com"));
853 EXPECT_TRUE(StaticShouldRedirect("www.romab.com"));
854 EXPECT_TRUE(StaticShouldRedirect("foo.romab.com"));
856 EXPECT_TRUE(StaticShouldRedirect("logentries.com"));
857 EXPECT_TRUE(StaticShouldRedirect("www.logentries.com"));
858 EXPECT_FALSE(HasStaticState("foo.logentries.com"));
860 EXPECT_TRUE(StaticShouldRedirect("stripe.com"));
861 EXPECT_TRUE(StaticShouldRedirect("foo.stripe.com"));
863 EXPECT_TRUE(StaticShouldRedirect("cloudsecurityalliance.org"));
864 EXPECT_TRUE(StaticShouldRedirect("foo.cloudsecurityalliance.org"));
866 EXPECT_TRUE(StaticShouldRedirect("login.sapo.pt"));
867 EXPECT_TRUE(StaticShouldRedirect("foo.login.sapo.pt"));
869 EXPECT_TRUE(StaticShouldRedirect("mattmccutchen.net"));
870 EXPECT_TRUE(StaticShouldRedirect("foo.mattmccutchen.net"));
872 EXPECT_TRUE(StaticShouldRedirect("betnet.fr"));
873 EXPECT_TRUE(StaticShouldRedirect("foo.betnet.fr"));
875 EXPECT_TRUE(StaticShouldRedirect("uprotect.it"));
876 EXPECT_TRUE(StaticShouldRedirect("foo.uprotect.it"));
878 EXPECT_TRUE(StaticShouldRedirect("squareup.com"));
879 EXPECT_FALSE(HasStaticState("foo.squareup.com"));
881 EXPECT_TRUE(StaticShouldRedirect("cert.se"));
882 EXPECT_TRUE(StaticShouldRedirect("foo.cert.se"));
884 EXPECT_TRUE(StaticShouldRedirect("crypto.is"));
885 EXPECT_TRUE(StaticShouldRedirect("foo.crypto.is"));
887 EXPECT_TRUE(StaticShouldRedirect("simon.butcher.name"));
888 EXPECT_TRUE(StaticShouldRedirect("foo.simon.butcher.name"));
890 EXPECT_TRUE(StaticShouldRedirect("linx.net"));
891 EXPECT_TRUE(StaticShouldRedirect("foo.linx.net"));
893 EXPECT_TRUE(StaticShouldRedirect("dropcam.com"));
894 EXPECT_TRUE(StaticShouldRedirect("www.dropcam.com"));
895 EXPECT_FALSE(HasStaticState("foo.dropcam.com"));
897 EXPECT_TRUE(StaticShouldRedirect("ebanking.indovinabank.com.vn"));
898 EXPECT_TRUE(StaticShouldRedirect("foo.ebanking.indovinabank.com.vn"));
900 EXPECT_TRUE(StaticShouldRedirect("epoxate.com"));
901 EXPECT_FALSE(HasStaticState("foo.epoxate.com"));
903 EXPECT_FALSE(HasStaticState("foo.torproject.org"));
905 EXPECT_TRUE(StaticShouldRedirect("www.moneybookers.com"));
906 EXPECT_FALSE(HasStaticState("moneybookers.com"));
908 EXPECT_TRUE(StaticShouldRedirect("ledgerscope.net"));
909 EXPECT_TRUE(StaticShouldRedirect("www.ledgerscope.net"));
910 EXPECT_FALSE(HasStaticState("status.ledgerscope.net"));
912 EXPECT_TRUE(StaticShouldRedirect("foo.app.recurly.com"));
913 EXPECT_TRUE(StaticShouldRedirect("foo.api.recurly.com"));
915 EXPECT_TRUE(StaticShouldRedirect("greplin.com"));
916 EXPECT_TRUE(StaticShouldRedirect("www.greplin.com"));
917 EXPECT_FALSE(HasStaticState("foo.greplin.com"));
919 EXPECT_TRUE(StaticShouldRedirect("luneta.nearbuysystems.com"));
920 EXPECT_TRUE(StaticShouldRedirect("foo.luneta.nearbuysystems.com"));
922 EXPECT_TRUE(StaticShouldRedirect("ubertt.org"));
923 EXPECT_TRUE(StaticShouldRedirect("foo.ubertt.org"));
925 EXPECT_TRUE(StaticShouldRedirect("pixi.me"));
926 EXPECT_TRUE(StaticShouldRedirect("www.pixi.me"));
928 EXPECT_TRUE(StaticShouldRedirect("grepular.com"));
929 EXPECT_TRUE(StaticShouldRedirect("www.grepular.com"));
931 EXPECT_TRUE(StaticShouldRedirect("mydigipass.com"));
932 EXPECT_FALSE(StaticShouldRedirect("foo.mydigipass.com"));
933 EXPECT_TRUE(StaticShouldRedirect("www.mydigipass.com"));
934 EXPECT_FALSE(StaticShouldRedirect("foo.www.mydigipass.com"));
935 EXPECT_TRUE(StaticShouldRedirect("developer.mydigipass.com"));
936 EXPECT_FALSE(StaticShouldRedirect("foo.developer.mydigipass.com"));
937 EXPECT_TRUE(StaticShouldRedirect("www.developer.mydigipass.com"));
938 EXPECT_FALSE(StaticShouldRedirect("foo.www.developer.mydigipass.com"));
939 EXPECT_TRUE(StaticShouldRedirect("sandbox.mydigipass.com"));
940 EXPECT_FALSE(StaticShouldRedirect("foo.sandbox.mydigipass.com"));
941 EXPECT_TRUE(StaticShouldRedirect("www.sandbox.mydigipass.com"));
942 EXPECT_FALSE(StaticShouldRedirect("foo.www.sandbox.mydigipass.com"));
944 EXPECT_TRUE(StaticShouldRedirect("bigshinylock.minazo.net"));
945 EXPECT_TRUE(StaticShouldRedirect("foo.bigshinylock.minazo.net"));
947 EXPECT_TRUE(StaticShouldRedirect("crate.io"));
948 EXPECT_TRUE(StaticShouldRedirect("foo.crate.io"));
951 TEST_F(TransportSecurityStateTest
, PreloadedPins
) {
952 TransportSecurityState state
;
953 EnableStaticPins(&state
);
954 TransportSecurityState::STSState sts_state
;
955 TransportSecurityState::PKPState pkp_state
;
957 // We do more extensive checks for the first domain.
959 state
.GetStaticDomainState("www.paypal.com", &sts_state
, &pkp_state
));
960 EXPECT_EQ(sts_state
.upgrade_mode
,
961 TransportSecurityState::STSState::MODE_FORCE_HTTPS
);
962 EXPECT_FALSE(sts_state
.include_subdomains
);
963 EXPECT_FALSE(pkp_state
.include_subdomains
);
965 EXPECT_TRUE(OnlyPinningInStaticState("www.google.com"));
966 EXPECT_TRUE(OnlyPinningInStaticState("foo.google.com"));
967 EXPECT_TRUE(OnlyPinningInStaticState("google.com"));
968 EXPECT_TRUE(OnlyPinningInStaticState("www.youtube.com"));
969 EXPECT_TRUE(OnlyPinningInStaticState("youtube.com"));
970 EXPECT_TRUE(OnlyPinningInStaticState("i.ytimg.com"));
971 EXPECT_TRUE(OnlyPinningInStaticState("ytimg.com"));
972 EXPECT_TRUE(OnlyPinningInStaticState("googleusercontent.com"));
973 EXPECT_TRUE(OnlyPinningInStaticState("www.googleusercontent.com"));
974 EXPECT_TRUE(OnlyPinningInStaticState("www.google-analytics.com"));
975 EXPECT_TRUE(OnlyPinningInStaticState("googleapis.com"));
976 EXPECT_TRUE(OnlyPinningInStaticState("googleadservices.com"));
977 EXPECT_TRUE(OnlyPinningInStaticState("googlecode.com"));
978 EXPECT_TRUE(OnlyPinningInStaticState("appspot.com"));
979 EXPECT_TRUE(OnlyPinningInStaticState("googlesyndication.com"));
980 EXPECT_TRUE(OnlyPinningInStaticState("doubleclick.net"));
981 EXPECT_TRUE(OnlyPinningInStaticState("googlegroups.com"));
983 EXPECT_TRUE(HasStaticPublicKeyPins("torproject.org"));
984 EXPECT_TRUE(HasStaticPublicKeyPins("www.torproject.org"));
985 EXPECT_TRUE(HasStaticPublicKeyPins("check.torproject.org"));
986 EXPECT_TRUE(HasStaticPublicKeyPins("blog.torproject.org"));
987 EXPECT_FALSE(HasStaticState("foo.torproject.org"));
990 state
.GetStaticDomainState("torproject.org", &sts_state
, &pkp_state
));
991 EXPECT_FALSE(pkp_state
.spki_hashes
.empty());
993 state
.GetStaticDomainState("www.torproject.org", &sts_state
, &pkp_state
));
994 EXPECT_FALSE(pkp_state
.spki_hashes
.empty());
995 EXPECT_TRUE(state
.GetStaticDomainState("check.torproject.org", &sts_state
,
997 EXPECT_FALSE(pkp_state
.spki_hashes
.empty());
998 EXPECT_TRUE(state
.GetStaticDomainState("blog.torproject.org", &sts_state
,
1000 EXPECT_FALSE(pkp_state
.spki_hashes
.empty());
1002 EXPECT_TRUE(HasStaticPublicKeyPins("www.twitter.com"));
1004 // Check that Facebook subdomains have pinning but not HSTS.
1006 state
.GetStaticDomainState("facebook.com", &sts_state
, &pkp_state
));
1007 EXPECT_FALSE(pkp_state
.spki_hashes
.empty());
1008 EXPECT_TRUE(StaticShouldRedirect("facebook.com"));
1011 state
.GetStaticDomainState("foo.facebook.com", &sts_state
, &pkp_state
));
1014 state
.GetStaticDomainState("www.facebook.com", &sts_state
, &pkp_state
));
1015 EXPECT_FALSE(pkp_state
.spki_hashes
.empty());
1016 EXPECT_TRUE(StaticShouldRedirect("www.facebook.com"));
1018 EXPECT_TRUE(state
.GetStaticDomainState("foo.www.facebook.com", &sts_state
,
1020 EXPECT_FALSE(pkp_state
.spki_hashes
.empty());
1021 EXPECT_TRUE(StaticShouldRedirect("foo.www.facebook.com"));
1024 TEST_F(TransportSecurityStateTest
, LongNames
) {
1025 TransportSecurityState state
;
1026 const char kLongName
[] =
1027 "lookupByWaveIdHashAndWaveIdIdAndWaveIdDomainAndWaveletIdIdAnd"
1028 "WaveletIdDomainAndBlipBlipid";
1029 TransportSecurityState::STSState sts_state
;
1030 TransportSecurityState::PKPState pkp_state
;
1031 // Just checks that we don't hit a NOTREACHED.
1032 EXPECT_FALSE(state
.GetStaticDomainState(kLongName
, &sts_state
, &pkp_state
));
1033 EXPECT_FALSE(state
.GetDynamicSTSState(kLongName
, &sts_state
));
1034 EXPECT_FALSE(state
.GetDynamicPKPState(kLongName
, &pkp_state
));
1037 TEST_F(TransportSecurityStateTest
, BuiltinCertPins
) {
1038 TransportSecurityState state
;
1039 EnableStaticPins(&state
);
1040 TransportSecurityState::STSState sts_state
;
1041 TransportSecurityState::PKPState pkp_state
;
1044 state
.GetStaticDomainState("chrome.google.com", &sts_state
, &pkp_state
));
1045 EXPECT_TRUE(HasStaticPublicKeyPins("chrome.google.com"));
1047 HashValueVector hashes
;
1048 std::string failure_log
;
1049 // Checks that a built-in list does exist.
1050 EXPECT_FALSE(pkp_state
.CheckPublicKeyPins(hashes
, &failure_log
));
1051 EXPECT_FALSE(HasStaticPublicKeyPins("www.paypal.com"));
1053 EXPECT_TRUE(HasStaticPublicKeyPins("docs.google.com"));
1054 EXPECT_TRUE(HasStaticPublicKeyPins("1.docs.google.com"));
1055 EXPECT_TRUE(HasStaticPublicKeyPins("sites.google.com"));
1056 EXPECT_TRUE(HasStaticPublicKeyPins("drive.google.com"));
1057 EXPECT_TRUE(HasStaticPublicKeyPins("spreadsheets.google.com"));
1058 EXPECT_TRUE(HasStaticPublicKeyPins("wallet.google.com"));
1059 EXPECT_TRUE(HasStaticPublicKeyPins("checkout.google.com"));
1060 EXPECT_TRUE(HasStaticPublicKeyPins("appengine.google.com"));
1061 EXPECT_TRUE(HasStaticPublicKeyPins("market.android.com"));
1062 EXPECT_TRUE(HasStaticPublicKeyPins("encrypted.google.com"));
1063 EXPECT_TRUE(HasStaticPublicKeyPins("accounts.google.com"));
1064 EXPECT_TRUE(HasStaticPublicKeyPins("profiles.google.com"));
1065 EXPECT_TRUE(HasStaticPublicKeyPins("mail.google.com"));
1066 EXPECT_TRUE(HasStaticPublicKeyPins("chatenabled.mail.google.com"));
1067 EXPECT_TRUE(HasStaticPublicKeyPins("talkgadget.google.com"));
1068 EXPECT_TRUE(HasStaticPublicKeyPins("hostedtalkgadget.google.com"));
1069 EXPECT_TRUE(HasStaticPublicKeyPins("talk.google.com"));
1070 EXPECT_TRUE(HasStaticPublicKeyPins("plus.google.com"));
1071 EXPECT_TRUE(HasStaticPublicKeyPins("groups.google.com"));
1072 EXPECT_TRUE(HasStaticPublicKeyPins("apis.google.com"));
1074 EXPECT_TRUE(HasStaticPublicKeyPins("ssl.gstatic.com"));
1075 EXPECT_TRUE(HasStaticPublicKeyPins("gstatic.com"));
1076 EXPECT_TRUE(HasStaticPublicKeyPins("www.gstatic.com"));
1077 EXPECT_TRUE(HasStaticPublicKeyPins("ssl.google-analytics.com"));
1078 EXPECT_TRUE(HasStaticPublicKeyPins("www.googleplex.com"));
1080 EXPECT_TRUE(HasStaticPublicKeyPins("twitter.com"));
1081 EXPECT_FALSE(HasStaticPublicKeyPins("foo.twitter.com"));
1082 EXPECT_TRUE(HasStaticPublicKeyPins("www.twitter.com"));
1083 EXPECT_TRUE(HasStaticPublicKeyPins("api.twitter.com"));
1084 EXPECT_TRUE(HasStaticPublicKeyPins("oauth.twitter.com"));
1085 EXPECT_TRUE(HasStaticPublicKeyPins("mobile.twitter.com"));
1086 EXPECT_TRUE(HasStaticPublicKeyPins("dev.twitter.com"));
1087 EXPECT_TRUE(HasStaticPublicKeyPins("business.twitter.com"));
1088 EXPECT_TRUE(HasStaticPublicKeyPins("platform.twitter.com"));
1089 EXPECT_TRUE(HasStaticPublicKeyPins("si0.twimg.com"));
1092 static bool AddHash(const std::string
& type_and_base64
,
1093 HashValueVector
* out
) {
1095 if (!hash
.FromString(type_and_base64
))
1098 out
->push_back(hash
);
1102 TEST_F(TransportSecurityStateTest
, PinValidationWithoutRejectedCerts
) {
1103 HashValueVector good_hashes
, bad_hashes
;
1105 for (size_t i
= 0; kGoodPath
[i
]; i
++) {
1106 EXPECT_TRUE(AddHash(kGoodPath
[i
], &good_hashes
));
1108 for (size_t i
= 0; kBadPath
[i
]; i
++) {
1109 EXPECT_TRUE(AddHash(kBadPath
[i
], &bad_hashes
));
1112 TransportSecurityState state
;
1113 EnableStaticPins(&state
);
1115 TransportSecurityState::STSState sts_state
;
1116 TransportSecurityState::PKPState pkp_state
;
1117 EXPECT_TRUE(state
.GetStaticDomainState("blog.torproject.org", &sts_state
,
1119 EXPECT_TRUE(pkp_state
.HasPublicKeyPins());
1121 std::string failure_log
;
1122 EXPECT_TRUE(pkp_state
.CheckPublicKeyPins(good_hashes
, &failure_log
));
1123 EXPECT_FALSE(pkp_state
.CheckPublicKeyPins(bad_hashes
, &failure_log
));
1126 TEST_F(TransportSecurityStateTest
, OptionalHSTSCertPins
) {
1127 TransportSecurityState state
;
1128 EnableStaticPins(&state
);
1130 EXPECT_FALSE(StaticShouldRedirect("www.google-analytics.com"));
1132 EXPECT_TRUE(HasStaticPublicKeyPins("www.google-analytics.com"));
1133 EXPECT_TRUE(HasStaticPublicKeyPins("google.com"));
1134 EXPECT_TRUE(HasStaticPublicKeyPins("www.google.com"));
1135 EXPECT_TRUE(HasStaticPublicKeyPins("mail-attachment.googleusercontent.com"));
1136 EXPECT_TRUE(HasStaticPublicKeyPins("www.youtube.com"));
1137 EXPECT_TRUE(HasStaticPublicKeyPins("i.ytimg.com"));
1138 EXPECT_TRUE(HasStaticPublicKeyPins("googleapis.com"));
1139 EXPECT_TRUE(HasStaticPublicKeyPins("ajax.googleapis.com"));
1140 EXPECT_TRUE(HasStaticPublicKeyPins("googleadservices.com"));
1141 EXPECT_TRUE(HasStaticPublicKeyPins("pagead2.googleadservices.com"));
1142 EXPECT_TRUE(HasStaticPublicKeyPins("googlecode.com"));
1143 EXPECT_TRUE(HasStaticPublicKeyPins("kibbles.googlecode.com"));
1144 EXPECT_TRUE(HasStaticPublicKeyPins("appspot.com"));
1145 EXPECT_TRUE(HasStaticPublicKeyPins("googlesyndication.com"));
1146 EXPECT_TRUE(HasStaticPublicKeyPins("doubleclick.net"));
1147 EXPECT_TRUE(HasStaticPublicKeyPins("ad.doubleclick.net"));
1148 EXPECT_FALSE(HasStaticPublicKeyPins("learn.doubleclick.net"));
1149 EXPECT_TRUE(HasStaticPublicKeyPins("a.googlegroups.com"));
1152 TEST_F(TransportSecurityStateTest
, OverrideBuiltins
) {
1153 EXPECT_TRUE(HasStaticPublicKeyPins("google.com"));
1154 EXPECT_FALSE(StaticShouldRedirect("google.com"));
1155 EXPECT_FALSE(StaticShouldRedirect("www.google.com"));
1157 TransportSecurityState state
;
1158 const base::Time
current_time(base::Time::Now());
1159 const base::Time expiry
= current_time
+ base::TimeDelta::FromSeconds(1000);
1160 state
.AddHSTS("www.google.com", expiry
, true);
1162 EXPECT_TRUE(state
.ShouldUpgradeToSSL("www.google.com"));
1165 TEST_F(TransportSecurityStateTest
, GooglePinnedProperties
) {
1166 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
1167 "www.example.com"));
1168 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
1170 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
1171 "mail.twitter.com"));
1172 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
1173 "www.google.com.int"));
1174 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
1176 // learn.doubleclick.net has a more specific match than
1177 // *.doubleclick.com, and has 0 or NULL for its required certs.
1178 // This test ensures that the exact-match-preferred behavior
1180 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
1181 "learn.doubleclick.net"));
1183 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
1184 "encrypted.google.com"));
1185 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
1186 "mail.google.com"));
1187 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
1188 "accounts.google.com"));
1189 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
1190 "doubleclick.net"));
1191 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
1192 "ad.doubleclick.net"));
1193 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
1195 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
1196 "www.profiles.google.com"));
1197 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
1198 "checkout.google.com"));
1199 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
1200 "googleadservices.com"));
1202 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
1203 "www.example.com"));
1204 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
1206 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
1207 "checkout.google.com"));
1208 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
1209 "googleadservices.com"));
1211 // Test some SNI hosts:
1212 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
1214 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
1215 "googlegroups.com"));
1216 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
1217 "www.googlegroups.com"));
1219 // These hosts used to only be HSTS when SNI was available.
1220 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
1222 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
1223 "googlegroups.com"));
1224 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
1225 "www.googlegroups.com"));
1228 TEST_F(TransportSecurityStateTest
, HPKPReporting
) {
1229 HostPortPair
host_port_pair(kHost
, kPort
);
1230 HostPortPair
subdomain_host_port_pair(kSubdomain
, kPort
);
1231 GURL
report_uri(kReportUri
);
1232 // Two dummy certs to use as the server-sent and validated chains. The
1233 // contents don't matter.
1234 scoped_refptr
<X509Certificate
> cert1
=
1235 ImportCertFromFile(GetTestCertsDirectory(), "test_mail_google_com.pem");
1236 scoped_refptr
<X509Certificate
> cert2
=
1237 ImportCertFromFile(GetTestCertsDirectory(), "expired_cert.pem");
1241 HashValueVector good_hashes
, bad_hashes
;
1243 for (size_t i
= 0; kGoodPath
[i
]; i
++)
1244 EXPECT_TRUE(AddHash(kGoodPath
[i
], &good_hashes
));
1245 for (size_t i
= 0; kBadPath
[i
]; i
++)
1246 EXPECT_TRUE(AddHash(kBadPath
[i
], &bad_hashes
));
1248 TransportSecurityState state
;
1249 MockCertificateReportSender mock_report_sender
;
1250 state
.SetReportSender(&mock_report_sender
);
1252 const base::Time current_time
= base::Time::Now();
1253 const base::Time expiry
= current_time
+ base::TimeDelta::FromSeconds(1000);
1254 state
.AddHPKP(kHost
, expiry
, true, good_hashes
, report_uri
);
1256 EXPECT_EQ(GURL(), mock_report_sender
.latest_report_uri());
1257 EXPECT_EQ(std::string(), mock_report_sender
.latest_report());
1259 std::string failure_log
;
1260 EXPECT_FALSE(state
.CheckPublicKeyPins(
1261 host_port_pair
, true, bad_hashes
, cert1
.get(), cert2
.get(),
1262 TransportSecurityState::DISABLE_PIN_REPORTS
, &failure_log
));
1264 // No report should have been sent because of the DISABLE_PIN_REPORTS
1266 EXPECT_EQ(GURL(), mock_report_sender
.latest_report_uri());
1267 EXPECT_EQ(std::string(), mock_report_sender
.latest_report());
1269 EXPECT_TRUE(state
.CheckPublicKeyPins(
1270 host_port_pair
, true, good_hashes
, cert1
.get(), cert2
.get(),
1271 TransportSecurityState::ENABLE_PIN_REPORTS
, &failure_log
));
1273 // No report should have been sent because there was no violation.
1274 EXPECT_EQ(GURL(), mock_report_sender
.latest_report_uri());
1275 EXPECT_EQ(std::string(), mock_report_sender
.latest_report());
1277 EXPECT_FALSE(state
.CheckPublicKeyPins(
1278 host_port_pair
, true, bad_hashes
, cert1
.get(), cert2
.get(),
1279 TransportSecurityState::ENABLE_PIN_REPORTS
, &failure_log
));
1281 // Now a report should have been sent. Check that it contains the
1282 // right information.
1283 EXPECT_EQ(report_uri
, mock_report_sender
.latest_report_uri());
1284 std::string report
= mock_report_sender
.latest_report();
1285 ASSERT_FALSE(report
.empty());
1286 ASSERT_NO_FATAL_FAILURE(CheckHPKPReport(report
, host_port_pair
, true, kHost
,
1287 cert1
.get(), cert2
.get(),
1289 mock_report_sender
.Clear();
1290 EXPECT_FALSE(state
.CheckPublicKeyPins(
1291 subdomain_host_port_pair
, true, bad_hashes
, cert1
.get(), cert2
.get(),
1292 TransportSecurityState::ENABLE_PIN_REPORTS
, &failure_log
));
1294 // Now a report should have been sent for the subdomain. Check that it
1295 // contains the right information.
1296 EXPECT_EQ(report_uri
, mock_report_sender
.latest_report_uri());
1297 report
= mock_report_sender
.latest_report();
1298 ASSERT_FALSE(report
.empty());
1299 ASSERT_NO_FATAL_FAILURE(CheckHPKPReport(report
, subdomain_host_port_pair
,
1300 true, kHost
, cert1
.get(), cert2
.get(),
1304 TEST_F(TransportSecurityStateTest
, HPKPReportOnly
) {
1305 HostPortPair
host_port_pair(kHost
, kPort
);
1306 GURL
report_uri(kReportUri
);
1307 // Two dummy certs to use as the server-sent and validated chains. The
1308 // contents don't matter.
1309 scoped_refptr
<X509Certificate
> cert1
=
1310 ImportCertFromFile(GetTestCertsDirectory(), "test_mail_google_com.pem");
1311 scoped_refptr
<X509Certificate
> cert2
=
1312 ImportCertFromFile(GetTestCertsDirectory(), "expired_cert.pem");
1316 TransportSecurityState state
;
1317 MockCertificateReportSender mock_report_sender
;
1318 state
.SetReportSender(&mock_report_sender
);
1320 // Check that a report is not sent for a Report-Only header with no
1322 std::string header
=
1323 "pin-sha256=\"" + std::string(kGoodPin1
) + "\";pin-sha256=\"" +
1324 std::string(kGoodPin2
) + "\";pin-sha256=\"" + std::string(kGoodPin3
) +
1325 "\";report-uri=\"" + report_uri
.spec() + "\";includeSubdomains";
1327 ssl_info
.is_issued_by_known_root
= true;
1328 ssl_info
.unverified_cert
= cert1
;
1329 ssl_info
.cert
= cert2
;
1330 for (size_t i
= 0; kGoodPath
[i
]; i
++)
1331 EXPECT_TRUE(AddHash(kGoodPath
[i
], &ssl_info
.public_key_hashes
));
1334 state
.ProcessHPKPReportOnlyHeader(header
, host_port_pair
, ssl_info
));
1335 EXPECT_EQ(GURL(), mock_report_sender
.latest_report_uri());
1336 EXPECT_EQ(std::string(), mock_report_sender
.latest_report());
1338 // Check that a report is sent for a Report-Only header with a
1340 ssl_info
.public_key_hashes
.clear();
1341 for (size_t i
= 0; kBadPath
[i
]; i
++)
1342 EXPECT_TRUE(AddHash(kBadPath
[i
], &ssl_info
.public_key_hashes
));
1345 state
.ProcessHPKPReportOnlyHeader(header
, host_port_pair
, ssl_info
));
1346 EXPECT_EQ(report_uri
, mock_report_sender
.latest_report_uri());
1347 std::string report
= mock_report_sender
.latest_report();
1348 ASSERT_FALSE(report
.empty());
1349 ASSERT_NO_FATAL_FAILURE(CheckHPKPReport(report
, host_port_pair
, true, kHost
,
1350 cert1
.get(), cert2
.get(),
1351 ssl_info
.public_key_hashes
));
1353 // HTTPS report URIs on the same host as the pin violation should not
1354 // be allowed, to avoid going into a report-sending loop.
1355 mock_report_sender
.Clear();
1356 header
= "pin-sha256=\"" + std::string(kGoodPin1
) + "\";pin-sha256=\"" +
1357 std::string(kGoodPin2
) + "\";pin-sha256=\"" +
1358 std::string(kGoodPin3
) + "\";report-uri=\"https://" +
1359 host_port_pair
.host() + "/report\";includeSubdomains";
1361 state
.ProcessHPKPReportOnlyHeader(header
, host_port_pair
, ssl_info
));
1362 EXPECT_TRUE(mock_report_sender
.latest_report_uri().is_empty());
1365 // Tests that Report-Only reports are not sent on certs that chain to
1367 TEST_F(TransportSecurityStateTest
, HPKPReportOnlyOnLocalRoot
) {
1368 HostPortPair
host_port_pair(kHost
, kPort
);
1369 GURL
report_uri(kReportUri
);
1370 // Two dummy certs to use as the server-sent and validated chains. The
1371 // contents don't matter.
1372 scoped_refptr
<X509Certificate
> cert1
=
1373 ImportCertFromFile(GetTestCertsDirectory(), "test_mail_google_com.pem");
1374 scoped_refptr
<X509Certificate
> cert2
=
1375 ImportCertFromFile(GetTestCertsDirectory(), "expired_cert.pem");
1379 std::string header
=
1380 "pin-sha256=\"" + std::string(kGoodPin1
) + "\";pin-sha256=\"" +
1381 std::string(kGoodPin2
) + "\";pin-sha256=\"" + std::string(kGoodPin3
) +
1382 "\";report-uri=\"" + report_uri
.spec() + "\";includeSubdomains";
1384 TransportSecurityState state
;
1385 MockCertificateReportSender mock_report_sender
;
1386 state
.SetReportSender(&mock_report_sender
);
1389 ssl_info
.is_issued_by_known_root
= true;
1390 ssl_info
.unverified_cert
= cert1
;
1391 ssl_info
.cert
= cert2
;
1392 for (size_t i
= 0; kGoodPath
[i
]; i
++)
1393 EXPECT_TRUE(AddHash(kGoodPath
[i
], &ssl_info
.public_key_hashes
));
1394 ssl_info
.is_issued_by_known_root
= false;
1397 state
.ProcessHPKPReportOnlyHeader(header
, host_port_pair
, ssl_info
));
1398 EXPECT_EQ(GURL(), mock_report_sender
.latest_report_uri());
1399 EXPECT_EQ(std::string(), mock_report_sender
.latest_report());
1402 // Tests that ProcessHPKPReportOnlyHeader() returns false if a report-uri
1403 // wasn't specified or if the header fails to parse.
1404 TEST_F(TransportSecurityStateTest
, HPKPReportOnlyParseErrors
) {
1405 HostPortPair
host_port_pair(kHost
, kPort
);
1406 GURL
report_uri(kReportUri
);
1407 // Two dummy certs to use as the server-sent and validated chains. The
1408 // contents don't matter.
1409 scoped_refptr
<X509Certificate
> cert1
=
1410 ImportCertFromFile(GetTestCertsDirectory(), "test_mail_google_com.pem");
1411 scoped_refptr
<X509Certificate
> cert2
=
1412 ImportCertFromFile(GetTestCertsDirectory(), "expired_cert.pem");
1416 std::string header
= "pin-sha256=\"" + std::string(kGoodPin1
) +
1417 "\";pin-sha256=\"" + std::string(kGoodPin2
) +
1418 "\";pin-sha256=\"" + std::string(kGoodPin3
) + "\"";
1420 TransportSecurityState state
;
1421 MockCertificateReportSender mock_report_sender
;
1422 state
.SetReportSender(&mock_report_sender
);
1425 ssl_info
.is_issued_by_known_root
= true;
1426 ssl_info
.unverified_cert
= cert1
;
1427 ssl_info
.cert
= cert2
;
1428 for (size_t i
= 0; kGoodPath
[i
]; i
++)
1429 EXPECT_TRUE(AddHash(kGoodPath
[i
], &ssl_info
.public_key_hashes
));
1432 state
.ProcessHPKPReportOnlyHeader(header
, host_port_pair
, ssl_info
));
1433 header
+= ";report-uri=\"";
1435 state
.ProcessHPKPReportOnlyHeader(header
, host_port_pair
, ssl_info
));
1438 // Tests that pinning violations on preloaded pins trigger reports when
1439 // the preloaded pin contains a report URI.
1440 TEST_F(TransportSecurityStateTest
, PreloadedPKPReportUri
) {
1441 const char kPreloadedPinDomain
[] = "www.google.com";
1442 const uint16_t kPort
= 443;
1443 HostPortPair
host_port_pair(kPreloadedPinDomain
, kPort
);
1445 TransportSecurityState state
;
1446 MockCertificateReportSender mock_report_sender
;
1447 state
.SetReportSender(&mock_report_sender
);
1450 TransportSecurityState::IsGooglePinnedProperty(kPreloadedPinDomain
));
1451 EnableStaticPins(&state
);
1453 TransportSecurityState::PKPState pkp_state
;
1454 TransportSecurityState::STSState unused_sts_state
;
1455 ASSERT_TRUE(state
.GetStaticDomainState(kPreloadedPinDomain
, &unused_sts_state
,
1458 GURL report_uri
= pkp_state
.report_uri
;
1459 ASSERT_TRUE(report_uri
.is_valid());
1460 ASSERT_FALSE(report_uri
.is_empty());
1462 // Two dummy certs to use as the server-sent and validated chains. The
1463 // contents don't matter, as long as they are not the real google.com
1464 // certs in the pins.
1465 scoped_refptr
<X509Certificate
> cert1
=
1466 ImportCertFromFile(GetTestCertsDirectory(), "test_mail_google_com.pem");
1467 scoped_refptr
<X509Certificate
> cert2
=
1468 ImportCertFromFile(GetTestCertsDirectory(), "expired_cert.pem");
1472 HashValueVector bad_hashes
;
1473 for (size_t i
= 0; kBadPath
[i
]; i
++)
1474 EXPECT_TRUE(AddHash(kBadPath
[i
], &bad_hashes
));
1476 // Trigger a violation and check that it sends a report.
1477 std::string failure_log
;
1478 EXPECT_FALSE(state
.CheckPublicKeyPins(
1479 host_port_pair
, true, bad_hashes
, cert1
.get(), cert2
.get(),
1480 TransportSecurityState::ENABLE_PIN_REPORTS
, &failure_log
));
1482 EXPECT_EQ(report_uri
, mock_report_sender
.latest_report_uri());
1484 std::string report
= mock_report_sender
.latest_report();
1485 ASSERT_FALSE(report
.empty());
1486 ASSERT_NO_FATAL_FAILURE(CheckHPKPReport(
1487 report
, host_port_pair
, pkp_state
.include_subdomains
, pkp_state
.domain
,
1488 cert1
.get(), cert2
.get(), pkp_state
.spki_hashes
));
1491 // Tests that report URIs are thrown out if they point to the same host,
1492 // over HTTPS, for which a pin was violated.
1493 TEST_F(TransportSecurityStateTest
, HPKPReportUriToSameHost
) {
1494 HostPortPair
host_port_pair(kHost
, kPort
);
1495 GURL
https_report_uri("https://example.test/report");
1496 GURL
http_report_uri("http://example.test/report");
1497 TransportSecurityState state
;
1498 MockCertificateReportSender mock_report_sender
;
1499 state
.SetReportSender(&mock_report_sender
);
1501 const base::Time current_time
= base::Time::Now();
1502 const base::Time expiry
= current_time
+ base::TimeDelta::FromSeconds(1000);
1503 HashValueVector good_hashes
;
1504 for (size_t i
= 0; kGoodPath
[i
]; i
++)
1505 EXPECT_TRUE(AddHash(kGoodPath
[i
], &good_hashes
));
1507 // Two dummy certs to use as the server-sent and validated chains. The
1508 // contents don't matter, as long as they are not the real google.com
1509 // certs in the pins.
1510 scoped_refptr
<X509Certificate
> cert1
=
1511 ImportCertFromFile(GetTestCertsDirectory(), "test_mail_google_com.pem");
1512 scoped_refptr
<X509Certificate
> cert2
=
1513 ImportCertFromFile(GetTestCertsDirectory(), "expired_cert.pem");
1517 HashValueVector bad_hashes
;
1518 for (size_t i
= 0; kBadPath
[i
]; i
++)
1519 EXPECT_TRUE(AddHash(kBadPath
[i
], &bad_hashes
));
1521 state
.AddHPKP(kHost
, expiry
, true, good_hashes
, https_report_uri
);
1523 // Trigger a violation and check that it does not send a report
1524 // because the report-uri is HTTPS and same-host as the pins.
1525 std::string failure_log
;
1526 EXPECT_FALSE(state
.CheckPublicKeyPins(
1527 host_port_pair
, true, bad_hashes
, cert1
.get(), cert2
.get(),
1528 TransportSecurityState::ENABLE_PIN_REPORTS
, &failure_log
));
1530 EXPECT_TRUE(mock_report_sender
.latest_report_uri().is_empty());
1532 // An HTTP report uri to the same host should be okay.
1533 state
.AddHPKP("example.test", expiry
, true, good_hashes
, http_report_uri
);
1534 EXPECT_FALSE(state
.CheckPublicKeyPins(
1535 host_port_pair
, true, bad_hashes
, cert1
.get(), cert2
.get(),
1536 TransportSecurityState::ENABLE_PIN_REPORTS
, &failure_log
));
1538 EXPECT_EQ(http_report_uri
, mock_report_sender
.latest_report_uri());