• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
GetTestHashValue(uint8 label,HashValueTag tag)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 
GetTestPin(uint8 label,HashValueTag tag)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 
TEST_F(HttpSecurityHeadersTest,BogusHeaders)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 
TestBogusPinsHeaders(HashValueTag tag)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 
TEST_F(HttpSecurityHeadersTest,ValidSTSHeaders)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 
TestValidPKPHeaders(HashValueTag tag)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 
TEST_F(HttpSecurityHeadersTest,BogusPinsHeadersSHA1)486 TEST_F(HttpSecurityHeadersTest, BogusPinsHeadersSHA1) {
487   TestBogusPinsHeaders(HASH_VALUE_SHA1);
488 }
489 
TEST_F(HttpSecurityHeadersTest,BogusPinsHeadersSHA256)490 TEST_F(HttpSecurityHeadersTest, BogusPinsHeadersSHA256) {
491   TestBogusPinsHeaders(HASH_VALUE_SHA256);
492 }
493 
TEST_F(HttpSecurityHeadersTest,ValidPKPHeadersSHA1)494 TEST_F(HttpSecurityHeadersTest, ValidPKPHeadersSHA1) {
495   TestValidPKPHeaders(HASH_VALUE_SHA1);
496 }
497 
TEST_F(HttpSecurityHeadersTest,ValidPKPHeadersSHA256)498 TEST_F(HttpSecurityHeadersTest, ValidPKPHeadersSHA256) {
499   TestValidPKPHeaders(HASH_VALUE_SHA256);
500 }
501 
TEST_F(HttpSecurityHeadersTest,UpdateDynamicPKPOnly)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
TEST_F(HttpSecurityHeadersTest,MAYBE_UpdateDynamicPKPMaxAge0)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.
TEST_F(HttpSecurityHeadersTest,NoClobberPins)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