Convert events_unittests to run exclusively on Swarming
[chromium-blink-merge.git] / net / http / http_security_headers_unittest.cc
blob3564245ccd62c88740293a8d23b9eb5d7327d08b
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.
5 #include <stdint.h>
6 #include <algorithm>
8 #include "base/base64.h"
9 #include "base/sha1.h"
10 #include "base/strings/string_piece.h"
11 #include "crypto/sha2.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/log/net_log.h"
17 #include "net/ssl/ssl_info.h"
18 #include "testing/gtest/include/gtest/gtest.h"
20 namespace net {
22 namespace {
24 HashValue GetTestHashValue(uint8 label, HashValueTag tag) {
25 HashValue hash_value(tag);
26 memset(hash_value.data(), label, hash_value.size());
27 return hash_value;
30 std::string GetTestPinImpl(uint8 label, HashValueTag tag, bool quoted) {
31 HashValue hash_value = GetTestHashValue(label, tag);
32 std::string base64;
33 base::Base64Encode(base::StringPiece(
34 reinterpret_cast<char*>(hash_value.data()), hash_value.size()), &base64);
36 std::string ret;
37 switch (hash_value.tag) {
38 case HASH_VALUE_SHA1:
39 ret = "pin-sha1=";
40 break;
41 case HASH_VALUE_SHA256:
42 ret = "pin-sha256=";
43 break;
44 default:
45 NOTREACHED() << "Unknown HashValueTag " << hash_value.tag;
46 return std::string("ERROR");
48 if (quoted)
49 ret += '\"';
50 ret += base64;
51 if (quoted)
52 ret += '\"';
53 return ret;
56 std::string GetTestPin(uint8 label, HashValueTag tag) {
57 return GetTestPinImpl(label, tag, true);
60 std::string GetTestPinUnquoted(uint8 label, HashValueTag tag) {
61 return GetTestPinImpl(label, tag, false);
67 class HttpSecurityHeadersTest : public testing::Test {
71 TEST_F(HttpSecurityHeadersTest, BogusHeaders) {
72 base::TimeDelta max_age;
73 bool include_subdomains = false;
75 EXPECT_FALSE(
76 ParseHSTSHeader(std::string(), &max_age, &include_subdomains));
77 EXPECT_FALSE(ParseHSTSHeader(" ", &max_age, &include_subdomains));
78 EXPECT_FALSE(ParseHSTSHeader("abc", &max_age, &include_subdomains));
79 EXPECT_FALSE(ParseHSTSHeader(" abc", &max_age, &include_subdomains));
80 EXPECT_FALSE(ParseHSTSHeader(" abc ", &max_age, &include_subdomains));
81 EXPECT_FALSE(ParseHSTSHeader("max-age", &max_age, &include_subdomains));
82 EXPECT_FALSE(ParseHSTSHeader(" max-age", &max_age,
83 &include_subdomains));
84 EXPECT_FALSE(ParseHSTSHeader(" max-age ", &max_age,
85 &include_subdomains));
86 EXPECT_FALSE(ParseHSTSHeader("max-age=", &max_age, &include_subdomains));
87 EXPECT_FALSE(ParseHSTSHeader(" max-age=", &max_age,
88 &include_subdomains));
89 EXPECT_FALSE(ParseHSTSHeader(" max-age =", &max_age,
90 &include_subdomains));
91 EXPECT_FALSE(ParseHSTSHeader(" max-age= ", &max_age,
92 &include_subdomains));
93 EXPECT_FALSE(ParseHSTSHeader(" max-age = ", &max_age,
94 &include_subdomains));
95 EXPECT_FALSE(ParseHSTSHeader(" max-age = xy", &max_age,
96 &include_subdomains));
97 EXPECT_FALSE(ParseHSTSHeader(" max-age = 3488a923", &max_age,
98 &include_subdomains));
99 EXPECT_FALSE(ParseHSTSHeader("max-age=3488a923 ", &max_age,
100 &include_subdomains));
101 EXPECT_FALSE(ParseHSTSHeader("max-ag=3488923", &max_age,
102 &include_subdomains));
103 EXPECT_FALSE(ParseHSTSHeader("max-aged=3488923", &max_age,
104 &include_subdomains));
105 EXPECT_FALSE(ParseHSTSHeader("max-age==3488923", &max_age,
106 &include_subdomains));
107 EXPECT_FALSE(ParseHSTSHeader("amax-age=3488923", &max_age,
108 &include_subdomains));
109 EXPECT_FALSE(ParseHSTSHeader("max-age=-3488923", &max_age,
110 &include_subdomains));
111 EXPECT_FALSE(ParseHSTSHeader("max-age=3488923 e", &max_age,
112 &include_subdomains));
113 EXPECT_FALSE(ParseHSTSHeader("max-age=3488923 includesubdomain",
114 &max_age, &include_subdomains));
115 EXPECT_FALSE(ParseHSTSHeader("max-age=3488923includesubdomains",
116 &max_age, &include_subdomains));
117 EXPECT_FALSE(ParseHSTSHeader("max-age=3488923=includesubdomains",
118 &max_age, &include_subdomains));
119 EXPECT_FALSE(ParseHSTSHeader("max-age=3488923 includesubdomainx",
120 &max_age, &include_subdomains));
121 EXPECT_FALSE(ParseHSTSHeader("max-age=3488923 includesubdomain=",
122 &max_age, &include_subdomains));
123 EXPECT_FALSE(ParseHSTSHeader("max-age=3488923 includesubdomain=true",
124 &max_age, &include_subdomains));
125 EXPECT_FALSE(ParseHSTSHeader("max-age=3488923 includesubdomainsx",
126 &max_age, &include_subdomains));
127 EXPECT_FALSE(ParseHSTSHeader("max-age=3488923 includesubdomains x",
128 &max_age, &include_subdomains));
129 EXPECT_FALSE(ParseHSTSHeader("max-age=34889.23 includesubdomains",
130 &max_age, &include_subdomains));
131 EXPECT_FALSE(ParseHSTSHeader("max-age=34889 includesubdomains",
132 &max_age, &include_subdomains));
133 EXPECT_FALSE(ParseHSTSHeader(";;;; ;;;",
134 &max_age, &include_subdomains));
135 EXPECT_FALSE(ParseHSTSHeader(";;;; includeSubDomains;;;",
136 &max_age, &include_subdomains));
137 EXPECT_FALSE(ParseHSTSHeader(" includeSubDomains; ",
138 &max_age, &include_subdomains));
139 EXPECT_FALSE(ParseHSTSHeader(";",
140 &max_age, &include_subdomains));
141 EXPECT_FALSE(ParseHSTSHeader("max-age; ;",
142 &max_age, &include_subdomains));
144 // Check the out args were not updated by checking the default
145 // values for its predictable fields.
146 EXPECT_EQ(0, max_age.InSeconds());
147 EXPECT_FALSE(include_subdomains);
150 static void TestBogusPinsHeaders(HashValueTag tag) {
151 base::TimeDelta max_age;
152 bool include_subdomains;
153 HashValueVector hashes;
154 HashValueVector chain_hashes;
156 // Set some fake "chain" hashes
157 chain_hashes.push_back(GetTestHashValue(1, tag));
158 chain_hashes.push_back(GetTestHashValue(2, tag));
159 chain_hashes.push_back(GetTestHashValue(3, tag));
161 // The good pin must be in the chain, the backup pin must not be
162 std::string good_pin = GetTestPin(2, tag);
163 std::string good_pin_unquoted = GetTestPinUnquoted(2, tag);
164 std::string backup_pin = GetTestPin(4, tag);
166 EXPECT_FALSE(ParseHPKPHeader(std::string(), chain_hashes, &max_age,
167 &include_subdomains, &hashes));
168 EXPECT_FALSE(ParseHPKPHeader(" ", chain_hashes, &max_age,
169 &include_subdomains, &hashes));
170 EXPECT_FALSE(ParseHPKPHeader("abc", chain_hashes, &max_age,
171 &include_subdomains, &hashes));
172 EXPECT_FALSE(ParseHPKPHeader(" abc", chain_hashes, &max_age,
173 &include_subdomains, &hashes));
174 EXPECT_FALSE(ParseHPKPHeader(" abc ", chain_hashes, &max_age,
175 &include_subdomains, &hashes));
176 EXPECT_FALSE(ParseHPKPHeader("max-age", chain_hashes, &max_age,
177 &include_subdomains, &hashes));
178 EXPECT_FALSE(ParseHPKPHeader(" max-age", chain_hashes, &max_age,
179 &include_subdomains, &hashes));
180 EXPECT_FALSE(ParseHPKPHeader(" max-age ", chain_hashes, &max_age,
181 &include_subdomains, &hashes));
182 EXPECT_FALSE(ParseHPKPHeader("max-age=", chain_hashes, &max_age,
183 &include_subdomains, &hashes));
184 EXPECT_FALSE(ParseHPKPHeader(" max-age=", chain_hashes, &max_age,
185 &include_subdomains, &hashes));
186 EXPECT_FALSE(ParseHPKPHeader(" max-age =", chain_hashes, &max_age,
187 &include_subdomains, &hashes));
188 EXPECT_FALSE(ParseHPKPHeader(" max-age= ", chain_hashes, &max_age,
189 &include_subdomains, &hashes));
190 EXPECT_FALSE(ParseHPKPHeader(" max-age = ", chain_hashes,
191 &max_age, &include_subdomains, &hashes));
192 EXPECT_FALSE(ParseHPKPHeader(" max-age = xy", chain_hashes,
193 &max_age, &include_subdomains, &hashes));
194 EXPECT_FALSE(ParseHPKPHeader(" max-age = 3488a923",
195 chain_hashes, &max_age, &include_subdomains,
196 &hashes));
197 EXPECT_FALSE(ParseHPKPHeader("max-age=3488a923 ", chain_hashes,
198 &max_age, &include_subdomains, &hashes));
199 EXPECT_FALSE(ParseHPKPHeader("max-ag=3488923pins=" + good_pin + "," +
200 backup_pin,
201 chain_hashes, &max_age, &include_subdomains,
202 &hashes));
203 EXPECT_FALSE(ParseHPKPHeader("max-aged=3488923" + backup_pin,
204 chain_hashes, &max_age, &include_subdomains,
205 &hashes));
206 EXPECT_FALSE(ParseHPKPHeader("max-aged=3488923; " + backup_pin,
207 chain_hashes, &max_age, &include_subdomains,
208 &hashes));
209 EXPECT_FALSE(ParseHPKPHeader("max-aged=3488923; " + backup_pin + ";" +
210 backup_pin,
211 chain_hashes, &max_age, &include_subdomains,
212 &hashes));
213 EXPECT_FALSE(ParseHPKPHeader("max-aged=3488923; " + good_pin + ";" +
214 good_pin,
215 chain_hashes, &max_age, &include_subdomains,
216 &hashes));
217 EXPECT_FALSE(ParseHPKPHeader("max-aged=3488923; " + good_pin,
218 chain_hashes, &max_age, &include_subdomains,
219 &hashes));
220 EXPECT_FALSE(ParseHPKPHeader("max-age==3488923", chain_hashes, &max_age,
221 &include_subdomains, &hashes));
222 EXPECT_FALSE(ParseHPKPHeader("amax-age=3488923", chain_hashes, &max_age,
223 &include_subdomains, &hashes));
224 EXPECT_FALSE(ParseHPKPHeader("max-age=-3488923", chain_hashes, &max_age,
225 &include_subdomains, &hashes));
226 EXPECT_FALSE(ParseHPKPHeader("max-age=3488923;", chain_hashes, &max_age,
227 &include_subdomains, &hashes));
228 EXPECT_FALSE(ParseHPKPHeader("max-age=3488923 e", chain_hashes,
229 &max_age, &include_subdomains, &hashes));
230 EXPECT_FALSE(ParseHPKPHeader("max-age=3488923 includesubdomain",
231 chain_hashes, &max_age, &include_subdomains,
232 &hashes));
233 EXPECT_FALSE(ParseHPKPHeader("max-age=34889.23", chain_hashes, &max_age,
234 &include_subdomains, &hashes));
235 EXPECT_FALSE(
236 ParseHPKPHeader("max-age=243; " + good_pin_unquoted + ";" + backup_pin,
237 chain_hashes, &max_age, &include_subdomains, &hashes));
239 // Check the out args were not updated by checking the default
240 // values for its predictable fields.
241 EXPECT_EQ(0, max_age.InSeconds());
242 EXPECT_EQ(hashes.size(), (size_t)0);
245 TEST_F(HttpSecurityHeadersTest, ValidSTSHeaders) {
246 base::TimeDelta max_age;
247 base::TimeDelta expect_max_age;
248 bool include_subdomains = false;
250 EXPECT_TRUE(ParseHSTSHeader("max-age=243", &max_age,
251 &include_subdomains));
252 expect_max_age = base::TimeDelta::FromSeconds(243);
253 EXPECT_EQ(expect_max_age, max_age);
254 EXPECT_FALSE(include_subdomains);
256 EXPECT_TRUE(ParseHSTSHeader("max-age=3488923;", &max_age,
257 &include_subdomains));
259 EXPECT_TRUE(ParseHSTSHeader(" Max-agE = 567", &max_age,
260 &include_subdomains));
261 expect_max_age = base::TimeDelta::FromSeconds(567);
262 EXPECT_EQ(expect_max_age, max_age);
263 EXPECT_FALSE(include_subdomains);
265 EXPECT_TRUE(ParseHSTSHeader(" mAx-aGe = 890 ", &max_age,
266 &include_subdomains));
267 expect_max_age = base::TimeDelta::FromSeconds(890);
268 EXPECT_EQ(expect_max_age, max_age);
269 EXPECT_FALSE(include_subdomains);
271 EXPECT_TRUE(ParseHSTSHeader("max-age=123;incLudesUbdOmains", &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);
277 EXPECT_TRUE(ParseHSTSHeader("incLudesUbdOmains; max-age=123", &max_age,
278 &include_subdomains));
279 expect_max_age = base::TimeDelta::FromSeconds(123);
280 EXPECT_EQ(expect_max_age, max_age);
281 EXPECT_TRUE(include_subdomains);
283 EXPECT_TRUE(ParseHSTSHeader(" incLudesUbdOmains; max-age=123",
284 &max_age, &include_subdomains));
285 expect_max_age = base::TimeDelta::FromSeconds(123);
286 EXPECT_EQ(expect_max_age, max_age);
287 EXPECT_TRUE(include_subdomains);
289 EXPECT_TRUE(ParseHSTSHeader(
290 " incLudesUbdOmains; max-age=123; pumpkin=kitten", &max_age,
291 &include_subdomains));
292 expect_max_age = base::TimeDelta::FromSeconds(123);
293 EXPECT_EQ(expect_max_age, max_age);
294 EXPECT_TRUE(include_subdomains);
296 EXPECT_TRUE(ParseHSTSHeader(
297 " pumpkin=894; incLudesUbdOmains; max-age=123 ", &max_age,
298 &include_subdomains));
299 expect_max_age = base::TimeDelta::FromSeconds(123);
300 EXPECT_EQ(expect_max_age, max_age);
301 EXPECT_TRUE(include_subdomains);
303 EXPECT_TRUE(ParseHSTSHeader(
304 " pumpkin; incLudesUbdOmains; max-age=123 ", &max_age,
305 &include_subdomains));
306 expect_max_age = base::TimeDelta::FromSeconds(123);
307 EXPECT_EQ(expect_max_age, max_age);
308 EXPECT_TRUE(include_subdomains);
310 EXPECT_TRUE(ParseHSTSHeader(
311 " pumpkin; incLudesUbdOmains; max-age=\"123\" ", &max_age,
312 &include_subdomains));
313 expect_max_age = base::TimeDelta::FromSeconds(123);
314 EXPECT_EQ(expect_max_age, max_age);
315 EXPECT_TRUE(include_subdomains);
317 EXPECT_TRUE(ParseHSTSHeader(
318 "animal=\"squirrel; distinguished\"; incLudesUbdOmains; max-age=123",
319 &max_age, &include_subdomains));
320 expect_max_age = base::TimeDelta::FromSeconds(123);
321 EXPECT_EQ(expect_max_age, max_age);
322 EXPECT_TRUE(include_subdomains);
324 EXPECT_TRUE(ParseHSTSHeader("max-age=394082; incLudesUbdOmains",
325 &max_age, &include_subdomains));
326 expect_max_age = base::TimeDelta::FromSeconds(394082);
327 EXPECT_EQ(expect_max_age, max_age);
328 EXPECT_TRUE(include_subdomains);
330 EXPECT_TRUE(ParseHSTSHeader(
331 "max-age=39408299 ;incLudesUbdOmains", &max_age,
332 &include_subdomains));
333 expect_max_age = base::TimeDelta::FromSeconds(
334 std::min(kMaxHSTSAgeSecs, static_cast<int64>(INT64_C(39408299))));
335 EXPECT_EQ(expect_max_age, max_age);
336 EXPECT_TRUE(include_subdomains);
338 EXPECT_TRUE(ParseHSTSHeader(
339 "max-age=394082038 ; incLudesUbdOmains", &max_age,
340 &include_subdomains));
341 expect_max_age = base::TimeDelta::FromSeconds(
342 std::min(kMaxHSTSAgeSecs, static_cast<int64>(INT64_C(394082038))));
343 EXPECT_EQ(expect_max_age, max_age);
344 EXPECT_TRUE(include_subdomains);
346 EXPECT_TRUE(ParseHSTSHeader(
347 "max-age=394082038 ; incLudesUbdOmains;", &max_age,
348 &include_subdomains));
349 expect_max_age = base::TimeDelta::FromSeconds(
350 std::min(kMaxHSTSAgeSecs, static_cast<int64>(INT64_C(394082038))));
351 EXPECT_EQ(expect_max_age, max_age);
352 EXPECT_TRUE(include_subdomains);
354 EXPECT_TRUE(ParseHSTSHeader(
355 ";; max-age=394082038 ; incLudesUbdOmains; ;", &max_age,
356 &include_subdomains));
357 expect_max_age = base::TimeDelta::FromSeconds(
358 std::min(kMaxHSTSAgeSecs, static_cast<int64>(INT64_C(394082038))));
359 EXPECT_EQ(expect_max_age, max_age);
360 EXPECT_TRUE(include_subdomains);
362 EXPECT_TRUE(ParseHSTSHeader(
363 ";; max-age=394082038 ;", &max_age,
364 &include_subdomains));
365 expect_max_age = base::TimeDelta::FromSeconds(
366 std::min(kMaxHSTSAgeSecs, static_cast<int64>(INT64_C(394082038))));
367 EXPECT_EQ(expect_max_age, max_age);
368 EXPECT_FALSE(include_subdomains);
370 EXPECT_TRUE(ParseHSTSHeader(
371 ";; ; ; max-age=394082038;;; includeSubdomains ;; ;", &max_age,
372 &include_subdomains));
373 expect_max_age = base::TimeDelta::FromSeconds(
374 std::min(kMaxHSTSAgeSecs, static_cast<int64>(INT64_C(394082038))));
375 EXPECT_EQ(expect_max_age, max_age);
376 EXPECT_TRUE(include_subdomains);
378 EXPECT_TRUE(ParseHSTSHeader(
379 "incLudesUbdOmains ; max-age=394082038 ;;", &max_age,
380 &include_subdomains));
381 expect_max_age = base::TimeDelta::FromSeconds(
382 std::min(kMaxHSTSAgeSecs, static_cast<int64>(INT64_C(394082038))));
383 EXPECT_EQ(expect_max_age, max_age);
384 EXPECT_TRUE(include_subdomains);
386 EXPECT_TRUE(ParseHSTSHeader(
387 " max-age=0 ; incLudesUbdOmains ", &max_age,
388 &include_subdomains));
389 expect_max_age = base::TimeDelta::FromSeconds(0);
390 EXPECT_EQ(expect_max_age, max_age);
391 EXPECT_TRUE(include_subdomains);
393 EXPECT_TRUE(ParseHSTSHeader(
394 " max-age=999999999999999999999999999999999999999999999 ;"
395 " incLudesUbdOmains ", &max_age, &include_subdomains));
396 expect_max_age = base::TimeDelta::FromSeconds(
397 kMaxHSTSAgeSecs);
398 EXPECT_EQ(expect_max_age, max_age);
399 EXPECT_TRUE(include_subdomains);
402 static void TestValidPKPHeaders(HashValueTag tag) {
403 base::TimeDelta max_age;
404 base::TimeDelta expect_max_age;
405 bool include_subdomains;
406 HashValueVector hashes;
407 HashValueVector chain_hashes;
409 // Set some fake "chain" hashes into chain_hashes
410 chain_hashes.push_back(GetTestHashValue(1, tag));
411 chain_hashes.push_back(GetTestHashValue(2, tag));
412 chain_hashes.push_back(GetTestHashValue(3, tag));
414 // The good pin must be in the chain, the backup pin must not be
415 std::string good_pin = GetTestPin(2, tag);
416 std::string good_pin2 = GetTestPin(3, tag);
417 std::string backup_pin = GetTestPin(4, tag);
419 EXPECT_TRUE(ParseHPKPHeader(
420 "max-age=243; " + good_pin + ";" + backup_pin,
421 chain_hashes, &max_age, &include_subdomains, &hashes));
422 expect_max_age = base::TimeDelta::FromSeconds(243);
423 EXPECT_EQ(expect_max_age, max_age);
424 EXPECT_FALSE(include_subdomains);
426 EXPECT_TRUE(ParseHPKPHeader(
427 " " + good_pin + "; " + backup_pin + " ; Max-agE = 567",
428 chain_hashes, &max_age, &include_subdomains, &hashes));
429 expect_max_age = base::TimeDelta::FromSeconds(567);
430 EXPECT_EQ(expect_max_age, max_age);
431 EXPECT_FALSE(include_subdomains);
433 EXPECT_TRUE(ParseHPKPHeader(
434 "includeSubDOMAINS;" + good_pin + ";" + backup_pin +
435 " ; mAx-aGe = 890 ",
436 chain_hashes, &max_age, &include_subdomains, &hashes));
437 expect_max_age = base::TimeDelta::FromSeconds(890);
438 EXPECT_EQ(expect_max_age, max_age);
439 EXPECT_TRUE(include_subdomains);
441 EXPECT_TRUE(ParseHPKPHeader(
442 good_pin + ";" + backup_pin + "; max-age=123;IGNORED;",
443 chain_hashes, &max_age, &include_subdomains, &hashes));
444 expect_max_age = base::TimeDelta::FromSeconds(123);
445 EXPECT_EQ(expect_max_age, max_age);
446 EXPECT_FALSE(include_subdomains);
448 EXPECT_TRUE(ParseHPKPHeader(
449 "max-age=394082;" + backup_pin + ";" + good_pin + "; ",
450 chain_hashes, &max_age, &include_subdomains, &hashes));
451 expect_max_age = base::TimeDelta::FromSeconds(394082);
452 EXPECT_EQ(expect_max_age, max_age);
453 EXPECT_FALSE(include_subdomains);
455 EXPECT_TRUE(ParseHPKPHeader(
456 "max-age=39408299 ;" + backup_pin + ";" + good_pin + "; ",
457 chain_hashes, &max_age, &include_subdomains, &hashes));
458 expect_max_age = base::TimeDelta::FromSeconds(
459 std::min(kMaxHSTSAgeSecs, static_cast<int64>(INT64_C(39408299))));
460 EXPECT_EQ(expect_max_age, max_age);
461 EXPECT_FALSE(include_subdomains);
463 EXPECT_TRUE(ParseHPKPHeader(
464 "max-age=39408038 ; cybers=39408038 ; includeSubdomains; " +
465 good_pin + ";" + backup_pin + "; ",
466 chain_hashes, &max_age, &include_subdomains, &hashes));
467 expect_max_age = base::TimeDelta::FromSeconds(
468 std::min(kMaxHSTSAgeSecs, static_cast<int64>(INT64_C(394082038))));
469 EXPECT_EQ(expect_max_age, max_age);
470 EXPECT_TRUE(include_subdomains);
472 EXPECT_TRUE(ParseHPKPHeader(
473 " max-age=0 ; " + good_pin + ";" + backup_pin,
474 chain_hashes, &max_age, &include_subdomains, &hashes));
475 expect_max_age = base::TimeDelta::FromSeconds(0);
476 EXPECT_EQ(expect_max_age, max_age);
477 EXPECT_FALSE(include_subdomains);
479 EXPECT_TRUE(ParseHPKPHeader(
480 " max-age=0 ; includeSubdomains; " + good_pin + ";" + backup_pin,
481 chain_hashes, &max_age, &include_subdomains, &hashes));
482 expect_max_age = base::TimeDelta::FromSeconds(0);
483 EXPECT_EQ(expect_max_age, max_age);
484 EXPECT_TRUE(include_subdomains);
486 EXPECT_TRUE(ParseHPKPHeader(
487 " max-age=999999999999999999999999999999999999999999999 ; " +
488 backup_pin + ";" + good_pin + "; ",
489 chain_hashes, &max_age, &include_subdomains, &hashes));
490 expect_max_age = base::TimeDelta::FromSeconds(kMaxHSTSAgeSecs);
491 EXPECT_EQ(expect_max_age, max_age);
492 EXPECT_FALSE(include_subdomains);
494 // Test that parsing a different header resets the hashes.
495 hashes.clear();
496 EXPECT_TRUE(ParseHPKPHeader(
497 " max-age=999; " +
498 backup_pin + ";" + good_pin + "; ",
499 chain_hashes, &max_age, &include_subdomains, &hashes));
500 EXPECT_EQ(2u, hashes.size());
501 EXPECT_TRUE(ParseHPKPHeader(
502 " max-age=999; " + backup_pin + ";" + good_pin2 + "; ", chain_hashes,
503 &max_age, &include_subdomains, &hashes));
504 EXPECT_EQ(2u, hashes.size());
507 TEST_F(HttpSecurityHeadersTest, BogusPinsHeadersSHA1) {
508 TestBogusPinsHeaders(HASH_VALUE_SHA1);
511 TEST_F(HttpSecurityHeadersTest, BogusPinsHeadersSHA256) {
512 TestBogusPinsHeaders(HASH_VALUE_SHA256);
515 TEST_F(HttpSecurityHeadersTest, ValidPKPHeadersSHA1) {
516 TestValidPKPHeaders(HASH_VALUE_SHA1);
519 TEST_F(HttpSecurityHeadersTest, ValidPKPHeadersSHA256) {
520 TestValidPKPHeaders(HASH_VALUE_SHA256);
523 TEST_F(HttpSecurityHeadersTest, UpdateDynamicPKPOnly) {
524 TransportSecurityState state;
525 TransportSecurityState::DomainState static_domain_state;
527 // docs.google.com has preloaded pins.
528 std::string domain = "docs.google.com";
529 state.enable_static_pins_ = true;
530 EXPECT_TRUE(
531 state.GetStaticDomainState(domain, &static_domain_state));
532 EXPECT_GT(static_domain_state.pkp.spki_hashes.size(), 1UL);
533 HashValueVector saved_hashes = static_domain_state.pkp.spki_hashes;
535 // Add a header, which should only update the dynamic state.
536 HashValue good_hash = GetTestHashValue(1, HASH_VALUE_SHA1);
537 HashValue backup_hash = GetTestHashValue(2, HASH_VALUE_SHA1);
538 std::string good_pin = GetTestPin(1, HASH_VALUE_SHA1);
539 std::string backup_pin = GetTestPin(2, HASH_VALUE_SHA1);
540 std::string header = "max-age = 10000; " + good_pin + "; " + backup_pin;
542 // Construct a fake SSLInfo that will pass AddHPKPHeader's checks.
543 SSLInfo ssl_info;
544 ssl_info.public_key_hashes.push_back(good_hash);
545 ssl_info.public_key_hashes.push_back(saved_hashes[0]);
546 EXPECT_TRUE(state.AddHPKPHeader(domain, header, ssl_info));
548 // Expect the static state to remain unchanged.
549 TransportSecurityState::DomainState new_static_domain_state;
550 EXPECT_TRUE(state.GetStaticDomainState(
551 domain, &new_static_domain_state));
552 for (size_t i = 0; i < saved_hashes.size(); ++i) {
553 EXPECT_TRUE(HashValuesEqual(saved_hashes[i])(
554 new_static_domain_state.pkp.spki_hashes[i]));
557 // Expect the dynamic state to reflect the header.
558 TransportSecurityState::DomainState dynamic_domain_state;
559 EXPECT_TRUE(state.GetDynamicDomainState(domain, &dynamic_domain_state));
560 EXPECT_EQ(2UL, dynamic_domain_state.pkp.spki_hashes.size());
562 HashValueVector::const_iterator hash =
563 std::find_if(dynamic_domain_state.pkp.spki_hashes.begin(),
564 dynamic_domain_state.pkp.spki_hashes.end(),
565 HashValuesEqual(good_hash));
566 EXPECT_NE(dynamic_domain_state.pkp.spki_hashes.end(), hash);
568 hash = std::find_if(dynamic_domain_state.pkp.spki_hashes.begin(),
569 dynamic_domain_state.pkp.spki_hashes.end(),
570 HashValuesEqual(backup_hash));
571 EXPECT_NE(dynamic_domain_state.pkp.spki_hashes.end(), hash);
573 // Expect the overall state to reflect the header, too.
574 EXPECT_TRUE(state.HasPublicKeyPins(domain));
575 HashValueVector hashes;
576 hashes.push_back(good_hash);
577 std::string failure_log;
578 const bool is_issued_by_known_root = true;
579 EXPECT_TRUE(state.CheckPublicKeyPins(
580 domain, is_issued_by_known_root, hashes, &failure_log));
582 TransportSecurityState::DomainState new_dynamic_domain_state;
583 EXPECT_TRUE(state.GetDynamicDomainState(domain, &new_dynamic_domain_state));
584 EXPECT_EQ(2UL, new_dynamic_domain_state.pkp.spki_hashes.size());
586 hash = std::find_if(new_dynamic_domain_state.pkp.spki_hashes.begin(),
587 new_dynamic_domain_state.pkp.spki_hashes.end(),
588 HashValuesEqual(good_hash));
589 EXPECT_NE(new_dynamic_domain_state.pkp.spki_hashes.end(), hash);
591 hash = std::find_if(new_dynamic_domain_state.pkp.spki_hashes.begin(),
592 new_dynamic_domain_state.pkp.spki_hashes.end(),
593 HashValuesEqual(backup_hash));
594 EXPECT_NE(new_dynamic_domain_state.pkp.spki_hashes.end(), hash);
597 TEST_F(HttpSecurityHeadersTest, UpdateDynamicPKPMaxAge0) {
598 TransportSecurityState state;
599 TransportSecurityState::DomainState static_domain_state;
601 // docs.google.com has preloaded pins.
602 std::string domain = "docs.google.com";
603 state.enable_static_pins_ = true;
604 ASSERT_TRUE(
605 state.GetStaticDomainState(domain, &static_domain_state));
606 EXPECT_GT(static_domain_state.pkp.spki_hashes.size(), 1UL);
607 HashValueVector saved_hashes = static_domain_state.pkp.spki_hashes;
609 // Add a header, which should only update the dynamic state.
610 HashValue good_hash = GetTestHashValue(1, HASH_VALUE_SHA1);
611 std::string good_pin = GetTestPin(1, HASH_VALUE_SHA1);
612 std::string backup_pin = GetTestPin(2, HASH_VALUE_SHA1);
613 std::string header = "max-age = 10000; " + good_pin + "; " + backup_pin;
615 // Construct a fake SSLInfo that will pass AddHPKPHeader's checks.
616 SSLInfo ssl_info;
617 ssl_info.public_key_hashes.push_back(good_hash);
618 ssl_info.public_key_hashes.push_back(saved_hashes[0]);
619 EXPECT_TRUE(state.AddHPKPHeader(domain, header, ssl_info));
621 // Expect the static state to remain unchanged.
622 TransportSecurityState::DomainState new_static_domain_state;
623 EXPECT_TRUE(state.GetStaticDomainState(
624 domain, &new_static_domain_state));
625 EXPECT_EQ(saved_hashes.size(),
626 new_static_domain_state.pkp.spki_hashes.size());
627 for (size_t i = 0; i < saved_hashes.size(); ++i) {
628 EXPECT_TRUE(HashValuesEqual(saved_hashes[i])(
629 new_static_domain_state.pkp.spki_hashes[i]));
632 // Expect the dynamic state to have pins.
633 TransportSecurityState::DomainState new_dynamic_domain_state;
634 EXPECT_TRUE(state.GetDynamicDomainState(domain, &new_dynamic_domain_state));
635 EXPECT_EQ(2UL, new_dynamic_domain_state.pkp.spki_hashes.size());
636 EXPECT_TRUE(new_dynamic_domain_state.HasPublicKeyPins());
638 // Now set another header with max-age=0, and check that the pins are
639 // cleared in the dynamic state only.
640 header = "max-age = 0; " + good_pin + "; " + backup_pin;
641 EXPECT_TRUE(state.AddHPKPHeader(domain, header, ssl_info));
643 // Expect the static state to remain unchanged.
644 TransportSecurityState::DomainState new_static_domain_state2;
645 EXPECT_TRUE(state.GetStaticDomainState(
646 domain, &new_static_domain_state2));
647 EXPECT_EQ(saved_hashes.size(),
648 new_static_domain_state2.pkp.spki_hashes.size());
649 for (size_t i = 0; i < saved_hashes.size(); ++i) {
650 EXPECT_TRUE(HashValuesEqual(saved_hashes[i])(
651 new_static_domain_state2.pkp.spki_hashes[i]));
654 // Expect the dynamic pins to be gone.
655 TransportSecurityState::DomainState new_dynamic_domain_state2;
656 EXPECT_FALSE(state.GetDynamicDomainState(domain, &new_dynamic_domain_state2));
658 // Expect the exact-matching static policy to continue to apply, even
659 // though dynamic policy has been removed. (This policy may change in the
660 // future, in which case this test must be updated.)
661 EXPECT_TRUE(state.HasPublicKeyPins(domain));
662 EXPECT_TRUE(state.ShouldSSLErrorsBeFatal(domain));
663 std::string failure_log;
664 // Damage the hashes to cause a pin validation failure.
665 new_static_domain_state2.pkp.spki_hashes[0].data()[0] ^= 0x80;
666 new_static_domain_state2.pkp.spki_hashes[1].data()[0] ^= 0x80;
667 new_static_domain_state2.pkp.spki_hashes[2].data()[0] ^= 0x80;
668 const bool is_issued_by_known_root = true;
669 EXPECT_FALSE(
670 state.CheckPublicKeyPins(domain,
671 is_issued_by_known_root,
672 new_static_domain_state2.pkp.spki_hashes,
673 &failure_log));
674 EXPECT_NE(0UL, failure_log.length());
677 // Tests that when a static HSTS and a static HPKP entry are present, adding a
678 // dynamic HSTS header does not clobber the static HPKP entry. Further, adding a
679 // dynamic HPKP entry could not affect the HSTS entry for the site.
680 TEST_F(HttpSecurityHeadersTest, NoClobberPins) {
681 TransportSecurityState state;
682 TransportSecurityState::DomainState domain_state;
684 // accounts.google.com has preloaded pins.
685 std::string domain = "accounts.google.com";
686 state.enable_static_pins_ = true;
688 // Retrieve the DomainState as it is by default, including its known good
689 // pins.
690 EXPECT_TRUE(state.GetStaticDomainState(domain, &domain_state));
691 HashValueVector saved_hashes = domain_state.pkp.spki_hashes;
692 EXPECT_TRUE(domain_state.ShouldUpgradeToSSL());
693 EXPECT_TRUE(domain_state.HasPublicKeyPins());
694 EXPECT_TRUE(state.ShouldUpgradeToSSL(domain));
695 EXPECT_TRUE(state.HasPublicKeyPins(domain));
697 // Add a dynamic HSTS header. CheckPublicKeyPins should still pass when given
698 // the original |saved_hashes|, indicating that the static PKP data is still
699 // configured for the domain.
700 EXPECT_TRUE(state.AddHSTSHeader(domain, "includesubdomains; max-age=10000"));
701 EXPECT_TRUE(state.ShouldUpgradeToSSL(domain));
702 std::string failure_log;
703 const bool is_issued_by_known_root = true;
704 EXPECT_TRUE(state.CheckPublicKeyPins(domain,
705 is_issued_by_known_root,
706 saved_hashes,
707 &failure_log));
709 // Add an HPKP header, which should only update the dynamic state.
710 HashValue good_hash = GetTestHashValue(1, HASH_VALUE_SHA1);
711 std::string good_pin = GetTestPin(1, HASH_VALUE_SHA1);
712 std::string backup_pin = GetTestPin(2, HASH_VALUE_SHA1);
713 std::string header = "max-age = 10000; " + good_pin + "; " + backup_pin;
715 // Construct a fake SSLInfo that will pass AddHPKPHeader's checks.
716 SSLInfo ssl_info;
717 ssl_info.public_key_hashes.push_back(good_hash);
718 ssl_info.public_key_hashes.push_back(saved_hashes[0]);
719 EXPECT_TRUE(state.AddHPKPHeader(domain, header, ssl_info));
721 EXPECT_TRUE(state.AddHPKPHeader(domain, header, ssl_info));
722 // HSTS should still be configured for this domain.
723 EXPECT_TRUE(domain_state.ShouldUpgradeToSSL());
724 EXPECT_TRUE(state.ShouldUpgradeToSSL(domain));
725 // The dynamic pins, which do not match |saved_hashes|, should take
726 // precedence over the static pins and cause the check to fail.
727 EXPECT_FALSE(state.CheckPublicKeyPins(domain,
728 is_issued_by_known_root,
729 saved_hashes,
730 &failure_log));
733 // Tests that seeing an invalid HPKP header leaves the existing one alone.
734 TEST_F(HttpSecurityHeadersTest, IgnoreInvalidHeaders) {
735 TransportSecurityState state;
737 HashValue good_hash = GetTestHashValue(1, HASH_VALUE_SHA256);
738 std::string good_pin = GetTestPin(1, HASH_VALUE_SHA256);
739 std::string bad_pin = GetTestPin(2, HASH_VALUE_SHA256);
740 std::string backup_pin = GetTestPin(3, HASH_VALUE_SHA256);
742 SSLInfo ssl_info;
743 ssl_info.public_key_hashes.push_back(good_hash);
745 // Add a valid HPKP header.
746 EXPECT_TRUE(state.AddHPKPHeader(
747 "example.com", "max-age = 10000; " + good_pin + "; " + backup_pin,
748 ssl_info));
750 // Check the insertion was valid.
751 EXPECT_TRUE(state.HasPublicKeyPins("example.com"));
752 std::string failure_log;
753 bool is_issued_by_known_root = true;
754 EXPECT_TRUE(state.CheckPublicKeyPins("example.com", is_issued_by_known_root,
755 ssl_info.public_key_hashes,
756 &failure_log));
758 // Now assert an invalid one. This should fail.
759 EXPECT_FALSE(state.AddHPKPHeader(
760 "example.com", "max-age = 10000; " + bad_pin + "; " + backup_pin,
761 ssl_info));
763 // The old pins must still exist.
764 EXPECT_TRUE(state.HasPublicKeyPins("example.com"));
765 EXPECT_TRUE(state.CheckPublicKeyPins("example.com", is_issued_by_known_root,
766 ssl_info.public_key_hashes,
767 &failure_log));
770 }; // namespace net