Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(337)

Side by Side Diff: net/http/http_security_headers_unittest.cc

Issue 992733002: Remove //net (except for Android test stuff) and sdch (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/http/http_security_headers.cc ('k') | net/http/http_server_properties.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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 GetTestPinImpl(uint8 label, HashValueTag tag, bool quoted) {
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 std::string ret;
36 switch (hash_value.tag) {
37 case HASH_VALUE_SHA1:
38 ret = "pin-sha1=";
39 break;
40 case HASH_VALUE_SHA256:
41 ret = "pin-sha256=";
42 break;
43 default:
44 NOTREACHED() << "Unknown HashValueTag " << hash_value.tag;
45 return std::string("ERROR");
46 }
47 if (quoted)
48 ret += '\"';
49 ret += base64;
50 if (quoted)
51 ret += '\"';
52 return ret;
53 }
54
55 std::string GetTestPin(uint8 label, HashValueTag tag) {
56 return GetTestPinImpl(label, tag, true);
57 }
58
59 std::string GetTestPinUnquoted(uint8 label, HashValueTag tag) {
60 return GetTestPinImpl(label, tag, false);
61 }
62
63 };
64
65
66 class HttpSecurityHeadersTest : public testing::Test {
67 };
68
69
70 TEST_F(HttpSecurityHeadersTest, BogusHeaders) {
71 base::TimeDelta max_age;
72 bool include_subdomains = false;
73
74 EXPECT_FALSE(
75 ParseHSTSHeader(std::string(), &max_age, &include_subdomains));
76 EXPECT_FALSE(ParseHSTSHeader(" ", &max_age, &include_subdomains));
77 EXPECT_FALSE(ParseHSTSHeader("abc", &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("max-age", &max_age, &include_subdomains));
81 EXPECT_FALSE(ParseHSTSHeader(" max-age", &max_age,
82 &include_subdomains));
83 EXPECT_FALSE(ParseHSTSHeader(" max-age ", &max_age,
84 &include_subdomains));
85 EXPECT_FALSE(ParseHSTSHeader("max-age=", &max_age, &include_subdomains));
86 EXPECT_FALSE(ParseHSTSHeader(" max-age=", &max_age,
87 &include_subdomains));
88 EXPECT_FALSE(ParseHSTSHeader(" max-age =", &max_age,
89 &include_subdomains));
90 EXPECT_FALSE(ParseHSTSHeader(" max-age= ", &max_age,
91 &include_subdomains));
92 EXPECT_FALSE(ParseHSTSHeader(" max-age = ", &max_age,
93 &include_subdomains));
94 EXPECT_FALSE(ParseHSTSHeader(" max-age = xy", &max_age,
95 &include_subdomains));
96 EXPECT_FALSE(ParseHSTSHeader(" max-age = 3488a923", &max_age,
97 &include_subdomains));
98 EXPECT_FALSE(ParseHSTSHeader("max-age=3488a923 ", &max_age,
99 &include_subdomains));
100 EXPECT_FALSE(ParseHSTSHeader("max-ag=3488923", &max_age,
101 &include_subdomains));
102 EXPECT_FALSE(ParseHSTSHeader("max-aged=3488923", &max_age,
103 &include_subdomains));
104 EXPECT_FALSE(ParseHSTSHeader("max-age==3488923", &max_age,
105 &include_subdomains));
106 EXPECT_FALSE(ParseHSTSHeader("amax-age=3488923", &max_age,
107 &include_subdomains));
108 EXPECT_FALSE(ParseHSTSHeader("max-age=-3488923", &max_age,
109 &include_subdomains));
110 EXPECT_FALSE(ParseHSTSHeader("max-age=3488923 e", &max_age,
111 &include_subdomains));
112 EXPECT_FALSE(ParseHSTSHeader("max-age=3488923 includesubdomain",
113 &max_age, &include_subdomains));
114 EXPECT_FALSE(ParseHSTSHeader("max-age=3488923includesubdomains",
115 &max_age, &include_subdomains));
116 EXPECT_FALSE(ParseHSTSHeader("max-age=3488923=includesubdomains",
117 &max_age, &include_subdomains));
118 EXPECT_FALSE(ParseHSTSHeader("max-age=3488923 includesubdomainx",
119 &max_age, &include_subdomains));
120 EXPECT_FALSE(ParseHSTSHeader("max-age=3488923 includesubdomain=",
121 &max_age, &include_subdomains));
122 EXPECT_FALSE(ParseHSTSHeader("max-age=3488923 includesubdomain=true",
123 &max_age, &include_subdomains));
124 EXPECT_FALSE(ParseHSTSHeader("max-age=3488923 includesubdomainsx",
125 &max_age, &include_subdomains));
126 EXPECT_FALSE(ParseHSTSHeader("max-age=3488923 includesubdomains x",
127 &max_age, &include_subdomains));
128 EXPECT_FALSE(ParseHSTSHeader("max-age=34889.23 includesubdomains",
129 &max_age, &include_subdomains));
130 EXPECT_FALSE(ParseHSTSHeader("max-age=34889 includesubdomains",
131 &max_age, &include_subdomains));
132 EXPECT_FALSE(ParseHSTSHeader(";;;; ;;;",
133 &max_age, &include_subdomains));
134 EXPECT_FALSE(ParseHSTSHeader(";;;; includeSubDomains;;;",
135 &max_age, &include_subdomains));
136 EXPECT_FALSE(ParseHSTSHeader(" includeSubDomains; ",
137 &max_age, &include_subdomains));
138 EXPECT_FALSE(ParseHSTSHeader(";",
139 &max_age, &include_subdomains));
140 EXPECT_FALSE(ParseHSTSHeader("max-age; ;",
141 &max_age, &include_subdomains));
142
143 // Check the out args were not updated by checking the default
144 // values for its predictable fields.
145 EXPECT_EQ(0, max_age.InSeconds());
146 EXPECT_FALSE(include_subdomains);
147 }
148
149 static void TestBogusPinsHeaders(HashValueTag tag) {
150 base::TimeDelta max_age;
151 bool include_subdomains;
152 HashValueVector hashes;
153 HashValueVector chain_hashes;
154
155 // Set some fake "chain" hashes
156 chain_hashes.push_back(GetTestHashValue(1, tag));
157 chain_hashes.push_back(GetTestHashValue(2, tag));
158 chain_hashes.push_back(GetTestHashValue(3, tag));
159
160 // The good pin must be in the chain, the backup pin must not be
161 std::string good_pin = GetTestPin(2, tag);
162 std::string good_pin_unquoted = GetTestPinUnquoted(2, tag);
163 std::string backup_pin = GetTestPin(4, tag);
164
165 EXPECT_FALSE(ParseHPKPHeader(std::string(), chain_hashes, &max_age,
166 &include_subdomains, &hashes));
167 EXPECT_FALSE(ParseHPKPHeader(" ", chain_hashes, &max_age,
168 &include_subdomains, &hashes));
169 EXPECT_FALSE(ParseHPKPHeader("abc", chain_hashes, &max_age,
170 &include_subdomains, &hashes));
171 EXPECT_FALSE(ParseHPKPHeader(" abc", chain_hashes, &max_age,
172 &include_subdomains, &hashes));
173 EXPECT_FALSE(ParseHPKPHeader(" abc ", chain_hashes, &max_age,
174 &include_subdomains, &hashes));
175 EXPECT_FALSE(ParseHPKPHeader("max-age", chain_hashes, &max_age,
176 &include_subdomains, &hashes));
177 EXPECT_FALSE(ParseHPKPHeader(" max-age", chain_hashes, &max_age,
178 &include_subdomains, &hashes));
179 EXPECT_FALSE(ParseHPKPHeader(" max-age ", chain_hashes, &max_age,
180 &include_subdomains, &hashes));
181 EXPECT_FALSE(ParseHPKPHeader("max-age=", chain_hashes, &max_age,
182 &include_subdomains, &hashes));
183 EXPECT_FALSE(ParseHPKPHeader(" max-age=", chain_hashes, &max_age,
184 &include_subdomains, &hashes));
185 EXPECT_FALSE(ParseHPKPHeader(" max-age =", chain_hashes, &max_age,
186 &include_subdomains, &hashes));
187 EXPECT_FALSE(ParseHPKPHeader(" max-age= ", chain_hashes, &max_age,
188 &include_subdomains, &hashes));
189 EXPECT_FALSE(ParseHPKPHeader(" max-age = ", chain_hashes,
190 &max_age, &include_subdomains, &hashes));
191 EXPECT_FALSE(ParseHPKPHeader(" max-age = xy", chain_hashes,
192 &max_age, &include_subdomains, &hashes));
193 EXPECT_FALSE(ParseHPKPHeader(" max-age = 3488a923",
194 chain_hashes, &max_age, &include_subdomains,
195 &hashes));
196 EXPECT_FALSE(ParseHPKPHeader("max-age=3488a923 ", chain_hashes,
197 &max_age, &include_subdomains, &hashes));
198 EXPECT_FALSE(ParseHPKPHeader("max-ag=3488923pins=" + good_pin + "," +
199 backup_pin,
200 chain_hashes, &max_age, &include_subdomains,
201 &hashes));
202 EXPECT_FALSE(ParseHPKPHeader("max-aged=3488923" + backup_pin,
203 chain_hashes, &max_age, &include_subdomains,
204 &hashes));
205 EXPECT_FALSE(ParseHPKPHeader("max-aged=3488923; " + backup_pin,
206 chain_hashes, &max_age, &include_subdomains,
207 &hashes));
208 EXPECT_FALSE(ParseHPKPHeader("max-aged=3488923; " + backup_pin + ";" +
209 backup_pin,
210 chain_hashes, &max_age, &include_subdomains,
211 &hashes));
212 EXPECT_FALSE(ParseHPKPHeader("max-aged=3488923; " + good_pin + ";" +
213 good_pin,
214 chain_hashes, &max_age, &include_subdomains,
215 &hashes));
216 EXPECT_FALSE(ParseHPKPHeader("max-aged=3488923; " + good_pin,
217 chain_hashes, &max_age, &include_subdomains,
218 &hashes));
219 EXPECT_FALSE(ParseHPKPHeader("max-age==3488923", chain_hashes, &max_age,
220 &include_subdomains, &hashes));
221 EXPECT_FALSE(ParseHPKPHeader("amax-age=3488923", chain_hashes, &max_age,
222 &include_subdomains, &hashes));
223 EXPECT_FALSE(ParseHPKPHeader("max-age=-3488923", chain_hashes, &max_age,
224 &include_subdomains, &hashes));
225 EXPECT_FALSE(ParseHPKPHeader("max-age=3488923;", chain_hashes, &max_age,
226 &include_subdomains, &hashes));
227 EXPECT_FALSE(ParseHPKPHeader("max-age=3488923 e", chain_hashes,
228 &max_age, &include_subdomains, &hashes));
229 EXPECT_FALSE(ParseHPKPHeader("max-age=3488923 includesubdomain",
230 chain_hashes, &max_age, &include_subdomains,
231 &hashes));
232 EXPECT_FALSE(ParseHPKPHeader("max-age=34889.23", chain_hashes, &max_age,
233 &include_subdomains, &hashes));
234 EXPECT_FALSE(
235 ParseHPKPHeader("max-age=243; " + good_pin_unquoted + ";" + backup_pin,
236 chain_hashes, &max_age, &include_subdomains, &hashes));
237
238 // Check the out args were not updated by checking the default
239 // values for its predictable fields.
240 EXPECT_EQ(0, max_age.InSeconds());
241 EXPECT_EQ(hashes.size(), (size_t)0);
242 }
243
244 TEST_F(HttpSecurityHeadersTest, ValidSTSHeaders) {
245 base::TimeDelta max_age;
246 base::TimeDelta expect_max_age;
247 bool include_subdomains = false;
248
249 EXPECT_TRUE(ParseHSTSHeader("max-age=243", &max_age,
250 &include_subdomains));
251 expect_max_age = base::TimeDelta::FromSeconds(243);
252 EXPECT_EQ(expect_max_age, max_age);
253 EXPECT_FALSE(include_subdomains);
254
255 EXPECT_TRUE(ParseHSTSHeader("max-age=3488923;", &max_age,
256 &include_subdomains));
257
258 EXPECT_TRUE(ParseHSTSHeader(" Max-agE = 567", &max_age,
259 &include_subdomains));
260 expect_max_age = base::TimeDelta::FromSeconds(567);
261 EXPECT_EQ(expect_max_age, max_age);
262 EXPECT_FALSE(include_subdomains);
263
264 EXPECT_TRUE(ParseHSTSHeader(" mAx-aGe = 890 ", &max_age,
265 &include_subdomains));
266 expect_max_age = base::TimeDelta::FromSeconds(890);
267 EXPECT_EQ(expect_max_age, max_age);
268 EXPECT_FALSE(include_subdomains);
269
270 EXPECT_TRUE(ParseHSTSHeader("max-age=123;incLudesUbdOmains", &max_age,
271 &include_subdomains));
272 expect_max_age = base::TimeDelta::FromSeconds(123);
273 EXPECT_EQ(expect_max_age, max_age);
274 EXPECT_TRUE(include_subdomains);
275
276 EXPECT_TRUE(ParseHSTSHeader("incLudesUbdOmains; max-age=123", &max_age,
277 &include_subdomains));
278 expect_max_age = base::TimeDelta::FromSeconds(123);
279 EXPECT_EQ(expect_max_age, max_age);
280 EXPECT_TRUE(include_subdomains);
281
282 EXPECT_TRUE(ParseHSTSHeader(" incLudesUbdOmains; max-age=123",
283 &max_age, &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 " incLudesUbdOmains; max-age=123; pumpkin=kitten", &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 " pumpkin=894; incLudesUbdOmains; max-age=123 ", &max_age,
297 &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(
303 " pumpkin; incLudesUbdOmains; max-age=123 ", &max_age,
304 &include_subdomains));
305 expect_max_age = base::TimeDelta::FromSeconds(123);
306 EXPECT_EQ(expect_max_age, max_age);
307 EXPECT_TRUE(include_subdomains);
308
309 EXPECT_TRUE(ParseHSTSHeader(
310 " pumpkin; incLudesUbdOmains; max-age=\"123\" ", &max_age,
311 &include_subdomains));
312 expect_max_age = base::TimeDelta::FromSeconds(123);
313 EXPECT_EQ(expect_max_age, max_age);
314 EXPECT_TRUE(include_subdomains);
315
316 EXPECT_TRUE(ParseHSTSHeader(
317 "animal=\"squirrel; distinguished\"; incLudesUbdOmains; max-age=123",
318 &max_age, &include_subdomains));
319 expect_max_age = base::TimeDelta::FromSeconds(123);
320 EXPECT_EQ(expect_max_age, max_age);
321 EXPECT_TRUE(include_subdomains);
322
323 EXPECT_TRUE(ParseHSTSHeader("max-age=394082; incLudesUbdOmains",
324 &max_age, &include_subdomains));
325 expect_max_age = base::TimeDelta::FromSeconds(394082);
326 EXPECT_EQ(expect_max_age, max_age);
327 EXPECT_TRUE(include_subdomains);
328
329 EXPECT_TRUE(ParseHSTSHeader(
330 "max-age=39408299 ;incLudesUbdOmains", &max_age,
331 &include_subdomains));
332 expect_max_age = base::TimeDelta::FromSeconds(
333 std::min(kMaxHSTSAgeSecs, static_cast<int64>(GG_INT64_C(39408299))));
334 EXPECT_EQ(expect_max_age, max_age);
335 EXPECT_TRUE(include_subdomains);
336
337 EXPECT_TRUE(ParseHSTSHeader(
338 "max-age=394082038 ; incLudesUbdOmains", &max_age,
339 &include_subdomains));
340 expect_max_age = base::TimeDelta::FromSeconds(
341 std::min(kMaxHSTSAgeSecs, static_cast<int64>(GG_INT64_C(394082038))));
342 EXPECT_EQ(expect_max_age, max_age);
343 EXPECT_TRUE(include_subdomains);
344
345 EXPECT_TRUE(ParseHSTSHeader(
346 "max-age=394082038 ; incLudesUbdOmains;", &max_age,
347 &include_subdomains));
348 expect_max_age = base::TimeDelta::FromSeconds(
349 std::min(kMaxHSTSAgeSecs, static_cast<int64>(GG_INT64_C(394082038))));
350 EXPECT_EQ(expect_max_age, max_age);
351 EXPECT_TRUE(include_subdomains);
352
353 EXPECT_TRUE(ParseHSTSHeader(
354 ";; max-age=394082038 ; incLudesUbdOmains; ;", &max_age,
355 &include_subdomains));
356 expect_max_age = base::TimeDelta::FromSeconds(
357 std::min(kMaxHSTSAgeSecs, static_cast<int64>(GG_INT64_C(394082038))));
358 EXPECT_EQ(expect_max_age, max_age);
359 EXPECT_TRUE(include_subdomains);
360
361 EXPECT_TRUE(ParseHSTSHeader(
362 ";; max-age=394082038 ;", &max_age,
363 &include_subdomains));
364 expect_max_age = base::TimeDelta::FromSeconds(
365 std::min(kMaxHSTSAgeSecs, static_cast<int64>(GG_INT64_C(394082038))));
366 EXPECT_EQ(expect_max_age, max_age);
367 EXPECT_FALSE(include_subdomains);
368
369 EXPECT_TRUE(ParseHSTSHeader(
370 ";; ; ; max-age=394082038;;; includeSubdomains ;; ;", &max_age,
371 &include_subdomains));
372 expect_max_age = base::TimeDelta::FromSeconds(
373 std::min(kMaxHSTSAgeSecs, static_cast<int64>(GG_INT64_C(394082038))));
374 EXPECT_EQ(expect_max_age, max_age);
375 EXPECT_TRUE(include_subdomains);
376
377 EXPECT_TRUE(ParseHSTSHeader(
378 "incLudesUbdOmains ; max-age=394082038 ;;", &max_age,
379 &include_subdomains));
380 expect_max_age = base::TimeDelta::FromSeconds(
381 std::min(kMaxHSTSAgeSecs, static_cast<int64>(GG_INT64_C(394082038))));
382 EXPECT_EQ(expect_max_age, max_age);
383 EXPECT_TRUE(include_subdomains);
384
385 EXPECT_TRUE(ParseHSTSHeader(
386 " max-age=0 ; incLudesUbdOmains ", &max_age,
387 &include_subdomains));
388 expect_max_age = base::TimeDelta::FromSeconds(0);
389 EXPECT_EQ(expect_max_age, max_age);
390 EXPECT_TRUE(include_subdomains);
391
392 EXPECT_TRUE(ParseHSTSHeader(
393 " max-age=999999999999999999999999999999999999999999999 ;"
394 " incLudesUbdOmains ", &max_age, &include_subdomains));
395 expect_max_age = base::TimeDelta::FromSeconds(
396 kMaxHSTSAgeSecs);
397 EXPECT_EQ(expect_max_age, max_age);
398 EXPECT_TRUE(include_subdomains);
399 }
400
401 static void TestValidPKPHeaders(HashValueTag tag) {
402 base::TimeDelta max_age;
403 base::TimeDelta expect_max_age;
404 bool include_subdomains;
405 HashValueVector hashes;
406 HashValueVector chain_hashes;
407
408 // Set some fake "chain" hashes into chain_hashes
409 chain_hashes.push_back(GetTestHashValue(1, tag));
410 chain_hashes.push_back(GetTestHashValue(2, tag));
411 chain_hashes.push_back(GetTestHashValue(3, tag));
412
413 // The good pin must be in the chain, the backup pin must not be
414 std::string good_pin = GetTestPin(2, tag);
415 std::string good_pin2 = GetTestPin(3, tag);
416 std::string backup_pin = GetTestPin(4, tag);
417
418 EXPECT_TRUE(ParseHPKPHeader(
419 "max-age=243; " + good_pin + ";" + backup_pin,
420 chain_hashes, &max_age, &include_subdomains, &hashes));
421 expect_max_age = base::TimeDelta::FromSeconds(243);
422 EXPECT_EQ(expect_max_age, max_age);
423 EXPECT_FALSE(include_subdomains);
424
425 EXPECT_TRUE(ParseHPKPHeader(
426 " " + good_pin + "; " + backup_pin + " ; Max-agE = 567",
427 chain_hashes, &max_age, &include_subdomains, &hashes));
428 expect_max_age = base::TimeDelta::FromSeconds(567);
429 EXPECT_EQ(expect_max_age, max_age);
430 EXPECT_FALSE(include_subdomains);
431
432 EXPECT_TRUE(ParseHPKPHeader(
433 "includeSubDOMAINS;" + good_pin + ";" + backup_pin +
434 " ; mAx-aGe = 890 ",
435 chain_hashes, &max_age, &include_subdomains, &hashes));
436 expect_max_age = base::TimeDelta::FromSeconds(890);
437 EXPECT_EQ(expect_max_age, max_age);
438 EXPECT_TRUE(include_subdomains);
439
440 EXPECT_TRUE(ParseHPKPHeader(
441 good_pin + ";" + backup_pin + "; max-age=123;IGNORED;",
442 chain_hashes, &max_age, &include_subdomains, &hashes));
443 expect_max_age = base::TimeDelta::FromSeconds(123);
444 EXPECT_EQ(expect_max_age, max_age);
445 EXPECT_FALSE(include_subdomains);
446
447 EXPECT_TRUE(ParseHPKPHeader(
448 "max-age=394082;" + backup_pin + ";" + good_pin + "; ",
449 chain_hashes, &max_age, &include_subdomains, &hashes));
450 expect_max_age = base::TimeDelta::FromSeconds(394082);
451 EXPECT_EQ(expect_max_age, max_age);
452 EXPECT_FALSE(include_subdomains);
453
454 EXPECT_TRUE(ParseHPKPHeader(
455 "max-age=39408299 ;" + backup_pin + ";" + good_pin + "; ",
456 chain_hashes, &max_age, &include_subdomains, &hashes));
457 expect_max_age = base::TimeDelta::FromSeconds(
458 std::min(kMaxHSTSAgeSecs, static_cast<int64>(GG_INT64_C(39408299))));
459 EXPECT_EQ(expect_max_age, max_age);
460 EXPECT_FALSE(include_subdomains);
461
462 EXPECT_TRUE(ParseHPKPHeader(
463 "max-age=39408038 ; cybers=39408038 ; includeSubdomains; " +
464 good_pin + ";" + backup_pin + "; ",
465 chain_hashes, &max_age, &include_subdomains, &hashes));
466 expect_max_age = base::TimeDelta::FromSeconds(
467 std::min(kMaxHSTSAgeSecs, static_cast<int64>(GG_INT64_C(394082038))));
468 EXPECT_EQ(expect_max_age, max_age);
469 EXPECT_TRUE(include_subdomains);
470
471 EXPECT_TRUE(ParseHPKPHeader(
472 " max-age=0 ; " + good_pin + ";" + backup_pin,
473 chain_hashes, &max_age, &include_subdomains, &hashes));
474 expect_max_age = base::TimeDelta::FromSeconds(0);
475 EXPECT_EQ(expect_max_age, max_age);
476 EXPECT_FALSE(include_subdomains);
477
478 EXPECT_TRUE(ParseHPKPHeader(
479 " max-age=0 ; includeSubdomains; " + good_pin + ";" + backup_pin,
480 chain_hashes, &max_age, &include_subdomains, &hashes));
481 expect_max_age = base::TimeDelta::FromSeconds(0);
482 EXPECT_EQ(expect_max_age, max_age);
483 EXPECT_TRUE(include_subdomains);
484
485 EXPECT_TRUE(ParseHPKPHeader(
486 " max-age=999999999999999999999999999999999999999999999 ; " +
487 backup_pin + ";" + good_pin + "; ",
488 chain_hashes, &max_age, &include_subdomains, &hashes));
489 expect_max_age = base::TimeDelta::FromSeconds(kMaxHSTSAgeSecs);
490 EXPECT_EQ(expect_max_age, max_age);
491 EXPECT_FALSE(include_subdomains);
492
493 // Test that parsing a different header resets the hashes.
494 hashes.clear();
495 EXPECT_TRUE(ParseHPKPHeader(
496 " max-age=999; " +
497 backup_pin + ";" + good_pin + "; ",
498 chain_hashes, &max_age, &include_subdomains, &hashes));
499 EXPECT_EQ(2u, hashes.size());
500 EXPECT_TRUE(ParseHPKPHeader(
501 " max-age=999; " + backup_pin + ";" + good_pin2 + "; ", chain_hashes,
502 &max_age, &include_subdomains, &hashes));
503 EXPECT_EQ(2u, hashes.size());
504 }
505
506 TEST_F(HttpSecurityHeadersTest, BogusPinsHeadersSHA1) {
507 TestBogusPinsHeaders(HASH_VALUE_SHA1);
508 }
509
510 TEST_F(HttpSecurityHeadersTest, BogusPinsHeadersSHA256) {
511 TestBogusPinsHeaders(HASH_VALUE_SHA256);
512 }
513
514 TEST_F(HttpSecurityHeadersTest, ValidPKPHeadersSHA1) {
515 TestValidPKPHeaders(HASH_VALUE_SHA1);
516 }
517
518 TEST_F(HttpSecurityHeadersTest, ValidPKPHeadersSHA256) {
519 TestValidPKPHeaders(HASH_VALUE_SHA256);
520 }
521
522 TEST_F(HttpSecurityHeadersTest, UpdateDynamicPKPOnly) {
523 TransportSecurityState state;
524 TransportSecurityState::DomainState static_domain_state;
525
526 // docs.google.com has preloaded pins.
527 std::string domain = "docs.google.com";
528 state.enable_static_pins_ = true;
529 EXPECT_TRUE(
530 state.GetStaticDomainState(domain, &static_domain_state));
531 EXPECT_GT(static_domain_state.pkp.spki_hashes.size(), 1UL);
532 HashValueVector saved_hashes = static_domain_state.pkp.spki_hashes;
533
534 // Add a header, which should only update the dynamic state.
535 HashValue good_hash = GetTestHashValue(1, HASH_VALUE_SHA1);
536 HashValue backup_hash = GetTestHashValue(2, HASH_VALUE_SHA1);
537 std::string good_pin = GetTestPin(1, HASH_VALUE_SHA1);
538 std::string backup_pin = GetTestPin(2, HASH_VALUE_SHA1);
539 std::string header = "max-age = 10000; " + good_pin + "; " + backup_pin;
540
541 // Construct a fake SSLInfo that will pass AddHPKPHeader's checks.
542 SSLInfo ssl_info;
543 ssl_info.public_key_hashes.push_back(good_hash);
544 ssl_info.public_key_hashes.push_back(saved_hashes[0]);
545 EXPECT_TRUE(state.AddHPKPHeader(domain, header, ssl_info));
546
547 // Expect the static state to remain unchanged.
548 TransportSecurityState::DomainState new_static_domain_state;
549 EXPECT_TRUE(state.GetStaticDomainState(
550 domain, &new_static_domain_state));
551 for (size_t i = 0; i < saved_hashes.size(); ++i) {
552 EXPECT_TRUE(HashValuesEqual(saved_hashes[i])(
553 new_static_domain_state.pkp.spki_hashes[i]));
554 }
555
556 // Expect the dynamic state to reflect the header.
557 TransportSecurityState::DomainState dynamic_domain_state;
558 EXPECT_TRUE(state.GetDynamicDomainState(domain, &dynamic_domain_state));
559 EXPECT_EQ(2UL, dynamic_domain_state.pkp.spki_hashes.size());
560
561 HashValueVector::const_iterator hash =
562 std::find_if(dynamic_domain_state.pkp.spki_hashes.begin(),
563 dynamic_domain_state.pkp.spki_hashes.end(),
564 HashValuesEqual(good_hash));
565 EXPECT_NE(dynamic_domain_state.pkp.spki_hashes.end(), hash);
566
567 hash = std::find_if(dynamic_domain_state.pkp.spki_hashes.begin(),
568 dynamic_domain_state.pkp.spki_hashes.end(),
569 HashValuesEqual(backup_hash));
570 EXPECT_NE(dynamic_domain_state.pkp.spki_hashes.end(), hash);
571
572 // Expect the overall state to reflect the header, too.
573 EXPECT_TRUE(state.HasPublicKeyPins(domain));
574 HashValueVector hashes;
575 hashes.push_back(good_hash);
576 std::string failure_log;
577 const bool is_issued_by_known_root = true;
578 EXPECT_TRUE(state.CheckPublicKeyPins(
579 domain, is_issued_by_known_root, hashes, &failure_log));
580
581 TransportSecurityState::DomainState new_dynamic_domain_state;
582 EXPECT_TRUE(state.GetDynamicDomainState(domain, &new_dynamic_domain_state));
583 EXPECT_EQ(2UL, new_dynamic_domain_state.pkp.spki_hashes.size());
584
585 hash = std::find_if(new_dynamic_domain_state.pkp.spki_hashes.begin(),
586 new_dynamic_domain_state.pkp.spki_hashes.end(),
587 HashValuesEqual(good_hash));
588 EXPECT_NE(new_dynamic_domain_state.pkp.spki_hashes.end(), hash);
589
590 hash = std::find_if(new_dynamic_domain_state.pkp.spki_hashes.begin(),
591 new_dynamic_domain_state.pkp.spki_hashes.end(),
592 HashValuesEqual(backup_hash));
593 EXPECT_NE(new_dynamic_domain_state.pkp.spki_hashes.end(), hash);
594 }
595
596 // Failing on win_chromium_rel. crbug.com/375538
597 #if defined(OS_WIN)
598 #define MAYBE_UpdateDynamicPKPMaxAge0 DISABLED_UpdateDynamicPKPMaxAge0
599 #else
600 #define MAYBE_UpdateDynamicPKPMaxAge0 UpdateDynamicPKPMaxAge0
601 #endif
602 TEST_F(HttpSecurityHeadersTest, MAYBE_UpdateDynamicPKPMaxAge0) {
603 TransportSecurityState state;
604 TransportSecurityState::DomainState static_domain_state;
605
606 // docs.google.com has preloaded pins.
607 std::string domain = "docs.google.com";
608 state.enable_static_pins_ = true;
609 ASSERT_TRUE(
610 state.GetStaticDomainState(domain, &static_domain_state));
611 EXPECT_GT(static_domain_state.pkp.spki_hashes.size(), 1UL);
612 HashValueVector saved_hashes = static_domain_state.pkp.spki_hashes;
613
614 // Add a header, which should only update the dynamic state.
615 HashValue good_hash = GetTestHashValue(1, HASH_VALUE_SHA1);
616 std::string good_pin = GetTestPin(1, HASH_VALUE_SHA1);
617 std::string backup_pin = GetTestPin(2, HASH_VALUE_SHA1);
618 std::string header = "max-age = 10000; " + good_pin + "; " + backup_pin;
619
620 // Construct a fake SSLInfo that will pass AddHPKPHeader's checks.
621 SSLInfo ssl_info;
622 ssl_info.public_key_hashes.push_back(good_hash);
623 ssl_info.public_key_hashes.push_back(saved_hashes[0]);
624 EXPECT_TRUE(state.AddHPKPHeader(domain, header, ssl_info));
625
626 // Expect the static state to remain unchanged.
627 TransportSecurityState::DomainState new_static_domain_state;
628 EXPECT_TRUE(state.GetStaticDomainState(
629 domain, &new_static_domain_state));
630 EXPECT_EQ(saved_hashes.size(),
631 new_static_domain_state.pkp.spki_hashes.size());
632 for (size_t i = 0; i < saved_hashes.size(); ++i) {
633 EXPECT_TRUE(HashValuesEqual(saved_hashes[i])(
634 new_static_domain_state.pkp.spki_hashes[i]));
635 }
636
637 // Expect the dynamic state to have pins.
638 TransportSecurityState::DomainState new_dynamic_domain_state;
639 EXPECT_TRUE(state.GetDynamicDomainState(domain, &new_dynamic_domain_state));
640 EXPECT_EQ(2UL, new_dynamic_domain_state.pkp.spki_hashes.size());
641 EXPECT_TRUE(new_dynamic_domain_state.HasPublicKeyPins());
642
643 // Now set another header with max-age=0, and check that the pins are
644 // cleared in the dynamic state only.
645 header = "max-age = 0; " + good_pin + "; " + backup_pin;
646 EXPECT_TRUE(state.AddHPKPHeader(domain, header, ssl_info));
647
648 // Expect the static state to remain unchanged.
649 TransportSecurityState::DomainState new_static_domain_state2;
650 EXPECT_TRUE(state.GetStaticDomainState(
651 domain, &new_static_domain_state2));
652 EXPECT_EQ(saved_hashes.size(),
653 new_static_domain_state2.pkp.spki_hashes.size());
654 for (size_t i = 0; i < saved_hashes.size(); ++i) {
655 EXPECT_TRUE(HashValuesEqual(saved_hashes[i])(
656 new_static_domain_state2.pkp.spki_hashes[i]));
657 }
658
659 // Expect the dynamic pins to be gone.
660 TransportSecurityState::DomainState new_dynamic_domain_state2;
661 EXPECT_FALSE(state.GetDynamicDomainState(domain, &new_dynamic_domain_state2));
662
663 // Expect the exact-matching static policy to continue to apply, even
664 // though dynamic policy has been removed. (This policy may change in the
665 // future, in which case this test must be updated.)
666 EXPECT_TRUE(state.HasPublicKeyPins(domain));
667 EXPECT_TRUE(state.ShouldSSLErrorsBeFatal(domain));
668 std::string failure_log;
669 // Damage the hashes to cause a pin validation failure.
670 new_static_domain_state2.pkp.spki_hashes[0].data()[0] ^= 0x80;
671 new_static_domain_state2.pkp.spki_hashes[1].data()[0] ^= 0x80;
672 const bool is_issued_by_known_root = true;
673 EXPECT_FALSE(
674 state.CheckPublicKeyPins(domain,
675 is_issued_by_known_root,
676 new_static_domain_state2.pkp.spki_hashes,
677 &failure_log));
678 EXPECT_NE(0UL, failure_log.length());
679 }
680 #undef MAYBE_UpdateDynamicPKPMaxAge0
681
682 // Tests that when a static HSTS and a static HPKP entry are present, adding a
683 // dynamic HSTS header does not clobber the static HPKP entry. Further, adding a
684 // dynamic HPKP entry could not affect the HSTS entry for the site.
685 TEST_F(HttpSecurityHeadersTest, NoClobberPins) {
686 TransportSecurityState state;
687 TransportSecurityState::DomainState domain_state;
688
689 // accounts.google.com has preloaded pins.
690 std::string domain = "accounts.google.com";
691 state.enable_static_pins_ = true;
692
693 // Retrieve the DomainState as it is by default, including its known good
694 // pins.
695 EXPECT_TRUE(state.GetStaticDomainState(domain, &domain_state));
696 HashValueVector saved_hashes = domain_state.pkp.spki_hashes;
697 EXPECT_TRUE(domain_state.ShouldUpgradeToSSL());
698 EXPECT_TRUE(domain_state.HasPublicKeyPins());
699 EXPECT_TRUE(state.ShouldUpgradeToSSL(domain));
700 EXPECT_TRUE(state.HasPublicKeyPins(domain));
701
702 // Add a dynamic HSTS header. CheckPublicKeyPins should still pass when given
703 // the original |saved_hashes|, indicating that the static PKP data is still
704 // configured for the domain.
705 EXPECT_TRUE(state.AddHSTSHeader(domain, "includesubdomains; max-age=10000"));
706 EXPECT_TRUE(state.ShouldUpgradeToSSL(domain));
707 std::string failure_log;
708 const bool is_issued_by_known_root = true;
709 EXPECT_TRUE(state.CheckPublicKeyPins(domain,
710 is_issued_by_known_root,
711 saved_hashes,
712 &failure_log));
713
714 // Add an HPKP header, which should only update the dynamic state.
715 HashValue good_hash = GetTestHashValue(1, HASH_VALUE_SHA1);
716 std::string good_pin = GetTestPin(1, HASH_VALUE_SHA1);
717 std::string backup_pin = GetTestPin(2, HASH_VALUE_SHA1);
718 std::string header = "max-age = 10000; " + good_pin + "; " + backup_pin;
719
720 // Construct a fake SSLInfo that will pass AddHPKPHeader's checks.
721 SSLInfo ssl_info;
722 ssl_info.public_key_hashes.push_back(good_hash);
723 ssl_info.public_key_hashes.push_back(saved_hashes[0]);
724 EXPECT_TRUE(state.AddHPKPHeader(domain, header, ssl_info));
725
726 EXPECT_TRUE(state.AddHPKPHeader(domain, header, ssl_info));
727 // HSTS should still be configured for this domain.
728 EXPECT_TRUE(domain_state.ShouldUpgradeToSSL());
729 EXPECT_TRUE(state.ShouldUpgradeToSSL(domain));
730 // The dynamic pins, which do not match |saved_hashes|, should take
731 // precedence over the static pins and cause the check to fail.
732 EXPECT_FALSE(state.CheckPublicKeyPins(domain,
733 is_issued_by_known_root,
734 saved_hashes,
735 &failure_log));
736 }
737
738 // Tests that seeing an invalid HPKP header leaves the existing one alone.
739 TEST_F(HttpSecurityHeadersTest, IgnoreInvalidHeaders) {
740 TransportSecurityState state;
741
742 HashValue good_hash = GetTestHashValue(1, HASH_VALUE_SHA256);
743 std::string good_pin = GetTestPin(1, HASH_VALUE_SHA256);
744 std::string bad_pin = GetTestPin(2, HASH_VALUE_SHA256);
745 std::string backup_pin = GetTestPin(3, HASH_VALUE_SHA256);
746
747 SSLInfo ssl_info;
748 ssl_info.public_key_hashes.push_back(good_hash);
749
750 // Add a valid HPKP header.
751 EXPECT_TRUE(state.AddHPKPHeader(
752 "example.com", "max-age = 10000; " + good_pin + "; " + backup_pin,
753 ssl_info));
754
755 // Check the insertion was valid.
756 EXPECT_TRUE(state.HasPublicKeyPins("example.com"));
757 std::string failure_log;
758 bool is_issued_by_known_root = true;
759 EXPECT_TRUE(state.CheckPublicKeyPins("example.com", is_issued_by_known_root,
760 ssl_info.public_key_hashes,
761 &failure_log));
762
763 // Now assert an invalid one. This should fail.
764 EXPECT_FALSE(state.AddHPKPHeader(
765 "example.com", "max-age = 10000; " + bad_pin + "; " + backup_pin,
766 ssl_info));
767
768 // The old pins must still exist.
769 EXPECT_TRUE(state.HasPublicKeyPins("example.com"));
770 EXPECT_TRUE(state.CheckPublicKeyPins("example.com", is_issued_by_known_root,
771 ssl_info.public_key_hashes,
772 &failure_log));
773 }
774
775 }; // namespace net
OLDNEW
« no previous file with comments | « net/http/http_security_headers.cc ('k') | net/http/http_server_properties.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698