| 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 "net/http/transport_security_state.h" | 5 #include "net/http/transport_security_state.h" |
| 6 | 6 |
| 7 #if defined(USE_OPENSSL) | 7 #if defined(USE_OPENSSL) |
| 8 #include <openssl/ecdsa.h> | 8 #include <openssl/ecdsa.h> |
| 9 #include <openssl/ssl.h> | 9 #include <openssl/ssl.h> |
| 10 #else // !defined(USE_OPENSSL) | 10 #else // !defined(USE_OPENSSL) |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 160 | 160 |
| 161 return false; | 161 return false; |
| 162 } | 162 } |
| 163 | 163 |
| 164 void TransportSecurityState::SetDelegate( | 164 void TransportSecurityState::SetDelegate( |
| 165 TransportSecurityState::Delegate* delegate) { | 165 TransportSecurityState::Delegate* delegate) { |
| 166 DCHECK(CalledOnValidThread()); | 166 DCHECK(CalledOnValidThread()); |
| 167 delegate_ = delegate; | 167 delegate_ = delegate; |
| 168 } | 168 } |
| 169 | 169 |
| 170 void TransportSecurityState::AddHSTSInternal( |
| 171 const std::string& host, |
| 172 TransportSecurityState::DomainState::UpgradeMode upgrade_mode, |
| 173 const base::Time& expiry, |
| 174 bool include_subdomains) { |
| 175 DCHECK(CalledOnValidThread()); |
| 176 |
| 177 // Copy-and-modify the existing DomainState for this host (if any). |
| 178 DomainState domain_state; |
| 179 const std::string canonicalized_host = CanonicalizeHost(host); |
| 180 const std::string hashed_host = HashHost(canonicalized_host); |
| 181 DomainStateMap::const_iterator i = enabled_hosts_.find(hashed_host); |
| 182 if (i != enabled_hosts_.end()) |
| 183 domain_state = i->second; |
| 184 |
| 185 domain_state.sts.last_observed = base::Time::Now(); |
| 186 domain_state.sts.include_subdomains = include_subdomains; |
| 187 domain_state.sts.expiry = expiry; |
| 188 domain_state.sts.upgrade_mode = upgrade_mode; |
| 189 EnableHost(host, domain_state); |
| 190 } |
| 191 |
| 192 void TransportSecurityState::AddHPKPInternal(const std::string& host, |
| 193 const base::Time& last_observed, |
| 194 const base::Time& expiry, |
| 195 bool include_subdomains, |
| 196 const HashValueVector& hashes) { |
| 197 DCHECK(CalledOnValidThread()); |
| 198 |
| 199 // Copy-and-modify the existing DomainState for this host (if any). |
| 200 DomainState domain_state; |
| 201 const std::string canonicalized_host = CanonicalizeHost(host); |
| 202 const std::string hashed_host = HashHost(canonicalized_host); |
| 203 DomainStateMap::const_iterator i = enabled_hosts_.find(hashed_host); |
| 204 if (i != enabled_hosts_.end()) |
| 205 domain_state = i->second; |
| 206 |
| 207 domain_state.pkp.last_observed = last_observed; |
| 208 domain_state.pkp.expiry = expiry; |
| 209 domain_state.pkp.include_subdomains = include_subdomains; |
| 210 domain_state.pkp.spki_hashes = hashes; |
| 211 EnableHost(host, domain_state); |
| 212 } |
| 213 |
| 170 void TransportSecurityState::EnableHost(const std::string& host, | 214 void TransportSecurityState::EnableHost(const std::string& host, |
| 171 const DomainState& state) { | 215 const DomainState& state) { |
| 172 DCHECK(CalledOnValidThread()); | 216 DCHECK(CalledOnValidThread()); |
| 173 | 217 |
| 174 const std::string canonicalized_host = CanonicalizeHost(host); | 218 const std::string canonicalized_host = CanonicalizeHost(host); |
| 175 if (canonicalized_host.empty()) | 219 if (canonicalized_host.empty()) |
| 176 return; | 220 return; |
| 177 | 221 |
| 178 DomainState state_copy(state); | 222 DomainState state_copy(state); |
| 179 // No need to store this value since it is redundant. (|canonicalized_host| | 223 // No need to store this value since it is redundant. (|canonicalized_host| |
| 180 // is the map key.) | 224 // is the map key.) |
| 181 state_copy.domain.clear(); | 225 state_copy.sts.domain.clear(); |
| 226 state_copy.pkp.domain.clear(); |
| 182 | 227 |
| 183 enabled_hosts_[HashHost(canonicalized_host)] = state_copy; | 228 enabled_hosts_[HashHost(canonicalized_host)] = state_copy; |
| 184 DirtyNotify(); | 229 DirtyNotify(); |
| 185 } | 230 } |
| 186 | 231 |
| 187 bool TransportSecurityState::DeleteDynamicDataForHost(const std::string& host) { | 232 bool TransportSecurityState::DeleteDynamicDataForHost(const std::string& host) { |
| 188 DCHECK(CalledOnValidThread()); | 233 DCHECK(CalledOnValidThread()); |
| 189 | 234 |
| 190 const std::string canonicalized_host = CanonicalizeHost(host); | 235 const std::string canonicalized_host = CanonicalizeHost(host); |
| 191 if (canonicalized_host.empty()) | 236 if (canonicalized_host.empty()) |
| (...skipping 13 matching lines...) Expand all Loading... |
| 205 DCHECK(CalledOnValidThread()); | 250 DCHECK(CalledOnValidThread()); |
| 206 enabled_hosts_.clear(); | 251 enabled_hosts_.clear(); |
| 207 } | 252 } |
| 208 | 253 |
| 209 void TransportSecurityState::DeleteAllDynamicDataSince(const base::Time& time) { | 254 void TransportSecurityState::DeleteAllDynamicDataSince(const base::Time& time) { |
| 210 DCHECK(CalledOnValidThread()); | 255 DCHECK(CalledOnValidThread()); |
| 211 | 256 |
| 212 bool dirtied = false; | 257 bool dirtied = false; |
| 213 DomainStateMap::iterator i = enabled_hosts_.begin(); | 258 DomainStateMap::iterator i = enabled_hosts_.begin(); |
| 214 while (i != enabled_hosts_.end()) { | 259 while (i != enabled_hosts_.end()) { |
| 215 if (i->second.sts.last_observed >= time && | 260 // Clear STS and PKP state independently. |
| 216 i->second.pkp.last_observed >= time) { | 261 if (i->second.sts.last_observed >= time) { |
| 262 dirtied = true; |
| 263 i->second.sts.upgrade_mode = DomainState::MODE_DEFAULT; |
| 264 } |
| 265 if (i->second.pkp.last_observed >= time) { |
| 266 dirtied = true; |
| 267 i->second.pkp.spki_hashes.clear(); |
| 268 i->second.pkp.expiry = base::Time(); |
| 269 } |
| 270 |
| 271 // If both are now invalid, drop the entry altogether. |
| 272 if (!i->second.ShouldUpgradeToSSL() && !i->second.HasPublicKeyPins()) { |
| 217 dirtied = true; | 273 dirtied = true; |
| 218 enabled_hosts_.erase(i++); | 274 enabled_hosts_.erase(i++); |
| 219 continue; | 275 continue; |
| 220 } | 276 } |
| 221 | 277 |
| 222 if (i->second.sts.last_observed >= time) { | |
| 223 dirtied = true; | |
| 224 i->second.sts.upgrade_mode = DomainState::MODE_DEFAULT; | |
| 225 } else if (i->second.pkp.last_observed >= time) { | |
| 226 dirtied = true; | |
| 227 i->second.pkp.spki_hashes.clear(); | |
| 228 i->second.pkp.expiry = base::Time(); | |
| 229 } | |
| 230 ++i; | 278 ++i; |
| 231 } | 279 } |
| 232 | 280 |
| 233 if (dirtied) | 281 if (dirtied) |
| 234 DirtyNotify(); | 282 DirtyNotify(); |
| 235 } | 283 } |
| 236 | 284 |
| 237 TransportSecurityState::~TransportSecurityState() { | 285 TransportSecurityState::~TransportSecurityState() { |
| 238 DCHECK(CalledOnValidThread()); | 286 DCHECK(CalledOnValidThread()); |
| 239 } | 287 } |
| (...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 614 | 662 |
| 615 return found; | 663 return found; |
| 616 } | 664 } |
| 617 | 665 |
| 618 bool TransportSecurityState::AddHSTSHeader(const std::string& host, | 666 bool TransportSecurityState::AddHSTSHeader(const std::string& host, |
| 619 const std::string& value) { | 667 const std::string& value) { |
| 620 DCHECK(CalledOnValidThread()); | 668 DCHECK(CalledOnValidThread()); |
| 621 | 669 |
| 622 base::Time now = base::Time::Now(); | 670 base::Time now = base::Time::Now(); |
| 623 base::TimeDelta max_age; | 671 base::TimeDelta max_age; |
| 624 TransportSecurityState::DomainState domain_state; | 672 bool include_subdomains; |
| 625 GetDynamicDomainState(host, &domain_state); | 673 if (!ParseHSTSHeader(value, &max_age, &include_subdomains)) { |
| 626 if (ParseHSTSHeader(value, &max_age, &domain_state.sts.include_subdomains)) { | 674 return false; |
| 627 // Handle max-age == 0. | |
| 628 if (max_age.InSeconds() == 0) | |
| 629 domain_state.sts.upgrade_mode = DomainState::MODE_DEFAULT; | |
| 630 else | |
| 631 domain_state.sts.upgrade_mode = DomainState::MODE_FORCE_HTTPS; | |
| 632 domain_state.sts.last_observed = now; | |
| 633 domain_state.sts.expiry = now + max_age; | |
| 634 EnableHost(host, domain_state); | |
| 635 return true; | |
| 636 } | 675 } |
| 637 return false; | 676 |
| 677 // Handle max-age == 0. |
| 678 DomainState::UpgradeMode upgrade_mode; |
| 679 if (max_age.InSeconds() == 0) { |
| 680 upgrade_mode = DomainState::MODE_DEFAULT; |
| 681 } else { |
| 682 upgrade_mode = DomainState::MODE_FORCE_HTTPS; |
| 683 } |
| 684 |
| 685 AddHSTSInternal(host, upgrade_mode, now + max_age, include_subdomains); |
| 686 return true; |
| 638 } | 687 } |
| 639 | 688 |
| 640 bool TransportSecurityState::AddHPKPHeader(const std::string& host, | 689 bool TransportSecurityState::AddHPKPHeader(const std::string& host, |
| 641 const std::string& value, | 690 const std::string& value, |
| 642 const SSLInfo& ssl_info) { | 691 const SSLInfo& ssl_info) { |
| 643 DCHECK(CalledOnValidThread()); | 692 DCHECK(CalledOnValidThread()); |
| 644 | 693 |
| 645 base::Time now = base::Time::Now(); | 694 base::Time now = base::Time::Now(); |
| 646 base::TimeDelta max_age; | 695 base::TimeDelta max_age; |
| 647 TransportSecurityState::DomainState domain_state; | 696 bool include_subdomains; |
| 648 GetDynamicDomainState(host, &domain_state); | 697 HashValueVector spki_hashes; |
| 649 if (ParseHPKPHeader(value, | 698 if (!ParseHPKPHeader(value, ssl_info.public_key_hashes, &max_age, |
| 650 ssl_info.public_key_hashes, | 699 &include_subdomains, &spki_hashes)) { |
| 651 &max_age, | 700 return false; |
| 652 &domain_state.pkp.include_subdomains, | |
| 653 &domain_state.pkp.spki_hashes)) { | |
| 654 // Handle max-age == 0. | |
| 655 if (max_age.InSeconds() == 0) | |
| 656 domain_state.pkp.spki_hashes.clear(); | |
| 657 domain_state.pkp.last_observed = now; | |
| 658 domain_state.pkp.expiry = now + max_age; | |
| 659 EnableHost(host, domain_state); | |
| 660 return true; | |
| 661 } | 701 } |
| 662 return false; | 702 // Handle max-age == 0. |
| 703 if (max_age.InSeconds() == 0) |
| 704 spki_hashes.clear(); |
| 705 AddHPKPInternal(host, now, now + max_age, include_subdomains, spki_hashes); |
| 706 return true; |
| 663 } | 707 } |
| 664 | 708 |
| 665 bool TransportSecurityState::AddHSTS(const std::string& host, | 709 void TransportSecurityState::AddHSTS(const std::string& host, |
| 666 const base::Time& expiry, | 710 const base::Time& expiry, |
| 667 bool include_subdomains) { | 711 bool include_subdomains) { |
| 668 DCHECK(CalledOnValidThread()); | 712 DCHECK(CalledOnValidThread()); |
| 669 | 713 AddHSTSInternal(host, DomainState::MODE_FORCE_HTTPS, expiry, |
| 670 // Copy-and-modify the existing DomainState for this host (if any). | 714 include_subdomains); |
| 671 TransportSecurityState::DomainState domain_state; | |
| 672 const std::string canonicalized_host = CanonicalizeHost(host); | |
| 673 const std::string hashed_host = HashHost(canonicalized_host); | |
| 674 DomainStateMap::const_iterator i = enabled_hosts_.find( | |
| 675 hashed_host); | |
| 676 if (i != enabled_hosts_.end()) | |
| 677 domain_state = i->second; | |
| 678 | |
| 679 domain_state.sts.last_observed = base::Time::Now(); | |
| 680 domain_state.sts.include_subdomains = include_subdomains; | |
| 681 domain_state.sts.expiry = expiry; | |
| 682 domain_state.sts.upgrade_mode = DomainState::MODE_FORCE_HTTPS; | |
| 683 EnableHost(host, domain_state); | |
| 684 return true; | |
| 685 } | 715 } |
| 686 | 716 |
| 687 bool TransportSecurityState::AddHPKP(const std::string& host, | 717 void TransportSecurityState::AddHPKP(const std::string& host, |
| 688 const base::Time& expiry, | 718 const base::Time& expiry, |
| 689 bool include_subdomains, | 719 bool include_subdomains, |
| 690 const HashValueVector& hashes) { | 720 const HashValueVector& hashes) { |
| 691 DCHECK(CalledOnValidThread()); | 721 DCHECK(CalledOnValidThread()); |
| 692 | 722 AddHPKPInternal(host, base::Time::Now(), expiry, include_subdomains, hashes); |
| 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.pkp.last_observed = base::Time::Now(); | |
| 703 domain_state.pkp.include_subdomains = include_subdomains; | |
| 704 domain_state.pkp.expiry = expiry; | |
| 705 domain_state.pkp.spki_hashes = hashes; | |
| 706 EnableHost(host, domain_state); | |
| 707 return true; | |
| 708 } | 723 } |
| 709 | 724 |
| 710 // static | 725 // static |
| 711 bool TransportSecurityState::IsGooglePinnedProperty(const std::string& host) { | 726 bool TransportSecurityState::IsGooglePinnedProperty(const std::string& host) { |
| 712 PreloadResult result; | 727 PreloadResult result; |
| 713 return DecodeHSTSPreload(host, &result) && result.has_pins && | 728 return DecodeHSTSPreload(host, &result) && result.has_pins && |
| 714 kPinsets[result.pinset_id].accepted_pins == kGoogleAcceptableCerts; | 729 kPinsets[result.pinset_id].accepted_pins == kGoogleAcceptableCerts; |
| 715 } | 730 } |
| 716 | 731 |
| 717 // static | 732 // static |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 769 out->sts.include_subdomains = false; | 784 out->sts.include_subdomains = false; |
| 770 out->pkp.include_subdomains = false; | 785 out->pkp.include_subdomains = false; |
| 771 | 786 |
| 772 if (!IsBuildTimely()) | 787 if (!IsBuildTimely()) |
| 773 return false; | 788 return false; |
| 774 | 789 |
| 775 PreloadResult result; | 790 PreloadResult result; |
| 776 if (!DecodeHSTSPreload(host, &result)) | 791 if (!DecodeHSTSPreload(host, &result)) |
| 777 return false; | 792 return false; |
| 778 | 793 |
| 779 out->domain = host.substr(result.hostname_offset); | 794 out->sts.domain = host.substr(result.hostname_offset); |
| 795 out->pkp.domain = out->sts.domain; |
| 780 out->sts.include_subdomains = result.sts_include_subdomains; | 796 out->sts.include_subdomains = result.sts_include_subdomains; |
| 781 out->sts.last_observed = base::GetBuildTime(); | 797 out->sts.last_observed = base::GetBuildTime(); |
| 782 out->sts.upgrade_mode = | 798 out->sts.upgrade_mode = |
| 783 TransportSecurityState::DomainState::MODE_DEFAULT; | 799 TransportSecurityState::DomainState::MODE_DEFAULT; |
| 784 if (result.force_https) { | 800 if (result.force_https) { |
| 785 out->sts.upgrade_mode = | 801 out->sts.upgrade_mode = |
| 786 TransportSecurityState::DomainState::MODE_FORCE_HTTPS; | 802 TransportSecurityState::DomainState::MODE_FORCE_HTTPS; |
| 787 } | 803 } |
| 788 | 804 |
| 789 if (enable_static_pins_ && result.has_pins) { | 805 if (enable_static_pins_ && result.has_pins) { |
| (...skipping 27 matching lines...) Expand all Loading... |
| 817 DomainState* result) { | 833 DomainState* result) { |
| 818 DCHECK(CalledOnValidThread()); | 834 DCHECK(CalledOnValidThread()); |
| 819 | 835 |
| 820 DomainState state; | 836 DomainState state; |
| 821 const std::string canonicalized_host = CanonicalizeHost(host); | 837 const std::string canonicalized_host = CanonicalizeHost(host); |
| 822 if (canonicalized_host.empty()) | 838 if (canonicalized_host.empty()) |
| 823 return false; | 839 return false; |
| 824 | 840 |
| 825 base::Time current_time(base::Time::Now()); | 841 base::Time current_time(base::Time::Now()); |
| 826 | 842 |
| 843 bool found_sts = false; |
| 844 bool found_pkp = false; |
| 827 for (size_t i = 0; canonicalized_host[i]; i += canonicalized_host[i] + 1) { | 845 for (size_t i = 0; canonicalized_host[i]; i += canonicalized_host[i] + 1) { |
| 828 std::string host_sub_chunk(&canonicalized_host[i], | 846 std::string host_sub_chunk(&canonicalized_host[i], |
| 829 canonicalized_host.size() - i); | 847 canonicalized_host.size() - i); |
| 830 DomainStateMap::iterator j = | 848 DomainStateMap::iterator j = |
| 831 enabled_hosts_.find(HashHost(host_sub_chunk)); | 849 enabled_hosts_.find(HashHost(host_sub_chunk)); |
| 832 if (j == enabled_hosts_.end()) | 850 if (j == enabled_hosts_.end()) |
| 833 continue; | 851 continue; |
| 834 | 852 |
| 853 // If both halves of the entry are invalid, drop it. |
| 835 if (current_time > j->second.sts.expiry && | 854 if (current_time > j->second.sts.expiry && |
| 836 current_time > j->second.pkp.expiry) { | 855 current_time > j->second.pkp.expiry) { |
| 837 enabled_hosts_.erase(j); | 856 enabled_hosts_.erase(j); |
| 838 DirtyNotify(); | 857 DirtyNotify(); |
| 839 continue; | 858 continue; |
| 840 } | 859 } |
| 841 | 860 |
| 842 state = j->second; | 861 // If this is the most specific STS match, add it to the result. |
| 843 state.domain = DNSDomainToString(host_sub_chunk); | 862 if (!found_sts && (i == 0 || j->second.sts.include_subdomains) && |
| 844 | 863 current_time <= j->second.sts.expiry && |
| 845 // Succeed if we matched the domain exactly or if subdomain matches are | 864 j->second.ShouldUpgradeToSSL()) { |
| 846 // allowed. | 865 found_sts = true; |
| 847 if (i == 0 || j->second.sts.include_subdomains || | 866 state.sts = j->second.sts; |
| 848 j->second.pkp.include_subdomains) { | 867 state.sts.domain = DNSDomainToString(host_sub_chunk); |
| 849 *result = state; | |
| 850 return true; | |
| 851 } | 868 } |
| 852 | 869 |
| 853 return false; | 870 // If this is the most specific PKP match, add it to the result. |
| 871 if (!found_pkp && (i == 0 || j->second.pkp.include_subdomains) && |
| 872 current_time <= j->second.pkp.expiry && j->second.HasPublicKeyPins()) { |
| 873 found_pkp = true; |
| 874 state.pkp = j->second.pkp; |
| 875 state.pkp.domain = DNSDomainToString(host_sub_chunk); |
| 876 } |
| 877 |
| 878 if (found_sts && found_pkp) |
| 879 break; |
| 854 } | 880 } |
| 855 | 881 |
| 856 return false; | 882 if (!found_sts && !found_pkp) |
| 883 return false; |
| 884 |
| 885 *result = state; |
| 886 return true; |
| 857 } | 887 } |
| 858 | 888 |
| 859 void TransportSecurityState::AddOrUpdateEnabledHosts( | 889 void TransportSecurityState::AddOrUpdateEnabledHosts( |
| 860 const std::string& hashed_host, const DomainState& state) { | 890 const std::string& hashed_host, const DomainState& state) { |
| 861 DCHECK(CalledOnValidThread()); | 891 DCHECK(CalledOnValidThread()); |
| 862 enabled_hosts_[hashed_host] = state; | 892 enabled_hosts_[hashed_host] = state; |
| 863 } | 893 } |
| 864 | 894 |
| 865 TransportSecurityState::DomainState::DomainState() { | 895 TransportSecurityState::DomainState::DomainState() { |
| 866 sts.upgrade_mode = MODE_DEFAULT; | 896 sts.upgrade_mode = MODE_DEFAULT; |
| 867 sts.include_subdomains = false; | 897 sts.include_subdomains = false; |
| 868 pkp.include_subdomains = false; | 898 pkp.include_subdomains = false; |
| 869 } | 899 } |
| 870 | 900 |
| 871 TransportSecurityState::DomainState::~DomainState() { | 901 TransportSecurityState::DomainState::~DomainState() { |
| 872 } | 902 } |
| 873 | 903 |
| 874 bool TransportSecurityState::DomainState::CheckPublicKeyPins( | 904 bool TransportSecurityState::DomainState::CheckPublicKeyPins( |
| 875 const HashValueVector& hashes, std::string* failure_log) const { | 905 const HashValueVector& hashes, std::string* failure_log) const { |
| 876 // Validate that hashes is not empty. By the time this code is called (in | 906 // Validate that hashes is not empty. By the time this code is called (in |
| 877 // production), that should never happen, but it's good to be defensive. | 907 // production), that should never happen, but it's good to be defensive. |
| 878 // And, hashes *can* be empty in some test scenarios. | 908 // And, hashes *can* be empty in some test scenarios. |
| 879 if (hashes.empty()) { | 909 if (hashes.empty()) { |
| 880 failure_log->append( | 910 failure_log->append( |
| 881 "Rejecting empty public key chain for public-key-pinned domains: " + | 911 "Rejecting empty public key chain for public-key-pinned domains: " + |
| 882 domain); | 912 pkp.domain); |
| 883 return false; | 913 return false; |
| 884 } | 914 } |
| 885 | 915 |
| 886 if (HashesIntersect(pkp.bad_spki_hashes, hashes)) { | 916 if (HashesIntersect(pkp.bad_spki_hashes, hashes)) { |
| 887 failure_log->append("Rejecting public key chain for domain " + domain + | 917 failure_log->append("Rejecting public key chain for domain " + pkp.domain + |
| 888 ". Validated chain: " + HashesToBase64String(hashes) + | 918 ". Validated chain: " + HashesToBase64String(hashes) + |
| 889 ", matches one or more bad hashes: " + | 919 ", matches one or more bad hashes: " + |
| 890 HashesToBase64String(pkp.bad_spki_hashes)); | 920 HashesToBase64String(pkp.bad_spki_hashes)); |
| 891 return false; | 921 return false; |
| 892 } | 922 } |
| 893 | 923 |
| 894 // If there are no pins, then any valid chain is acceptable. | 924 // If there are no pins, then any valid chain is acceptable. |
| 895 if (pkp.spki_hashes.empty()) | 925 if (pkp.spki_hashes.empty()) |
| 896 return true; | 926 return true; |
| 897 | 927 |
| 898 if (HashesIntersect(pkp.spki_hashes, hashes)) { | 928 if (HashesIntersect(pkp.spki_hashes, hashes)) { |
| 899 return true; | 929 return true; |
| 900 } | 930 } |
| 901 | 931 |
| 902 failure_log->append("Rejecting public key chain for domain " + domain + | 932 failure_log->append("Rejecting public key chain for domain " + pkp.domain + |
| 903 ". Validated chain: " + HashesToBase64String(hashes) + | 933 ". Validated chain: " + HashesToBase64String(hashes) + |
| 904 ", expected: " + HashesToBase64String(pkp.spki_hashes)); | 934 ", expected: " + HashesToBase64String(pkp.spki_hashes)); |
| 905 return false; | 935 return false; |
| 906 } | 936 } |
| 907 | 937 |
| 908 bool TransportSecurityState::DomainState::ShouldUpgradeToSSL() const { | 938 bool TransportSecurityState::DomainState::ShouldUpgradeToSSL() const { |
| 909 return sts.upgrade_mode == MODE_FORCE_HTTPS; | 939 return sts.upgrade_mode == MODE_FORCE_HTTPS; |
| 910 } | 940 } |
| 911 | 941 |
| 912 bool TransportSecurityState::DomainState::ShouldSSLErrorsBeFatal() const { | 942 bool TransportSecurityState::DomainState::ShouldSSLErrorsBeFatal() const { |
| 943 // Both HSTS and HPKP cause fatal SSL errors, so enable this on the presense |
| 944 // of either. (If neither is active, no DomainState will be returned.) |
| 913 return true; | 945 return true; |
| 914 } | 946 } |
| 915 | 947 |
| 916 bool TransportSecurityState::DomainState::HasPublicKeyPins() const { | 948 bool TransportSecurityState::DomainState::HasPublicKeyPins() const { |
| 917 return pkp.spki_hashes.size() > 0 || pkp.bad_spki_hashes.size() > 0; | 949 return pkp.spki_hashes.size() > 0 || pkp.bad_spki_hashes.size() > 0; |
| 918 } | 950 } |
| 919 | 951 |
| 952 TransportSecurityState::DomainState::STSState::STSState() { |
| 953 } |
| 954 |
| 955 TransportSecurityState::DomainState::STSState::~STSState() { |
| 956 } |
| 957 |
| 920 TransportSecurityState::DomainState::PKPState::PKPState() { | 958 TransportSecurityState::DomainState::PKPState::PKPState() { |
| 921 } | 959 } |
| 922 | 960 |
| 923 TransportSecurityState::DomainState::PKPState::~PKPState() { | 961 TransportSecurityState::DomainState::PKPState::~PKPState() { |
| 924 } | 962 } |
| 925 | 963 |
| 926 } // namespace | 964 } // namespace |
| OLD | NEW |