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/base/transport_security_state.h" | 5 #include "net/base/transport_security_state.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <string> | 8 #include <string> |
| 9 #include <vector> |
9 | 10 |
10 #include "base/base64.h" | 11 #include "base/base64.h" |
11 #include "base/file_path.h" | 12 #include "base/file_path.h" |
12 #include "base/sha1.h" | 13 #include "base/sha1.h" |
13 #include "base/string_piece.h" | 14 #include "base/string_piece.h" |
| 15 #include "crypto/sha2.h" |
14 #include "net/base/asn1_util.h" | 16 #include "net/base/asn1_util.h" |
15 #include "net/base/cert_test_util.h" | 17 #include "net/base/cert_test_util.h" |
16 #include "net/base/cert_verifier.h" | 18 #include "net/base/cert_verifier.h" |
17 #include "net/base/cert_verify_result.h" | 19 #include "net/base/cert_verify_result.h" |
18 #include "net/base/net_errors.h" | 20 #include "net/base/net_errors.h" |
19 #include "net/base/net_log.h" | 21 #include "net/base/net_log.h" |
20 #include "net/base/ssl_info.h" | 22 #include "net/base/ssl_info.h" |
21 #include "net/base/test_completion_callback.h" | 23 #include "net/base/test_completion_callback.h" |
22 #include "net/base/test_root_certs.h" | 24 #include "net/base/test_root_certs.h" |
| 25 #include "net/base/x509_cert_types.h" |
23 #include "net/base/x509_certificate.h" | 26 #include "net/base/x509_certificate.h" |
24 #include "net/http/http_util.h" | 27 #include "net/http/http_util.h" |
25 #include "testing/gtest/include/gtest/gtest.h" | 28 #include "testing/gtest/include/gtest/gtest.h" |
26 | 29 |
27 #if defined(USE_OPENSSL) | 30 #if defined(USE_OPENSSL) |
28 #include "crypto/openssl_util.h" | 31 #include "crypto/openssl_util.h" |
29 #else | 32 #else |
30 #include "crypto/nss_util.h" | 33 #include "crypto/nss_util.h" |
31 #endif | 34 #endif |
32 | 35 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
84 EXPECT_FALSE(state.ParseSTSHeader(now, "max-age=34889 includesubdomains")); | 87 EXPECT_FALSE(state.ParseSTSHeader(now, "max-age=34889 includesubdomains")); |
85 | 88 |
86 // Check that |state| was not updated by expecting the default | 89 // Check that |state| was not updated by expecting the default |
87 // values for its predictable fields. | 90 // values for its predictable fields. |
88 EXPECT_EQ(state.upgrade_mode, | 91 EXPECT_EQ(state.upgrade_mode, |
89 TransportSecurityState::DomainState::MODE_FORCE_HTTPS); | 92 TransportSecurityState::DomainState::MODE_FORCE_HTTPS); |
90 EXPECT_FALSE(state.include_subdomains); | 93 EXPECT_FALSE(state.include_subdomains); |
91 } | 94 } |
92 | 95 |
93 static bool GetPublicKeyHash(const net::X509Certificate::OSCertHandle& cert, | 96 static bool GetPublicKeyHash(const net::X509Certificate::OSCertHandle& cert, |
94 SHA1Fingerprint* fingerprint) { | 97 HashValue* fingerprint, |
| 98 HashValueTag tag) { |
95 std::string der_bytes; | 99 std::string der_bytes; |
96 if (!net::X509Certificate::GetDEREncoded(cert, &der_bytes)) | 100 if (!net::X509Certificate::GetDEREncoded(cert, &der_bytes)) |
97 return false; | 101 return false; |
98 | 102 |
99 base::StringPiece spki; | 103 base::StringPiece spki; |
100 if (!asn1::ExtractSPKIFromDERCert(der_bytes, &spki)) | 104 if (!asn1::ExtractSPKIFromDERCert(der_bytes, &spki)) |
101 return false; | 105 return false; |
102 | 106 |
103 base::SHA1HashBytes(reinterpret_cast<const unsigned char*>(spki.data()), | 107 fingerprint->tag = tag; |
104 spki.size(), fingerprint->data); | 108 switch (tag) { |
| 109 case HASH_VALUE_SHA1: |
| 110 base::SHA1HashBytes(reinterpret_cast<const unsigned char*>(spki.data()), |
| 111 spki.size(), fingerprint->data()); |
| 112 break; |
| 113 case HASH_VALUE_SHA256: |
| 114 crypto::SHA256HashString(spki, fingerprint->data(), |
| 115 crypto::kSHA256Length); |
| 116 break; |
| 117 default: |
| 118 NOTREACHED() << "Unknown HashValueTag " << tag; |
| 119 } |
| 120 |
105 return true; | 121 return true; |
106 } | 122 } |
107 | 123 |
108 static std::string GetPinFromCert(X509Certificate* cert) { | 124 static std::string GetPinFromCert(X509Certificate* cert, HashValueTag tag) { |
109 SHA1Fingerprint spki_hash; | 125 HashValue spki_hash; |
110 EXPECT_TRUE(GetPublicKeyHash(cert->os_cert_handle(), &spki_hash)); | 126 EXPECT_TRUE(GetPublicKeyHash(cert->os_cert_handle(), &spki_hash, tag)); |
111 | 127 |
112 std::string base64; | 128 std::string base64; |
113 base::Base64Encode(base::StringPiece(reinterpret_cast<char*>(spki_hash.data), | 129 base::Base64Encode(base::StringPiece( |
114 sizeof(spki_hash.data)), | 130 reinterpret_cast<char*>(spki_hash.data()), spki_hash.size()), &base64); |
115 &base64); | 131 |
116 return "pin-sha1=" + HttpUtil::Quote(base64); | 132 std::string label; |
| 133 switch (tag) { |
| 134 case HASH_VALUE_SHA1: |
| 135 label = "pin-sha1="; |
| 136 break; |
| 137 case HASH_VALUE_SHA256: |
| 138 label = "pin-sha256="; |
| 139 break; |
| 140 default: |
| 141 NOTREACHED() << "Unknown HashValueTag " << tag; |
| 142 } |
| 143 |
| 144 return label + HttpUtil::Quote(base64); |
117 } | 145 } |
118 | 146 |
119 TEST_F(TransportSecurityStateTest, BogusPinsHeaders) { | 147 static void TestBogusPinsHeaders(HashValueTag tag) { |
120 TransportSecurityState::DomainState state; | 148 TransportSecurityState::DomainState state; |
121 SSLInfo ssl_info; | 149 SSLInfo ssl_info; |
122 ssl_info.cert = | 150 ssl_info.cert = |
123 ImportCertFromFile(GetTestCertsDirectory(), "test_mail_google_com.pem"); | 151 ImportCertFromFile(GetTestCertsDirectory(), "test_mail_google_com.pem"); |
124 std::string good_pin = GetPinFromCert(ssl_info.cert); | 152 std::string good_pin = GetPinFromCert(ssl_info.cert, tag); |
125 base::Time now = base::Time::Now(); | 153 base::Time now = base::Time::Now(); |
126 | 154 |
127 // The backup pin is fake --- it just has to not be in the chain. | 155 // The backup pin is fake --- it just has to not be in the chain. |
128 std::string backup_pin = "pin-sha1=" + | 156 std::string backup_pin = "pin-sha1=" + |
129 HttpUtil::Quote("6dcfXufJLW3J6S/9rRe4vUlBj5g="); | 157 HttpUtil::Quote("6dcfXufJLW3J6S/9rRe4vUlBj5g="); |
130 | 158 |
131 EXPECT_FALSE(state.ParsePinsHeader(now, "", ssl_info)); | 159 EXPECT_FALSE(state.ParsePinsHeader(now, "", ssl_info)); |
132 EXPECT_FALSE(state.ParsePinsHeader(now, " ", ssl_info)); | 160 EXPECT_FALSE(state.ParsePinsHeader(now, " ", ssl_info)); |
133 EXPECT_FALSE(state.ParsePinsHeader(now, "abc", ssl_info)); | 161 EXPECT_FALSE(state.ParsePinsHeader(now, "abc", ssl_info)); |
134 EXPECT_FALSE(state.ParsePinsHeader(now, " abc", ssl_info)); | 162 EXPECT_FALSE(state.ParsePinsHeader(now, " abc", ssl_info)); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
173 ssl_info)); | 201 ssl_info)); |
174 EXPECT_FALSE(state.ParsePinsHeader(now, "max-age=34889.23", ssl_info)); | 202 EXPECT_FALSE(state.ParsePinsHeader(now, "max-age=34889.23", ssl_info)); |
175 | 203 |
176 // Check that |state| was not updated by expecting the default | 204 // Check that |state| was not updated by expecting the default |
177 // values for its predictable fields. | 205 // values for its predictable fields. |
178 EXPECT_EQ(state.upgrade_mode, | 206 EXPECT_EQ(state.upgrade_mode, |
179 TransportSecurityState::DomainState::MODE_FORCE_HTTPS); | 207 TransportSecurityState::DomainState::MODE_FORCE_HTTPS); |
180 EXPECT_FALSE(state.include_subdomains); | 208 EXPECT_FALSE(state.include_subdomains); |
181 } | 209 } |
182 | 210 |
| 211 TEST_F(TransportSecurityStateTest, BogusPinsHeadersSHA1) { |
| 212 TestBogusPinsHeaders(HASH_VALUE_SHA1); |
| 213 } |
| 214 |
| 215 TEST_F(TransportSecurityStateTest, BogusPinsHeadersSHA256) { |
| 216 TestBogusPinsHeaders(HASH_VALUE_SHA256); |
| 217 } |
| 218 |
183 TEST_F(TransportSecurityStateTest, ValidSTSHeaders) { | 219 TEST_F(TransportSecurityStateTest, ValidSTSHeaders) { |
184 TransportSecurityState::DomainState state; | 220 TransportSecurityState::DomainState state; |
185 base::Time expiry; | 221 base::Time expiry; |
186 base::Time now = base::Time::Now(); | 222 base::Time now = base::Time::Now(); |
187 | 223 |
188 EXPECT_TRUE(state.ParseSTSHeader(now, "max-age=243")); | 224 EXPECT_TRUE(state.ParseSTSHeader(now, "max-age=243")); |
189 expiry = now + base::TimeDelta::FromSeconds(243); | 225 expiry = now + base::TimeDelta::FromSeconds(243); |
190 EXPECT_EQ(expiry, state.upgrade_expiry); | 226 EXPECT_EQ(expiry, state.upgrade_expiry); |
191 EXPECT_FALSE(state.include_subdomains); | 227 EXPECT_FALSE(state.include_subdomains); |
192 | 228 |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
233 EXPECT_TRUE(state.ParseSTSHeader( | 269 EXPECT_TRUE(state.ParseSTSHeader( |
234 now, | 270 now, |
235 " max-age=999999999999999999999999999999999999999999999 ;" | 271 " max-age=999999999999999999999999999999999999999999999 ;" |
236 " incLudesUbdOmains ")); | 272 " incLudesUbdOmains ")); |
237 expiry = now + base::TimeDelta::FromSeconds( | 273 expiry = now + base::TimeDelta::FromSeconds( |
238 TransportSecurityState::kMaxHSTSAgeSecs); | 274 TransportSecurityState::kMaxHSTSAgeSecs); |
239 EXPECT_EQ(expiry, state.upgrade_expiry); | 275 EXPECT_EQ(expiry, state.upgrade_expiry); |
240 EXPECT_TRUE(state.include_subdomains); | 276 EXPECT_TRUE(state.include_subdomains); |
241 } | 277 } |
242 | 278 |
243 TEST_F(TransportSecurityStateTest, ValidPinsHeaders) { | 279 static void TestValidPinsHeaders(HashValueTag tag) { |
244 TransportSecurityState::DomainState state; | 280 TransportSecurityState::DomainState state; |
245 base::Time expiry; | 281 base::Time expiry; |
246 base::Time now = base::Time::Now(); | 282 base::Time now = base::Time::Now(); |
247 | 283 |
248 // Set up a realistic SSLInfo with a realistic cert chain. | 284 // Set up a realistic SSLInfo with a realistic cert chain. |
249 FilePath certs_dir = GetTestCertsDirectory(); | 285 FilePath certs_dir = GetTestCertsDirectory(); |
250 scoped_refptr<X509Certificate> ee_cert = | 286 scoped_refptr<X509Certificate> ee_cert = |
251 ImportCertFromFile(certs_dir, "2048-rsa-ee-by-2048-rsa-intermediate.pem"); | 287 ImportCertFromFile(certs_dir, "2048-rsa-ee-by-2048-rsa-intermediate.pem"); |
252 ASSERT_NE(static_cast<X509Certificate*>(NULL), ee_cert); | 288 ASSERT_NE(static_cast<X509Certificate*>(NULL), ee_cert); |
253 scoped_refptr<X509Certificate> intermediate = | 289 scoped_refptr<X509Certificate> intermediate = |
(...skipping 19 matching lines...) Expand all Loading... |
273 scoped_ptr<CertVerifier> verifier(CertVerifier::CreateDefault()); | 309 scoped_ptr<CertVerifier> verifier(CertVerifier::CreateDefault()); |
274 TestCompletionCallback callback; | 310 TestCompletionCallback callback; |
275 CertVerifier::RequestHandle handle = NULL; | 311 CertVerifier::RequestHandle handle = NULL; |
276 rv = verifier->Verify(ssl_info.cert, "127.0.0.1", 0, NULL, &result, | 312 rv = verifier->Verify(ssl_info.cert, "127.0.0.1", 0, NULL, &result, |
277 callback.callback(), &handle, BoundNetLog()); | 313 callback.callback(), &handle, BoundNetLog()); |
278 rv = callback.GetResult(rv); | 314 rv = callback.GetResult(rv); |
279 ASSERT_EQ(OK, rv); | 315 ASSERT_EQ(OK, rv); |
280 // Normally, ssl_client_socket_nss would do this, but for a unit test we | 316 // Normally, ssl_client_socket_nss would do this, but for a unit test we |
281 // fake it. | 317 // fake it. |
282 ssl_info.public_key_hashes = result.public_key_hashes; | 318 ssl_info.public_key_hashes = result.public_key_hashes; |
283 std::string good_pin = GetPinFromCert(ssl_info.cert); | 319 std::string good_pin = GetPinFromCert(ssl_info.cert, /*tag*/HASH_VALUE_SHA1); |
| 320 DLOG(WARNING) << "good pin: " << good_pin; |
284 | 321 |
285 // The backup pin is fake --- we just need an SPKI hash that does not match | 322 // The backup pin is fake --- we just need an SPKI hash that does not match |
286 // the hash of any SPKI in the certificate chain. | 323 // the hash of any SPKI in the certificate chain. |
287 std::string backup_pin = "pin-sha1=" + | 324 std::string backup_pin = "pin-sha1=" + |
288 HttpUtil::Quote("6dcfXufJLW3J6S/9rRe4vUlBj5g="); | 325 HttpUtil::Quote("6dcfXufJLW3J6S/9rRe4vUlBj5g="); |
289 | 326 |
290 EXPECT_TRUE(state.ParsePinsHeader( | 327 EXPECT_TRUE(state.ParsePinsHeader( |
291 now, | 328 now, |
292 "max-age=243; " + good_pin + ";" + backup_pin, | 329 "max-age=243; " + good_pin + ";" + backup_pin, |
293 ssl_info)); | 330 ssl_info)); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
349 EXPECT_TRUE(state.ParsePinsHeader( | 386 EXPECT_TRUE(state.ParsePinsHeader( |
350 now, | 387 now, |
351 " max-age=999999999999999999999999999999999999999999999 ; " + | 388 " max-age=999999999999999999999999999999999999999999999 ; " + |
352 backup_pin + ";" + good_pin + "; ", | 389 backup_pin + ";" + good_pin + "; ", |
353 ssl_info)); | 390 ssl_info)); |
354 expiry = now + | 391 expiry = now + |
355 base::TimeDelta::FromSeconds(TransportSecurityState::kMaxHSTSAgeSecs); | 392 base::TimeDelta::FromSeconds(TransportSecurityState::kMaxHSTSAgeSecs); |
356 EXPECT_EQ(expiry, state.dynamic_spki_hashes_expiry); | 393 EXPECT_EQ(expiry, state.dynamic_spki_hashes_expiry); |
357 } | 394 } |
358 | 395 |
| 396 TEST_F(TransportSecurityStateTest, ValidPinsHeadersSHA1) { |
| 397 TestValidPinsHeaders(HASH_VALUE_SHA1); |
| 398 } |
| 399 |
| 400 TEST_F(TransportSecurityStateTest, ValidPinsHeadersSHA256) { |
| 401 TestValidPinsHeaders(HASH_VALUE_SHA256); |
| 402 } |
| 403 |
359 TEST_F(TransportSecurityStateTest, SimpleMatches) { | 404 TEST_F(TransportSecurityStateTest, SimpleMatches) { |
360 TransportSecurityState state; | 405 TransportSecurityState state; |
361 TransportSecurityState::DomainState domain_state; | 406 TransportSecurityState::DomainState domain_state; |
362 const base::Time current_time(base::Time::Now()); | 407 const base::Time current_time(base::Time::Now()); |
363 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000); | 408 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000); |
364 | 409 |
365 EXPECT_FALSE(state.GetDomainState("yahoo.com", true, &domain_state)); | 410 EXPECT_FALSE(state.GetDomainState("yahoo.com", true, &domain_state)); |
366 domain_state.upgrade_expiry = expiry; | 411 domain_state.upgrade_expiry = expiry; |
367 state.EnableHost("yahoo.com", domain_state); | 412 state.EnableHost("yahoo.com", domain_state); |
368 EXPECT_TRUE(state.GetDomainState("yahoo.com", true, &domain_state)); | 413 EXPECT_TRUE(state.GetDomainState("yahoo.com", true, &domain_state)); |
(...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
776 EXPECT_FALSE(state.GetDomainState(kLongName, true, &domain_state)); | 821 EXPECT_FALSE(state.GetDomainState(kLongName, true, &domain_state)); |
777 } | 822 } |
778 | 823 |
779 TEST_F(TransportSecurityStateTest, BuiltinCertPins) { | 824 TEST_F(TransportSecurityStateTest, BuiltinCertPins) { |
780 TransportSecurityState state; | 825 TransportSecurityState state; |
781 TransportSecurityState::DomainState domain_state; | 826 TransportSecurityState::DomainState domain_state; |
782 | 827 |
783 EXPECT_TRUE(state.GetDomainState("chrome.google.com", true, &domain_state)); | 828 EXPECT_TRUE(state.GetDomainState("chrome.google.com", true, &domain_state)); |
784 EXPECT_TRUE(HasPins("chrome.google.com")); | 829 EXPECT_TRUE(HasPins("chrome.google.com")); |
785 | 830 |
786 FingerprintVector hashes; | 831 std::vector<HashValueVector> hashes; |
787 // Checks that a built-in list does exist. | 832 // Checks that a built-in list does exist. |
788 EXPECT_FALSE(domain_state.IsChainOfPublicKeysPermitted(hashes)); | 833 EXPECT_FALSE(domain_state.IsChainOfPublicKeysPermitted(hashes)); |
789 EXPECT_FALSE(HasPins("www.paypal.com")); | 834 EXPECT_FALSE(HasPins("www.paypal.com")); |
790 | 835 |
791 EXPECT_TRUE(HasPins("docs.google.com")); | 836 EXPECT_TRUE(HasPins("docs.google.com")); |
792 EXPECT_TRUE(HasPins("1.docs.google.com")); | 837 EXPECT_TRUE(HasPins("1.docs.google.com")); |
793 EXPECT_TRUE(HasPins("sites.google.com")); | 838 EXPECT_TRUE(HasPins("sites.google.com")); |
794 EXPECT_TRUE(HasPins("drive.google.com")); | 839 EXPECT_TRUE(HasPins("drive.google.com")); |
795 EXPECT_TRUE(HasPins("spreadsheets.google.com")); | 840 EXPECT_TRUE(HasPins("spreadsheets.google.com")); |
796 EXPECT_TRUE(HasPins("health.google.com")); | 841 EXPECT_TRUE(HasPins("health.google.com")); |
(...skipping 25 matching lines...) Expand all Loading... |
822 EXPECT_TRUE(HasPins("oauth.twitter.com")); | 867 EXPECT_TRUE(HasPins("oauth.twitter.com")); |
823 EXPECT_TRUE(HasPins("mobile.twitter.com")); | 868 EXPECT_TRUE(HasPins("mobile.twitter.com")); |
824 EXPECT_TRUE(HasPins("dev.twitter.com")); | 869 EXPECT_TRUE(HasPins("dev.twitter.com")); |
825 EXPECT_TRUE(HasPins("business.twitter.com")); | 870 EXPECT_TRUE(HasPins("business.twitter.com")); |
826 EXPECT_TRUE(HasPins("platform.twitter.com")); | 871 EXPECT_TRUE(HasPins("platform.twitter.com")); |
827 EXPECT_TRUE(HasPins("si0.twimg.com")); | 872 EXPECT_TRUE(HasPins("si0.twimg.com")); |
828 EXPECT_TRUE(HasPins("twimg0-a.akamaihd.net")); | 873 EXPECT_TRUE(HasPins("twimg0-a.akamaihd.net")); |
829 } | 874 } |
830 | 875 |
831 static bool AddHash(const std::string& type_and_base64, | 876 static bool AddHash(const std::string& type_and_base64, |
832 FingerprintVector* out) { | 877 HashValueVector* out) { |
833 std::string hash_str; | 878 HashValue hash; |
834 if (type_and_base64.find("sha1/") == 0 && | 879 |
835 base::Base64Decode(type_and_base64.substr(5, type_and_base64.size() - 5), | 880 if (!TransportSecurityState::ParsePin(type_and_base64, &hash)) |
836 &hash_str) && | 881 return false; |
837 hash_str.size() == base::kSHA1Length) { | 882 |
838 SHA1Fingerprint hash; | 883 out->push_back(hash); |
839 memcpy(hash.data, hash_str.data(), sizeof(hash.data)); | 884 return true; |
840 out->push_back(hash); | |
841 return true; | |
842 } | |
843 return false; | |
844 } | 885 } |
845 | 886 |
| 887 |
846 TEST_F(TransportSecurityStateTest, PinValidationWithRejectedCerts) { | 888 TEST_F(TransportSecurityStateTest, PinValidationWithRejectedCerts) { |
847 // kGoodPath is plus.google.com via Google Internet Authority. | 889 // kGoodPath is plus.google.com via Google Internet Authority. |
848 static const char* kGoodPath[] = { | 890 static const char* kGoodPath[] = { |
849 "sha1/4BjDjn8v2lWeUFQnqSs0BgbIcrU=", | 891 "sha1/4BjDjn8v2lWeUFQnqSs0BgbIcrU=", |
850 "sha1/QMVAHW+MuvCLAO3vse6H0AWzuc0=", | 892 "sha1/QMVAHW+MuvCLAO3vse6H0AWzuc0=", |
851 "sha1/SOZo+SvSspXXR9gjIBBPM5iQn9Q=", | 893 "sha1/SOZo+SvSspXXR9gjIBBPM5iQn9Q=", |
852 NULL, | 894 NULL, |
853 }; | 895 }; |
854 | 896 |
855 // kBadPath is plus.google.com via Trustcenter, which contains a required | 897 // kBadPath is plus.google.com via Trustcenter, which contains a required |
856 // certificate (Equifax root), but also an excluded certificate | 898 // certificate (Equifax root), but also an excluded certificate |
857 // (Trustcenter). | 899 // (Trustcenter). |
858 static const char* kBadPath[] = { | 900 static const char* kBadPath[] = { |
859 "sha1/4BjDjn8v2lWeUFQnqSs0BgbIcrU=", | 901 "sha1/4BjDjn8v2lWeUFQnqSs0BgbIcrU=", |
860 "sha1/gzuEEAB/bkqdQS3EIjk2by7lW+k=", | 902 "sha1/gzuEEAB/bkqdQS3EIjk2by7lW+k=", |
861 "sha1/SOZo+SvSspXXR9gjIBBPM5iQn9Q=", | 903 "sha1/SOZo+SvSspXXR9gjIBBPM5iQn9Q=", |
862 NULL, | 904 NULL, |
863 }; | 905 }; |
864 | 906 |
865 std::vector<net::SHA1Fingerprint> good_hashes, bad_hashes; | 907 HashValueVector good_hashes, bad_hashes; |
866 | 908 |
867 for (size_t i = 0; kGoodPath[i]; i++) { | 909 for (size_t i = 0; kGoodPath[i]; i++) { |
868 EXPECT_TRUE(AddHash(kGoodPath[i], &good_hashes)); | 910 EXPECT_TRUE(AddHash(kGoodPath[i], &good_hashes)); |
869 } | 911 } |
870 for (size_t i = 0; kBadPath[i]; i++) { | 912 for (size_t i = 0; kBadPath[i]; i++) { |
871 EXPECT_TRUE(AddHash(kBadPath[i], &bad_hashes)); | 913 EXPECT_TRUE(AddHash(kBadPath[i], &bad_hashes)); |
872 } | 914 } |
873 | 915 |
874 TransportSecurityState state; | 916 TransportSecurityState state; |
875 TransportSecurityState::DomainState domain_state; | 917 TransportSecurityState::DomainState domain_state; |
876 EXPECT_TRUE(state.GetDomainState("plus.google.com", true, &domain_state)); | 918 EXPECT_TRUE(state.GetDomainState("plus.google.com", true, &domain_state)); |
877 EXPECT_TRUE(domain_state.HasPins()); | 919 EXPECT_TRUE(domain_state.HasPins()); |
878 | 920 |
879 EXPECT_TRUE(domain_state.IsChainOfPublicKeysPermitted(good_hashes)); | 921 std::vector<HashValueVector> good; |
880 EXPECT_FALSE(domain_state.IsChainOfPublicKeysPermitted(bad_hashes)); | 922 good.push_back(good_hashes); |
| 923 EXPECT_TRUE(domain_state.IsChainOfPublicKeysPermitted(good)); |
| 924 |
| 925 std::vector<HashValueVector> bad; |
| 926 bad.push_back(bad_hashes); |
| 927 EXPECT_FALSE(domain_state.IsChainOfPublicKeysPermitted(bad)); |
881 } | 928 } |
882 | 929 |
883 TEST_F(TransportSecurityStateTest, PinValidationWithoutRejectedCerts) { | 930 TEST_F(TransportSecurityStateTest, PinValidationWithoutRejectedCerts) { |
884 // kGoodPath is blog.torproject.org. | 931 // kGoodPath is blog.torproject.org. |
885 static const char* kGoodPath[] = { | 932 static const char* kGoodPath[] = { |
886 "sha1/m9lHYJYke9k0GtVZ+bXSQYE8nDI=", | 933 "sha1/m9lHYJYke9k0GtVZ+bXSQYE8nDI=", |
887 "sha1/o5OZxATDsgmwgcIfIWIneMJ0jkw=", | 934 "sha1/o5OZxATDsgmwgcIfIWIneMJ0jkw=", |
888 "sha1/wHqYaI2J+6sFZAwRfap9ZbjKzE4=", | 935 "sha1/wHqYaI2J+6sFZAwRfap9ZbjKzE4=", |
889 NULL, | 936 NULL, |
890 }; | 937 }; |
891 | 938 |
892 // kBadPath is plus.google.com via Trustcenter, which is utterly wrong for | 939 // kBadPath is plus.google.com via Trustcenter, which is utterly wrong for |
893 // torproject.org. | 940 // torproject.org. |
894 static const char* kBadPath[] = { | 941 static const char* kBadPath[] = { |
895 "sha1/4BjDjn8v2lWeUFQnqSs0BgbIcrU=", | 942 "sha1/4BjDjn8v2lWeUFQnqSs0BgbIcrU=", |
896 "sha1/gzuEEAB/bkqdQS3EIjk2by7lW+k=", | 943 "sha1/gzuEEAB/bkqdQS3EIjk2by7lW+k=", |
897 "sha1/SOZo+SvSspXXR9gjIBBPM5iQn9Q=", | 944 "sha1/SOZo+SvSspXXR9gjIBBPM5iQn9Q=", |
898 NULL, | 945 NULL, |
899 }; | 946 }; |
900 | 947 |
901 std::vector<net::SHA1Fingerprint> good_hashes, bad_hashes; | 948 HashValueVector good_hashes, bad_hashes; |
902 | 949 |
903 for (size_t i = 0; kGoodPath[i]; i++) { | 950 for (size_t i = 0; kGoodPath[i]; i++) { |
904 EXPECT_TRUE(AddHash(kGoodPath[i], &good_hashes)); | 951 EXPECT_TRUE(AddHash(kGoodPath[i], &good_hashes)); |
905 } | 952 } |
906 for (size_t i = 0; kBadPath[i]; i++) { | 953 for (size_t i = 0; kBadPath[i]; i++) { |
907 EXPECT_TRUE(AddHash(kBadPath[i], &bad_hashes)); | 954 EXPECT_TRUE(AddHash(kBadPath[i], &bad_hashes)); |
908 } | 955 } |
909 | 956 |
910 TransportSecurityState state; | 957 TransportSecurityState state; |
911 TransportSecurityState::DomainState domain_state; | 958 TransportSecurityState::DomainState domain_state; |
912 EXPECT_TRUE(state.GetDomainState("blog.torproject.org", true, &domain_state)); | 959 EXPECT_TRUE(state.GetDomainState("blog.torproject.org", true, &domain_state)); |
913 EXPECT_TRUE(domain_state.HasPins()); | 960 EXPECT_TRUE(domain_state.HasPins()); |
914 | 961 |
915 EXPECT_TRUE(domain_state.IsChainOfPublicKeysPermitted(good_hashes)); | 962 std::vector<HashValueVector> good; |
916 EXPECT_FALSE(domain_state.IsChainOfPublicKeysPermitted(bad_hashes)); | 963 good.push_back(good_hashes); |
| 964 EXPECT_TRUE(domain_state.IsChainOfPublicKeysPermitted(good)); |
| 965 |
| 966 std::vector<HashValueVector> bad; |
| 967 bad.push_back(bad_hashes); |
| 968 EXPECT_FALSE(domain_state.IsChainOfPublicKeysPermitted(bad)); |
917 } | 969 } |
918 | 970 |
919 TEST_F(TransportSecurityStateTest, OptionalHSTSCertPins) { | 971 TEST_F(TransportSecurityStateTest, OptionalHSTSCertPins) { |
920 TransportSecurityState state; | 972 TransportSecurityState state; |
921 TransportSecurityState::DomainState domain_state; | 973 TransportSecurityState::DomainState domain_state; |
922 | 974 |
923 EXPECT_FALSE(ShouldRedirect("www.google-analytics.com")); | 975 EXPECT_FALSE(ShouldRedirect("www.google-analytics.com")); |
924 | 976 |
925 EXPECT_FALSE(HasPins("www.google-analytics.com", false)); | 977 EXPECT_FALSE(HasPins("www.google-analytics.com", false)); |
926 EXPECT_TRUE(HasPins("www.google-analytics.com")); | 978 EXPECT_TRUE(HasPins("www.google-analytics.com")); |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1048 // Expect to fail for SNI hosts when not searching the SNI list: | 1100 // Expect to fail for SNI hosts when not searching the SNI list: |
1049 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty( | 1101 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty( |
1050 "gmail.com", false)); | 1102 "gmail.com", false)); |
1051 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty( | 1103 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty( |
1052 "googlegroups.com", false)); | 1104 "googlegroups.com", false)); |
1053 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty( | 1105 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty( |
1054 "www.googlegroups.com", false)); | 1106 "www.googlegroups.com", false)); |
1055 } | 1107 } |
1056 | 1108 |
1057 } // namespace net | 1109 } // namespace net |
OLD | NEW |