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     e", &max_age,
     94                                &include_subdomains));
     95   EXPECT_FALSE(ParseHSTSHeader("max-age=3488923     includesubdomain",
     96                                &max_age, &include_subdomains));
     97   EXPECT_FALSE(ParseHSTSHeader("max-age=3488923includesubdomains",
     98                                &max_age, &include_subdomains));
     99   EXPECT_FALSE(ParseHSTSHeader("max-age=3488923=includesubdomains",
    100                                &max_age, &include_subdomains));
    101   EXPECT_FALSE(ParseHSTSHeader("max-age=3488923 includesubdomainx",
    102                                &max_age, &include_subdomains));
    103   EXPECT_FALSE(ParseHSTSHeader("max-age=3488923 includesubdomain=",
    104                                &max_age, &include_subdomains));
    105   EXPECT_FALSE(ParseHSTSHeader("max-age=3488923 includesubdomain=true",
    106                                &max_age, &include_subdomains));
    107   EXPECT_FALSE(ParseHSTSHeader("max-age=3488923 includesubdomainsx",
    108                                &max_age, &include_subdomains));
    109   EXPECT_FALSE(ParseHSTSHeader("max-age=3488923 includesubdomains x",
    110                                &max_age, &include_subdomains));
    111   EXPECT_FALSE(ParseHSTSHeader("max-age=34889.23 includesubdomains",
    112                                &max_age, &include_subdomains));
    113   EXPECT_FALSE(ParseHSTSHeader("max-age=34889 includesubdomains",
    114                                &max_age, &include_subdomains));
    115   EXPECT_FALSE(ParseHSTSHeader(";;;; ;;;",
    116                                &max_age, &include_subdomains));
    117   EXPECT_FALSE(ParseHSTSHeader(";;;; includeSubDomains;;;",
    118                                &max_age, &include_subdomains));
    119   EXPECT_FALSE(ParseHSTSHeader("   includeSubDomains;  ",
    120                                &max_age, &include_subdomains));
    121   EXPECT_FALSE(ParseHSTSHeader(";",
    122                                &max_age, &include_subdomains));
    123   EXPECT_FALSE(ParseHSTSHeader("max-age; ;",
    124                                &max_age, &include_subdomains));
    125 
    126   // Check the out args were not updated by checking the default
    127   // values for its predictable fields.
    128   EXPECT_EQ(0, max_age.InSeconds());
    129   EXPECT_FALSE(include_subdomains);
    130 }
    131 
    132 static void TestBogusPinsHeaders(HashValueTag tag) {
    133   base::TimeDelta max_age;
    134   bool include_subdomains;
    135   HashValueVector hashes;
    136   HashValueVector chain_hashes;
    137 
    138   // Set some fake "chain" hashes
    139   chain_hashes.push_back(GetTestHashValue(1, tag));
    140   chain_hashes.push_back(GetTestHashValue(2, tag));
    141   chain_hashes.push_back(GetTestHashValue(3, tag));
    142 
    143   // The good pin must be in the chain, the backup pin must not be
    144   std::string good_pin = GetTestPin(2, tag);
    145   std::string backup_pin = GetTestPin(4, tag);
    146 
    147   EXPECT_FALSE(ParseHPKPHeader(std::string(), chain_hashes, &max_age,
    148                                &include_subdomains, &hashes));
    149   EXPECT_FALSE(ParseHPKPHeader("    ", chain_hashes, &max_age,
    150                                &include_subdomains, &hashes));
    151   EXPECT_FALSE(ParseHPKPHeader("abc", chain_hashes, &max_age,
    152                                &include_subdomains, &hashes));
    153   EXPECT_FALSE(ParseHPKPHeader("  abc", chain_hashes, &max_age,
    154                                &include_subdomains, &hashes));
    155   EXPECT_FALSE(ParseHPKPHeader("  abc   ", 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, &max_age,
    164                                &include_subdomains, &hashes));
    165   EXPECT_FALSE(ParseHPKPHeader("   max-age=", chain_hashes, &max_age,
    166                                &include_subdomains, &hashes));
    167   EXPECT_FALSE(ParseHPKPHeader("   max-age  =", chain_hashes, &max_age,
    168                                &include_subdomains, &hashes));
    169   EXPECT_FALSE(ParseHPKPHeader("   max-age=   ", chain_hashes, &max_age,
    170                                &include_subdomains, &hashes));
    171   EXPECT_FALSE(ParseHPKPHeader("   max-age  =     ", chain_hashes,
    172                                &max_age, &include_subdomains, &hashes));
    173   EXPECT_FALSE(ParseHPKPHeader("   max-age  =     xy", chain_hashes,
    174                                &max_age, &include_subdomains, &hashes));
    175   EXPECT_FALSE(ParseHPKPHeader("   max-age  =     3488a923",
    176                                chain_hashes, &max_age, &include_subdomains,
    177                                &hashes));
    178   EXPECT_FALSE(ParseHPKPHeader("max-age=3488a923  ", chain_hashes,
    179                                &max_age, &include_subdomains, &hashes));
    180   EXPECT_FALSE(ParseHPKPHeader("max-ag=3488923pins=" + good_pin + "," +
    181                                backup_pin,
    182                                chain_hashes, &max_age, &include_subdomains,
    183                                &hashes));
    184   EXPECT_FALSE(ParseHPKPHeader("max-aged=3488923" + backup_pin,
    185                                chain_hashes, &max_age, &include_subdomains,
    186                                &hashes));
    187   EXPECT_FALSE(ParseHPKPHeader("max-aged=3488923; " + backup_pin,
    188                                chain_hashes, &max_age, &include_subdomains,
    189                                &hashes));
    190   EXPECT_FALSE(ParseHPKPHeader("max-aged=3488923; " + backup_pin + ";" +
    191                                backup_pin,
    192                                chain_hashes, &max_age, &include_subdomains,
    193                                &hashes));
    194   EXPECT_FALSE(ParseHPKPHeader("max-aged=3488923; " + good_pin + ";" +
    195                                good_pin,
    196                                chain_hashes, &max_age, &include_subdomains,
    197                                &hashes));
    198   EXPECT_FALSE(ParseHPKPHeader("max-aged=3488923; " + good_pin,
    199                                chain_hashes, &max_age, &include_subdomains,
    200                                &hashes));
    201   EXPECT_FALSE(ParseHPKPHeader("max-age==3488923", chain_hashes, &max_age,
    202                                &include_subdomains, &hashes));
    203   EXPECT_FALSE(ParseHPKPHeader("amax-age=3488923", chain_hashes, &max_age,
    204                                &include_subdomains, &hashes));
    205   EXPECT_FALSE(ParseHPKPHeader("max-age=-3488923", chain_hashes, &max_age,
    206                                &include_subdomains, &hashes));
    207   EXPECT_FALSE(ParseHPKPHeader("max-age=3488923;", chain_hashes, &max_age,
    208                                &include_subdomains, &hashes));
    209   EXPECT_FALSE(ParseHPKPHeader("max-age=3488923     e", chain_hashes,
    210                                &max_age, &include_subdomains, &hashes));
    211   EXPECT_FALSE(ParseHPKPHeader("max-age=3488923     includesubdomain",
    212                                chain_hashes, &max_age, &include_subdomains,
    213                                &hashes));
    214   EXPECT_FALSE(ParseHPKPHeader("max-age=34889.23", chain_hashes, &max_age,
    215                                &include_subdomains, &hashes));
    216 
    217   // Check the out args were not updated by checking the default
    218   // values for its predictable fields.
    219   EXPECT_EQ(0, max_age.InSeconds());
    220   EXPECT_EQ(hashes.size(), (size_t)0);
    221 }
    222 
    223 TEST_F(HttpSecurityHeadersTest, ValidSTSHeaders) {
    224   base::TimeDelta max_age;
    225   base::TimeDelta expect_max_age;
    226   bool include_subdomains = false;
    227 
    228   EXPECT_TRUE(ParseHSTSHeader("max-age=243", &max_age,
    229                               &include_subdomains));
    230   expect_max_age = base::TimeDelta::FromSeconds(243);
    231   EXPECT_EQ(expect_max_age, max_age);
    232   EXPECT_FALSE(include_subdomains);
    233 
    234   EXPECT_TRUE(ParseHSTSHeader("max-age=3488923;", &max_age,
    235                               &include_subdomains));
    236 
    237   EXPECT_TRUE(ParseHSTSHeader("  Max-agE    = 567", &max_age,
    238                               &include_subdomains));
    239   expect_max_age = base::TimeDelta::FromSeconds(567);
    240   EXPECT_EQ(expect_max_age, max_age);
    241   EXPECT_FALSE(include_subdomains);
    242 
    243   EXPECT_TRUE(ParseHSTSHeader("  mAx-aGe    = 890      ", &max_age,
    244                               &include_subdomains));
    245   expect_max_age = base::TimeDelta::FromSeconds(890);
    246   EXPECT_EQ(expect_max_age, max_age);
    247   EXPECT_FALSE(include_subdomains);
    248 
    249   EXPECT_TRUE(ParseHSTSHeader("max-age=123;incLudesUbdOmains", &max_age,
    250                               &include_subdomains));
    251   expect_max_age = base::TimeDelta::FromSeconds(123);
    252   EXPECT_EQ(expect_max_age, max_age);
    253   EXPECT_TRUE(include_subdomains);
    254 
    255   EXPECT_TRUE(ParseHSTSHeader("incLudesUbdOmains; max-age=123", &max_age,
    256                               &include_subdomains));
    257   expect_max_age = base::TimeDelta::FromSeconds(123);
    258   EXPECT_EQ(expect_max_age, max_age);
    259   EXPECT_TRUE(include_subdomains);
    260 
    261   EXPECT_TRUE(ParseHSTSHeader("   incLudesUbdOmains; max-age=123",
    262                               &max_age, &include_subdomains));
    263   expect_max_age = base::TimeDelta::FromSeconds(123);
    264   EXPECT_EQ(expect_max_age, max_age);
    265   EXPECT_TRUE(include_subdomains);
    266 
    267   EXPECT_TRUE(ParseHSTSHeader(
    268       "   incLudesUbdOmains; max-age=123; pumpkin=kitten", &max_age,
    269                                    &include_subdomains));
    270   expect_max_age = base::TimeDelta::FromSeconds(123);
    271   EXPECT_EQ(expect_max_age, max_age);
    272   EXPECT_TRUE(include_subdomains);
    273 
    274   EXPECT_TRUE(ParseHSTSHeader(
    275       "   pumpkin=894; incLudesUbdOmains; max-age=123  ", &max_age,
    276                                    &include_subdomains));
    277   expect_max_age = base::TimeDelta::FromSeconds(123);
    278   EXPECT_EQ(expect_max_age, max_age);
    279   EXPECT_TRUE(include_subdomains);
    280 
    281   EXPECT_TRUE(ParseHSTSHeader(
    282       "   pumpkin; incLudesUbdOmains; max-age=123  ", &max_age,
    283                                    &include_subdomains));
    284   expect_max_age = base::TimeDelta::FromSeconds(123);
    285   EXPECT_EQ(expect_max_age, max_age);
    286   EXPECT_TRUE(include_subdomains);
    287 
    288   EXPECT_TRUE(ParseHSTSHeader(
    289       "   pumpkin; incLudesUbdOmains; max-age=\"123\"  ", &max_age,
    290                                    &include_subdomains));
    291   expect_max_age = base::TimeDelta::FromSeconds(123);
    292   EXPECT_EQ(expect_max_age, max_age);
    293   EXPECT_TRUE(include_subdomains);
    294 
    295   EXPECT_TRUE(ParseHSTSHeader(
    296       "animal=\"squirrel; distinguished\"; incLudesUbdOmains; max-age=123",
    297                                    &max_age, &include_subdomains));
    298   expect_max_age = base::TimeDelta::FromSeconds(123);
    299   EXPECT_EQ(expect_max_age, max_age);
    300   EXPECT_TRUE(include_subdomains);
    301 
    302   EXPECT_TRUE(ParseHSTSHeader("max-age=394082;  incLudesUbdOmains",
    303                               &max_age, &include_subdomains));
    304   expect_max_age = base::TimeDelta::FromSeconds(394082);
    305   EXPECT_EQ(expect_max_age, max_age);
    306   EXPECT_TRUE(include_subdomains);
    307 
    308   EXPECT_TRUE(ParseHSTSHeader(
    309       "max-age=39408299  ;incLudesUbdOmains", &max_age,
    310       &include_subdomains));
    311   expect_max_age = base::TimeDelta::FromSeconds(
    312       std::min(kMaxHSTSAgeSecs, static_cast<int64>(GG_INT64_C(39408299))));
    313   EXPECT_EQ(expect_max_age, max_age);
    314   EXPECT_TRUE(include_subdomains);
    315 
    316   EXPECT_TRUE(ParseHSTSHeader(
    317       "max-age=394082038  ; incLudesUbdOmains", &max_age,
    318       &include_subdomains));
    319   expect_max_age = base::TimeDelta::FromSeconds(
    320       std::min(kMaxHSTSAgeSecs, static_cast<int64>(GG_INT64_C(394082038))));
    321   EXPECT_EQ(expect_max_age, max_age);
    322   EXPECT_TRUE(include_subdomains);
    323 
    324   EXPECT_TRUE(ParseHSTSHeader(
    325       "max-age=394082038  ; incLudesUbdOmains;", &max_age,
    326       &include_subdomains));
    327   expect_max_age = base::TimeDelta::FromSeconds(
    328       std::min(kMaxHSTSAgeSecs, static_cast<int64>(GG_INT64_C(394082038))));
    329   EXPECT_EQ(expect_max_age, max_age);
    330   EXPECT_TRUE(include_subdomains);
    331 
    332   EXPECT_TRUE(ParseHSTSHeader(
    333       ";; max-age=394082038  ; incLudesUbdOmains; ;", &max_age,
    334       &include_subdomains));
    335   expect_max_age = base::TimeDelta::FromSeconds(
    336       std::min(kMaxHSTSAgeSecs, static_cast<int64>(GG_INT64_C(394082038))));
    337   EXPECT_EQ(expect_max_age, max_age);
    338   EXPECT_TRUE(include_subdomains);
    339 
    340   EXPECT_TRUE(ParseHSTSHeader(
    341       ";; max-age=394082038  ;", &max_age,
    342       &include_subdomains));
    343   expect_max_age = base::TimeDelta::FromSeconds(
    344       std::min(kMaxHSTSAgeSecs, static_cast<int64>(GG_INT64_C(394082038))));
    345   EXPECT_EQ(expect_max_age, max_age);
    346   EXPECT_FALSE(include_subdomains);
    347 
    348   EXPECT_TRUE(ParseHSTSHeader(
    349       ";;    ; ; max-age=394082038;;; includeSubdomains     ;;  ;", &max_age,
    350       &include_subdomains));
    351   expect_max_age = base::TimeDelta::FromSeconds(
    352       std::min(kMaxHSTSAgeSecs, static_cast<int64>(GG_INT64_C(394082038))));
    353   EXPECT_EQ(expect_max_age, max_age);
    354   EXPECT_TRUE(include_subdomains);
    355 
    356   EXPECT_TRUE(ParseHSTSHeader(
    357       "incLudesUbdOmains   ; max-age=394082038 ;;", &max_age,
    358       &include_subdomains));
    359   expect_max_age = base::TimeDelta::FromSeconds(
    360       std::min(kMaxHSTSAgeSecs, static_cast<int64>(GG_INT64_C(394082038))));
    361   EXPECT_EQ(expect_max_age, max_age);
    362   EXPECT_TRUE(include_subdomains);
    363 
    364   EXPECT_TRUE(ParseHSTSHeader(
    365       "  max-age=0  ;  incLudesUbdOmains   ", &max_age,
    366       &include_subdomains));
    367   expect_max_age = base::TimeDelta::FromSeconds(0);
    368   EXPECT_EQ(expect_max_age, max_age);
    369   EXPECT_TRUE(include_subdomains);
    370 
    371   EXPECT_TRUE(ParseHSTSHeader(
    372       "  max-age=999999999999999999999999999999999999999999999  ;"
    373       "  incLudesUbdOmains   ", &max_age, &include_subdomains));
    374   expect_max_age = base::TimeDelta::FromSeconds(
    375       kMaxHSTSAgeSecs);
    376   EXPECT_EQ(expect_max_age, max_age);
    377   EXPECT_TRUE(include_subdomains);
    378 }
    379 
    380 static void TestValidPKPHeaders(HashValueTag tag) {
    381   base::TimeDelta max_age;
    382   base::TimeDelta expect_max_age;
    383   bool include_subdomains;
    384   HashValueVector hashes;
    385   HashValueVector chain_hashes;
    386 
    387   // Set some fake "chain" hashes into chain_hashes
    388   chain_hashes.push_back(GetTestHashValue(1, tag));
    389   chain_hashes.push_back(GetTestHashValue(2, tag));
    390   chain_hashes.push_back(GetTestHashValue(3, tag));
    391 
    392   // The good pin must be in the chain, the backup pin must not be
    393   std::string good_pin = GetTestPin(2, tag);
    394   std::string backup_pin = GetTestPin(4, tag);
    395 
    396   EXPECT_TRUE(ParseHPKPHeader(
    397       "max-age=243; " + good_pin + ";" + backup_pin,
    398       chain_hashes, &max_age, &include_subdomains, &hashes));
    399   expect_max_age = base::TimeDelta::FromSeconds(243);
    400   EXPECT_EQ(expect_max_age, max_age);
    401   EXPECT_FALSE(include_subdomains);
    402 
    403   EXPECT_TRUE(ParseHPKPHeader(
    404       "   " + good_pin + "; " + backup_pin + "  ; Max-agE    = 567",
    405       chain_hashes, &max_age, &include_subdomains, &hashes));
    406   expect_max_age = base::TimeDelta::FromSeconds(567);
    407   EXPECT_EQ(expect_max_age, max_age);
    408   EXPECT_FALSE(include_subdomains);
    409 
    410   EXPECT_TRUE(ParseHPKPHeader(
    411       "includeSubDOMAINS;" + good_pin + ";" + backup_pin +
    412       "  ; mAx-aGe    = 890      ",
    413       chain_hashes, &max_age, &include_subdomains, &hashes));
    414   expect_max_age = base::TimeDelta::FromSeconds(890);
    415   EXPECT_EQ(expect_max_age, max_age);
    416   EXPECT_TRUE(include_subdomains);
    417 
    418   EXPECT_TRUE(ParseHPKPHeader(
    419       good_pin + ";" + backup_pin + "; max-age=123;IGNORED;",
    420       chain_hashes, &max_age, &include_subdomains, &hashes));
    421   expect_max_age = base::TimeDelta::FromSeconds(123);
    422   EXPECT_EQ(expect_max_age, max_age);
    423   EXPECT_FALSE(include_subdomains);
    424 
    425   EXPECT_TRUE(ParseHPKPHeader(
    426       "max-age=394082;" + backup_pin + ";" + good_pin + ";  ",
    427       chain_hashes, &max_age, &include_subdomains, &hashes));
    428   expect_max_age = base::TimeDelta::FromSeconds(394082);
    429   EXPECT_EQ(expect_max_age, max_age);
    430   EXPECT_FALSE(include_subdomains);
    431 
    432   EXPECT_TRUE(ParseHPKPHeader(
    433       "max-age=39408299  ;" + backup_pin + ";" + good_pin + ";  ",
    434       chain_hashes, &max_age, &include_subdomains, &hashes));
    435   expect_max_age = base::TimeDelta::FromSeconds(
    436       std::min(kMaxHSTSAgeSecs, static_cast<int64>(GG_INT64_C(39408299))));
    437   EXPECT_EQ(expect_max_age, max_age);
    438   EXPECT_FALSE(include_subdomains);
    439 
    440   EXPECT_TRUE(ParseHPKPHeader(
    441       "max-age=39408038  ;    cybers=39408038  ;  includeSubdomains; " +
    442           good_pin + ";" + backup_pin + ";   ",
    443       chain_hashes, &max_age, &include_subdomains, &hashes));
    444   expect_max_age = base::TimeDelta::FromSeconds(
    445       std::min(kMaxHSTSAgeSecs, static_cast<int64>(GG_INT64_C(394082038))));
    446   EXPECT_EQ(expect_max_age, max_age);
    447   EXPECT_TRUE(include_subdomains);
    448 
    449   EXPECT_TRUE(ParseHPKPHeader(
    450       "  max-age=0  ;  " + good_pin + ";" + backup_pin,
    451       chain_hashes, &max_age, &include_subdomains, &hashes));
    452   expect_max_age = base::TimeDelta::FromSeconds(0);
    453   EXPECT_EQ(expect_max_age, max_age);
    454   EXPECT_FALSE(include_subdomains);
    455 
    456   EXPECT_TRUE(ParseHPKPHeader(
    457       "  max-age=0 ; includeSubdomains;  " + good_pin + ";" + backup_pin,
    458       chain_hashes, &max_age, &include_subdomains, &hashes));
    459   expect_max_age = base::TimeDelta::FromSeconds(0);
    460   EXPECT_EQ(expect_max_age, max_age);
    461   EXPECT_TRUE(include_subdomains);
    462 
    463   EXPECT_TRUE(ParseHPKPHeader(
    464       "  max-age=999999999999999999999999999999999999999999999  ;  " +
    465           backup_pin + ";" + good_pin + ";   ",
    466       chain_hashes, &max_age, &include_subdomains, &hashes));
    467   expect_max_age = base::TimeDelta::FromSeconds(kMaxHSTSAgeSecs);
    468   EXPECT_EQ(expect_max_age, max_age);
    469   EXPECT_FALSE(include_subdomains);
    470 
    471   // Test that parsing the same header twice doesn't duplicate the recorded
    472   // hashes.
    473   hashes.clear();
    474   EXPECT_TRUE(ParseHPKPHeader(
    475       "  max-age=999;  " +
    476           backup_pin + ";" + good_pin + ";   ",
    477       chain_hashes, &max_age, &include_subdomains, &hashes));
    478   EXPECT_EQ(2u, hashes.size());
    479   EXPECT_TRUE(ParseHPKPHeader(
    480       "  max-age=999;  " +
    481           backup_pin + ";" + good_pin + ";   ",
    482       chain_hashes, &max_age, &include_subdomains, &hashes));
    483   EXPECT_EQ(2u, hashes.size());
    484 }
    485 
    486 TEST_F(HttpSecurityHeadersTest, BogusPinsHeadersSHA1) {
    487   TestBogusPinsHeaders(HASH_VALUE_SHA1);
    488 }
    489 
    490 TEST_F(HttpSecurityHeadersTest, BogusPinsHeadersSHA256) {
    491   TestBogusPinsHeaders(HASH_VALUE_SHA256);
    492 }
    493 
    494 TEST_F(HttpSecurityHeadersTest, ValidPKPHeadersSHA1) {
    495   TestValidPKPHeaders(HASH_VALUE_SHA1);
    496 }
    497 
    498 TEST_F(HttpSecurityHeadersTest, ValidPKPHeadersSHA256) {
    499   TestValidPKPHeaders(HASH_VALUE_SHA256);
    500 }
    501 
    502 TEST_F(HttpSecurityHeadersTest, UpdateDynamicPKPOnly) {
    503   TransportSecurityState state;
    504   TransportSecurityState::DomainState static_domain_state;
    505 
    506   // docs.google.com has preloaded pins.
    507   const bool sni_enabled = true;
    508   std::string domain = "docs.google.com";
    509   EXPECT_TRUE(
    510       state.GetStaticDomainState(domain, sni_enabled, &static_domain_state));
    511   EXPECT_GT(static_domain_state.pkp.spki_hashes.size(), 1UL);
    512   HashValueVector saved_hashes = static_domain_state.pkp.spki_hashes;
    513 
    514   // Add a header, which should only update the dynamic state.
    515   HashValue good_hash = GetTestHashValue(1, HASH_VALUE_SHA1);
    516   HashValue backup_hash = GetTestHashValue(2, HASH_VALUE_SHA1);
    517   std::string good_pin = GetTestPin(1, HASH_VALUE_SHA1);
    518   std::string backup_pin = GetTestPin(2, HASH_VALUE_SHA1);
    519   std::string header = "max-age = 10000; " + good_pin + "; " + backup_pin;
    520 
    521   // Construct a fake SSLInfo that will pass AddHPKPHeader's checks.
    522   SSLInfo ssl_info;
    523   ssl_info.public_key_hashes.push_back(good_hash);
    524   ssl_info.public_key_hashes.push_back(saved_hashes[0]);
    525   EXPECT_TRUE(state.AddHPKPHeader(domain, header, ssl_info));
    526 
    527   // Expect the static state to remain unchanged.
    528   TransportSecurityState::DomainState new_static_domain_state;
    529   EXPECT_TRUE(state.GetStaticDomainState(
    530       domain, sni_enabled, &new_static_domain_state));
    531   for (size_t i = 0; i < saved_hashes.size(); ++i) {
    532     EXPECT_TRUE(HashValuesEqual(saved_hashes[i])(
    533         new_static_domain_state.pkp.spki_hashes[i]));
    534   }
    535 
    536   // Expect the dynamic state to reflect the header.
    537   TransportSecurityState::DomainState dynamic_domain_state;
    538   EXPECT_TRUE(state.GetDynamicDomainState(domain, &dynamic_domain_state));
    539   EXPECT_EQ(2UL, dynamic_domain_state.pkp.spki_hashes.size());
    540 
    541   HashValueVector::const_iterator hash =
    542       std::find_if(dynamic_domain_state.pkp.spki_hashes.begin(),
    543                    dynamic_domain_state.pkp.spki_hashes.end(),
    544                    HashValuesEqual(good_hash));
    545   EXPECT_NE(dynamic_domain_state.pkp.spki_hashes.end(), hash);
    546 
    547   hash = std::find_if(dynamic_domain_state.pkp.spki_hashes.begin(),
    548                       dynamic_domain_state.pkp.spki_hashes.end(),
    549                       HashValuesEqual(backup_hash));
    550   EXPECT_NE(dynamic_domain_state.pkp.spki_hashes.end(), hash);
    551 
    552   // Expect the overall state to reflect the header, too.
    553   EXPECT_TRUE(state.HasPublicKeyPins(domain, sni_enabled));
    554   HashValueVector hashes;
    555   hashes.push_back(good_hash);
    556   std::string failure_log;
    557   EXPECT_TRUE(
    558       state.CheckPublicKeyPins(domain, sni_enabled, hashes, &failure_log));
    559 
    560   TransportSecurityState::DomainState new_dynamic_domain_state;
    561   EXPECT_TRUE(state.GetDynamicDomainState(domain, &new_dynamic_domain_state));
    562   EXPECT_EQ(2UL, new_dynamic_domain_state.pkp.spki_hashes.size());
    563 
    564   hash = std::find_if(new_dynamic_domain_state.pkp.spki_hashes.begin(),
    565                       new_dynamic_domain_state.pkp.spki_hashes.end(),
    566                       HashValuesEqual(good_hash));
    567   EXPECT_NE(new_dynamic_domain_state.pkp.spki_hashes.end(), hash);
    568 
    569   hash = std::find_if(new_dynamic_domain_state.pkp.spki_hashes.begin(),
    570                       new_dynamic_domain_state.pkp.spki_hashes.end(),
    571                       HashValuesEqual(backup_hash));
    572   EXPECT_NE(new_dynamic_domain_state.pkp.spki_hashes.end(), hash);
    573 }
    574 
    575 // Failing on win_chromium_rel. crbug.com/375538
    576 #if defined(OS_WIN)
    577 #define MAYBE_UpdateDynamicPKPMaxAge0 DISABLED_UpdateDynamicPKPMaxAge0
    578 #else
    579 #define MAYBE_UpdateDynamicPKPMaxAge0 UpdateDynamicPKPMaxAge0
    580 #endif
    581 TEST_F(HttpSecurityHeadersTest, MAYBE_UpdateDynamicPKPMaxAge0) {
    582   TransportSecurityState state;
    583   TransportSecurityState::DomainState static_domain_state;
    584 
    585   // docs.google.com has preloaded pins.
    586   const bool sni_enabled = true;
    587   std::string domain = "docs.google.com";
    588   ASSERT_TRUE(
    589       state.GetStaticDomainState(domain, sni_enabled, &static_domain_state));
    590   EXPECT_GT(static_domain_state.pkp.spki_hashes.size(), 1UL);
    591   HashValueVector saved_hashes = static_domain_state.pkp.spki_hashes;
    592 
    593   // Add a header, which should only update the dynamic state.
    594   HashValue good_hash = GetTestHashValue(1, HASH_VALUE_SHA1);
    595   std::string good_pin = GetTestPin(1, HASH_VALUE_SHA1);
    596   std::string backup_pin = GetTestPin(2, HASH_VALUE_SHA1);
    597   std::string header = "max-age = 10000; " + good_pin + "; " + backup_pin;
    598 
    599   // Construct a fake SSLInfo that will pass AddHPKPHeader's checks.
    600   SSLInfo ssl_info;
    601   ssl_info.public_key_hashes.push_back(good_hash);
    602   ssl_info.public_key_hashes.push_back(saved_hashes[0]);
    603   EXPECT_TRUE(state.AddHPKPHeader(domain, header, ssl_info));
    604 
    605   // Expect the static state to remain unchanged.
    606   TransportSecurityState::DomainState new_static_domain_state;
    607   EXPECT_TRUE(state.GetStaticDomainState(
    608       domain, sni_enabled, &new_static_domain_state));
    609   EXPECT_EQ(saved_hashes.size(),
    610             new_static_domain_state.pkp.spki_hashes.size());
    611   for (size_t i = 0; i < saved_hashes.size(); ++i) {
    612     EXPECT_TRUE(HashValuesEqual(saved_hashes[i])(
    613         new_static_domain_state.pkp.spki_hashes[i]));
    614   }
    615 
    616   // Expect the dynamic state to have pins.
    617   TransportSecurityState::DomainState new_dynamic_domain_state;
    618   EXPECT_TRUE(state.GetDynamicDomainState(domain, &new_dynamic_domain_state));
    619   EXPECT_EQ(2UL, new_dynamic_domain_state.pkp.spki_hashes.size());
    620   EXPECT_TRUE(new_dynamic_domain_state.HasPublicKeyPins());
    621 
    622   // Now set another header with max-age=0, and check that the pins are
    623   // cleared in the dynamic state only.
    624   header = "max-age = 0; " + good_pin + "; " + backup_pin;
    625   EXPECT_TRUE(state.AddHPKPHeader(domain, header, ssl_info));
    626 
    627   // Expect the static state to remain unchanged.
    628   TransportSecurityState::DomainState new_static_domain_state2;
    629   EXPECT_TRUE(state.GetStaticDomainState(
    630       domain, sni_enabled, &new_static_domain_state2));
    631   EXPECT_EQ(saved_hashes.size(),
    632             new_static_domain_state2.pkp.spki_hashes.size());
    633   for (size_t i = 0; i < saved_hashes.size(); ++i) {
    634     EXPECT_TRUE(HashValuesEqual(saved_hashes[i])(
    635         new_static_domain_state2.pkp.spki_hashes[i]));
    636   }
    637 
    638   // Expect the dynamic pins to be gone.
    639   TransportSecurityState::DomainState new_dynamic_domain_state2;
    640   EXPECT_FALSE(state.GetDynamicDomainState(domain, &new_dynamic_domain_state2));
    641 
    642   // Expect the exact-matching static policy to continue to apply, even
    643   // though dynamic policy has been removed. (This policy may change in the
    644   // future, in which case this test must be updated.)
    645   EXPECT_TRUE(state.HasPublicKeyPins(domain, true));
    646   EXPECT_TRUE(state.ShouldSSLErrorsBeFatal(domain, true));
    647   std::string failure_log;
    648   // Damage the hashes to cause a pin validation failure.
    649   new_static_domain_state2.pkp.spki_hashes[0].data()[0] ^= 0x80;
    650   new_static_domain_state2.pkp.spki_hashes[1].data()[0] ^= 0x80;
    651   EXPECT_FALSE(state.CheckPublicKeyPins(
    652       domain, true, new_static_domain_state2.pkp.spki_hashes, &failure_log));
    653   EXPECT_NE(0UL, failure_log.length());
    654 }
    655 #undef MAYBE_UpdateDynamicPKPMaxAge0
    656 
    657 // Tests that when a static HSTS and a static HPKP entry are present, adding a
    658 // dynamic HSTS header does not clobber the static HPKP entry. Further, adding a
    659 // dynamic HPKP entry could not affect the HSTS entry for the site.
    660 TEST_F(HttpSecurityHeadersTest, NoClobberPins) {
    661   TransportSecurityState state;
    662   TransportSecurityState::DomainState domain_state;
    663 
    664   // accounts.google.com has preloaded pins.
    665   std::string domain = "accounts.google.com";
    666 
    667   // Retrieve the DomainState as it is by default, including its known good
    668   // pins.
    669   const bool sni_enabled = true;
    670   EXPECT_TRUE(state.GetStaticDomainState(domain, sni_enabled, &domain_state));
    671   HashValueVector saved_hashes = domain_state.pkp.spki_hashes;
    672   EXPECT_TRUE(domain_state.ShouldUpgradeToSSL());
    673   EXPECT_TRUE(domain_state.HasPublicKeyPins());
    674   EXPECT_TRUE(state.ShouldUpgradeToSSL(domain, sni_enabled));
    675   EXPECT_TRUE(state.HasPublicKeyPins(domain, sni_enabled));
    676 
    677   // Add a dynamic HSTS header. CheckPublicKeyPins should still pass when given
    678   // the original |saved_hashes|, indicating that the static PKP data is still
    679   // configured for the domain.
    680   EXPECT_TRUE(state.AddHSTSHeader(domain, "includesubdomains; max-age=10000"));
    681   EXPECT_TRUE(state.ShouldUpgradeToSSL(domain, sni_enabled));
    682   std::string failure_log;
    683   EXPECT_TRUE(state.CheckPublicKeyPins(
    684       domain, sni_enabled, saved_hashes, &failure_log));
    685 
    686   // Add an HPKP header, which should only update the dynamic state.
    687   HashValue good_hash = GetTestHashValue(1, HASH_VALUE_SHA1);
    688   std::string good_pin = GetTestPin(1, HASH_VALUE_SHA1);
    689   std::string backup_pin = GetTestPin(2, HASH_VALUE_SHA1);
    690   std::string header = "max-age = 10000; " + good_pin + "; " + backup_pin;
    691 
    692   // Construct a fake SSLInfo that will pass AddHPKPHeader's checks.
    693   SSLInfo ssl_info;
    694   ssl_info.public_key_hashes.push_back(good_hash);
    695   ssl_info.public_key_hashes.push_back(saved_hashes[0]);
    696   EXPECT_TRUE(state.AddHPKPHeader(domain, header, ssl_info));
    697 
    698   EXPECT_TRUE(state.AddHPKPHeader(domain, header, ssl_info));
    699   // HSTS should still be configured for this domain.
    700   EXPECT_TRUE(domain_state.ShouldUpgradeToSSL());
    701   EXPECT_TRUE(state.ShouldUpgradeToSSL(domain, sni_enabled));
    702   // The dynamic pins, which do not match |saved_hashes|, should take
    703   // precedence over the static pins and cause the check to fail.
    704   EXPECT_FALSE(state.CheckPublicKeyPins(
    705       domain, sni_enabled, saved_hashes, &failure_log));
    706 }
    707 
    708 };    // namespace net
    709