| 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 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 DCHECK(CalledOnValidThread()); |
| 88 } | 89 } |
| 89 | 90 |
| 90 TransportSecurityState::Iterator::Iterator(const TransportSecurityState& state) | 91 TransportSecurityState::Iterator::Iterator(const TransportSecurityState& state) |
| 91 : iterator_(state.enabled_hosts_.begin()), | 92 : iterator_(state.enabled_hosts_.begin()), |
| 92 end_(state.enabled_hosts_.end()) { | 93 end_(state.enabled_hosts_.end()) { |
| 93 } | 94 } |
| 94 | 95 |
| 95 TransportSecurityState::Iterator::~Iterator() {} | 96 TransportSecurityState::Iterator::~Iterator() {} |
| 96 | 97 |
| 97 void TransportSecurityState::SetDelegate( | 98 void TransportSecurityState::SetDelegate( |
| 98 TransportSecurityState::Delegate* delegate) { | 99 TransportSecurityState::Delegate* delegate) { |
| 100 DCHECK(CalledOnValidThread()); |
| 99 delegate_ = delegate; | 101 delegate_ = delegate; |
| 100 } | 102 } |
| 101 | 103 |
| 102 void TransportSecurityState::EnableHost(const std::string& host, | 104 void TransportSecurityState::EnableHost(const std::string& host, |
| 103 const DomainState& state) { | 105 const DomainState& state) { |
| 104 DCHECK(CalledOnValidThread()); | 106 DCHECK(CalledOnValidThread()); |
| 105 | 107 |
| 106 const std::string canonicalized_host = CanonicalizeHost(host); | 108 const std::string canonicalized_host = CanonicalizeHost(host); |
| 107 if (canonicalized_host.empty()) | 109 if (canonicalized_host.empty()) |
| 108 return; | 110 return; |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 190 return true; | 192 return true; |
| 191 } | 193 } |
| 192 | 194 |
| 193 return false; | 195 return false; |
| 194 } | 196 } |
| 195 | 197 |
| 196 return false; | 198 return false; |
| 197 } | 199 } |
| 198 | 200 |
| 199 void TransportSecurityState::ClearDynamicData() { | 201 void TransportSecurityState::ClearDynamicData() { |
| 202 DCHECK(CalledOnValidThread()); |
| 200 enabled_hosts_.clear(); | 203 enabled_hosts_.clear(); |
| 201 } | 204 } |
| 202 | 205 |
| 203 void TransportSecurityState::DeleteAllDynamicDataSince(const base::Time& time) { | 206 void TransportSecurityState::DeleteAllDynamicDataSince(const base::Time& time) { |
| 204 DCHECK(CalledOnValidThread()); | 207 DCHECK(CalledOnValidThread()); |
| 205 | 208 |
| 206 bool dirtied = false; | 209 bool dirtied = false; |
| 207 | 210 |
| 208 DomainStateMap::iterator i = enabled_hosts_.begin(); | 211 DomainStateMap::iterator i = enabled_hosts_.begin(); |
| 209 while (i != enabled_hosts_.end()) { | 212 while (i != enabled_hosts_.end()) { |
| 210 if (i->second.created >= time) { | 213 if (i->second.created >= time) { |
| 211 dirtied = true; | 214 dirtied = true; |
| 212 enabled_hosts_.erase(i++); | 215 enabled_hosts_.erase(i++); |
| 213 } else { | 216 } else { |
| 214 i++; | 217 i++; |
| 215 } | 218 } |
| 216 } | 219 } |
| 217 | 220 |
| 218 if (dirtied) | 221 if (dirtied) |
| 219 DirtyNotify(); | 222 DirtyNotify(); |
| 220 } | 223 } |
| 221 | 224 |
| 222 TransportSecurityState::~TransportSecurityState() {} | 225 TransportSecurityState::~TransportSecurityState() { |
| 226 DCHECK(CalledOnValidThread()); |
| 227 } |
| 223 | 228 |
| 224 void TransportSecurityState::DirtyNotify() { | 229 void TransportSecurityState::DirtyNotify() { |
| 225 DCHECK(CalledOnValidThread()); | 230 DCHECK(CalledOnValidThread()); |
| 226 | 231 |
| 227 if (delegate_) | 232 if (delegate_) |
| 228 delegate_->StateIsDirty(this); | 233 delegate_->StateIsDirty(this); |
| 229 } | 234 } |
| 230 | 235 |
| 231 // static | 236 // static |
| 232 std::string TransportSecurityState::CanonicalizeHost(const std::string& host) { | 237 std::string TransportSecurityState::CanonicalizeHost(const std::string& host) { |
| (...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 606 return entry; | 611 return entry; |
| 607 } | 612 } |
| 608 } | 613 } |
| 609 } | 614 } |
| 610 | 615 |
| 611 return NULL; | 616 return NULL; |
| 612 } | 617 } |
| 613 | 618 |
| 614 bool TransportSecurityState::AddHSTSHeader(const std::string& host, | 619 bool TransportSecurityState::AddHSTSHeader(const std::string& host, |
| 615 const std::string& value) { | 620 const std::string& value) { |
| 621 DCHECK(CalledOnValidThread()); |
| 622 |
| 616 base::Time now = base::Time::Now(); | 623 base::Time now = base::Time::Now(); |
| 617 base::TimeDelta max_age; | 624 base::TimeDelta max_age; |
| 618 TransportSecurityState::DomainState domain_state; | 625 TransportSecurityState::DomainState domain_state; |
| 619 if (ParseHSTSHeader(value, &max_age, &domain_state.include_subdomains)) { | 626 if (ParseHSTSHeader(value, &max_age, &domain_state.include_subdomains)) { |
| 620 // Handle max-age == 0 | 627 // Handle max-age == 0 |
| 621 if (max_age.InSeconds() == 0) | 628 if (max_age.InSeconds() == 0) |
| 622 domain_state.upgrade_mode = DomainState::MODE_DEFAULT; | 629 domain_state.upgrade_mode = DomainState::MODE_DEFAULT; |
| 623 else | 630 else |
| 624 domain_state.upgrade_mode = DomainState::MODE_FORCE_HTTPS; | 631 domain_state.upgrade_mode = DomainState::MODE_FORCE_HTTPS; |
| 625 domain_state.created = now; | 632 domain_state.created = now; |
| 626 domain_state.upgrade_expiry = now + max_age; | 633 domain_state.upgrade_expiry = now + max_age; |
| 627 EnableHost(host, domain_state); | 634 EnableHost(host, domain_state); |
| 628 return true; | 635 return true; |
| 629 } | 636 } |
| 630 return false; | 637 return false; |
| 631 } | 638 } |
| 632 | 639 |
| 633 bool TransportSecurityState::AddHPKPHeader(const std::string& host, | 640 bool TransportSecurityState::AddHPKPHeader(const std::string& host, |
| 634 const std::string& value, | 641 const std::string& value, |
| 635 const SSLInfo& ssl_info) { | 642 const SSLInfo& ssl_info) { |
| 643 DCHECK(CalledOnValidThread()); |
| 644 |
| 636 base::Time now = base::Time::Now(); | 645 base::Time now = base::Time::Now(); |
| 637 base::TimeDelta max_age; | 646 base::TimeDelta max_age; |
| 638 TransportSecurityState::DomainState domain_state; | 647 TransportSecurityState::DomainState domain_state; |
| 639 if (ParseHPKPHeader(value, ssl_info.public_key_hashes, | 648 if (ParseHPKPHeader(value, ssl_info.public_key_hashes, |
| 640 &max_age, &domain_state.dynamic_spki_hashes)) { | 649 &max_age, &domain_state.dynamic_spki_hashes)) { |
| 641 // TODO(palmer): http://crbug.com/243865 handle max-age == 0 | 650 // TODO(palmer): http://crbug.com/243865 handle max-age == 0 |
| 642 // and includeSubdomains. | 651 // and includeSubdomains. |
| 643 domain_state.created = now; | 652 domain_state.created = now; |
| 644 domain_state.dynamic_spki_hashes_expiry = now + max_age; | 653 domain_state.dynamic_spki_hashes_expiry = now + max_age; |
| 645 EnableHost(host, domain_state); | 654 EnableHost(host, domain_state); |
| 646 return true; | 655 return true; |
| 647 } | 656 } |
| 648 return false; | 657 return false; |
| 649 } | 658 } |
| 650 | 659 |
| 651 bool TransportSecurityState::AddHSTS(const std::string& host, | 660 bool TransportSecurityState::AddHSTS(const std::string& host, |
| 652 const base::Time& expiry, | 661 const base::Time& expiry, |
| 653 bool include_subdomains) { | 662 bool include_subdomains) { |
| 663 DCHECK(CalledOnValidThread()); |
| 664 |
| 654 // Copy-and-modify the existing DomainState for this host (if any). | 665 // Copy-and-modify the existing DomainState for this host (if any). |
| 655 TransportSecurityState::DomainState domain_state; | 666 TransportSecurityState::DomainState domain_state; |
| 656 const std::string canonicalized_host = CanonicalizeHost(host); | 667 const std::string canonicalized_host = CanonicalizeHost(host); |
| 657 const std::string hashed_host = HashHost(canonicalized_host); | 668 const std::string hashed_host = HashHost(canonicalized_host); |
| 658 DomainStateMap::const_iterator i = enabled_hosts_.find( | 669 DomainStateMap::const_iterator i = enabled_hosts_.find( |
| 659 hashed_host); | 670 hashed_host); |
| 660 if (i != enabled_hosts_.end()) | 671 if (i != enabled_hosts_.end()) |
| 661 domain_state = i->second; | 672 domain_state = i->second; |
| 662 | 673 |
| 663 domain_state.created = base::Time::Now(); | 674 domain_state.created = base::Time::Now(); |
| 664 domain_state.include_subdomains = include_subdomains; | 675 domain_state.include_subdomains = include_subdomains; |
| 665 domain_state.upgrade_expiry = expiry; | 676 domain_state.upgrade_expiry = expiry; |
| 666 domain_state.upgrade_mode = DomainState::MODE_FORCE_HTTPS; | 677 domain_state.upgrade_mode = DomainState::MODE_FORCE_HTTPS; |
| 667 EnableHost(host, domain_state); | 678 EnableHost(host, domain_state); |
| 668 return true; | 679 return true; |
| 669 } | 680 } |
| 670 | 681 |
| 671 bool TransportSecurityState::AddHPKP(const std::string& host, | 682 bool TransportSecurityState::AddHPKP(const std::string& host, |
| 672 const base::Time& expiry, | 683 const base::Time& expiry, |
| 673 bool include_subdomains, | 684 bool include_subdomains, |
| 674 const HashValueVector& hashes) { | 685 const HashValueVector& hashes) { |
| 686 DCHECK(CalledOnValidThread()); |
| 687 |
| 675 // Copy-and-modify the existing DomainState for this host (if any). | 688 // Copy-and-modify the existing DomainState for this host (if any). |
| 676 TransportSecurityState::DomainState domain_state; | 689 TransportSecurityState::DomainState domain_state; |
| 677 const std::string canonicalized_host = CanonicalizeHost(host); | 690 const std::string canonicalized_host = CanonicalizeHost(host); |
| 678 const std::string hashed_host = HashHost(canonicalized_host); | 691 const std::string hashed_host = HashHost(canonicalized_host); |
| 679 DomainStateMap::const_iterator i = enabled_hosts_.find( | 692 DomainStateMap::const_iterator i = enabled_hosts_.find( |
| 680 hashed_host); | 693 hashed_host); |
| 681 if (i != enabled_hosts_.end()) | 694 if (i != enabled_hosts_.end()) |
| 682 domain_state = i->second; | 695 domain_state = i->second; |
| 683 | 696 |
| 684 domain_state.created = base::Time::Now(); | 697 domain_state.created = base::Time::Now(); |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 768 out, &ret)) { | 781 out, &ret)) { |
| 769 return ret; | 782 return ret; |
| 770 } | 783 } |
| 771 } | 784 } |
| 772 | 785 |
| 773 return false; | 786 return false; |
| 774 } | 787 } |
| 775 | 788 |
| 776 void TransportSecurityState::AddOrUpdateEnabledHosts( | 789 void TransportSecurityState::AddOrUpdateEnabledHosts( |
| 777 const std::string& hashed_host, const DomainState& state) { | 790 const std::string& hashed_host, const DomainState& state) { |
| 791 DCHECK(CalledOnValidThread()); |
| 778 enabled_hosts_[hashed_host] = state; | 792 enabled_hosts_[hashed_host] = state; |
| 779 } | 793 } |
| 780 | 794 |
| 781 TransportSecurityState::DomainState::DomainState() | 795 TransportSecurityState::DomainState::DomainState() |
| 782 : upgrade_mode(MODE_FORCE_HTTPS), | 796 : upgrade_mode(MODE_FORCE_HTTPS), |
| 783 created(base::Time::Now()), | 797 created(base::Time::Now()), |
| 784 include_subdomains(false) { | 798 include_subdomains(false) { |
| 785 } | 799 } |
| 786 | 800 |
| 787 TransportSecurityState::DomainState::~DomainState() { | 801 TransportSecurityState::DomainState::~DomainState() { |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 830 return true; | 844 return true; |
| 831 } | 845 } |
| 832 | 846 |
| 833 bool TransportSecurityState::DomainState::HasPublicKeyPins() const { | 847 bool TransportSecurityState::DomainState::HasPublicKeyPins() const { |
| 834 return static_spki_hashes.size() > 0 || | 848 return static_spki_hashes.size() > 0 || |
| 835 bad_static_spki_hashes.size() > 0 || | 849 bad_static_spki_hashes.size() > 0 || |
| 836 dynamic_spki_hashes.size() > 0; | 850 dynamic_spki_hashes.size() > 0; |
| 837 } | 851 } |
| 838 | 852 |
| 839 } // namespace | 853 } // namespace |
| OLD | NEW |