Chromium Code Reviews| 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 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <memory> | 8 #include <memory> |
| 9 #include <utility> | 9 #include <utility> |
| 10 #include <vector> | 10 #include <vector> |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 49 | 49 |
| 50 // Points to the active transport security state source. | 50 // Points to the active transport security state source. |
| 51 const TransportSecurityStateSource* g_hsts_source = &kHSTSSource; | 51 const TransportSecurityStateSource* g_hsts_source = &kHSTSSource; |
| 52 | 52 |
| 53 // Override for ShouldRequireCT() for unit tests. Possible values: | 53 // Override for ShouldRequireCT() for unit tests. Possible values: |
| 54 // -1: Unless a delegate says otherwise, do not require CT. | 54 // -1: Unless a delegate says otherwise, do not require CT. |
| 55 // 0: Use the default implementation (e.g. production) | 55 // 0: Use the default implementation (e.g. production) |
| 56 // 1: Unless a delegate says otherwise, require CT. | 56 // 1: Unless a delegate says otherwise, require CT. |
| 57 int g_ct_required_for_testing = 0; | 57 int g_ct_required_for_testing = 0; |
| 58 | 58 |
| 59 bool IsDynamicExpectCTEnabled() { | |
| 60 return base::FeatureList::IsEnabled( | |
| 61 TransportSecurityState::kDynamicExpectCTFeature); | |
| 62 } | |
| 63 | |
| 59 // LessThan comparator for use with std::binary_search() in determining | 64 // LessThan comparator for use with std::binary_search() in determining |
| 60 // whether a SHA-256 HashValue appears within a sorted array of | 65 // whether a SHA-256 HashValue appears within a sorted array of |
| 61 // SHA256HashValues. | 66 // SHA256HashValues. |
| 62 struct SHA256ToHashValueComparator { | 67 struct SHA256ToHashValueComparator { |
| 63 bool operator()(const SHA256HashValue& lhs, const HashValue& rhs) const { | 68 bool operator()(const SHA256HashValue& lhs, const HashValue& rhs) const { |
| 64 DCHECK_EQ(HASH_VALUE_SHA256, rhs.tag); | 69 DCHECK_EQ(HASH_VALUE_SHA256, rhs.tag); |
| 65 return memcmp(lhs.data, rhs.data(), rhs.size()) < 0; | 70 return memcmp(lhs.data, rhs.data(), rhs.size()) < 0; |
| 66 } | 71 } |
| 67 | 72 |
| 68 bool operator()(const HashValue& lhs, const SHA256HashValue& rhs) const { | 73 bool operator()(const HashValue& lhs, const SHA256HashValue& rhs) const { |
| (...skipping 650 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 719 report.Set("validated-certificate-chain", | 724 report.Set("validated-certificate-chain", |
| 720 GetPEMEncodedChainAsList(ssl_info.cert.get())); | 725 GetPEMEncodedChainAsList(ssl_info.cert.get())); |
| 721 | 726 |
| 722 if (!base::JSONWriter::Write(report, out_serialized_report)) | 727 if (!base::JSONWriter::Write(report, out_serialized_report)) |
| 723 return false; | 728 return false; |
| 724 return true; | 729 return true; |
| 725 } | 730 } |
| 726 | 731 |
| 727 } // namespace | 732 } // namespace |
| 728 | 733 |
| 734 // static | |
| 735 const base::Feature TransportSecurityState::kDynamicExpectCTFeature{ | |
| 736 "DynamicExpectCT", base::FEATURE_DISABLED_BY_DEFAULT}; | |
| 737 | |
| 729 void SetTransportSecurityStateSourceForTesting( | 738 void SetTransportSecurityStateSourceForTesting( |
| 730 const TransportSecurityStateSource* source) { | 739 const TransportSecurityStateSource* source) { |
| 731 g_hsts_source = source ? source : &kHSTSSource; | 740 g_hsts_source = source ? source : &kHSTSSource; |
| 732 } | 741 } |
| 733 | 742 |
| 734 TransportSecurityState::TransportSecurityState() | 743 TransportSecurityState::TransportSecurityState() |
| 735 : enable_static_pins_(true), | 744 : enable_static_pins_(true), |
| 736 enable_static_expect_ct_(true), | 745 enable_static_expect_ct_(true), |
| 737 enable_static_expect_staple_(true), | 746 enable_static_expect_staple_(true), |
| 738 enable_pkp_bypass_for_local_trust_anchors_(true), | 747 enable_pkp_bypass_for_local_trust_anchors_(true), |
| (...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 981 PKPState pkp_state; | 990 PKPState pkp_state; |
| 982 pkp_state.last_observed = last_observed; | 991 pkp_state.last_observed = last_observed; |
| 983 pkp_state.expiry = expiry; | 992 pkp_state.expiry = expiry; |
| 984 pkp_state.include_subdomains = include_subdomains; | 993 pkp_state.include_subdomains = include_subdomains; |
| 985 pkp_state.spki_hashes = hashes; | 994 pkp_state.spki_hashes = hashes; |
| 986 pkp_state.report_uri = report_uri; | 995 pkp_state.report_uri = report_uri; |
| 987 | 996 |
| 988 EnablePKPHost(host, pkp_state); | 997 EnablePKPHost(host, pkp_state); |
| 989 } | 998 } |
| 990 | 999 |
| 1000 void TransportSecurityState::AddExpectCTInternal( | |
| 1001 const std::string& host, | |
| 1002 const base::Time& last_observed, | |
| 1003 const base::Time& expiry, | |
| 1004 bool enforce, | |
| 1005 const GURL& report_uri) { | |
| 1006 DCHECK(CalledOnValidThread()); | |
| 1007 | |
| 1008 ExpectCTState expect_ct_state; | |
| 1009 expect_ct_state.last_observed = last_observed; | |
| 1010 expect_ct_state.expiry = expiry; | |
| 1011 expect_ct_state.enforce = enforce; | |
| 1012 expect_ct_state.report_uri = report_uri; | |
| 1013 | |
| 1014 EnableExpectCTHost(host, expect_ct_state); | |
| 1015 } | |
| 1016 | |
| 991 void TransportSecurityState:: | 1017 void TransportSecurityState:: |
| 992 SetEnablePublicKeyPinningBypassForLocalTrustAnchors(bool value) { | 1018 SetEnablePublicKeyPinningBypassForLocalTrustAnchors(bool value) { |
| 993 enable_pkp_bypass_for_local_trust_anchors_ = value; | 1019 enable_pkp_bypass_for_local_trust_anchors_ = value; |
| 994 } | 1020 } |
| 995 | 1021 |
| 996 void TransportSecurityState::EnableSTSHost(const std::string& host, | 1022 void TransportSecurityState::EnableSTSHost(const std::string& host, |
| 997 const STSState& state) { | 1023 const STSState& state) { |
| 998 DCHECK(CalledOnValidThread()); | 1024 DCHECK(CalledOnValidThread()); |
| 999 | 1025 |
| 1000 const std::string canonicalized_host = CanonicalizeHost(host); | 1026 const std::string canonicalized_host = CanonicalizeHost(host); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1036 | 1062 |
| 1037 enabled_pkp_hosts_[HashHost(canonicalized_host)] = pkp_state; | 1063 enabled_pkp_hosts_[HashHost(canonicalized_host)] = pkp_state; |
| 1038 } else { | 1064 } else { |
| 1039 const std::string hashed_host = HashHost(canonicalized_host); | 1065 const std::string hashed_host = HashHost(canonicalized_host); |
| 1040 enabled_pkp_hosts_.erase(hashed_host); | 1066 enabled_pkp_hosts_.erase(hashed_host); |
| 1041 } | 1067 } |
| 1042 | 1068 |
| 1043 DirtyNotify(); | 1069 DirtyNotify(); |
| 1044 } | 1070 } |
| 1045 | 1071 |
| 1072 void TransportSecurityState::EnableExpectCTHost(const std::string& host, | |
| 1073 const ExpectCTState& state) { | |
| 1074 DCHECK(CalledOnValidThread()); | |
| 1075 if (!IsDynamicExpectCTEnabled()) | |
| 1076 return; | |
| 1077 | |
| 1078 const std::string canonicalized_host = CanonicalizeHost(host); | |
| 1079 if (canonicalized_host.empty()) | |
| 1080 return; | |
| 1081 | |
| 1082 // Only store new state when Expect-CT is explicitly enabled. If it is | |
| 1083 // disabled, remove the state from the enabled hosts. | |
| 1084 if (state.enforce || !state.report_uri.is_empty()) { | |
| 1085 ExpectCTState expect_ct_state(state); | |
| 1086 // No need to store this value since it is redundant. (|canonicalized_host| | |
| 1087 // is the map key.) | |
| 1088 expect_ct_state.domain.clear(); | |
| 1089 | |
| 1090 enabled_expect_ct_hosts_[HashHost(canonicalized_host)] = expect_ct_state; | |
| 1091 } else { | |
| 1092 const std::string hashed_host = HashHost(canonicalized_host); | |
| 1093 enabled_expect_ct_hosts_.erase(hashed_host); | |
| 1094 } | |
| 1095 | |
| 1096 DirtyNotify(); | |
| 1097 } | |
| 1098 | |
| 1046 TransportSecurityState::PKPStatus | 1099 TransportSecurityState::PKPStatus |
| 1047 TransportSecurityState::CheckPinsAndMaybeSendReport( | 1100 TransportSecurityState::CheckPinsAndMaybeSendReport( |
| 1048 const HostPortPair& host_port_pair, | 1101 const HostPortPair& host_port_pair, |
| 1049 bool is_issued_by_known_root, | 1102 bool is_issued_by_known_root, |
| 1050 const TransportSecurityState::PKPState& pkp_state, | 1103 const TransportSecurityState::PKPState& pkp_state, |
| 1051 const HashValueVector& hashes, | 1104 const HashValueVector& hashes, |
| 1052 const X509Certificate* served_certificate_chain, | 1105 const X509Certificate* served_certificate_chain, |
| 1053 const X509Certificate* validated_certificate_chain, | 1106 const X509Certificate* validated_certificate_chain, |
| 1054 const TransportSecurityState::PublicKeyPinReportStatus report_status, | 1107 const TransportSecurityState::PublicKeyPinReportStatus report_status, |
| 1055 std::string* failure_log) { | 1108 std::string* failure_log) { |
| (...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1272 void TransportSecurityState::AddHPKP(const std::string& host, | 1325 void TransportSecurityState::AddHPKP(const std::string& host, |
| 1273 const base::Time& expiry, | 1326 const base::Time& expiry, |
| 1274 bool include_subdomains, | 1327 bool include_subdomains, |
| 1275 const HashValueVector& hashes, | 1328 const HashValueVector& hashes, |
| 1276 const GURL& report_uri) { | 1329 const GURL& report_uri) { |
| 1277 DCHECK(CalledOnValidThread()); | 1330 DCHECK(CalledOnValidThread()); |
| 1278 AddHPKPInternal(host, base::Time::Now(), expiry, include_subdomains, hashes, | 1331 AddHPKPInternal(host, base::Time::Now(), expiry, include_subdomains, hashes, |
| 1279 report_uri); | 1332 report_uri); |
| 1280 } | 1333 } |
| 1281 | 1334 |
| 1335 void TransportSecurityState::AddExpectCT(const std::string& host, | |
| 1336 const base::Time& expiry, | |
| 1337 bool enforce, | |
| 1338 const GURL& report_uri) { | |
| 1339 DCHECK(CalledOnValidThread()); | |
| 1340 AddExpectCTInternal(host, base::Time::Now(), expiry, enforce, report_uri); | |
| 1341 } | |
| 1342 | |
| 1282 bool TransportSecurityState::ProcessHPKPReportOnlyHeader( | 1343 bool TransportSecurityState::ProcessHPKPReportOnlyHeader( |
| 1283 const std::string& value, | 1344 const std::string& value, |
| 1284 const HostPortPair& host_port_pair, | 1345 const HostPortPair& host_port_pair, |
| 1285 const SSLInfo& ssl_info) { | 1346 const SSLInfo& ssl_info) { |
| 1286 DCHECK(CalledOnValidThread()); | 1347 DCHECK(CalledOnValidThread()); |
| 1287 | 1348 |
| 1288 base::Time now = base::Time::Now(); | 1349 base::Time now = base::Time::Now(); |
| 1289 bool include_subdomains; | 1350 bool include_subdomains; |
| 1290 HashValueVector spki_hashes; | 1351 HashValueVector spki_hashes; |
| 1291 GURL report_uri; | 1352 GURL report_uri; |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1564 return true; | 1625 return true; |
| 1565 } | 1626 } |
| 1566 | 1627 |
| 1567 break; | 1628 break; |
| 1568 } | 1629 } |
| 1569 } | 1630 } |
| 1570 | 1631 |
| 1571 return false; | 1632 return false; |
| 1572 } | 1633 } |
| 1573 | 1634 |
| 1635 bool TransportSecurityState::GetDynamicExpectCTState(const std::string& host, | |
| 1636 ExpectCTState* result) { | |
| 1637 DCHECK(CalledOnValidThread()); | |
| 1638 | |
| 1639 const std::string canonicalized_host = CanonicalizeHost(host); | |
| 1640 if (canonicalized_host.empty()) | |
| 1641 return false; | |
| 1642 | |
| 1643 base::Time current_time(base::Time::Now()); | |
| 1644 ExpectCTStateMap::iterator j = | |
| 1645 enabled_expect_ct_hosts_.find(HashHost(canonicalized_host)); | |
| 1646 if (j == enabled_expect_ct_hosts_.end()) | |
| 1647 return false; | |
| 1648 // If the entry is invalid, drop it. | |
| 1649 if (current_time > j->second.expiry) { | |
| 1650 enabled_expect_ct_hosts_.erase(j); | |
| 1651 DirtyNotify(); | |
| 1652 return false; | |
| 1653 } | |
| 1654 | |
| 1655 *result = j->second; | |
| 1656 return true; | |
| 1657 } | |
| 1658 | |
| 1574 void TransportSecurityState::AddOrUpdateEnabledSTSHosts( | 1659 void TransportSecurityState::AddOrUpdateEnabledSTSHosts( |
| 1575 const std::string& hashed_host, | 1660 const std::string& hashed_host, |
| 1576 const STSState& state) { | 1661 const STSState& state) { |
| 1577 DCHECK(CalledOnValidThread()); | 1662 DCHECK(CalledOnValidThread()); |
| 1578 DCHECK(state.ShouldUpgradeToSSL()); | 1663 DCHECK(state.ShouldUpgradeToSSL()); |
| 1579 enabled_sts_hosts_[hashed_host] = state; | 1664 enabled_sts_hosts_[hashed_host] = state; |
| 1580 } | 1665 } |
| 1581 | 1666 |
| 1582 void TransportSecurityState::AddOrUpdateEnabledPKPHosts( | 1667 void TransportSecurityState::AddOrUpdateEnabledPKPHosts( |
| 1583 const std::string& hashed_host, | 1668 const std::string& hashed_host, |
| 1584 const PKPState& state) { | 1669 const PKPState& state) { |
| 1585 DCHECK(CalledOnValidThread()); | 1670 DCHECK(CalledOnValidThread()); |
| 1586 DCHECK(state.HasPublicKeyPins()); | 1671 DCHECK(state.HasPublicKeyPins()); |
| 1587 enabled_pkp_hosts_[hashed_host] = state; | 1672 enabled_pkp_hosts_[hashed_host] = state; |
| 1588 } | 1673 } |
| 1589 | 1674 |
| 1675 void TransportSecurityState::AddOrUpdateEnabledExpectCTHosts( | |
| 1676 const std::string& hashed_host, | |
| 1677 const ExpectCTState& state) { | |
| 1678 DCHECK(CalledOnValidThread()); | |
| 1679 DCHECK(state.enforce || !state.report_uri.is_empty()); | |
| 1680 enabled_expect_ct_hosts_[hashed_host] = state; | |
| 1681 } | |
| 1682 | |
| 1590 TransportSecurityState::STSState::STSState() | 1683 TransportSecurityState::STSState::STSState() |
| 1591 : upgrade_mode(MODE_DEFAULT), include_subdomains(false) { | 1684 : upgrade_mode(MODE_DEFAULT), include_subdomains(false) { |
| 1592 } | 1685 } |
| 1593 | 1686 |
| 1594 TransportSecurityState::STSState::~STSState() { | 1687 TransportSecurityState::STSState::~STSState() { |
| 1595 } | 1688 } |
| 1596 | 1689 |
| 1597 bool TransportSecurityState::STSState::ShouldUpgradeToSSL() const { | 1690 bool TransportSecurityState::STSState::ShouldUpgradeToSSL() const { |
| 1598 return upgrade_mode == MODE_FORCE_HTTPS; | 1691 return upgrade_mode == MODE_FORCE_HTTPS; |
| 1599 } | 1692 } |
| 1600 | 1693 |
| 1601 TransportSecurityState::STSStateIterator::STSStateIterator( | 1694 TransportSecurityState::STSStateIterator::STSStateIterator( |
| 1602 const TransportSecurityState& state) | 1695 const TransportSecurityState& state) |
| 1603 : iterator_(state.enabled_sts_hosts_.begin()), | 1696 : iterator_(state.enabled_sts_hosts_.begin()), |
| 1604 end_(state.enabled_sts_hosts_.end()) { | 1697 end_(state.enabled_sts_hosts_.end()) { |
| 1605 } | 1698 } |
| 1606 | 1699 |
| 1607 TransportSecurityState::STSStateIterator::~STSStateIterator() { | 1700 TransportSecurityState::STSStateIterator::~STSStateIterator() { |
| 1608 } | 1701 } |
| 1609 | 1702 |
| 1610 TransportSecurityState::PKPState::PKPState() : include_subdomains(false) { | 1703 TransportSecurityState::PKPState::PKPState() : include_subdomains(false) { |
| 1611 } | 1704 } |
| 1612 | 1705 |
| 1613 TransportSecurityState::PKPState::PKPState(const PKPState& other) = default; | 1706 TransportSecurityState::PKPState::PKPState(const PKPState& other) = default; |
| 1614 | 1707 |
| 1615 TransportSecurityState::PKPState::~PKPState() { | 1708 TransportSecurityState::PKPState::~PKPState() { |
| 1616 } | 1709 } |
| 1617 | 1710 |
| 1618 TransportSecurityState::ExpectCTState::ExpectCTState() {} | 1711 TransportSecurityState::ExpectCTState::ExpectCTState() : enforce(false) {} |
| 1619 | 1712 |
| 1620 TransportSecurityState::ExpectCTState::~ExpectCTState() {} | 1713 TransportSecurityState::ExpectCTState::~ExpectCTState() {} |
| 1621 | 1714 |
| 1715 TransportSecurityState::ExpectCTStateIterator::ExpectCTStateIterator( | |
| 1716 const TransportSecurityState& state) | |
| 1717 : iterator_(state.enabled_expect_ct_hosts_.begin()), | |
| 1718 end_(state.enabled_expect_ct_hosts_.end()) {} | |
|
mattm
2017/04/15 04:50:17
Can you check state.CalledOnValidThread() here to
estark
2017/04/15 19:16:08
Done.
| |
| 1719 | |
| 1720 TransportSecurityState::ExpectCTStateIterator::~ExpectCTStateIterator() {} | |
| 1721 | |
| 1622 TransportSecurityState::ExpectStapleState::ExpectStapleState() | 1722 TransportSecurityState::ExpectStapleState::ExpectStapleState() |
| 1623 : include_subdomains(false) {} | 1723 : include_subdomains(false) {} |
| 1624 | 1724 |
| 1625 TransportSecurityState::ExpectStapleState::~ExpectStapleState() {} | 1725 TransportSecurityState::ExpectStapleState::~ExpectStapleState() {} |
| 1626 | 1726 |
| 1627 bool TransportSecurityState::PKPState::CheckPublicKeyPins( | 1727 bool TransportSecurityState::PKPState::CheckPublicKeyPins( |
| 1628 const HashValueVector& hashes, | 1728 const HashValueVector& hashes, |
| 1629 std::string* failure_log) const { | 1729 std::string* failure_log) const { |
| 1630 // Validate that hashes is not empty. By the time this code is called (in | 1730 // Validate that hashes is not empty. By the time this code is called (in |
| 1631 // production), that should never happen, but it's good to be defensive. | 1731 // production), that should never happen, but it's good to be defensive. |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1666 TransportSecurityState::PKPStateIterator::PKPStateIterator( | 1766 TransportSecurityState::PKPStateIterator::PKPStateIterator( |
| 1667 const TransportSecurityState& state) | 1767 const TransportSecurityState& state) |
| 1668 : iterator_(state.enabled_pkp_hosts_.begin()), | 1768 : iterator_(state.enabled_pkp_hosts_.begin()), |
| 1669 end_(state.enabled_pkp_hosts_.end()) { | 1769 end_(state.enabled_pkp_hosts_.end()) { |
| 1670 } | 1770 } |
| 1671 | 1771 |
| 1672 TransportSecurityState::PKPStateIterator::~PKPStateIterator() { | 1772 TransportSecurityState::PKPStateIterator::~PKPStateIterator() { |
| 1673 } | 1773 } |
| 1674 | 1774 |
| 1675 } // namespace | 1775 } // namespace |
| OLD | NEW |