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

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

Issue 266243004: Clang format slam. Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: 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 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
55 } 55 }
56 56
57 std::string HashHost(const std::string& canonicalized_host) { 57 std::string HashHost(const std::string& canonicalized_host) {
58 char hashed[crypto::kSHA256Length]; 58 char hashed[crypto::kSHA256Length];
59 crypto::SHA256HashString(canonicalized_host, hashed, sizeof(hashed)); 59 crypto::SHA256HashString(canonicalized_host, hashed, sizeof(hashed));
60 return std::string(hashed, sizeof(hashed)); 60 return std::string(hashed, sizeof(hashed));
61 } 61 }
62 62
63 // Returns true if the intersection of |a| and |b| is not empty. If either 63 // Returns true if the intersection of |a| and |b| is not empty. If either
64 // |a| or |b| is empty, returns false. 64 // |a| or |b| is empty, returns false.
65 bool HashesIntersect(const HashValueVector& a, 65 bool HashesIntersect(const HashValueVector& a, const HashValueVector& b) {
66 const HashValueVector& b) {
67 for (HashValueVector::const_iterator i = a.begin(); i != a.end(); ++i) { 66 for (HashValueVector::const_iterator i = a.begin(); i != a.end(); ++i) {
68 HashValueVector::const_iterator j = 67 HashValueVector::const_iterator j =
69 std::find_if(b.begin(), b.end(), HashValuesEqual(*i)); 68 std::find_if(b.begin(), b.end(), HashValuesEqual(*i));
70 if (j != b.end()) 69 if (j != b.end())
71 return true; 70 return true;
72 } 71 }
73 return false; 72 return false;
74 } 73 }
75 74
76 bool AddHash(const char* sha1_hash, 75 bool AddHash(const char* sha1_hash, HashValueVector* out) {
77 HashValueVector* out) {
78 HashValue hash(HASH_VALUE_SHA1); 76 HashValue hash(HASH_VALUE_SHA1);
79 memcpy(hash.data(), sha1_hash, hash.size()); 77 memcpy(hash.data(), sha1_hash, hash.size());
80 out->push_back(hash); 78 out->push_back(hash);
81 return true; 79 return true;
82 } 80 }
83 81
84 } // namespace 82 } // namespace
85 83
86 TransportSecurityState::TransportSecurityState() 84 TransportSecurityState::TransportSecurityState() : delegate_(NULL) {
87 : delegate_(NULL) {
88 DCHECK(CalledOnValidThread()); 85 DCHECK(CalledOnValidThread());
89 } 86 }
90 87
91 TransportSecurityState::Iterator::Iterator(const TransportSecurityState& state) 88 TransportSecurityState::Iterator::Iterator(const TransportSecurityState& state)
92 : iterator_(state.enabled_hosts_.begin()), 89 : iterator_(state.enabled_hosts_.begin()),
93 end_(state.enabled_hosts_.end()) { 90 end_(state.enabled_hosts_.end()) {
94 } 91 }
95 92
96 TransportSecurityState::Iterator::~Iterator() {} 93 TransportSecurityState::Iterator::~Iterator() {
94 }
97 95
98 void TransportSecurityState::SetDelegate( 96 void TransportSecurityState::SetDelegate(
99 TransportSecurityState::Delegate* delegate) { 97 TransportSecurityState::Delegate* delegate) {
100 DCHECK(CalledOnValidThread()); 98 DCHECK(CalledOnValidThread());
101 delegate_ = delegate; 99 delegate_ = delegate;
102 } 100 }
103 101
104 void TransportSecurityState::EnableHost(const std::string& host, 102 void TransportSecurityState::EnableHost(const std::string& host,
105 const DomainState& state) { 103 const DomainState& state) {
106 DCHECK(CalledOnValidThread()); 104 DCHECK(CalledOnValidThread());
(...skipping 11 matching lines...) Expand all
118 DirtyNotify(); 116 DirtyNotify();
119 } 117 }
120 118
121 bool TransportSecurityState::DeleteDynamicDataForHost(const std::string& host) { 119 bool TransportSecurityState::DeleteDynamicDataForHost(const std::string& host) {
122 DCHECK(CalledOnValidThread()); 120 DCHECK(CalledOnValidThread());
123 121
124 const std::string canonicalized_host = CanonicalizeHost(host); 122 const std::string canonicalized_host = CanonicalizeHost(host);
125 if (canonicalized_host.empty()) 123 if (canonicalized_host.empty())
126 return false; 124 return false;
127 125
128 DomainStateMap::iterator i = enabled_hosts_.find( 126 DomainStateMap::iterator i =
129 HashHost(canonicalized_host)); 127 enabled_hosts_.find(HashHost(canonicalized_host));
130 if (i != enabled_hosts_.end()) { 128 if (i != enabled_hosts_.end()) {
131 enabled_hosts_.erase(i); 129 enabled_hosts_.erase(i);
132 DirtyNotify(); 130 DirtyNotify();
133 return true; 131 return true;
134 } 132 }
135 return false; 133 return false;
136 } 134 }
137 135
138 bool TransportSecurityState::GetDomainState(const std::string& host, 136 bool TransportSecurityState::GetDomainState(const std::string& host,
139 bool sni_enabled, 137 bool sni_enabled,
140 DomainState* result) { 138 DomainState* result) {
141 DCHECK(CalledOnValidThread()); 139 DCHECK(CalledOnValidThread());
142 140
143 DomainState state; 141 DomainState state;
144 const std::string canonicalized_host = CanonicalizeHost(host); 142 const std::string canonicalized_host = CanonicalizeHost(host);
145 if (canonicalized_host.empty()) 143 if (canonicalized_host.empty())
146 return false; 144 return false;
147 145
148 bool has_preload = GetStaticDomainState(canonicalized_host, sni_enabled, 146 bool has_preload =
149 &state); 147 GetStaticDomainState(canonicalized_host, sni_enabled, &state);
150 std::string canonicalized_preload = CanonicalizeHost(state.domain); 148 std::string canonicalized_preload = CanonicalizeHost(state.domain);
151 GetDynamicDomainState(host, &state); 149 GetDynamicDomainState(host, &state);
152 150
153 base::Time current_time(base::Time::Now()); 151 base::Time current_time(base::Time::Now());
154 152
155 for (size_t i = 0; canonicalized_host[i]; i += canonicalized_host[i] + 1) { 153 for (size_t i = 0; canonicalized_host[i]; i += canonicalized_host[i] + 1) {
156 std::string host_sub_chunk(&canonicalized_host[i], 154 std::string host_sub_chunk(&canonicalized_host[i],
157 canonicalized_host.size() - i); 155 canonicalized_host.size() - i);
158 // Exact match of a preload always wins. 156 // Exact match of a preload always wins.
159 if (has_preload && host_sub_chunk == canonicalized_preload) { 157 if (has_preload && host_sub_chunk == canonicalized_preload) {
160 *result = state; 158 *result = state;
161 return true; 159 return true;
162 } 160 }
163 161
164 DomainStateMap::iterator j = 162 DomainStateMap::iterator j = enabled_hosts_.find(HashHost(host_sub_chunk));
165 enabled_hosts_.find(HashHost(host_sub_chunk));
166 if (j == enabled_hosts_.end()) 163 if (j == enabled_hosts_.end())
167 continue; 164 continue;
168 165
169 if (current_time > j->second.upgrade_expiry && 166 if (current_time > j->second.upgrade_expiry &&
170 current_time > j->second.dynamic_spki_hashes_expiry) { 167 current_time > j->second.dynamic_spki_hashes_expiry) {
171 enabled_hosts_.erase(j); 168 enabled_hosts_.erase(j);
172 DirtyNotify(); 169 DirtyNotify();
173 continue; 170 continue;
174 } 171 }
175 172
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
258 return new_host; 255 return new_host;
259 } 256 }
260 257
261 // |ReportUMAOnPinFailure| uses these to report which domain was associated 258 // |ReportUMAOnPinFailure| uses these to report which domain was associated
262 // with the public key pinning failure. 259 // with the public key pinning failure.
263 // 260 //
264 // DO NOT CHANGE THE ORDERING OF THESE NAMES OR REMOVE ANY OF THEM. Add new 261 // DO NOT CHANGE THE ORDERING OF THESE NAMES OR REMOVE ANY OF THEM. Add new
265 // domains at the END of the listing (but before DOMAIN_NUM_EVENTS). 262 // domains at the END of the listing (but before DOMAIN_NUM_EVENTS).
266 enum SecondLevelDomainName { 263 enum SecondLevelDomainName {
267 DOMAIN_NOT_PINNED, 264 DOMAIN_NOT_PINNED,
268
269 DOMAIN_GOOGLE_COM, 265 DOMAIN_GOOGLE_COM,
270 DOMAIN_ANDROID_COM, 266 DOMAIN_ANDROID_COM,
271 DOMAIN_GOOGLE_ANALYTICS_COM, 267 DOMAIN_GOOGLE_ANALYTICS_COM,
272 DOMAIN_GOOGLEPLEX_COM, 268 DOMAIN_GOOGLEPLEX_COM,
273 DOMAIN_YTIMG_COM, 269 DOMAIN_YTIMG_COM,
274 DOMAIN_GOOGLEUSERCONTENT_COM, 270 DOMAIN_GOOGLEUSERCONTENT_COM,
275 DOMAIN_YOUTUBE_COM, 271 DOMAIN_YOUTUBE_COM,
276 DOMAIN_GOOGLEAPIS_COM, 272 DOMAIN_GOOGLEAPIS_COM,
277 DOMAIN_GOOGLEADSERVICES_COM, 273 DOMAIN_GOOGLEADSERVICES_COM,
278 DOMAIN_GOOGLECODE_COM, 274 DOMAIN_GOOGLECODE_COM,
279 DOMAIN_APPSPOT_COM, 275 DOMAIN_APPSPOT_COM,
280 DOMAIN_GOOGLESYNDICATION_COM, 276 DOMAIN_GOOGLESYNDICATION_COM,
281 DOMAIN_DOUBLECLICK_NET, 277 DOMAIN_DOUBLECLICK_NET,
282 DOMAIN_GSTATIC_COM, 278 DOMAIN_GSTATIC_COM,
283 DOMAIN_GMAIL_COM, 279 DOMAIN_GMAIL_COM,
284 DOMAIN_GOOGLEMAIL_COM, 280 DOMAIN_GOOGLEMAIL_COM,
285 DOMAIN_GOOGLEGROUPS_COM, 281 DOMAIN_GOOGLEGROUPS_COM,
286
287 DOMAIN_TORPROJECT_ORG, 282 DOMAIN_TORPROJECT_ORG,
288
289 DOMAIN_TWITTER_COM, 283 DOMAIN_TWITTER_COM,
290 DOMAIN_TWIMG_COM, 284 DOMAIN_TWIMG_COM,
291
292 DOMAIN_AKAMAIHD_NET, 285 DOMAIN_AKAMAIHD_NET,
293
294 DOMAIN_TOR2WEB_ORG, 286 DOMAIN_TOR2WEB_ORG,
295
296 DOMAIN_YOUTU_BE, 287 DOMAIN_YOUTU_BE,
297 DOMAIN_GOOGLECOMMERCE_COM, 288 DOMAIN_GOOGLECOMMERCE_COM,
298 DOMAIN_URCHIN_COM, 289 DOMAIN_URCHIN_COM,
299 DOMAIN_GOO_GL, 290 DOMAIN_GOO_GL,
300 DOMAIN_G_CO, 291 DOMAIN_G_CO,
301 DOMAIN_GOOGLE_AC, 292 DOMAIN_GOOGLE_AC,
302 DOMAIN_GOOGLE_AD, 293 DOMAIN_GOOGLE_AD,
303 DOMAIN_GOOGLE_AE, 294 DOMAIN_GOOGLE_AE,
304 DOMAIN_GOOGLE_AF, 295 DOMAIN_GOOGLE_AF,
305 DOMAIN_GOOGLE_AG, 296 DOMAIN_GOOGLE_AG,
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
508 DOMAIN_GOOGLE_TM, 499 DOMAIN_GOOGLE_TM,
509 DOMAIN_GOOGLE_TN, 500 DOMAIN_GOOGLE_TN,
510 DOMAIN_GOOGLE_TO, 501 DOMAIN_GOOGLE_TO,
511 DOMAIN_GOOGLE_TP, 502 DOMAIN_GOOGLE_TP,
512 DOMAIN_GOOGLE_TT, 503 DOMAIN_GOOGLE_TT,
513 DOMAIN_GOOGLE_US, 504 DOMAIN_GOOGLE_US,
514 DOMAIN_GOOGLE_UZ, 505 DOMAIN_GOOGLE_UZ,
515 DOMAIN_GOOGLE_VG, 506 DOMAIN_GOOGLE_VG,
516 DOMAIN_GOOGLE_VU, 507 DOMAIN_GOOGLE_VU,
517 DOMAIN_GOOGLE_WS, 508 DOMAIN_GOOGLE_WS,
518
519 DOMAIN_CHROMIUM_ORG, 509 DOMAIN_CHROMIUM_ORG,
520
521 DOMAIN_CRYPTO_CAT, 510 DOMAIN_CRYPTO_CAT,
522 DOMAIN_LAVABIT_COM, 511 DOMAIN_LAVABIT_COM,
523
524 DOMAIN_GOOGLETAGMANAGER_COM, 512 DOMAIN_GOOGLETAGMANAGER_COM,
525 DOMAIN_GOOGLETAGSERVICES_COM, 513 DOMAIN_GOOGLETAGSERVICES_COM,
526 514
527 // Boundary value for UMA_HISTOGRAM_ENUMERATION: 515 // Boundary value for UMA_HISTOGRAM_ENUMERATION:
528 DOMAIN_NUM_EVENTS 516 DOMAIN_NUM_EVENTS
529 }; 517 };
530 518
531 // PublicKeyPins contains a number of SubjectPublicKeyInfo hashes for a site. 519 // PublicKeyPins contains a number of SubjectPublicKeyInfo hashes for a site.
532 // The validated certificate chain for the site must not include any of 520 // The validated certificate chain for the site must not include any of
533 // |excluded_hashes| and must include one or more of |required_hashes|. 521 // |excluded_hashes| and must include one or more of |required_hashes|.
534 struct PublicKeyPins { 522 struct PublicKeyPins {
535 const char* const* required_hashes; 523 const char* const* required_hashes;
536 const char* const* excluded_hashes; 524 const char* const* excluded_hashes;
537 }; 525 };
538 526
539 struct HSTSPreload { 527 struct HSTSPreload {
540 uint8 length; 528 uint8 length;
541 bool include_subdomains; 529 bool include_subdomains;
542 char dns_name[38]; 530 char dns_name[38];
543 bool https_required; 531 bool https_required;
544 PublicKeyPins pins; 532 PublicKeyPins pins;
545 SecondLevelDomainName second_level_domain_name; 533 SecondLevelDomainName second_level_domain_name;
546 }; 534 };
547 535
548 static bool HasPreload(const struct HSTSPreload* entries, size_t num_entries, 536 static bool HasPreload(const struct HSTSPreload* entries,
549 const std::string& canonicalized_host, size_t i, 537 size_t num_entries,
550 TransportSecurityState::DomainState* out, bool* ret) { 538 const std::string& canonicalized_host,
539 size_t i,
540 TransportSecurityState::DomainState* out,
541 bool* ret) {
551 for (size_t j = 0; j < num_entries; j++) { 542 for (size_t j = 0; j < num_entries; j++) {
552 if (entries[j].length == canonicalized_host.size() - i && 543 if (entries[j].length == canonicalized_host.size() - i &&
553 memcmp(entries[j].dns_name, &canonicalized_host[i], 544 memcmp(entries[j].dns_name,
545 &canonicalized_host[i],
554 entries[j].length) == 0) { 546 entries[j].length) == 0) {
555 if (!entries[j].include_subdomains && i != 0) { 547 if (!entries[j].include_subdomains && i != 0) {
556 *ret = false; 548 *ret = false;
557 } else { 549 } else {
558 out->sts_include_subdomains = entries[j].include_subdomains; 550 out->sts_include_subdomains = entries[j].include_subdomains;
559 out->pkp_include_subdomains = entries[j].include_subdomains; 551 out->pkp_include_subdomains = entries[j].include_subdomains;
560 *ret = true; 552 *ret = true;
561 if (!entries[j].https_required) 553 if (!entries[j].https_required)
562 out->upgrade_mode = TransportSecurityState::DomainState::MODE_DEFAULT; 554 out->upgrade_mode = TransportSecurityState::DomainState::MODE_DEFAULT;
563 if (entries[j].pins.required_hashes) { 555 if (entries[j].pins.required_hashes) {
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
634 626
635 bool TransportSecurityState::AddHPKPHeader(const std::string& host, 627 bool TransportSecurityState::AddHPKPHeader(const std::string& host,
636 const std::string& value, 628 const std::string& value,
637 const SSLInfo& ssl_info) { 629 const SSLInfo& ssl_info) {
638 DCHECK(CalledOnValidThread()); 630 DCHECK(CalledOnValidThread());
639 631
640 base::Time now = base::Time::Now(); 632 base::Time now = base::Time::Now();
641 base::TimeDelta max_age; 633 base::TimeDelta max_age;
642 TransportSecurityState::DomainState domain_state; 634 TransportSecurityState::DomainState domain_state;
643 GetDynamicDomainState(host, &domain_state); 635 GetDynamicDomainState(host, &domain_state);
644 if (ParseHPKPHeader(value, ssl_info.public_key_hashes, 636 if (ParseHPKPHeader(value,
645 &max_age, &domain_state.pkp_include_subdomains, 637 ssl_info.public_key_hashes,
638 &max_age,
639 &domain_state.pkp_include_subdomains,
646 &domain_state.dynamic_spki_hashes)) { 640 &domain_state.dynamic_spki_hashes)) {
647 // TODO(palmer): http://crbug.com/243865 handle max-age == 0. 641 // TODO(palmer): http://crbug.com/243865 handle max-age == 0.
648 domain_state.pkp_observed = now; 642 domain_state.pkp_observed = now;
649 domain_state.dynamic_spki_hashes_expiry = now + max_age; 643 domain_state.dynamic_spki_hashes_expiry = now + max_age;
650 EnableHost(host, domain_state); 644 EnableHost(host, domain_state);
651 return true; 645 return true;
652 } 646 }
653 return false; 647 return false;
654 } 648 }
655 649
656 bool TransportSecurityState::AddHSTS(const std::string& host, 650 bool TransportSecurityState::AddHSTS(const std::string& host,
657 const base::Time& expiry, 651 const base::Time& expiry,
658 bool include_subdomains) { 652 bool include_subdomains) {
659 DCHECK(CalledOnValidThread()); 653 DCHECK(CalledOnValidThread());
660 654
661 // Copy-and-modify the existing DomainState for this host (if any). 655 // Copy-and-modify the existing DomainState for this host (if any).
662 TransportSecurityState::DomainState domain_state; 656 TransportSecurityState::DomainState domain_state;
663 const std::string canonicalized_host = CanonicalizeHost(host); 657 const std::string canonicalized_host = CanonicalizeHost(host);
664 const std::string hashed_host = HashHost(canonicalized_host); 658 const std::string hashed_host = HashHost(canonicalized_host);
665 DomainStateMap::const_iterator i = enabled_hosts_.find( 659 DomainStateMap::const_iterator i = enabled_hosts_.find(hashed_host);
666 hashed_host);
667 if (i != enabled_hosts_.end()) 660 if (i != enabled_hosts_.end())
668 domain_state = i->second; 661 domain_state = i->second;
669 662
670 domain_state.sts_observed = base::Time::Now(); 663 domain_state.sts_observed = base::Time::Now();
671 domain_state.sts_include_subdomains = include_subdomains; 664 domain_state.sts_include_subdomains = include_subdomains;
672 domain_state.upgrade_expiry = expiry; 665 domain_state.upgrade_expiry = expiry;
673 domain_state.upgrade_mode = DomainState::MODE_FORCE_HTTPS; 666 domain_state.upgrade_mode = DomainState::MODE_FORCE_HTTPS;
674 EnableHost(host, domain_state); 667 EnableHost(host, domain_state);
675 return true; 668 return true;
676 } 669 }
677 670
678 bool TransportSecurityState::AddHPKP(const std::string& host, 671 bool TransportSecurityState::AddHPKP(const std::string& host,
679 const base::Time& expiry, 672 const base::Time& expiry,
680 bool include_subdomains, 673 bool include_subdomains,
681 const HashValueVector& hashes) { 674 const HashValueVector& hashes) {
682 DCHECK(CalledOnValidThread()); 675 DCHECK(CalledOnValidThread());
683 676
684 // Copy-and-modify the existing DomainState for this host (if any). 677 // Copy-and-modify the existing DomainState for this host (if any).
685 TransportSecurityState::DomainState domain_state; 678 TransportSecurityState::DomainState domain_state;
686 const std::string canonicalized_host = CanonicalizeHost(host); 679 const std::string canonicalized_host = CanonicalizeHost(host);
687 const std::string hashed_host = HashHost(canonicalized_host); 680 const std::string hashed_host = HashHost(canonicalized_host);
688 DomainStateMap::const_iterator i = enabled_hosts_.find( 681 DomainStateMap::const_iterator i = enabled_hosts_.find(hashed_host);
689 hashed_host);
690 if (i != enabled_hosts_.end()) 682 if (i != enabled_hosts_.end())
691 domain_state = i->second; 683 domain_state = i->second;
692 684
693 domain_state.pkp_observed = base::Time::Now(); 685 domain_state.pkp_observed = base::Time::Now();
694 domain_state.pkp_include_subdomains = include_subdomains; 686 domain_state.pkp_include_subdomains = include_subdomains;
695 domain_state.dynamic_spki_hashes_expiry = expiry; 687 domain_state.dynamic_spki_hashes_expiry = expiry;
696 domain_state.dynamic_spki_hashes = hashes; 688 domain_state.dynamic_spki_hashes = hashes;
697 EnableHost(host, domain_state); 689 EnableHost(host, domain_state);
698 return true; 690 return true;
699 } 691 }
700 692
701 // static 693 // static
702 bool TransportSecurityState::IsGooglePinnedProperty(const std::string& host, 694 bool TransportSecurityState::IsGooglePinnedProperty(const std::string& host,
703 bool sni_enabled) { 695 bool sni_enabled) {
704 std::string canonicalized_host = CanonicalizeHost(host); 696 std::string canonicalized_host = CanonicalizeHost(host);
705 const struct HSTSPreload* entry = 697 const struct HSTSPreload* entry =
706 GetHSTSPreload(canonicalized_host, kPreloadedSTS, kNumPreloadedSTS); 698 GetHSTSPreload(canonicalized_host, kPreloadedSTS, kNumPreloadedSTS);
707 699
708 if (entry && entry->pins.required_hashes == kGoogleAcceptableCerts) 700 if (entry && entry->pins.required_hashes == kGoogleAcceptableCerts)
709 return true; 701 return true;
710 702
711 if (sni_enabled) { 703 if (sni_enabled) {
712 entry = GetHSTSPreload(canonicalized_host, kPreloadedSNISTS, 704 entry = GetHSTSPreload(
713 kNumPreloadedSNISTS); 705 canonicalized_host, kPreloadedSNISTS, kNumPreloadedSNISTS);
714 if (entry && entry->pins.required_hashes == kGoogleAcceptableCerts) 706 if (entry && entry->pins.required_hashes == kGoogleAcceptableCerts)
715 return true; 707 return true;
716 } 708 }
717 709
718 return false; 710 return false;
719 } 711 }
720 712
721 // static 713 // static
722 void TransportSecurityState::ReportUMAOnPinFailure(const std::string& host) { 714 void TransportSecurityState::ReportUMAOnPinFailure(const std::string& host) {
723 std::string canonicalized_host = CanonicalizeHost(host); 715 std::string canonicalized_host = CanonicalizeHost(host);
724 716
725 const struct HSTSPreload* entry = 717 const struct HSTSPreload* entry =
726 GetHSTSPreload(canonicalized_host, kPreloadedSTS, kNumPreloadedSTS); 718 GetHSTSPreload(canonicalized_host, kPreloadedSTS, kNumPreloadedSTS);
727 719
728 if (!entry) { 720 if (!entry) {
729 entry = GetHSTSPreload(canonicalized_host, kPreloadedSNISTS, 721 entry = GetHSTSPreload(
730 kNumPreloadedSNISTS); 722 canonicalized_host, kPreloadedSNISTS, kNumPreloadedSNISTS);
731 } 723 }
732 724
733 if (!entry) { 725 if (!entry) {
734 // We don't care to report pin failures for dynamic pins. 726 // We don't care to report pin failures for dynamic pins.
735 return; 727 return;
736 } 728 }
737 729
738 DCHECK(entry); 730 DCHECK(entry);
739 DCHECK(entry->pins.required_hashes); 731 DCHECK(entry->pins.required_hashes);
740 DCHECK(entry->second_level_domain_name != DOMAIN_NOT_PINNED); 732 DCHECK(entry->second_level_domain_name != DOMAIN_NOT_PINNED);
741 733
742 UMA_HISTOGRAM_ENUMERATION("Net.PublicKeyPinFailureDomain", 734 UMA_HISTOGRAM_ENUMERATION("Net.PublicKeyPinFailureDomain",
743 entry->second_level_domain_name, DOMAIN_NUM_EVENTS); 735 entry->second_level_domain_name,
736 DOMAIN_NUM_EVENTS);
744 } 737 }
745 738
746 // static 739 // static
747 bool TransportSecurityState::IsBuildTimely() { 740 bool TransportSecurityState::IsBuildTimely() {
748 const base::Time build_time = base::GetBuildTime(); 741 const base::Time build_time = base::GetBuildTime();
749 // We consider built-in information to be timely for 10 weeks. 742 // We consider built-in information to be timely for 10 weeks.
750 return (base::Time::Now() - build_time).InDays() < 70 /* 10 weeks */; 743 return (base::Time::Now() - build_time).InDays() < 70 /* 10 weeks */;
751 } 744 }
752 745
753 bool TransportSecurityState::GetStaticDomainState( 746 bool TransportSecurityState::GetStaticDomainState(
754 const std::string& canonicalized_host, 747 const std::string& canonicalized_host,
755 bool sni_enabled, 748 bool sni_enabled,
756 DomainState* out) { 749 DomainState* out) {
757 DCHECK(CalledOnValidThread()); 750 DCHECK(CalledOnValidThread());
758 751
759 out->upgrade_mode = DomainState::MODE_FORCE_HTTPS; 752 out->upgrade_mode = DomainState::MODE_FORCE_HTTPS;
760 out->sts_include_subdomains = false; 753 out->sts_include_subdomains = false;
761 out->pkp_include_subdomains = false; 754 out->pkp_include_subdomains = false;
762 755
763 const bool is_build_timely = IsBuildTimely(); 756 const bool is_build_timely = IsBuildTimely();
764 757
765 for (size_t i = 0; canonicalized_host[i]; i += canonicalized_host[i] + 1) { 758 for (size_t i = 0; canonicalized_host[i]; i += canonicalized_host[i] + 1) {
766 std::string host_sub_chunk(&canonicalized_host[i], 759 std::string host_sub_chunk(&canonicalized_host[i],
767 canonicalized_host.size() - i); 760 canonicalized_host.size() - i);
768 out->domain = DNSDomainToString(host_sub_chunk); 761 out->domain = DNSDomainToString(host_sub_chunk);
769 bool ret; 762 bool ret;
770 if (is_build_timely && 763 if (is_build_timely && HasPreload(kPreloadedSTS,
771 HasPreload(kPreloadedSTS, kNumPreloadedSTS, canonicalized_host, i, out, 764 kNumPreloadedSTS,
772 &ret)) { 765 canonicalized_host,
766 i,
767 out,
768 &ret)) {
773 return ret; 769 return ret;
774 } 770 }
775 if (sni_enabled && 771 if (sni_enabled && is_build_timely && HasPreload(kPreloadedSNISTS,
776 is_build_timely && 772 kNumPreloadedSNISTS,
777 HasPreload(kPreloadedSNISTS, kNumPreloadedSNISTS, canonicalized_host, i, 773 canonicalized_host,
778 out, &ret)) { 774 i,
775 out,
776 &ret)) {
779 return ret; 777 return ret;
780 } 778 }
781 } 779 }
782 780
783 return false; 781 return false;
784 } 782 }
785 783
786 bool TransportSecurityState::GetDynamicDomainState(const std::string& host, 784 bool TransportSecurityState::GetDynamicDomainState(const std::string& host,
787 DomainState* result) { 785 DomainState* result) {
788 DCHECK(CalledOnValidThread()); 786 DCHECK(CalledOnValidThread());
789 787
790 DomainState state; 788 DomainState state;
791 const std::string canonicalized_host = CanonicalizeHost(host); 789 const std::string canonicalized_host = CanonicalizeHost(host);
792 if (canonicalized_host.empty()) 790 if (canonicalized_host.empty())
793 return false; 791 return false;
794 792
795 base::Time current_time(base::Time::Now()); 793 base::Time current_time(base::Time::Now());
796 794
797 for (size_t i = 0; canonicalized_host[i]; i += canonicalized_host[i] + 1) { 795 for (size_t i = 0; canonicalized_host[i]; i += canonicalized_host[i] + 1) {
798 std::string host_sub_chunk(&canonicalized_host[i], 796 std::string host_sub_chunk(&canonicalized_host[i],
799 canonicalized_host.size() - i); 797 canonicalized_host.size() - i);
800 DomainStateMap::iterator j = 798 DomainStateMap::iterator j = enabled_hosts_.find(HashHost(host_sub_chunk));
801 enabled_hosts_.find(HashHost(host_sub_chunk));
802 if (j == enabled_hosts_.end()) 799 if (j == enabled_hosts_.end())
803 continue; 800 continue;
804 801
805 if (current_time > j->second.upgrade_expiry && 802 if (current_time > j->second.upgrade_expiry &&
806 current_time > j->second.dynamic_spki_hashes_expiry) { 803 current_time > j->second.dynamic_spki_hashes_expiry) {
807 enabled_hosts_.erase(j); 804 enabled_hosts_.erase(j);
808 DirtyNotify(); 805 DirtyNotify();
809 continue; 806 continue;
810 } 807 }
811 808
812 state = j->second; 809 state = j->second;
813 state.domain = DNSDomainToString(host_sub_chunk); 810 state.domain = DNSDomainToString(host_sub_chunk);
814 811
815 // Succeed if we matched the domain exactly or if subdomain matches are 812 // Succeed if we matched the domain exactly or if subdomain matches are
816 // allowed. 813 // allowed.
817 if (i == 0 || j->second.sts_include_subdomains || 814 if (i == 0 || j->second.sts_include_subdomains ||
818 j->second.pkp_include_subdomains) { 815 j->second.pkp_include_subdomains) {
819 *result = state; 816 *result = state;
820 return true; 817 return true;
821 } 818 }
822 819
823 return false; 820 return false;
824 } 821 }
825 822
826 return false; 823 return false;
827 } 824 }
828 825
829
830 void TransportSecurityState::AddOrUpdateEnabledHosts( 826 void TransportSecurityState::AddOrUpdateEnabledHosts(
831 const std::string& hashed_host, const DomainState& state) { 827 const std::string& hashed_host,
828 const DomainState& state) {
832 DCHECK(CalledOnValidThread()); 829 DCHECK(CalledOnValidThread());
833 enabled_hosts_[hashed_host] = state; 830 enabled_hosts_[hashed_host] = state;
834 } 831 }
835 832
836 TransportSecurityState::DomainState::DomainState() 833 TransportSecurityState::DomainState::DomainState()
837 : upgrade_mode(MODE_DEFAULT), 834 : upgrade_mode(MODE_DEFAULT),
838 sts_include_subdomains(false), 835 sts_include_subdomains(false),
839 pkp_include_subdomains(false) { 836 pkp_include_subdomains(false) {
840 base::Time now(base::Time::Now()); 837 base::Time now(base::Time::Now());
841 sts_observed = now; 838 sts_observed = now;
842 pkp_observed = now; 839 pkp_observed = now;
843 } 840 }
844 841
845 TransportSecurityState::DomainState::~DomainState() { 842 TransportSecurityState::DomainState::~DomainState() {
846 } 843 }
847 844
848 bool TransportSecurityState::DomainState::CheckPublicKeyPins( 845 bool TransportSecurityState::DomainState::CheckPublicKeyPins(
849 const HashValueVector& hashes, std::string* failure_log) const { 846 const HashValueVector& hashes,
847 std::string* failure_log) const {
850 // Validate that hashes is not empty. By the time this code is called (in 848 // 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. 849 // production), that should never happen, but it's good to be defensive.
852 // And, hashes *can* be empty in some test scenarios. 850 // And, hashes *can* be empty in some test scenarios.
853 if (hashes.empty()) { 851 if (hashes.empty()) {
854 *failure_log = "Rejecting empty public key chain for public-key-pinned " 852 *failure_log =
855 "domains: " + domain; 853 "Rejecting empty public key chain for public-key-pinned "
854 "domains: " +
855 domain;
856 return false; 856 return false;
857 } 857 }
858 858
859 if (HashesIntersect(bad_static_spki_hashes, hashes)) { 859 if (HashesIntersect(bad_static_spki_hashes, hashes)) {
860 *failure_log = "Rejecting public key chain for domain " + domain + 860 *failure_log = "Rejecting public key chain for domain " + domain +
861 ". Validated chain: " + HashesToBase64String(hashes) + 861 ". Validated chain: " + HashesToBase64String(hashes) +
862 ", matches one or more bad hashes: " + 862 ", matches one or more bad hashes: " +
863 HashesToBase64String(bad_static_spki_hashes); 863 HashesToBase64String(bad_static_spki_hashes);
864 return false; 864 return false;
865 } 865 }
(...skipping 16 matching lines...) Expand all
882 882
883 bool TransportSecurityState::DomainState::ShouldUpgradeToSSL() const { 883 bool TransportSecurityState::DomainState::ShouldUpgradeToSSL() const {
884 return upgrade_mode == MODE_FORCE_HTTPS; 884 return upgrade_mode == MODE_FORCE_HTTPS;
885 } 885 }
886 886
887 bool TransportSecurityState::DomainState::ShouldSSLErrorsBeFatal() const { 887 bool TransportSecurityState::DomainState::ShouldSSLErrorsBeFatal() const {
888 return true; 888 return true;
889 } 889 }
890 890
891 bool TransportSecurityState::DomainState::HasPublicKeyPins() const { 891 bool TransportSecurityState::DomainState::HasPublicKeyPins() const {
892 return static_spki_hashes.size() > 0 || 892 return static_spki_hashes.size() > 0 || bad_static_spki_hashes.size() > 0 ||
893 bad_static_spki_hashes.size() > 0 ||
894 dynamic_spki_hashes.size() > 0; 893 dynamic_spki_hashes.size() > 0;
895 } 894 }
896 895
897 } // namespace 896 } // namespace
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698