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. 4 5 #include "net/http/transport_security_state.h" 6 7 #include <algorithm> 8 #include <string> 9 #include <vector> 10 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" 30 31 #if defined(USE_OPENSSL) 32 #include "crypto/openssl_util.h" 33 #else 34 #include "crypto/nss_util.h" 35 #endif 36 37 namespace net { 38 39 class TransportSecurityStateTest : public testing::Test { 40 virtual void SetUp() { 41 #if defined(USE_OPENSSL) 42 crypto::EnsureOpenSSLInit(); 43 #else 44 crypto::EnsureNSSInit(); 45 #endif 46 } 47 48 protected: 49 std::string CanonicalizeHost(const std::string& host) { 50 return TransportSecurityState::CanonicalizeHost(host); 51 } 52 53 bool GetStaticDomainState(TransportSecurityState* state, 54 const std::string& host, 55 bool sni_enabled, 56 TransportSecurityState::DomainState* result) { 57 return state->GetStaticDomainState(host, sni_enabled, result); 58 } 59 60 void EnableHost(TransportSecurityState* state, 61 const std::string& host, 62 const TransportSecurityState::DomainState& domain_state) { 63 return state->EnableHost(host, domain_state); 64 } 65 }; 66 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); 72 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)); 77 } 78 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); 84 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)); 89 } 90 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); 96 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)); 101 } 102 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); 108 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, 116 &domain_state)); 117 EXPECT_FALSE(state.GetDomainState("com", true, &domain_state)); 118 } 119 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); 125 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)); 131 } 132 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); 139 140 EXPECT_FALSE(state.GetDomainState("yahoo.com", true, &domain_state)); 141 bool include_subdomains = false; 142 state.AddHSTS("yahoo.com", expiry, include_subdomains); 143 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)); 148 } 149 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); 157 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)); 162 } 163 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"); 172 173 TransportSecurityState state; 174 TransportSecurityState::DomainState domain_state; 175 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)); 184 } 185 186 TEST_F(TransportSecurityStateTest, PreloadedDomainSet) { 187 TransportSecurityState state; 188 TransportSecurityState::DomainState domain_state; 189 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, 195 &domain_state)); 196 EXPECT_EQ(domain_state.domain, "market.android.com"); 197 } 198 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(); 204 } 205 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); 210 } 211 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)) 216 return false; 217 218 return domain_state.HasPublicKeyPins(); 219 } 220 221 static bool HasPublicKeyPins(const char* hostname) { 222 return HasPublicKeyPins(hostname, true); 223 } 224 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)) 229 return false; 230 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(); 235 } 236 237 TEST_F(TransportSecurityStateTest, Preloaded) { 238 TransportSecurityState state; 239 TransportSecurityState::DomainState domain_state; 240 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); 247 248 EXPECT_TRUE(HasState("paypal.com")); 249 EXPECT_FALSE(HasState("www2.paypal.com")); 250 EXPECT_FALSE(HasState("www2.paypal.com")); 251 252 // Google hosts: 253 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")); 284 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")); 302 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, 309 &domain_state)); 310 EXPECT_FALSE(state.GetDomainState("m.googlemail.com", false, &domain_state)); 311 312 // Other hosts: 313 314 EXPECT_TRUE(ShouldRedirect("aladdinschools.appspot.com")); 315 316 EXPECT_TRUE(ShouldRedirect("ottospora.nl")); 317 EXPECT_TRUE(ShouldRedirect("www.ottospora.nl")); 318 319 EXPECT_TRUE(ShouldRedirect("www.paycheckrecords.com")); 320 321 EXPECT_TRUE(ShouldRedirect("lastpass.com")); 322 EXPECT_TRUE(ShouldRedirect("www.lastpass.com")); 323 EXPECT_FALSE(HasState("blog.lastpass.com")); 324 325 EXPECT_TRUE(ShouldRedirect("keyerror.com")); 326 EXPECT_TRUE(ShouldRedirect("www.keyerror.com")); 327 328 EXPECT_TRUE(ShouldRedirect("entropia.de")); 329 EXPECT_TRUE(ShouldRedirect("www.entropia.de")); 330 EXPECT_FALSE(HasState("foo.entropia.de")); 331 332 EXPECT_TRUE(ShouldRedirect("www.elanex.biz")); 333 EXPECT_FALSE(HasState("elanex.biz")); 334 EXPECT_FALSE(HasState("foo.elanex.biz")); 335 336 EXPECT_TRUE(ShouldRedirect("sunshinepress.org")); 337 EXPECT_TRUE(ShouldRedirect("www.sunshinepress.org")); 338 EXPECT_TRUE(ShouldRedirect("a.b.sunshinepress.org")); 339 340 EXPECT_TRUE(ShouldRedirect("www.noisebridge.net")); 341 EXPECT_FALSE(HasState("noisebridge.net")); 342 EXPECT_FALSE(HasState("foo.noisebridge.net")); 343 344 EXPECT_TRUE(ShouldRedirect("neg9.org")); 345 EXPECT_FALSE(HasState("www.neg9.org")); 346 347 EXPECT_TRUE(ShouldRedirect("riseup.net")); 348 EXPECT_TRUE(ShouldRedirect("foo.riseup.net")); 349 350 EXPECT_TRUE(ShouldRedirect("factor.cc")); 351 EXPECT_FALSE(HasState("www.factor.cc")); 352 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")); 358 359 EXPECT_TRUE(ShouldRedirect("romab.com")); 360 EXPECT_TRUE(ShouldRedirect("www.romab.com")); 361 EXPECT_TRUE(ShouldRedirect("foo.romab.com")); 362 363 EXPECT_TRUE(ShouldRedirect("logentries.com")); 364 EXPECT_TRUE(ShouldRedirect("www.logentries.com")); 365 EXPECT_FALSE(HasState("foo.logentries.com")); 366 367 EXPECT_TRUE(ShouldRedirect("stripe.com")); 368 EXPECT_TRUE(ShouldRedirect("foo.stripe.com")); 369 370 EXPECT_TRUE(ShouldRedirect("cloudsecurityalliance.org")); 371 EXPECT_TRUE(ShouldRedirect("foo.cloudsecurityalliance.org")); 372 373 EXPECT_TRUE(ShouldRedirect("login.sapo.pt")); 374 EXPECT_TRUE(ShouldRedirect("foo.login.sapo.pt")); 375 376 EXPECT_TRUE(ShouldRedirect("mattmccutchen.net")); 377 EXPECT_TRUE(ShouldRedirect("foo.mattmccutchen.net")); 378 379 EXPECT_TRUE(ShouldRedirect("betnet.fr")); 380 EXPECT_TRUE(ShouldRedirect("foo.betnet.fr")); 381 382 EXPECT_TRUE(ShouldRedirect("uprotect.it")); 383 EXPECT_TRUE(ShouldRedirect("foo.uprotect.it")); 384 385 EXPECT_TRUE(ShouldRedirect("squareup.com")); 386 EXPECT_FALSE(HasState("foo.squareup.com")); 387 388 EXPECT_TRUE(ShouldRedirect("cert.se")); 389 EXPECT_TRUE(ShouldRedirect("foo.cert.se")); 390 391 EXPECT_TRUE(ShouldRedirect("crypto.is")); 392 EXPECT_TRUE(ShouldRedirect("foo.crypto.is")); 393 394 EXPECT_TRUE(ShouldRedirect("simon.butcher.name")); 395 EXPECT_TRUE(ShouldRedirect("foo.simon.butcher.name")); 396 397 EXPECT_TRUE(ShouldRedirect("linx.net")); 398 EXPECT_TRUE(ShouldRedirect("foo.linx.net")); 399 400 EXPECT_TRUE(ShouldRedirect("dropcam.com")); 401 EXPECT_TRUE(ShouldRedirect("www.dropcam.com")); 402 EXPECT_FALSE(HasState("foo.dropcam.com")); 403 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, 407 &domain_state)); 408 EXPECT_FALSE(domain_state.static_spki_hashes.empty()); 409 EXPECT_TRUE(state.GetDomainState("check.torproject.org", false, 410 &domain_state)); 411 EXPECT_FALSE(domain_state.static_spki_hashes.empty()); 412 EXPECT_TRUE(state.GetDomainState("blog.torproject.org", false, 413 &domain_state)); 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")); 417 418 EXPECT_TRUE(ShouldRedirect("epoxate.com")); 419 EXPECT_FALSE(HasState("foo.epoxate.com")); 420 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")); 426 427 EXPECT_TRUE(ShouldRedirect("www.moneybookers.com")); 428 EXPECT_FALSE(HasState("moneybookers.com")); 429 430 EXPECT_TRUE(ShouldRedirect("ledgerscope.net")); 431 EXPECT_TRUE(ShouldRedirect("www.ledgerscope.net")); 432 EXPECT_FALSE(HasState("status.ledgerscope.net")); 433 434 EXPECT_TRUE(ShouldRedirect("foo.app.recurly.com")); 435 EXPECT_TRUE(ShouldRedirect("foo.api.recurly.com")); 436 437 EXPECT_TRUE(ShouldRedirect("greplin.com")); 438 EXPECT_TRUE(ShouldRedirect("www.greplin.com")); 439 EXPECT_FALSE(HasState("foo.greplin.com")); 440 441 EXPECT_TRUE(ShouldRedirect("luneta.nearbuysystems.com")); 442 EXPECT_TRUE(ShouldRedirect("foo.luneta.nearbuysystems.com")); 443 444 EXPECT_TRUE(ShouldRedirect("ubertt.org")); 445 EXPECT_TRUE(ShouldRedirect("foo.ubertt.org")); 446 447 EXPECT_TRUE(ShouldRedirect("pixi.me")); 448 EXPECT_TRUE(ShouldRedirect("www.pixi.me")); 449 450 EXPECT_TRUE(ShouldRedirect("grepular.com")); 451 EXPECT_TRUE(ShouldRedirect("www.grepular.com")); 452 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")); 465 466 EXPECT_TRUE(ShouldRedirect("crypto.cat")); 467 EXPECT_FALSE(ShouldRedirect("foo.crypto.cat")); 468 469 EXPECT_TRUE(ShouldRedirect("bigshinylock.minazo.net")); 470 EXPECT_TRUE(ShouldRedirect("foo.bigshinylock.minazo.net")); 471 472 EXPECT_TRUE(ShouldRedirect("crate.io")); 473 EXPECT_TRUE(ShouldRedirect("foo.crate.io")); 474 475 EXPECT_TRUE(HasPublicKeyPins("www.twitter.com")); 476 } 477 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)); 486 } 487 488 TEST_F(TransportSecurityStateTest, BuiltinCertPins) { 489 TransportSecurityState state; 490 TransportSecurityState::DomainState domain_state; 491 492 EXPECT_TRUE(state.GetDomainState("chrome.google.com", true, &domain_state)); 493 EXPECT_TRUE(HasPublicKeyPins("chrome.google.com")); 494 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")); 499 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")); 520 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")); 526 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")); 538 } 539 540 static bool AddHash(const std::string& type_and_base64, 541 HashValueVector* out) { 542 HashValue hash; 543 if (!hash.FromString(type_and_base64)) 544 return false; 545 546 out->push_back(hash); 547 return true; 548 } 549 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=", 556 NULL, 557 }; 558 559 // kBadPath is plus.google.com via Trustcenter, which is utterly wrong for 560 // torproject.org. 561 static const char* kBadPath[] = { 562 "sha1/4BjDjn8v2lWeUFQnqSs0BgbIcrU=", 563 "sha1/gzuEEAB/bkqdQS3EIjk2by7lW+k=", 564 "sha1/SOZo+SvSspXXR9gjIBBPM5iQn9Q=", 565 NULL, 566 }; 567 568 HashValueVector good_hashes, bad_hashes; 569 570 for (size_t i = 0; kGoodPath[i]; i++) { 571 EXPECT_TRUE(AddHash(kGoodPath[i], &good_hashes)); 572 } 573 for (size_t i = 0; kBadPath[i]; i++) { 574 EXPECT_TRUE(AddHash(kBadPath[i], &bad_hashes)); 575 } 576 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()); 581 582 EXPECT_TRUE(domain_state.CheckPublicKeyPins(good_hashes)); 583 EXPECT_FALSE(domain_state.CheckPublicKeyPins(bad_hashes)); 584 } 585 586 TEST_F(TransportSecurityStateTest, OptionalHSTSCertPins) { 587 TransportSecurityState state; 588 TransportSecurityState::DomainState domain_state; 589 590 EXPECT_FALSE(ShouldRedirect("www.google-analytics.com")); 591 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)); 612 } 613 614 TEST_F(TransportSecurityStateTest, OverrideBuiltins) { 615 EXPECT_TRUE(HasPublicKeyPins("google.com")); 616 EXPECT_FALSE(ShouldRedirect("google.com")); 617 EXPECT_FALSE(ShouldRedirect("www.google.com")); 618 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); 625 626 EXPECT_TRUE(state.GetDomainState("www.google.com", true, &domain_state)); 627 } 628 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 643 // works. 644 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty( 645 "learn.doubleclick.net", true)); 646 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)); 665 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)); 675 676 // Test some SNI hosts: 677 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty( 678 "gmail.com", true)); 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)); 690 } 691 692 } // namespace net 693