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 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
77 HashValueVector* out) { | 77 HashValueVector* out) { |
78 HashValue hash(HASH_VALUE_SHA1); | 78 HashValue hash(HASH_VALUE_SHA1); |
79 memcpy(hash.data(), sha1_hash, hash.size()); | 79 memcpy(hash.data(), sha1_hash, hash.size()); |
80 out->push_back(hash); | 80 out->push_back(hash); |
81 return true; | 81 return true; |
82 } | 82 } |
83 | 83 |
84 } // namespace | 84 } // namespace |
85 | 85 |
86 TransportSecurityState::TransportSecurityState() | 86 TransportSecurityState::TransportSecurityState() |
87 : delegate_(NULL) { | 87 : delegate_(NULL), |
88 enable_static_pinning_(true) { | |
89 // Static pinning is only enabled for official builds to make sure that | |
90 // others don't end up with pins that cannot be easily updated. | |
91 #if !defined(OFFICIAL_BUILD) || defined(OS_ANDROID) || defined(OS_IOS) | |
92 enable_static_pinning_ = false; | |
93 #endif | |
88 DCHECK(CalledOnValidThread()); | 94 DCHECK(CalledOnValidThread()); |
89 } | 95 } |
90 | 96 |
91 TransportSecurityState::Iterator::Iterator(const TransportSecurityState& state) | 97 TransportSecurityState::Iterator::Iterator(const TransportSecurityState& state) |
92 : iterator_(state.enabled_hosts_.begin()), | 98 : iterator_(state.enabled_hosts_.begin()), |
93 end_(state.enabled_hosts_.end()) { | 99 end_(state.enabled_hosts_.end()) { |
94 } | 100 } |
95 | 101 |
96 TransportSecurityState::Iterator::~Iterator() {} | 102 TransportSecurityState::Iterator::~Iterator() {} |
97 | 103 |
(...skipping 13 matching lines...) Expand all Loading... | |
111 | 117 |
112 DomainState static_state; | 118 DomainState static_state; |
113 if (GetStaticDomainState(host, sni_enabled, &static_state) && | 119 if (GetStaticDomainState(host, sni_enabled, &static_state) && |
114 static_state.ShouldUpgradeToSSL()) { | 120 static_state.ShouldUpgradeToSSL()) { |
115 return true; | 121 return true; |
116 } | 122 } |
117 | 123 |
118 return false; | 124 return false; |
119 } | 125 } |
120 | 126 |
121 bool TransportSecurityState::CheckPublicKeyPins(const std::string& host, | 127 bool TransportSecurityState::CheckPublicKeyPins( |
122 bool sni_enabled, | 128 const std::string& host, |
123 const HashValueVector& hashes, | 129 bool sni_available, |
124 std::string* failure_log) { | 130 bool is_issued_by_known_root, |
131 const HashValueVector& public_key_hashes, | |
132 std::string* pinning_failure_log) { | |
133 // Perform pin validation if, and only if, all these conditions obtain: | |
134 // | |
135 // * the server's certificate chain chains up to a known root (i.e. not a | |
136 // user-installed trust anchor); and | |
137 // * the build is recent (very old builds should fail open so that users | |
138 // have some chance to recover). | |
139 // | |
140 if (!is_issued_by_known_root || | |
141 !IsBuildTimely() || | |
142 !HasPublicKeyPins(host, sni_available)) { | |
143 return true; | |
Ryan Sleevi
2014/08/07 23:31:19
Re-git-cl-format this?
Ryan Hamilton
2014/08/08 00:54:00
Done.
| |
144 } | |
145 | |
146 bool pins_are_valid = CheckPublicKeyPinsImpl(host, | |
147 sni_available, | |
148 public_key_hashes, | |
149 pinning_failure_log); | |
150 if (!pins_are_valid) { | |
151 LOG(ERROR) << *pinning_failure_log; | |
152 ReportUMAOnPinFailure(host); | |
153 } | |
154 | |
155 UMA_HISTOGRAM_BOOLEAN("Net.PublicKeyPinSuccess", pins_are_valid); | |
156 return pins_are_valid; | |
157 } | |
158 | |
159 bool TransportSecurityState::CheckPublicKeyPinsImpl( | |
160 const std::string& host, | |
161 bool sni_enabled, | |
162 const HashValueVector& hashes, | |
163 std::string* failure_log) { | |
125 DomainState dynamic_state; | 164 DomainState dynamic_state; |
126 if (GetDynamicDomainState(host, &dynamic_state)) | 165 if (GetDynamicDomainState(host, &dynamic_state)) |
127 return dynamic_state.CheckPublicKeyPins(hashes, failure_log); | 166 return dynamic_state.CheckPublicKeyPins(hashes, failure_log); |
128 | 167 |
129 DomainState static_state; | 168 DomainState static_state; |
130 if (GetStaticDomainState(host, sni_enabled, &static_state) && | 169 if (GetStaticDomainState(host, sni_enabled, &static_state)) |
131 static_state.CheckPublicKeyPins(hashes, failure_log)) { | 170 return static_state.CheckPublicKeyPins(hashes, failure_log); |
132 return true; | |
133 } | |
134 | 171 |
172 // HasPublicKeyPins should have returned true in order for this method | |
173 // to have been called, so if we fall through to here, it's an error. | |
135 return false; | 174 return false; |
136 } | 175 } |
137 | 176 |
138 bool TransportSecurityState::HasPublicKeyPins(const std::string& host, | 177 bool TransportSecurityState::HasPublicKeyPins(const std::string& host, |
139 bool sni_enabled) { | 178 bool sni_enabled) { |
140 DomainState dynamic_state; | 179 DomainState dynamic_state; |
141 if (GetDynamicDomainState(host, &dynamic_state)) | 180 if (GetDynamicDomainState(host, &dynamic_state)) |
142 return dynamic_state.HasPublicKeyPins(); | 181 return dynamic_state.HasPublicKeyPins(); |
143 | 182 |
144 DomainState static_state; | 183 DomainState static_state; |
(...skipping 616 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
761 const base::Time build_time = base::GetBuildTime(); | 800 const base::Time build_time = base::GetBuildTime(); |
762 // We consider built-in information to be timely for 10 weeks. | 801 // We consider built-in information to be timely for 10 weeks. |
763 return (base::Time::Now() - build_time).InDays() < 70 /* 10 weeks */; | 802 return (base::Time::Now() - build_time).InDays() < 70 /* 10 weeks */; |
764 } | 803 } |
765 | 804 |
766 bool TransportSecurityState::GetStaticDomainState(const std::string& host, | 805 bool TransportSecurityState::GetStaticDomainState(const std::string& host, |
767 bool sni_enabled, | 806 bool sni_enabled, |
768 DomainState* out) const { | 807 DomainState* out) const { |
769 DCHECK(CalledOnValidThread()); | 808 DCHECK(CalledOnValidThread()); |
770 | 809 |
810 if (!enable_static_pinning_) | |
811 return false; | |
Ryan Sleevi
2014/08/07 23:31:19
Ugh and crap.
This breaks HSTS. And we didn't hav
Ryan Hamilton
2014/08/08 00:54:00
Done. (I hope :>)
| |
812 | |
771 const std::string canonicalized_host = CanonicalizeHost(host); | 813 const std::string canonicalized_host = CanonicalizeHost(host); |
772 | 814 |
773 out->sts.upgrade_mode = DomainState::MODE_FORCE_HTTPS; | 815 out->sts.upgrade_mode = DomainState::MODE_FORCE_HTTPS; |
774 out->sts.include_subdomains = false; | 816 out->sts.include_subdomains = false; |
775 out->pkp.include_subdomains = false; | 817 out->pkp.include_subdomains = false; |
776 | 818 |
777 const bool is_build_timely = IsBuildTimely(); | 819 const bool is_build_timely = IsBuildTimely(); |
778 | 820 |
779 for (size_t i = 0; canonicalized_host[i]; i += canonicalized_host[i] + 1) { | 821 for (size_t i = 0; canonicalized_host[i]; i += canonicalized_host[i] + 1) { |
780 std::string host_sub_chunk(&canonicalized_host[i], | 822 std::string host_sub_chunk(&canonicalized_host[i], |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
901 return pkp.spki_hashes.size() > 0 || pkp.bad_spki_hashes.size() > 0; | 943 return pkp.spki_hashes.size() > 0 || pkp.bad_spki_hashes.size() > 0; |
902 } | 944 } |
903 | 945 |
904 TransportSecurityState::DomainState::PKPState::PKPState() { | 946 TransportSecurityState::DomainState::PKPState::PKPState() { |
905 } | 947 } |
906 | 948 |
907 TransportSecurityState::DomainState::PKPState::~PKPState() { | 949 TransportSecurityState::DomainState::PKPState::~PKPState() { |
908 } | 950 } |
909 | 951 |
910 } // namespace | 952 } // namespace |
OLD | NEW |