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