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 <algorithm>
      6 
      7 #include "base/base64.h"
      8 #include "base/sha1.h"
      9 #include "base/strings/string_piece.h"
     10 #include "crypto/sha2.h"
     11 #include "net/base/net_log.h"
     12 #include "net/base/test_completion_callback.h"
     13 #include "net/http/http_security_headers.h"
     14 #include "net/http/http_util.h"
     15 #include "net/http/transport_security_state.h"
     16 #include "net/ssl/ssl_info.h"
     17 #include "testing/gtest/include/gtest/gtest.h"
     18 
     19 namespace net {
     20 
     21 namespace {
     22 
     23 HashValue GetTestHashValue(uint8 label, HashValueTag tag) {
     24   HashValue hash_value(tag);
     25   memset(hash_value.data(), label, hash_value.size());
     26   return hash_value;
     27 }
     28 
     29 std::string GetTestPin(uint8 label, HashValueTag tag) {
     30   HashValue hash_value = GetTestHashValue(label, tag);
     31   std::string base64;
     32   base::Base64Encode(base::StringPiece(
     33       reinterpret_cast<char*>(hash_value.data()), hash_value.size()), &base64);
     34 
     35   switch (hash_value.tag) {
     36     case HASH_VALUE_SHA1:
     37       return std::string("pin-sha1=\"") + base64 + "\"";
     38     case HASH_VALUE_SHA256:
     39       return std::string("pin-sha256=\"") + base64 + "\"";
     40     default:
     41       NOTREACHED() << "Unknown HashValueTag " << hash_value.tag;
     42       return std::string("ERROR");
     43   }
     44 }
     45 
     46 };
     47 
     48 
     49 class HttpSecurityHeadersTest : public testing::Test {
     50 };
     51 
     52 
     53 TEST_F(HttpSecurityHeadersTest, BogusHeaders) {
     54   base::TimeDelta max_age;
     55   bool include_subdomains = false;
     56 
     57   EXPECT_FALSE(
     58       ParseHSTSHeader(std::string(), &max_age, &include_subdomains));
     59   EXPECT_FALSE(ParseHSTSHeader("    ", &max_age, &include_subdomains));
     60   EXPECT_FALSE(ParseHSTSHeader("abc", &max_age, &include_subdomains));
     61   EXPECT_FALSE(ParseHSTSHeader("  abc", &max_age, &include_subdomains));
     62   EXPECT_FALSE(ParseHSTSHeader("  abc   ", &max_age, &include_subdomains));
     63   EXPECT_FALSE(ParseHSTSHeader("max-age", &max_age, &include_subdomains));
     64   EXPECT_FALSE(ParseHSTSHeader("  max-age", &max_age,
     65                                &include_subdomains));
     66   EXPECT_FALSE(ParseHSTSHeader("  max-age  ", &max_age,
     67                                &include_subdomains));
     68   EXPECT_FALSE(ParseHSTSHeader("max-age=", &max_age, &include_subdomains));
     69   EXPECT_FALSE(ParseHSTSHeader("   max-age=", &max_age,
     70                                &include_subdomains));
     71   EXPECT_FALSE(ParseHSTSHeader("   max-age  =", &max_age,
     72                                &include_subdomains));
     73   EXPECT_FALSE(ParseHSTSHeader("   max-age=   ", &max_age,
     74                                &include_subdomains));
     75   EXPECT_FALSE(ParseHSTSHeader("   max-age  =     ", &max_age,
     76                                &include_subdomains));
     77   EXPECT_FALSE(ParseHSTSHeader("   max-age  =     xy", &max_age,
     78                                &include_subdomains));
     79   EXPECT_FALSE(ParseHSTSHeader("   max-age  =     3488a923", &max_age,
     80                                &include_subdomains));
     81   EXPECT_FALSE(ParseHSTSHeader("max-age=3488a923  ", &max_age,
     82                                &include_subdomains));
     83   EXPECT_FALSE(ParseHSTSHeader("max-ag=3488923", &max_age,
     84                                &include_subdomains));
     85   EXPECT_FALSE(ParseHSTSHeader("max-aged=3488923", &max_age,
     86                                &include_subdomains));
     87   EXPECT_FALSE(ParseHSTSHeader("max-age==3488923", &max_age,
     88                                &include_subdomains));
     89   EXPECT_FALSE(ParseHSTSHeader("amax-age=3488923", &max_age,
     90                                &include_subdomains));
     91   EXPECT_FALSE(ParseHSTSHeader("max-age=-3488923", &max_age,
     92                                &include_subdomains));
     93   EXPECT_FALSE(ParseHSTSHeader("max-age=3488923;", &max_age,
     94                                &include_subdomains));
     95   EXPECT_FALSE(ParseHSTSHeader("max-age=3488923     e", &max_age,
     96                                &include_subdomains));
     97   EXPECT_FALSE(ParseHSTSHeader("max-age=3488923     includesubdomain",
     98                                &max_age, &include_subdomains));
     99   EXPECT_FALSE(ParseHSTSHeader("max-age=3488923includesubdomains",
    100                                &max_age, &include_subdomains));
    101   EXPECT_FALSE(ParseHSTSHeader("max-age=3488923=includesubdomains",
    102                                &max_age, &include_subdomains));
    103   EXPECT_FALSE(ParseHSTSHeader("max-age=3488923 includesubdomainx",
    104                                &max_age, &include_subdomains));
    105   EXPECT_FALSE(ParseHSTSHeader("max-age=3488923 includesubdomain=",
    106                                &max_age, &include_subdomains));
    107   EXPECT_FALSE(ParseHSTSHeader("max-age=3488923 includesubdomain=true",
    108                                &max_age, &include_subdomains));
    109   EXPECT_FALSE(ParseHSTSHeader("max-age=3488923 includesubdomainsx",
    110                                &max_age, &include_subdomains));
    111   EXPECT_FALSE(ParseHSTSHeader("max-age=3488923 includesubdomains x",
    112                                &max_age, &include_subdomains));
    113   EXPECT_FALSE(ParseHSTSHeader("max-age=34889.23 includesubdomains",
    114                                &max_age, &include_subdomains));
    115   EXPECT_FALSE(ParseHSTSHeader("max-age=34889 includesubdomains",
    116                                &max_age, &include_subdomains));
    117 
    118   // Check the out args were not updated by checking the default
    119   // values for its predictable fields.
    120   EXPECT_EQ(0, max_age.InSeconds());
    121   EXPECT_FALSE(include_subdomains);
    122 }
    123 
    124 static void TestBogusPinsHeaders(HashValueTag tag) {
    125   base::TimeDelta max_age;
    126   bool include_subdomains;
    127   HashValueVector hashes;
    128   HashValueVector chain_hashes;
    129 
    130   // Set some fake "chain" hashes
    131   chain_hashes.push_back(GetTestHashValue(1, tag));
    132   chain_hashes.push_back(GetTestHashValue(2, tag));
    133   chain_hashes.push_back(GetTestHashValue(3, tag));
    134 
    135   // The good pin must be in the chain, the backup pin must not be
    136   std::string good_pin = GetTestPin(2, tag);
    137   std::string backup_pin = GetTestPin(4, tag);
    138 
    139   EXPECT_FALSE(ParseHPKPHeader(std::string(), chain_hashes, &max_age,
    140                                &include_subdomains, &hashes));
    141   EXPECT_FALSE(ParseHPKPHeader("    ", chain_hashes, &max_age,
    142                                &include_subdomains, &hashes));
    143   EXPECT_FALSE(ParseHPKPHeader("abc", chain_hashes, &max_age,
    144                                &include_subdomains, &hashes));
    145   EXPECT_FALSE(ParseHPKPHeader("  abc", chain_hashes, &max_age,
    146                                &include_subdomains, &hashes));
    147   EXPECT_FALSE(ParseHPKPHeader("  abc   ", chain_hashes, &max_age,
    148                                &include_subdomains, &hashes));
    149   EXPECT_FALSE(ParseHPKPHeader("max-age", chain_hashes, &max_age,
    150                                &include_subdomains, &hashes));
    151   EXPECT_FALSE(ParseHPKPHeader("  max-age", chain_hashes, &max_age,
    152                                &include_subdomains, &hashes));
    153   EXPECT_FALSE(ParseHPKPHeader("  max-age  ", chain_hashes, &max_age,
    154                                &include_subdomains, &hashes));
    155   EXPECT_FALSE(ParseHPKPHeader("max-age=", chain_hashes, &max_age,
    156                                &include_subdomains, &hashes));
    157   EXPECT_FALSE(ParseHPKPHeader("   max-age=", chain_hashes, &max_age,
    158                                &include_subdomains, &hashes));
    159   EXPECT_FALSE(ParseHPKPHeader("   max-age  =", chain_hashes, &max_age,
    160                                &include_subdomains, &hashes));
    161   EXPECT_FALSE(ParseHPKPHeader("   max-age=   ", chain_hashes, &max_age,
    162                                &include_subdomains, &hashes));
    163   EXPECT_FALSE(ParseHPKPHeader("   max-age  =     ", chain_hashes,
    164                                &max_age, &include_subdomains, &hashes));
    165   EXPECT_FALSE(ParseHPKPHeader("   max-age  =     xy", chain_hashes,
    166                                &max_age, &include_subdomains, &hashes));
    167   EXPECT_FALSE(ParseHPKPHeader("   max-age  =     3488a923",
    168                                chain_hashes, &max_age, &include_subdomains,
    169                                &hashes));
    170   EXPECT_FALSE(ParseHPKPHeader("max-age=3488a923  ", chain_hashes,
    171                                &max_age, &include_subdomains, &hashes));
    172   EXPECT_FALSE(ParseHPKPHeader("max-ag=3488923pins=" + good_pin + "," +
    173                                backup_pin,
    174                                chain_hashes, &max_age, &include_subdomains,
    175                                &hashes));
    176   EXPECT_FALSE(ParseHPKPHeader("max-aged=3488923" + backup_pin,
    177                                chain_hashes, &max_age, &include_subdomains,
    178                                &hashes));
    179   EXPECT_FALSE(ParseHPKPHeader("max-aged=3488923; " + backup_pin,
    180                                chain_hashes, &max_age, &include_subdomains,
    181                                &hashes));
    182   EXPECT_FALSE(ParseHPKPHeader("max-aged=3488923; " + backup_pin + ";" +
    183                                backup_pin,
    184                                chain_hashes, &max_age, &include_subdomains,
    185                                &hashes));
    186   EXPECT_FALSE(ParseHPKPHeader("max-aged=3488923; " + good_pin + ";" +
    187                                good_pin,
    188                                chain_hashes, &max_age, &include_subdomains,
    189                                &hashes));
    190   EXPECT_FALSE(ParseHPKPHeader("max-aged=3488923; " + good_pin,
    191                                chain_hashes, &max_age, &include_subdomains,
    192                                &hashes));
    193   EXPECT_FALSE(ParseHPKPHeader("max-age==3488923", chain_hashes, &max_age,
    194                                &include_subdomains, &hashes));
    195   EXPECT_FALSE(ParseHPKPHeader("amax-age=3488923", chain_hashes, &max_age,
    196                                &include_subdomains, &hashes));
    197   EXPECT_FALSE(ParseHPKPHeader("max-age=-3488923", chain_hashes, &max_age,
    198                                &include_subdomains, &hashes));
    199   EXPECT_FALSE(ParseHPKPHeader("max-age=3488923;", chain_hashes, &max_age,
    200                                &include_subdomains, &hashes));
    201   EXPECT_FALSE(ParseHPKPHeader("max-age=3488923     e", chain_hashes,
    202                                &max_age, &include_subdomains, &hashes));
    203   EXPECT_FALSE(ParseHPKPHeader("max-age=3488923     includesubdomain",
    204                                chain_hashes, &max_age, &include_subdomains,
    205                                &hashes));
    206   EXPECT_FALSE(ParseHPKPHeader("max-age=34889.23", chain_hashes, &max_age,
    207                                &include_subdomains, &hashes));
    208 
    209   // Check the out args were not updated by checking the default
    210   // values for its predictable fields.
    211   EXPECT_EQ(0, max_age.InSeconds());
    212   EXPECT_EQ(hashes.size(), (size_t)0);
    213 }
    214 
    215 TEST_F(HttpSecurityHeadersTest, ValidSTSHeaders) {
    216   base::TimeDelta max_age;
    217   base::TimeDelta expect_max_age;
    218   bool include_subdomains = false;
    219 
    220   EXPECT_TRUE(ParseHSTSHeader("max-age=243", &max_age,
    221                               &include_subdomains));
    222   expect_max_age = base::TimeDelta::FromSeconds(243);
    223   EXPECT_EQ(expect_max_age, max_age);
    224   EXPECT_FALSE(include_subdomains);
    225 
    226   EXPECT_TRUE(ParseHSTSHeader("  Max-agE    = 567", &max_age,
    227                               &include_subdomains));
    228   expect_max_age = base::TimeDelta::FromSeconds(567);
    229   EXPECT_EQ(expect_max_age, max_age);
    230   EXPECT_FALSE(include_subdomains);
    231 
    232   EXPECT_TRUE(ParseHSTSHeader("  mAx-aGe    = 890      ", &max_age,
    233                               &include_subdomains));
    234   expect_max_age = base::TimeDelta::FromSeconds(890);
    235   EXPECT_EQ(expect_max_age, max_age);
    236   EXPECT_FALSE(include_subdomains);
    237 
    238   EXPECT_TRUE(ParseHSTSHeader("max-age=123;incLudesUbdOmains", &max_age,
    239                               &include_subdomains));
    240   expect_max_age = base::TimeDelta::FromSeconds(123);
    241   EXPECT_EQ(expect_max_age, max_age);
    242   EXPECT_TRUE(include_subdomains);
    243 
    244   EXPECT_TRUE(ParseHSTSHeader("incLudesUbdOmains; max-age=123", &max_age,
    245                               &include_subdomains));
    246   expect_max_age = base::TimeDelta::FromSeconds(123);
    247   EXPECT_EQ(expect_max_age, max_age);
    248   EXPECT_TRUE(include_subdomains);
    249 
    250   EXPECT_TRUE(ParseHSTSHeader("   incLudesUbdOmains; max-age=123",
    251                               &max_age, &include_subdomains));
    252   expect_max_age = base::TimeDelta::FromSeconds(123);
    253   EXPECT_EQ(expect_max_age, max_age);
    254   EXPECT_TRUE(include_subdomains);
    255 
    256   EXPECT_TRUE(ParseHSTSHeader(
    257       "   incLudesUbdOmains; max-age=123; pumpkin=kitten", &max_age,
    258                                    &include_subdomains));
    259   expect_max_age = base::TimeDelta::FromSeconds(123);
    260   EXPECT_EQ(expect_max_age, max_age);
    261   EXPECT_TRUE(include_subdomains);
    262 
    263   EXPECT_TRUE(ParseHSTSHeader(
    264       "   pumpkin=894; incLudesUbdOmains; max-age=123  ", &max_age,
    265                                    &include_subdomains));
    266   expect_max_age = base::TimeDelta::FromSeconds(123);
    267   EXPECT_EQ(expect_max_age, max_age);
    268   EXPECT_TRUE(include_subdomains);
    269 
    270   EXPECT_TRUE(ParseHSTSHeader(
    271       "   pumpkin; incLudesUbdOmains; max-age=123  ", &max_age,
    272                                    &include_subdomains));
    273   expect_max_age = base::TimeDelta::FromSeconds(123);
    274   EXPECT_EQ(expect_max_age, max_age);
    275   EXPECT_TRUE(include_subdomains);
    276 
    277   EXPECT_TRUE(ParseHSTSHeader(
    278       "   pumpkin; incLudesUbdOmains; max-age=\"123\"  ", &max_age,
    279                                    &include_subdomains));
    280   expect_max_age = base::TimeDelta::FromSeconds(123);
    281   EXPECT_EQ(expect_max_age, max_age);
    282   EXPECT_TRUE(include_subdomains);
    283 
    284   EXPECT_TRUE(ParseHSTSHeader(
    285       "animal=\"squirrel; distinguished\"; incLudesUbdOmains; max-age=123",
    286                                    &max_age, &include_subdomains));
    287   expect_max_age = base::TimeDelta::FromSeconds(123);
    288   EXPECT_EQ(expect_max_age, max_age);
    289   EXPECT_TRUE(include_subdomains);
    290 
    291   EXPECT_TRUE(ParseHSTSHeader("max-age=394082;  incLudesUbdOmains",
    292                               &max_age, &include_subdomains));
    293   expect_max_age = base::TimeDelta::FromSeconds(394082);
    294   EXPECT_EQ(expect_max_age, max_age);
    295   EXPECT_TRUE(include_subdomains);
    296 
    297   EXPECT_TRUE(ParseHSTSHeader(
    298       "max-age=39408299  ;incLudesUbdOmains", &max_age,
    299       &include_subdomains));
    300   expect_max_age = base::TimeDelta::FromSeconds(
    301       std::min(kMaxHSTSAgeSecs, static_cast<int64>(GG_INT64_C(39408299))));
    302   EXPECT_EQ(expect_max_age, max_age);
    303   EXPECT_TRUE(include_subdomains);
    304 
    305   EXPECT_TRUE(ParseHSTSHeader(
    306       "max-age=394082038  ; incLudesUbdOmains", &max_age,
    307       &include_subdomains));
    308   expect_max_age = base::TimeDelta::FromSeconds(
    309       std::min(kMaxHSTSAgeSecs, static_cast<int64>(GG_INT64_C(394082038))));
    310   EXPECT_EQ(expect_max_age, max_age);
    311   EXPECT_TRUE(include_subdomains);
    312 
    313   EXPECT_TRUE(ParseHSTSHeader(
    314       "  max-age=0  ;  incLudesUbdOmains   ", &max_age,
    315       &include_subdomains));
    316   expect_max_age = base::TimeDelta::FromSeconds(0);
    317   EXPECT_EQ(expect_max_age, max_age);
    318   EXPECT_TRUE(include_subdomains);
    319 
    320   EXPECT_TRUE(ParseHSTSHeader(
    321       "  max-age=999999999999999999999999999999999999999999999  ;"
    322       "  incLudesUbdOmains   ", &max_age, &include_subdomains));
    323   expect_max_age = base::TimeDelta::FromSeconds(
    324       kMaxHSTSAgeSecs);
    325   EXPECT_EQ(expect_max_age, max_age);
    326   EXPECT_TRUE(include_subdomains);
    327 }
    328 
    329 static void TestValidPKPHeaders(HashValueTag tag) {
    330   base::TimeDelta max_age;
    331   base::TimeDelta expect_max_age;
    332   bool include_subdomains;
    333   HashValueVector hashes;
    334   HashValueVector chain_hashes;
    335 
    336   // Set some fake "chain" hashes into chain_hashes
    337   chain_hashes.push_back(GetTestHashValue(1, tag));
    338   chain_hashes.push_back(GetTestHashValue(2, tag));
    339   chain_hashes.push_back(GetTestHashValue(3, tag));
    340 
    341   // The good pin must be in the chain, the backup pin must not be
    342   std::string good_pin = GetTestPin(2, tag);
    343   std::string backup_pin = GetTestPin(4, tag);
    344 
    345   EXPECT_TRUE(ParseHPKPHeader(
    346       "max-age=243; " + good_pin + ";" + backup_pin,
    347       chain_hashes, &max_age, &include_subdomains, &hashes));
    348   expect_max_age = base::TimeDelta::FromSeconds(243);
    349   EXPECT_EQ(expect_max_age, max_age);
    350   EXPECT_FALSE(include_subdomains);
    351 
    352   EXPECT_TRUE(ParseHPKPHeader(
    353       "   " + good_pin + "; " + backup_pin + "  ; Max-agE    = 567",
    354       chain_hashes, &max_age, &include_subdomains, &hashes));
    355   expect_max_age = base::TimeDelta::FromSeconds(567);
    356   EXPECT_EQ(expect_max_age, max_age);
    357   EXPECT_FALSE(include_subdomains);
    358 
    359   EXPECT_TRUE(ParseHPKPHeader(
    360       "includeSubDOMAINS;" + good_pin + ";" + backup_pin +
    361       "  ; mAx-aGe    = 890      ",
    362       chain_hashes, &max_age, &include_subdomains, &hashes));
    363   expect_max_age = base::TimeDelta::FromSeconds(890);
    364   EXPECT_EQ(expect_max_age, max_age);
    365   EXPECT_TRUE(include_subdomains);
    366 
    367   EXPECT_TRUE(ParseHPKPHeader(
    368       good_pin + ";" + backup_pin + "; max-age=123;IGNORED;",
    369       chain_hashes, &max_age, &include_subdomains, &hashes));
    370   expect_max_age = base::TimeDelta::FromSeconds(123);
    371   EXPECT_EQ(expect_max_age, max_age);
    372   EXPECT_FALSE(include_subdomains);
    373 
    374   EXPECT_TRUE(ParseHPKPHeader(
    375       "max-age=394082;" + backup_pin + ";" + good_pin + ";  ",
    376       chain_hashes, &max_age, &include_subdomains, &hashes));
    377   expect_max_age = base::TimeDelta::FromSeconds(394082);
    378   EXPECT_EQ(expect_max_age, max_age);
    379   EXPECT_FALSE(include_subdomains);
    380 
    381   EXPECT_TRUE(ParseHPKPHeader(
    382       "max-age=39408299  ;" + backup_pin + ";" + good_pin + ";  ",
    383       chain_hashes, &max_age, &include_subdomains, &hashes));
    384   expect_max_age = base::TimeDelta::FromSeconds(
    385       std::min(kMaxHSTSAgeSecs, static_cast<int64>(GG_INT64_C(39408299))));
    386   EXPECT_EQ(expect_max_age, max_age);
    387   EXPECT_FALSE(include_subdomains);
    388 
    389   EXPECT_TRUE(ParseHPKPHeader(
    390       "max-age=39408038  ;    cybers=39408038  ;  includeSubdomains; " +
    391           good_pin + ";" + backup_pin + ";   ",
    392       chain_hashes, &max_age, &include_subdomains, &hashes));
    393   expect_max_age = base::TimeDelta::FromSeconds(
    394       std::min(kMaxHSTSAgeSecs, static_cast<int64>(GG_INT64_C(394082038))));
    395   EXPECT_EQ(expect_max_age, max_age);
    396   EXPECT_TRUE(include_subdomains);
    397 
    398   EXPECT_TRUE(ParseHPKPHeader(
    399       "  max-age=0  ;  " + good_pin + ";" + backup_pin,
    400       chain_hashes, &max_age, &include_subdomains, &hashes));
    401   expect_max_age = base::TimeDelta::FromSeconds(0);
    402   EXPECT_EQ(expect_max_age, max_age);
    403   EXPECT_FALSE(include_subdomains);
    404 
    405   EXPECT_TRUE(ParseHPKPHeader(
    406       "  max-age=0 ; includeSubdomains;  " + good_pin + ";" + backup_pin,
    407       chain_hashes, &max_age, &include_subdomains, &hashes));
    408   expect_max_age = base::TimeDelta::FromSeconds(0);
    409   EXPECT_EQ(expect_max_age, max_age);
    410   EXPECT_TRUE(include_subdomains);
    411 
    412   EXPECT_TRUE(ParseHPKPHeader(
    413       "  max-age=999999999999999999999999999999999999999999999  ;  " +
    414           backup_pin + ";" + good_pin + ";   ",
    415       chain_hashes, &max_age, &include_subdomains, &hashes));
    416   expect_max_age = base::TimeDelta::FromSeconds(kMaxHSTSAgeSecs);
    417   EXPECT_EQ(expect_max_age, max_age);
    418   EXPECT_FALSE(include_subdomains);
    419 
    420   // Test that parsing the same header twice doesn't duplicate the recorded
    421   // hashes.
    422   hashes.clear();
    423   EXPECT_TRUE(ParseHPKPHeader(
    424       "  max-age=999;  " +
    425           backup_pin + ";" + good_pin + ";   ",
    426       chain_hashes, &max_age, &include_subdomains, &hashes));
    427   EXPECT_EQ(2u, hashes.size());
    428   EXPECT_TRUE(ParseHPKPHeader(
    429       "  max-age=999;  " +
    430           backup_pin + ";" + good_pin + ";   ",
    431       chain_hashes, &max_age, &include_subdomains, &hashes));
    432   EXPECT_EQ(2u, hashes.size());
    433 }
    434 
    435 TEST_F(HttpSecurityHeadersTest, BogusPinsHeadersSHA1) {
    436   TestBogusPinsHeaders(HASH_VALUE_SHA1);
    437 }
    438 
    439 TEST_F(HttpSecurityHeadersTest, BogusPinsHeadersSHA256) {
    440   TestBogusPinsHeaders(HASH_VALUE_SHA256);
    441 }
    442 
    443 TEST_F(HttpSecurityHeadersTest, ValidPKPHeadersSHA1) {
    444   TestValidPKPHeaders(HASH_VALUE_SHA1);
    445 }
    446 
    447 TEST_F(HttpSecurityHeadersTest, ValidPKPHeadersSHA256) {
    448   TestValidPKPHeaders(HASH_VALUE_SHA256);
    449 }
    450 
    451 TEST_F(HttpSecurityHeadersTest, UpdateDynamicPKPOnly) {
    452   TransportSecurityState state;
    453   TransportSecurityState::DomainState domain_state;
    454 
    455   // docs.google.com has preloaded pins.
    456   std::string domain = "docs.google.com";
    457   EXPECT_TRUE(state.GetDomainState(domain, true, &domain_state));
    458   EXPECT_GT(domain_state.static_spki_hashes.size(), 1UL);
    459   HashValueVector saved_hashes = domain_state.static_spki_hashes;
    460 
    461   // Add a header, which should only update the dynamic state.
    462   HashValue good_hash = GetTestHashValue(1, HASH_VALUE_SHA1);
    463   HashValue backup_hash = GetTestHashValue(2, HASH_VALUE_SHA1);
    464   std::string good_pin = GetTestPin(1, HASH_VALUE_SHA1);
    465   std::string backup_pin = GetTestPin(2, HASH_VALUE_SHA1);
    466   std::string header = "max-age = 10000; " + good_pin + "; " + backup_pin;
    467 
    468   // Construct a fake SSLInfo that will pass AddHPKPHeader's checks.
    469   SSLInfo ssl_info;
    470   ssl_info.public_key_hashes.push_back(good_hash);
    471   ssl_info.public_key_hashes.push_back(saved_hashes[0]);
    472   EXPECT_TRUE(state.AddHPKPHeader(domain, header, ssl_info));
    473 
    474   // Expect the preloaded state to remain unchanged.
    475   std::string canonicalized_host = TransportSecurityState::CanonicalizeHost(
    476       domain);
    477   TransportSecurityState::DomainState static_domain_state;
    478   EXPECT_TRUE(state.GetStaticDomainState(canonicalized_host,
    479                                          true,
    480                                          &static_domain_state));
    481   for (size_t i = 0; i < saved_hashes.size(); ++i) {
    482     EXPECT_TRUE(HashValuesEqual(
    483         saved_hashes[i])(static_domain_state.static_spki_hashes[i]));
    484   }
    485 
    486   // Expect the dynamic state to reflect the header.
    487   TransportSecurityState::DomainState dynamic_domain_state;
    488   EXPECT_TRUE(state.GetDynamicDomainState(domain, &dynamic_domain_state));
    489   EXPECT_EQ(2UL, dynamic_domain_state.dynamic_spki_hashes.size());
    490 
    491   HashValueVector::const_iterator hash = std::find_if(
    492       dynamic_domain_state.dynamic_spki_hashes.begin(),
    493       dynamic_domain_state.dynamic_spki_hashes.end(),
    494       HashValuesEqual(good_hash));
    495   EXPECT_NE(dynamic_domain_state.dynamic_spki_hashes.end(), hash);
    496 
    497   hash = std::find_if(
    498       dynamic_domain_state.dynamic_spki_hashes.begin(),
    499       dynamic_domain_state.dynamic_spki_hashes.end(),
    500       HashValuesEqual(backup_hash));
    501   EXPECT_NE(dynamic_domain_state.dynamic_spki_hashes.end(), hash);
    502 
    503   // Expect the overall state to reflect the header, too.
    504   EXPECT_TRUE(state.GetDomainState(domain, true, &domain_state));
    505   EXPECT_EQ(2UL, domain_state.dynamic_spki_hashes.size());
    506 
    507   hash = std::find_if(domain_state.dynamic_spki_hashes.begin(),
    508                       domain_state.dynamic_spki_hashes.end(),
    509                       HashValuesEqual(good_hash));
    510   EXPECT_NE(domain_state.dynamic_spki_hashes.end(), hash);
    511 
    512   hash = std::find_if(
    513       domain_state.dynamic_spki_hashes.begin(),
    514       domain_state.dynamic_spki_hashes.end(),
    515       HashValuesEqual(backup_hash));
    516   EXPECT_NE(domain_state.dynamic_spki_hashes.end(), hash);
    517 }
    518 
    519 };    // namespace net
    520