Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(540)

Side by Side Diff: net/base/transport_security_state_unittest.cc

Issue 10826257: Implement SHA-256 fingerprint support (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/base/transport_security_state.cc ('k') | net/base/x509_cert_types.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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* hash) {
95 std::string der_bytes; 98 std::string der_bytes;
96 if (!net::X509Certificate::GetDEREncoded(cert, &der_bytes)) 99 if (!net::X509Certificate::GetDEREncoded(cert, &der_bytes))
97 return false; 100 return false;
98 101
99 base::StringPiece spki; 102 base::StringPiece spki;
100 if (!asn1::ExtractSPKIFromDERCert(der_bytes, &spki)) 103 if (!asn1::ExtractSPKIFromDERCert(der_bytes, &spki))
101 return false; 104 return false;
102 105
103 base::SHA1HashBytes(reinterpret_cast<const unsigned char*>(spki.data()), 106 switch (hash->tag) {
104 spki.size(), fingerprint->data); 107 case HASH_VALUE_SHA1:
108 base::SHA1HashBytes(reinterpret_cast<const unsigned char*>(spki.data()),
109 spki.size(), hash->data());
110 break;
111 case HASH_VALUE_SHA256:
112 crypto::SHA256HashString(spki, hash->data(), crypto::kSHA256Length);
113 break;
114 default:
115 NOTREACHED() << "Unknown HashValueTag " << hash->tag;
116 }
117
105 return true; 118 return true;
106 } 119 }
107 120
108 static std::string GetPinFromCert(X509Certificate* cert) { 121 static std::string GetPinFromCert(X509Certificate* cert, HashValueTag tag) {
109 SHA1Fingerprint spki_hash; 122 HashValue spki_hash(tag);
110 EXPECT_TRUE(GetPublicKeyHash(cert->os_cert_handle(), &spki_hash)); 123 EXPECT_TRUE(GetPublicKeyHash(cert->os_cert_handle(), &spki_hash));
111 124
112 std::string base64; 125 std::string base64;
113 base::Base64Encode(base::StringPiece(reinterpret_cast<char*>(spki_hash.data), 126 base::Base64Encode(base::StringPiece(
114 sizeof(spki_hash.data)), 127 reinterpret_cast<char*>(spki_hash.data()), spki_hash.size()), &base64);
115 &base64); 128
116 return "pin-sha1=" + HttpUtil::Quote(base64); 129 std::string label;
130 switch (tag) {
131 case HASH_VALUE_SHA1:
132 label = "pin-sha1=";
133 break;
134 case HASH_VALUE_SHA256:
135 label = "pin-sha256=";
136 break;
137 default:
138 NOTREACHED() << "Unknown HashValueTag " << tag;
139 }
140
141 return label + HttpUtil::Quote(base64);
117 } 142 }
118 143
119 TEST_F(TransportSecurityStateTest, BogusPinsHeaders) { 144 static void TestBogusPinsHeaders(HashValueTag tag) {
120 TransportSecurityState::DomainState state; 145 TransportSecurityState::DomainState state;
121 SSLInfo ssl_info; 146 SSLInfo ssl_info;
122 ssl_info.cert = 147 ssl_info.cert =
123 ImportCertFromFile(GetTestCertsDirectory(), "test_mail_google_com.pem"); 148 ImportCertFromFile(GetTestCertsDirectory(), "test_mail_google_com.pem");
124 std::string good_pin = GetPinFromCert(ssl_info.cert); 149 std::string good_pin = GetPinFromCert(ssl_info.cert, tag);
125 base::Time now = base::Time::Now(); 150 base::Time now = base::Time::Now();
126 151
127 // The backup pin is fake --- it just has to not be in the chain. 152 // The backup pin is fake --- it just has to not be in the chain.
128 std::string backup_pin = "pin-sha1=" + 153 std::string backup_pin = "pin-sha1=" +
129 HttpUtil::Quote("6dcfXufJLW3J6S/9rRe4vUlBj5g="); 154 HttpUtil::Quote("6dcfXufJLW3J6S/9rRe4vUlBj5g=");
130 155
131 EXPECT_FALSE(state.ParsePinsHeader(now, "", ssl_info)); 156 EXPECT_FALSE(state.ParsePinsHeader(now, "", ssl_info));
132 EXPECT_FALSE(state.ParsePinsHeader(now, " ", ssl_info)); 157 EXPECT_FALSE(state.ParsePinsHeader(now, " ", ssl_info));
133 EXPECT_FALSE(state.ParsePinsHeader(now, "abc", ssl_info)); 158 EXPECT_FALSE(state.ParsePinsHeader(now, "abc", ssl_info));
134 EXPECT_FALSE(state.ParsePinsHeader(now, " abc", ssl_info)); 159 EXPECT_FALSE(state.ParsePinsHeader(now, " abc", ssl_info));
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
173 ssl_info)); 198 ssl_info));
174 EXPECT_FALSE(state.ParsePinsHeader(now, "max-age=34889.23", ssl_info)); 199 EXPECT_FALSE(state.ParsePinsHeader(now, "max-age=34889.23", ssl_info));
175 200
176 // Check that |state| was not updated by expecting the default 201 // Check that |state| was not updated by expecting the default
177 // values for its predictable fields. 202 // values for its predictable fields.
178 EXPECT_EQ(state.upgrade_mode, 203 EXPECT_EQ(state.upgrade_mode,
179 TransportSecurityState::DomainState::MODE_FORCE_HTTPS); 204 TransportSecurityState::DomainState::MODE_FORCE_HTTPS);
180 EXPECT_FALSE(state.include_subdomains); 205 EXPECT_FALSE(state.include_subdomains);
181 } 206 }
182 207
208 TEST_F(TransportSecurityStateTest, BogusPinsHeadersSHA1) {
209 TestBogusPinsHeaders(HASH_VALUE_SHA1);
210 }
211
212 TEST_F(TransportSecurityStateTest, BogusPinsHeadersSHA256) {
213 TestBogusPinsHeaders(HASH_VALUE_SHA256);
214 }
215
183 TEST_F(TransportSecurityStateTest, ValidSTSHeaders) { 216 TEST_F(TransportSecurityStateTest, ValidSTSHeaders) {
184 TransportSecurityState::DomainState state; 217 TransportSecurityState::DomainState state;
185 base::Time expiry; 218 base::Time expiry;
186 base::Time now = base::Time::Now(); 219 base::Time now = base::Time::Now();
187 220
188 EXPECT_TRUE(state.ParseSTSHeader(now, "max-age=243")); 221 EXPECT_TRUE(state.ParseSTSHeader(now, "max-age=243"));
189 expiry = now + base::TimeDelta::FromSeconds(243); 222 expiry = now + base::TimeDelta::FromSeconds(243);
190 EXPECT_EQ(expiry, state.upgrade_expiry); 223 EXPECT_EQ(expiry, state.upgrade_expiry);
191 EXPECT_FALSE(state.include_subdomains); 224 EXPECT_FALSE(state.include_subdomains);
192 225
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 EXPECT_TRUE(state.ParseSTSHeader( 266 EXPECT_TRUE(state.ParseSTSHeader(
234 now, 267 now,
235 " max-age=999999999999999999999999999999999999999999999 ;" 268 " max-age=999999999999999999999999999999999999999999999 ;"
236 " incLudesUbdOmains ")); 269 " incLudesUbdOmains "));
237 expiry = now + base::TimeDelta::FromSeconds( 270 expiry = now + base::TimeDelta::FromSeconds(
238 TransportSecurityState::kMaxHSTSAgeSecs); 271 TransportSecurityState::kMaxHSTSAgeSecs);
239 EXPECT_EQ(expiry, state.upgrade_expiry); 272 EXPECT_EQ(expiry, state.upgrade_expiry);
240 EXPECT_TRUE(state.include_subdomains); 273 EXPECT_TRUE(state.include_subdomains);
241 } 274 }
242 275
243 TEST_F(TransportSecurityStateTest, ValidPinsHeaders) { 276 static void TestValidPinsHeaders(HashValueTag tag) {
244 TransportSecurityState::DomainState state; 277 TransportSecurityState::DomainState state;
245 base::Time expiry; 278 base::Time expiry;
246 base::Time now = base::Time::Now(); 279 base::Time now = base::Time::Now();
247 280
248 // Set up a realistic SSLInfo with a realistic cert chain. 281 // Set up a realistic SSLInfo with a realistic cert chain.
249 FilePath certs_dir = GetTestCertsDirectory(); 282 FilePath certs_dir = GetTestCertsDirectory();
250 scoped_refptr<X509Certificate> ee_cert = 283 scoped_refptr<X509Certificate> ee_cert =
251 ImportCertFromFile(certs_dir, "2048-rsa-ee-by-2048-rsa-intermediate.pem"); 284 ImportCertFromFile(certs_dir, "2048-rsa-ee-by-2048-rsa-intermediate.pem");
252 ASSERT_NE(static_cast<X509Certificate*>(NULL), ee_cert); 285 ASSERT_NE(static_cast<X509Certificate*>(NULL), ee_cert);
253 scoped_refptr<X509Certificate> intermediate = 286 scoped_refptr<X509Certificate> intermediate =
(...skipping 19 matching lines...) Expand all
273 scoped_ptr<CertVerifier> verifier(CertVerifier::CreateDefault()); 306 scoped_ptr<CertVerifier> verifier(CertVerifier::CreateDefault());
274 TestCompletionCallback callback; 307 TestCompletionCallback callback;
275 CertVerifier::RequestHandle handle = NULL; 308 CertVerifier::RequestHandle handle = NULL;
276 rv = verifier->Verify(ssl_info.cert, "127.0.0.1", 0, NULL, &result, 309 rv = verifier->Verify(ssl_info.cert, "127.0.0.1", 0, NULL, &result,
277 callback.callback(), &handle, BoundNetLog()); 310 callback.callback(), &handle, BoundNetLog());
278 rv = callback.GetResult(rv); 311 rv = callback.GetResult(rv);
279 ASSERT_EQ(OK, rv); 312 ASSERT_EQ(OK, rv);
280 // Normally, ssl_client_socket_nss would do this, but for a unit test we 313 // Normally, ssl_client_socket_nss would do this, but for a unit test we
281 // fake it. 314 // fake it.
282 ssl_info.public_key_hashes = result.public_key_hashes; 315 ssl_info.public_key_hashes = result.public_key_hashes;
283 std::string good_pin = GetPinFromCert(ssl_info.cert); 316 std::string good_pin = GetPinFromCert(ssl_info.cert, /*tag*/HASH_VALUE_SHA1);
317 DLOG(WARNING) << "good pin: " << good_pin;
284 318
285 // The backup pin is fake --- we just need an SPKI hash that does not match 319 // 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. 320 // the hash of any SPKI in the certificate chain.
287 std::string backup_pin = "pin-sha1=" + 321 std::string backup_pin = "pin-sha1=" +
288 HttpUtil::Quote("6dcfXufJLW3J6S/9rRe4vUlBj5g="); 322 HttpUtil::Quote("6dcfXufJLW3J6S/9rRe4vUlBj5g=");
289 323
290 EXPECT_TRUE(state.ParsePinsHeader( 324 EXPECT_TRUE(state.ParsePinsHeader(
291 now, 325 now,
292 "max-age=243; " + good_pin + ";" + backup_pin, 326 "max-age=243; " + good_pin + ";" + backup_pin,
293 ssl_info)); 327 ssl_info));
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
349 EXPECT_TRUE(state.ParsePinsHeader( 383 EXPECT_TRUE(state.ParsePinsHeader(
350 now, 384 now,
351 " max-age=999999999999999999999999999999999999999999999 ; " + 385 " max-age=999999999999999999999999999999999999999999999 ; " +
352 backup_pin + ";" + good_pin + "; ", 386 backup_pin + ";" + good_pin + "; ",
353 ssl_info)); 387 ssl_info));
354 expiry = now + 388 expiry = now +
355 base::TimeDelta::FromSeconds(TransportSecurityState::kMaxHSTSAgeSecs); 389 base::TimeDelta::FromSeconds(TransportSecurityState::kMaxHSTSAgeSecs);
356 EXPECT_EQ(expiry, state.dynamic_spki_hashes_expiry); 390 EXPECT_EQ(expiry, state.dynamic_spki_hashes_expiry);
357 } 391 }
358 392
393 TEST_F(TransportSecurityStateTest, ValidPinsHeadersSHA1) {
394 TestValidPinsHeaders(HASH_VALUE_SHA1);
395 }
396
397 TEST_F(TransportSecurityStateTest, ValidPinsHeadersSHA256) {
398 TestValidPinsHeaders(HASH_VALUE_SHA256);
399 }
400
359 TEST_F(TransportSecurityStateTest, SimpleMatches) { 401 TEST_F(TransportSecurityStateTest, SimpleMatches) {
360 TransportSecurityState state; 402 TransportSecurityState state;
361 TransportSecurityState::DomainState domain_state; 403 TransportSecurityState::DomainState domain_state;
362 const base::Time current_time(base::Time::Now()); 404 const base::Time current_time(base::Time::Now());
363 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000); 405 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
364 406
365 EXPECT_FALSE(state.GetDomainState("yahoo.com", true, &domain_state)); 407 EXPECT_FALSE(state.GetDomainState("yahoo.com", true, &domain_state));
366 domain_state.upgrade_expiry = expiry; 408 domain_state.upgrade_expiry = expiry;
367 state.EnableHost("yahoo.com", domain_state); 409 state.EnableHost("yahoo.com", domain_state);
368 EXPECT_TRUE(state.GetDomainState("yahoo.com", true, &domain_state)); 410 EXPECT_TRUE(state.GetDomainState("yahoo.com", true, &domain_state));
(...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after
776 EXPECT_FALSE(state.GetDomainState(kLongName, true, &domain_state)); 818 EXPECT_FALSE(state.GetDomainState(kLongName, true, &domain_state));
777 } 819 }
778 820
779 TEST_F(TransportSecurityStateTest, BuiltinCertPins) { 821 TEST_F(TransportSecurityStateTest, BuiltinCertPins) {
780 TransportSecurityState state; 822 TransportSecurityState state;
781 TransportSecurityState::DomainState domain_state; 823 TransportSecurityState::DomainState domain_state;
782 824
783 EXPECT_TRUE(state.GetDomainState("chrome.google.com", true, &domain_state)); 825 EXPECT_TRUE(state.GetDomainState("chrome.google.com", true, &domain_state));
784 EXPECT_TRUE(HasPins("chrome.google.com")); 826 EXPECT_TRUE(HasPins("chrome.google.com"));
785 827
786 FingerprintVector hashes; 828 HashValueVector hashes;
787 // Checks that a built-in list does exist. 829 // Checks that a built-in list does exist.
788 EXPECT_FALSE(domain_state.IsChainOfPublicKeysPermitted(hashes)); 830 EXPECT_FALSE(domain_state.IsChainOfPublicKeysPermitted(hashes));
789 EXPECT_FALSE(HasPins("www.paypal.com")); 831 EXPECT_FALSE(HasPins("www.paypal.com"));
790 832
791 EXPECT_TRUE(HasPins("docs.google.com")); 833 EXPECT_TRUE(HasPins("docs.google.com"));
792 EXPECT_TRUE(HasPins("1.docs.google.com")); 834 EXPECT_TRUE(HasPins("1.docs.google.com"));
793 EXPECT_TRUE(HasPins("sites.google.com")); 835 EXPECT_TRUE(HasPins("sites.google.com"));
794 EXPECT_TRUE(HasPins("drive.google.com")); 836 EXPECT_TRUE(HasPins("drive.google.com"));
795 EXPECT_TRUE(HasPins("spreadsheets.google.com")); 837 EXPECT_TRUE(HasPins("spreadsheets.google.com"));
796 EXPECT_TRUE(HasPins("health.google.com")); 838 EXPECT_TRUE(HasPins("health.google.com"));
(...skipping 25 matching lines...) Expand all
822 EXPECT_TRUE(HasPins("oauth.twitter.com")); 864 EXPECT_TRUE(HasPins("oauth.twitter.com"));
823 EXPECT_TRUE(HasPins("mobile.twitter.com")); 865 EXPECT_TRUE(HasPins("mobile.twitter.com"));
824 EXPECT_TRUE(HasPins("dev.twitter.com")); 866 EXPECT_TRUE(HasPins("dev.twitter.com"));
825 EXPECT_TRUE(HasPins("business.twitter.com")); 867 EXPECT_TRUE(HasPins("business.twitter.com"));
826 EXPECT_TRUE(HasPins("platform.twitter.com")); 868 EXPECT_TRUE(HasPins("platform.twitter.com"));
827 EXPECT_TRUE(HasPins("si0.twimg.com")); 869 EXPECT_TRUE(HasPins("si0.twimg.com"));
828 EXPECT_TRUE(HasPins("twimg0-a.akamaihd.net")); 870 EXPECT_TRUE(HasPins("twimg0-a.akamaihd.net"));
829 } 871 }
830 872
831 static bool AddHash(const std::string& type_and_base64, 873 static bool AddHash(const std::string& type_and_base64,
832 FingerprintVector* out) { 874 HashValueVector* out) {
833 std::string hash_str; 875 HashValue hash;
834 if (type_and_base64.find("sha1/") == 0 && 876
835 base::Base64Decode(type_and_base64.substr(5, type_and_base64.size() - 5), 877 if (!TransportSecurityState::ParsePin(type_and_base64, &hash))
836 &hash_str) && 878 return false;
837 hash_str.size() == base::kSHA1Length) { 879
838 SHA1Fingerprint hash; 880 out->push_back(hash);
839 memcpy(hash.data, hash_str.data(), sizeof(hash.data)); 881 return true;
840 out->push_back(hash);
841 return true;
842 }
843 return false;
844 } 882 }
845 883
846 TEST_F(TransportSecurityStateTest, PinValidationWithRejectedCerts) { 884 TEST_F(TransportSecurityStateTest, PinValidationWithRejectedCerts) {
847 // kGoodPath is plus.google.com via Google Internet Authority. 885 // kGoodPath is plus.google.com via Google Internet Authority.
848 static const char* kGoodPath[] = { 886 static const char* kGoodPath[] = {
849 "sha1/4BjDjn8v2lWeUFQnqSs0BgbIcrU=", 887 "sha1/4BjDjn8v2lWeUFQnqSs0BgbIcrU=",
850 "sha1/QMVAHW+MuvCLAO3vse6H0AWzuc0=", 888 "sha1/QMVAHW+MuvCLAO3vse6H0AWzuc0=",
851 "sha1/SOZo+SvSspXXR9gjIBBPM5iQn9Q=", 889 "sha1/SOZo+SvSspXXR9gjIBBPM5iQn9Q=",
852 NULL, 890 NULL,
853 }; 891 };
854 892
855 // kBadPath is plus.google.com via Trustcenter, which contains a required 893 // kBadPath is plus.google.com via Trustcenter, which contains a required
856 // certificate (Equifax root), but also an excluded certificate 894 // certificate (Equifax root), but also an excluded certificate
857 // (Trustcenter). 895 // (Trustcenter).
858 static const char* kBadPath[] = { 896 static const char* kBadPath[] = {
859 "sha1/4BjDjn8v2lWeUFQnqSs0BgbIcrU=", 897 "sha1/4BjDjn8v2lWeUFQnqSs0BgbIcrU=",
860 "sha1/gzuEEAB/bkqdQS3EIjk2by7lW+k=", 898 "sha1/gzuEEAB/bkqdQS3EIjk2by7lW+k=",
861 "sha1/SOZo+SvSspXXR9gjIBBPM5iQn9Q=", 899 "sha1/SOZo+SvSspXXR9gjIBBPM5iQn9Q=",
862 NULL, 900 NULL,
863 }; 901 };
864 902
865 std::vector<net::SHA1Fingerprint> good_hashes, bad_hashes; 903 HashValueVector good_hashes, bad_hashes;
866 904
867 for (size_t i = 0; kGoodPath[i]; i++) { 905 for (size_t i = 0; kGoodPath[i]; i++) {
868 EXPECT_TRUE(AddHash(kGoodPath[i], &good_hashes)); 906 EXPECT_TRUE(AddHash(kGoodPath[i], &good_hashes));
869 } 907 }
870 for (size_t i = 0; kBadPath[i]; i++) { 908 for (size_t i = 0; kBadPath[i]; i++) {
871 EXPECT_TRUE(AddHash(kBadPath[i], &bad_hashes)); 909 EXPECT_TRUE(AddHash(kBadPath[i], &bad_hashes));
872 } 910 }
873 911
874 TransportSecurityState state; 912 TransportSecurityState state;
875 TransportSecurityState::DomainState domain_state; 913 TransportSecurityState::DomainState domain_state;
(...skipping 15 matching lines...) Expand all
891 929
892 // kBadPath is plus.google.com via Trustcenter, which is utterly wrong for 930 // kBadPath is plus.google.com via Trustcenter, which is utterly wrong for
893 // torproject.org. 931 // torproject.org.
894 static const char* kBadPath[] = { 932 static const char* kBadPath[] = {
895 "sha1/4BjDjn8v2lWeUFQnqSs0BgbIcrU=", 933 "sha1/4BjDjn8v2lWeUFQnqSs0BgbIcrU=",
896 "sha1/gzuEEAB/bkqdQS3EIjk2by7lW+k=", 934 "sha1/gzuEEAB/bkqdQS3EIjk2by7lW+k=",
897 "sha1/SOZo+SvSspXXR9gjIBBPM5iQn9Q=", 935 "sha1/SOZo+SvSspXXR9gjIBBPM5iQn9Q=",
898 NULL, 936 NULL,
899 }; 937 };
900 938
901 std::vector<net::SHA1Fingerprint> good_hashes, bad_hashes; 939 HashValueVector good_hashes, bad_hashes;
902 940
903 for (size_t i = 0; kGoodPath[i]; i++) { 941 for (size_t i = 0; kGoodPath[i]; i++) {
904 EXPECT_TRUE(AddHash(kGoodPath[i], &good_hashes)); 942 EXPECT_TRUE(AddHash(kGoodPath[i], &good_hashes));
905 } 943 }
906 for (size_t i = 0; kBadPath[i]; i++) { 944 for (size_t i = 0; kBadPath[i]; i++) {
907 EXPECT_TRUE(AddHash(kBadPath[i], &bad_hashes)); 945 EXPECT_TRUE(AddHash(kBadPath[i], &bad_hashes));
908 } 946 }
909 947
910 TransportSecurityState state; 948 TransportSecurityState state;
911 TransportSecurityState::DomainState domain_state; 949 TransportSecurityState::DomainState domain_state;
912 EXPECT_TRUE(state.GetDomainState("blog.torproject.org", true, &domain_state)); 950 EXPECT_TRUE(state.GetDomainState("blog.torproject.org", true, &domain_state));
913 EXPECT_TRUE(domain_state.HasPins()); 951 EXPECT_TRUE(domain_state.HasPins());
914 952
915 EXPECT_TRUE(domain_state.IsChainOfPublicKeysPermitted(good_hashes)); 953 EXPECT_TRUE(domain_state.IsChainOfPublicKeysPermitted(good_hashes));
916 EXPECT_FALSE(domain_state.IsChainOfPublicKeysPermitted(bad_hashes)); 954 EXPECT_FALSE(domain_state.IsChainOfPublicKeysPermitted(bad_hashes));
917 } 955 }
918 956
957 TEST_F(TransportSecurityStateTest, PinValidationWithRejectedCertsMixedHashes) {
958 static const char* ee_sha1 = "sha1/4BjDjn8v2lWeUFQnqSs0BgbIcrU=";
959 static const char* ee_sha256 =
960 "sha256/sRJBQqWhpaKIGcc1NA7/jJ4vgWj+47oYfyU7waOS1+I=";
961 static const char* google_1024_sha1 = "sha1/QMVAHW+MuvCLAO3vse6H0AWzuc0=";
962 static const char* google_1024_sha256 =
963 "sha256/trlUMquuV/4CDLK3T0+fkXPIxwivyecyrOIyeQR8bQU=";
964 static const char* equifax_sha1 = "sha1/SOZo+SvSspXXR9gjIBBPM5iQn9Q=";
965 static const char* equifax_sha256 =
966 "sha256//1aAzXOlcD2gSBegdf1GJQanNQbEuBoVg+9UlHjSZHY=";
967 static const char* trustcenter_sha1 = "sha1/gzuEEAB/bkqdQS3EIjk2by7lW+k=";
968 static const char* trustcenter_sha256 =
969 "sha256/Dq58KIA4NMLsboWMLU8/aTREzaAGEFW+EtUule8dd/M=";
970
971 // Good chains for plus.google.com chain up through google_1024_sha{1,256}
972 // to equifax_sha{1,256}. Bad chains chain up to Equifax through
973 // trustcenter_sha{1,256}, which is a blacklisted key. Even though Equifax
974 // and Google1024 are known-good, the blacklistedness of Trustcenter
975 // should override and cause pin validation failure.
976
977 TransportSecurityState state;
978 TransportSecurityState::DomainState domain_state;
979 EXPECT_TRUE(state.GetDomainState("plus.google.com", true, &domain_state));
980 EXPECT_TRUE(domain_state.HasPins());
981
982 // The statically-defined pins are all SHA-1, so we add some SHA-256 pins
983 // manually:
984 EXPECT_TRUE(AddHash(google_1024_sha256, &domain_state.static_spki_hashes));
985 EXPECT_TRUE(AddHash(trustcenter_sha256,
986 &domain_state.bad_static_spki_hashes));
987
988 // Try an all-good SHA1 chain.
989 HashValueVector validated_chain;
990 EXPECT_TRUE(AddHash(ee_sha1, &validated_chain));
991 EXPECT_TRUE(AddHash(google_1024_sha1, &validated_chain));
992 EXPECT_TRUE(AddHash(equifax_sha1, &validated_chain));
993 EXPECT_TRUE(domain_state.IsChainOfPublicKeysPermitted(validated_chain));
994
995 // Try an all-bad SHA1 chain.
996 validated_chain.clear();
997 EXPECT_TRUE(AddHash(ee_sha1, &validated_chain));
998 EXPECT_TRUE(AddHash(trustcenter_sha1, &validated_chain));
999 EXPECT_TRUE(AddHash(equifax_sha1, &validated_chain));
1000 EXPECT_FALSE(domain_state.IsChainOfPublicKeysPermitted(validated_chain));
1001
1002 // Try an all-good SHA-256 chain.
1003 validated_chain.clear();
1004 EXPECT_TRUE(AddHash(ee_sha256, &validated_chain));
1005 EXPECT_TRUE(AddHash(google_1024_sha256, &validated_chain));
1006 EXPECT_TRUE(AddHash(equifax_sha256, &validated_chain));
1007 EXPECT_TRUE(domain_state.IsChainOfPublicKeysPermitted(validated_chain));
1008
1009 // Try an all-bad SHA-256 chain.
1010 validated_chain.clear();
1011 EXPECT_TRUE(AddHash(ee_sha256, &validated_chain));
1012 EXPECT_TRUE(AddHash(trustcenter_sha256, &validated_chain));
1013 EXPECT_TRUE(AddHash(equifax_sha256, &validated_chain));
1014 EXPECT_FALSE(domain_state.IsChainOfPublicKeysPermitted(validated_chain));
1015
1016 // Try a mixed-hash good chain.
1017 validated_chain.clear();
1018 EXPECT_TRUE(AddHash(ee_sha256, &validated_chain));
1019 EXPECT_TRUE(AddHash(google_1024_sha1, &validated_chain));
1020 EXPECT_TRUE(AddHash(equifax_sha256, &validated_chain));
1021 EXPECT_TRUE(domain_state.IsChainOfPublicKeysPermitted(validated_chain));
1022
1023 // Try a mixed-hash bad chain.
1024 validated_chain.clear();
1025 EXPECT_TRUE(AddHash(ee_sha1, &validated_chain));
1026 EXPECT_TRUE(AddHash(trustcenter_sha256, &validated_chain));
1027 EXPECT_TRUE(AddHash(equifax_sha1, &validated_chain));
1028 EXPECT_FALSE(domain_state.IsChainOfPublicKeysPermitted(validated_chain));
1029
1030 // Try a chain with all good hashes.
1031 validated_chain.clear();
1032 EXPECT_TRUE(AddHash(ee_sha1, &validated_chain));
1033 EXPECT_TRUE(AddHash(google_1024_sha1, &validated_chain));
1034 EXPECT_TRUE(AddHash(equifax_sha1, &validated_chain));
1035 EXPECT_TRUE(AddHash(ee_sha256, &validated_chain));
1036 EXPECT_TRUE(AddHash(google_1024_sha256, &validated_chain));
1037 EXPECT_TRUE(AddHash(equifax_sha256, &validated_chain));
1038 EXPECT_TRUE(domain_state.IsChainOfPublicKeysPermitted(validated_chain));
1039
1040 // Try a chain with all bad hashes.
1041 validated_chain.clear();
1042 EXPECT_TRUE(AddHash(ee_sha1, &validated_chain));
1043 EXPECT_TRUE(AddHash(trustcenter_sha1, &validated_chain));
1044 EXPECT_TRUE(AddHash(equifax_sha1, &validated_chain));
1045 EXPECT_TRUE(AddHash(ee_sha256, &validated_chain));
1046 EXPECT_TRUE(AddHash(trustcenter_sha256, &validated_chain));
1047 EXPECT_TRUE(AddHash(equifax_sha256, &validated_chain));
1048 EXPECT_FALSE(domain_state.IsChainOfPublicKeysPermitted(validated_chain));
1049 }
1050
919 TEST_F(TransportSecurityStateTest, OptionalHSTSCertPins) { 1051 TEST_F(TransportSecurityStateTest, OptionalHSTSCertPins) {
920 TransportSecurityState state; 1052 TransportSecurityState state;
921 TransportSecurityState::DomainState domain_state; 1053 TransportSecurityState::DomainState domain_state;
922 1054
923 EXPECT_FALSE(ShouldRedirect("www.google-analytics.com")); 1055 EXPECT_FALSE(ShouldRedirect("www.google-analytics.com"));
924 1056
925 EXPECT_FALSE(HasPins("www.google-analytics.com", false)); 1057 EXPECT_FALSE(HasPins("www.google-analytics.com", false));
926 EXPECT_TRUE(HasPins("www.google-analytics.com")); 1058 EXPECT_TRUE(HasPins("www.google-analytics.com"));
927 EXPECT_TRUE(HasPins("google.com")); 1059 EXPECT_TRUE(HasPins("google.com"));
928 EXPECT_TRUE(HasPins("www.google.com")); 1060 EXPECT_TRUE(HasPins("www.google.com"));
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
1048 // Expect to fail for SNI hosts when not searching the SNI list: 1180 // Expect to fail for SNI hosts when not searching the SNI list:
1049 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty( 1181 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
1050 "gmail.com", false)); 1182 "gmail.com", false));
1051 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty( 1183 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
1052 "googlegroups.com", false)); 1184 "googlegroups.com", false));
1053 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty( 1185 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
1054 "www.googlegroups.com", false)); 1186 "www.googlegroups.com", false));
1055 } 1187 }
1056 1188
1057 } // namespace net 1189 } // namespace net
OLDNEW
« no previous file with comments | « net/base/transport_security_state.cc ('k') | net/base/x509_cert_types.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698