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 |