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

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: Rebase and refactor. (Not done yet.) Created 6 years, 8 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 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 } 74 }
75 75
76 bool AddHash(const char* sha1_hash, 76 bool AddHash(const char* sha1_hash,
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 // Updates |other| to contain the most recent observations found
85 // between the states |state| and |other|.
86 void MergeDomainStates(const TransportSecurityState::DomainState& state,
87 TransportSecurityState::DomainState* other) {
88 if (other->pkp.last_observed < state.pkp.last_observed)
89 other->pkp = state.pkp;
90 if (other->sts.last_observed < state.sts.last_observed)
91 other->sts = state.sts;
92 }
93
84 } // namespace 94 } // namespace
85 95
86 TransportSecurityState::TransportSecurityState() 96 TransportSecurityState::TransportSecurityState()
87 : delegate_(NULL) { 97 : delegate_(NULL) {
88 DCHECK(CalledOnValidThread()); 98 DCHECK(CalledOnValidThread());
89 } 99 }
90 100
91 TransportSecurityState::Iterator::Iterator(const TransportSecurityState& state) 101 TransportSecurityState::Iterator::Iterator(const TransportSecurityState& state)
92 : iterator_(state.enabled_hosts_.begin()), 102 : iterator_(state.enabled_hosts_.begin()),
93 end_(state.enabled_hosts_.end()) { 103 end_(state.enabled_hosts_.end()) {
94 } 104 }
95 105
96 TransportSecurityState::Iterator::~Iterator() {} 106 TransportSecurityState::Iterator::~Iterator() {}
97 107
108 bool TransportSecurityState::ShouldSSLErrorsBeFatal(const std::string& host,
109 bool sni_enabled) const {
110 // TODO(palmer): Implement this.
111 return true;
112 }
113
114 bool TransportSecurityState::ShouldUpgradeToSSL(const std::string& host,
115 bool sni_enabled) const {
116 // TODO(palmer): Implement this.
117 return true;
118 }
119
120 bool TransportSecurityState::CheckPublicKeyPins(
121 const std::string& host,
122 bool sni_enabled,
123 const HashValueVector& hashes) const {
124 // TODO(palmer): Implement this.
125 return true;
126 }
127
128 bool TransportSecurityState::HasPublicKeyPins(const std::string& host,
129 bool sni_enabled) const {
130 // TODO(palmer): Implement this.
131 return true;
132 }
133
98 void TransportSecurityState::SetDelegate( 134 void TransportSecurityState::SetDelegate(
99 TransportSecurityState::Delegate* delegate) { 135 TransportSecurityState::Delegate* delegate) {
100 DCHECK(CalledOnValidThread()); 136 DCHECK(CalledOnValidThread());
101 delegate_ = delegate; 137 delegate_ = delegate;
102 } 138 }
103 139
104 void TransportSecurityState::EnableHost(const std::string& host, 140 void TransportSecurityState::EnableHost(const std::string& host,
105 const DomainState& state) { 141 const DomainState& state) {
106 DCHECK(CalledOnValidThread()); 142 DCHECK(CalledOnValidThread());
107 143
(...skipping 20 matching lines...) Expand all
128 DomainStateMap::iterator i = enabled_hosts_.find( 164 DomainStateMap::iterator i = enabled_hosts_.find(
129 HashHost(canonicalized_host)); 165 HashHost(canonicalized_host));
130 if (i != enabled_hosts_.end()) { 166 if (i != enabled_hosts_.end()) {
131 enabled_hosts_.erase(i); 167 enabled_hosts_.erase(i);
132 DirtyNotify(); 168 DirtyNotify();
133 return true; 169 return true;
134 } 170 }
135 return false; 171 return false;
136 } 172 }
137 173
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() { 174 void TransportSecurityState::ClearDynamicData() {
194 DCHECK(CalledOnValidThread()); 175 DCHECK(CalledOnValidThread());
195 enabled_hosts_.clear(); 176 enabled_hosts_.clear();
196 } 177 }
197 178
198 void TransportSecurityState::DeleteAllDynamicDataSince(const base::Time& time) { 179 void TransportSecurityState::DeleteAllDynamicDataSince(const base::Time& time) {
199 DCHECK(CalledOnValidThread()); 180 DCHECK(CalledOnValidThread());
200 181
201 bool dirtied = false; 182 bool dirtied = false;
202 DomainStateMap::iterator i = enabled_hosts_.begin(); 183 DomainStateMap::iterator i = enabled_hosts_.begin();
203 while (i != enabled_hosts_.end()) { 184 while (i != enabled_hosts_.end()) {
204 if (i->second.sts_observed >= time && i->second.pkp_observed >= time) { 185 if (i->second.sts.last_observed >= time &&
186 i->second.pkp.last_observed >= time) {
205 dirtied = true; 187 dirtied = true;
206 enabled_hosts_.erase(i++); 188 enabled_hosts_.erase(i++);
207 continue; 189 continue;
208 } 190 }
209 191
210 if (i->second.sts_observed >= time) { 192 if (i->second.sts.last_observed >= time) {
211 dirtied = true; 193 dirtied = true;
212 i->second.upgrade_mode = DomainState::MODE_DEFAULT; 194 i->second.sts.upgrade_mode = DomainState::MODE_DEFAULT;
213 } else if (i->second.pkp_observed >= time) { 195 } else if (i->second.pkp.last_observed >= time) {
214 dirtied = true; 196 dirtied = true;
215 i->second.dynamic_spki_hashes.clear(); 197 i->second.pkp.spki_hashes.clear();
216 } 198 }
217 ++i; 199 ++i;
218 } 200 }
219 201
220 if (dirtied) 202 if (dirtied)
221 DirtyNotify(); 203 DirtyNotify();
222 } 204 }
223 205
224 TransportSecurityState::~TransportSecurityState() { 206 TransportSecurityState::~TransportSecurityState() {
225 DCHECK(CalledOnValidThread()); 207 DCHECK(CalledOnValidThread());
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after
547 static bool HasPreload(const struct HSTSPreload* entries, size_t num_entries, 529 static bool HasPreload(const struct HSTSPreload* entries, size_t num_entries,
548 const std::string& canonicalized_host, size_t i, 530 const std::string& canonicalized_host, size_t i,
549 TransportSecurityState::DomainState* out, bool* ret) { 531 TransportSecurityState::DomainState* out, bool* ret) {
550 for (size_t j = 0; j < num_entries; j++) { 532 for (size_t j = 0; j < num_entries; j++) {
551 if (entries[j].length == canonicalized_host.size() - i && 533 if (entries[j].length == canonicalized_host.size() - i &&
552 memcmp(entries[j].dns_name, &canonicalized_host[i], 534 memcmp(entries[j].dns_name, &canonicalized_host[i],
553 entries[j].length) == 0) { 535 entries[j].length) == 0) {
554 if (!entries[j].include_subdomains && i != 0) { 536 if (!entries[j].include_subdomains && i != 0) {
555 *ret = false; 537 *ret = false;
556 } else { 538 } else {
557 out->sts_include_subdomains = entries[j].include_subdomains; 539 out->sts.include_subdomains = entries[j].include_subdomains;
558 out->pkp_include_subdomains = entries[j].include_subdomains; 540 out->sts.last_observed = base::GetBuildTime();
541 out->pkp.include_subdomains = entries[j].include_subdomains;
542 out->pkp.last_observed = base::GetBuildTime();
559 *ret = true; 543 *ret = true;
544 out->sts.upgrade_mode =
545 TransportSecurityState::DomainState::MODE_FORCE_HTTPS;
560 if (!entries[j].https_required) 546 if (!entries[j].https_required)
561 out->upgrade_mode = TransportSecurityState::DomainState::MODE_DEFAULT; 547 out->sts.upgrade_mode =
548 TransportSecurityState::DomainState::MODE_DEFAULT;
562 if (entries[j].pins.required_hashes) { 549 if (entries[j].pins.required_hashes) {
563 const char* const* sha1_hash = entries[j].pins.required_hashes; 550 const char* const* sha1_hash = entries[j].pins.required_hashes;
564 while (*sha1_hash) { 551 while (*sha1_hash) {
565 AddHash(*sha1_hash, &out->static_spki_hashes); 552 AddHash(*sha1_hash, &out->pkp.spki_hashes);
566 sha1_hash++; 553 sha1_hash++;
567 } 554 }
568 } 555 }
569 if (entries[j].pins.excluded_hashes) { 556 if (entries[j].pins.excluded_hashes) {
570 const char* const* sha1_hash = entries[j].pins.excluded_hashes; 557 const char* const* sha1_hash = entries[j].pins.excluded_hashes;
571 while (*sha1_hash) { 558 while (*sha1_hash) {
572 AddHash(*sha1_hash, &out->bad_static_spki_hashes); 559 AddHash(*sha1_hash, &out->pkp.bad_spki_hashes);
573 sha1_hash++; 560 sha1_hash++;
574 } 561 }
575 } 562 }
576 } 563 }
577 return true; 564 return true;
578 } 565 }
579 } 566 }
580 return false; 567 return false;
581 } 568 }
582 569
(...skipping 27 matching lines...) Expand all
610 } 597 }
611 598
612 bool TransportSecurityState::AddHSTSHeader(const std::string& host, 599 bool TransportSecurityState::AddHSTSHeader(const std::string& host,
613 const std::string& value) { 600 const std::string& value) {
614 DCHECK(CalledOnValidThread()); 601 DCHECK(CalledOnValidThread());
615 602
616 base::Time now = base::Time::Now(); 603 base::Time now = base::Time::Now();
617 base::TimeDelta max_age; 604 base::TimeDelta max_age;
618 TransportSecurityState::DomainState domain_state; 605 TransportSecurityState::DomainState domain_state;
619 GetDynamicDomainState(host, &domain_state); 606 GetDynamicDomainState(host, &domain_state);
620 if (ParseHSTSHeader(value, &max_age, &domain_state.sts_include_subdomains)) { 607 if (ParseHSTSHeader(value, &max_age,
608 &domain_state.sts.include_subdomains)) {
621 // Handle max-age == 0 609 // Handle max-age == 0
622 if (max_age.InSeconds() == 0) 610 if (max_age.InSeconds() == 0)
623 domain_state.upgrade_mode = DomainState::MODE_DEFAULT; 611 domain_state.sts.upgrade_mode = DomainState::MODE_DEFAULT;
624 else 612 else
625 domain_state.upgrade_mode = DomainState::MODE_FORCE_HTTPS; 613 domain_state.sts.upgrade_mode = DomainState::MODE_FORCE_HTTPS;
626 domain_state.sts_observed = now; 614 domain_state.sts.last_observed = now;
627 domain_state.upgrade_expiry = now + max_age; 615 domain_state.sts.expiry = now + max_age;
628 EnableHost(host, domain_state); 616 EnableHost(host, domain_state);
629 return true; 617 return true;
630 } 618 }
631 return false; 619 return false;
632 } 620 }
633 621
634 bool TransportSecurityState::AddHPKPHeader(const std::string& host, 622 bool TransportSecurityState::AddHPKPHeader(const std::string& host,
635 const std::string& value, 623 const std::string& value,
636 const SSLInfo& ssl_info) { 624 const SSLInfo& ssl_info) {
637 DCHECK(CalledOnValidThread()); 625 DCHECK(CalledOnValidThread());
638 626
639 base::Time now = base::Time::Now(); 627 base::Time now = base::Time::Now();
640 base::TimeDelta max_age; 628 base::TimeDelta max_age;
641 TransportSecurityState::DomainState domain_state; 629 TransportSecurityState::DomainState domain_state;
642 GetDynamicDomainState(host, &domain_state); 630 GetDynamicDomainState(host, &domain_state);
643 if (ParseHPKPHeader(value, ssl_info.public_key_hashes, 631 if (ParseHPKPHeader(value, ssl_info.public_key_hashes,
644 &max_age, &domain_state.pkp_include_subdomains, 632 &max_age, &domain_state.pkp.include_subdomains,
645 &domain_state.dynamic_spki_hashes)) { 633 &domain_state.pkp.spki_hashes)) {
646 // TODO(palmer): http://crbug.com/243865 handle max-age == 0. 634 // TODO(palmer): http://crbug.com/243865 handle max-age == 0.
647 domain_state.pkp_observed = now; 635 domain_state.pkp.last_observed = now;
648 domain_state.dynamic_spki_hashes_expiry = now + max_age; 636 domain_state.pkp.expiry = now + max_age;
649 EnableHost(host, domain_state); 637 EnableHost(host, domain_state);
650 return true; 638 return true;
651 } 639 }
652 return false; 640 return false;
653 } 641 }
654 642
655 bool TransportSecurityState::AddHSTS(const std::string& host, 643 bool TransportSecurityState::AddHSTS(const std::string& host,
656 const base::Time& expiry, 644 const base::Time& expiry,
657 bool include_subdomains) { 645 bool include_subdomains) {
658 DCHECK(CalledOnValidThread()); 646 DCHECK(CalledOnValidThread());
659 647
660 // Copy-and-modify the existing DomainState for this host (if any). 648 // Copy-and-modify the existing DomainState for this host (if any).
661 TransportSecurityState::DomainState domain_state; 649 TransportSecurityState::DomainState domain_state;
662 const std::string canonicalized_host = CanonicalizeHost(host); 650 const std::string canonicalized_host = CanonicalizeHost(host);
663 const std::string hashed_host = HashHost(canonicalized_host); 651 const std::string hashed_host = HashHost(canonicalized_host);
664 DomainStateMap::const_iterator i = enabled_hosts_.find( 652 DomainStateMap::const_iterator i = enabled_hosts_.find(
665 hashed_host); 653 hashed_host);
666 if (i != enabled_hosts_.end()) 654 if (i != enabled_hosts_.end())
667 domain_state = i->second; 655 domain_state = i->second;
668 656
669 domain_state.sts_observed = base::Time::Now(); 657 domain_state.sts.last_observed = base::Time::Now();
670 domain_state.sts_include_subdomains = include_subdomains; 658 domain_state.sts.include_subdomains = include_subdomains;
671 domain_state.upgrade_expiry = expiry; 659 domain_state.sts.expiry = expiry;
672 domain_state.upgrade_mode = DomainState::MODE_FORCE_HTTPS; 660 domain_state.sts.upgrade_mode = DomainState::MODE_FORCE_HTTPS;
673 EnableHost(host, domain_state); 661 EnableHost(host, domain_state);
674 return true; 662 return true;
675 } 663 }
676 664
677 bool TransportSecurityState::AddHPKP(const std::string& host, 665 bool TransportSecurityState::AddHPKP(const std::string& host,
678 const base::Time& expiry, 666 const base::Time& expiry,
679 bool include_subdomains, 667 bool include_subdomains,
680 const HashValueVector& hashes) { 668 const HashValueVector& hashes) {
681 DCHECK(CalledOnValidThread()); 669 DCHECK(CalledOnValidThread());
682 670
683 // Copy-and-modify the existing DomainState for this host (if any). 671 // Copy-and-modify the existing DomainState for this host (if any).
684 TransportSecurityState::DomainState domain_state; 672 TransportSecurityState::DomainState domain_state;
685 const std::string canonicalized_host = CanonicalizeHost(host); 673 const std::string canonicalized_host = CanonicalizeHost(host);
686 const std::string hashed_host = HashHost(canonicalized_host); 674 const std::string hashed_host = HashHost(canonicalized_host);
687 DomainStateMap::const_iterator i = enabled_hosts_.find( 675 DomainStateMap::const_iterator i = enabled_hosts_.find(
688 hashed_host); 676 hashed_host);
689 if (i != enabled_hosts_.end()) 677 if (i != enabled_hosts_.end())
690 domain_state = i->second; 678 domain_state = i->second;
691 679
692 domain_state.pkp_observed = base::Time::Now(); 680 domain_state.pkp.last_observed = base::Time::Now();
693 domain_state.pkp_include_subdomains = include_subdomains; 681 domain_state.pkp.include_subdomains = include_subdomains;
694 domain_state.dynamic_spki_hashes_expiry = expiry; 682 domain_state.pkp.expiry = expiry;
695 domain_state.dynamic_spki_hashes = hashes; 683 domain_state.pkp.spki_hashes = hashes;
696 EnableHost(host, domain_state); 684 EnableHost(host, domain_state);
697 return true; 685 return true;
698 } 686 }
699 687
700 // static 688 // static
701 bool TransportSecurityState::IsGooglePinnedProperty(const std::string& host, 689 bool TransportSecurityState::IsGooglePinnedProperty(const std::string& host,
702 bool sni_enabled) { 690 bool sni_enabled) {
703 std::string canonicalized_host = CanonicalizeHost(host); 691 std::string canonicalized_host = CanonicalizeHost(host);
704 const struct HSTSPreload* entry = 692 const struct HSTSPreload* entry =
705 GetHSTSPreload(canonicalized_host, kPreloadedSTS, kNumPreloadedSTS); 693 GetHSTSPreload(canonicalized_host, kPreloadedSTS, kNumPreloadedSTS);
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
758 } 746 }
759 747
760 // static 748 // static
761 bool TransportSecurityState::IsBuildTimely() { 749 bool TransportSecurityState::IsBuildTimely() {
762 const base::Time build_time = base::GetBuildTime(); 750 const base::Time build_time = base::GetBuildTime();
763 // We consider built-in information to be timely for 10 weeks. 751 // We consider built-in information to be timely for 10 weeks.
764 return (base::Time::Now() - build_time).InDays() < 70 /* 10 weeks */; 752 return (base::Time::Now() - build_time).InDays() < 70 /* 10 weeks */;
765 } 753 }
766 754
767 bool TransportSecurityState::GetStaticDomainState( 755 bool TransportSecurityState::GetStaticDomainState(
768 const std::string& canonicalized_host, 756 const std::string& host,
769 bool sni_enabled, 757 bool sni_enabled,
770 DomainState* out) { 758 DomainState* out) {
771 DCHECK(CalledOnValidThread()); 759 DCHECK(CalledOnValidThread());
772 760
773 out->upgrade_mode = DomainState::MODE_FORCE_HTTPS; 761 const std::string canonicalized_host = CanonicalizeHost(host);
774 out->sts_include_subdomains = false; 762
775 out->pkp_include_subdomains = false; 763 out->sts.upgrade_mode = DomainState::MODE_FORCE_HTTPS;
764 out->sts.include_subdomains = false;
765 out->pkp.include_subdomains = false;
776 766
777 const bool is_build_timely = IsBuildTimely(); 767 const bool is_build_timely = IsBuildTimely();
778 768
779 for (size_t i = 0; canonicalized_host[i]; i += canonicalized_host[i] + 1) { 769 for (size_t i = 0; canonicalized_host[i]; i += canonicalized_host[i] + 1) {
780 std::string host_sub_chunk(&canonicalized_host[i], 770 std::string host_sub_chunk(&canonicalized_host[i],
781 canonicalized_host.size() - i); 771 canonicalized_host.size() - i);
782 out->domain = DNSDomainToString(host_sub_chunk); 772 out->domain = DNSDomainToString(host_sub_chunk);
783 bool ret; 773 bool ret;
784 if (is_build_timely && 774 if (is_build_timely &&
785 HasPreload(kPreloadedSTS, kNumPreloadedSTS, canonicalized_host, i, out, 775 HasPreload(kPreloadedSTS, kNumPreloadedSTS, canonicalized_host, i, out,
(...skipping 23 matching lines...) Expand all
809 base::Time current_time(base::Time::Now()); 799 base::Time current_time(base::Time::Now());
810 800
811 for (size_t i = 0; canonicalized_host[i]; i += canonicalized_host[i] + 1) { 801 for (size_t i = 0; canonicalized_host[i]; i += canonicalized_host[i] + 1) {
812 std::string host_sub_chunk(&canonicalized_host[i], 802 std::string host_sub_chunk(&canonicalized_host[i],
813 canonicalized_host.size() - i); 803 canonicalized_host.size() - i);
814 DomainStateMap::iterator j = 804 DomainStateMap::iterator j =
815 enabled_hosts_.find(HashHost(host_sub_chunk)); 805 enabled_hosts_.find(HashHost(host_sub_chunk));
816 if (j == enabled_hosts_.end()) 806 if (j == enabled_hosts_.end())
817 continue; 807 continue;
818 808
819 if (current_time > j->second.upgrade_expiry && 809 if (current_time > j->second.sts.expiry &&
820 current_time > j->second.dynamic_spki_hashes_expiry) { 810 current_time > j->second.pkp.expiry) {
821 enabled_hosts_.erase(j); 811 enabled_hosts_.erase(j);
822 DirtyNotify(); 812 DirtyNotify();
823 continue; 813 continue;
824 } 814 }
825 815
826 state = j->second; 816 state = j->second;
827 state.domain = DNSDomainToString(host_sub_chunk); 817 state.domain = DNSDomainToString(host_sub_chunk);
828 818
829 // Succeed if we matched the domain exactly or if subdomain matches are 819 // Succeed if we matched the domain exactly or if subdomain matches are
830 // allowed. 820 // allowed.
831 if (i == 0 || j->second.sts_include_subdomains || 821 if (i == 0 || j->second.sts.include_subdomains ||
832 j->second.pkp_include_subdomains) { 822 j->second.pkp.include_subdomains) {
833 *result = state; 823 *result = state;
834 return true; 824 return true;
835 } 825 }
836 826
837 return false; 827 return false;
838 } 828 }
839 829
840 return false; 830 return false;
841 } 831 }
842 832
843
844 void TransportSecurityState::AddOrUpdateEnabledHosts( 833 void TransportSecurityState::AddOrUpdateEnabledHosts(
845 const std::string& hashed_host, const DomainState& state) { 834 const std::string& hashed_host, const DomainState& state) {
846 DCHECK(CalledOnValidThread()); 835 DCHECK(CalledOnValidThread());
847 enabled_hosts_[hashed_host] = state; 836 enabled_hosts_[hashed_host] = state;
848 } 837 }
849 838
850 TransportSecurityState::DomainState::DomainState() 839 TransportSecurityState::DomainState::DomainState() {
851 : upgrade_mode(MODE_DEFAULT), 840 sts.upgrade_mode = MODE_DEFAULT;
852 sts_include_subdomains(false), 841 sts.include_subdomains = false;
853 pkp_include_subdomains(false) { 842 pkp.include_subdomains = false;
854 base::Time now(base::Time::Now());
855 sts_observed = now;
856 pkp_observed = now;
857 } 843 }
858 844
859 TransportSecurityState::DomainState::~DomainState() { 845 TransportSecurityState::DomainState::~DomainState() {
860 } 846 }
861 847
862 bool TransportSecurityState::DomainState::CheckPublicKeyPins( 848 bool TransportSecurityState::DomainState::CheckPublicKeyPins(
863 const HashValueVector& hashes) const { 849 const HashValueVector& hashes) const {
864 // Validate that hashes is not empty. By the time this code is called (in 850 // Validate that hashes is not empty. By the time this code is called (in
865 // production), that should never happen, but it's good to be defensive. 851 // production), that should never happen, but it's good to be defensive.
866 // And, hashes *can* be empty in some test scenarios. 852 // And, hashes *can* be empty in some test scenarios.
867 if (hashes.empty()) { 853 if (hashes.empty()) {
868 LOG(ERROR) << "Rejecting empty public key chain for public-key-pinned " 854 LOG(ERROR) << "Rejecting empty public key chain for public-key-pinned "
869 "domain " << domain; 855 "domain " << domain;
870 return false; 856 return false;
871 } 857 }
872 858
873 if (HashesIntersect(bad_static_spki_hashes, hashes)) { 859 if (HashesIntersect(pkp.bad_spki_hashes, hashes)) {
874 LOG(ERROR) << "Rejecting public key chain for domain " << domain 860 LOG(ERROR) << "Rejecting public key chain for domain " << domain
875 << ". Validated chain: " << HashesToBase64String(hashes) 861 << ". Validated chain: " << HashesToBase64String(hashes)
876 << ", matches one or more bad hashes: " 862 << ", matches one or more bad hashes: "
877 << HashesToBase64String(bad_static_spki_hashes); 863 << HashesToBase64String(pkp.bad_spki_hashes);
878 return false; 864 return false;
879 } 865 }
880 866
881 // If there are no pins, then any valid chain is acceptable. 867 // If there are no pins, then any valid chain is acceptable.
882 if (dynamic_spki_hashes.empty() && static_spki_hashes.empty()) 868 if (pkp.spki_hashes.empty())
883 return true; 869 return true;
884 870
885 if (HashesIntersect(dynamic_spki_hashes, hashes) || 871 if (HashesIntersect(pkp.spki_hashes, hashes)) {
886 HashesIntersect(static_spki_hashes, hashes)) {
887 return true; 872 return true;
888 } 873 }
889 874
890 LOG(ERROR) << "Rejecting public key chain for domain " << domain 875 LOG(ERROR) << "Rejecting public key chain for domain " << domain
891 << ". Validated chain: " << HashesToBase64String(hashes) 876 << ". Validated chain: " << HashesToBase64String(hashes)
892 << ", expected: " << HashesToBase64String(dynamic_spki_hashes) 877 << ", expected: " << HashesToBase64String(pkp.spki_hashes);
893 << " or: " << HashesToBase64String(static_spki_hashes);
894 return false; 878 return false;
895 } 879 }
896 880
897 bool TransportSecurityState::DomainState::ShouldUpgradeToSSL() const { 881 bool TransportSecurityState::DomainState::ShouldUpgradeToSSL() const {
898 return upgrade_mode == MODE_FORCE_HTTPS; 882 return sts.upgrade_mode == MODE_FORCE_HTTPS;
899 } 883 }
900 884
901 bool TransportSecurityState::DomainState::ShouldSSLErrorsBeFatal() const { 885 bool TransportSecurityState::DomainState::ShouldSSLErrorsBeFatal() const {
902 return true; 886 return true;
903 } 887 }
904 888
905 bool TransportSecurityState::DomainState::HasPublicKeyPins() const { 889 bool TransportSecurityState::DomainState::HasPublicKeyPins() const {
906 return static_spki_hashes.size() > 0 || 890 return pkp.spki_hashes.size() > 0 ||
907 bad_static_spki_hashes.size() > 0 || 891 pkp.bad_spki_hashes.size() > 0;
908 dynamic_spki_hashes.size() > 0;
909 } 892 }
910 893
911 } // namespace 894 } // namespace
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698