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 bool GetStaticDomainState(TransportSecurityState* state, 50 const std::string& host, 51 bool sni_enabled, 52 TransportSecurityState::DomainState* result) { 53 return state->GetStaticDomainState(host, sni_enabled, result); 54 } 55 56 void EnableHost(TransportSecurityState* state, 57 const std::string& host, 58 const TransportSecurityState::DomainState& domain_state) { 59 return state->EnableHost(host, domain_state); 60 } 61 }; 62 63 TEST_F(TransportSecurityStateTest, SimpleMatches) { 64 TransportSecurityState state; 65 TransportSecurityState::DomainState domain_state; 66 const base::Time current_time(base::Time::Now()); 67 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000); 68 69 EXPECT_FALSE(state.GetDynamicDomainState("yahoo.com", &domain_state)); 70 bool include_subdomains = false; 71 state.AddHSTS("yahoo.com", expiry, include_subdomains); 72 EXPECT_TRUE(state.GetDynamicDomainState("yahoo.com", &domain_state)); 73 } 74 75 TEST_F(TransportSecurityStateTest, MatchesCase1) { 76 TransportSecurityState state; 77 TransportSecurityState::DomainState domain_state; 78 const base::Time current_time(base::Time::Now()); 79 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000); 80 81 EXPECT_FALSE(state.GetDynamicDomainState("yahoo.com", &domain_state)); 82 bool include_subdomains = false; 83 state.AddHSTS("YAhoo.coM", expiry, include_subdomains); 84 EXPECT_TRUE(state.GetDynamicDomainState("yahoo.com", &domain_state)); 85 } 86 87 TEST_F(TransportSecurityStateTest, MatchesCase2) { 88 TransportSecurityState state; 89 TransportSecurityState::DomainState domain_state; 90 const base::Time current_time(base::Time::Now()); 91 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000); 92 93 EXPECT_FALSE(state.GetDynamicDomainState("YAhoo.coM", &domain_state)); 94 bool include_subdomains = false; 95 state.AddHSTS("yahoo.com", expiry, include_subdomains); 96 EXPECT_TRUE(state.GetDynamicDomainState("YAhoo.coM", &domain_state)); 97 } 98 99 TEST_F(TransportSecurityStateTest, SubdomainMatches) { 100 TransportSecurityState state; 101 TransportSecurityState::DomainState domain_state; 102 const base::Time current_time(base::Time::Now()); 103 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000); 104 105 EXPECT_FALSE(state.GetDynamicDomainState("yahoo.com", &domain_state)); 106 bool include_subdomains = true; 107 state.AddHSTS("yahoo.com", expiry, include_subdomains); 108 EXPECT_TRUE(state.GetDynamicDomainState("yahoo.com", &domain_state)); 109 EXPECT_TRUE(state.GetDynamicDomainState("foo.yahoo.com", &domain_state)); 110 EXPECT_TRUE(state.GetDynamicDomainState("foo.bar.yahoo.com", &domain_state)); 111 EXPECT_TRUE( 112 state.GetDynamicDomainState("foo.bar.baz.yahoo.com", &domain_state)); 113 EXPECT_FALSE(state.GetDynamicDomainState("com", &domain_state)); 114 } 115 116 TEST_F(TransportSecurityStateTest, InvalidDomains) { 117 TransportSecurityState state; 118 TransportSecurityState::DomainState domain_state; 119 const base::Time current_time(base::Time::Now()); 120 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000); 121 122 EXPECT_FALSE(state.GetDynamicDomainState("yahoo.com", &domain_state)); 123 bool include_subdomains = true; 124 state.AddHSTS("yahoo.com", expiry, include_subdomains); 125 EXPECT_TRUE(state.GetDynamicDomainState("www-.foo.yahoo.com", &domain_state)); 126 EXPECT_TRUE( 127 state.GetDynamicDomainState("2\x01.foo.yahoo.com", &domain_state)); 128 } 129 130 TEST_F(TransportSecurityStateTest, DeleteAllDynamicDataSince) { 131 TransportSecurityState state; 132 TransportSecurityState::DomainState domain_state; 133 const base::Time current_time(base::Time::Now()); 134 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000); 135 const base::Time older = current_time - base::TimeDelta::FromSeconds(1000); 136 137 EXPECT_FALSE(state.GetDynamicDomainState("yahoo.com", &domain_state)); 138 bool include_subdomains = false; 139 state.AddHSTS("yahoo.com", expiry, include_subdomains); 140 141 state.DeleteAllDynamicDataSince(expiry); 142 EXPECT_TRUE(state.GetDynamicDomainState("yahoo.com", &domain_state)); 143 EXPECT_EQ(TransportSecurityState::DomainState::MODE_FORCE_HTTPS, 144 domain_state.sts.upgrade_mode); 145 state.DeleteAllDynamicDataSince(older); 146 EXPECT_TRUE(state.GetDynamicDomainState("yahoo.com", &domain_state)); 147 EXPECT_EQ(TransportSecurityState::DomainState::MODE_DEFAULT, 148 domain_state.sts.upgrade_mode); 149 } 150 151 TEST_F(TransportSecurityStateTest, DeleteDynamicDataForHost) { 152 TransportSecurityState state; 153 TransportSecurityState::DomainState domain_state; 154 const base::Time current_time(base::Time::Now()); 155 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000); 156 bool include_subdomains = false; 157 state.AddHSTS("yahoo.com", expiry, include_subdomains); 158 159 EXPECT_TRUE(state.GetDynamicDomainState("yahoo.com", &domain_state)); 160 EXPECT_FALSE(state.GetDynamicDomainState("example.com", &domain_state)); 161 EXPECT_TRUE(state.DeleteDynamicDataForHost("yahoo.com")); 162 EXPECT_FALSE(state.GetDynamicDomainState("yahoo.com", &domain_state)); 163 } 164 165 TEST_F(TransportSecurityStateTest, IsPreloaded) { 166 const std::string paypal = "paypal.com"; 167 const std::string www_paypal = "www.paypal.com"; 168 const std::string foo_paypal = "foo.paypal.com"; 169 const std::string a_www_paypal = "a.www.paypal.com"; 170 const std::string abc_paypal = "a.b.c.paypal.com"; 171 const std::string example = "example.com"; 172 const std::string aypal = "aypal.com"; 173 174 TransportSecurityState state; 175 TransportSecurityState::DomainState domain_state; 176 177 EXPECT_TRUE(GetStaticDomainState(&state, paypal, true, &domain_state)); 178 EXPECT_TRUE(GetStaticDomainState(&state, www_paypal, true, &domain_state)); 179 EXPECT_FALSE(domain_state.sts.include_subdomains); 180 EXPECT_FALSE(domain_state.pkp.include_subdomains); 181 EXPECT_FALSE(GetStaticDomainState(&state, a_www_paypal, true, &domain_state)); 182 EXPECT_FALSE(GetStaticDomainState(&state, abc_paypal, true, &domain_state)); 183 EXPECT_FALSE(GetStaticDomainState(&state, example, true, &domain_state)); 184 EXPECT_FALSE(GetStaticDomainState(&state, aypal, true, &domain_state)); 185 } 186 187 TEST_F(TransportSecurityStateTest, PreloadedDomainSet) { 188 TransportSecurityState state; 189 TransportSecurityState::DomainState domain_state; 190 191 // The domain wasn't being set, leading to a blank string in the 192 // chrome://net-internals/#hsts UI. So test that. 193 EXPECT_TRUE( 194 state.GetStaticDomainState("market.android.com", true, &domain_state)); 195 EXPECT_EQ(domain_state.domain, "market.android.com"); 196 EXPECT_TRUE(state.GetStaticDomainState( 197 "sub.market.android.com", true, &domain_state)); 198 EXPECT_EQ(domain_state.domain, "market.android.com"); 199 } 200 201 static bool StaticShouldRedirect(const char* hostname) { 202 TransportSecurityState state; 203 TransportSecurityState::DomainState domain_state; 204 return state.GetStaticDomainState( 205 hostname, true /* SNI ok */, &domain_state) && 206 domain_state.ShouldUpgradeToSSL(); 207 } 208 209 static bool HasStaticState(const char* hostname) { 210 TransportSecurityState state; 211 TransportSecurityState::DomainState domain_state; 212 return state.GetStaticDomainState(hostname, true /* SNI ok */, &domain_state); 213 } 214 215 static bool HasStaticPublicKeyPins(const char* hostname, bool sni_enabled) { 216 TransportSecurityState state; 217 TransportSecurityState::DomainState domain_state; 218 if (!state.GetStaticDomainState(hostname, sni_enabled, &domain_state)) 219 return false; 220 221 return domain_state.HasPublicKeyPins(); 222 } 223 224 static bool HasStaticPublicKeyPins(const char* hostname) { 225 return HasStaticPublicKeyPins(hostname, true); 226 } 227 228 static bool OnlyPinningInStaticState(const char* hostname) { 229 TransportSecurityState state; 230 TransportSecurityState::DomainState domain_state; 231 if (!state.GetStaticDomainState(hostname, true /* SNI ok */, &domain_state)) 232 return false; 233 234 return (domain_state.pkp.spki_hashes.size() > 0 || 235 domain_state.pkp.bad_spki_hashes.size() > 0) && 236 !domain_state.ShouldUpgradeToSSL(); 237 } 238 239 TEST_F(TransportSecurityStateTest, Preloaded) { 240 TransportSecurityState state; 241 TransportSecurityState::DomainState domain_state; 242 243 // We do more extensive checks for the first domain. 244 EXPECT_TRUE( 245 state.GetStaticDomainState("www.paypal.com", true, &domain_state)); 246 EXPECT_EQ(domain_state.sts.upgrade_mode, 247 TransportSecurityState::DomainState::MODE_FORCE_HTTPS); 248 EXPECT_FALSE(domain_state.sts.include_subdomains); 249 EXPECT_FALSE(domain_state.pkp.include_subdomains); 250 251 EXPECT_TRUE(HasStaticState("paypal.com")); 252 EXPECT_FALSE(HasStaticState("www2.paypal.com")); 253 EXPECT_FALSE(HasStaticState("www2.paypal.com")); 254 255 // Google hosts: 256 257 EXPECT_TRUE(StaticShouldRedirect("chrome.google.com")); 258 EXPECT_TRUE(StaticShouldRedirect("checkout.google.com")); 259 EXPECT_TRUE(StaticShouldRedirect("wallet.google.com")); 260 EXPECT_TRUE(StaticShouldRedirect("docs.google.com")); 261 EXPECT_TRUE(StaticShouldRedirect("sites.google.com")); 262 EXPECT_TRUE(StaticShouldRedirect("drive.google.com")); 263 EXPECT_TRUE(StaticShouldRedirect("spreadsheets.google.com")); 264 EXPECT_TRUE(StaticShouldRedirect("appengine.google.com")); 265 EXPECT_TRUE(StaticShouldRedirect("market.android.com")); 266 EXPECT_TRUE(StaticShouldRedirect("encrypted.google.com")); 267 EXPECT_TRUE(StaticShouldRedirect("accounts.google.com")); 268 EXPECT_TRUE(StaticShouldRedirect("profiles.google.com")); 269 EXPECT_TRUE(StaticShouldRedirect("mail.google.com")); 270 EXPECT_TRUE(StaticShouldRedirect("chatenabled.mail.google.com")); 271 EXPECT_TRUE(StaticShouldRedirect("talkgadget.google.com")); 272 EXPECT_TRUE(StaticShouldRedirect("hostedtalkgadget.google.com")); 273 EXPECT_TRUE(StaticShouldRedirect("talk.google.com")); 274 EXPECT_TRUE(StaticShouldRedirect("plus.google.com")); 275 EXPECT_TRUE(StaticShouldRedirect("groups.google.com")); 276 EXPECT_TRUE(StaticShouldRedirect("apis.google.com")); 277 EXPECT_FALSE(StaticShouldRedirect("chart.apis.google.com")); 278 EXPECT_TRUE(StaticShouldRedirect("ssl.google-analytics.com")); 279 EXPECT_TRUE(StaticShouldRedirect("gmail.com")); 280 EXPECT_TRUE(StaticShouldRedirect("www.gmail.com")); 281 EXPECT_TRUE(StaticShouldRedirect("googlemail.com")); 282 EXPECT_TRUE(StaticShouldRedirect("www.googlemail.com")); 283 EXPECT_TRUE(StaticShouldRedirect("googleplex.com")); 284 EXPECT_TRUE(StaticShouldRedirect("www.googleplex.com")); 285 EXPECT_FALSE(HasStaticState("m.gmail.com")); 286 EXPECT_FALSE(HasStaticState("m.googlemail.com")); 287 288 EXPECT_TRUE(OnlyPinningInStaticState("www.google.com")); 289 EXPECT_TRUE(OnlyPinningInStaticState("foo.google.com")); 290 EXPECT_TRUE(OnlyPinningInStaticState("google.com")); 291 EXPECT_TRUE(OnlyPinningInStaticState("www.youtube.com")); 292 EXPECT_TRUE(OnlyPinningInStaticState("youtube.com")); 293 EXPECT_TRUE(OnlyPinningInStaticState("i.ytimg.com")); 294 EXPECT_TRUE(OnlyPinningInStaticState("ytimg.com")); 295 EXPECT_TRUE(OnlyPinningInStaticState("googleusercontent.com")); 296 EXPECT_TRUE(OnlyPinningInStaticState("www.googleusercontent.com")); 297 EXPECT_TRUE(OnlyPinningInStaticState("www.google-analytics.com")); 298 EXPECT_TRUE(OnlyPinningInStaticState("googleapis.com")); 299 EXPECT_TRUE(OnlyPinningInStaticState("googleadservices.com")); 300 EXPECT_TRUE(OnlyPinningInStaticState("googlecode.com")); 301 EXPECT_TRUE(OnlyPinningInStaticState("appspot.com")); 302 EXPECT_TRUE(OnlyPinningInStaticState("googlesyndication.com")); 303 EXPECT_TRUE(OnlyPinningInStaticState("doubleclick.net")); 304 EXPECT_TRUE(OnlyPinningInStaticState("googlegroups.com")); 305 306 // Tests for domains that don't work without SNI. 307 EXPECT_FALSE(state.GetStaticDomainState("gmail.com", false, &domain_state)); 308 EXPECT_FALSE( 309 state.GetStaticDomainState("www.gmail.com", false, &domain_state)); 310 EXPECT_FALSE(state.GetStaticDomainState("m.gmail.com", false, &domain_state)); 311 EXPECT_FALSE( 312 state.GetStaticDomainState("googlemail.com", false, &domain_state)); 313 EXPECT_FALSE( 314 state.GetStaticDomainState("www.googlemail.com", false, &domain_state)); 315 EXPECT_FALSE( 316 state.GetStaticDomainState("m.googlemail.com", false, &domain_state)); 317 318 // Other hosts: 319 320 EXPECT_TRUE(StaticShouldRedirect("aladdinschools.appspot.com")); 321 322 EXPECT_TRUE(StaticShouldRedirect("ottospora.nl")); 323 EXPECT_TRUE(StaticShouldRedirect("www.ottospora.nl")); 324 325 EXPECT_TRUE(StaticShouldRedirect("www.paycheckrecords.com")); 326 327 EXPECT_TRUE(StaticShouldRedirect("lastpass.com")); 328 EXPECT_TRUE(StaticShouldRedirect("www.lastpass.com")); 329 EXPECT_FALSE(HasStaticState("blog.lastpass.com")); 330 331 EXPECT_TRUE(StaticShouldRedirect("keyerror.com")); 332 EXPECT_TRUE(StaticShouldRedirect("www.keyerror.com")); 333 334 EXPECT_TRUE(StaticShouldRedirect("entropia.de")); 335 EXPECT_TRUE(StaticShouldRedirect("www.entropia.de")); 336 EXPECT_FALSE(HasStaticState("foo.entropia.de")); 337 338 EXPECT_TRUE(StaticShouldRedirect("www.elanex.biz")); 339 EXPECT_FALSE(HasStaticState("elanex.biz")); 340 EXPECT_FALSE(HasStaticState("foo.elanex.biz")); 341 342 EXPECT_TRUE(StaticShouldRedirect("sunshinepress.org")); 343 EXPECT_TRUE(StaticShouldRedirect("www.sunshinepress.org")); 344 EXPECT_TRUE(StaticShouldRedirect("a.b.sunshinepress.org")); 345 346 EXPECT_TRUE(StaticShouldRedirect("www.noisebridge.net")); 347 EXPECT_FALSE(HasStaticState("noisebridge.net")); 348 EXPECT_FALSE(HasStaticState("foo.noisebridge.net")); 349 350 EXPECT_TRUE(StaticShouldRedirect("neg9.org")); 351 EXPECT_FALSE(HasStaticState("www.neg9.org")); 352 353 EXPECT_TRUE(StaticShouldRedirect("riseup.net")); 354 EXPECT_TRUE(StaticShouldRedirect("foo.riseup.net")); 355 356 EXPECT_TRUE(StaticShouldRedirect("factor.cc")); 357 EXPECT_FALSE(HasStaticState("www.factor.cc")); 358 359 EXPECT_TRUE(StaticShouldRedirect("members.mayfirst.org")); 360 EXPECT_TRUE(StaticShouldRedirect("support.mayfirst.org")); 361 EXPECT_TRUE(StaticShouldRedirect("id.mayfirst.org")); 362 EXPECT_TRUE(StaticShouldRedirect("lists.mayfirst.org")); 363 EXPECT_FALSE(HasStaticState("www.mayfirst.org")); 364 365 EXPECT_TRUE(StaticShouldRedirect("romab.com")); 366 EXPECT_TRUE(StaticShouldRedirect("www.romab.com")); 367 EXPECT_TRUE(StaticShouldRedirect("foo.romab.com")); 368 369 EXPECT_TRUE(StaticShouldRedirect("logentries.com")); 370 EXPECT_TRUE(StaticShouldRedirect("www.logentries.com")); 371 EXPECT_FALSE(HasStaticState("foo.logentries.com")); 372 373 EXPECT_TRUE(StaticShouldRedirect("stripe.com")); 374 EXPECT_TRUE(StaticShouldRedirect("foo.stripe.com")); 375 376 EXPECT_TRUE(StaticShouldRedirect("cloudsecurityalliance.org")); 377 EXPECT_TRUE(StaticShouldRedirect("foo.cloudsecurityalliance.org")); 378 379 EXPECT_TRUE(StaticShouldRedirect("login.sapo.pt")); 380 EXPECT_TRUE(StaticShouldRedirect("foo.login.sapo.pt")); 381 382 EXPECT_TRUE(StaticShouldRedirect("mattmccutchen.net")); 383 EXPECT_TRUE(StaticShouldRedirect("foo.mattmccutchen.net")); 384 385 EXPECT_TRUE(StaticShouldRedirect("betnet.fr")); 386 EXPECT_TRUE(StaticShouldRedirect("foo.betnet.fr")); 387 388 EXPECT_TRUE(StaticShouldRedirect("uprotect.it")); 389 EXPECT_TRUE(StaticShouldRedirect("foo.uprotect.it")); 390 391 EXPECT_TRUE(StaticShouldRedirect("squareup.com")); 392 EXPECT_FALSE(HasStaticState("foo.squareup.com")); 393 394 EXPECT_TRUE(StaticShouldRedirect("cert.se")); 395 EXPECT_TRUE(StaticShouldRedirect("foo.cert.se")); 396 397 EXPECT_TRUE(StaticShouldRedirect("crypto.is")); 398 EXPECT_TRUE(StaticShouldRedirect("foo.crypto.is")); 399 400 EXPECT_TRUE(StaticShouldRedirect("simon.butcher.name")); 401 EXPECT_TRUE(StaticShouldRedirect("foo.simon.butcher.name")); 402 403 EXPECT_TRUE(StaticShouldRedirect("linx.net")); 404 EXPECT_TRUE(StaticShouldRedirect("foo.linx.net")); 405 406 EXPECT_TRUE(StaticShouldRedirect("dropcam.com")); 407 EXPECT_TRUE(StaticShouldRedirect("www.dropcam.com")); 408 EXPECT_FALSE(HasStaticState("foo.dropcam.com")); 409 410 EXPECT_TRUE( 411 state.GetStaticDomainState("torproject.org", false, &domain_state)); 412 EXPECT_FALSE(domain_state.pkp.spki_hashes.empty()); 413 EXPECT_TRUE( 414 state.GetStaticDomainState("www.torproject.org", false, &domain_state)); 415 EXPECT_FALSE(domain_state.pkp.spki_hashes.empty()); 416 EXPECT_TRUE( 417 state.GetStaticDomainState("check.torproject.org", false, &domain_state)); 418 EXPECT_FALSE(domain_state.pkp.spki_hashes.empty()); 419 EXPECT_TRUE( 420 state.GetStaticDomainState("blog.torproject.org", false, &domain_state)); 421 EXPECT_FALSE(domain_state.pkp.spki_hashes.empty()); 422 EXPECT_TRUE(StaticShouldRedirect("ebanking.indovinabank.com.vn")); 423 EXPECT_TRUE(StaticShouldRedirect("foo.ebanking.indovinabank.com.vn")); 424 425 EXPECT_TRUE(StaticShouldRedirect("epoxate.com")); 426 EXPECT_FALSE(HasStaticState("foo.epoxate.com")); 427 428 EXPECT_TRUE(HasStaticPublicKeyPins("torproject.org")); 429 EXPECT_TRUE(HasStaticPublicKeyPins("www.torproject.org")); 430 EXPECT_TRUE(HasStaticPublicKeyPins("check.torproject.org")); 431 EXPECT_TRUE(HasStaticPublicKeyPins("blog.torproject.org")); 432 EXPECT_FALSE(HasStaticState("foo.torproject.org")); 433 434 EXPECT_TRUE(StaticShouldRedirect("www.moneybookers.com")); 435 EXPECT_FALSE(HasStaticState("moneybookers.com")); 436 437 EXPECT_TRUE(StaticShouldRedirect("ledgerscope.net")); 438 EXPECT_TRUE(StaticShouldRedirect("www.ledgerscope.net")); 439 EXPECT_FALSE(HasStaticState("status.ledgerscope.net")); 440 441 EXPECT_TRUE(StaticShouldRedirect("foo.app.recurly.com")); 442 EXPECT_TRUE(StaticShouldRedirect("foo.api.recurly.com")); 443 444 EXPECT_TRUE(StaticShouldRedirect("greplin.com")); 445 EXPECT_TRUE(StaticShouldRedirect("www.greplin.com")); 446 EXPECT_FALSE(HasStaticState("foo.greplin.com")); 447 448 EXPECT_TRUE(StaticShouldRedirect("luneta.nearbuysystems.com")); 449 EXPECT_TRUE(StaticShouldRedirect("foo.luneta.nearbuysystems.com")); 450 451 EXPECT_TRUE(StaticShouldRedirect("ubertt.org")); 452 EXPECT_TRUE(StaticShouldRedirect("foo.ubertt.org")); 453 454 EXPECT_TRUE(StaticShouldRedirect("pixi.me")); 455 EXPECT_TRUE(StaticShouldRedirect("www.pixi.me")); 456 457 EXPECT_TRUE(StaticShouldRedirect("grepular.com")); 458 EXPECT_TRUE(StaticShouldRedirect("www.grepular.com")); 459 460 EXPECT_TRUE(StaticShouldRedirect("mydigipass.com")); 461 EXPECT_FALSE(StaticShouldRedirect("foo.mydigipass.com")); 462 EXPECT_TRUE(StaticShouldRedirect("www.mydigipass.com")); 463 EXPECT_FALSE(StaticShouldRedirect("foo.www.mydigipass.com")); 464 EXPECT_TRUE(StaticShouldRedirect("developer.mydigipass.com")); 465 EXPECT_FALSE(StaticShouldRedirect("foo.developer.mydigipass.com")); 466 EXPECT_TRUE(StaticShouldRedirect("www.developer.mydigipass.com")); 467 EXPECT_FALSE(StaticShouldRedirect("foo.www.developer.mydigipass.com")); 468 EXPECT_TRUE(StaticShouldRedirect("sandbox.mydigipass.com")); 469 EXPECT_FALSE(StaticShouldRedirect("foo.sandbox.mydigipass.com")); 470 EXPECT_TRUE(StaticShouldRedirect("www.sandbox.mydigipass.com")); 471 EXPECT_FALSE(StaticShouldRedirect("foo.www.sandbox.mydigipass.com")); 472 473 EXPECT_TRUE(StaticShouldRedirect("crypto.cat")); 474 EXPECT_FALSE(StaticShouldRedirect("foo.crypto.cat")); 475 476 EXPECT_TRUE(StaticShouldRedirect("bigshinylock.minazo.net")); 477 EXPECT_TRUE(StaticShouldRedirect("foo.bigshinylock.minazo.net")); 478 479 EXPECT_TRUE(StaticShouldRedirect("crate.io")); 480 EXPECT_TRUE(StaticShouldRedirect("foo.crate.io")); 481 482 EXPECT_TRUE(HasStaticPublicKeyPins("www.twitter.com")); 483 } 484 485 TEST_F(TransportSecurityStateTest, LongNames) { 486 TransportSecurityState state; 487 const char kLongName[] = 488 "lookupByWaveIdHashAndWaveIdIdAndWaveIdDomainAndWaveletIdIdAnd" 489 "WaveletIdDomainAndBlipBlipid"; 490 TransportSecurityState::DomainState domain_state; 491 // Just checks that we don't hit a NOTREACHED. 492 EXPECT_FALSE(state.GetStaticDomainState(kLongName, true, &domain_state)); 493 EXPECT_FALSE(state.GetDynamicDomainState(kLongName, &domain_state)); 494 } 495 496 TEST_F(TransportSecurityStateTest, BuiltinCertPins) { 497 TransportSecurityState state; 498 TransportSecurityState::DomainState domain_state; 499 500 EXPECT_TRUE( 501 state.GetStaticDomainState("chrome.google.com", true, &domain_state)); 502 EXPECT_TRUE(HasStaticPublicKeyPins("chrome.google.com")); 503 504 HashValueVector hashes; 505 std::string failure_log; 506 // Checks that a built-in list does exist. 507 EXPECT_FALSE(domain_state.CheckPublicKeyPins(hashes, &failure_log)); 508 EXPECT_FALSE(HasStaticPublicKeyPins("www.paypal.com")); 509 510 EXPECT_TRUE(HasStaticPublicKeyPins("docs.google.com")); 511 EXPECT_TRUE(HasStaticPublicKeyPins("1.docs.google.com")); 512 EXPECT_TRUE(HasStaticPublicKeyPins("sites.google.com")); 513 EXPECT_TRUE(HasStaticPublicKeyPins("drive.google.com")); 514 EXPECT_TRUE(HasStaticPublicKeyPins("spreadsheets.google.com")); 515 EXPECT_TRUE(HasStaticPublicKeyPins("wallet.google.com")); 516 EXPECT_TRUE(HasStaticPublicKeyPins("checkout.google.com")); 517 EXPECT_TRUE(HasStaticPublicKeyPins("appengine.google.com")); 518 EXPECT_TRUE(HasStaticPublicKeyPins("market.android.com")); 519 EXPECT_TRUE(HasStaticPublicKeyPins("encrypted.google.com")); 520 EXPECT_TRUE(HasStaticPublicKeyPins("accounts.google.com")); 521 EXPECT_TRUE(HasStaticPublicKeyPins("profiles.google.com")); 522 EXPECT_TRUE(HasStaticPublicKeyPins("mail.google.com")); 523 EXPECT_TRUE(HasStaticPublicKeyPins("chatenabled.mail.google.com")); 524 EXPECT_TRUE(HasStaticPublicKeyPins("talkgadget.google.com")); 525 EXPECT_TRUE(HasStaticPublicKeyPins("hostedtalkgadget.google.com")); 526 EXPECT_TRUE(HasStaticPublicKeyPins("talk.google.com")); 527 EXPECT_TRUE(HasStaticPublicKeyPins("plus.google.com")); 528 EXPECT_TRUE(HasStaticPublicKeyPins("groups.google.com")); 529 EXPECT_TRUE(HasStaticPublicKeyPins("apis.google.com")); 530 531 EXPECT_TRUE(HasStaticPublicKeyPins("ssl.gstatic.com")); 532 EXPECT_TRUE(HasStaticPublicKeyPins("gstatic.com")); 533 EXPECT_TRUE(HasStaticPublicKeyPins("www.gstatic.com")); 534 EXPECT_TRUE(HasStaticPublicKeyPins("ssl.google-analytics.com")); 535 EXPECT_TRUE(HasStaticPublicKeyPins("www.googleplex.com")); 536 537 // Disabled in order to help track down pinning failures --agl 538 EXPECT_TRUE(HasStaticPublicKeyPins("twitter.com")); 539 EXPECT_FALSE(HasStaticPublicKeyPins("foo.twitter.com")); 540 EXPECT_TRUE(HasStaticPublicKeyPins("www.twitter.com")); 541 EXPECT_TRUE(HasStaticPublicKeyPins("api.twitter.com")); 542 EXPECT_TRUE(HasStaticPublicKeyPins("oauth.twitter.com")); 543 EXPECT_TRUE(HasStaticPublicKeyPins("mobile.twitter.com")); 544 EXPECT_TRUE(HasStaticPublicKeyPins("dev.twitter.com")); 545 EXPECT_TRUE(HasStaticPublicKeyPins("business.twitter.com")); 546 EXPECT_TRUE(HasStaticPublicKeyPins("platform.twitter.com")); 547 EXPECT_TRUE(HasStaticPublicKeyPins("si0.twimg.com")); 548 } 549 550 static bool AddHash(const std::string& type_and_base64, 551 HashValueVector* out) { 552 HashValue hash; 553 if (!hash.FromString(type_and_base64)) 554 return false; 555 556 out->push_back(hash); 557 return true; 558 } 559 560 TEST_F(TransportSecurityStateTest, PinValidationWithoutRejectedCerts) { 561 // kGoodPath is blog.torproject.org. 562 static const char* kGoodPath[] = { 563 "sha1/m9lHYJYke9k0GtVZ+bXSQYE8nDI=", 564 "sha1/o5OZxATDsgmwgcIfIWIneMJ0jkw=", 565 "sha1/wHqYaI2J+6sFZAwRfap9ZbjKzE4=", 566 NULL, 567 }; 568 569 // kBadPath is plus.google.com via Trustcenter, which is utterly wrong for 570 // torproject.org. 571 static const char* kBadPath[] = { 572 "sha1/4BjDjn8v2lWeUFQnqSs0BgbIcrU=", 573 "sha1/gzuEEAB/bkqdQS3EIjk2by7lW+k=", 574 "sha1/SOZo+SvSspXXR9gjIBBPM5iQn9Q=", 575 NULL, 576 }; 577 578 HashValueVector good_hashes, bad_hashes; 579 580 for (size_t i = 0; kGoodPath[i]; i++) { 581 EXPECT_TRUE(AddHash(kGoodPath[i], &good_hashes)); 582 } 583 for (size_t i = 0; kBadPath[i]; i++) { 584 EXPECT_TRUE(AddHash(kBadPath[i], &bad_hashes)); 585 } 586 587 TransportSecurityState state; 588 TransportSecurityState::DomainState domain_state; 589 EXPECT_TRUE( 590 state.GetStaticDomainState("blog.torproject.org", true, &domain_state)); 591 EXPECT_TRUE(domain_state.HasPublicKeyPins()); 592 593 std::string failure_log; 594 EXPECT_TRUE(domain_state.CheckPublicKeyPins(good_hashes, &failure_log)); 595 EXPECT_FALSE(domain_state.CheckPublicKeyPins(bad_hashes, &failure_log)); 596 } 597 598 TEST_F(TransportSecurityStateTest, OptionalHSTSCertPins) { 599 TransportSecurityState state; 600 TransportSecurityState::DomainState domain_state; 601 602 EXPECT_FALSE(StaticShouldRedirect("www.google-analytics.com")); 603 604 EXPECT_FALSE(HasStaticPublicKeyPins("www.google-analytics.com", false)); 605 EXPECT_TRUE(HasStaticPublicKeyPins("www.google-analytics.com")); 606 EXPECT_TRUE(HasStaticPublicKeyPins("google.com")); 607 EXPECT_TRUE(HasStaticPublicKeyPins("www.google.com")); 608 EXPECT_TRUE(HasStaticPublicKeyPins("mail-attachment.googleusercontent.com")); 609 EXPECT_TRUE(HasStaticPublicKeyPins("www.youtube.com")); 610 EXPECT_TRUE(HasStaticPublicKeyPins("i.ytimg.com")); 611 EXPECT_TRUE(HasStaticPublicKeyPins("googleapis.com")); 612 EXPECT_TRUE(HasStaticPublicKeyPins("ajax.googleapis.com")); 613 EXPECT_TRUE(HasStaticPublicKeyPins("googleadservices.com")); 614 EXPECT_TRUE(HasStaticPublicKeyPins("pagead2.googleadservices.com")); 615 EXPECT_TRUE(HasStaticPublicKeyPins("googlecode.com")); 616 EXPECT_TRUE(HasStaticPublicKeyPins("kibbles.googlecode.com")); 617 EXPECT_TRUE(HasStaticPublicKeyPins("appspot.com")); 618 EXPECT_TRUE(HasStaticPublicKeyPins("googlesyndication.com")); 619 EXPECT_TRUE(HasStaticPublicKeyPins("doubleclick.net")); 620 EXPECT_TRUE(HasStaticPublicKeyPins("ad.doubleclick.net")); 621 EXPECT_FALSE(HasStaticPublicKeyPins("learn.doubleclick.net")); 622 EXPECT_TRUE(HasStaticPublicKeyPins("a.googlegroups.com")); 623 EXPECT_FALSE(HasStaticPublicKeyPins("a.googlegroups.com", false)); 624 } 625 626 TEST_F(TransportSecurityStateTest, OverrideBuiltins) { 627 EXPECT_TRUE(HasStaticPublicKeyPins("google.com")); 628 EXPECT_FALSE(StaticShouldRedirect("google.com")); 629 EXPECT_FALSE(StaticShouldRedirect("www.google.com")); 630 631 TransportSecurityState state; 632 TransportSecurityState::DomainState domain_state; 633 const base::Time current_time(base::Time::Now()); 634 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000); 635 domain_state.sts.expiry = expiry; 636 EnableHost(&state, "www.google.com", domain_state); 637 638 EXPECT_TRUE(state.GetDynamicDomainState("www.google.com", &domain_state)); 639 } 640 641 TEST_F(TransportSecurityStateTest, GooglePinnedProperties) { 642 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty( 643 "www.example.com", true)); 644 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty( 645 "www.paypal.com", true)); 646 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty( 647 "mail.twitter.com", true)); 648 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty( 649 "www.google.com.int", true)); 650 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty( 651 "jottit.com", true)); 652 // learn.doubleclick.net has a more specific match than 653 // *.doubleclick.com, and has 0 or NULL for its required certs. 654 // This test ensures that the exact-match-preferred behavior 655 // works. 656 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty( 657 "learn.doubleclick.net", true)); 658 659 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty( 660 "encrypted.google.com", true)); 661 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty( 662 "mail.google.com", true)); 663 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty( 664 "accounts.google.com", true)); 665 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty( 666 "doubleclick.net", true)); 667 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty( 668 "ad.doubleclick.net", true)); 669 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty( 670 "youtube.com", true)); 671 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty( 672 "www.profiles.google.com", true)); 673 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty( 674 "checkout.google.com", true)); 675 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty( 676 "googleadservices.com", true)); 677 678 // Test with sni_enabled false: 679 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty( 680 "www.example.com", false)); 681 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty( 682 "www.paypal.com", false)); 683 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty( 684 "checkout.google.com", false)); 685 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty( 686 "googleadservices.com", false)); 687 688 // Test some SNI hosts: 689 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty( 690 "gmail.com", true)); 691 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty( 692 "googlegroups.com", true)); 693 EXPECT_TRUE(TransportSecurityState::IsGooglePinnedProperty( 694 "www.googlegroups.com", true)); 695 // Expect to fail for SNI hosts when not searching the SNI list: 696 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty( 697 "gmail.com", false)); 698 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty( 699 "googlegroups.com", false)); 700 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty( 701 "www.googlegroups.com", false)); 702 } 703 704 } // namespace net 705