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   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