OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/http/transport_security_state.h" | 5 #include "net/http/transport_security_state.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <string> | 8 #include <string> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
11 #include "base/base64.h" | 11 #include "base/base64.h" |
12 #include "base/files/file_path.h" | 12 #include "base/files/file_path.h" |
| 13 #include "base/json/json_reader.h" |
13 #include "base/rand_util.h" | 14 #include "base/rand_util.h" |
14 #include "base/sha1.h" | 15 #include "base/sha1.h" |
15 #include "base/strings/string_piece.h" | 16 #include "base/strings/string_piece.h" |
| 17 #include "base/values.h" |
16 #include "crypto/sha2.h" | 18 #include "crypto/sha2.h" |
17 #include "net/base/net_errors.h" | 19 #include "net/base/net_errors.h" |
18 #include "net/base/test_completion_callback.h" | 20 #include "net/base/test_completion_callback.h" |
19 #include "net/base/test_data_directory.h" | 21 #include "net/base/test_data_directory.h" |
20 #include "net/cert/asn1_util.h" | 22 #include "net/cert/asn1_util.h" |
21 #include "net/cert/cert_verifier.h" | 23 #include "net/cert/cert_verifier.h" |
22 #include "net/cert/cert_verify_result.h" | 24 #include "net/cert/cert_verify_result.h" |
23 #include "net/cert/test_root_certs.h" | 25 #include "net/cert/test_root_certs.h" |
24 #include "net/cert/x509_cert_types.h" | 26 #include "net/cert/x509_cert_types.h" |
25 #include "net/cert/x509_certificate.h" | 27 #include "net/cert/x509_certificate.h" |
| 28 #include "net/http/certificate_report_sender.h" |
26 #include "net/http/http_util.h" | 29 #include "net/http/http_util.h" |
| 30 #include "net/http/transport_security_reporter.h" |
27 #include "net/log/net_log.h" | 31 #include "net/log/net_log.h" |
28 #include "net/ssl/ssl_info.h" | 32 #include "net/ssl/ssl_info.h" |
29 #include "net/test/cert_test_util.h" | 33 #include "net/test/cert_test_util.h" |
30 #include "testing/gtest/include/gtest/gtest.h" | 34 #include "testing/gtest/include/gtest/gtest.h" |
31 | 35 |
32 #if defined(USE_OPENSSL) | 36 #if defined(USE_OPENSSL) |
33 #include "crypto/openssl_util.h" | 37 #include "crypto/openssl_util.h" |
34 #else | 38 #else |
35 #include "crypto/nss_util.h" | 39 #include "crypto/nss_util.h" |
36 #endif | 40 #endif |
37 | 41 |
| 42 namespace { |
| 43 |
| 44 // A mock CertificateReportSender that just remembers the latest report |
| 45 // URI and report to be sent. |
| 46 class MockCertificateReportSender : public net::CertificateReportSender { |
| 47 public: |
| 48 MockCertificateReportSender() {} |
| 49 ~MockCertificateReportSender() override {} |
| 50 |
| 51 void Send(const GURL& report_uri, const std::string& report) override { |
| 52 latest_report_uri_ = report_uri; |
| 53 latest_report_ = report; |
| 54 } |
| 55 |
| 56 const GURL& latest_report_uri() { return latest_report_uri_; } |
| 57 const std::string& latest_report() { return latest_report_; } |
| 58 |
| 59 private: |
| 60 GURL latest_report_uri_; |
| 61 std::string latest_report_; |
| 62 }; |
| 63 |
| 64 void CompareCertificateChainWithList( |
| 65 const scoped_refptr<net::X509Certificate>& cert_chain, |
| 66 const base::ListValue* cert_list) { |
| 67 ASSERT_TRUE(cert_chain); |
| 68 std::vector<std::string> pem_encoded_chain; |
| 69 cert_chain->GetPEMEncodedChain(&pem_encoded_chain); |
| 70 EXPECT_EQ(pem_encoded_chain.size(), cert_list->GetSize()); |
| 71 |
| 72 for (size_t i = 0; i < pem_encoded_chain.size(); i++) { |
| 73 std::string list_cert; |
| 74 ASSERT_TRUE(cert_list->GetString(i, &list_cert)); |
| 75 EXPECT_EQ(pem_encoded_chain[i], list_cert); |
| 76 } |
| 77 } |
| 78 |
| 79 void CheckHPKPReport( |
| 80 const std::string& report, |
| 81 const std::string& hostname, |
| 82 uint16_t port, |
| 83 const base::Time& expiry, |
| 84 bool include_subdomains, |
| 85 const std::string& noted_hostname, |
| 86 const scoped_refptr<net::X509Certificate>& served_certificate_chain, |
| 87 const scoped_refptr<net::X509Certificate>& validated_certificate_chain, |
| 88 const net::HashValueVector& known_pins) { |
| 89 // TODO(estark): check time in RFC3339 format. |
| 90 |
| 91 scoped_ptr<base::Value> value(base::JSONReader::Read(report)); |
| 92 ASSERT_TRUE(value); |
| 93 ASSERT_TRUE(value->IsType(base::Value::TYPE_DICTIONARY)); |
| 94 |
| 95 scoped_ptr<base::DictionaryValue> report_dict( |
| 96 static_cast<base::DictionaryValue*>(value.release())); |
| 97 |
| 98 std::string report_hostname; |
| 99 EXPECT_TRUE(report_dict->GetString("hostname", &report_hostname)); |
| 100 EXPECT_EQ(hostname, report_hostname); |
| 101 |
| 102 int report_port; |
| 103 EXPECT_TRUE(report_dict->GetInteger("port", &report_port)); |
| 104 EXPECT_EQ(port, report_port); |
| 105 |
| 106 bool report_include_subdomains; |
| 107 EXPECT_TRUE(report_dict->GetBoolean("include-subdomains", |
| 108 &report_include_subdomains)); |
| 109 EXPECT_EQ(include_subdomains, report_include_subdomains); |
| 110 |
| 111 std::string report_noted_hostname; |
| 112 EXPECT_TRUE(report_dict->GetString("hostname", &report_noted_hostname)); |
| 113 EXPECT_EQ(hostname, report_noted_hostname); |
| 114 |
| 115 base::ListValue* report_served_certificate_chain; |
| 116 EXPECT_TRUE(report_dict->GetList("served-certificate-chain", |
| 117 &report_served_certificate_chain)); |
| 118 CompareCertificateChainWithList(served_certificate_chain, |
| 119 report_served_certificate_chain); |
| 120 |
| 121 base::ListValue* report_validated_certificate_chain; |
| 122 EXPECT_TRUE(report_dict->GetList("validated-certificate-chain", |
| 123 &report_validated_certificate_chain)); |
| 124 CompareCertificateChainWithList(validated_certificate_chain, |
| 125 report_validated_certificate_chain); |
| 126 } |
| 127 |
| 128 } // namespace |
| 129 |
38 namespace net { | 130 namespace net { |
39 | 131 |
40 class TransportSecurityStateTest : public testing::Test { | 132 class TransportSecurityStateTest : public testing::Test { |
41 public: | 133 public: |
42 void SetUp() override { | 134 void SetUp() override { |
43 #if defined(USE_OPENSSL) | 135 #if defined(USE_OPENSSL) |
44 crypto::EnsureOpenSSLInit(); | 136 crypto::EnsureOpenSSLInit(); |
45 #else | 137 #else |
46 crypto::EnsureNSSInit(); | 138 crypto::EnsureNSSInit(); |
47 #endif | 139 #endif |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
205 EXPECT_TRUE(state.ShouldUpgradeToSSL("foo.bar.example.test")); | 297 EXPECT_TRUE(state.ShouldUpgradeToSSL("foo.bar.example.test")); |
206 EXPECT_TRUE(state.ShouldUpgradeToSSL("foo.bar.baz.example.test")); | 298 EXPECT_TRUE(state.ShouldUpgradeToSSL("foo.bar.baz.example.test")); |
207 EXPECT_FALSE(state.ShouldUpgradeToSSL("test")); | 299 EXPECT_FALSE(state.ShouldUpgradeToSSL("test")); |
208 EXPECT_FALSE(state.ShouldUpgradeToSSL("notexample.test")); | 300 EXPECT_FALSE(state.ShouldUpgradeToSSL("notexample.test")); |
209 } | 301 } |
210 | 302 |
211 // Tests that a more-specific HSTS or HPKP rule overrides a less-specific rule | 303 // Tests that a more-specific HSTS or HPKP rule overrides a less-specific rule |
212 // with it, regardless of the includeSubDomains bit. This is a regression test | 304 // with it, regardless of the includeSubDomains bit. This is a regression test |
213 // for https://crbug.com/469957. | 305 // for https://crbug.com/469957. |
214 TEST_F(TransportSecurityStateTest, SubdomainCarveout) { | 306 TEST_F(TransportSecurityStateTest, SubdomainCarveout) { |
| 307 static const char kReportUri[] = "http://example.com/test"; |
| 308 std::string report_uri(kReportUri); |
| 309 |
215 TransportSecurityState state; | 310 TransportSecurityState state; |
216 const base::Time current_time(base::Time::Now()); | 311 const base::Time current_time(base::Time::Now()); |
217 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000); | 312 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000); |
218 const base::Time older = current_time - base::TimeDelta::FromSeconds(1000); | 313 const base::Time older = current_time - base::TimeDelta::FromSeconds(1000); |
219 | 314 |
220 state.AddHSTS("example1.test", expiry, true); | 315 state.AddHSTS("example1.test", expiry, true); |
221 state.AddHSTS("foo.example1.test", expiry, false); | 316 state.AddHSTS("foo.example1.test", expiry, false); |
222 | 317 |
223 state.AddHPKP("example2.test", expiry, true, GetSampleSPKIHashes()); | 318 state.AddHPKP("example2.test", expiry, true, GetSampleSPKIHashes(), |
224 state.AddHPKP("foo.example2.test", expiry, false, GetSampleSPKIHashes()); | 319 report_uri); |
| 320 state.AddHPKP("foo.example2.test", expiry, false, GetSampleSPKIHashes(), |
| 321 report_uri); |
225 | 322 |
226 EXPECT_TRUE(state.ShouldUpgradeToSSL("example1.test")); | 323 EXPECT_TRUE(state.ShouldUpgradeToSSL("example1.test")); |
227 EXPECT_TRUE(state.ShouldUpgradeToSSL("foo.example1.test")); | 324 EXPECT_TRUE(state.ShouldUpgradeToSSL("foo.example1.test")); |
228 | 325 |
229 // The foo.example1.test rule overrides the example1.test rule, so | 326 // The foo.example1.test rule overrides the example1.test rule, so |
230 // bar.foo.example1.test has no HSTS state. | 327 // bar.foo.example1.test has no HSTS state. |
231 EXPECT_FALSE(state.ShouldUpgradeToSSL("bar.foo.example1.test")); | 328 EXPECT_FALSE(state.ShouldUpgradeToSSL("bar.foo.example1.test")); |
232 EXPECT_FALSE(state.ShouldSSLErrorsBeFatal("bar.foo.example1.test")); | 329 EXPECT_FALSE(state.ShouldSSLErrorsBeFatal("bar.foo.example1.test")); |
233 | 330 |
234 EXPECT_TRUE(state.HasPublicKeyPins("example2.test")); | 331 EXPECT_TRUE(state.HasPublicKeyPins("example2.test")); |
235 EXPECT_TRUE(state.HasPublicKeyPins("foo.example2.test")); | 332 EXPECT_TRUE(state.HasPublicKeyPins("foo.example2.test")); |
236 | 333 |
237 // The foo.example2.test rule overrides the example1.test rule, so | 334 // The foo.example2.test rule overrides the example1.test rule, so |
238 // bar.foo.example2.test has no HPKP state. | 335 // bar.foo.example2.test has no HPKP state. |
239 EXPECT_FALSE(state.HasPublicKeyPins("bar.foo.example2.test")); | 336 EXPECT_FALSE(state.HasPublicKeyPins("bar.foo.example2.test")); |
240 EXPECT_FALSE(state.ShouldSSLErrorsBeFatal("bar.foo.example2.test")); | 337 EXPECT_FALSE(state.ShouldSSLErrorsBeFatal("bar.foo.example2.test")); |
241 | 338 |
242 // Expire the foo.example*.test rules. | 339 // Expire the foo.example*.test rules. |
243 state.AddHSTS("foo.example1.test", older, false); | 340 state.AddHSTS("foo.example1.test", older, false); |
244 state.AddHPKP("foo.example2.test", older, false, GetSampleSPKIHashes()); | 341 state.AddHPKP("foo.example2.test", older, false, GetSampleSPKIHashes(), |
| 342 report_uri); |
245 | 343 |
246 // Now the base example*.test rules apply to bar.foo.example*.test. | 344 // Now the base example*.test rules apply to bar.foo.example*.test. |
247 EXPECT_TRUE(state.ShouldUpgradeToSSL("bar.foo.example1.test")); | 345 EXPECT_TRUE(state.ShouldUpgradeToSSL("bar.foo.example1.test")); |
248 EXPECT_TRUE(state.ShouldSSLErrorsBeFatal("bar.foo.example1.test")); | 346 EXPECT_TRUE(state.ShouldSSLErrorsBeFatal("bar.foo.example1.test")); |
249 EXPECT_TRUE(state.HasPublicKeyPins("bar.foo.example2.test")); | 347 EXPECT_TRUE(state.HasPublicKeyPins("bar.foo.example2.test")); |
250 EXPECT_TRUE(state.ShouldSSLErrorsBeFatal("bar.foo.example2.test")); | 348 EXPECT_TRUE(state.ShouldSSLErrorsBeFatal("bar.foo.example2.test")); |
251 } | 349 } |
252 | 350 |
253 TEST_F(TransportSecurityStateTest, FatalSSLErrors) { | 351 TEST_F(TransportSecurityStateTest, FatalSSLErrors) { |
| 352 static const char kReportUri[] = "http://example.com/test"; |
| 353 std::string report_uri(kReportUri); |
| 354 |
254 TransportSecurityState state; | 355 TransportSecurityState state; |
255 const base::Time current_time(base::Time::Now()); | 356 const base::Time current_time(base::Time::Now()); |
256 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000); | 357 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000); |
257 | 358 |
258 state.AddHSTS("example1.test", expiry, false); | 359 state.AddHSTS("example1.test", expiry, false); |
259 state.AddHPKP("example2.test", expiry, false, GetSampleSPKIHashes()); | 360 state.AddHPKP("example2.test", expiry, false, GetSampleSPKIHashes(), |
| 361 report_uri); |
260 | 362 |
261 // The presense of either HSTS or HPKP is enough to make SSL errors fatal. | 363 // The presense of either HSTS or HPKP is enough to make SSL errors fatal. |
262 EXPECT_TRUE(state.ShouldSSLErrorsBeFatal("example1.test")); | 364 EXPECT_TRUE(state.ShouldSSLErrorsBeFatal("example1.test")); |
263 EXPECT_TRUE(state.ShouldSSLErrorsBeFatal("example2.test")); | 365 EXPECT_TRUE(state.ShouldSSLErrorsBeFatal("example2.test")); |
264 } | 366 } |
265 | 367 |
266 // Tests that HPKP and HSTS state both expire. Also tests that expired entries | 368 // Tests that HPKP and HSTS state both expire. Also tests that expired entries |
267 // are pruned. | 369 // are pruned. |
268 TEST_F(TransportSecurityStateTest, Expiration) { | 370 TEST_F(TransportSecurityStateTest, Expiration) { |
| 371 static const char kReportUri[] = "http://example.com/test"; |
| 372 std::string report_uri(kReportUri); |
| 373 |
269 TransportSecurityState state; | 374 TransportSecurityState state; |
270 const base::Time current_time(base::Time::Now()); | 375 const base::Time current_time(base::Time::Now()); |
271 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000); | 376 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000); |
272 const base::Time older = current_time - base::TimeDelta::FromSeconds(1000); | 377 const base::Time older = current_time - base::TimeDelta::FromSeconds(1000); |
273 | 378 |
274 // Note: this test assumes that inserting an entry with an expiration time in | 379 // Note: this test assumes that inserting an entry with an expiration time in |
275 // the past works and is pruned on query. | 380 // the past works and is pruned on query. |
276 state.AddHSTS("example1.test", older, false); | 381 state.AddHSTS("example1.test", older, false); |
277 EXPECT_TRUE(TransportSecurityState::Iterator(state).HasNext()); | 382 EXPECT_TRUE(TransportSecurityState::Iterator(state).HasNext()); |
278 EXPECT_FALSE(state.ShouldUpgradeToSSL("example1.test")); | 383 EXPECT_FALSE(state.ShouldUpgradeToSSL("example1.test")); |
279 // Querying |state| for a domain should flush out expired entries. | 384 // Querying |state| for a domain should flush out expired entries. |
280 EXPECT_FALSE(TransportSecurityState::Iterator(state).HasNext()); | 385 EXPECT_FALSE(TransportSecurityState::Iterator(state).HasNext()); |
281 | 386 |
282 state.AddHPKP("example1.test", older, false, GetSampleSPKIHashes()); | 387 state.AddHPKP("example1.test", older, false, GetSampleSPKIHashes(), |
| 388 report_uri); |
283 EXPECT_TRUE(TransportSecurityState::Iterator(state).HasNext()); | 389 EXPECT_TRUE(TransportSecurityState::Iterator(state).HasNext()); |
284 EXPECT_FALSE(state.HasPublicKeyPins("example1.test")); | 390 EXPECT_FALSE(state.HasPublicKeyPins("example1.test")); |
285 // Querying |state| for a domain should flush out expired entries. | 391 // Querying |state| for a domain should flush out expired entries. |
286 EXPECT_FALSE(TransportSecurityState::Iterator(state).HasNext()); | 392 EXPECT_FALSE(TransportSecurityState::Iterator(state).HasNext()); |
287 | 393 |
288 state.AddHSTS("example1.test", older, false); | 394 state.AddHSTS("example1.test", older, false); |
289 state.AddHPKP("example1.test", older, false, GetSampleSPKIHashes()); | 395 state.AddHPKP("example1.test", older, false, GetSampleSPKIHashes(), |
| 396 report_uri); |
290 EXPECT_TRUE(TransportSecurityState::Iterator(state).HasNext()); | 397 EXPECT_TRUE(TransportSecurityState::Iterator(state).HasNext()); |
291 EXPECT_FALSE(state.ShouldSSLErrorsBeFatal("example1.test")); | 398 EXPECT_FALSE(state.ShouldSSLErrorsBeFatal("example1.test")); |
292 // Querying |state| for a domain should flush out expired entries. | 399 // Querying |state| for a domain should flush out expired entries. |
293 EXPECT_FALSE(TransportSecurityState::Iterator(state).HasNext()); | 400 EXPECT_FALSE(TransportSecurityState::Iterator(state).HasNext()); |
294 | 401 |
295 // Test that HSTS can outlive HPKP. | 402 // Test that HSTS can outlive HPKP. |
296 state.AddHSTS("example1.test", expiry, false); | 403 state.AddHSTS("example1.test", expiry, false); |
297 state.AddHPKP("example1.test", older, false, GetSampleSPKIHashes()); | 404 state.AddHPKP("example1.test", older, false, GetSampleSPKIHashes(), |
| 405 report_uri); |
298 EXPECT_TRUE(state.ShouldUpgradeToSSL("example1.test")); | 406 EXPECT_TRUE(state.ShouldUpgradeToSSL("example1.test")); |
299 EXPECT_FALSE(state.HasPublicKeyPins("example1.test")); | 407 EXPECT_FALSE(state.HasPublicKeyPins("example1.test")); |
300 | 408 |
301 // Test that HPKP can outlive HSTS. | 409 // Test that HPKP can outlive HSTS. |
302 state.AddHSTS("example2.test", older, false); | 410 state.AddHSTS("example2.test", older, false); |
303 state.AddHPKP("example2.test", expiry, false, GetSampleSPKIHashes()); | 411 state.AddHPKP("example2.test", expiry, false, GetSampleSPKIHashes(), |
| 412 report_uri); |
304 EXPECT_FALSE(state.ShouldUpgradeToSSL("example2.test")); | 413 EXPECT_FALSE(state.ShouldUpgradeToSSL("example2.test")); |
305 EXPECT_TRUE(state.HasPublicKeyPins("example2.test")); | 414 EXPECT_TRUE(state.HasPublicKeyPins("example2.test")); |
306 } | 415 } |
307 | 416 |
308 TEST_F(TransportSecurityStateTest, InvalidDomains) { | 417 TEST_F(TransportSecurityStateTest, InvalidDomains) { |
309 TransportSecurityState state; | 418 TransportSecurityState state; |
310 const base::Time current_time(base::Time::Now()); | 419 const base::Time current_time(base::Time::Now()); |
311 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000); | 420 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000); |
312 | 421 |
313 EXPECT_FALSE(state.ShouldUpgradeToSSL("example.test")); | 422 EXPECT_FALSE(state.ShouldUpgradeToSSL("example.test")); |
314 bool include_subdomains = true; | 423 bool include_subdomains = true; |
315 state.AddHSTS("example.test", expiry, include_subdomains); | 424 state.AddHSTS("example.test", expiry, include_subdomains); |
316 EXPECT_TRUE(state.ShouldUpgradeToSSL("www-.foo.example.test")); | 425 EXPECT_TRUE(state.ShouldUpgradeToSSL("www-.foo.example.test")); |
317 EXPECT_TRUE(state.ShouldUpgradeToSSL("2\x01.foo.example.test")); | 426 EXPECT_TRUE(state.ShouldUpgradeToSSL("2\x01.foo.example.test")); |
318 } | 427 } |
319 | 428 |
320 // Tests that HPKP and HSTS state are queried independently for subdomain | 429 // Tests that HPKP and HSTS state are queried independently for subdomain |
321 // matches. | 430 // matches. |
322 TEST_F(TransportSecurityStateTest, IndependentSubdomain) { | 431 TEST_F(TransportSecurityStateTest, IndependentSubdomain) { |
| 432 static const char kReportUri[] = "http://example.com/test"; |
| 433 std::string report_uri(kReportUri); |
| 434 |
323 TransportSecurityState state; | 435 TransportSecurityState state; |
324 const base::Time current_time(base::Time::Now()); | 436 const base::Time current_time(base::Time::Now()); |
325 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000); | 437 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000); |
326 | 438 |
327 state.AddHSTS("example1.test", expiry, true); | 439 state.AddHSTS("example1.test", expiry, true); |
328 state.AddHPKP("example1.test", expiry, false, GetSampleSPKIHashes()); | 440 state.AddHPKP("example1.test", expiry, false, GetSampleSPKIHashes(), |
| 441 report_uri); |
329 | 442 |
330 state.AddHSTS("example2.test", expiry, false); | 443 state.AddHSTS("example2.test", expiry, false); |
331 state.AddHPKP("example2.test", expiry, true, GetSampleSPKIHashes()); | 444 state.AddHPKP("example2.test", expiry, true, GetSampleSPKIHashes(), |
| 445 report_uri); |
332 | 446 |
333 EXPECT_TRUE(state.ShouldUpgradeToSSL("foo.example1.test")); | 447 EXPECT_TRUE(state.ShouldUpgradeToSSL("foo.example1.test")); |
334 EXPECT_FALSE(state.HasPublicKeyPins("foo.example1.test")); | 448 EXPECT_FALSE(state.HasPublicKeyPins("foo.example1.test")); |
335 EXPECT_FALSE(state.ShouldUpgradeToSSL("foo.example2.test")); | 449 EXPECT_FALSE(state.ShouldUpgradeToSSL("foo.example2.test")); |
336 EXPECT_TRUE(state.HasPublicKeyPins("foo.example2.test")); | 450 EXPECT_TRUE(state.HasPublicKeyPins("foo.example2.test")); |
337 } | 451 } |
338 | 452 |
339 // Tests that HPKP and HSTS state are inserted and overridden independently. | 453 // Tests that HPKP and HSTS state are inserted and overridden independently. |
340 TEST_F(TransportSecurityStateTest, IndependentInsertion) { | 454 TEST_F(TransportSecurityStateTest, IndependentInsertion) { |
| 455 static const char kReportUri[] = "http://example.com/test"; |
| 456 std::string report_uri(kReportUri); |
| 457 |
341 TransportSecurityState state; | 458 TransportSecurityState state; |
342 const base::Time current_time(base::Time::Now()); | 459 const base::Time current_time(base::Time::Now()); |
343 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000); | 460 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000); |
344 | 461 |
345 // Place an includeSubdomains HSTS entry below a normal HPKP entry. | 462 // Place an includeSubdomains HSTS entry below a normal HPKP entry. |
346 state.AddHSTS("example1.test", expiry, true); | 463 state.AddHSTS("example1.test", expiry, true); |
347 state.AddHPKP("foo.example1.test", expiry, false, GetSampleSPKIHashes()); | 464 state.AddHPKP("foo.example1.test", expiry, false, GetSampleSPKIHashes(), |
| 465 report_uri); |
348 | 466 |
349 EXPECT_TRUE(state.ShouldUpgradeToSSL("foo.example1.test")); | 467 EXPECT_TRUE(state.ShouldUpgradeToSSL("foo.example1.test")); |
350 EXPECT_TRUE(state.HasPublicKeyPins("foo.example1.test")); | 468 EXPECT_TRUE(state.HasPublicKeyPins("foo.example1.test")); |
351 EXPECT_TRUE(state.ShouldUpgradeToSSL("example1.test")); | 469 EXPECT_TRUE(state.ShouldUpgradeToSSL("example1.test")); |
352 EXPECT_FALSE(state.HasPublicKeyPins("example1.test")); | 470 EXPECT_FALSE(state.HasPublicKeyPins("example1.test")); |
353 | 471 |
354 // Drop the includeSubdomains from the HSTS entry. | 472 // Drop the includeSubdomains from the HSTS entry. |
355 state.AddHSTS("example1.test", expiry, false); | 473 state.AddHSTS("example1.test", expiry, false); |
356 | 474 |
357 EXPECT_FALSE(state.ShouldUpgradeToSSL("foo.example1.test")); | 475 EXPECT_FALSE(state.ShouldUpgradeToSSL("foo.example1.test")); |
358 EXPECT_TRUE(state.HasPublicKeyPins("foo.example1.test")); | 476 EXPECT_TRUE(state.HasPublicKeyPins("foo.example1.test")); |
359 | 477 |
360 // Place an includeSubdomains HPKP entry below a normal HSTS entry. | 478 // Place an includeSubdomains HPKP entry below a normal HSTS entry. |
361 state.AddHSTS("foo.example2.test", expiry, false); | 479 state.AddHSTS("foo.example2.test", expiry, false); |
362 state.AddHPKP("example2.test", expiry, true, GetSampleSPKIHashes()); | 480 state.AddHPKP("example2.test", expiry, true, GetSampleSPKIHashes(), |
| 481 report_uri); |
363 | 482 |
364 EXPECT_TRUE(state.ShouldUpgradeToSSL("foo.example2.test")); | 483 EXPECT_TRUE(state.ShouldUpgradeToSSL("foo.example2.test")); |
365 EXPECT_TRUE(state.HasPublicKeyPins("foo.example2.test")); | 484 EXPECT_TRUE(state.HasPublicKeyPins("foo.example2.test")); |
366 | 485 |
367 // Drop the includeSubdomains from the HSTS entry. | 486 // Drop the includeSubdomains from the HSTS entry. |
368 state.AddHPKP("example2.test", expiry, false, GetSampleSPKIHashes()); | 487 state.AddHPKP("example2.test", expiry, false, GetSampleSPKIHashes(), |
| 488 report_uri); |
369 | 489 |
370 EXPECT_TRUE(state.ShouldUpgradeToSSL("foo.example2.test")); | 490 EXPECT_TRUE(state.ShouldUpgradeToSSL("foo.example2.test")); |
371 EXPECT_FALSE(state.HasPublicKeyPins("foo.example2.test")); | 491 EXPECT_FALSE(state.HasPublicKeyPins("foo.example2.test")); |
372 } | 492 } |
373 | 493 |
374 // Tests that GetDynamicDomainState appropriately stitches together the results | 494 // Tests that GetDynamicDomainState appropriately stitches together the results |
375 // of HSTS and HPKP. | 495 // of HSTS and HPKP. |
376 TEST_F(TransportSecurityStateTest, DynamicDomainState) { | 496 TEST_F(TransportSecurityStateTest, DynamicDomainState) { |
| 497 static const char kReportUri[] = "http://example.com/test"; |
| 498 std::string report_uri(kReportUri); |
| 499 |
377 TransportSecurityState state; | 500 TransportSecurityState state; |
378 const base::Time current_time(base::Time::Now()); | 501 const base::Time current_time(base::Time::Now()); |
379 const base::Time expiry1 = current_time + base::TimeDelta::FromSeconds(1000); | 502 const base::Time expiry1 = current_time + base::TimeDelta::FromSeconds(1000); |
380 const base::Time expiry2 = current_time + base::TimeDelta::FromSeconds(2000); | 503 const base::Time expiry2 = current_time + base::TimeDelta::FromSeconds(2000); |
381 | 504 |
382 state.AddHSTS("example.com", expiry1, true); | 505 state.AddHSTS("example.com", expiry1, true); |
383 state.AddHPKP("foo.example.com", expiry2, false, GetSampleSPKIHashes()); | 506 state.AddHPKP("foo.example.com", expiry2, false, GetSampleSPKIHashes(), |
| 507 report_uri); |
384 | 508 |
385 TransportSecurityState::DomainState domain_state; | 509 TransportSecurityState::DomainState domain_state; |
386 ASSERT_TRUE(state.GetDynamicDomainState("foo.example.com", &domain_state)); | 510 ASSERT_TRUE(state.GetDynamicDomainState("foo.example.com", &domain_state)); |
387 EXPECT_TRUE(domain_state.ShouldUpgradeToSSL()); | 511 EXPECT_TRUE(domain_state.ShouldUpgradeToSSL()); |
388 EXPECT_TRUE(domain_state.HasPublicKeyPins()); | 512 EXPECT_TRUE(domain_state.HasPublicKeyPins()); |
389 EXPECT_TRUE(domain_state.sts.include_subdomains); | 513 EXPECT_TRUE(domain_state.sts.include_subdomains); |
390 EXPECT_FALSE(domain_state.pkp.include_subdomains); | 514 EXPECT_FALSE(domain_state.pkp.include_subdomains); |
391 EXPECT_EQ(expiry1, domain_state.sts.expiry); | 515 EXPECT_EQ(expiry1, domain_state.sts.expiry); |
392 EXPECT_EQ(expiry2, domain_state.pkp.expiry); | 516 EXPECT_EQ(expiry2, domain_state.pkp.expiry); |
393 EXPECT_EQ("example.com", domain_state.sts.domain); | 517 EXPECT_EQ("example.com", domain_state.sts.domain); |
394 EXPECT_EQ("foo.example.com", domain_state.pkp.domain); | 518 EXPECT_EQ("foo.example.com", domain_state.pkp.domain); |
395 } | 519 } |
396 | 520 |
397 // Tests that new pins always override previous pins. This should be true for | 521 // Tests that new pins always override previous pins. This should be true for |
398 // both pins at the same domain or includeSubdomains pins at a parent domain. | 522 // both pins at the same domain or includeSubdomains pins at a parent domain. |
399 TEST_F(TransportSecurityStateTest, NewPinsOverride) { | 523 TEST_F(TransportSecurityStateTest, NewPinsOverride) { |
| 524 static const char kReportUri[] = "http://example.com/test"; |
| 525 std::string report_uri(kReportUri); |
| 526 |
400 TransportSecurityState state; | 527 TransportSecurityState state; |
401 TransportSecurityState::DomainState domain_state; | 528 TransportSecurityState::DomainState domain_state; |
402 const base::Time current_time(base::Time::Now()); | 529 const base::Time current_time(base::Time::Now()); |
403 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000); | 530 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000); |
404 HashValue hash1(HASH_VALUE_SHA1); | 531 HashValue hash1(HASH_VALUE_SHA1); |
405 memset(hash1.data(), 0x01, hash1.size()); | 532 memset(hash1.data(), 0x01, hash1.size()); |
406 HashValue hash2(HASH_VALUE_SHA1); | 533 HashValue hash2(HASH_VALUE_SHA1); |
407 memset(hash2.data(), 0x02, hash1.size()); | 534 memset(hash2.data(), 0x02, hash1.size()); |
408 HashValue hash3(HASH_VALUE_SHA1); | 535 HashValue hash3(HASH_VALUE_SHA1); |
409 memset(hash3.data(), 0x03, hash1.size()); | 536 memset(hash3.data(), 0x03, hash1.size()); |
410 | 537 |
411 state.AddHPKP("example.com", expiry, true, HashValueVector(1, hash1)); | 538 state.AddHPKP("example.com", expiry, true, HashValueVector(1, hash1), |
| 539 report_uri); |
412 | 540 |
413 ASSERT_TRUE(state.GetDynamicDomainState("foo.example.com", &domain_state)); | 541 ASSERT_TRUE(state.GetDynamicDomainState("foo.example.com", &domain_state)); |
414 ASSERT_EQ(1u, domain_state.pkp.spki_hashes.size()); | 542 ASSERT_EQ(1u, domain_state.pkp.spki_hashes.size()); |
415 EXPECT_TRUE(domain_state.pkp.spki_hashes[0].Equals(hash1)); | 543 EXPECT_TRUE(domain_state.pkp.spki_hashes[0].Equals(hash1)); |
416 | 544 |
417 state.AddHPKP("foo.example.com", expiry, false, HashValueVector(1, hash2)); | 545 state.AddHPKP("foo.example.com", expiry, false, HashValueVector(1, hash2), |
| 546 report_uri); |
418 | 547 |
419 ASSERT_TRUE(state.GetDynamicDomainState("foo.example.com", &domain_state)); | 548 ASSERT_TRUE(state.GetDynamicDomainState("foo.example.com", &domain_state)); |
420 ASSERT_EQ(1u, domain_state.pkp.spki_hashes.size()); | 549 ASSERT_EQ(1u, domain_state.pkp.spki_hashes.size()); |
421 EXPECT_TRUE(domain_state.pkp.spki_hashes[0].Equals(hash2)); | 550 EXPECT_TRUE(domain_state.pkp.spki_hashes[0].Equals(hash2)); |
422 | 551 |
423 state.AddHPKP("foo.example.com", expiry, false, HashValueVector(1, hash3)); | 552 state.AddHPKP("foo.example.com", expiry, false, HashValueVector(1, hash3), |
| 553 report_uri); |
424 | 554 |
425 ASSERT_TRUE(state.GetDynamicDomainState("foo.example.com", &domain_state)); | 555 ASSERT_TRUE(state.GetDynamicDomainState("foo.example.com", &domain_state)); |
426 ASSERT_EQ(1u, domain_state.pkp.spki_hashes.size()); | 556 ASSERT_EQ(1u, domain_state.pkp.spki_hashes.size()); |
427 EXPECT_TRUE(domain_state.pkp.spki_hashes[0].Equals(hash3)); | 557 EXPECT_TRUE(domain_state.pkp.spki_hashes[0].Equals(hash3)); |
428 } | 558 } |
429 | 559 |
430 TEST_F(TransportSecurityStateTest, DeleteAllDynamicDataSince) { | 560 TEST_F(TransportSecurityStateTest, DeleteAllDynamicDataSince) { |
431 TransportSecurityState state; | 561 TransportSecurityState state; |
432 const base::Time current_time(base::Time::Now()); | 562 const base::Time current_time(base::Time::Now()); |
433 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000); | 563 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000); |
(...skipping 594 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1028 | 1158 |
1029 // These hosts used to only be HSTS when SNI was available. | 1159 // These hosts used to only be HSTS when SNI was available. |
1030 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty( | 1160 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty( |
1031 "gmail.com")); | 1161 "gmail.com")); |
1032 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty( | 1162 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty( |
1033 "googlegroups.com")); | 1163 "googlegroups.com")); |
1034 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty( | 1164 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty( |
1035 "www.googlegroups.com")); | 1165 "www.googlegroups.com")); |
1036 } | 1166 } |
1037 | 1167 |
| 1168 TEST_F(TransportSecurityStateTest, HPKPReporting) { |
| 1169 const char kHost[] = "example.com"; |
| 1170 const char kSubdomain[] = "foo.example.com"; |
| 1171 const uint16_t kPort = 443; |
| 1172 GURL report_uri("http://www.example.com/report"); |
| 1173 // Two dummy certs to use as the server-sent and validated chains. The |
| 1174 // contents don't matter. |
| 1175 scoped_refptr<X509Certificate> cert1 = |
| 1176 ImportCertFromFile(GetTestCertsDirectory(), "test_mail_google_com.pem"); |
| 1177 scoped_refptr<X509Certificate> cert2 = |
| 1178 ImportCertFromFile(GetTestCertsDirectory(), "expired_cert.pem"); |
| 1179 ASSERT_TRUE(cert1); |
| 1180 ASSERT_TRUE(cert2); |
| 1181 |
| 1182 // kGoodPath is blog.torproject.org. |
| 1183 static const char* const kGoodPath[] = { |
| 1184 "sha1/m9lHYJYke9k0GtVZ+bXSQYE8nDI=", |
| 1185 "sha1/o5OZxATDsgmwgcIfIWIneMJ0jkw=", |
| 1186 "sha1/wHqYaI2J+6sFZAwRfap9ZbjKzE4=", |
| 1187 NULL, |
| 1188 }; |
| 1189 |
| 1190 // kBadPath is plus.google.com via Trustcenter, which is utterly wrong for |
| 1191 // torproject.org. |
| 1192 static const char* const kBadPath[] = { |
| 1193 "sha1/4BjDjn8v2lWeUFQnqSs0BgbIcrU=", |
| 1194 "sha1/gzuEEAB/bkqdQS3EIjk2by7lW+k=", |
| 1195 "sha1/SOZo+SvSspXXR9gjIBBPM5iQn9Q=", |
| 1196 NULL, |
| 1197 }; |
| 1198 |
| 1199 HashValueVector good_hashes, bad_hashes; |
| 1200 |
| 1201 for (size_t i = 0; kGoodPath[i]; i++) { |
| 1202 EXPECT_TRUE(AddHash(kGoodPath[i], &good_hashes)); |
| 1203 } |
| 1204 for (size_t i = 0; kBadPath[i]; i++) { |
| 1205 EXPECT_TRUE(AddHash(kBadPath[i], &bad_hashes)); |
| 1206 } |
| 1207 |
| 1208 TransportSecurityState state; |
| 1209 MockCertificateReportSender* mock_report_sender = |
| 1210 new MockCertificateReportSender(); |
| 1211 TransportSecurityReporter reporter( |
| 1212 &state, scoped_ptr<CertificateReportSender>(mock_report_sender)); |
| 1213 |
| 1214 const base::Time current_time(base::Time::Now()); |
| 1215 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000); |
| 1216 state.AddHPKP(kHost, expiry, true, good_hashes, report_uri.spec()); |
| 1217 |
| 1218 EXPECT_EQ(GURL(), mock_report_sender->latest_report_uri()); |
| 1219 EXPECT_EQ(std::string(), mock_report_sender->latest_report()); |
| 1220 |
| 1221 std::string failure_log; |
| 1222 EXPECT_FALSE(state.CheckPublicKeyPins( |
| 1223 kHost, true, bad_hashes, kPort, cert1, cert2, |
| 1224 TransportSecurityState::DO_NOT_SEND_PUBLIC_KEY_PIN_REPORT, &failure_log)); |
| 1225 |
| 1226 // No report should have been sent because of the DO_NOT_SEND_REPORT |
| 1227 // argument. |
| 1228 EXPECT_EQ(GURL(), mock_report_sender->latest_report_uri()); |
| 1229 EXPECT_EQ(std::string(), mock_report_sender->latest_report()); |
| 1230 |
| 1231 EXPECT_TRUE(state.CheckPublicKeyPins( |
| 1232 kHost, true, good_hashes, kPort, cert1, cert2, |
| 1233 TransportSecurityState::SEND_PUBLIC_KEY_PIN_REPORT, &failure_log)); |
| 1234 |
| 1235 // No report should have been sent because there was no violation. |
| 1236 EXPECT_EQ(GURL(), mock_report_sender->latest_report_uri()); |
| 1237 EXPECT_EQ(std::string(), mock_report_sender->latest_report()); |
| 1238 |
| 1239 EXPECT_FALSE(state.CheckPublicKeyPins( |
| 1240 kHost, true, bad_hashes, kPort, cert1, cert2, |
| 1241 TransportSecurityState::SEND_PUBLIC_KEY_PIN_REPORT, &failure_log)); |
| 1242 |
| 1243 // Now a report should have been sent. Check that it contains the |
| 1244 // right information. |
| 1245 EXPECT_EQ(report_uri, mock_report_sender->latest_report_uri()); |
| 1246 std::string report = mock_report_sender->latest_report(); |
| 1247 ASSERT_FALSE(report.empty()); |
| 1248 CheckHPKPReport(report, kHost, kPort, expiry, true, kHost, cert1, cert2, |
| 1249 good_hashes); |
| 1250 |
| 1251 EXPECT_FALSE(state.CheckPublicKeyPins( |
| 1252 kSubdomain, true, bad_hashes, kPort, cert1, cert2, |
| 1253 TransportSecurityState::SEND_PUBLIC_KEY_PIN_REPORT, &failure_log)); |
| 1254 |
| 1255 // Now a report should have been sent for the subdomain. Check that it |
| 1256 // contains the |
| 1257 // right information. |
| 1258 EXPECT_EQ(report_uri, mock_report_sender->latest_report_uri()); |
| 1259 report = mock_report_sender->latest_report(); |
| 1260 ASSERT_FALSE(report.empty()); |
| 1261 CheckHPKPReport(report, kSubdomain, kPort, expiry, true, kHost, cert1, cert2, |
| 1262 good_hashes); |
| 1263 } |
| 1264 |
1038 } // namespace net | 1265 } // namespace net |
OLD | NEW |