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