| 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 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 93 DCHECK(CalledOnValidThread()); | 93 DCHECK(CalledOnValidThread()); |
| 94 } | 94 } |
| 95 | 95 |
| 96 TransportSecurityState::Iterator::Iterator(const TransportSecurityState& state) | 96 TransportSecurityState::Iterator::Iterator(const TransportSecurityState& state) |
| 97 : iterator_(state.enabled_hosts_.begin()), | 97 : iterator_(state.enabled_hosts_.begin()), |
| 98 end_(state.enabled_hosts_.end()) { | 98 end_(state.enabled_hosts_.end()) { |
| 99 } | 99 } |
| 100 | 100 |
| 101 TransportSecurityState::Iterator::~Iterator() {} | 101 TransportSecurityState::Iterator::~Iterator() {} |
| 102 | 102 |
| 103 bool TransportSecurityState::ShouldSSLErrorsBeFatal(const std::string& host, | 103 bool TransportSecurityState::ShouldSSLErrorsBeFatal(const std::string& host) { |
| 104 bool sni_enabled) { | |
| 105 DomainState state; | 104 DomainState state; |
| 106 if (GetStaticDomainState(host, sni_enabled, &state)) | 105 if (GetStaticDomainState(host, &state)) |
| 107 return true; | 106 return true; |
| 108 return GetDynamicDomainState(host, &state); | 107 return GetDynamicDomainState(host, &state); |
| 109 } | 108 } |
| 110 | 109 |
| 111 bool TransportSecurityState::ShouldUpgradeToSSL(const std::string& host, | 110 bool TransportSecurityState::ShouldUpgradeToSSL(const std::string& host) { |
| 112 bool sni_enabled) { | |
| 113 DomainState dynamic_state; | 111 DomainState dynamic_state; |
| 114 if (GetDynamicDomainState(host, &dynamic_state)) | 112 if (GetDynamicDomainState(host, &dynamic_state)) |
| 115 return dynamic_state.ShouldUpgradeToSSL(); | 113 return dynamic_state.ShouldUpgradeToSSL(); |
| 116 | 114 |
| 117 DomainState static_state; | 115 DomainState static_state; |
| 118 if (GetStaticDomainState(host, sni_enabled, &static_state) && | 116 if (GetStaticDomainState(host, &static_state) && |
| 119 static_state.ShouldUpgradeToSSL()) { | 117 static_state.ShouldUpgradeToSSL()) { |
| 120 return true; | 118 return true; |
| 121 } | 119 } |
| 122 | 120 |
| 123 return false; | 121 return false; |
| 124 } | 122 } |
| 125 | 123 |
| 126 bool TransportSecurityState::CheckPublicKeyPins( | 124 bool TransportSecurityState::CheckPublicKeyPins( |
| 127 const std::string& host, | 125 const std::string& host, |
| 128 bool sni_available, | |
| 129 bool is_issued_by_known_root, | 126 bool is_issued_by_known_root, |
| 130 const HashValueVector& public_key_hashes, | 127 const HashValueVector& public_key_hashes, |
| 131 std::string* pinning_failure_log) { | 128 std::string* pinning_failure_log) { |
| 132 // Perform pin validation if, and only if, all these conditions obtain: | 129 // Perform pin validation if, and only if, all these conditions obtain: |
| 133 // | 130 // |
| 134 // * the server's certificate chain chains up to a known root (i.e. not a | 131 // * the server's certificate chain chains up to a known root (i.e. not a |
| 135 // user-installed trust anchor); and | 132 // user-installed trust anchor); and |
| 136 // * the server actually has public key pins. | 133 // * the server actually has public key pins. |
| 137 if (!is_issued_by_known_root || !HasPublicKeyPins(host, sni_available)) { | 134 if (!is_issued_by_known_root || !HasPublicKeyPins(host)) { |
| 138 return true; | 135 return true; |
| 139 } | 136 } |
| 140 | 137 |
| 141 bool pins_are_valid = CheckPublicKeyPinsImpl( | 138 bool pins_are_valid = CheckPublicKeyPinsImpl( |
| 142 host, sni_available, public_key_hashes, pinning_failure_log); | 139 host, public_key_hashes, pinning_failure_log); |
| 143 if (!pins_are_valid) { | 140 if (!pins_are_valid) { |
| 144 LOG(ERROR) << *pinning_failure_log; | 141 LOG(ERROR) << *pinning_failure_log; |
| 145 ReportUMAOnPinFailure(host); | 142 ReportUMAOnPinFailure(host); |
| 146 } | 143 } |
| 147 | 144 |
| 148 UMA_HISTOGRAM_BOOLEAN("Net.PublicKeyPinSuccess", pins_are_valid); | 145 UMA_HISTOGRAM_BOOLEAN("Net.PublicKeyPinSuccess", pins_are_valid); |
| 149 return pins_are_valid; | 146 return pins_are_valid; |
| 150 } | 147 } |
| 151 | 148 |
| 152 bool TransportSecurityState::HasPublicKeyPins(const std::string& host, | 149 bool TransportSecurityState::HasPublicKeyPins(const std::string& host) { |
| 153 bool sni_enabled) { | |
| 154 DomainState dynamic_state; | 150 DomainState dynamic_state; |
| 155 if (GetDynamicDomainState(host, &dynamic_state)) | 151 if (GetDynamicDomainState(host, &dynamic_state)) |
| 156 return dynamic_state.HasPublicKeyPins(); | 152 return dynamic_state.HasPublicKeyPins(); |
| 157 | 153 |
| 158 DomainState static_state; | 154 DomainState static_state; |
| 159 if (GetStaticDomainState(host, sni_enabled, &static_state)) { | 155 if (GetStaticDomainState(host, &static_state)) { |
| 160 if (static_state.HasPublicKeyPins()) | 156 if (static_state.HasPublicKeyPins()) |
| 161 return true; | 157 return true; |
| 162 } | 158 } |
| 163 | 159 |
| 164 return false; | 160 return false; |
| 165 } | 161 } |
| 166 | 162 |
| 167 void TransportSecurityState::SetDelegate( | 163 void TransportSecurityState::SetDelegate( |
| 168 TransportSecurityState::Delegate* delegate) { | 164 TransportSecurityState::Delegate* delegate) { |
| 169 DCHECK(CalledOnValidThread()); | 165 DCHECK(CalledOnValidThread()); |
| (...skipping 558 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 728 | 724 |
| 729 domain_state.pkp.last_observed = base::Time::Now(); | 725 domain_state.pkp.last_observed = base::Time::Now(); |
| 730 domain_state.pkp.include_subdomains = include_subdomains; | 726 domain_state.pkp.include_subdomains = include_subdomains; |
| 731 domain_state.pkp.expiry = expiry; | 727 domain_state.pkp.expiry = expiry; |
| 732 domain_state.pkp.spki_hashes = hashes; | 728 domain_state.pkp.spki_hashes = hashes; |
| 733 EnableHost(host, domain_state); | 729 EnableHost(host, domain_state); |
| 734 return true; | 730 return true; |
| 735 } | 731 } |
| 736 | 732 |
| 737 // static | 733 // static |
| 738 bool TransportSecurityState::IsGooglePinnedProperty(const std::string& host, | 734 bool TransportSecurityState::IsGooglePinnedProperty(const std::string& host) { |
| 739 bool sni_enabled) { | |
| 740 std::string canonicalized_host = CanonicalizeHost(host); | 735 std::string canonicalized_host = CanonicalizeHost(host); |
| 741 const struct HSTSPreload* entry = | 736 const struct HSTSPreload* entry = |
| 742 GetHSTSPreload(canonicalized_host, kPreloadedSTS, kNumPreloadedSTS); | 737 GetHSTSPreload(canonicalized_host, kPreloadedSTS, kNumPreloadedSTS); |
| 743 | 738 |
| 744 if (entry && entry->pins.required_hashes == kGoogleAcceptableCerts) | 739 return entry && entry->pins.required_hashes == kGoogleAcceptableCerts; |
| 745 return true; | |
| 746 | |
| 747 if (sni_enabled) { | |
| 748 entry = GetHSTSPreload(canonicalized_host, kPreloadedSNISTS, | |
| 749 kNumPreloadedSNISTS); | |
| 750 if (entry && entry->pins.required_hashes == kGoogleAcceptableCerts) | |
| 751 return true; | |
| 752 } | |
| 753 | |
| 754 return false; | |
| 755 } | 740 } |
| 756 | 741 |
| 757 // static | 742 // static |
| 758 void TransportSecurityState::ReportUMAOnPinFailure(const std::string& host) { | 743 void TransportSecurityState::ReportUMAOnPinFailure(const std::string& host) { |
| 759 std::string canonicalized_host = CanonicalizeHost(host); | 744 std::string canonicalized_host = CanonicalizeHost(host); |
| 760 | 745 |
| 761 const struct HSTSPreload* entry = | 746 const struct HSTSPreload* entry = |
| 762 GetHSTSPreload(canonicalized_host, kPreloadedSTS, kNumPreloadedSTS); | 747 GetHSTSPreload(canonicalized_host, kPreloadedSTS, kNumPreloadedSTS); |
| 763 | 748 |
| 764 if (!entry) { | 749 if (!entry) { |
| 765 entry = GetHSTSPreload(canonicalized_host, kPreloadedSNISTS, | |
| 766 kNumPreloadedSNISTS); | |
| 767 } | |
| 768 | |
| 769 if (!entry) { | |
| 770 // We don't care to report pin failures for dynamic pins. | 750 // We don't care to report pin failures for dynamic pins. |
| 771 return; | 751 return; |
| 772 } | 752 } |
| 773 | 753 |
| 774 DCHECK(entry); | 754 DCHECK(entry); |
| 775 DCHECK(entry->pins.required_hashes); | 755 DCHECK(entry->pins.required_hashes); |
| 776 DCHECK(entry->second_level_domain_name != DOMAIN_NOT_PINNED); | 756 DCHECK(entry->second_level_domain_name != DOMAIN_NOT_PINNED); |
| 777 | 757 |
| 778 UMA_HISTOGRAM_ENUMERATION("Net.PublicKeyPinFailureDomain", | 758 UMA_HISTOGRAM_ENUMERATION("Net.PublicKeyPinFailureDomain", |
| 779 entry->second_level_domain_name, DOMAIN_NUM_EVENTS); | 759 entry->second_level_domain_name, DOMAIN_NUM_EVENTS); |
| 780 } | 760 } |
| 781 | 761 |
| 782 // static | 762 // static |
| 783 bool TransportSecurityState::IsBuildTimely() { | 763 bool TransportSecurityState::IsBuildTimely() { |
| 784 const base::Time build_time = base::GetBuildTime(); | 764 const base::Time build_time = base::GetBuildTime(); |
| 785 // We consider built-in information to be timely for 10 weeks. | 765 // We consider built-in information to be timely for 10 weeks. |
| 786 return (base::Time::Now() - build_time).InDays() < 70 /* 10 weeks */; | 766 return (base::Time::Now() - build_time).InDays() < 70 /* 10 weeks */; |
| 787 } | 767 } |
| 788 | 768 |
| 789 bool TransportSecurityState::CheckPublicKeyPinsImpl( | 769 bool TransportSecurityState::CheckPublicKeyPinsImpl( |
| 790 const std::string& host, | 770 const std::string& host, |
| 791 bool sni_enabled, | |
| 792 const HashValueVector& hashes, | 771 const HashValueVector& hashes, |
| 793 std::string* failure_log) { | 772 std::string* failure_log) { |
| 794 DomainState dynamic_state; | 773 DomainState dynamic_state; |
| 795 if (GetDynamicDomainState(host, &dynamic_state)) | 774 if (GetDynamicDomainState(host, &dynamic_state)) |
| 796 return dynamic_state.CheckPublicKeyPins(hashes, failure_log); | 775 return dynamic_state.CheckPublicKeyPins(hashes, failure_log); |
| 797 | 776 |
| 798 DomainState static_state; | 777 DomainState static_state; |
| 799 if (GetStaticDomainState(host, sni_enabled, &static_state)) | 778 if (GetStaticDomainState(host, &static_state)) |
| 800 return static_state.CheckPublicKeyPins(hashes, failure_log); | 779 return static_state.CheckPublicKeyPins(hashes, failure_log); |
| 801 | 780 |
| 802 // HasPublicKeyPins should have returned true in order for this method | 781 // HasPublicKeyPins should have returned true in order for this method |
| 803 // to have been called, so if we fall through to here, it's an error. | 782 // to have been called, so if we fall through to here, it's an error. |
| 804 return false; | 783 return false; |
| 805 } | 784 } |
| 806 | 785 |
| 807 bool TransportSecurityState::GetStaticDomainState(const std::string& host, | 786 bool TransportSecurityState::GetStaticDomainState(const std::string& host, |
| 808 bool sni_enabled, | |
| 809 DomainState* out) const { | 787 DomainState* out) const { |
| 810 DCHECK(CalledOnValidThread()); | 788 DCHECK(CalledOnValidThread()); |
| 811 | 789 |
| 812 const std::string canonicalized_host = CanonicalizeHost(host); | 790 const std::string canonicalized_host = CanonicalizeHost(host); |
| 813 | 791 |
| 814 out->sts.upgrade_mode = DomainState::MODE_FORCE_HTTPS; | 792 out->sts.upgrade_mode = DomainState::MODE_FORCE_HTTPS; |
| 815 out->sts.include_subdomains = false; | 793 out->sts.include_subdomains = false; |
| 816 out->pkp.include_subdomains = false; | 794 out->pkp.include_subdomains = false; |
| 817 | 795 |
| 818 const bool is_build_timely = IsBuildTimely(); | 796 const bool is_build_timely = IsBuildTimely(); |
| 819 | 797 |
| 820 for (size_t i = 0; canonicalized_host[i]; i += canonicalized_host[i] + 1) { | 798 for (size_t i = 0; canonicalized_host[i]; i += canonicalized_host[i] + 1) { |
| 821 std::string host_sub_chunk(&canonicalized_host[i], | 799 std::string host_sub_chunk(&canonicalized_host[i], |
| 822 canonicalized_host.size() - i); | 800 canonicalized_host.size() - i); |
| 823 out->domain = DNSDomainToString(host_sub_chunk); | 801 out->domain = DNSDomainToString(host_sub_chunk); |
| 824 bool ret; | 802 bool ret; |
| 825 if (is_build_timely && HasPreload(kPreloadedSTS, | 803 if (is_build_timely && HasPreload(kPreloadedSTS, |
| 826 kNumPreloadedSTS, | 804 kNumPreloadedSTS, |
| 827 canonicalized_host, | 805 canonicalized_host, |
| 828 i, | 806 i, |
| 829 enable_static_pins_, | 807 enable_static_pins_, |
| 830 out, | 808 out, |
| 831 &ret)) { | 809 &ret)) { |
| 832 return ret; | 810 return ret; |
| 833 } | 811 } |
| 834 if (sni_enabled && is_build_timely && HasPreload(kPreloadedSNISTS, | |
| 835 kNumPreloadedSNISTS, | |
| 836 canonicalized_host, | |
| 837 i, | |
| 838 enable_static_pins_, | |
| 839 out, | |
| 840 &ret)) { | |
| 841 return ret; | |
| 842 } | |
| 843 } | 812 } |
| 844 | 813 |
| 845 return false; | 814 return false; |
| 846 } | 815 } |
| 847 | 816 |
| 848 bool TransportSecurityState::GetDynamicDomainState(const std::string& host, | 817 bool TransportSecurityState::GetDynamicDomainState(const std::string& host, |
| 849 DomainState* result) { | 818 DomainState* result) { |
| 850 DCHECK(CalledOnValidThread()); | 819 DCHECK(CalledOnValidThread()); |
| 851 | 820 |
| 852 DomainState state; | 821 DomainState state; |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 949 return pkp.spki_hashes.size() > 0 || pkp.bad_spki_hashes.size() > 0; | 918 return pkp.spki_hashes.size() > 0 || pkp.bad_spki_hashes.size() > 0; |
| 950 } | 919 } |
| 951 | 920 |
| 952 TransportSecurityState::DomainState::PKPState::PKPState() { | 921 TransportSecurityState::DomainState::PKPState::PKPState() { |
| 953 } | 922 } |
| 954 | 923 |
| 955 TransportSecurityState::DomainState::PKPState::~PKPState() { | 924 TransportSecurityState::DomainState::PKPState::~PKPState() { |
| 956 } | 925 } |
| 957 | 926 |
| 958 } // namespace | 927 } // namespace |
| OLD | NEW |