Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(130)

Side by Side Diff: net/http/transport_security_state.cc

Issue 103803012: Make HSTS headers not clobber preloaded pins. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Respond to comments and fix compilation errors. Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
88 DCHECK(CalledOnValidThread()); 88 DCHECK(CalledOnValidThread());
89 } 89 }
90 90
91 TransportSecurityState::Iterator::Iterator(const TransportSecurityState& state) 91 TransportSecurityState::Iterator::Iterator(const TransportSecurityState& state)
92 : iterator_(state.enabled_hosts_.begin()), 92 : iterator_(state.enabled_hosts_.begin()),
93 end_(state.enabled_hosts_.end()) { 93 end_(state.enabled_hosts_.end()) {
94 } 94 }
95 95
96 TransportSecurityState::Iterator::~Iterator() {} 96 TransportSecurityState::Iterator::~Iterator() {}
97 97
98 bool TransportSecurityState::ShouldSSLErrorsBeFatal(const std::string& host,
99 bool sni_enabled) {
100 DomainState state;
101 if (GetStaticDomainState(host, sni_enabled, &state))
102 return true;
103 return GetDynamicDomainState(host, &state);
104 }
105
106 bool TransportSecurityState::ShouldUpgradeToSSL(const std::string& host,
107 bool sni_enabled) {
108 DomainState dynamic_state;
109 if (GetDynamicDomainState(host, &dynamic_state))
110 return dynamic_state.ShouldUpgradeToSSL();
111
112 DomainState static_state;
113 if (GetStaticDomainState(host, sni_enabled, &static_state) &&
114 static_state.ShouldUpgradeToSSL()) {
115 return true;
116 }
117
118 return false;
119 }
120
121 bool TransportSecurityState::CheckPublicKeyPins(const std::string& host,
122 bool sni_enabled,
123 const HashValueVector& hashes,
124 std::string* failure_log) {
125 DomainState dynamic_state;
126 if (GetDynamicDomainState(host, &dynamic_state))
127 return dynamic_state.CheckPublicKeyPins(hashes, failure_log);
128
129 DomainState static_state;
130 if (GetStaticDomainState(host, sni_enabled, &static_state) &&
131 static_state.CheckPublicKeyPins(hashes, failure_log)) {
132 return true;
133 }
134
135 return false;
136 }
137
138 bool TransportSecurityState::HasPublicKeyPins(const std::string& host,
139 bool sni_enabled) {
140 DomainState dynamic_state;
141 if (GetDynamicDomainState(host, &dynamic_state))
142 return dynamic_state.HasPublicKeyPins();
143
144 DomainState static_state;
145 if (GetStaticDomainState(host, sni_enabled, &static_state)) {
146 if (static_state.HasPublicKeyPins())
147 return true;
148 }
149
150 return false;
151 }
152
98 void TransportSecurityState::SetDelegate( 153 void TransportSecurityState::SetDelegate(
99 TransportSecurityState::Delegate* delegate) { 154 TransportSecurityState::Delegate* delegate) {
100 DCHECK(CalledOnValidThread()); 155 DCHECK(CalledOnValidThread());
101 delegate_ = delegate; 156 delegate_ = delegate;
102 } 157 }
103 158
104 void TransportSecurityState::EnableHost(const std::string& host, 159 void TransportSecurityState::EnableHost(const std::string& host,
105 const DomainState& state) { 160 const DomainState& state) {
106 DCHECK(CalledOnValidThread()); 161 DCHECK(CalledOnValidThread());
107 162
(...skipping 20 matching lines...) Expand all
128 DomainStateMap::iterator i = enabled_hosts_.find( 183 DomainStateMap::iterator i = enabled_hosts_.find(
129 HashHost(canonicalized_host)); 184 HashHost(canonicalized_host));
130 if (i != enabled_hosts_.end()) { 185 if (i != enabled_hosts_.end()) {
131 enabled_hosts_.erase(i); 186 enabled_hosts_.erase(i);
132 DirtyNotify(); 187 DirtyNotify();
133 return true; 188 return true;
134 } 189 }
135 return false; 190 return false;
136 } 191 }
137 192
138 bool TransportSecurityState::GetDomainState(const std::string& host,
139 bool sni_enabled,
140 DomainState* result) {
141 DCHECK(CalledOnValidThread());
142
143 DomainState state;
144 const std::string canonicalized_host = CanonicalizeHost(host);
145 if (canonicalized_host.empty())
146 return false;
147
148 bool has_preload = GetStaticDomainState(canonicalized_host, sni_enabled,
149 &state);
150 std::string canonicalized_preload = CanonicalizeHost(state.domain);
151 GetDynamicDomainState(host, &state);
152
153 base::Time current_time(base::Time::Now());
154
155 for (size_t i = 0; canonicalized_host[i]; i += canonicalized_host[i] + 1) {
156 std::string host_sub_chunk(&canonicalized_host[i],
157 canonicalized_host.size() - i);
158 // Exact match of a preload always wins.
159 if (has_preload && host_sub_chunk == canonicalized_preload) {
160 *result = state;
161 return true;
162 }
163
164 DomainStateMap::iterator j =
165 enabled_hosts_.find(HashHost(host_sub_chunk));
166 if (j == enabled_hosts_.end())
167 continue;
168
169 if (current_time > j->second.upgrade_expiry &&
170 current_time > j->second.dynamic_spki_hashes_expiry) {
171 enabled_hosts_.erase(j);
172 DirtyNotify();
173 continue;
174 }
175
176 state = j->second;
177 state.domain = DNSDomainToString(host_sub_chunk);
178
179 // Succeed if we matched the domain exactly or if subdomain matches are
180 // allowed.
181 if (i == 0 || j->second.sts_include_subdomains ||
182 j->second.pkp_include_subdomains) {
183 *result = state;
184 return true;
185 }
186
187 return false;
188 }
189
190 return false;
191 }
192
193 void TransportSecurityState::ClearDynamicData() { 193 void TransportSecurityState::ClearDynamicData() {
194 DCHECK(CalledOnValidThread()); 194 DCHECK(CalledOnValidThread());
195 enabled_hosts_.clear(); 195 enabled_hosts_.clear();
196 } 196 }
197 197
198 void TransportSecurityState::DeleteAllDynamicDataSince(const base::Time& time) { 198 void TransportSecurityState::DeleteAllDynamicDataSince(const base::Time& time) {
199 DCHECK(CalledOnValidThread()); 199 DCHECK(CalledOnValidThread());
200 200
201 bool dirtied = false; 201 bool dirtied = false;
202 DomainStateMap::iterator i = enabled_hosts_.begin(); 202 DomainStateMap::iterator i = enabled_hosts_.begin();
203 while (i != enabled_hosts_.end()) { 203 while (i != enabled_hosts_.end()) {
204 if (i->second.sts_observed >= time && i->second.pkp_observed >= time) { 204 if (i->second.sts.last_observed >= time &&
205 i->second.pkp.last_observed >= time) {
205 dirtied = true; 206 dirtied = true;
206 enabled_hosts_.erase(i++); 207 enabled_hosts_.erase(i++);
207 continue; 208 continue;
208 } 209 }
209 210
210 if (i->second.sts_observed >= time) { 211 if (i->second.sts.last_observed >= time) {
211 dirtied = true; 212 dirtied = true;
212 i->second.upgrade_mode = DomainState::MODE_DEFAULT; 213 i->second.sts.upgrade_mode = DomainState::MODE_DEFAULT;
213 } else if (i->second.pkp_observed >= time) { 214 } else if (i->second.pkp.last_observed >= time) {
214 dirtied = true; 215 dirtied = true;
215 i->second.dynamic_spki_hashes.clear(); 216 i->second.pkp.spki_hashes.clear();
217 i->second.pkp.expiry = base::Time();
216 } 218 }
217 ++i; 219 ++i;
218 } 220 }
219 221
220 if (dirtied) 222 if (dirtied)
221 DirtyNotify(); 223 DirtyNotify();
222 } 224 }
223 225
224 TransportSecurityState::~TransportSecurityState() { 226 TransportSecurityState::~TransportSecurityState() {
225 DCHECK(CalledOnValidThread()); 227 DCHECK(CalledOnValidThread());
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after
548 static bool HasPreload(const struct HSTSPreload* entries, size_t num_entries, 550 static bool HasPreload(const struct HSTSPreload* entries, size_t num_entries,
549 const std::string& canonicalized_host, size_t i, 551 const std::string& canonicalized_host, size_t i,
550 TransportSecurityState::DomainState* out, bool* ret) { 552 TransportSecurityState::DomainState* out, bool* ret) {
551 for (size_t j = 0; j < num_entries; j++) { 553 for (size_t j = 0; j < num_entries; j++) {
552 if (entries[j].length == canonicalized_host.size() - i && 554 if (entries[j].length == canonicalized_host.size() - i &&
553 memcmp(entries[j].dns_name, &canonicalized_host[i], 555 memcmp(entries[j].dns_name, &canonicalized_host[i],
554 entries[j].length) == 0) { 556 entries[j].length) == 0) {
555 if (!entries[j].include_subdomains && i != 0) { 557 if (!entries[j].include_subdomains && i != 0) {
556 *ret = false; 558 *ret = false;
557 } else { 559 } else {
558 out->sts_include_subdomains = entries[j].include_subdomains; 560 out->sts.include_subdomains = entries[j].include_subdomains;
559 out->pkp_include_subdomains = entries[j].include_subdomains; 561 out->sts.last_observed = base::GetBuildTime();
562 out->pkp.include_subdomains = entries[j].include_subdomains;
563 out->pkp.last_observed = base::GetBuildTime();
560 *ret = true; 564 *ret = true;
565 out->sts.upgrade_mode =
566 TransportSecurityState::DomainState::MODE_FORCE_HTTPS;
561 if (!entries[j].https_required) 567 if (!entries[j].https_required)
562 out->upgrade_mode = TransportSecurityState::DomainState::MODE_DEFAULT; 568 out->sts.upgrade_mode =
569 TransportSecurityState::DomainState::MODE_DEFAULT;
563 if (entries[j].pins.required_hashes) { 570 if (entries[j].pins.required_hashes) {
564 const char* const* sha1_hash = entries[j].pins.required_hashes; 571 const char* const* sha1_hash = entries[j].pins.required_hashes;
565 while (*sha1_hash) { 572 while (*sha1_hash) {
566 AddHash(*sha1_hash, &out->static_spki_hashes); 573 AddHash(*sha1_hash, &out->pkp.spki_hashes);
567 sha1_hash++; 574 sha1_hash++;
568 } 575 }
569 } 576 }
570 if (entries[j].pins.excluded_hashes) { 577 if (entries[j].pins.excluded_hashes) {
571 const char* const* sha1_hash = entries[j].pins.excluded_hashes; 578 const char* const* sha1_hash = entries[j].pins.excluded_hashes;
572 while (*sha1_hash) { 579 while (*sha1_hash) {
573 AddHash(*sha1_hash, &out->bad_static_spki_hashes); 580 AddHash(*sha1_hash, &out->pkp.bad_spki_hashes);
574 sha1_hash++; 581 sha1_hash++;
575 } 582 }
576 } 583 }
577 } 584 }
578 return true; 585 return true;
579 } 586 }
580 } 587 }
581 return false; 588 return false;
582 } 589 }
583 590
(...skipping 27 matching lines...) Expand all
611 } 618 }
612 619
613 bool TransportSecurityState::AddHSTSHeader(const std::string& host, 620 bool TransportSecurityState::AddHSTSHeader(const std::string& host,
614 const std::string& value) { 621 const std::string& value) {
615 DCHECK(CalledOnValidThread()); 622 DCHECK(CalledOnValidThread());
616 623
617 base::Time now = base::Time::Now(); 624 base::Time now = base::Time::Now();
618 base::TimeDelta max_age; 625 base::TimeDelta max_age;
619 TransportSecurityState::DomainState domain_state; 626 TransportSecurityState::DomainState domain_state;
620 GetDynamicDomainState(host, &domain_state); 627 GetDynamicDomainState(host, &domain_state);
621 if (ParseHSTSHeader(value, &max_age, &domain_state.sts_include_subdomains)) { 628 if (ParseHSTSHeader(value, &max_age, &domain_state.sts.include_subdomains)) {
622 // Handle max-age == 0 629 // Handle max-age == 0
623 if (max_age.InSeconds() == 0) 630 if (max_age.InSeconds() == 0)
624 domain_state.upgrade_mode = DomainState::MODE_DEFAULT; 631 domain_state.sts.upgrade_mode = DomainState::MODE_DEFAULT;
625 else 632 else
626 domain_state.upgrade_mode = DomainState::MODE_FORCE_HTTPS; 633 domain_state.sts.upgrade_mode = DomainState::MODE_FORCE_HTTPS;
627 domain_state.sts_observed = now; 634 domain_state.sts.last_observed = now;
628 domain_state.upgrade_expiry = now + max_age; 635 domain_state.sts.expiry = now + max_age;
629 EnableHost(host, domain_state); 636 EnableHost(host, domain_state);
630 return true; 637 return true;
631 } 638 }
632 return false; 639 return false;
633 } 640 }
634 641
635 bool TransportSecurityState::AddHPKPHeader(const std::string& host, 642 bool TransportSecurityState::AddHPKPHeader(const std::string& host,
636 const std::string& value, 643 const std::string& value,
637 const SSLInfo& ssl_info) { 644 const SSLInfo& ssl_info) {
638 DCHECK(CalledOnValidThread()); 645 DCHECK(CalledOnValidThread());
639 646
640 base::Time now = base::Time::Now(); 647 base::Time now = base::Time::Now();
641 base::TimeDelta max_age; 648 base::TimeDelta max_age;
642 TransportSecurityState::DomainState domain_state; 649 TransportSecurityState::DomainState domain_state;
643 GetDynamicDomainState(host, &domain_state); 650 GetDynamicDomainState(host, &domain_state);
644 if (ParseHPKPHeader(value, ssl_info.public_key_hashes, 651 if (ParseHPKPHeader(value,
645 &max_age, &domain_state.pkp_include_subdomains, 652 ssl_info.public_key_hashes,
646 &domain_state.dynamic_spki_hashes)) { 653 &max_age,
654 &domain_state.pkp.include_subdomains,
655 &domain_state.pkp.spki_hashes)) {
647 // TODO(palmer): http://crbug.com/243865 handle max-age == 0. 656 // TODO(palmer): http://crbug.com/243865 handle max-age == 0.
648 domain_state.pkp_observed = now; 657 domain_state.pkp.last_observed = now;
649 domain_state.dynamic_spki_hashes_expiry = now + max_age; 658 domain_state.pkp.expiry = now + max_age;
650 EnableHost(host, domain_state); 659 EnableHost(host, domain_state);
651 return true; 660 return true;
652 } 661 }
653 return false; 662 return false;
654 } 663 }
655 664
656 bool TransportSecurityState::AddHSTS(const std::string& host, 665 bool TransportSecurityState::AddHSTS(const std::string& host,
657 const base::Time& expiry, 666 const base::Time& expiry,
658 bool include_subdomains) { 667 bool include_subdomains) {
659 DCHECK(CalledOnValidThread()); 668 DCHECK(CalledOnValidThread());
660 669
661 // Copy-and-modify the existing DomainState for this host (if any). 670 // Copy-and-modify the existing DomainState for this host (if any).
662 TransportSecurityState::DomainState domain_state; 671 TransportSecurityState::DomainState domain_state;
663 const std::string canonicalized_host = CanonicalizeHost(host); 672 const std::string canonicalized_host = CanonicalizeHost(host);
664 const std::string hashed_host = HashHost(canonicalized_host); 673 const std::string hashed_host = HashHost(canonicalized_host);
665 DomainStateMap::const_iterator i = enabled_hosts_.find( 674 DomainStateMap::const_iterator i = enabled_hosts_.find(
666 hashed_host); 675 hashed_host);
667 if (i != enabled_hosts_.end()) 676 if (i != enabled_hosts_.end())
668 domain_state = i->second; 677 domain_state = i->second;
669 678
670 domain_state.sts_observed = base::Time::Now(); 679 domain_state.sts.last_observed = base::Time::Now();
671 domain_state.sts_include_subdomains = include_subdomains; 680 domain_state.sts.include_subdomains = include_subdomains;
672 domain_state.upgrade_expiry = expiry; 681 domain_state.sts.expiry = expiry;
673 domain_state.upgrade_mode = DomainState::MODE_FORCE_HTTPS; 682 domain_state.sts.upgrade_mode = DomainState::MODE_FORCE_HTTPS;
674 EnableHost(host, domain_state); 683 EnableHost(host, domain_state);
675 return true; 684 return true;
676 } 685 }
677 686
678 bool TransportSecurityState::AddHPKP(const std::string& host, 687 bool TransportSecurityState::AddHPKP(const std::string& host,
679 const base::Time& expiry, 688 const base::Time& expiry,
680 bool include_subdomains, 689 bool include_subdomains,
681 const HashValueVector& hashes) { 690 const HashValueVector& hashes) {
682 DCHECK(CalledOnValidThread()); 691 DCHECK(CalledOnValidThread());
683 692
684 // Copy-and-modify the existing DomainState for this host (if any). 693 // Copy-and-modify the existing DomainState for this host (if any).
685 TransportSecurityState::DomainState domain_state; 694 TransportSecurityState::DomainState domain_state;
686 const std::string canonicalized_host = CanonicalizeHost(host); 695 const std::string canonicalized_host = CanonicalizeHost(host);
687 const std::string hashed_host = HashHost(canonicalized_host); 696 const std::string hashed_host = HashHost(canonicalized_host);
688 DomainStateMap::const_iterator i = enabled_hosts_.find( 697 DomainStateMap::const_iterator i = enabled_hosts_.find(
689 hashed_host); 698 hashed_host);
690 if (i != enabled_hosts_.end()) 699 if (i != enabled_hosts_.end())
691 domain_state = i->second; 700 domain_state = i->second;
692 701
693 domain_state.pkp_observed = base::Time::Now(); 702 domain_state.pkp.last_observed = base::Time::Now();
694 domain_state.pkp_include_subdomains = include_subdomains; 703 domain_state.pkp.include_subdomains = include_subdomains;
695 domain_state.dynamic_spki_hashes_expiry = expiry; 704 domain_state.pkp.expiry = expiry;
696 domain_state.dynamic_spki_hashes = hashes; 705 domain_state.pkp.spki_hashes = hashes;
697 EnableHost(host, domain_state); 706 EnableHost(host, domain_state);
698 return true; 707 return true;
699 } 708 }
700 709
701 // static 710 // static
702 bool TransportSecurityState::IsGooglePinnedProperty(const std::string& host, 711 bool TransportSecurityState::IsGooglePinnedProperty(const std::string& host,
703 bool sni_enabled) { 712 bool sni_enabled) {
704 std::string canonicalized_host = CanonicalizeHost(host); 713 std::string canonicalized_host = CanonicalizeHost(host);
705 const struct HSTSPreload* entry = 714 const struct HSTSPreload* entry =
706 GetHSTSPreload(canonicalized_host, kPreloadedSTS, kNumPreloadedSTS); 715 GetHSTSPreload(canonicalized_host, kPreloadedSTS, kNumPreloadedSTS);
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
743 entry->second_level_domain_name, DOMAIN_NUM_EVENTS); 752 entry->second_level_domain_name, DOMAIN_NUM_EVENTS);
744 } 753 }
745 754
746 // static 755 // static
747 bool TransportSecurityState::IsBuildTimely() { 756 bool TransportSecurityState::IsBuildTimely() {
748 const base::Time build_time = base::GetBuildTime(); 757 const base::Time build_time = base::GetBuildTime();
749 // We consider built-in information to be timely for 10 weeks. 758 // We consider built-in information to be timely for 10 weeks.
750 return (base::Time::Now() - build_time).InDays() < 70 /* 10 weeks */; 759 return (base::Time::Now() - build_time).InDays() < 70 /* 10 weeks */;
751 } 760 }
752 761
753 bool TransportSecurityState::GetStaticDomainState( 762 bool TransportSecurityState::GetStaticDomainState(const std::string& host,
754 const std::string& canonicalized_host, 763 bool sni_enabled,
755 bool sni_enabled, 764 DomainState* out) const {
756 DomainState* out) {
757 DCHECK(CalledOnValidThread()); 765 DCHECK(CalledOnValidThread());
758 766
759 out->upgrade_mode = DomainState::MODE_FORCE_HTTPS; 767 const std::string canonicalized_host = CanonicalizeHost(host);
760 out->sts_include_subdomains = false; 768
761 out->pkp_include_subdomains = false; 769 out->sts.upgrade_mode = DomainState::MODE_FORCE_HTTPS;
770 out->sts.include_subdomains = false;
771 out->pkp.include_subdomains = false;
762 772
763 const bool is_build_timely = IsBuildTimely(); 773 const bool is_build_timely = IsBuildTimely();
764 774
765 for (size_t i = 0; canonicalized_host[i]; i += canonicalized_host[i] + 1) { 775 for (size_t i = 0; canonicalized_host[i]; i += canonicalized_host[i] + 1) {
766 std::string host_sub_chunk(&canonicalized_host[i], 776 std::string host_sub_chunk(&canonicalized_host[i],
767 canonicalized_host.size() - i); 777 canonicalized_host.size() - i);
768 out->domain = DNSDomainToString(host_sub_chunk); 778 out->domain = DNSDomainToString(host_sub_chunk);
769 bool ret; 779 bool ret;
770 if (is_build_timely && 780 if (is_build_timely &&
771 HasPreload(kPreloadedSTS, kNumPreloadedSTS, canonicalized_host, i, out, 781 HasPreload(kPreloadedSTS, kNumPreloadedSTS, canonicalized_host, i, out,
(...skipping 23 matching lines...) Expand all
795 base::Time current_time(base::Time::Now()); 805 base::Time current_time(base::Time::Now());
796 806
797 for (size_t i = 0; canonicalized_host[i]; i += canonicalized_host[i] + 1) { 807 for (size_t i = 0; canonicalized_host[i]; i += canonicalized_host[i] + 1) {
798 std::string host_sub_chunk(&canonicalized_host[i], 808 std::string host_sub_chunk(&canonicalized_host[i],
799 canonicalized_host.size() - i); 809 canonicalized_host.size() - i);
800 DomainStateMap::iterator j = 810 DomainStateMap::iterator j =
801 enabled_hosts_.find(HashHost(host_sub_chunk)); 811 enabled_hosts_.find(HashHost(host_sub_chunk));
802 if (j == enabled_hosts_.end()) 812 if (j == enabled_hosts_.end())
803 continue; 813 continue;
804 814
805 if (current_time > j->second.upgrade_expiry && 815 if (current_time > j->second.sts.expiry &&
806 current_time > j->second.dynamic_spki_hashes_expiry) { 816 current_time > j->second.pkp.expiry) {
807 enabled_hosts_.erase(j); 817 enabled_hosts_.erase(j);
808 DirtyNotify(); 818 DirtyNotify();
809 continue; 819 continue;
810 } 820 }
811 821
812 state = j->second; 822 state = j->second;
813 state.domain = DNSDomainToString(host_sub_chunk); 823 state.domain = DNSDomainToString(host_sub_chunk);
814 824
815 // Succeed if we matched the domain exactly or if subdomain matches are 825 // Succeed if we matched the domain exactly or if subdomain matches are
816 // allowed. 826 // allowed.
817 if (i == 0 || j->second.sts_include_subdomains || 827 if (i == 0 || j->second.sts.include_subdomains ||
818 j->second.pkp_include_subdomains) { 828 j->second.pkp.include_subdomains) {
819 *result = state; 829 *result = state;
820 return true; 830 return true;
821 } 831 }
822 832
823 return false; 833 return false;
824 } 834 }
825 835
826 return false; 836 return false;
827 } 837 }
828 838
829
830 void TransportSecurityState::AddOrUpdateEnabledHosts( 839 void TransportSecurityState::AddOrUpdateEnabledHosts(
831 const std::string& hashed_host, const DomainState& state) { 840 const std::string& hashed_host, const DomainState& state) {
832 DCHECK(CalledOnValidThread()); 841 DCHECK(CalledOnValidThread());
833 enabled_hosts_[hashed_host] = state; 842 enabled_hosts_[hashed_host] = state;
834 } 843 }
835 844
836 TransportSecurityState::DomainState::DomainState() 845 TransportSecurityState::DomainState::DomainState() {
837 : upgrade_mode(MODE_DEFAULT), 846 sts.upgrade_mode = MODE_DEFAULT;
838 sts_include_subdomains(false), 847 sts.include_subdomains = false;
839 pkp_include_subdomains(false) { 848 pkp.include_subdomains = false;
840 base::Time now(base::Time::Now());
841 sts_observed = now;
842 pkp_observed = now;
843 } 849 }
844 850
845 TransportSecurityState::DomainState::~DomainState() { 851 TransportSecurityState::DomainState::~DomainState() {
846 } 852 }
847 853
848 bool TransportSecurityState::DomainState::CheckPublicKeyPins( 854 bool TransportSecurityState::DomainState::CheckPublicKeyPins(
849 const HashValueVector& hashes, std::string* failure_log) const { 855 const HashValueVector& hashes, std::string* failure_log) const {
850 // Validate that hashes is not empty. By the time this code is called (in 856 // Validate that hashes is not empty. By the time this code is called (in
851 // production), that should never happen, but it's good to be defensive. 857 // production), that should never happen, but it's good to be defensive.
852 // And, hashes *can* be empty in some test scenarios. 858 // And, hashes *can* be empty in some test scenarios.
853 if (hashes.empty()) { 859 if (hashes.empty()) {
854 *failure_log = "Rejecting empty public key chain for public-key-pinned " 860 failure_log->append(
855 "domains: " + domain; 861 "Rejecting empty public key chain for public-key-pinned domains: " +
862 domain);
856 return false; 863 return false;
857 } 864 }
858 865
859 if (HashesIntersect(bad_static_spki_hashes, hashes)) { 866 if (HashesIntersect(pkp.bad_spki_hashes, hashes)) {
860 *failure_log = "Rejecting public key chain for domain " + domain + 867 failure_log->append("Rejecting public key chain for domain " + domain +
861 ". Validated chain: " + HashesToBase64String(hashes) + 868 ". Validated chain: " + HashesToBase64String(hashes) +
862 ", matches one or more bad hashes: " + 869 ", matches one or more bad hashes: " +
863 HashesToBase64String(bad_static_spki_hashes); 870 HashesToBase64String(pkp.bad_spki_hashes));
864 return false; 871 return false;
865 } 872 }
866 873
867 // If there are no pins, then any valid chain is acceptable. 874 // If there are no pins, then any valid chain is acceptable.
868 if (dynamic_spki_hashes.empty() && static_spki_hashes.empty()) 875 if (pkp.spki_hashes.empty())
869 return true; 876 return true;
870 877
871 if (HashesIntersect(dynamic_spki_hashes, hashes) || 878 if (HashesIntersect(pkp.spki_hashes, hashes)) {
872 HashesIntersect(static_spki_hashes, hashes)) {
873 return true; 879 return true;
874 } 880 }
875 881
876 *failure_log = "Rejecting public key chain for domain " + domain + 882 failure_log->append("Rejecting public key chain for domain " + domain +
877 ". Validated chain: " + HashesToBase64String(hashes) + 883 ". Validated chain: " + HashesToBase64String(hashes) +
878 ", expected: " + HashesToBase64String(dynamic_spki_hashes) + 884 ", expected: " + HashesToBase64String(pkp.spki_hashes));
879 " or: " + HashesToBase64String(static_spki_hashes);
880 return false; 885 return false;
881 } 886 }
882 887
883 bool TransportSecurityState::DomainState::ShouldUpgradeToSSL() const { 888 bool TransportSecurityState::DomainState::ShouldUpgradeToSSL() const {
884 return upgrade_mode == MODE_FORCE_HTTPS; 889 return sts.upgrade_mode == MODE_FORCE_HTTPS;
885 } 890 }
886 891
887 bool TransportSecurityState::DomainState::ShouldSSLErrorsBeFatal() const { 892 bool TransportSecurityState::DomainState::ShouldSSLErrorsBeFatal() const {
888 return true; 893 return true;
889 } 894 }
890 895
891 bool TransportSecurityState::DomainState::HasPublicKeyPins() const { 896 bool TransportSecurityState::DomainState::HasPublicKeyPins() const {
892 return static_spki_hashes.size() > 0 || 897 return pkp.spki_hashes.size() > 0 || pkp.bad_spki_hashes.size() > 0;
893 bad_static_spki_hashes.size() > 0 || 898 }
894 dynamic_spki_hashes.size() > 0; 899
900 TransportSecurityState::DomainState::PKPState::PKPState() {
901 }
902
903 TransportSecurityState::DomainState::PKPState::~PKPState() {
895 } 904 }
896 905
897 } // namespace 906 } // namespace
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698