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://example.test/test";
50 // kGoodPath is blog.torproject.org.
51 const char* const kGoodPath
[] = {
52 "sha1/m9lHYJYke9k0GtVZ+bXSQYE8nDI=", "sha1/o5OZxATDsgmwgcIfIWIneMJ0jkw=",
53 "sha1/wHqYaI2J+6sFZAwRfap9ZbjKzE4=", NULL
,
56 const char kGoodPin1
[] = "m9lHYJYke9k0GtVZ+bXSQYE8nDI=";
57 const char kGoodPin2
[] = "o5OZxATDsgmwgcIfIWIneMJ0jkw=";
58 const char kGoodPin3
[] = "wHqYaI2J+6sFZAwRfap9ZbjKzE4=";
60 // kBadPath is plus.google.com via Trustcenter, which is utterly wrong for
62 const char* const kBadPath
[] = {
63 "sha1/4BjDjn8v2lWeUFQnqSs0BgbIcrU=", "sha1/gzuEEAB/bkqdQS3EIjk2by7lW+k=",
64 "sha1/SOZo+SvSspXXR9gjIBBPM5iQn9Q=", NULL
,
67 // A mock ReportSender that just remembers the latest report
68 // URI and report to be sent.
69 class MockCertificateReportSender
70 : public TransportSecurityState::ReportSender
{
72 MockCertificateReportSender() {}
73 ~MockCertificateReportSender() override
{}
75 void Send(const GURL
& report_uri
, const std::string
& report
) override
{
76 latest_report_uri_
= report_uri
;
77 latest_report_
= report
;
81 latest_report_uri_
= GURL();
82 latest_report_
= std::string();
85 const GURL
& latest_report_uri() { return latest_report_uri_
; }
86 const std::string
& latest_report() { return latest_report_
; }
89 GURL latest_report_uri_
;
90 std::string latest_report_
;
93 void CompareCertificateChainWithList(
94 const scoped_refptr
<X509Certificate
>& cert_chain
,
95 const base::ListValue
* cert_list
) {
96 ASSERT_TRUE(cert_chain
);
97 std::vector
<std::string
> pem_encoded_chain
;
98 cert_chain
->GetPEMEncodedChain(&pem_encoded_chain
);
99 EXPECT_EQ(pem_encoded_chain
.size(), cert_list
->GetSize());
101 for (size_t i
= 0; i
< pem_encoded_chain
.size(); i
++) {
102 std::string list_cert
;
103 ASSERT_TRUE(cert_list
->GetString(i
, &list_cert
));
104 EXPECT_EQ(pem_encoded_chain
[i
], list_cert
);
108 void CheckHPKPReport(
109 const std::string
& report
,
110 const HostPortPair
& host_port_pair
,
111 bool include_subdomains
,
112 const std::string
& noted_hostname
,
113 const scoped_refptr
<X509Certificate
>& served_certificate_chain
,
114 const scoped_refptr
<X509Certificate
>& validated_certificate_chain
,
115 const HashValueVector
& known_pins
) {
116 scoped_ptr
<base::Value
> value(base::JSONReader::Read(report
));
118 ASSERT_TRUE(value
->IsType(base::Value::TYPE_DICTIONARY
));
120 base::DictionaryValue
* report_dict
;
121 ASSERT_TRUE(value
->GetAsDictionary(&report_dict
));
123 std::string report_hostname
;
124 EXPECT_TRUE(report_dict
->GetString("hostname", &report_hostname
));
125 EXPECT_EQ(host_port_pair
.host(), report_hostname
);
128 EXPECT_TRUE(report_dict
->GetInteger("port", &report_port
));
129 EXPECT_EQ(host_port_pair
.port(), report_port
);
131 bool report_include_subdomains
;
132 EXPECT_TRUE(report_dict
->GetBoolean("include-subdomains",
133 &report_include_subdomains
));
134 EXPECT_EQ(include_subdomains
, report_include_subdomains
);
136 std::string report_noted_hostname
;
137 EXPECT_TRUE(report_dict
->GetString("noted-hostname", &report_noted_hostname
));
138 EXPECT_EQ(noted_hostname
, report_noted_hostname
);
140 // TODO(estark): check times in RFC3339 format.
142 std::string report_expiration
;
144 report_dict
->GetString("effective-expiration-date", &report_expiration
));
145 EXPECT_FALSE(report_expiration
.empty());
147 std::string report_date
;
148 EXPECT_TRUE(report_dict
->GetString("date-time", &report_date
));
149 EXPECT_FALSE(report_date
.empty());
151 base::ListValue
* report_served_certificate_chain
;
152 EXPECT_TRUE(report_dict
->GetList("served-certificate-chain",
153 &report_served_certificate_chain
));
154 ASSERT_NO_FATAL_FAILURE(CompareCertificateChainWithList(
155 served_certificate_chain
, report_served_certificate_chain
));
157 base::ListValue
* report_validated_certificate_chain
;
158 EXPECT_TRUE(report_dict
->GetList("validated-certificate-chain",
159 &report_validated_certificate_chain
));
160 ASSERT_NO_FATAL_FAILURE(CompareCertificateChainWithList(
161 validated_certificate_chain
, report_validated_certificate_chain
));
166 class TransportSecurityStateTest
: public testing::Test
{
168 void SetUp() override
{
169 #if defined(USE_OPENSSL)
170 crypto::EnsureOpenSSLInit();
172 crypto::EnsureNSSInit();
176 static void DisableStaticPins(TransportSecurityState
* state
) {
177 state
->enable_static_pins_
= false;
180 static void EnableStaticPins(TransportSecurityState
* state
) {
181 state
->enable_static_pins_
= true;
184 static HashValueVector
GetSampleSPKIHashes() {
185 HashValueVector spki_hashes
;
186 HashValue
hash(HASH_VALUE_SHA1
);
187 memset(hash
.data(), 0, hash
.size());
188 spki_hashes
.push_back(hash
);
193 bool GetStaticDomainState(TransportSecurityState
* state
,
194 const std::string
& host
,
195 TransportSecurityState::STSState
* sts_result
,
196 TransportSecurityState::PKPState
* pkp_result
) {
197 return state
->GetStaticDomainState(host
, sts_result
, pkp_result
);
201 TEST_F(TransportSecurityStateTest
, DomainNameOddities
) {
202 TransportSecurityState state
;
203 const base::Time
current_time(base::Time::Now());
204 const base::Time expiry
= current_time
+ base::TimeDelta::FromSeconds(1000);
206 // DNS suffix search tests. Some DNS resolvers allow a terminal "." to
207 // indicate not perform DNS suffix searching. Ensure that regardless
208 // of how this is treated at the resolver layer, or at the URL/origin
209 // layer (that is, whether they are treated as equivalent or distinct),
210 // ensure that for policy matching, something lacking a terminal "."
211 // is equivalent to something with a terminal "."
212 EXPECT_FALSE(state
.ShouldUpgradeToSSL("example.com"));
214 state
.AddHSTS("example.com", expiry
, true /* include_subdomains */);
215 EXPECT_TRUE(state
.ShouldUpgradeToSSL("example.com"));
216 // Trailing '.' should be equivalent; it's just a resolver hint
217 EXPECT_TRUE(state
.ShouldUpgradeToSSL("example.com."));
218 // Leading '.' should be invalid
219 EXPECT_FALSE(state
.ShouldUpgradeToSSL(".example.com"));
220 // Subdomains should work regardless
221 EXPECT_TRUE(state
.ShouldUpgradeToSSL("sub.example.com"));
222 EXPECT_TRUE(state
.ShouldUpgradeToSSL("sub.example.com."));
223 // But invalid subdomains should be rejected
224 EXPECT_FALSE(state
.ShouldUpgradeToSSL("sub..example.com"));
225 EXPECT_FALSE(state
.ShouldUpgradeToSSL("sub..example.com."));
227 // Now try the inverse form
228 TransportSecurityState state2
;
229 state2
.AddHSTS("example.net.", expiry
, true /* include_subdomains */);
230 EXPECT_TRUE(state2
.ShouldUpgradeToSSL("example.net."));
231 EXPECT_TRUE(state2
.ShouldUpgradeToSSL("example.net"));
232 EXPECT_TRUE(state2
.ShouldUpgradeToSSL("sub.example.net."));
233 EXPECT_TRUE(state2
.ShouldUpgradeToSSL("sub.example.net"));
235 // Finally, test weird things
236 TransportSecurityState state3
;
237 state3
.AddHSTS("", expiry
, true /* include_subdomains */);
238 EXPECT_FALSE(state3
.ShouldUpgradeToSSL(""));
239 EXPECT_FALSE(state3
.ShouldUpgradeToSSL("."));
240 EXPECT_FALSE(state3
.ShouldUpgradeToSSL("..."));
241 // Make sure it didn't somehow apply HSTS to the world
242 EXPECT_FALSE(state3
.ShouldUpgradeToSSL("example.org"));
244 TransportSecurityState state4
;
245 state4
.AddHSTS(".", expiry
, true /* include_subdomains */);
246 EXPECT_FALSE(state4
.ShouldUpgradeToSSL(""));
247 EXPECT_FALSE(state4
.ShouldUpgradeToSSL("."));
248 EXPECT_FALSE(state4
.ShouldUpgradeToSSL("..."));
249 EXPECT_FALSE(state4
.ShouldUpgradeToSSL("example.org"));
251 // Now do the same for preloaded entries
252 TransportSecurityState state5
;
253 EXPECT_TRUE(state5
.ShouldUpgradeToSSL("accounts.google.com"));
254 EXPECT_TRUE(state5
.ShouldUpgradeToSSL("accounts.google.com."));
255 EXPECT_FALSE(state5
.ShouldUpgradeToSSL("accounts..google.com"));
256 EXPECT_FALSE(state5
.ShouldUpgradeToSSL("accounts..google.com."));
259 TEST_F(TransportSecurityStateTest
, SimpleMatches
) {
260 TransportSecurityState state
;
261 const base::Time
current_time(base::Time::Now());
262 const base::Time expiry
= current_time
+ base::TimeDelta::FromSeconds(1000);
264 EXPECT_FALSE(state
.ShouldUpgradeToSSL("example.com"));
265 bool include_subdomains
= false;
266 state
.AddHSTS("example.com", expiry
, include_subdomains
);
267 EXPECT_TRUE(state
.ShouldUpgradeToSSL("example.com"));
268 EXPECT_TRUE(state
.ShouldSSLErrorsBeFatal("example.com"));
269 EXPECT_FALSE(state
.ShouldUpgradeToSSL("foo.example.com"));
270 EXPECT_FALSE(state
.ShouldSSLErrorsBeFatal("foo.example.com"));
273 TEST_F(TransportSecurityStateTest
, MatchesCase1
) {
274 TransportSecurityState state
;
275 const base::Time
current_time(base::Time::Now());
276 const base::Time expiry
= current_time
+ base::TimeDelta::FromSeconds(1000);
278 EXPECT_FALSE(state
.ShouldUpgradeToSSL("example.com"));
279 bool include_subdomains
= false;
280 state
.AddHSTS("EXample.coM", expiry
, include_subdomains
);
281 EXPECT_TRUE(state
.ShouldUpgradeToSSL("example.com"));
284 TEST_F(TransportSecurityStateTest
, Fuzz
) {
285 TransportSecurityState state
;
286 TransportSecurityState::STSState sts_state
;
287 TransportSecurityState::PKPState pkp_state
;
289 EnableStaticPins(&state
);
291 for (size_t i
= 0; i
< 128; i
++) {
292 std::string hostname
;
295 if (base::RandInt(0, 16) == 7) {
298 if (i
> 0 && base::RandInt(0, 7) == 7) {
299 hostname
.append(1, '.');
301 hostname
.append(1, 'a' + base::RandInt(0, 25));
303 state
.GetStaticDomainState(hostname
, &sts_state
, &pkp_state
);
307 TEST_F(TransportSecurityStateTest
, MatchesCase2
) {
308 TransportSecurityState state
;
309 const base::Time
current_time(base::Time::Now());
310 const base::Time expiry
= current_time
+ base::TimeDelta::FromSeconds(1000);
312 // Check dynamic entries
313 EXPECT_FALSE(state
.ShouldUpgradeToSSL("EXample.coM"));
314 bool include_subdomains
= false;
315 state
.AddHSTS("example.com", expiry
, include_subdomains
);
316 EXPECT_TRUE(state
.ShouldUpgradeToSSL("EXample.coM"));
318 // Check static entries
319 EXPECT_TRUE(state
.ShouldUpgradeToSSL("AccounTs.GooGle.com"));
320 EXPECT_TRUE(state
.ShouldUpgradeToSSL("mail.google.COM"));
323 TEST_F(TransportSecurityStateTest
, SubdomainMatches
) {
324 TransportSecurityState state
;
325 const base::Time
current_time(base::Time::Now());
326 const base::Time expiry
= current_time
+ base::TimeDelta::FromSeconds(1000);
328 EXPECT_FALSE(state
.ShouldUpgradeToSSL("example.test"));
329 bool include_subdomains
= true;
330 state
.AddHSTS("example.test", expiry
, include_subdomains
);
331 EXPECT_TRUE(state
.ShouldUpgradeToSSL("example.test"));
332 EXPECT_TRUE(state
.ShouldUpgradeToSSL("foo.example.test"));
333 EXPECT_TRUE(state
.ShouldUpgradeToSSL("foo.bar.example.test"));
334 EXPECT_TRUE(state
.ShouldUpgradeToSSL("foo.bar.baz.example.test"));
335 EXPECT_FALSE(state
.ShouldUpgradeToSSL("test"));
336 EXPECT_FALSE(state
.ShouldUpgradeToSSL("notexample.test"));
339 // Tests that a more-specific HSTS or HPKP rule overrides a less-specific rule
340 // with it, regardless of the includeSubDomains bit. This is a regression test
341 // for https://crbug.com/469957.
342 TEST_F(TransportSecurityStateTest
, SubdomainCarveout
) {
343 const GURL
report_uri(kReportUri
);
344 TransportSecurityState state
;
345 const base::Time
current_time(base::Time::Now());
346 const base::Time expiry
= current_time
+ base::TimeDelta::FromSeconds(1000);
347 const base::Time older
= current_time
- base::TimeDelta::FromSeconds(1000);
349 state
.AddHSTS("example1.test", expiry
, true);
350 state
.AddHSTS("foo.example1.test", expiry
, false);
352 state
.AddHPKP("example2.test", expiry
, true, GetSampleSPKIHashes(),
354 state
.AddHPKP("foo.example2.test", expiry
, false, GetSampleSPKIHashes(),
357 EXPECT_TRUE(state
.ShouldUpgradeToSSL("example1.test"));
358 EXPECT_TRUE(state
.ShouldUpgradeToSSL("foo.example1.test"));
360 // The foo.example1.test rule overrides the example1.test rule, so
361 // bar.foo.example1.test has no HSTS state.
362 EXPECT_FALSE(state
.ShouldUpgradeToSSL("bar.foo.example1.test"));
363 EXPECT_FALSE(state
.ShouldSSLErrorsBeFatal("bar.foo.example1.test"));
365 EXPECT_TRUE(state
.HasPublicKeyPins("example2.test"));
366 EXPECT_TRUE(state
.HasPublicKeyPins("foo.example2.test"));
368 // The foo.example2.test rule overrides the example1.test rule, so
369 // bar.foo.example2.test has no HPKP state.
370 EXPECT_FALSE(state
.HasPublicKeyPins("bar.foo.example2.test"));
371 EXPECT_FALSE(state
.ShouldSSLErrorsBeFatal("bar.foo.example2.test"));
373 // Expire the foo.example*.test rules.
374 state
.AddHSTS("foo.example1.test", older
, false);
375 state
.AddHPKP("foo.example2.test", older
, false, GetSampleSPKIHashes(),
378 // Now the base example*.test rules apply to bar.foo.example*.test.
379 EXPECT_TRUE(state
.ShouldUpgradeToSSL("bar.foo.example1.test"));
380 EXPECT_TRUE(state
.ShouldSSLErrorsBeFatal("bar.foo.example1.test"));
381 EXPECT_TRUE(state
.HasPublicKeyPins("bar.foo.example2.test"));
382 EXPECT_TRUE(state
.ShouldSSLErrorsBeFatal("bar.foo.example2.test"));
385 TEST_F(TransportSecurityStateTest
, FatalSSLErrors
) {
386 const GURL
report_uri(kReportUri
);
387 TransportSecurityState state
;
388 const base::Time
current_time(base::Time::Now());
389 const base::Time expiry
= current_time
+ base::TimeDelta::FromSeconds(1000);
391 state
.AddHSTS("example1.test", expiry
, false);
392 state
.AddHPKP("example2.test", expiry
, false, GetSampleSPKIHashes(),
395 // The presense of either HSTS or HPKP is enough to make SSL errors fatal.
396 EXPECT_TRUE(state
.ShouldSSLErrorsBeFatal("example1.test"));
397 EXPECT_TRUE(state
.ShouldSSLErrorsBeFatal("example2.test"));
400 // Tests that HPKP and HSTS state both expire. Also tests that expired entries
402 TEST_F(TransportSecurityStateTest
, Expiration
) {
403 const GURL
report_uri(kReportUri
);
404 TransportSecurityState state
;
405 const base::Time
current_time(base::Time::Now());
406 const base::Time expiry
= current_time
+ base::TimeDelta::FromSeconds(1000);
407 const base::Time older
= current_time
- base::TimeDelta::FromSeconds(1000);
409 // Note: this test assumes that inserting an entry with an expiration time in
410 // the past works and is pruned on query.
411 state
.AddHSTS("example1.test", older
, false);
412 EXPECT_TRUE(TransportSecurityState::STSStateIterator(state
).HasNext());
413 EXPECT_FALSE(state
.ShouldUpgradeToSSL("example1.test"));
414 // Querying |state| for a domain should flush out expired entries.
415 EXPECT_FALSE(TransportSecurityState::STSStateIterator(state
).HasNext());
417 state
.AddHPKP("example1.test", older
, false, GetSampleSPKIHashes(),
419 EXPECT_TRUE(TransportSecurityState::PKPStateIterator(state
).HasNext());
420 EXPECT_FALSE(state
.HasPublicKeyPins("example1.test"));
421 // Querying |state| for a domain should flush out expired entries.
422 EXPECT_FALSE(TransportSecurityState::PKPStateIterator(state
).HasNext());
424 state
.AddHSTS("example1.test", older
, false);
425 state
.AddHPKP("example1.test", older
, false, GetSampleSPKIHashes(),
427 EXPECT_TRUE(TransportSecurityState::STSStateIterator(state
).HasNext());
428 EXPECT_TRUE(TransportSecurityState::PKPStateIterator(state
).HasNext());
429 EXPECT_FALSE(state
.ShouldSSLErrorsBeFatal("example1.test"));
430 // Querying |state| for a domain should flush out expired entries.
431 EXPECT_FALSE(TransportSecurityState::STSStateIterator(state
).HasNext());
432 EXPECT_FALSE(TransportSecurityState::PKPStateIterator(state
).HasNext());
434 // Test that HSTS can outlive HPKP.
435 state
.AddHSTS("example1.test", expiry
, false);
436 state
.AddHPKP("example1.test", older
, false, GetSampleSPKIHashes(),
438 EXPECT_TRUE(state
.ShouldUpgradeToSSL("example1.test"));
439 EXPECT_FALSE(state
.HasPublicKeyPins("example1.test"));
441 // Test that HPKP can outlive HSTS.
442 state
.AddHSTS("example2.test", older
, false);
443 state
.AddHPKP("example2.test", expiry
, false, GetSampleSPKIHashes(),
445 EXPECT_FALSE(state
.ShouldUpgradeToSSL("example2.test"));
446 EXPECT_TRUE(state
.HasPublicKeyPins("example2.test"));
449 TEST_F(TransportSecurityStateTest
, InvalidDomains
) {
450 TransportSecurityState state
;
451 const base::Time
current_time(base::Time::Now());
452 const base::Time expiry
= current_time
+ base::TimeDelta::FromSeconds(1000);
454 EXPECT_FALSE(state
.ShouldUpgradeToSSL("example.test"));
455 bool include_subdomains
= true;
456 state
.AddHSTS("example.test", expiry
, include_subdomains
);
457 EXPECT_TRUE(state
.ShouldUpgradeToSSL("www-.foo.example.test"));
458 EXPECT_TRUE(state
.ShouldUpgradeToSSL("2\x01.foo.example.test"));
461 // Tests that HPKP and HSTS state are queried independently for subdomain
463 TEST_F(TransportSecurityStateTest
, IndependentSubdomain
) {
464 const GURL
report_uri(kReportUri
);
465 TransportSecurityState state
;
466 const base::Time
current_time(base::Time::Now());
467 const base::Time expiry
= current_time
+ base::TimeDelta::FromSeconds(1000);
469 state
.AddHSTS("example1.test", expiry
, true);
470 state
.AddHPKP("example1.test", expiry
, false, GetSampleSPKIHashes(),
473 state
.AddHSTS("example2.test", expiry
, false);
474 state
.AddHPKP("example2.test", expiry
, true, GetSampleSPKIHashes(),
477 EXPECT_TRUE(state
.ShouldUpgradeToSSL("foo.example1.test"));
478 EXPECT_FALSE(state
.HasPublicKeyPins("foo.example1.test"));
479 EXPECT_FALSE(state
.ShouldUpgradeToSSL("foo.example2.test"));
480 EXPECT_TRUE(state
.HasPublicKeyPins("foo.example2.test"));
483 // Tests that HPKP and HSTS state are inserted and overridden independently.
484 TEST_F(TransportSecurityStateTest
, IndependentInsertion
) {
485 const GURL
report_uri(kReportUri
);
486 TransportSecurityState state
;
487 const base::Time
current_time(base::Time::Now());
488 const base::Time expiry
= current_time
+ base::TimeDelta::FromSeconds(1000);
490 // Place an includeSubdomains HSTS entry below a normal HPKP entry.
491 state
.AddHSTS("example1.test", expiry
, true);
492 state
.AddHPKP("foo.example1.test", expiry
, false, GetSampleSPKIHashes(),
495 EXPECT_TRUE(state
.ShouldUpgradeToSSL("foo.example1.test"));
496 EXPECT_TRUE(state
.HasPublicKeyPins("foo.example1.test"));
497 EXPECT_TRUE(state
.ShouldUpgradeToSSL("example1.test"));
498 EXPECT_FALSE(state
.HasPublicKeyPins("example1.test"));
500 // Drop the includeSubdomains from the HSTS entry.
501 state
.AddHSTS("example1.test", expiry
, false);
503 EXPECT_FALSE(state
.ShouldUpgradeToSSL("foo.example1.test"));
504 EXPECT_TRUE(state
.HasPublicKeyPins("foo.example1.test"));
506 // Place an includeSubdomains HPKP entry below a normal HSTS entry.
507 state
.AddHSTS("foo.example2.test", expiry
, false);
508 state
.AddHPKP("example2.test", expiry
, true, GetSampleSPKIHashes(),
511 EXPECT_TRUE(state
.ShouldUpgradeToSSL("foo.example2.test"));
512 EXPECT_TRUE(state
.HasPublicKeyPins("foo.example2.test"));
514 // Drop the includeSubdomains from the HSTS entry.
515 state
.AddHPKP("example2.test", expiry
, false, GetSampleSPKIHashes(),
518 EXPECT_TRUE(state
.ShouldUpgradeToSSL("foo.example2.test"));
519 EXPECT_FALSE(state
.HasPublicKeyPins("foo.example2.test"));
522 // Tests that GetDynamic[PKP|STS]State returns the correct data and that the
523 // states are not mixed together.
524 TEST_F(TransportSecurityStateTest
, DynamicDomainState
) {
525 const GURL
report_uri(kReportUri
);
526 TransportSecurityState state
;
527 const base::Time
current_time(base::Time::Now());
528 const base::Time expiry1
= current_time
+ base::TimeDelta::FromSeconds(1000);
529 const base::Time expiry2
= current_time
+ base::TimeDelta::FromSeconds(2000);
531 state
.AddHSTS("example.com", expiry1
, true);
532 state
.AddHPKP("foo.example.com", expiry2
, false, GetSampleSPKIHashes(),
535 TransportSecurityState::STSState sts_state
;
536 TransportSecurityState::PKPState pkp_state
;
537 ASSERT_TRUE(state
.GetDynamicSTSState("foo.example.com", &sts_state
));
538 ASSERT_TRUE(state
.GetDynamicPKPState("foo.example.com", &pkp_state
));
539 EXPECT_TRUE(sts_state
.ShouldUpgradeToSSL());
540 EXPECT_TRUE(pkp_state
.HasPublicKeyPins());
541 EXPECT_TRUE(sts_state
.include_subdomains
);
542 EXPECT_FALSE(pkp_state
.include_subdomains
);
543 EXPECT_EQ(expiry1
, sts_state
.expiry
);
544 EXPECT_EQ(expiry2
, pkp_state
.expiry
);
545 EXPECT_EQ("example.com", sts_state
.domain
);
546 EXPECT_EQ("foo.example.com", pkp_state
.domain
);
549 // Tests that new pins always override previous pins. This should be true for
550 // both pins at the same domain or includeSubdomains pins at a parent domain.
551 TEST_F(TransportSecurityStateTest
, NewPinsOverride
) {
552 const GURL
report_uri(kReportUri
);
553 TransportSecurityState state
;
554 TransportSecurityState::PKPState pkp_state
;
555 const base::Time
current_time(base::Time::Now());
556 const base::Time expiry
= current_time
+ base::TimeDelta::FromSeconds(1000);
557 HashValue
hash1(HASH_VALUE_SHA1
);
558 memset(hash1
.data(), 0x01, hash1
.size());
559 HashValue
hash2(HASH_VALUE_SHA1
);
560 memset(hash2
.data(), 0x02, hash1
.size());
561 HashValue
hash3(HASH_VALUE_SHA1
);
562 memset(hash3
.data(), 0x03, hash1
.size());
564 state
.AddHPKP("example.com", expiry
, true, HashValueVector(1, hash1
),
567 ASSERT_TRUE(state
.GetDynamicPKPState("foo.example.com", &pkp_state
));
568 ASSERT_EQ(1u, pkp_state
.spki_hashes
.size());
569 EXPECT_TRUE(pkp_state
.spki_hashes
[0].Equals(hash1
));
571 state
.AddHPKP("foo.example.com", expiry
, false, HashValueVector(1, hash2
),
574 ASSERT_TRUE(state
.GetDynamicPKPState("foo.example.com", &pkp_state
));
575 ASSERT_EQ(1u, pkp_state
.spki_hashes
.size());
576 EXPECT_TRUE(pkp_state
.spki_hashes
[0].Equals(hash2
));
578 state
.AddHPKP("foo.example.com", expiry
, false, HashValueVector(1, hash3
),
581 ASSERT_TRUE(state
.GetDynamicPKPState("foo.example.com", &pkp_state
));
582 ASSERT_EQ(1u, pkp_state
.spki_hashes
.size());
583 EXPECT_TRUE(pkp_state
.spki_hashes
[0].Equals(hash3
));
586 TEST_F(TransportSecurityStateTest
, DeleteAllDynamicDataSince
) {
587 TransportSecurityState state
;
588 const base::Time
current_time(base::Time::Now());
589 const base::Time expiry
= current_time
+ base::TimeDelta::FromSeconds(1000);
590 const base::Time older
= current_time
- base::TimeDelta::FromSeconds(1000);
592 EXPECT_FALSE(state
.ShouldUpgradeToSSL("example.com"));
593 EXPECT_FALSE(state
.HasPublicKeyPins("example.com"));
594 bool include_subdomains
= false;
595 state
.AddHSTS("example.com", expiry
, include_subdomains
);
596 state
.AddHPKP("example.com", expiry
, include_subdomains
,
597 GetSampleSPKIHashes(), GURL());
599 state
.DeleteAllDynamicDataSince(expiry
);
600 EXPECT_TRUE(state
.ShouldUpgradeToSSL("example.com"));
601 EXPECT_TRUE(state
.HasPublicKeyPins("example.com"));
602 state
.DeleteAllDynamicDataSince(older
);
603 EXPECT_FALSE(state
.ShouldUpgradeToSSL("example.com"));
604 EXPECT_FALSE(state
.HasPublicKeyPins("example.com"));
606 // STS and PKP data in |state| should be empty now.
607 EXPECT_FALSE(TransportSecurityState::STSStateIterator(state
).HasNext());
608 EXPECT_FALSE(TransportSecurityState::PKPStateIterator(state
).HasNext());
611 TEST_F(TransportSecurityStateTest
, DeleteDynamicDataForHost
) {
612 TransportSecurityState state
;
613 const base::Time
current_time(base::Time::Now());
614 const base::Time expiry
= current_time
+ base::TimeDelta::FromSeconds(1000);
615 bool include_subdomains
= false;
617 state
.AddHSTS("example1.test", expiry
, include_subdomains
);
618 state
.AddHPKP("example1.test", expiry
, include_subdomains
,
619 GetSampleSPKIHashes(), GURL());
621 EXPECT_TRUE(state
.ShouldUpgradeToSSL("example1.test"));
622 EXPECT_FALSE(state
.ShouldUpgradeToSSL("example2.test"));
623 EXPECT_TRUE(state
.HasPublicKeyPins("example1.test"));
624 EXPECT_FALSE(state
.HasPublicKeyPins("example2.test"));
625 EXPECT_TRUE(state
.DeleteDynamicDataForHost("example1.test"));
626 EXPECT_FALSE(state
.ShouldUpgradeToSSL("example1.test"));
627 EXPECT_FALSE(state
.HasPublicKeyPins("example1.test"));
630 TEST_F(TransportSecurityStateTest
, EnableStaticPins
) {
631 TransportSecurityState state
;
632 TransportSecurityState::STSState sts_state
;
633 TransportSecurityState::PKPState pkp_state
;
635 EnableStaticPins(&state
);
638 state
.GetStaticDomainState("chrome.google.com", &sts_state
, &pkp_state
));
639 EXPECT_FALSE(pkp_state
.spki_hashes
.empty());
642 TEST_F(TransportSecurityStateTest
, DisableStaticPins
) {
643 TransportSecurityState state
;
644 TransportSecurityState::STSState sts_state
;
645 TransportSecurityState::PKPState pkp_state
;
647 DisableStaticPins(&state
);
649 state
.GetStaticDomainState("chrome.google.com", &sts_state
, &pkp_state
));
650 EXPECT_TRUE(pkp_state
.spki_hashes
.empty());
653 TEST_F(TransportSecurityStateTest
, IsPreloaded
) {
654 const std::string paypal
= "paypal.com";
655 const std::string www_paypal
= "www.paypal.com";
656 const std::string foo_paypal
= "foo.paypal.com";
657 const std::string a_www_paypal
= "a.www.paypal.com";
658 const std::string abc_paypal
= "a.b.c.paypal.com";
659 const std::string example
= "example.com";
660 const std::string aypal
= "aypal.com";
661 const std::string google
= "google";
662 const std::string www_google
= "www.google";
664 TransportSecurityState state
;
665 TransportSecurityState::STSState sts_state
;
666 TransportSecurityState::PKPState pkp_state
;
668 EXPECT_TRUE(GetStaticDomainState(&state
, paypal
, &sts_state
, &pkp_state
));
669 EXPECT_TRUE(GetStaticDomainState(&state
, www_paypal
, &sts_state
, &pkp_state
));
670 EXPECT_FALSE(sts_state
.include_subdomains
);
671 EXPECT_TRUE(GetStaticDomainState(&state
, google
, &sts_state
, &pkp_state
));
672 EXPECT_TRUE(GetStaticDomainState(&state
, www_google
, &sts_state
, &pkp_state
));
674 GetStaticDomainState(&state
, a_www_paypal
, &sts_state
, &pkp_state
));
676 GetStaticDomainState(&state
, abc_paypal
, &sts_state
, &pkp_state
));
677 EXPECT_FALSE(GetStaticDomainState(&state
, example
, &sts_state
, &pkp_state
));
678 EXPECT_FALSE(GetStaticDomainState(&state
, aypal
, &sts_state
, &pkp_state
));
681 TEST_F(TransportSecurityStateTest
, PreloadedDomainSet
) {
682 TransportSecurityState state
;
683 TransportSecurityState::STSState sts_state
;
684 TransportSecurityState::PKPState pkp_state
;
686 // The domain wasn't being set, leading to a blank string in the
687 // chrome://net-internals/#hsts UI. So test that.
689 state
.GetStaticDomainState("market.android.com", &sts_state
, &pkp_state
));
690 EXPECT_EQ(sts_state
.domain
, "market.android.com");
691 EXPECT_EQ(pkp_state
.domain
, "market.android.com");
692 EXPECT_TRUE(state
.GetStaticDomainState("sub.market.android.com", &sts_state
,
694 EXPECT_EQ(sts_state
.domain
, "market.android.com");
695 EXPECT_EQ(pkp_state
.domain
, "market.android.com");
698 static bool StaticShouldRedirect(const char* hostname
) {
699 TransportSecurityState state
;
700 TransportSecurityState::STSState sts_state
;
701 TransportSecurityState::PKPState pkp_state
;
702 return state
.GetStaticDomainState(hostname
, &sts_state
, &pkp_state
) &&
703 sts_state
.ShouldUpgradeToSSL();
706 static bool HasStaticState(const char* hostname
) {
707 TransportSecurityState state
;
708 TransportSecurityState::STSState sts_state
;
709 TransportSecurityState::PKPState pkp_state
;
710 return state
.GetStaticDomainState(hostname
, &sts_state
, &pkp_state
);
713 static bool HasStaticPublicKeyPins(const char* hostname
) {
714 TransportSecurityState state
;
715 TransportSecurityStateTest::EnableStaticPins(&state
);
716 TransportSecurityState::STSState sts_state
;
717 TransportSecurityState::PKPState pkp_state
;
718 if (!state
.GetStaticDomainState(hostname
, &sts_state
, &pkp_state
))
721 return pkp_state
.HasPublicKeyPins();
724 static bool OnlyPinningInStaticState(const char* hostname
) {
725 TransportSecurityState state
;
726 TransportSecurityStateTest::EnableStaticPins(&state
);
727 TransportSecurityState::STSState sts_state
;
728 TransportSecurityState::PKPState pkp_state
;
729 if (!state
.GetStaticDomainState(hostname
, &sts_state
, &pkp_state
))
732 return (pkp_state
.spki_hashes
.size() > 0 ||
733 pkp_state
.bad_spki_hashes
.size() > 0) &&
734 !sts_state
.ShouldUpgradeToSSL();
737 TEST_F(TransportSecurityStateTest
, Preloaded
) {
738 TransportSecurityState state
;
739 TransportSecurityState::STSState sts_state
;
740 TransportSecurityState::PKPState pkp_state
;
742 // We do more extensive checks for the first domain.
744 state
.GetStaticDomainState("www.paypal.com", &sts_state
, &pkp_state
));
745 EXPECT_EQ(sts_state
.upgrade_mode
,
746 TransportSecurityState::STSState::MODE_FORCE_HTTPS
);
747 EXPECT_FALSE(sts_state
.include_subdomains
);
748 EXPECT_FALSE(pkp_state
.include_subdomains
);
750 EXPECT_TRUE(HasStaticState("paypal.com"));
751 EXPECT_FALSE(HasStaticState("www2.paypal.com"));
755 EXPECT_TRUE(StaticShouldRedirect("chrome.google.com"));
756 EXPECT_TRUE(StaticShouldRedirect("checkout.google.com"));
757 EXPECT_TRUE(StaticShouldRedirect("wallet.google.com"));
758 EXPECT_TRUE(StaticShouldRedirect("docs.google.com"));
759 EXPECT_TRUE(StaticShouldRedirect("sites.google.com"));
760 EXPECT_TRUE(StaticShouldRedirect("drive.google.com"));
761 EXPECT_TRUE(StaticShouldRedirect("spreadsheets.google.com"));
762 EXPECT_TRUE(StaticShouldRedirect("appengine.google.com"));
763 EXPECT_TRUE(StaticShouldRedirect("market.android.com"));
764 EXPECT_TRUE(StaticShouldRedirect("encrypted.google.com"));
765 EXPECT_TRUE(StaticShouldRedirect("accounts.google.com"));
766 EXPECT_TRUE(StaticShouldRedirect("profiles.google.com"));
767 EXPECT_TRUE(StaticShouldRedirect("mail.google.com"));
768 EXPECT_TRUE(StaticShouldRedirect("chatenabled.mail.google.com"));
769 EXPECT_TRUE(StaticShouldRedirect("talkgadget.google.com"));
770 EXPECT_TRUE(StaticShouldRedirect("hostedtalkgadget.google.com"));
771 EXPECT_TRUE(StaticShouldRedirect("talk.google.com"));
772 EXPECT_TRUE(StaticShouldRedirect("plus.google.com"));
773 EXPECT_TRUE(StaticShouldRedirect("groups.google.com"));
774 EXPECT_TRUE(StaticShouldRedirect("apis.google.com"));
775 EXPECT_FALSE(StaticShouldRedirect("chart.apis.google.com"));
776 EXPECT_TRUE(StaticShouldRedirect("ssl.google-analytics.com"));
777 EXPECT_TRUE(StaticShouldRedirect("google"));
778 EXPECT_TRUE(StaticShouldRedirect("foo.google"));
779 EXPECT_TRUE(StaticShouldRedirect("gmail.com"));
780 EXPECT_TRUE(StaticShouldRedirect("www.gmail.com"));
781 EXPECT_TRUE(StaticShouldRedirect("googlemail.com"));
782 EXPECT_TRUE(StaticShouldRedirect("www.googlemail.com"));
783 EXPECT_TRUE(StaticShouldRedirect("googleplex.com"));
784 EXPECT_TRUE(StaticShouldRedirect("www.googleplex.com"));
786 // These domains used to be only HSTS when SNI was available.
787 EXPECT_TRUE(state
.GetStaticDomainState("gmail.com", &sts_state
, &pkp_state
));
789 state
.GetStaticDomainState("www.gmail.com", &sts_state
, &pkp_state
));
791 state
.GetStaticDomainState("googlemail.com", &sts_state
, &pkp_state
));
793 state
.GetStaticDomainState("www.googlemail.com", &sts_state
, &pkp_state
));
797 EXPECT_TRUE(StaticShouldRedirect("aladdinschools.appspot.com"));
799 EXPECT_TRUE(StaticShouldRedirect("ottospora.nl"));
800 EXPECT_TRUE(StaticShouldRedirect("www.ottospora.nl"));
802 EXPECT_TRUE(StaticShouldRedirect("www.paycheckrecords.com"));
804 EXPECT_TRUE(StaticShouldRedirect("lastpass.com"));
805 EXPECT_TRUE(StaticShouldRedirect("www.lastpass.com"));
806 EXPECT_FALSE(HasStaticState("blog.lastpass.com"));
808 EXPECT_TRUE(StaticShouldRedirect("keyerror.com"));
809 EXPECT_TRUE(StaticShouldRedirect("www.keyerror.com"));
811 EXPECT_TRUE(StaticShouldRedirect("entropia.de"));
812 EXPECT_TRUE(StaticShouldRedirect("www.entropia.de"));
813 EXPECT_FALSE(HasStaticState("foo.entropia.de"));
815 EXPECT_TRUE(StaticShouldRedirect("www.elanex.biz"));
816 EXPECT_FALSE(HasStaticState("elanex.biz"));
817 EXPECT_FALSE(HasStaticState("foo.elanex.biz"));
819 EXPECT_TRUE(StaticShouldRedirect("sunshinepress.org"));
820 EXPECT_TRUE(StaticShouldRedirect("www.sunshinepress.org"));
821 EXPECT_TRUE(StaticShouldRedirect("a.b.sunshinepress.org"));
823 EXPECT_TRUE(StaticShouldRedirect("www.noisebridge.net"));
824 EXPECT_FALSE(HasStaticState("noisebridge.net"));
825 EXPECT_FALSE(HasStaticState("foo.noisebridge.net"));
827 EXPECT_TRUE(StaticShouldRedirect("neg9.org"));
828 EXPECT_FALSE(HasStaticState("www.neg9.org"));
830 EXPECT_TRUE(StaticShouldRedirect("riseup.net"));
831 EXPECT_TRUE(StaticShouldRedirect("foo.riseup.net"));
833 EXPECT_TRUE(StaticShouldRedirect("factor.cc"));
834 EXPECT_FALSE(HasStaticState("www.factor.cc"));
836 EXPECT_TRUE(StaticShouldRedirect("members.mayfirst.org"));
837 EXPECT_TRUE(StaticShouldRedirect("support.mayfirst.org"));
838 EXPECT_TRUE(StaticShouldRedirect("id.mayfirst.org"));
839 EXPECT_TRUE(StaticShouldRedirect("lists.mayfirst.org"));
840 EXPECT_FALSE(HasStaticState("www.mayfirst.org"));
842 EXPECT_TRUE(StaticShouldRedirect("romab.com"));
843 EXPECT_TRUE(StaticShouldRedirect("www.romab.com"));
844 EXPECT_TRUE(StaticShouldRedirect("foo.romab.com"));
846 EXPECT_TRUE(StaticShouldRedirect("logentries.com"));
847 EXPECT_TRUE(StaticShouldRedirect("www.logentries.com"));
848 EXPECT_FALSE(HasStaticState("foo.logentries.com"));
850 EXPECT_TRUE(StaticShouldRedirect("stripe.com"));
851 EXPECT_TRUE(StaticShouldRedirect("foo.stripe.com"));
853 EXPECT_TRUE(StaticShouldRedirect("cloudsecurityalliance.org"));
854 EXPECT_TRUE(StaticShouldRedirect("foo.cloudsecurityalliance.org"));
856 EXPECT_TRUE(StaticShouldRedirect("login.sapo.pt"));
857 EXPECT_TRUE(StaticShouldRedirect("foo.login.sapo.pt"));
859 EXPECT_TRUE(StaticShouldRedirect("mattmccutchen.net"));
860 EXPECT_TRUE(StaticShouldRedirect("foo.mattmccutchen.net"));
862 EXPECT_TRUE(StaticShouldRedirect("betnet.fr"));
863 EXPECT_TRUE(StaticShouldRedirect("foo.betnet.fr"));
865 EXPECT_TRUE(StaticShouldRedirect("uprotect.it"));
866 EXPECT_TRUE(StaticShouldRedirect("foo.uprotect.it"));
868 EXPECT_TRUE(StaticShouldRedirect("squareup.com"));
869 EXPECT_FALSE(HasStaticState("foo.squareup.com"));
871 EXPECT_TRUE(StaticShouldRedirect("cert.se"));
872 EXPECT_TRUE(StaticShouldRedirect("foo.cert.se"));
874 EXPECT_TRUE(StaticShouldRedirect("crypto.is"));
875 EXPECT_TRUE(StaticShouldRedirect("foo.crypto.is"));
877 EXPECT_TRUE(StaticShouldRedirect("simon.butcher.name"));
878 EXPECT_TRUE(StaticShouldRedirect("foo.simon.butcher.name"));
880 EXPECT_TRUE(StaticShouldRedirect("linx.net"));
881 EXPECT_TRUE(StaticShouldRedirect("foo.linx.net"));
883 EXPECT_TRUE(StaticShouldRedirect("dropcam.com"));
884 EXPECT_TRUE(StaticShouldRedirect("www.dropcam.com"));
885 EXPECT_FALSE(HasStaticState("foo.dropcam.com"));
887 EXPECT_TRUE(StaticShouldRedirect("ebanking.indovinabank.com.vn"));
888 EXPECT_TRUE(StaticShouldRedirect("foo.ebanking.indovinabank.com.vn"));
890 EXPECT_TRUE(StaticShouldRedirect("epoxate.com"));
891 EXPECT_FALSE(HasStaticState("foo.epoxate.com"));
893 EXPECT_FALSE(HasStaticState("foo.torproject.org"));
895 EXPECT_TRUE(StaticShouldRedirect("www.moneybookers.com"));
896 EXPECT_FALSE(HasStaticState("moneybookers.com"));
898 EXPECT_TRUE(StaticShouldRedirect("ledgerscope.net"));
899 EXPECT_TRUE(StaticShouldRedirect("www.ledgerscope.net"));
900 EXPECT_FALSE(HasStaticState("status.ledgerscope.net"));
902 EXPECT_TRUE(StaticShouldRedirect("foo.app.recurly.com"));
903 EXPECT_TRUE(StaticShouldRedirect("foo.api.recurly.com"));
905 EXPECT_TRUE(StaticShouldRedirect("greplin.com"));
906 EXPECT_TRUE(StaticShouldRedirect("www.greplin.com"));
907 EXPECT_FALSE(HasStaticState("foo.greplin.com"));
909 EXPECT_TRUE(StaticShouldRedirect("luneta.nearbuysystems.com"));
910 EXPECT_TRUE(StaticShouldRedirect("foo.luneta.nearbuysystems.com"));
912 EXPECT_TRUE(StaticShouldRedirect("ubertt.org"));
913 EXPECT_TRUE(StaticShouldRedirect("foo.ubertt.org"));
915 EXPECT_TRUE(StaticShouldRedirect("pixi.me"));
916 EXPECT_TRUE(StaticShouldRedirect("www.pixi.me"));
918 EXPECT_TRUE(StaticShouldRedirect("grepular.com"));
919 EXPECT_TRUE(StaticShouldRedirect("www.grepular.com"));
921 EXPECT_TRUE(StaticShouldRedirect("mydigipass.com"));
922 EXPECT_FALSE(StaticShouldRedirect("foo.mydigipass.com"));
923 EXPECT_TRUE(StaticShouldRedirect("www.mydigipass.com"));
924 EXPECT_FALSE(StaticShouldRedirect("foo.www.mydigipass.com"));
925 EXPECT_TRUE(StaticShouldRedirect("developer.mydigipass.com"));
926 EXPECT_FALSE(StaticShouldRedirect("foo.developer.mydigipass.com"));
927 EXPECT_TRUE(StaticShouldRedirect("www.developer.mydigipass.com"));
928 EXPECT_FALSE(StaticShouldRedirect("foo.www.developer.mydigipass.com"));
929 EXPECT_TRUE(StaticShouldRedirect("sandbox.mydigipass.com"));
930 EXPECT_FALSE(StaticShouldRedirect("foo.sandbox.mydigipass.com"));
931 EXPECT_TRUE(StaticShouldRedirect("www.sandbox.mydigipass.com"));
932 EXPECT_FALSE(StaticShouldRedirect("foo.www.sandbox.mydigipass.com"));
934 EXPECT_TRUE(StaticShouldRedirect("bigshinylock.minazo.net"));
935 EXPECT_TRUE(StaticShouldRedirect("foo.bigshinylock.minazo.net"));
937 EXPECT_TRUE(StaticShouldRedirect("crate.io"));
938 EXPECT_TRUE(StaticShouldRedirect("foo.crate.io"));
941 TEST_F(TransportSecurityStateTest
, PreloadedPins
) {
942 TransportSecurityState state
;
943 EnableStaticPins(&state
);
944 TransportSecurityState::STSState sts_state
;
945 TransportSecurityState::PKPState pkp_state
;
947 // We do more extensive checks for the first domain.
949 state
.GetStaticDomainState("www.paypal.com", &sts_state
, &pkp_state
));
950 EXPECT_EQ(sts_state
.upgrade_mode
,
951 TransportSecurityState::STSState::MODE_FORCE_HTTPS
);
952 EXPECT_FALSE(sts_state
.include_subdomains
);
953 EXPECT_FALSE(pkp_state
.include_subdomains
);
955 EXPECT_TRUE(OnlyPinningInStaticState("www.google.com"));
956 EXPECT_TRUE(OnlyPinningInStaticState("foo.google.com"));
957 EXPECT_TRUE(OnlyPinningInStaticState("google.com"));
958 EXPECT_TRUE(OnlyPinningInStaticState("www.youtube.com"));
959 EXPECT_TRUE(OnlyPinningInStaticState("youtube.com"));
960 EXPECT_TRUE(OnlyPinningInStaticState("i.ytimg.com"));
961 EXPECT_TRUE(OnlyPinningInStaticState("ytimg.com"));
962 EXPECT_TRUE(OnlyPinningInStaticState("googleusercontent.com"));
963 EXPECT_TRUE(OnlyPinningInStaticState("www.googleusercontent.com"));
964 EXPECT_TRUE(OnlyPinningInStaticState("www.google-analytics.com"));
965 EXPECT_TRUE(OnlyPinningInStaticState("googleapis.com"));
966 EXPECT_TRUE(OnlyPinningInStaticState("googleadservices.com"));
967 EXPECT_TRUE(OnlyPinningInStaticState("googlecode.com"));
968 EXPECT_TRUE(OnlyPinningInStaticState("appspot.com"));
969 EXPECT_TRUE(OnlyPinningInStaticState("googlesyndication.com"));
970 EXPECT_TRUE(OnlyPinningInStaticState("doubleclick.net"));
971 EXPECT_TRUE(OnlyPinningInStaticState("googlegroups.com"));
973 EXPECT_TRUE(HasStaticPublicKeyPins("torproject.org"));
974 EXPECT_TRUE(HasStaticPublicKeyPins("www.torproject.org"));
975 EXPECT_TRUE(HasStaticPublicKeyPins("check.torproject.org"));
976 EXPECT_TRUE(HasStaticPublicKeyPins("blog.torproject.org"));
977 EXPECT_FALSE(HasStaticState("foo.torproject.org"));
980 state
.GetStaticDomainState("torproject.org", &sts_state
, &pkp_state
));
981 EXPECT_FALSE(pkp_state
.spki_hashes
.empty());
983 state
.GetStaticDomainState("www.torproject.org", &sts_state
, &pkp_state
));
984 EXPECT_FALSE(pkp_state
.spki_hashes
.empty());
985 EXPECT_TRUE(state
.GetStaticDomainState("check.torproject.org", &sts_state
,
987 EXPECT_FALSE(pkp_state
.spki_hashes
.empty());
988 EXPECT_TRUE(state
.GetStaticDomainState("blog.torproject.org", &sts_state
,
990 EXPECT_FALSE(pkp_state
.spki_hashes
.empty());
992 EXPECT_TRUE(HasStaticPublicKeyPins("www.twitter.com"));
994 // Check that Facebook subdomains have pinning but not HSTS.
996 state
.GetStaticDomainState("facebook.com", &sts_state
, &pkp_state
));
997 EXPECT_FALSE(pkp_state
.spki_hashes
.empty());
998 EXPECT_TRUE(StaticShouldRedirect("facebook.com"));
1001 state
.GetStaticDomainState("foo.facebook.com", &sts_state
, &pkp_state
));
1004 state
.GetStaticDomainState("www.facebook.com", &sts_state
, &pkp_state
));
1005 EXPECT_FALSE(pkp_state
.spki_hashes
.empty());
1006 EXPECT_TRUE(StaticShouldRedirect("www.facebook.com"));
1008 EXPECT_TRUE(state
.GetStaticDomainState("foo.www.facebook.com", &sts_state
,
1010 EXPECT_FALSE(pkp_state
.spki_hashes
.empty());
1011 EXPECT_TRUE(StaticShouldRedirect("foo.www.facebook.com"));
1014 TEST_F(TransportSecurityStateTest
, LongNames
) {
1015 TransportSecurityState state
;
1016 const char kLongName
[] =
1017 "lookupByWaveIdHashAndWaveIdIdAndWaveIdDomainAndWaveletIdIdAnd"
1018 "WaveletIdDomainAndBlipBlipid";
1019 TransportSecurityState::STSState sts_state
;
1020 TransportSecurityState::PKPState pkp_state
;
1021 // Just checks that we don't hit a NOTREACHED.
1022 EXPECT_FALSE(state
.GetStaticDomainState(kLongName
, &sts_state
, &pkp_state
));
1023 EXPECT_FALSE(state
.GetDynamicSTSState(kLongName
, &sts_state
));
1024 EXPECT_FALSE(state
.GetDynamicPKPState(kLongName
, &pkp_state
));
1027 TEST_F(TransportSecurityStateTest
, BuiltinCertPins
) {
1028 TransportSecurityState state
;
1029 EnableStaticPins(&state
);
1030 TransportSecurityState::STSState sts_state
;
1031 TransportSecurityState::PKPState pkp_state
;
1034 state
.GetStaticDomainState("chrome.google.com", &sts_state
, &pkp_state
));
1035 EXPECT_TRUE(HasStaticPublicKeyPins("chrome.google.com"));
1037 HashValueVector hashes
;
1038 std::string failure_log
;
1039 // Checks that a built-in list does exist.
1040 EXPECT_FALSE(pkp_state
.CheckPublicKeyPins(hashes
, &failure_log
));
1041 EXPECT_FALSE(HasStaticPublicKeyPins("www.paypal.com"));
1043 EXPECT_TRUE(HasStaticPublicKeyPins("docs.google.com"));
1044 EXPECT_TRUE(HasStaticPublicKeyPins("1.docs.google.com"));
1045 EXPECT_TRUE(HasStaticPublicKeyPins("sites.google.com"));
1046 EXPECT_TRUE(HasStaticPublicKeyPins("drive.google.com"));
1047 EXPECT_TRUE(HasStaticPublicKeyPins("spreadsheets.google.com"));
1048 EXPECT_TRUE(HasStaticPublicKeyPins("wallet.google.com"));
1049 EXPECT_TRUE(HasStaticPublicKeyPins("checkout.google.com"));
1050 EXPECT_TRUE(HasStaticPublicKeyPins("appengine.google.com"));
1051 EXPECT_TRUE(HasStaticPublicKeyPins("market.android.com"));
1052 EXPECT_TRUE(HasStaticPublicKeyPins("encrypted.google.com"));
1053 EXPECT_TRUE(HasStaticPublicKeyPins("accounts.google.com"));
1054 EXPECT_TRUE(HasStaticPublicKeyPins("profiles.google.com"));
1055 EXPECT_TRUE(HasStaticPublicKeyPins("mail.google.com"));
1056 EXPECT_TRUE(HasStaticPublicKeyPins("chatenabled.mail.google.com"));
1057 EXPECT_TRUE(HasStaticPublicKeyPins("talkgadget.google.com"));
1058 EXPECT_TRUE(HasStaticPublicKeyPins("hostedtalkgadget.google.com"));
1059 EXPECT_TRUE(HasStaticPublicKeyPins("talk.google.com"));
1060 EXPECT_TRUE(HasStaticPublicKeyPins("plus.google.com"));
1061 EXPECT_TRUE(HasStaticPublicKeyPins("groups.google.com"));
1062 EXPECT_TRUE(HasStaticPublicKeyPins("apis.google.com"));
1064 EXPECT_TRUE(HasStaticPublicKeyPins("ssl.gstatic.com"));
1065 EXPECT_TRUE(HasStaticPublicKeyPins("gstatic.com"));
1066 EXPECT_TRUE(HasStaticPublicKeyPins("www.gstatic.com"));
1067 EXPECT_TRUE(HasStaticPublicKeyPins("ssl.google-analytics.com"));
1068 EXPECT_TRUE(HasStaticPublicKeyPins("www.googleplex.com"));
1070 EXPECT_TRUE(HasStaticPublicKeyPins("twitter.com"));
1071 EXPECT_FALSE(HasStaticPublicKeyPins("foo.twitter.com"));
1072 EXPECT_TRUE(HasStaticPublicKeyPins("www.twitter.com"));
1073 EXPECT_TRUE(HasStaticPublicKeyPins("api.twitter.com"));
1074 EXPECT_TRUE(HasStaticPublicKeyPins("oauth.twitter.com"));
1075 EXPECT_TRUE(HasStaticPublicKeyPins("mobile.twitter.com"));
1076 EXPECT_TRUE(HasStaticPublicKeyPins("dev.twitter.com"));
1077 EXPECT_TRUE(HasStaticPublicKeyPins("business.twitter.com"));
1078 EXPECT_TRUE(HasStaticPublicKeyPins("platform.twitter.com"));
1079 EXPECT_TRUE(HasStaticPublicKeyPins("si0.twimg.com"));
1082 static bool AddHash(const std::string
& type_and_base64
,
1083 HashValueVector
* out
) {
1085 if (!hash
.FromString(type_and_base64
))
1088 out
->push_back(hash
);
1092 TEST_F(TransportSecurityStateTest
, PinValidationWithoutRejectedCerts
) {
1093 HashValueVector good_hashes
, bad_hashes
;
1095 for (size_t i
= 0; kGoodPath
[i
]; i
++) {
1096 EXPECT_TRUE(AddHash(kGoodPath
[i
], &good_hashes
));
1098 for (size_t i
= 0; kBadPath
[i
]; i
++) {
1099 EXPECT_TRUE(AddHash(kBadPath
[i
], &bad_hashes
));
1102 TransportSecurityState state
;
1103 EnableStaticPins(&state
);
1105 TransportSecurityState::STSState sts_state
;
1106 TransportSecurityState::PKPState pkp_state
;
1107 EXPECT_TRUE(state
.GetStaticDomainState("blog.torproject.org", &sts_state
,
1109 EXPECT_TRUE(pkp_state
.HasPublicKeyPins());
1111 std::string failure_log
;
1112 EXPECT_TRUE(pkp_state
.CheckPublicKeyPins(good_hashes
, &failure_log
));
1113 EXPECT_FALSE(pkp_state
.CheckPublicKeyPins(bad_hashes
, &failure_log
));
1116 TEST_F(TransportSecurityStateTest
, OptionalHSTSCertPins
) {
1117 TransportSecurityState state
;
1118 EnableStaticPins(&state
);
1120 EXPECT_FALSE(StaticShouldRedirect("www.google-analytics.com"));
1122 EXPECT_TRUE(HasStaticPublicKeyPins("www.google-analytics.com"));
1123 EXPECT_TRUE(HasStaticPublicKeyPins("google.com"));
1124 EXPECT_TRUE(HasStaticPublicKeyPins("www.google.com"));
1125 EXPECT_TRUE(HasStaticPublicKeyPins("mail-attachment.googleusercontent.com"));
1126 EXPECT_TRUE(HasStaticPublicKeyPins("www.youtube.com"));
1127 EXPECT_TRUE(HasStaticPublicKeyPins("i.ytimg.com"));
1128 EXPECT_TRUE(HasStaticPublicKeyPins("googleapis.com"));
1129 EXPECT_TRUE(HasStaticPublicKeyPins("ajax.googleapis.com"));
1130 EXPECT_TRUE(HasStaticPublicKeyPins("googleadservices.com"));
1131 EXPECT_TRUE(HasStaticPublicKeyPins("pagead2.googleadservices.com"));
1132 EXPECT_TRUE(HasStaticPublicKeyPins("googlecode.com"));
1133 EXPECT_TRUE(HasStaticPublicKeyPins("kibbles.googlecode.com"));
1134 EXPECT_TRUE(HasStaticPublicKeyPins("appspot.com"));
1135 EXPECT_TRUE(HasStaticPublicKeyPins("googlesyndication.com"));
1136 EXPECT_TRUE(HasStaticPublicKeyPins("doubleclick.net"));
1137 EXPECT_TRUE(HasStaticPublicKeyPins("ad.doubleclick.net"));
1138 EXPECT_FALSE(HasStaticPublicKeyPins("learn.doubleclick.net"));
1139 EXPECT_TRUE(HasStaticPublicKeyPins("a.googlegroups.com"));
1142 TEST_F(TransportSecurityStateTest
, OverrideBuiltins
) {
1143 EXPECT_TRUE(HasStaticPublicKeyPins("google.com"));
1144 EXPECT_FALSE(StaticShouldRedirect("google.com"));
1145 EXPECT_FALSE(StaticShouldRedirect("www.google.com"));
1147 TransportSecurityState state
;
1148 const base::Time
current_time(base::Time::Now());
1149 const base::Time expiry
= current_time
+ base::TimeDelta::FromSeconds(1000);
1150 state
.AddHSTS("www.google.com", expiry
, true);
1152 EXPECT_TRUE(state
.ShouldUpgradeToSSL("www.google.com"));
1155 TEST_F(TransportSecurityStateTest
, GooglePinnedProperties
) {
1156 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
1157 "www.example.com"));
1158 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
1160 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
1161 "mail.twitter.com"));
1162 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
1163 "www.google.com.int"));
1164 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
1166 // learn.doubleclick.net has a more specific match than
1167 // *.doubleclick.com, and has 0 or NULL for its required certs.
1168 // This test ensures that the exact-match-preferred behavior
1170 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
1171 "learn.doubleclick.net"));
1173 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
1174 "encrypted.google.com"));
1175 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
1176 "mail.google.com"));
1177 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
1178 "accounts.google.com"));
1179 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
1180 "doubleclick.net"));
1181 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
1182 "ad.doubleclick.net"));
1183 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
1185 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
1186 "www.profiles.google.com"));
1187 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
1188 "checkout.google.com"));
1189 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
1190 "googleadservices.com"));
1192 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
1193 "www.example.com"));
1194 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
1196 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
1197 "checkout.google.com"));
1198 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
1199 "googleadservices.com"));
1201 // Test some SNI hosts:
1202 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
1204 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
1205 "googlegroups.com"));
1206 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
1207 "www.googlegroups.com"));
1209 // These hosts used to only be HSTS when SNI was available.
1210 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
1212 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
1213 "googlegroups.com"));
1214 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
1215 "www.googlegroups.com"));
1218 TEST_F(TransportSecurityStateTest
, HPKPReporting
) {
1219 HostPortPair
host_port_pair(kHost
, kPort
);
1220 HostPortPair
subdomain_host_port_pair(kSubdomain
, kPort
);
1221 GURL
report_uri(kReportUri
);
1222 // Two dummy certs to use as the server-sent and validated chains. The
1223 // contents don't matter.
1224 scoped_refptr
<X509Certificate
> cert1
=
1225 ImportCertFromFile(GetTestCertsDirectory(), "test_mail_google_com.pem");
1226 scoped_refptr
<X509Certificate
> cert2
=
1227 ImportCertFromFile(GetTestCertsDirectory(), "expired_cert.pem");
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
, true, kHost
,
1277 cert1
.get(), cert2
.get(),
1279 mock_report_sender
.Clear();
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 true, kHost
, cert1
.get(), cert2
.get(),
1294 TEST_F(TransportSecurityStateTest
, HPKPReportOnly
) {
1295 HostPortPair
host_port_pair(kHost
, kPort
);
1296 GURL
report_uri(kReportUri
);
1297 // Two dummy certs to use as the server-sent and validated chains. The
1298 // contents don't matter.
1299 scoped_refptr
<X509Certificate
> cert1
=
1300 ImportCertFromFile(GetTestCertsDirectory(), "test_mail_google_com.pem");
1301 scoped_refptr
<X509Certificate
> cert2
=
1302 ImportCertFromFile(GetTestCertsDirectory(), "expired_cert.pem");
1306 TransportSecurityState state
;
1307 MockCertificateReportSender mock_report_sender
;
1308 state
.SetReportSender(&mock_report_sender
);
1310 // Check that a report is not sent for a Report-Only header with no
1312 std::string header
=
1313 "pin-sha1=\"" + std::string(kGoodPin1
) + "\";pin-sha1=\"" +
1314 std::string(kGoodPin2
) + "\";pin-sha1=\"" + std::string(kGoodPin3
) +
1315 "\";report-uri=\"" + report_uri
.spec() + "\";includeSubdomains";
1317 ssl_info
.is_issued_by_known_root
= true;
1318 ssl_info
.unverified_cert
= cert1
;
1319 ssl_info
.cert
= cert2
;
1320 for (size_t i
= 0; kGoodPath
[i
]; i
++)
1321 EXPECT_TRUE(AddHash(kGoodPath
[i
], &ssl_info
.public_key_hashes
));
1324 state
.ProcessHPKPReportOnlyHeader(header
, host_port_pair
, ssl_info
));
1325 EXPECT_EQ(GURL(), mock_report_sender
.latest_report_uri());
1326 EXPECT_EQ(std::string(), mock_report_sender
.latest_report());
1328 // Check that a report is sent for a Report-Only header with a
1330 ssl_info
.public_key_hashes
.clear();
1331 for (size_t i
= 0; kBadPath
[i
]; i
++)
1332 EXPECT_TRUE(AddHash(kBadPath
[i
], &ssl_info
.public_key_hashes
));
1335 state
.ProcessHPKPReportOnlyHeader(header
, host_port_pair
, ssl_info
));
1336 EXPECT_EQ(report_uri
, mock_report_sender
.latest_report_uri());
1337 std::string report
= mock_report_sender
.latest_report();
1338 ASSERT_FALSE(report
.empty());
1339 ASSERT_NO_FATAL_FAILURE(CheckHPKPReport(report
, host_port_pair
, true, kHost
,
1340 cert1
.get(), cert2
.get(),
1341 ssl_info
.public_key_hashes
));
1344 // Test that Report-Only reports are not sent on certs that chain to
1346 TEST_F(TransportSecurityStateTest
, HPKPReportOnlyOnLocalRoot
) {
1347 HostPortPair
host_port_pair(kHost
, kPort
);
1348 GURL
report_uri(kReportUri
);
1349 // Two dummy certs to use as the server-sent and validated chains. The
1350 // contents don't matter.
1351 scoped_refptr
<X509Certificate
> cert1
=
1352 ImportCertFromFile(GetTestCertsDirectory(), "test_mail_google_com.pem");
1353 scoped_refptr
<X509Certificate
> cert2
=
1354 ImportCertFromFile(GetTestCertsDirectory(), "expired_cert.pem");
1358 std::string header
=
1359 "pin-sha1=\"" + std::string(kGoodPin1
) + "\";pin-sha1=\"" +
1360 std::string(kGoodPin2
) + "\";pin-sha1=\"" + std::string(kGoodPin3
) +
1361 "\";report-uri=\"" + report_uri
.spec() + "\";includeSubdomains";
1363 TransportSecurityState state
;
1364 MockCertificateReportSender mock_report_sender
;
1365 state
.SetReportSender(&mock_report_sender
);
1368 ssl_info
.is_issued_by_known_root
= true;
1369 ssl_info
.unverified_cert
= cert1
;
1370 ssl_info
.cert
= cert2
;
1371 for (size_t i
= 0; kGoodPath
[i
]; i
++)
1372 EXPECT_TRUE(AddHash(kGoodPath
[i
], &ssl_info
.public_key_hashes
));
1373 ssl_info
.is_issued_by_known_root
= false;
1376 state
.ProcessHPKPReportOnlyHeader(header
, host_port_pair
, ssl_info
));
1377 EXPECT_EQ(GURL(), mock_report_sender
.latest_report_uri());
1378 EXPECT_EQ(std::string(), mock_report_sender
.latest_report());
1381 // Test that ProcessHPKPReportOnlyHeader() returns false if a report-uri
1382 // wasn't specified or if the header fails to parse.
1383 TEST_F(TransportSecurityStateTest
, HPKPReportOnlyParseErrors
) {
1384 HostPortPair
host_port_pair(kHost
, kPort
);
1385 GURL
report_uri(kReportUri
);
1386 // Two dummy certs to use as the server-sent and validated chains. The
1387 // contents don't matter.
1388 scoped_refptr
<X509Certificate
> cert1
=
1389 ImportCertFromFile(GetTestCertsDirectory(), "test_mail_google_com.pem");
1390 scoped_refptr
<X509Certificate
> cert2
=
1391 ImportCertFromFile(GetTestCertsDirectory(), "expired_cert.pem");
1395 std::string header
= "pin-sha1=\"" + std::string(kGoodPin1
) +
1396 "\";pin-sha1=\"" + std::string(kGoodPin2
) +
1397 "\";pin-sha1=\"" + std::string(kGoodPin3
) + "\"";
1399 TransportSecurityState state
;
1400 MockCertificateReportSender mock_report_sender
;
1401 state
.SetReportSender(&mock_report_sender
);
1404 ssl_info
.is_issued_by_known_root
= true;
1405 ssl_info
.unverified_cert
= cert1
;
1406 ssl_info
.cert
= cert2
;
1407 for (size_t i
= 0; kGoodPath
[i
]; i
++)
1408 EXPECT_TRUE(AddHash(kGoodPath
[i
], &ssl_info
.public_key_hashes
));
1411 state
.ProcessHPKPReportOnlyHeader(header
, host_port_pair
, ssl_info
));
1412 header
+= ";report-uri=\"";
1414 state
.ProcessHPKPReportOnlyHeader(header
, host_port_pair
, ssl_info
));