1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "net/http/transport_security_state.h"
11 #include "base/base64.h"
12 #include "base/files/file_path.h"
13 #include "base/sha1.h"
14 #include "base/strings/string_piece.h"
15 #include "crypto/sha2.h"
16 #include "net/base/net_errors.h"
17 #include "net/base/net_log.h"
18 #include "net/base/test_completion_callback.h"
19 #include "net/base/test_data_directory.h"
20 #include "net/cert/asn1_util.h"
21 #include "net/cert/cert_verifier.h"
22 #include "net/cert/cert_verify_result.h"
23 #include "net/cert/test_root_certs.h"
24 #include "net/cert/x509_cert_types.h"
25 #include "net/cert/x509_certificate.h"
26 #include "net/http/http_util.h"
27 #include "net/ssl/ssl_info.h"
28 #include "net/test/cert_test_util.h"
29 #include "testing/gtest/include/gtest/gtest.h"
31 #if defined(USE_OPENSSL)
32 #include "crypto/openssl_util.h"
34 #include "crypto/nss_util.h"
39 class TransportSecurityStateTest
: public testing::Test
{
40 virtual void SetUp() {
41 #if defined(USE_OPENSSL)
42 crypto::EnsureOpenSSLInit();
44 crypto::EnsureNSSInit();
49 std::string
CanonicalizeHost(const std::string
& host
) {
50 return TransportSecurityState::CanonicalizeHost(host
);
53 bool GetStaticDomainState(TransportSecurityState
* state
,
54 const std::string
& host
,
56 TransportSecurityState::DomainState
* result
) {
57 return state
->GetStaticDomainState(host
, sni_enabled
, result
);
60 void EnableHost(TransportSecurityState
* state
,
61 const std::string
& host
,
62 const TransportSecurityState::DomainState
& domain_state
) {
63 return state
->EnableHost(host
, domain_state
);
67 TEST_F(TransportSecurityStateTest
, SimpleMatches
) {
68 TransportSecurityState state
;
69 TransportSecurityState::DomainState domain_state
;
70 const base::Time
current_time(base::Time::Now());
71 const base::Time expiry
= current_time
+ base::TimeDelta::FromSeconds(1000);
73 EXPECT_FALSE(state
.GetDomainState("yahoo.com", true, &domain_state
));
74 bool include_subdomains
= false;
75 state
.AddHSTS("yahoo.com", expiry
, include_subdomains
);
76 EXPECT_TRUE(state
.GetDomainState("yahoo.com", true, &domain_state
));
79 TEST_F(TransportSecurityStateTest
, MatchesCase1
) {
80 TransportSecurityState state
;
81 TransportSecurityState::DomainState domain_state
;
82 const base::Time
current_time(base::Time::Now());
83 const base::Time expiry
= current_time
+ base::TimeDelta::FromSeconds(1000);
85 EXPECT_FALSE(state
.GetDomainState("yahoo.com", true, &domain_state
));
86 bool include_subdomains
= false;
87 state
.AddHSTS("YAhoo.coM", expiry
, include_subdomains
);
88 EXPECT_TRUE(state
.GetDomainState("yahoo.com", true, &domain_state
));
91 TEST_F(TransportSecurityStateTest
, MatchesCase2
) {
92 TransportSecurityState state
;
93 TransportSecurityState::DomainState domain_state
;
94 const base::Time
current_time(base::Time::Now());
95 const base::Time expiry
= current_time
+ base::TimeDelta::FromSeconds(1000);
97 EXPECT_FALSE(state
.GetDomainState("YAhoo.coM", true, &domain_state
));
98 bool include_subdomains
= false;
99 state
.AddHSTS("yahoo.com", expiry
, include_subdomains
);
100 EXPECT_TRUE(state
.GetDomainState("YAhoo.coM", true, &domain_state
));
103 TEST_F(TransportSecurityStateTest
, SubdomainMatches
) {
104 TransportSecurityState state
;
105 TransportSecurityState::DomainState domain_state
;
106 const base::Time
current_time(base::Time::Now());
107 const base::Time expiry
= current_time
+ base::TimeDelta::FromSeconds(1000);
109 EXPECT_FALSE(state
.GetDomainState("yahoo.com", true, &domain_state
));
110 bool include_subdomains
= true;
111 state
.AddHSTS("yahoo.com", expiry
, include_subdomains
);
112 EXPECT_TRUE(state
.GetDomainState("yahoo.com", true, &domain_state
));
113 EXPECT_TRUE(state
.GetDomainState("foo.yahoo.com", true, &domain_state
));
114 EXPECT_TRUE(state
.GetDomainState("foo.bar.yahoo.com", true, &domain_state
));
115 EXPECT_TRUE(state
.GetDomainState("foo.bar.baz.yahoo.com", true,
117 EXPECT_FALSE(state
.GetDomainState("com", true, &domain_state
));
120 TEST_F(TransportSecurityStateTest
, InvalidDomains
) {
121 TransportSecurityState state
;
122 TransportSecurityState::DomainState domain_state
;
123 const base::Time
current_time(base::Time::Now());
124 const base::Time expiry
= current_time
+ base::TimeDelta::FromSeconds(1000);
126 EXPECT_FALSE(state
.GetDomainState("yahoo.com", true, &domain_state
));
127 bool include_subdomains
= true;
128 state
.AddHSTS("yahoo.com", expiry
, include_subdomains
);
129 EXPECT_TRUE(state
.GetDomainState("www-.foo.yahoo.com", true, &domain_state
));
130 EXPECT_TRUE(state
.GetDomainState("2\x01.foo.yahoo.com", true, &domain_state
));
133 TEST_F(TransportSecurityStateTest
, DeleteAllDynamicDataSince
) {
134 TransportSecurityState state
;
135 TransportSecurityState::DomainState domain_state
;
136 const base::Time
current_time(base::Time::Now());
137 const base::Time expiry
= current_time
+ base::TimeDelta::FromSeconds(1000);
138 const base::Time older
= current_time
- base::TimeDelta::FromSeconds(1000);
140 EXPECT_FALSE(state
.GetDomainState("yahoo.com", true, &domain_state
));
141 bool include_subdomains
= false;
142 state
.AddHSTS("yahoo.com", expiry
, include_subdomains
);
144 state
.DeleteAllDynamicDataSince(expiry
);
145 EXPECT_TRUE(state
.GetDomainState("yahoo.com", true, &domain_state
));
146 state
.DeleteAllDynamicDataSince(older
);
147 EXPECT_FALSE(state
.GetDomainState("yahoo.com", true, &domain_state
));
150 TEST_F(TransportSecurityStateTest
, DeleteDynamicDataForHost
) {
151 TransportSecurityState state
;
152 TransportSecurityState::DomainState domain_state
;
153 const base::Time
current_time(base::Time::Now());
154 const base::Time expiry
= current_time
+ base::TimeDelta::FromSeconds(1000);
155 bool include_subdomains
= false;
156 state
.AddHSTS("yahoo.com", expiry
, include_subdomains
);
158 EXPECT_TRUE(state
.GetDomainState("yahoo.com", true, &domain_state
));
159 EXPECT_FALSE(state
.GetDomainState("example.com", true, &domain_state
));
160 EXPECT_TRUE(state
.DeleteDynamicDataForHost("yahoo.com"));
161 EXPECT_FALSE(state
.GetDomainState("yahoo.com", true, &domain_state
));
164 TEST_F(TransportSecurityStateTest
, IsPreloaded
) {
165 const std::string paypal
= CanonicalizeHost("paypal.com");
166 const std::string www_paypal
= CanonicalizeHost("www.paypal.com");
167 const std::string foo_paypal
= CanonicalizeHost("foo.paypal.com");
168 const std::string a_www_paypal
= CanonicalizeHost("a.www.paypal.com");
169 const std::string abc_paypal
= CanonicalizeHost("a.b.c.paypal.com");
170 const std::string example
= CanonicalizeHost("example.com");
171 const std::string aypal
= CanonicalizeHost("aypal.com");
173 TransportSecurityState state
;
174 TransportSecurityState::DomainState domain_state
;
176 EXPECT_TRUE(GetStaticDomainState(&state
, paypal
, true, &domain_state
));
177 EXPECT_TRUE(GetStaticDomainState(&state
, www_paypal
, true, &domain_state
));
178 EXPECT_FALSE(domain_state
.sts_include_subdomains
);
179 EXPECT_FALSE(domain_state
.pkp_include_subdomains
);
180 EXPECT_FALSE(GetStaticDomainState(&state
, a_www_paypal
, true, &domain_state
));
181 EXPECT_FALSE(GetStaticDomainState(&state
, abc_paypal
, true, &domain_state
));
182 EXPECT_FALSE(GetStaticDomainState(&state
, example
, true, &domain_state
));
183 EXPECT_FALSE(GetStaticDomainState(&state
, aypal
, true, &domain_state
));
186 TEST_F(TransportSecurityStateTest
, PreloadedDomainSet
) {
187 TransportSecurityState state
;
188 TransportSecurityState::DomainState domain_state
;
190 // The domain wasn't being set, leading to a blank string in the
191 // chrome://net-internals/#hsts UI. So test that.
192 EXPECT_TRUE(state
.GetDomainState("market.android.com", true, &domain_state
));
193 EXPECT_EQ(domain_state
.domain
, "market.android.com");
194 EXPECT_TRUE(state
.GetDomainState("sub.market.android.com", true,
196 EXPECT_EQ(domain_state
.domain
, "market.android.com");
199 static bool ShouldRedirect(const char* hostname
) {
200 TransportSecurityState state
;
201 TransportSecurityState::DomainState domain_state
;
202 return state
.GetDomainState(hostname
, true /* SNI ok */, &domain_state
) &&
203 domain_state
.ShouldUpgradeToSSL();
206 static bool HasState(const char* hostname
) {
207 TransportSecurityState state
;
208 TransportSecurityState::DomainState domain_state
;
209 return state
.GetDomainState(hostname
, true /* SNI ok */, &domain_state
);
212 static bool HasPublicKeyPins(const char* hostname
, bool sni_enabled
) {
213 TransportSecurityState state
;
214 TransportSecurityState::DomainState domain_state
;
215 if (!state
.GetDomainState(hostname
, sni_enabled
, &domain_state
))
218 return domain_state
.HasPublicKeyPins();
221 static bool HasPublicKeyPins(const char* hostname
) {
222 return HasPublicKeyPins(hostname
, true);
225 static bool OnlyPinning(const char *hostname
) {
226 TransportSecurityState state
;
227 TransportSecurityState::DomainState domain_state
;
228 if (!state
.GetDomainState(hostname
, true /* SNI ok */, &domain_state
))
231 return (domain_state
.static_spki_hashes
.size() > 0 ||
232 domain_state
.bad_static_spki_hashes
.size() > 0 ||
233 domain_state
.dynamic_spki_hashes
.size() > 0) &&
234 !domain_state
.ShouldUpgradeToSSL();
237 TEST_F(TransportSecurityStateTest
, Preloaded
) {
238 TransportSecurityState state
;
239 TransportSecurityState::DomainState domain_state
;
241 // We do more extensive checks for the first domain.
242 EXPECT_TRUE(state
.GetDomainState("www.paypal.com", true, &domain_state
));
243 EXPECT_EQ(domain_state
.upgrade_mode
,
244 TransportSecurityState::DomainState::MODE_FORCE_HTTPS
);
245 EXPECT_FALSE(domain_state
.sts_include_subdomains
);
246 EXPECT_FALSE(domain_state
.pkp_include_subdomains
);
248 EXPECT_TRUE(HasState("paypal.com"));
249 EXPECT_FALSE(HasState("www2.paypal.com"));
250 EXPECT_FALSE(HasState("www2.paypal.com"));
254 EXPECT_TRUE(ShouldRedirect("chrome.google.com"));
255 EXPECT_TRUE(ShouldRedirect("checkout.google.com"));
256 EXPECT_TRUE(ShouldRedirect("wallet.google.com"));
257 EXPECT_TRUE(ShouldRedirect("docs.google.com"));
258 EXPECT_TRUE(ShouldRedirect("sites.google.com"));
259 EXPECT_TRUE(ShouldRedirect("drive.google.com"));
260 EXPECT_TRUE(ShouldRedirect("spreadsheets.google.com"));
261 EXPECT_TRUE(ShouldRedirect("appengine.google.com"));
262 EXPECT_TRUE(ShouldRedirect("market.android.com"));
263 EXPECT_TRUE(ShouldRedirect("encrypted.google.com"));
264 EXPECT_TRUE(ShouldRedirect("accounts.google.com"));
265 EXPECT_TRUE(ShouldRedirect("profiles.google.com"));
266 EXPECT_TRUE(ShouldRedirect("mail.google.com"));
267 EXPECT_TRUE(ShouldRedirect("chatenabled.mail.google.com"));
268 EXPECT_TRUE(ShouldRedirect("talkgadget.google.com"));
269 EXPECT_TRUE(ShouldRedirect("hostedtalkgadget.google.com"));
270 EXPECT_TRUE(ShouldRedirect("talk.google.com"));
271 EXPECT_TRUE(ShouldRedirect("plus.google.com"));
272 EXPECT_TRUE(ShouldRedirect("groups.google.com"));
273 EXPECT_TRUE(ShouldRedirect("apis.google.com"));
274 EXPECT_FALSE(ShouldRedirect("chart.apis.google.com"));
275 EXPECT_TRUE(ShouldRedirect("ssl.google-analytics.com"));
276 EXPECT_TRUE(ShouldRedirect("gmail.com"));
277 EXPECT_TRUE(ShouldRedirect("www.gmail.com"));
278 EXPECT_TRUE(ShouldRedirect("googlemail.com"));
279 EXPECT_TRUE(ShouldRedirect("www.googlemail.com"));
280 EXPECT_TRUE(ShouldRedirect("googleplex.com"));
281 EXPECT_TRUE(ShouldRedirect("www.googleplex.com"));
282 EXPECT_FALSE(HasState("m.gmail.com"));
283 EXPECT_FALSE(HasState("m.googlemail.com"));
285 EXPECT_TRUE(OnlyPinning("www.google.com"));
286 EXPECT_TRUE(OnlyPinning("foo.google.com"));
287 EXPECT_TRUE(OnlyPinning("google.com"));
288 EXPECT_TRUE(OnlyPinning("www.youtube.com"));
289 EXPECT_TRUE(OnlyPinning("youtube.com"));
290 EXPECT_TRUE(OnlyPinning("i.ytimg.com"));
291 EXPECT_TRUE(OnlyPinning("ytimg.com"));
292 EXPECT_TRUE(OnlyPinning("googleusercontent.com"));
293 EXPECT_TRUE(OnlyPinning("www.googleusercontent.com"));
294 EXPECT_TRUE(OnlyPinning("www.google-analytics.com"));
295 EXPECT_TRUE(OnlyPinning("googleapis.com"));
296 EXPECT_TRUE(OnlyPinning("googleadservices.com"));
297 EXPECT_TRUE(OnlyPinning("googlecode.com"));
298 EXPECT_TRUE(OnlyPinning("appspot.com"));
299 EXPECT_TRUE(OnlyPinning("googlesyndication.com"));
300 EXPECT_TRUE(OnlyPinning("doubleclick.net"));
301 EXPECT_TRUE(OnlyPinning("googlegroups.com"));
303 // Tests for domains that don't work without SNI.
304 EXPECT_FALSE(state
.GetDomainState("gmail.com", false, &domain_state
));
305 EXPECT_FALSE(state
.GetDomainState("www.gmail.com", false, &domain_state
));
306 EXPECT_FALSE(state
.GetDomainState("m.gmail.com", false, &domain_state
));
307 EXPECT_FALSE(state
.GetDomainState("googlemail.com", false, &domain_state
));
308 EXPECT_FALSE(state
.GetDomainState("www.googlemail.com", false,
310 EXPECT_FALSE(state
.GetDomainState("m.googlemail.com", false, &domain_state
));
314 EXPECT_TRUE(ShouldRedirect("aladdinschools.appspot.com"));
316 EXPECT_TRUE(ShouldRedirect("ottospora.nl"));
317 EXPECT_TRUE(ShouldRedirect("www.ottospora.nl"));
319 EXPECT_TRUE(ShouldRedirect("www.paycheckrecords.com"));
321 EXPECT_TRUE(ShouldRedirect("lastpass.com"));
322 EXPECT_TRUE(ShouldRedirect("www.lastpass.com"));
323 EXPECT_FALSE(HasState("blog.lastpass.com"));
325 EXPECT_TRUE(ShouldRedirect("keyerror.com"));
326 EXPECT_TRUE(ShouldRedirect("www.keyerror.com"));
328 EXPECT_TRUE(ShouldRedirect("entropia.de"));
329 EXPECT_TRUE(ShouldRedirect("www.entropia.de"));
330 EXPECT_FALSE(HasState("foo.entropia.de"));
332 EXPECT_TRUE(ShouldRedirect("www.elanex.biz"));
333 EXPECT_FALSE(HasState("elanex.biz"));
334 EXPECT_FALSE(HasState("foo.elanex.biz"));
336 EXPECT_TRUE(ShouldRedirect("sunshinepress.org"));
337 EXPECT_TRUE(ShouldRedirect("www.sunshinepress.org"));
338 EXPECT_TRUE(ShouldRedirect("a.b.sunshinepress.org"));
340 EXPECT_TRUE(ShouldRedirect("www.noisebridge.net"));
341 EXPECT_FALSE(HasState("noisebridge.net"));
342 EXPECT_FALSE(HasState("foo.noisebridge.net"));
344 EXPECT_TRUE(ShouldRedirect("neg9.org"));
345 EXPECT_FALSE(HasState("www.neg9.org"));
347 EXPECT_TRUE(ShouldRedirect("riseup.net"));
348 EXPECT_TRUE(ShouldRedirect("foo.riseup.net"));
350 EXPECT_TRUE(ShouldRedirect("factor.cc"));
351 EXPECT_FALSE(HasState("www.factor.cc"));
353 EXPECT_TRUE(ShouldRedirect("members.mayfirst.org"));
354 EXPECT_TRUE(ShouldRedirect("support.mayfirst.org"));
355 EXPECT_TRUE(ShouldRedirect("id.mayfirst.org"));
356 EXPECT_TRUE(ShouldRedirect("lists.mayfirst.org"));
357 EXPECT_FALSE(HasState("www.mayfirst.org"));
359 EXPECT_TRUE(ShouldRedirect("romab.com"));
360 EXPECT_TRUE(ShouldRedirect("www.romab.com"));
361 EXPECT_TRUE(ShouldRedirect("foo.romab.com"));
363 EXPECT_TRUE(ShouldRedirect("logentries.com"));
364 EXPECT_TRUE(ShouldRedirect("www.logentries.com"));
365 EXPECT_FALSE(HasState("foo.logentries.com"));
367 EXPECT_TRUE(ShouldRedirect("stripe.com"));
368 EXPECT_TRUE(ShouldRedirect("foo.stripe.com"));
370 EXPECT_TRUE(ShouldRedirect("cloudsecurityalliance.org"));
371 EXPECT_TRUE(ShouldRedirect("foo.cloudsecurityalliance.org"));
373 EXPECT_TRUE(ShouldRedirect("login.sapo.pt"));
374 EXPECT_TRUE(ShouldRedirect("foo.login.sapo.pt"));
376 EXPECT_TRUE(ShouldRedirect("mattmccutchen.net"));
377 EXPECT_TRUE(ShouldRedirect("foo.mattmccutchen.net"));
379 EXPECT_TRUE(ShouldRedirect("betnet.fr"));
380 EXPECT_TRUE(ShouldRedirect("foo.betnet.fr"));
382 EXPECT_TRUE(ShouldRedirect("uprotect.it"));
383 EXPECT_TRUE(ShouldRedirect("foo.uprotect.it"));
385 EXPECT_TRUE(ShouldRedirect("squareup.com"));
386 EXPECT_FALSE(HasState("foo.squareup.com"));
388 EXPECT_TRUE(ShouldRedirect("cert.se"));
389 EXPECT_TRUE(ShouldRedirect("foo.cert.se"));
391 EXPECT_TRUE(ShouldRedirect("crypto.is"));
392 EXPECT_TRUE(ShouldRedirect("foo.crypto.is"));
394 EXPECT_TRUE(ShouldRedirect("simon.butcher.name"));
395 EXPECT_TRUE(ShouldRedirect("foo.simon.butcher.name"));
397 EXPECT_TRUE(ShouldRedirect("linx.net"));
398 EXPECT_TRUE(ShouldRedirect("foo.linx.net"));
400 EXPECT_TRUE(ShouldRedirect("dropcam.com"));
401 EXPECT_TRUE(ShouldRedirect("www.dropcam.com"));
402 EXPECT_FALSE(HasState("foo.dropcam.com"));
404 EXPECT_TRUE(state
.GetDomainState("torproject.org", false, &domain_state
));
405 EXPECT_FALSE(domain_state
.static_spki_hashes
.empty());
406 EXPECT_TRUE(state
.GetDomainState("www.torproject.org", false,
408 EXPECT_FALSE(domain_state
.static_spki_hashes
.empty());
409 EXPECT_TRUE(state
.GetDomainState("check.torproject.org", false,
411 EXPECT_FALSE(domain_state
.static_spki_hashes
.empty());
412 EXPECT_TRUE(state
.GetDomainState("blog.torproject.org", false,
414 EXPECT_FALSE(domain_state
.static_spki_hashes
.empty());
415 EXPECT_TRUE(ShouldRedirect("ebanking.indovinabank.com.vn"));
416 EXPECT_TRUE(ShouldRedirect("foo.ebanking.indovinabank.com.vn"));
418 EXPECT_TRUE(ShouldRedirect("epoxate.com"));
419 EXPECT_FALSE(HasState("foo.epoxate.com"));
421 EXPECT_TRUE(HasPublicKeyPins("torproject.org"));
422 EXPECT_TRUE(HasPublicKeyPins("www.torproject.org"));
423 EXPECT_TRUE(HasPublicKeyPins("check.torproject.org"));
424 EXPECT_TRUE(HasPublicKeyPins("blog.torproject.org"));
425 EXPECT_FALSE(HasState("foo.torproject.org"));
427 EXPECT_TRUE(ShouldRedirect("www.moneybookers.com"));
428 EXPECT_FALSE(HasState("moneybookers.com"));
430 EXPECT_TRUE(ShouldRedirect("ledgerscope.net"));
431 EXPECT_TRUE(ShouldRedirect("www.ledgerscope.net"));
432 EXPECT_FALSE(HasState("status.ledgerscope.net"));
434 EXPECT_TRUE(ShouldRedirect("foo.app.recurly.com"));
435 EXPECT_TRUE(ShouldRedirect("foo.api.recurly.com"));
437 EXPECT_TRUE(ShouldRedirect("greplin.com"));
438 EXPECT_TRUE(ShouldRedirect("www.greplin.com"));
439 EXPECT_FALSE(HasState("foo.greplin.com"));
441 EXPECT_TRUE(ShouldRedirect("luneta.nearbuysystems.com"));
442 EXPECT_TRUE(ShouldRedirect("foo.luneta.nearbuysystems.com"));
444 EXPECT_TRUE(ShouldRedirect("ubertt.org"));
445 EXPECT_TRUE(ShouldRedirect("foo.ubertt.org"));
447 EXPECT_TRUE(ShouldRedirect("pixi.me"));
448 EXPECT_TRUE(ShouldRedirect("www.pixi.me"));
450 EXPECT_TRUE(ShouldRedirect("grepular.com"));
451 EXPECT_TRUE(ShouldRedirect("www.grepular.com"));
453 EXPECT_TRUE(ShouldRedirect("mydigipass.com"));
454 EXPECT_FALSE(ShouldRedirect("foo.mydigipass.com"));
455 EXPECT_TRUE(ShouldRedirect("www.mydigipass.com"));
456 EXPECT_FALSE(ShouldRedirect("foo.www.mydigipass.com"));
457 EXPECT_TRUE(ShouldRedirect("developer.mydigipass.com"));
458 EXPECT_FALSE(ShouldRedirect("foo.developer.mydigipass.com"));
459 EXPECT_TRUE(ShouldRedirect("www.developer.mydigipass.com"));
460 EXPECT_FALSE(ShouldRedirect("foo.www.developer.mydigipass.com"));
461 EXPECT_TRUE(ShouldRedirect("sandbox.mydigipass.com"));
462 EXPECT_FALSE(ShouldRedirect("foo.sandbox.mydigipass.com"));
463 EXPECT_TRUE(ShouldRedirect("www.sandbox.mydigipass.com"));
464 EXPECT_FALSE(ShouldRedirect("foo.www.sandbox.mydigipass.com"));
466 EXPECT_TRUE(ShouldRedirect("crypto.cat"));
467 EXPECT_FALSE(ShouldRedirect("foo.crypto.cat"));
469 EXPECT_TRUE(ShouldRedirect("bigshinylock.minazo.net"));
470 EXPECT_TRUE(ShouldRedirect("foo.bigshinylock.minazo.net"));
472 EXPECT_TRUE(ShouldRedirect("crate.io"));
473 EXPECT_TRUE(ShouldRedirect("foo.crate.io"));
475 EXPECT_TRUE(HasPublicKeyPins("www.twitter.com"));
478 TEST_F(TransportSecurityStateTest
, LongNames
) {
479 TransportSecurityState state
;
480 const char kLongName
[] =
481 "lookupByWaveIdHashAndWaveIdIdAndWaveIdDomainAndWaveletIdIdAnd"
482 "WaveletIdDomainAndBlipBlipid";
483 TransportSecurityState::DomainState domain_state
;
484 // Just checks that we don't hit a NOTREACHED.
485 EXPECT_FALSE(state
.GetDomainState(kLongName
, true, &domain_state
));
488 TEST_F(TransportSecurityStateTest
, BuiltinCertPins
) {
489 TransportSecurityState state
;
490 TransportSecurityState::DomainState domain_state
;
492 EXPECT_TRUE(state
.GetDomainState("chrome.google.com", true, &domain_state
));
493 EXPECT_TRUE(HasPublicKeyPins("chrome.google.com"));
495 HashValueVector hashes
;
496 // Checks that a built-in list does exist.
497 EXPECT_FALSE(domain_state
.CheckPublicKeyPins(hashes
));
498 EXPECT_FALSE(HasPublicKeyPins("www.paypal.com"));
500 EXPECT_TRUE(HasPublicKeyPins("docs.google.com"));
501 EXPECT_TRUE(HasPublicKeyPins("1.docs.google.com"));
502 EXPECT_TRUE(HasPublicKeyPins("sites.google.com"));
503 EXPECT_TRUE(HasPublicKeyPins("drive.google.com"));
504 EXPECT_TRUE(HasPublicKeyPins("spreadsheets.google.com"));
505 EXPECT_TRUE(HasPublicKeyPins("wallet.google.com"));
506 EXPECT_TRUE(HasPublicKeyPins("checkout.google.com"));
507 EXPECT_TRUE(HasPublicKeyPins("appengine.google.com"));
508 EXPECT_TRUE(HasPublicKeyPins("market.android.com"));
509 EXPECT_TRUE(HasPublicKeyPins("encrypted.google.com"));
510 EXPECT_TRUE(HasPublicKeyPins("accounts.google.com"));
511 EXPECT_TRUE(HasPublicKeyPins("profiles.google.com"));
512 EXPECT_TRUE(HasPublicKeyPins("mail.google.com"));
513 EXPECT_TRUE(HasPublicKeyPins("chatenabled.mail.google.com"));
514 EXPECT_TRUE(HasPublicKeyPins("talkgadget.google.com"));
515 EXPECT_TRUE(HasPublicKeyPins("hostedtalkgadget.google.com"));
516 EXPECT_TRUE(HasPublicKeyPins("talk.google.com"));
517 EXPECT_TRUE(HasPublicKeyPins("plus.google.com"));
518 EXPECT_TRUE(HasPublicKeyPins("groups.google.com"));
519 EXPECT_TRUE(HasPublicKeyPins("apis.google.com"));
521 EXPECT_TRUE(HasPublicKeyPins("ssl.gstatic.com"));
522 EXPECT_TRUE(HasPublicKeyPins("gstatic.com"));
523 EXPECT_TRUE(HasPublicKeyPins("www.gstatic.com"));
524 EXPECT_TRUE(HasPublicKeyPins("ssl.google-analytics.com"));
525 EXPECT_TRUE(HasPublicKeyPins("www.googleplex.com"));
527 // Disabled in order to help track down pinning failures --agl
528 EXPECT_TRUE(HasPublicKeyPins("twitter.com"));
529 EXPECT_FALSE(HasPublicKeyPins("foo.twitter.com"));
530 EXPECT_TRUE(HasPublicKeyPins("www.twitter.com"));
531 EXPECT_TRUE(HasPublicKeyPins("api.twitter.com"));
532 EXPECT_TRUE(HasPublicKeyPins("oauth.twitter.com"));
533 EXPECT_TRUE(HasPublicKeyPins("mobile.twitter.com"));
534 EXPECT_TRUE(HasPublicKeyPins("dev.twitter.com"));
535 EXPECT_TRUE(HasPublicKeyPins("business.twitter.com"));
536 EXPECT_TRUE(HasPublicKeyPins("platform.twitter.com"));
537 EXPECT_TRUE(HasPublicKeyPins("si0.twimg.com"));
540 static bool AddHash(const std::string
& type_and_base64
,
541 HashValueVector
* out
) {
543 if (!hash
.FromString(type_and_base64
))
546 out
->push_back(hash
);
550 TEST_F(TransportSecurityStateTest
, PinValidationWithoutRejectedCerts
) {
551 // kGoodPath is blog.torproject.org.
552 static const char* kGoodPath
[] = {
553 "sha1/m9lHYJYke9k0GtVZ+bXSQYE8nDI=",
554 "sha1/o5OZxATDsgmwgcIfIWIneMJ0jkw=",
555 "sha1/wHqYaI2J+6sFZAwRfap9ZbjKzE4=",
559 // kBadPath is plus.google.com via Trustcenter, which is utterly wrong for
561 static const char* kBadPath
[] = {
562 "sha1/4BjDjn8v2lWeUFQnqSs0BgbIcrU=",
563 "sha1/gzuEEAB/bkqdQS3EIjk2by7lW+k=",
564 "sha1/SOZo+SvSspXXR9gjIBBPM5iQn9Q=",
568 HashValueVector good_hashes
, bad_hashes
;
570 for (size_t i
= 0; kGoodPath
[i
]; i
++) {
571 EXPECT_TRUE(AddHash(kGoodPath
[i
], &good_hashes
));
573 for (size_t i
= 0; kBadPath
[i
]; i
++) {
574 EXPECT_TRUE(AddHash(kBadPath
[i
], &bad_hashes
));
577 TransportSecurityState state
;
578 TransportSecurityState::DomainState domain_state
;
579 EXPECT_TRUE(state
.GetDomainState("blog.torproject.org", true, &domain_state
));
580 EXPECT_TRUE(domain_state
.HasPublicKeyPins());
582 EXPECT_TRUE(domain_state
.CheckPublicKeyPins(good_hashes
));
583 EXPECT_FALSE(domain_state
.CheckPublicKeyPins(bad_hashes
));
586 TEST_F(TransportSecurityStateTest
, OptionalHSTSCertPins
) {
587 TransportSecurityState state
;
588 TransportSecurityState::DomainState domain_state
;
590 EXPECT_FALSE(ShouldRedirect("www.google-analytics.com"));
592 EXPECT_FALSE(HasPublicKeyPins("www.google-analytics.com", false));
593 EXPECT_TRUE(HasPublicKeyPins("www.google-analytics.com"));
594 EXPECT_TRUE(HasPublicKeyPins("google.com"));
595 EXPECT_TRUE(HasPublicKeyPins("www.google.com"));
596 EXPECT_TRUE(HasPublicKeyPins("mail-attachment.googleusercontent.com"));
597 EXPECT_TRUE(HasPublicKeyPins("www.youtube.com"));
598 EXPECT_TRUE(HasPublicKeyPins("i.ytimg.com"));
599 EXPECT_TRUE(HasPublicKeyPins("googleapis.com"));
600 EXPECT_TRUE(HasPublicKeyPins("ajax.googleapis.com"));
601 EXPECT_TRUE(HasPublicKeyPins("googleadservices.com"));
602 EXPECT_TRUE(HasPublicKeyPins("pagead2.googleadservices.com"));
603 EXPECT_TRUE(HasPublicKeyPins("googlecode.com"));
604 EXPECT_TRUE(HasPublicKeyPins("kibbles.googlecode.com"));
605 EXPECT_TRUE(HasPublicKeyPins("appspot.com"));
606 EXPECT_TRUE(HasPublicKeyPins("googlesyndication.com"));
607 EXPECT_TRUE(HasPublicKeyPins("doubleclick.net"));
608 EXPECT_TRUE(HasPublicKeyPins("ad.doubleclick.net"));
609 EXPECT_FALSE(HasPublicKeyPins("learn.doubleclick.net"));
610 EXPECT_TRUE(HasPublicKeyPins("a.googlegroups.com"));
611 EXPECT_FALSE(HasPublicKeyPins("a.googlegroups.com", false));
614 TEST_F(TransportSecurityStateTest
, OverrideBuiltins
) {
615 EXPECT_TRUE(HasPublicKeyPins("google.com"));
616 EXPECT_FALSE(ShouldRedirect("google.com"));
617 EXPECT_FALSE(ShouldRedirect("www.google.com"));
619 TransportSecurityState state
;
620 TransportSecurityState::DomainState domain_state
;
621 const base::Time
current_time(base::Time::Now());
622 const base::Time expiry
= current_time
+ base::TimeDelta::FromSeconds(1000);
623 domain_state
.upgrade_expiry
= expiry
;
624 EnableHost(&state
, "www.google.com", domain_state
);
626 EXPECT_TRUE(state
.GetDomainState("www.google.com", true, &domain_state
));
629 TEST_F(TransportSecurityStateTest
, GooglePinnedProperties
) {
630 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
631 "www.example.com", true));
632 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
633 "www.paypal.com", true));
634 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
635 "mail.twitter.com", true));
636 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
637 "www.google.com.int", true));
638 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
639 "jottit.com", true));
640 // learn.doubleclick.net has a more specific match than
641 // *.doubleclick.com, and has 0 or NULL for its required certs.
642 // This test ensures that the exact-match-preferred behavior
644 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
645 "learn.doubleclick.net", true));
647 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
648 "encrypted.google.com", true));
649 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
650 "mail.google.com", true));
651 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
652 "accounts.google.com", true));
653 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
654 "doubleclick.net", true));
655 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
656 "ad.doubleclick.net", true));
657 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
658 "youtube.com", true));
659 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
660 "www.profiles.google.com", true));
661 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
662 "checkout.google.com", true));
663 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
664 "googleadservices.com", true));
666 // Test with sni_enabled false:
667 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
668 "www.example.com", false));
669 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
670 "www.paypal.com", false));
671 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
672 "checkout.google.com", false));
673 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
674 "googleadservices.com", false));
676 // Test some SNI hosts:
677 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
679 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
680 "googlegroups.com", true));
681 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty(
682 "www.googlegroups.com", true));
683 // Expect to fail for SNI hosts when not searching the SNI list:
684 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
685 "gmail.com", false));
686 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
687 "googlegroups.com", false));
688 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty(
689 "www.googlegroups.com", false));