Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <stdint.h> | 5 #include <stdint.h> |
| 6 #include <algorithm> | 6 #include <algorithm> |
| 7 | 7 |
| 8 #include "base/base64.h" | 8 #include "base/base64.h" |
| 9 #include "base/sha1.h" | 9 #include "base/sha1.h" |
| 10 #include "base/strings/string_piece.h" | 10 #include "base/strings/string_piece.h" |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 57 std::string GetTestPin(uint8 label, HashValueTag tag) { | 57 std::string GetTestPin(uint8 label, HashValueTag tag) { |
| 58 return GetTestPinImpl(label, tag, true); | 58 return GetTestPinImpl(label, tag, true); |
| 59 } | 59 } |
| 60 | 60 |
| 61 std::string GetTestPinUnquoted(uint8 label, HashValueTag tag) { | 61 std::string GetTestPinUnquoted(uint8 label, HashValueTag tag) { |
| 62 return GetTestPinImpl(label, tag, false); | 62 return GetTestPinImpl(label, tag, false); |
| 63 } | 63 } |
| 64 | 64 |
| 65 }; | 65 }; |
| 66 | 66 |
| 67 // Parses the given header |value| as both a Public-Key-Pins-Report-Only | |
| 68 // and Public-Key-Pins header. Returns true if the value parses | |
| 69 // successfully for both header types, and if the parsed hashes and | |
| 70 // report_uri match for both header types. | |
| 71 bool ParseBothHPKPHeaders(const std::string& value, | |
|
Ryan Sleevi
2015/07/30 01:43:50
Naming wise, this feels a bit odd - you're not par
estark
2015/07/30 02:43:49
I thought it might be weird to shadow net::ParseHP
Ryan Sleevi
2015/07/30 02:53:32
ParsesAsHPKPHeader ? :)
estark
2015/07/30 15:21:21
Done.
| |
| 72 const HashValueVector& chain_hashes, | |
| 73 base::TimeDelta* max_age, | |
| 74 bool* include_subdomains, | |
| 75 HashValueVector* hashes, | |
| 76 GURL* report_uri) { | |
| 77 GURL report_only_uri; | |
| 78 HashValueVector report_only_hashes; | |
| 79 if (!ParseHPKPReportOnlyHeader(value, &report_only_hashes, | |
| 80 &report_only_uri)) { | |
| 81 return false; | |
| 82 } | |
| 83 | |
| 84 bool result = ParseHPKPHeader(value, chain_hashes, max_age, | |
| 85 include_subdomains, hashes, report_uri); | |
| 86 if (!result || report_only_uri != *report_uri || | |
| 87 report_only_hashes.size() != hashes->size()) { | |
| 88 return false; | |
| 89 } | |
| 90 | |
| 91 for (size_t i = 0; i < report_only_hashes.size(); i++) { | |
| 92 if (!(*hashes)[i].Equals(report_only_hashes[i])) | |
| 93 return false; | |
| 94 } | |
| 95 | |
| 96 return true; | |
| 97 } | |
| 67 | 98 |
| 68 class HttpSecurityHeadersTest : public testing::Test { | 99 class HttpSecurityHeadersTest : public testing::Test { |
| 69 }; | 100 }; |
| 70 | 101 |
| 71 | 102 |
| 72 TEST_F(HttpSecurityHeadersTest, BogusHeaders) { | 103 TEST_F(HttpSecurityHeadersTest, BogusHeaders) { |
| 73 base::TimeDelta max_age; | 104 base::TimeDelta max_age; |
| 74 bool include_subdomains = false; | 105 bool include_subdomains = false; |
| 75 | 106 |
| 76 EXPECT_FALSE( | 107 EXPECT_FALSE( |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 158 // Set some fake "chain" hashes | 189 // Set some fake "chain" hashes |
| 159 chain_hashes.push_back(GetTestHashValue(1, tag)); | 190 chain_hashes.push_back(GetTestHashValue(1, tag)); |
| 160 chain_hashes.push_back(GetTestHashValue(2, tag)); | 191 chain_hashes.push_back(GetTestHashValue(2, tag)); |
| 161 chain_hashes.push_back(GetTestHashValue(3, tag)); | 192 chain_hashes.push_back(GetTestHashValue(3, tag)); |
| 162 | 193 |
| 163 // The good pin must be in the chain, the backup pin must not be | 194 // The good pin must be in the chain, the backup pin must not be |
| 164 std::string good_pin = GetTestPin(2, tag); | 195 std::string good_pin = GetTestPin(2, tag); |
| 165 std::string good_pin_unquoted = GetTestPinUnquoted(2, tag); | 196 std::string good_pin_unquoted = GetTestPinUnquoted(2, tag); |
| 166 std::string backup_pin = GetTestPin(4, tag); | 197 std::string backup_pin = GetTestPin(4, tag); |
| 167 | 198 |
| 168 EXPECT_FALSE(ParseHPKPHeader(std::string(), chain_hashes, &max_age, | 199 EXPECT_FALSE(ParseBothHPKPHeaders(std::string(), chain_hashes, &max_age, |
| 169 &include_subdomains, &hashes, &report_uri)); | 200 &include_subdomains, &hashes, &report_uri)); |
| 170 EXPECT_FALSE(ParseHPKPHeader(" ", chain_hashes, &max_age, | 201 EXPECT_FALSE(ParseBothHPKPHeaders(" ", chain_hashes, &max_age, |
| 171 &include_subdomains, &hashes, &report_uri)); | 202 &include_subdomains, &hashes, &report_uri)); |
| 172 EXPECT_FALSE(ParseHPKPHeader("abc", chain_hashes, &max_age, | 203 EXPECT_FALSE(ParseBothHPKPHeaders("abc", chain_hashes, &max_age, |
| 173 &include_subdomains, &hashes, &report_uri)); | 204 &include_subdomains, &hashes, &report_uri)); |
| 174 EXPECT_FALSE(ParseHPKPHeader(" abc", chain_hashes, &max_age, | 205 EXPECT_FALSE(ParseBothHPKPHeaders(" abc", chain_hashes, &max_age, |
| 175 &include_subdomains, &hashes, &report_uri)); | 206 &include_subdomains, &hashes, &report_uri)); |
| 176 EXPECT_FALSE(ParseHPKPHeader(" abc ", chain_hashes, &max_age, | 207 EXPECT_FALSE(ParseBothHPKPHeaders(" abc ", chain_hashes, &max_age, |
| 177 &include_subdomains, &hashes, &report_uri)); | 208 &include_subdomains, &hashes, &report_uri)); |
| 178 EXPECT_FALSE(ParseHPKPHeader("max-age", chain_hashes, &max_age, | 209 EXPECT_FALSE(ParseBothHPKPHeaders("max-age", chain_hashes, &max_age, |
| 179 &include_subdomains, &hashes, &report_uri)); | 210 &include_subdomains, &hashes, &report_uri)); |
| 180 EXPECT_FALSE(ParseHPKPHeader(" max-age", chain_hashes, &max_age, | 211 EXPECT_FALSE(ParseBothHPKPHeaders(" max-age", chain_hashes, &max_age, |
| 181 &include_subdomains, &hashes, &report_uri)); | 212 &include_subdomains, &hashes, &report_uri)); |
| 182 EXPECT_FALSE(ParseHPKPHeader(" max-age ", chain_hashes, &max_age, | 213 EXPECT_FALSE(ParseBothHPKPHeaders(" max-age ", chain_hashes, &max_age, |
| 183 &include_subdomains, &hashes, &report_uri)); | 214 &include_subdomains, &hashes, &report_uri)); |
| 184 EXPECT_FALSE(ParseHPKPHeader("max-age=", chain_hashes, &max_age, | 215 EXPECT_FALSE(ParseBothHPKPHeaders("max-age=", chain_hashes, &max_age, |
| 185 &include_subdomains, &hashes, &report_uri)); | 216 &include_subdomains, &hashes, &report_uri)); |
| 186 EXPECT_FALSE(ParseHPKPHeader(" max-age=", chain_hashes, &max_age, | 217 EXPECT_FALSE(ParseBothHPKPHeaders(" max-age=", chain_hashes, &max_age, |
| 187 &include_subdomains, &hashes, &report_uri)); | 218 &include_subdomains, &hashes, &report_uri)); |
| 188 EXPECT_FALSE(ParseHPKPHeader(" max-age =", chain_hashes, &max_age, | 219 EXPECT_FALSE(ParseBothHPKPHeaders(" max-age =", chain_hashes, &max_age, |
| 189 &include_subdomains, &hashes, &report_uri)); | 220 &include_subdomains, &hashes, &report_uri)); |
| 190 EXPECT_FALSE(ParseHPKPHeader(" max-age= ", chain_hashes, &max_age, | 221 EXPECT_FALSE(ParseBothHPKPHeaders(" max-age= ", chain_hashes, &max_age, |
| 191 &include_subdomains, &hashes, &report_uri)); | 222 &include_subdomains, &hashes, &report_uri)); |
| 192 EXPECT_FALSE(ParseHPKPHeader(" max-age = ", chain_hashes, &max_age, | 223 EXPECT_FALSE(ParseBothHPKPHeaders(" max-age = ", chain_hashes, |
| 193 &include_subdomains, &hashes, &report_uri)); | 224 &max_age, &include_subdomains, &hashes, |
| 194 EXPECT_FALSE(ParseHPKPHeader(" max-age = xy", chain_hashes, &max_age, | 225 &report_uri)); |
| 195 &include_subdomains, &hashes, &report_uri)); | 226 EXPECT_FALSE(ParseBothHPKPHeaders(" max-age = xy", chain_hashes, |
| 196 EXPECT_FALSE(ParseHPKPHeader(" max-age = 3488a923", chain_hashes, | 227 &max_age, &include_subdomains, &hashes, |
| 197 &max_age, &include_subdomains, &hashes, | 228 &report_uri)); |
| 198 &report_uri)); | 229 EXPECT_FALSE(ParseBothHPKPHeaders(" max-age = 3488a923", chain_hashes, |
| 199 EXPECT_FALSE(ParseHPKPHeader("max-age=3488a923 ", chain_hashes, &max_age, | 230 &max_age, &include_subdomains, &hashes, |
| 200 &include_subdomains, &hashes, &report_uri)); | 231 &report_uri)); |
| 201 EXPECT_FALSE(ParseHPKPHeader( | 232 EXPECT_FALSE(ParseBothHPKPHeaders("max-age=3488a923 ", chain_hashes, |
| 233 &max_age, &include_subdomains, &hashes, | |
| 234 &report_uri)); | |
| 235 EXPECT_FALSE(ParseBothHPKPHeaders( | |
| 202 "max-ag=3488923pins=" + good_pin + "," + backup_pin, chain_hashes, | 236 "max-ag=3488923pins=" + good_pin + "," + backup_pin, chain_hashes, |
| 203 &max_age, &include_subdomains, &hashes, &report_uri)); | 237 &max_age, &include_subdomains, &hashes, &report_uri)); |
| 204 EXPECT_FALSE(ParseHPKPHeader("max-age=3488923;pins=" + good_pin + "," + | 238 EXPECT_FALSE(ParseBothHPKPHeaders( |
| 205 backup_pin + "report-uri=\"http://foo.com\"", | 239 "max-age=3488923;pins=" + good_pin + "," + backup_pin + |
| 206 chain_hashes, &max_age, &include_subdomains, | 240 "report-uri=\"http://foo.com\"", |
| 207 &hashes, &report_uri)); | 241 chain_hashes, &max_age, &include_subdomains, &hashes, &report_uri)); |
| 208 EXPECT_FALSE(ParseHPKPHeader("max-aged=3488923" + backup_pin, chain_hashes, | 242 EXPECT_FALSE(ParseBothHPKPHeaders("max-aged=3488923" + backup_pin, |
| 209 &max_age, &include_subdomains, &hashes, | 243 chain_hashes, &max_age, &include_subdomains, |
| 210 &report_uri)); | 244 &hashes, &report_uri)); |
| 211 EXPECT_FALSE(ParseHPKPHeader("max-aged=3488923; " + backup_pin, chain_hashes, | 245 EXPECT_FALSE(ParseBothHPKPHeaders("max-aged=3488923; " + backup_pin, |
| 212 &max_age, &include_subdomains, &hashes, | 246 chain_hashes, &max_age, &include_subdomains, |
| 213 &report_uri)); | 247 &hashes, &report_uri)); |
| 214 EXPECT_FALSE(ParseHPKPHeader( | 248 EXPECT_FALSE(ParseBothHPKPHeaders( |
| 215 "max-aged=3488923; " + backup_pin + ";" + backup_pin, chain_hashes, | 249 "max-aged=3488923; " + backup_pin + ";" + backup_pin, chain_hashes, |
| 216 &max_age, &include_subdomains, &hashes, &report_uri)); | 250 &max_age, &include_subdomains, &hashes, &report_uri)); |
| 217 EXPECT_FALSE(ParseHPKPHeader("max-aged=3488923; " + good_pin + ";" + good_pin, | 251 EXPECT_FALSE(ParseBothHPKPHeaders( |
| 218 chain_hashes, &max_age, &include_subdomains, | 252 "max-aged=3488923; " + good_pin + ";" + good_pin, chain_hashes, &max_age, |
| 219 &hashes, &report_uri)); | 253 &include_subdomains, &hashes, &report_uri)); |
| 220 EXPECT_FALSE(ParseHPKPHeader("max-aged=3488923; " + good_pin, chain_hashes, | 254 EXPECT_FALSE(ParseBothHPKPHeaders("max-aged=3488923; " + good_pin, |
| 221 &max_age, &include_subdomains, &hashes, | 255 chain_hashes, &max_age, &include_subdomains, |
| 222 &report_uri)); | 256 &hashes, &report_uri)); |
| 223 EXPECT_FALSE(ParseHPKPHeader("max-age==3488923", chain_hashes, &max_age, | 257 EXPECT_FALSE(ParseBothHPKPHeaders("max-age==3488923", chain_hashes, &max_age, |
| 224 &include_subdomains, &hashes, &report_uri)); | 258 &include_subdomains, &hashes, &report_uri)); |
| 225 EXPECT_FALSE(ParseHPKPHeader("amax-age=3488923", chain_hashes, &max_age, | 259 EXPECT_FALSE(ParseBothHPKPHeaders("amax-age=3488923", chain_hashes, &max_age, |
| 226 &include_subdomains, &hashes, &report_uri)); | 260 &include_subdomains, &hashes, &report_uri)); |
| 227 EXPECT_FALSE(ParseHPKPHeader("max-age=-3488923", chain_hashes, &max_age, | 261 EXPECT_FALSE(ParseBothHPKPHeaders("max-age=-3488923", chain_hashes, &max_age, |
| 228 &include_subdomains, &hashes, &report_uri)); | 262 &include_subdomains, &hashes, &report_uri)); |
| 229 EXPECT_FALSE(ParseHPKPHeader("max-age=3488923;", chain_hashes, &max_age, | 263 EXPECT_FALSE(ParseBothHPKPHeaders("max-age=3488923;", chain_hashes, &max_age, |
| 230 &include_subdomains, &hashes, &report_uri)); | 264 &include_subdomains, &hashes, &report_uri)); |
| 231 EXPECT_FALSE(ParseHPKPHeader("max-age=3488923 e", chain_hashes, &max_age, | 265 EXPECT_FALSE(ParseBothHPKPHeaders("max-age=3488923 e", chain_hashes, |
| 232 &include_subdomains, &hashes, &report_uri)); | 266 &max_age, &include_subdomains, &hashes, |
| 233 EXPECT_FALSE(ParseHPKPHeader("max-age=3488923 includesubdomain", | 267 &report_uri)); |
| 234 chain_hashes, &max_age, &include_subdomains, | 268 EXPECT_FALSE(ParseBothHPKPHeaders("max-age=3488923 includesubdomain", |
| 235 &hashes, &report_uri)); | 269 chain_hashes, &max_age, &include_subdomains, |
| 236 EXPECT_FALSE(ParseHPKPHeader( | 270 &hashes, &report_uri)); |
| 271 EXPECT_FALSE(ParseBothHPKPHeaders( | |
| 237 "max-age=3488923 report-uri=\"http://foo.com\"", chain_hashes, | 272 "max-age=3488923 report-uri=\"http://foo.com\"", chain_hashes, |
| 238 &max_age, &include_subdomains, &hashes, &report_uri)); | 273 &max_age, &include_subdomains, &hashes, &report_uri)); |
| 239 EXPECT_FALSE(ParseHPKPHeader("max-age=34889.23", chain_hashes, &max_age, | 274 EXPECT_FALSE(ParseBothHPKPHeaders("max-age=34889.23", chain_hashes, &max_age, |
| 240 &include_subdomains, &hashes, &report_uri)); | 275 &include_subdomains, &hashes, &report_uri)); |
| 241 EXPECT_FALSE(ParseHPKPHeader( | 276 EXPECT_FALSE(ParseBothHPKPHeaders( |
| 242 "max-age=243; " + good_pin_unquoted + ";" + backup_pin, chain_hashes, | 277 "max-age=243; " + good_pin_unquoted + ";" + backup_pin, chain_hashes, |
| 243 &max_age, &include_subdomains, &hashes, &report_uri)); | 278 &max_age, &include_subdomains, &hashes, &report_uri)); |
| 244 EXPECT_FALSE(ParseHPKPHeader( | 279 EXPECT_FALSE(ParseBothHPKPHeaders( |
| 245 "max-age=243; " + good_pin + ";" + backup_pin + ";report-uri=;", | 280 "max-age=243; " + good_pin + ";" + backup_pin + ";report-uri=;", |
| 246 chain_hashes, &max_age, &include_subdomains, &hashes, &report_uri)); | 281 chain_hashes, &max_age, &include_subdomains, &hashes, &report_uri)); |
| 247 EXPECT_FALSE(ParseHPKPHeader("max-age=243; " + good_pin + ";" + backup_pin + | 282 EXPECT_FALSE(ParseBothHPKPHeaders( |
| 248 ";report-uri=http://foo.com;", | 283 "max-age=243; " + good_pin + ";" + backup_pin + |
| 249 chain_hashes, &max_age, &include_subdomains, | 284 ";report-uri=http://foo.com;", |
| 250 &hashes, &report_uri)); | 285 chain_hashes, &max_age, &include_subdomains, &hashes, &report_uri)); |
| 251 EXPECT_FALSE(ParseHPKPHeader( | 286 EXPECT_FALSE(ParseBothHPKPHeaders( |
| 252 "max-age=243; " + good_pin + ";" + backup_pin + ";report-uri=''", | 287 "max-age=243; " + good_pin + ";" + backup_pin + ";report-uri=''", |
| 253 chain_hashes, &max_age, &include_subdomains, &hashes, &report_uri)); | 288 chain_hashes, &max_age, &include_subdomains, &hashes, &report_uri)); |
| 254 | 289 |
| 255 // Test that the parser rejects misquoted strings. | 290 // Test that the parser rejects misquoted strings. |
| 256 EXPECT_FALSE(ParseHPKPHeader("max-age=999; " + backup_pin + "; " + good_pin + | 291 EXPECT_FALSE(ParseBothHPKPHeaders( |
| 257 "; report-uri=\"http://foo;bar\'", | 292 "max-age=999; " + backup_pin + "; " + good_pin + |
| 258 chain_hashes, &max_age, &include_subdomains, | 293 "; report-uri=\"http://foo;bar\'", |
| 259 &hashes, &report_uri)); | 294 chain_hashes, &max_age, &include_subdomains, &hashes, &report_uri)); |
| 260 | 295 |
| 261 // Test that the parser rejects invalid report-uris. | 296 // Test that the parser rejects invalid report-uris. |
| 262 EXPECT_FALSE(ParseHPKPHeader("max-age=999; " + backup_pin + "; " + good_pin + | 297 EXPECT_FALSE(ParseBothHPKPHeaders("max-age=999; " + backup_pin + "; " + |
| 263 "; report-uri=\"foo;bar\'", | 298 good_pin + "; report-uri=\"foo;bar\'", |
| 264 chain_hashes, &max_age, &include_subdomains, | 299 chain_hashes, &max_age, &include_subdomains, |
| 265 &hashes, &report_uri)); | 300 &hashes, &report_uri)); |
| 266 | 301 |
| 267 // Check the out args were not updated by checking the default | 302 // Check the out args were not updated by checking the default |
| 268 // values for its predictable fields. | 303 // values for its predictable fields. |
| 269 EXPECT_EQ(0, max_age.InSeconds()); | 304 EXPECT_EQ(0, max_age.InSeconds()); |
| 270 EXPECT_EQ(hashes.size(), (size_t)0); | 305 EXPECT_EQ(hashes.size(), (size_t)0); |
| 271 } | 306 } |
| 272 | 307 |
| 273 TEST_F(HttpSecurityHeadersTest, ValidSTSHeaders) { | 308 TEST_F(HttpSecurityHeadersTest, ValidSTSHeaders) { |
| 274 base::TimeDelta max_age; | 309 base::TimeDelta max_age; |
| 275 base::TimeDelta expect_max_age; | 310 base::TimeDelta expect_max_age; |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 439 // Set some fake "chain" hashes into chain_hashes | 474 // Set some fake "chain" hashes into chain_hashes |
| 440 chain_hashes.push_back(GetTestHashValue(1, tag)); | 475 chain_hashes.push_back(GetTestHashValue(1, tag)); |
| 441 chain_hashes.push_back(GetTestHashValue(2, tag)); | 476 chain_hashes.push_back(GetTestHashValue(2, tag)); |
| 442 chain_hashes.push_back(GetTestHashValue(3, tag)); | 477 chain_hashes.push_back(GetTestHashValue(3, tag)); |
| 443 | 478 |
| 444 // The good pin must be in the chain, the backup pin must not be | 479 // The good pin must be in the chain, the backup pin must not be |
| 445 std::string good_pin = GetTestPin(2, tag); | 480 std::string good_pin = GetTestPin(2, tag); |
| 446 std::string good_pin2 = GetTestPin(3, tag); | 481 std::string good_pin2 = GetTestPin(3, tag); |
| 447 std::string backup_pin = GetTestPin(4, tag); | 482 std::string backup_pin = GetTestPin(4, tag); |
| 448 | 483 |
| 449 EXPECT_TRUE(ParseHPKPHeader("max-age=243; " + good_pin + ";" + backup_pin, | 484 EXPECT_TRUE(ParseBothHPKPHeaders( |
| 450 chain_hashes, &max_age, &include_subdomains, | 485 "max-age=243; " + good_pin + ";" + backup_pin, chain_hashes, &max_age, |
| 451 &hashes, &report_uri)); | 486 &include_subdomains, &hashes, &report_uri)); |
| 452 expect_max_age = base::TimeDelta::FromSeconds(243); | 487 expect_max_age = base::TimeDelta::FromSeconds(243); |
| 453 EXPECT_EQ(expect_max_age, max_age); | 488 EXPECT_EQ(expect_max_age, max_age); |
| 454 EXPECT_FALSE(include_subdomains); | 489 EXPECT_FALSE(include_subdomains); |
| 455 EXPECT_TRUE(report_uri.is_empty()); | 490 EXPECT_TRUE(report_uri.is_empty()); |
| 456 | 491 |
| 457 EXPECT_TRUE(ParseHPKPHeader("max-age=243; " + good_pin + ";" + backup_pin + | 492 EXPECT_TRUE(ParseBothHPKPHeaders( |
| 458 "; report-uri= \"http://example.test/foo\"", | 493 "max-age=243; " + good_pin + ";" + backup_pin + |
| 459 chain_hashes, &max_age, &include_subdomains, | 494 "; report-uri= \"http://example.test/foo\"", |
| 460 &hashes, &report_uri)); | 495 chain_hashes, &max_age, &include_subdomains, &hashes, &report_uri)); |
| 461 expect_max_age = base::TimeDelta::FromSeconds(243); | 496 expect_max_age = base::TimeDelta::FromSeconds(243); |
| 462 expect_report_uri = GURL("http://example.test/foo"); | 497 expect_report_uri = GURL("http://example.test/foo"); |
| 463 EXPECT_EQ(expect_max_age, max_age); | 498 EXPECT_EQ(expect_max_age, max_age); |
| 464 EXPECT_FALSE(include_subdomains); | 499 EXPECT_FALSE(include_subdomains); |
| 465 EXPECT_EQ(expect_report_uri, report_uri); | 500 EXPECT_EQ(expect_report_uri, report_uri); |
| 466 | 501 |
| 467 EXPECT_TRUE(ParseHPKPHeader( | 502 EXPECT_TRUE(ParseBothHPKPHeaders( |
| 468 " " + good_pin + "; " + backup_pin + | 503 " " + good_pin + "; " + backup_pin + |
| 469 " ; Max-agE = 567; repOrT-URi = \"http://example.test/foo\"", | 504 " ; Max-agE = 567; repOrT-URi = \"http://example.test/foo\"", |
| 470 chain_hashes, &max_age, &include_subdomains, &hashes, &report_uri)); | 505 chain_hashes, &max_age, &include_subdomains, &hashes, &report_uri)); |
| 471 expect_max_age = base::TimeDelta::FromSeconds(567); | 506 expect_max_age = base::TimeDelta::FromSeconds(567); |
| 472 expect_report_uri = GURL("http://example.test/foo"); | 507 expect_report_uri = GURL("http://example.test/foo"); |
| 473 EXPECT_EQ(expect_max_age, max_age); | 508 EXPECT_EQ(expect_max_age, max_age); |
| 474 EXPECT_FALSE(include_subdomains); | 509 EXPECT_FALSE(include_subdomains); |
| 475 EXPECT_EQ(expect_report_uri, report_uri); | 510 EXPECT_EQ(expect_report_uri, report_uri); |
| 476 | 511 |
| 477 EXPECT_TRUE(ParseHPKPHeader("includeSubDOMAINS;" + good_pin + ";" + | 512 EXPECT_TRUE(ParseBothHPKPHeaders( |
| 478 backup_pin + " ; mAx-aGe = 890 ", | 513 "includeSubDOMAINS;" + good_pin + ";" + backup_pin + |
| 479 chain_hashes, &max_age, &include_subdomains, | 514 " ; mAx-aGe = 890 ", |
| 480 &hashes, &report_uri)); | 515 chain_hashes, &max_age, &include_subdomains, &hashes, &report_uri)); |
| 481 expect_max_age = base::TimeDelta::FromSeconds(890); | 516 expect_max_age = base::TimeDelta::FromSeconds(890); |
| 482 EXPECT_EQ(expect_max_age, max_age); | 517 EXPECT_EQ(expect_max_age, max_age); |
| 483 EXPECT_TRUE(include_subdomains); | 518 EXPECT_TRUE(include_subdomains); |
| 484 | 519 |
| 485 EXPECT_TRUE(ParseHPKPHeader( | 520 EXPECT_TRUE(ParseBothHPKPHeaders( |
| 486 good_pin + ";" + backup_pin + "; max-age=123;IGNORED;", chain_hashes, | 521 good_pin + ";" + backup_pin + "; max-age=123;IGNORED;", chain_hashes, |
| 487 &max_age, &include_subdomains, &hashes, &report_uri)); | 522 &max_age, &include_subdomains, &hashes, &report_uri)); |
| 488 expect_max_age = base::TimeDelta::FromSeconds(123); | 523 expect_max_age = base::TimeDelta::FromSeconds(123); |
| 489 EXPECT_EQ(expect_max_age, max_age); | 524 EXPECT_EQ(expect_max_age, max_age); |
| 490 EXPECT_FALSE(include_subdomains); | 525 EXPECT_FALSE(include_subdomains); |
| 491 | 526 |
| 492 EXPECT_TRUE(ParseHPKPHeader( | 527 EXPECT_TRUE(ParseBothHPKPHeaders( |
| 493 "max-age=394082;" + backup_pin + ";" + good_pin + "; ", chain_hashes, | 528 "max-age=394082;" + backup_pin + ";" + good_pin + "; ", chain_hashes, |
| 494 &max_age, &include_subdomains, &hashes, &report_uri)); | 529 &max_age, &include_subdomains, &hashes, &report_uri)); |
| 495 expect_max_age = base::TimeDelta::FromSeconds(394082); | 530 expect_max_age = base::TimeDelta::FromSeconds(394082); |
| 496 EXPECT_EQ(expect_max_age, max_age); | 531 EXPECT_EQ(expect_max_age, max_age); |
| 497 EXPECT_FALSE(include_subdomains); | 532 EXPECT_FALSE(include_subdomains); |
| 498 | 533 |
| 499 EXPECT_TRUE(ParseHPKPHeader( | 534 EXPECT_TRUE(ParseBothHPKPHeaders( |
| 500 "max-age=39408299 ;" + backup_pin + ";" + good_pin + "; ", chain_hashes, | 535 "max-age=39408299 ;" + backup_pin + ";" + good_pin + "; ", chain_hashes, |
| 501 &max_age, &include_subdomains, &hashes, &report_uri)); | 536 &max_age, &include_subdomains, &hashes, &report_uri)); |
| 502 expect_max_age = base::TimeDelta::FromSeconds( | 537 expect_max_age = base::TimeDelta::FromSeconds( |
| 503 std::min(kMaxHSTSAgeSecs, static_cast<int64>(INT64_C(39408299)))); | 538 std::min(kMaxHSTSAgeSecs, static_cast<int64>(INT64_C(39408299)))); |
| 504 EXPECT_EQ(expect_max_age, max_age); | 539 EXPECT_EQ(expect_max_age, max_age); |
| 505 EXPECT_FALSE(include_subdomains); | 540 EXPECT_FALSE(include_subdomains); |
| 506 | 541 |
| 507 EXPECT_TRUE(ParseHPKPHeader( | 542 EXPECT_TRUE(ParseBothHPKPHeaders( |
| 508 "max-age=39408038 ; cybers=39408038 ; includeSubdomains; " + | 543 "max-age=39408038 ; cybers=39408038 ; includeSubdomains; " + |
| 509 good_pin + ";" + backup_pin + "; ", | 544 good_pin + ";" + backup_pin + "; ", |
| 510 chain_hashes, &max_age, &include_subdomains, &hashes, &report_uri)); | 545 chain_hashes, &max_age, &include_subdomains, &hashes, &report_uri)); |
| 511 expect_max_age = base::TimeDelta::FromSeconds( | 546 expect_max_age = base::TimeDelta::FromSeconds( |
| 512 std::min(kMaxHSTSAgeSecs, static_cast<int64>(INT64_C(394082038)))); | 547 std::min(kMaxHSTSAgeSecs, static_cast<int64>(INT64_C(394082038)))); |
| 513 EXPECT_EQ(expect_max_age, max_age); | 548 EXPECT_EQ(expect_max_age, max_age); |
| 514 EXPECT_TRUE(include_subdomains); | 549 EXPECT_TRUE(include_subdomains); |
| 515 | 550 |
| 516 EXPECT_TRUE(ParseHPKPHeader(" max-age=0 ; " + good_pin + ";" + backup_pin, | 551 EXPECT_TRUE(ParseBothHPKPHeaders( |
| 517 chain_hashes, &max_age, &include_subdomains, | 552 " max-age=0 ; " + good_pin + ";" + backup_pin, chain_hashes, &max_age, |
| 518 &hashes, &report_uri)); | 553 &include_subdomains, &hashes, &report_uri)); |
| 519 expect_max_age = base::TimeDelta::FromSeconds(0); | 554 expect_max_age = base::TimeDelta::FromSeconds(0); |
| 520 EXPECT_EQ(expect_max_age, max_age); | 555 EXPECT_EQ(expect_max_age, max_age); |
| 521 EXPECT_FALSE(include_subdomains); | 556 EXPECT_FALSE(include_subdomains); |
| 522 | 557 |
| 523 EXPECT_TRUE(ParseHPKPHeader( | 558 EXPECT_TRUE(ParseBothHPKPHeaders( |
| 524 " max-age=0 ; includeSubdomains; " + good_pin + ";" + backup_pin, | 559 " max-age=0 ; includeSubdomains; " + good_pin + ";" + backup_pin, |
| 525 chain_hashes, &max_age, &include_subdomains, &hashes, &report_uri)); | 560 chain_hashes, &max_age, &include_subdomains, &hashes, &report_uri)); |
| 526 expect_max_age = base::TimeDelta::FromSeconds(0); | 561 expect_max_age = base::TimeDelta::FromSeconds(0); |
| 527 EXPECT_EQ(expect_max_age, max_age); | 562 EXPECT_EQ(expect_max_age, max_age); |
| 528 EXPECT_TRUE(include_subdomains); | 563 EXPECT_TRUE(include_subdomains); |
| 529 | 564 |
| 530 EXPECT_TRUE(ParseHPKPHeader( | 565 EXPECT_TRUE(ParseBothHPKPHeaders( |
| 531 " max-age=999999999999999999999999999999999999999999999 ; " + | 566 " max-age=999999999999999999999999999999999999999999999 ; " + |
| 532 backup_pin + ";" + good_pin + "; ", | 567 backup_pin + ";" + good_pin + "; ", |
| 533 chain_hashes, &max_age, &include_subdomains, &hashes, &report_uri)); | 568 chain_hashes, &max_age, &include_subdomains, &hashes, &report_uri)); |
| 534 expect_max_age = base::TimeDelta::FromSeconds(kMaxHSTSAgeSecs); | 569 expect_max_age = base::TimeDelta::FromSeconds(kMaxHSTSAgeSecs); |
| 535 EXPECT_EQ(expect_max_age, max_age); | 570 EXPECT_EQ(expect_max_age, max_age); |
| 536 EXPECT_FALSE(include_subdomains); | 571 EXPECT_FALSE(include_subdomains); |
| 537 | 572 |
| 538 EXPECT_TRUE(ParseHPKPHeader( | 573 EXPECT_TRUE(ParseBothHPKPHeaders( |
| 539 " max-age=999999999999999999999999999999999999999999999 ; " + | 574 " max-age=999999999999999999999999999999999999999999999 ; " + |
| 540 backup_pin + ";" + good_pin + | 575 backup_pin + ";" + good_pin + |
| 541 "; report-uri=\"http://example.test/foo\"", | 576 "; report-uri=\"http://example.test/foo\"", |
| 542 chain_hashes, &max_age, &include_subdomains, &hashes, &report_uri)); | 577 chain_hashes, &max_age, &include_subdomains, &hashes, &report_uri)); |
| 543 expect_max_age = base::TimeDelta::FromSeconds(kMaxHSTSAgeSecs); | 578 expect_max_age = base::TimeDelta::FromSeconds(kMaxHSTSAgeSecs); |
| 544 expect_report_uri = GURL("http://example.test/foo"); | 579 expect_report_uri = GURL("http://example.test/foo"); |
| 545 EXPECT_EQ(expect_max_age, max_age); | 580 EXPECT_EQ(expect_max_age, max_age); |
| 546 EXPECT_FALSE(include_subdomains); | 581 EXPECT_FALSE(include_subdomains); |
| 547 EXPECT_EQ(expect_report_uri, report_uri); | 582 EXPECT_EQ(expect_report_uri, report_uri); |
| 548 | 583 |
| 549 // Test that parsing a different header resets the hashes. | 584 // Test that parsing a different header resets the hashes. |
| 550 hashes.clear(); | 585 hashes.clear(); |
| 551 EXPECT_TRUE(ParseHPKPHeader( | 586 EXPECT_TRUE(ParseBothHPKPHeaders( |
| 552 " max-age=999; " + backup_pin + ";" + good_pin + "; ", chain_hashes, | 587 " max-age=999; " + backup_pin + ";" + good_pin + "; ", chain_hashes, |
| 553 &max_age, &include_subdomains, &hashes, &report_uri)); | 588 &max_age, &include_subdomains, &hashes, &report_uri)); |
| 554 EXPECT_EQ(2u, hashes.size()); | 589 EXPECT_EQ(2u, hashes.size()); |
| 555 EXPECT_TRUE(ParseHPKPHeader( | 590 EXPECT_TRUE(ParseBothHPKPHeaders( |
| 556 " max-age=999; " + backup_pin + ";" + good_pin2 + "; ", chain_hashes, | 591 " max-age=999; " + backup_pin + ";" + good_pin2 + "; ", chain_hashes, |
| 557 &max_age, &include_subdomains, &hashes, &report_uri)); | 592 &max_age, &include_subdomains, &hashes, &report_uri)); |
| 558 EXPECT_EQ(2u, hashes.size()); | 593 EXPECT_EQ(2u, hashes.size()); |
| 559 | 594 |
| 560 // Test that the parser correctly parses an unencoded ';' inside a | 595 // Test that the parser correctly parses an unencoded ';' inside a |
| 561 // quoted report-uri. | 596 // quoted report-uri. |
| 562 EXPECT_TRUE(ParseHPKPHeader("max-age=999; " + backup_pin + "; " + good_pin + | 597 EXPECT_TRUE(ParseBothHPKPHeaders( |
| 563 "; report-uri=\"http://foo.com/?;bar\"", | 598 "max-age=999; " + backup_pin + "; " + good_pin + |
| 564 chain_hashes, &max_age, &include_subdomains, | 599 "; report-uri=\"http://foo.com/?;bar\"", |
| 565 &hashes, &report_uri)); | 600 chain_hashes, &max_age, &include_subdomains, &hashes, &report_uri)); |
| 566 expect_max_age = base::TimeDelta::FromSeconds(999); | 601 expect_max_age = base::TimeDelta::FromSeconds(999); |
| 567 expect_report_uri = GURL("http://foo.com/?;bar"); | 602 expect_report_uri = GURL("http://foo.com/?;bar"); |
| 568 EXPECT_EQ(expect_max_age, max_age); | 603 EXPECT_EQ(expect_max_age, max_age); |
| 569 EXPECT_FALSE(include_subdomains); | 604 EXPECT_FALSE(include_subdomains); |
| 570 EXPECT_EQ(expect_report_uri, report_uri); | 605 EXPECT_EQ(expect_report_uri, report_uri); |
| 571 | 606 |
| 572 // Test that the parser correctly parses a report-uri with a >0x7f | 607 // Test that the parser correctly parses a report-uri with a >0x7f |
| 573 // character. | 608 // character. |
| 574 std::string uri = "http://foo.com/"; | 609 std::string uri = "http://foo.com/"; |
| 575 uri += char(0x7f); | 610 uri += char(0x7f); |
| 576 expect_report_uri = GURL(uri); | 611 expect_report_uri = GURL(uri); |
| 577 EXPECT_TRUE(ParseHPKPHeader("max-age=999; " + backup_pin + "; " + good_pin + | 612 EXPECT_TRUE(ParseBothHPKPHeaders( |
| 578 "; report-uri=\"" + uri + "\"", | 613 "max-age=999; " + backup_pin + "; " + good_pin + "; report-uri=\"" + uri + |
| 579 chain_hashes, &max_age, &include_subdomains, | 614 "\"", |
| 580 &hashes, &report_uri)); | 615 chain_hashes, &max_age, &include_subdomains, &hashes, &report_uri)); |
| 581 expect_max_age = base::TimeDelta::FromSeconds(999); | 616 expect_max_age = base::TimeDelta::FromSeconds(999); |
| 582 EXPECT_EQ(expect_max_age, max_age); | 617 EXPECT_EQ(expect_max_age, max_age); |
| 583 EXPECT_FALSE(include_subdomains); | 618 EXPECT_FALSE(include_subdomains); |
| 584 EXPECT_EQ(expect_report_uri, report_uri); | 619 EXPECT_EQ(expect_report_uri, report_uri); |
| 585 | 620 |
| 586 // Test that the parser allows quoted max-age values. | 621 // Test that the parser allows quoted max-age values. |
| 587 EXPECT_TRUE(ParseHPKPHeader("max-age='999'; " + backup_pin + "; " + good_pin, | 622 EXPECT_TRUE(ParseBothHPKPHeaders( |
| 588 chain_hashes, &max_age, &include_subdomains, | 623 "max-age='999'; " + backup_pin + "; " + good_pin, chain_hashes, &max_age, |
| 589 &hashes, &report_uri)); | 624 &include_subdomains, &hashes, &report_uri)); |
| 590 expect_max_age = base::TimeDelta::FromSeconds(999); | 625 expect_max_age = base::TimeDelta::FromSeconds(999); |
| 591 EXPECT_EQ(expect_max_age, max_age); | 626 EXPECT_EQ(expect_max_age, max_age); |
| 592 EXPECT_FALSE(include_subdomains); | 627 EXPECT_FALSE(include_subdomains); |
| 593 | 628 |
| 594 // Test that the parser handles escaped values. | 629 // Test that the parser handles escaped values. |
| 595 expect_report_uri = GURL("http://foo.com'a"); | 630 expect_report_uri = GURL("http://foo.com'a"); |
| 596 EXPECT_TRUE(ParseHPKPHeader("max-age=999; " + backup_pin + "; " + good_pin + | 631 EXPECT_TRUE(ParseBothHPKPHeaders( |
| 597 "; report-uri='http://foo.com\\'\\a'", | 632 "max-age=999; " + backup_pin + "; " + good_pin + |
| 598 chain_hashes, &max_age, &include_subdomains, | 633 "; report-uri='http://foo.com\\'\\a'", |
| 599 &hashes, &report_uri)); | 634 chain_hashes, &max_age, &include_subdomains, &hashes, &report_uri)); |
| 600 expect_max_age = base::TimeDelta::FromSeconds(999); | 635 expect_max_age = base::TimeDelta::FromSeconds(999); |
| 601 EXPECT_EQ(expect_max_age, max_age); | 636 EXPECT_EQ(expect_max_age, max_age); |
| 602 EXPECT_FALSE(include_subdomains); | 637 EXPECT_FALSE(include_subdomains); |
| 603 EXPECT_EQ(expect_report_uri, report_uri); | 638 EXPECT_EQ(expect_report_uri, report_uri); |
| 639 | |
| 640 // Test that the parser does not require max-age for Report-Only | |
| 641 // headers. | |
| 642 expect_report_uri = GURL("http://foo.com"); | |
| 643 EXPECT_TRUE(ParseHPKPReportOnlyHeader( | |
| 644 backup_pin + "; " + good_pin + "; report-uri='http://foo.com'", &hashes, | |
| 645 &report_uri)); | |
| 646 EXPECT_EQ(expect_report_uri, report_uri); | |
| 604 } | 647 } |
| 605 | 648 |
| 606 TEST_F(HttpSecurityHeadersTest, BogusPinsHeadersSHA1) { | 649 TEST_F(HttpSecurityHeadersTest, BogusPinsHeadersSHA1) { |
| 607 TestBogusPinsHeaders(HASH_VALUE_SHA1); | 650 TestBogusPinsHeaders(HASH_VALUE_SHA1); |
| 608 } | 651 } |
| 609 | 652 |
| 610 TEST_F(HttpSecurityHeadersTest, BogusPinsHeadersSHA256) { | 653 TEST_F(HttpSecurityHeadersTest, BogusPinsHeadersSHA256) { |
| 611 TestBogusPinsHeaders(HASH_VALUE_SHA256); | 654 TestBogusPinsHeaders(HASH_VALUE_SHA256); |
| 612 } | 655 } |
| 613 | 656 |
| (...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 870 ssl_info)); | 913 ssl_info)); |
| 871 | 914 |
| 872 // The old pins must still exist. | 915 // The old pins must still exist. |
| 873 EXPECT_TRUE(state.HasPublicKeyPins("example.com")); | 916 EXPECT_TRUE(state.HasPublicKeyPins("example.com")); |
| 874 EXPECT_TRUE(state.CheckPublicKeyPins( | 917 EXPECT_TRUE(state.CheckPublicKeyPins( |
| 875 domain_port, is_issued_by_known_root, ssl_info.public_key_hashes, nullptr, | 918 domain_port, is_issued_by_known_root, ssl_info.public_key_hashes, nullptr, |
| 876 nullptr, TransportSecurityState::DISABLE_PIN_REPORTS, &failure_log)); | 919 nullptr, TransportSecurityState::DISABLE_PIN_REPORTS, &failure_log)); |
| 877 } | 920 } |
| 878 | 921 |
| 879 }; // namespace net | 922 }; // namespace net |
| OLD | NEW |