Home | History | Annotate | Download | only in http
      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