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 "net/http/transport_security_state.h" 6 7 #if defined(USE_OPENSSL) 8 #include <openssl/ecdsa.h> 9 #include <openssl/ssl.h> 10 #else // !defined(USE_OPENSSL) 11 #include <cryptohi.h> 12 #include <hasht.h> 13 #include <keyhi.h> 14 #include <nspr.h> 15 #include <pk11pub.h> 16 #endif 17 18 #include <algorithm> 19 20 #include "base/base64.h" 21 #include "base/build_time.h" 22 #include "base/logging.h" 23 #include "base/memory/scoped_ptr.h" 24 #include "base/metrics/histogram.h" 25 #include "base/sha1.h" 26 #include "base/strings/string_number_conversions.h" 27 #include "base/strings/string_util.h" 28 #include "base/strings/utf_string_conversions.h" 29 #include "base/time/time.h" 30 #include "base/values.h" 31 #include "crypto/sha2.h" 32 #include "net/base/dns_util.h" 33 #include "net/cert/x509_cert_types.h" 34 #include "net/cert/x509_certificate.h" 35 #include "net/http/http_security_headers.h" 36 #include "net/ssl/ssl_info.h" 37 #include "url/gurl.h" 38 39 #if defined(USE_OPENSSL) 40 #include "crypto/openssl_util.h" 41 #endif 42 43 namespace net { 44 45 namespace { 46 47 std::string HashesToBase64String(const HashValueVector& hashes) { 48 std::string str; 49 for (size_t i = 0; i != hashes.size(); ++i) { 50 if (i != 0) 51 str += ","; 52 str += hashes[i].ToString(); 53 } 54 return str; 55 } 56 57 std::string HashHost(const std::string& canonicalized_host) { 58 char hashed[crypto::kSHA256Length]; 59 crypto::SHA256HashString(canonicalized_host, hashed, sizeof(hashed)); 60 return std::string(hashed, sizeof(hashed)); 61 } 62 63 // Returns true if the intersection of |a| and |b| is not empty. If either 64 // |a| or |b| is empty, returns false. 65 bool HashesIntersect(const HashValueVector& a, 66 const HashValueVector& b) { 67 for (HashValueVector::const_iterator i = a.begin(); i != a.end(); ++i) { 68 HashValueVector::const_iterator j = 69 std::find_if(b.begin(), b.end(), HashValuesEqual(*i)); 70 if (j != b.end()) 71 return true; 72 } 73 return false; 74 } 75 76 bool AddHash(const char* sha1_hash, 77 HashValueVector* out) { 78 HashValue hash(HASH_VALUE_SHA1); 79 memcpy(hash.data(), sha1_hash, hash.size()); 80 out->push_back(hash); 81 return true; 82 } 83 84 } // namespace 85 86 TransportSecurityState::TransportSecurityState() 87 : delegate_(NULL), enable_static_pins_(true) { 88 // Static pinning is only enabled for official builds to make sure that 89 // others don't end up with pins that cannot be easily updated. 90 #if !defined(OFFICIAL_BUILD) || defined(OS_ANDROID) || defined(OS_IOS) 91 enable_static_pins_ = false; 92 #endif 93 DCHECK(CalledOnValidThread()); 94 } 95 96 TransportSecurityState::Iterator::Iterator(const TransportSecurityState& state) 97 : iterator_(state.enabled_hosts_.begin()), 98 end_(state.enabled_hosts_.end()) { 99 } 100 101 TransportSecurityState::Iterator::~Iterator() {} 102 103 bool TransportSecurityState::ShouldSSLErrorsBeFatal(const std::string& host) { 104 DomainState state; 105 if (GetStaticDomainState(host, &state)) 106 return true; 107 return GetDynamicDomainState(host, &state); 108 } 109 110 bool TransportSecurityState::ShouldUpgradeToSSL(const std::string& host) { 111 DomainState dynamic_state; 112 if (GetDynamicDomainState(host, &dynamic_state)) 113 return dynamic_state.ShouldUpgradeToSSL(); 114 115 DomainState static_state; 116 if (GetStaticDomainState(host, &static_state) && 117 static_state.ShouldUpgradeToSSL()) { 118 return true; 119 } 120 121 return false; 122 } 123 124 bool TransportSecurityState::CheckPublicKeyPins( 125 const std::string& host, 126 bool is_issued_by_known_root, 127 const HashValueVector& public_key_hashes, 128 std::string* pinning_failure_log) { 129 // Perform pin validation if, and only if, all these conditions obtain: 130 // 131 // * the server's certificate chain chains up to a known root (i.e. not a 132 // user-installed trust anchor); and 133 // * the server actually has public key pins. 134 if (!is_issued_by_known_root || !HasPublicKeyPins(host)) { 135 return true; 136 } 137 138 bool pins_are_valid = CheckPublicKeyPinsImpl( 139 host, public_key_hashes, pinning_failure_log); 140 if (!pins_are_valid) { 141 LOG(ERROR) << *pinning_failure_log; 142 ReportUMAOnPinFailure(host); 143 } 144 145 UMA_HISTOGRAM_BOOLEAN("Net.PublicKeyPinSuccess", pins_are_valid); 146 return pins_are_valid; 147 } 148 149 bool TransportSecurityState::HasPublicKeyPins(const std::string& host) { 150 DomainState dynamic_state; 151 if (GetDynamicDomainState(host, &dynamic_state)) 152 return dynamic_state.HasPublicKeyPins(); 153 154 DomainState static_state; 155 if (GetStaticDomainState(host, &static_state)) { 156 if (static_state.HasPublicKeyPins()) 157 return true; 158 } 159 160 return false; 161 } 162 163 void TransportSecurityState::SetDelegate( 164 TransportSecurityState::Delegate* delegate) { 165 DCHECK(CalledOnValidThread()); 166 delegate_ = delegate; 167 } 168 169 void TransportSecurityState::EnableHost(const std::string& host, 170 const DomainState& state) { 171 DCHECK(CalledOnValidThread()); 172 173 const std::string canonicalized_host = CanonicalizeHost(host); 174 if (canonicalized_host.empty()) 175 return; 176 177 DomainState state_copy(state); 178 // No need to store this value since it is redundant. (|canonicalized_host| 179 // is the map key.) 180 state_copy.domain.clear(); 181 182 enabled_hosts_[HashHost(canonicalized_host)] = state_copy; 183 DirtyNotify(); 184 } 185 186 bool TransportSecurityState::DeleteDynamicDataForHost(const std::string& host) { 187 DCHECK(CalledOnValidThread()); 188 189 const std::string canonicalized_host = CanonicalizeHost(host); 190 if (canonicalized_host.empty()) 191 return false; 192 193 DomainStateMap::iterator i = enabled_hosts_.find( 194 HashHost(canonicalized_host)); 195 if (i != enabled_hosts_.end()) { 196 enabled_hosts_.erase(i); 197 DirtyNotify(); 198 return true; 199 } 200 return false; 201 } 202 203 void TransportSecurityState::ClearDynamicData() { 204 DCHECK(CalledOnValidThread()); 205 enabled_hosts_.clear(); 206 } 207 208 void TransportSecurityState::DeleteAllDynamicDataSince(const base::Time& time) { 209 DCHECK(CalledOnValidThread()); 210 211 bool dirtied = false; 212 DomainStateMap::iterator i = enabled_hosts_.begin(); 213 while (i != enabled_hosts_.end()) { 214 if (i->second.sts.last_observed >= time && 215 i->second.pkp.last_observed >= time) { 216 dirtied = true; 217 enabled_hosts_.erase(i++); 218 continue; 219 } 220 221 if (i->second.sts.last_observed >= time) { 222 dirtied = true; 223 i->second.sts.upgrade_mode = DomainState::MODE_DEFAULT; 224 } else if (i->second.pkp.last_observed >= time) { 225 dirtied = true; 226 i->second.pkp.spki_hashes.clear(); 227 i->second.pkp.expiry = base::Time(); 228 } 229 ++i; 230 } 231 232 if (dirtied) 233 DirtyNotify(); 234 } 235 236 TransportSecurityState::~TransportSecurityState() { 237 DCHECK(CalledOnValidThread()); 238 } 239 240 void TransportSecurityState::DirtyNotify() { 241 DCHECK(CalledOnValidThread()); 242 243 if (delegate_) 244 delegate_->StateIsDirty(this); 245 } 246 247 // static 248 std::string TransportSecurityState::CanonicalizeHost(const std::string& host) { 249 // We cannot perform the operations as detailed in the spec here as |host| 250 // has already undergone IDN processing before it reached us. Thus, we check 251 // that there are no invalid characters in the host and lowercase the result. 252 253 std::string new_host; 254 if (!DNSDomainFromDot(host, &new_host)) { 255 // DNSDomainFromDot can fail if any label is > 63 bytes or if the whole 256 // name is >255 bytes. However, search terms can have those properties. 257 return std::string(); 258 } 259 260 for (size_t i = 0; new_host[i]; i += new_host[i] + 1) { 261 const unsigned label_length = static_cast<unsigned>(new_host[i]); 262 if (!label_length) 263 break; 264 265 for (size_t j = 0; j < label_length; ++j) { 266 new_host[i + 1 + j] = tolower(new_host[i + 1 + j]); 267 } 268 } 269 270 return new_host; 271 } 272 273 // |ReportUMAOnPinFailure| uses these to report which domain was associated 274 // with the public key pinning failure. 275 // 276 // DO NOT CHANGE THE ORDERING OF THESE NAMES OR REMOVE ANY OF THEM. Add new 277 // domains at the END of the listing (but before DOMAIN_NUM_EVENTS). 278 enum SecondLevelDomainName { 279 DOMAIN_NOT_PINNED, 280 281 DOMAIN_GOOGLE_COM, 282 DOMAIN_ANDROID_COM, 283 DOMAIN_GOOGLE_ANALYTICS_COM, 284 DOMAIN_GOOGLEPLEX_COM, 285 DOMAIN_YTIMG_COM, 286 DOMAIN_GOOGLEUSERCONTENT_COM, 287 DOMAIN_YOUTUBE_COM, 288 DOMAIN_GOOGLEAPIS_COM, 289 DOMAIN_GOOGLEADSERVICES_COM, 290 DOMAIN_GOOGLECODE_COM, 291 DOMAIN_APPSPOT_COM, 292 DOMAIN_GOOGLESYNDICATION_COM, 293 DOMAIN_DOUBLECLICK_NET, 294 DOMAIN_GSTATIC_COM, 295 DOMAIN_GMAIL_COM, 296 DOMAIN_GOOGLEMAIL_COM, 297 DOMAIN_GOOGLEGROUPS_COM, 298 299 DOMAIN_TORPROJECT_ORG, 300 301 DOMAIN_TWITTER_COM, 302 DOMAIN_TWIMG_COM, 303 304 DOMAIN_AKAMAIHD_NET, 305 306 DOMAIN_TOR2WEB_ORG, 307 308 DOMAIN_YOUTU_BE, 309 DOMAIN_GOOGLECOMMERCE_COM, 310 DOMAIN_URCHIN_COM, 311 DOMAIN_GOO_GL, 312 DOMAIN_G_CO, 313 DOMAIN_GOOGLE_AC, 314 DOMAIN_GOOGLE_AD, 315 DOMAIN_GOOGLE_AE, 316 DOMAIN_GOOGLE_AF, 317 DOMAIN_GOOGLE_AG, 318 DOMAIN_GOOGLE_AM, 319 DOMAIN_GOOGLE_AS, 320 DOMAIN_GOOGLE_AT, 321 DOMAIN_GOOGLE_AZ, 322 DOMAIN_GOOGLE_BA, 323 DOMAIN_GOOGLE_BE, 324 DOMAIN_GOOGLE_BF, 325 DOMAIN_GOOGLE_BG, 326 DOMAIN_GOOGLE_BI, 327 DOMAIN_GOOGLE_BJ, 328 DOMAIN_GOOGLE_BS, 329 DOMAIN_GOOGLE_BY, 330 DOMAIN_GOOGLE_CA, 331 DOMAIN_GOOGLE_CAT, 332 DOMAIN_GOOGLE_CC, 333 DOMAIN_GOOGLE_CD, 334 DOMAIN_GOOGLE_CF, 335 DOMAIN_GOOGLE_CG, 336 DOMAIN_GOOGLE_CH, 337 DOMAIN_GOOGLE_CI, 338 DOMAIN_GOOGLE_CL, 339 DOMAIN_GOOGLE_CM, 340 DOMAIN_GOOGLE_CN, 341 DOMAIN_CO_AO, 342 DOMAIN_CO_BW, 343 DOMAIN_CO_CK, 344 DOMAIN_CO_CR, 345 DOMAIN_CO_HU, 346 DOMAIN_CO_ID, 347 DOMAIN_CO_IL, 348 DOMAIN_CO_IM, 349 DOMAIN_CO_IN, 350 DOMAIN_CO_JE, 351 DOMAIN_CO_JP, 352 DOMAIN_CO_KE, 353 DOMAIN_CO_KR, 354 DOMAIN_CO_LS, 355 DOMAIN_CO_MA, 356 DOMAIN_CO_MZ, 357 DOMAIN_CO_NZ, 358 DOMAIN_CO_TH, 359 DOMAIN_CO_TZ, 360 DOMAIN_CO_UG, 361 DOMAIN_CO_UK, 362 DOMAIN_CO_UZ, 363 DOMAIN_CO_VE, 364 DOMAIN_CO_VI, 365 DOMAIN_CO_ZA, 366 DOMAIN_CO_ZM, 367 DOMAIN_CO_ZW, 368 DOMAIN_COM_AF, 369 DOMAIN_COM_AG, 370 DOMAIN_COM_AI, 371 DOMAIN_COM_AR, 372 DOMAIN_COM_AU, 373 DOMAIN_COM_BD, 374 DOMAIN_COM_BH, 375 DOMAIN_COM_BN, 376 DOMAIN_COM_BO, 377 DOMAIN_COM_BR, 378 DOMAIN_COM_BY, 379 DOMAIN_COM_BZ, 380 DOMAIN_COM_CN, 381 DOMAIN_COM_CO, 382 DOMAIN_COM_CU, 383 DOMAIN_COM_CY, 384 DOMAIN_COM_DO, 385 DOMAIN_COM_EC, 386 DOMAIN_COM_EG, 387 DOMAIN_COM_ET, 388 DOMAIN_COM_FJ, 389 DOMAIN_COM_GE, 390 DOMAIN_COM_GH, 391 DOMAIN_COM_GI, 392 DOMAIN_COM_GR, 393 DOMAIN_COM_GT, 394 DOMAIN_COM_HK, 395 DOMAIN_COM_IQ, 396 DOMAIN_COM_JM, 397 DOMAIN_COM_JO, 398 DOMAIN_COM_KH, 399 DOMAIN_COM_KW, 400 DOMAIN_COM_LB, 401 DOMAIN_COM_LY, 402 DOMAIN_COM_MT, 403 DOMAIN_COM_MX, 404 DOMAIN_COM_MY, 405 DOMAIN_COM_NA, 406 DOMAIN_COM_NF, 407 DOMAIN_COM_NG, 408 DOMAIN_COM_NI, 409 DOMAIN_COM_NP, 410 DOMAIN_COM_NR, 411 DOMAIN_COM_OM, 412 DOMAIN_COM_PA, 413 DOMAIN_COM_PE, 414 DOMAIN_COM_PH, 415 DOMAIN_COM_PK, 416 DOMAIN_COM_PL, 417 DOMAIN_COM_PR, 418 DOMAIN_COM_PY, 419 DOMAIN_COM_QA, 420 DOMAIN_COM_RU, 421 DOMAIN_COM_SA, 422 DOMAIN_COM_SB, 423 DOMAIN_COM_SG, 424 DOMAIN_COM_SL, 425 DOMAIN_COM_SV, 426 DOMAIN_COM_TJ, 427 DOMAIN_COM_TN, 428 DOMAIN_COM_TR, 429 DOMAIN_COM_TW, 430 DOMAIN_COM_UA, 431 DOMAIN_COM_UY, 432 DOMAIN_COM_VC, 433 DOMAIN_COM_VE, 434 DOMAIN_COM_VN, 435 DOMAIN_GOOGLE_CV, 436 DOMAIN_GOOGLE_CZ, 437 DOMAIN_GOOGLE_DE, 438 DOMAIN_GOOGLE_DJ, 439 DOMAIN_GOOGLE_DK, 440 DOMAIN_GOOGLE_DM, 441 DOMAIN_GOOGLE_DZ, 442 DOMAIN_GOOGLE_EE, 443 DOMAIN_GOOGLE_ES, 444 DOMAIN_GOOGLE_FI, 445 DOMAIN_GOOGLE_FM, 446 DOMAIN_GOOGLE_FR, 447 DOMAIN_GOOGLE_GA, 448 DOMAIN_GOOGLE_GE, 449 DOMAIN_GOOGLE_GG, 450 DOMAIN_GOOGLE_GL, 451 DOMAIN_GOOGLE_GM, 452 DOMAIN_GOOGLE_GP, 453 DOMAIN_GOOGLE_GR, 454 DOMAIN_GOOGLE_GY, 455 DOMAIN_GOOGLE_HK, 456 DOMAIN_GOOGLE_HN, 457 DOMAIN_GOOGLE_HR, 458 DOMAIN_GOOGLE_HT, 459 DOMAIN_GOOGLE_HU, 460 DOMAIN_GOOGLE_IE, 461 DOMAIN_GOOGLE_IM, 462 DOMAIN_GOOGLE_INFO, 463 DOMAIN_GOOGLE_IQ, 464 DOMAIN_GOOGLE_IS, 465 DOMAIN_GOOGLE_IT, 466 DOMAIN_IT_AO, 467 DOMAIN_GOOGLE_JE, 468 DOMAIN_GOOGLE_JO, 469 DOMAIN_GOOGLE_JOBS, 470 DOMAIN_GOOGLE_JP, 471 DOMAIN_GOOGLE_KG, 472 DOMAIN_GOOGLE_KI, 473 DOMAIN_GOOGLE_KZ, 474 DOMAIN_GOOGLE_LA, 475 DOMAIN_GOOGLE_LI, 476 DOMAIN_GOOGLE_LK, 477 DOMAIN_GOOGLE_LT, 478 DOMAIN_GOOGLE_LU, 479 DOMAIN_GOOGLE_LV, 480 DOMAIN_GOOGLE_MD, 481 DOMAIN_GOOGLE_ME, 482 DOMAIN_GOOGLE_MG, 483 DOMAIN_GOOGLE_MK, 484 DOMAIN_GOOGLE_ML, 485 DOMAIN_GOOGLE_MN, 486 DOMAIN_GOOGLE_MS, 487 DOMAIN_GOOGLE_MU, 488 DOMAIN_GOOGLE_MV, 489 DOMAIN_GOOGLE_MW, 490 DOMAIN_GOOGLE_NE, 491 DOMAIN_NE_JP, 492 DOMAIN_GOOGLE_NET, 493 DOMAIN_GOOGLE_NL, 494 DOMAIN_GOOGLE_NO, 495 DOMAIN_GOOGLE_NR, 496 DOMAIN_GOOGLE_NU, 497 DOMAIN_OFF_AI, 498 DOMAIN_GOOGLE_PK, 499 DOMAIN_GOOGLE_PL, 500 DOMAIN_GOOGLE_PN, 501 DOMAIN_GOOGLE_PS, 502 DOMAIN_GOOGLE_PT, 503 DOMAIN_GOOGLE_RO, 504 DOMAIN_GOOGLE_RS, 505 DOMAIN_GOOGLE_RU, 506 DOMAIN_GOOGLE_RW, 507 DOMAIN_GOOGLE_SC, 508 DOMAIN_GOOGLE_SE, 509 DOMAIN_GOOGLE_SH, 510 DOMAIN_GOOGLE_SI, 511 DOMAIN_GOOGLE_SK, 512 DOMAIN_GOOGLE_SM, 513 DOMAIN_GOOGLE_SN, 514 DOMAIN_GOOGLE_SO, 515 DOMAIN_GOOGLE_ST, 516 DOMAIN_GOOGLE_TD, 517 DOMAIN_GOOGLE_TG, 518 DOMAIN_GOOGLE_TK, 519 DOMAIN_GOOGLE_TL, 520 DOMAIN_GOOGLE_TM, 521 DOMAIN_GOOGLE_TN, 522 DOMAIN_GOOGLE_TO, 523 DOMAIN_GOOGLE_TP, 524 DOMAIN_GOOGLE_TT, 525 DOMAIN_GOOGLE_US, 526 DOMAIN_GOOGLE_UZ, 527 DOMAIN_GOOGLE_VG, 528 DOMAIN_GOOGLE_VU, 529 DOMAIN_GOOGLE_WS, 530 531 DOMAIN_CHROMIUM_ORG, 532 533 DOMAIN_CRYPTO_CAT, 534 DOMAIN_LAVABIT_COM, 535 536 DOMAIN_GOOGLETAGMANAGER_COM, 537 DOMAIN_GOOGLETAGSERVICES_COM, 538 539 DOMAIN_DROPBOX_COM, 540 DOMAIN_YOUTUBE_NOCOOKIE_COM, 541 DOMAIN_2MDN_NET, 542 543 // Boundary value for UMA_HISTOGRAM_ENUMERATION: 544 DOMAIN_NUM_EVENTS 545 }; 546 547 // PublicKeyPins contains a number of SubjectPublicKeyInfo hashes for a site. 548 // The validated certificate chain for the site must not include any of 549 // |excluded_hashes| and must include one or more of |required_hashes|. 550 struct PublicKeyPins { 551 const char* const* required_hashes; 552 const char* const* excluded_hashes; 553 }; 554 555 struct HSTSPreload { 556 uint8 length; 557 bool include_subdomains; 558 char dns_name[38]; 559 bool https_required; 560 PublicKeyPins pins; 561 SecondLevelDomainName second_level_domain_name; 562 }; 563 564 static bool HasPreload(const struct HSTSPreload* entries, 565 size_t num_entries, 566 const std::string& canonicalized_host, 567 size_t i, 568 bool enable_static_pins, 569 TransportSecurityState::DomainState* out, 570 bool* ret) { 571 for (size_t j = 0; j < num_entries; j++) { 572 if (entries[j].length == canonicalized_host.size() - i && 573 memcmp(entries[j].dns_name, &canonicalized_host[i], 574 entries[j].length) == 0) { 575 if (!entries[j].include_subdomains && i != 0) { 576 *ret = false; 577 } else { 578 out->sts.include_subdomains = entries[j].include_subdomains; 579 out->sts.last_observed = base::GetBuildTime(); 580 *ret = true; 581 out->sts.upgrade_mode = 582 TransportSecurityState::DomainState::MODE_FORCE_HTTPS; 583 if (!entries[j].https_required) 584 out->sts.upgrade_mode = 585 TransportSecurityState::DomainState::MODE_DEFAULT; 586 587 if (enable_static_pins) { 588 out->pkp.include_subdomains = entries[j].include_subdomains; 589 out->pkp.last_observed = base::GetBuildTime(); 590 if (entries[j].pins.required_hashes) { 591 const char* const* sha1_hash = entries[j].pins.required_hashes; 592 while (*sha1_hash) { 593 AddHash(*sha1_hash, &out->pkp.spki_hashes); 594 sha1_hash++; 595 } 596 } 597 if (entries[j].pins.excluded_hashes) { 598 const char* const* sha1_hash = entries[j].pins.excluded_hashes; 599 while (*sha1_hash) { 600 AddHash(*sha1_hash, &out->pkp.bad_spki_hashes); 601 sha1_hash++; 602 } 603 } 604 } 605 } 606 return true; 607 } 608 } 609 return false; 610 } 611 612 #include "net/http/transport_security_state_static.h" 613 614 // Returns the HSTSPreload entry for the |canonicalized_host| in |entries|, 615 // or NULL if there is none. Prefers exact hostname matches to those that 616 // match only because HSTSPreload.include_subdomains is true. 617 // 618 // |canonicalized_host| should be the hostname as canonicalized by 619 // CanonicalizeHost. 620 static const struct HSTSPreload* GetHSTSPreload( 621 const std::string& canonicalized_host, 622 const struct HSTSPreload* entries, 623 size_t num_entries) { 624 for (size_t i = 0; canonicalized_host[i]; i += canonicalized_host[i] + 1) { 625 for (size_t j = 0; j < num_entries; j++) { 626 const struct HSTSPreload* entry = entries + j; 627 628 if (i != 0 && !entry->include_subdomains) 629 continue; 630 631 if (entry->length == canonicalized_host.size() - i && 632 memcmp(entry->dns_name, &canonicalized_host[i], entry->length) == 0) { 633 return entry; 634 } 635 } 636 } 637 638 return NULL; 639 } 640 641 bool TransportSecurityState::AddHSTSHeader(const std::string& host, 642 const std::string& value) { 643 DCHECK(CalledOnValidThread()); 644 645 base::Time now = base::Time::Now(); 646 base::TimeDelta max_age; 647 TransportSecurityState::DomainState domain_state; 648 GetDynamicDomainState(host, &domain_state); 649 if (ParseHSTSHeader(value, &max_age, &domain_state.sts.include_subdomains)) { 650 // Handle max-age == 0. 651 if (max_age.InSeconds() == 0) 652 domain_state.sts.upgrade_mode = DomainState::MODE_DEFAULT; 653 else 654 domain_state.sts.upgrade_mode = DomainState::MODE_FORCE_HTTPS; 655 domain_state.sts.last_observed = now; 656 domain_state.sts.expiry = now + max_age; 657 EnableHost(host, domain_state); 658 return true; 659 } 660 return false; 661 } 662 663 bool TransportSecurityState::AddHPKPHeader(const std::string& host, 664 const std::string& value, 665 const SSLInfo& ssl_info) { 666 DCHECK(CalledOnValidThread()); 667 668 base::Time now = base::Time::Now(); 669 base::TimeDelta max_age; 670 TransportSecurityState::DomainState domain_state; 671 GetDynamicDomainState(host, &domain_state); 672 if (ParseHPKPHeader(value, 673 ssl_info.public_key_hashes, 674 &max_age, 675 &domain_state.pkp.include_subdomains, 676 &domain_state.pkp.spki_hashes)) { 677 // Handle max-age == 0. 678 if (max_age.InSeconds() == 0) 679 domain_state.pkp.spki_hashes.clear(); 680 domain_state.pkp.last_observed = now; 681 domain_state.pkp.expiry = now + max_age; 682 EnableHost(host, domain_state); 683 return true; 684 } 685 return false; 686 } 687 688 bool TransportSecurityState::AddHSTS(const std::string& host, 689 const base::Time& expiry, 690 bool include_subdomains) { 691 DCHECK(CalledOnValidThread()); 692 693 // Copy-and-modify the existing DomainState for this host (if any). 694 TransportSecurityState::DomainState domain_state; 695 const std::string canonicalized_host = CanonicalizeHost(host); 696 const std::string hashed_host = HashHost(canonicalized_host); 697 DomainStateMap::const_iterator i = enabled_hosts_.find( 698 hashed_host); 699 if (i != enabled_hosts_.end()) 700 domain_state = i->second; 701 702 domain_state.sts.last_observed = base::Time::Now(); 703 domain_state.sts.include_subdomains = include_subdomains; 704 domain_state.sts.expiry = expiry; 705 domain_state.sts.upgrade_mode = DomainState::MODE_FORCE_HTTPS; 706 EnableHost(host, domain_state); 707 return true; 708 } 709 710 bool TransportSecurityState::AddHPKP(const std::string& host, 711 const base::Time& expiry, 712 bool include_subdomains, 713 const HashValueVector& hashes) { 714 DCHECK(CalledOnValidThread()); 715 716 // Copy-and-modify the existing DomainState for this host (if any). 717 TransportSecurityState::DomainState domain_state; 718 const std::string canonicalized_host = CanonicalizeHost(host); 719 const std::string hashed_host = HashHost(canonicalized_host); 720 DomainStateMap::const_iterator i = enabled_hosts_.find( 721 hashed_host); 722 if (i != enabled_hosts_.end()) 723 domain_state = i->second; 724 725 domain_state.pkp.last_observed = base::Time::Now(); 726 domain_state.pkp.include_subdomains = include_subdomains; 727 domain_state.pkp.expiry = expiry; 728 domain_state.pkp.spki_hashes = hashes; 729 EnableHost(host, domain_state); 730 return true; 731 } 732 733 // static 734 bool TransportSecurityState::IsGooglePinnedProperty(const std::string& host) { 735 std::string canonicalized_host = CanonicalizeHost(host); 736 const struct HSTSPreload* entry = 737 GetHSTSPreload(canonicalized_host, kPreloadedSTS, kNumPreloadedSTS); 738 739 return entry && entry->pins.required_hashes == kGoogleAcceptableCerts; 740 } 741 742 // static 743 void TransportSecurityState::ReportUMAOnPinFailure(const std::string& host) { 744 std::string canonicalized_host = CanonicalizeHost(host); 745 746 const struct HSTSPreload* entry = 747 GetHSTSPreload(canonicalized_host, kPreloadedSTS, kNumPreloadedSTS); 748 749 if (!entry) { 750 // We don't care to report pin failures for dynamic pins. 751 return; 752 } 753 754 DCHECK(entry); 755 DCHECK(entry->pins.required_hashes); 756 DCHECK(entry->second_level_domain_name != DOMAIN_NOT_PINNED); 757 758 UMA_HISTOGRAM_ENUMERATION("Net.PublicKeyPinFailureDomain", 759 entry->second_level_domain_name, DOMAIN_NUM_EVENTS); 760 } 761 762 // static 763 bool TransportSecurityState::IsBuildTimely() { 764 const base::Time build_time = base::GetBuildTime(); 765 // We consider built-in information to be timely for 10 weeks. 766 return (base::Time::Now() - build_time).InDays() < 70 /* 10 weeks */; 767 } 768 769 bool TransportSecurityState::CheckPublicKeyPinsImpl( 770 const std::string& host, 771 const HashValueVector& hashes, 772 std::string* failure_log) { 773 DomainState dynamic_state; 774 if (GetDynamicDomainState(host, &dynamic_state)) 775 return dynamic_state.CheckPublicKeyPins(hashes, failure_log); 776 777 DomainState static_state; 778 if (GetStaticDomainState(host, &static_state)) 779 return static_state.CheckPublicKeyPins(hashes, failure_log); 780 781 // HasPublicKeyPins should have returned true in order for this method 782 // to have been called, so if we fall through to here, it's an error. 783 return false; 784 } 785 786 bool TransportSecurityState::GetStaticDomainState(const std::string& host, 787 DomainState* out) const { 788 DCHECK(CalledOnValidThread()); 789 790 const std::string canonicalized_host = CanonicalizeHost(host); 791 792 out->sts.upgrade_mode = DomainState::MODE_FORCE_HTTPS; 793 out->sts.include_subdomains = false; 794 out->pkp.include_subdomains = false; 795 796 const bool is_build_timely = IsBuildTimely(); 797 798 for (size_t i = 0; canonicalized_host[i]; i += canonicalized_host[i] + 1) { 799 std::string host_sub_chunk(&canonicalized_host[i], 800 canonicalized_host.size() - i); 801 out->domain = DNSDomainToString(host_sub_chunk); 802 bool ret; 803 if (is_build_timely && HasPreload(kPreloadedSTS, 804 kNumPreloadedSTS, 805 canonicalized_host, 806 i, 807 enable_static_pins_, 808 out, 809 &ret)) { 810 return ret; 811 } 812 } 813 814 return false; 815 } 816 817 bool TransportSecurityState::GetDynamicDomainState(const std::string& host, 818 DomainState* result) { 819 DCHECK(CalledOnValidThread()); 820 821 DomainState state; 822 const std::string canonicalized_host = CanonicalizeHost(host); 823 if (canonicalized_host.empty()) 824 return false; 825 826 base::Time current_time(base::Time::Now()); 827 828 for (size_t i = 0; canonicalized_host[i]; i += canonicalized_host[i] + 1) { 829 std::string host_sub_chunk(&canonicalized_host[i], 830 canonicalized_host.size() - i); 831 DomainStateMap::iterator j = 832 enabled_hosts_.find(HashHost(host_sub_chunk)); 833 if (j == enabled_hosts_.end()) 834 continue; 835 836 if (current_time > j->second.sts.expiry && 837 current_time > j->second.pkp.expiry) { 838 enabled_hosts_.erase(j); 839 DirtyNotify(); 840 continue; 841 } 842 843 state = j->second; 844 state.domain = DNSDomainToString(host_sub_chunk); 845 846 // Succeed if we matched the domain exactly or if subdomain matches are 847 // allowed. 848 if (i == 0 || j->second.sts.include_subdomains || 849 j->second.pkp.include_subdomains) { 850 *result = state; 851 return true; 852 } 853 854 return false; 855 } 856 857 return false; 858 } 859 860 void TransportSecurityState::AddOrUpdateEnabledHosts( 861 const std::string& hashed_host, const DomainState& state) { 862 DCHECK(CalledOnValidThread()); 863 enabled_hosts_[hashed_host] = state; 864 } 865 866 TransportSecurityState::DomainState::DomainState() { 867 sts.upgrade_mode = MODE_DEFAULT; 868 sts.include_subdomains = false; 869 pkp.include_subdomains = false; 870 } 871 872 TransportSecurityState::DomainState::~DomainState() { 873 } 874 875 bool TransportSecurityState::DomainState::CheckPublicKeyPins( 876 const HashValueVector& hashes, std::string* failure_log) const { 877 // Validate that hashes is not empty. By the time this code is called (in 878 // production), that should never happen, but it's good to be defensive. 879 // And, hashes *can* be empty in some test scenarios. 880 if (hashes.empty()) { 881 failure_log->append( 882 "Rejecting empty public key chain for public-key-pinned domains: " + 883 domain); 884 return false; 885 } 886 887 if (HashesIntersect(pkp.bad_spki_hashes, hashes)) { 888 failure_log->append("Rejecting public key chain for domain " + domain + 889 ". Validated chain: " + HashesToBase64String(hashes) + 890 ", matches one or more bad hashes: " + 891 HashesToBase64String(pkp.bad_spki_hashes)); 892 return false; 893 } 894 895 // If there are no pins, then any valid chain is acceptable. 896 if (pkp.spki_hashes.empty()) 897 return true; 898 899 if (HashesIntersect(pkp.spki_hashes, hashes)) { 900 return true; 901 } 902 903 failure_log->append("Rejecting public key chain for domain " + domain + 904 ". Validated chain: " + HashesToBase64String(hashes) + 905 ", expected: " + HashesToBase64String(pkp.spki_hashes)); 906 return false; 907 } 908 909 bool TransportSecurityState::DomainState::ShouldUpgradeToSSL() const { 910 return sts.upgrade_mode == MODE_FORCE_HTTPS; 911 } 912 913 bool TransportSecurityState::DomainState::ShouldSSLErrorsBeFatal() const { 914 return true; 915 } 916 917 bool TransportSecurityState::DomainState::HasPublicKeyPins() const { 918 return pkp.spki_hashes.size() > 0 || pkp.bad_spki_hashes.size() > 0; 919 } 920 921 TransportSecurityState::DomainState::PKPState::PKPState() { 922 } 923 924 TransportSecurityState::DomainState::PKPState::~PKPState() { 925 } 926 927 } // namespace 928