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

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

Issue 2747173005: Store dynamic Expect-CT state (Closed)
Patch Set: fix rebase mishap Created 3 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
« no previous file with comments | « net/http/transport_security_state.h ('k') | net/http/transport_security_state_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 #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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « net/http/transport_security_state.h ('k') | net/http/transport_security_state_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698