| 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 25 matching lines...) Expand all Loading... |
| 36 #include "base/metrics/field_trial.h" | 36 #include "base/metrics/field_trial.h" |
| 37 #endif | 37 #endif |
| 38 | 38 |
| 39 namespace net { | 39 namespace net { |
| 40 | 40 |
| 41 namespace { | 41 namespace { |
| 42 | 42 |
| 43 #include "net/http/transport_security_state_ct_policies.inc" | 43 #include "net/http/transport_security_state_ct_policies.inc" |
| 44 #include "net/http/transport_security_state_static.h" | 44 #include "net/http/transport_security_state_static.h" |
| 45 | 45 |
| 46 const size_t kMaxHPKPReportCacheEntries = 50; | 46 // Parameters for remembering sent HPKP and Expect-CT reports. |
| 47 const int kTimeToRememberHPKPReportsMins = 60; | 47 const size_t kMaxReportCacheEntries = 50; |
| 48 const int kTimeToRememberReportsMins = 60; |
| 48 const size_t kReportCacheKeyLength = 16; | 49 const size_t kReportCacheKeyLength = 16; |
| 49 | 50 |
| 50 // Points to the active transport security state source. | 51 // Points to the active transport security state source. |
| 51 const TransportSecurityStateSource* g_hsts_source = &kHSTSSource; | 52 const TransportSecurityStateSource* g_hsts_source = &kHSTSSource; |
| 52 | 53 |
| 53 // Override for CheckCTRequirements() for unit tests. Possible values: | 54 // Override for CheckCTRequirements() for unit tests. Possible values: |
| 54 // -1: Unless a delegate says otherwise, do not require CT. | 55 // -1: Unless a delegate says otherwise, do not require CT. |
| 55 // 0: Use the default implementation (e.g. production) | 56 // 0: Use the default implementation (e.g. production) |
| 56 // 1: Unless a delegate says otherwise, require CT. | 57 // 1: Unless a delegate says otherwise, require CT. |
| 57 int g_ct_required_for_testing = 0; | 58 int g_ct_required_for_testing = 0; |
| (...skipping 677 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 735 void SetTransportSecurityStateSourceForTesting( | 736 void SetTransportSecurityStateSourceForTesting( |
| 736 const TransportSecurityStateSource* source) { | 737 const TransportSecurityStateSource* source) { |
| 737 g_hsts_source = source ? source : &kHSTSSource; | 738 g_hsts_source = source ? source : &kHSTSSource; |
| 738 } | 739 } |
| 739 | 740 |
| 740 TransportSecurityState::TransportSecurityState() | 741 TransportSecurityState::TransportSecurityState() |
| 741 : enable_static_pins_(true), | 742 : enable_static_pins_(true), |
| 742 enable_static_expect_ct_(true), | 743 enable_static_expect_ct_(true), |
| 743 enable_static_expect_staple_(true), | 744 enable_static_expect_staple_(true), |
| 744 enable_pkp_bypass_for_local_trust_anchors_(true), | 745 enable_pkp_bypass_for_local_trust_anchors_(true), |
| 745 sent_reports_cache_(kMaxHPKPReportCacheEntries) { | 746 sent_hpkp_reports_cache_(kMaxReportCacheEntries), |
| 747 sent_expect_ct_reports_cache_(kMaxReportCacheEntries) { |
| 746 // Static pinning is only enabled for official builds to make sure that | 748 // Static pinning is only enabled for official builds to make sure that |
| 747 // others don't end up with pins that cannot be easily updated. | 749 // others don't end up with pins that cannot be easily updated. |
| 748 #if !defined(GOOGLE_CHROME_BUILD) || defined(OS_ANDROID) || defined(OS_IOS) | 750 #if !defined(GOOGLE_CHROME_BUILD) || defined(OS_ANDROID) || defined(OS_IOS) |
| 749 enable_static_pins_ = false; | 751 enable_static_pins_ = false; |
| 750 enable_static_expect_ct_ = false; | 752 enable_static_expect_ct_ = false; |
| 751 #endif | 753 #endif |
| 752 DCHECK(CalledOnValidThread()); | 754 DCHECK(CalledOnValidThread()); |
| 753 } | 755 } |
| 754 | 756 |
| 755 // Both HSTS and HPKP cause fatal SSL errors, so return true if a | 757 // Both HSTS and HPKP cause fatal SSL errors, so return true if a |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 883 return CT_REQUIREMENTS_MET; | 885 return CT_REQUIREMENTS_MET; |
| 884 } | 886 } |
| 885 | 887 |
| 886 // Check Expect-CT first so that other CT requirements do not prevent | 888 // Check Expect-CT first so that other CT requirements do not prevent |
| 887 // Expect-CT reports from being sent. | 889 // Expect-CT reports from being sent. |
| 888 ExpectCTState state; | 890 ExpectCTState state; |
| 889 if (is_issued_by_known_root && IsDynamicExpectCTEnabled() && | 891 if (is_issued_by_known_root && IsDynamicExpectCTEnabled() && |
| 890 GetDynamicExpectCTState(hostname, &state)) { | 892 GetDynamicExpectCTState(hostname, &state)) { |
| 891 if (expect_ct_reporter_ && !state.report_uri.is_empty() && | 893 if (expect_ct_reporter_ && !state.report_uri.is_empty() && |
| 892 report_status == ENABLE_EXPECT_CT_REPORTS) { | 894 report_status == ENABLE_EXPECT_CT_REPORTS) { |
| 893 expect_ct_reporter_->OnExpectCTFailed( | 895 MaybeNotifyExpectCTFailed( |
| 894 host_port_pair, state.report_uri, validated_certificate_chain, | 896 host_port_pair, state.report_uri, validated_certificate_chain, |
| 895 served_certificate_chain, signed_certificate_timestamps); | 897 served_certificate_chain, signed_certificate_timestamps); |
| 896 } | 898 } |
| 897 if (state.enforce) | 899 if (state.enforce) |
| 898 return CT_REQUIREMENTS_NOT_MET; | 900 return CT_REQUIREMENTS_NOT_MET; |
| 899 } | 901 } |
| 900 | 902 |
| 901 CTRequirementLevel ct_required = CTRequirementLevel::DEFAULT; | 903 CTRequirementLevel ct_required = CTRequirementLevel::DEFAULT; |
| 902 if (require_ct_delegate_) | 904 if (require_ct_delegate_) |
| 903 ct_required = require_ct_delegate_->IsCTRequiredForHost(hostname); | 905 ct_required = require_ct_delegate_->IsCTRequiredForHost(hostname); |
| (...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1160 std::string serialized_report; | 1162 std::string serialized_report; |
| 1161 std::string report_cache_key; | 1163 std::string report_cache_key; |
| 1162 if (!GetHPKPReport(host_port_pair, pkp_state, served_certificate_chain, | 1164 if (!GetHPKPReport(host_port_pair, pkp_state, served_certificate_chain, |
| 1163 validated_certificate_chain, &serialized_report, | 1165 validated_certificate_chain, &serialized_report, |
| 1164 &report_cache_key)) { | 1166 &report_cache_key)) { |
| 1165 return PKPStatus::VIOLATED; | 1167 return PKPStatus::VIOLATED; |
| 1166 } | 1168 } |
| 1167 | 1169 |
| 1168 // Limit the rate at which duplicate reports are sent to the same | 1170 // Limit the rate at which duplicate reports are sent to the same |
| 1169 // report URI. The same report will not be sent within | 1171 // report URI. The same report will not be sent within |
| 1170 // |kTimeToRememberHPKPReportsMins|, which reduces load on servers and | 1172 // |kTimeToRememberReportsMins|, which reduces load on servers and |
| 1171 // also prevents accidental loops (a.com triggers a report to b.com | 1173 // also prevents accidental loops (a.com triggers a report to b.com |
| 1172 // which triggers a report to a.com). See section 2.1.4 of RFC 7469. | 1174 // which triggers a report to a.com). See section 2.1.4 of RFC 7469. |
| 1173 if (sent_reports_cache_.Get(report_cache_key, base::TimeTicks::Now())) | 1175 if (sent_hpkp_reports_cache_.Get(report_cache_key, base::TimeTicks::Now())) |
| 1174 return PKPStatus::VIOLATED; | 1176 return PKPStatus::VIOLATED; |
| 1175 sent_reports_cache_.Put( | 1177 sent_hpkp_reports_cache_.Put( |
| 1176 report_cache_key, true, base::TimeTicks::Now(), | 1178 report_cache_key, true, base::TimeTicks::Now(), |
| 1177 base::TimeTicks::Now() + | 1179 base::TimeTicks::Now() + |
| 1178 base::TimeDelta::FromMinutes(kTimeToRememberHPKPReportsMins)); | 1180 base::TimeDelta::FromMinutes(kTimeToRememberReportsMins)); |
| 1179 | 1181 |
| 1180 report_sender_->Send(pkp_state.report_uri, "application/json; charset=utf-8", | 1182 report_sender_->Send(pkp_state.report_uri, "application/json; charset=utf-8", |
| 1181 serialized_report, base::Callback<void()>(), | 1183 serialized_report, base::Callback<void()>(), |
| 1182 base::Bind(RecordUMAForHPKPReportFailure)); | 1184 base::Bind(RecordUMAForHPKPReportFailure)); |
| 1183 return PKPStatus::VIOLATED; | 1185 return PKPStatus::VIOLATED; |
| 1184 } | 1186 } |
| 1185 | 1187 |
| 1186 bool TransportSecurityState::GetStaticExpectCTState( | 1188 bool TransportSecurityState::GetStaticExpectCTState( |
| 1187 const std::string& host, | 1189 const std::string& host, |
| 1188 ExpectCTState* expect_ct_state) const { | 1190 ExpectCTState* expect_ct_state) const { |
| 1189 DCHECK(CalledOnValidThread()); | 1191 DCHECK(CalledOnValidThread()); |
| 1190 | 1192 |
| 1191 if (!IsBuildTimely()) | 1193 if (!IsBuildTimely()) |
| 1192 return false; | 1194 return false; |
| 1193 | 1195 |
| 1194 PreloadResult result; | 1196 PreloadResult result; |
| 1195 if (!DecodeHSTSPreload(host, &result)) | 1197 if (!DecodeHSTSPreload(host, &result)) |
| 1196 return false; | 1198 return false; |
| 1197 | 1199 |
| 1198 if (!enable_static_expect_ct_ || !result.expect_ct) | 1200 if (!enable_static_expect_ct_ || !result.expect_ct) |
| 1199 return false; | 1201 return false; |
| 1200 | 1202 |
| 1201 expect_ct_state->domain = host.substr(result.hostname_offset); | 1203 expect_ct_state->domain = host.substr(result.hostname_offset); |
| 1202 expect_ct_state->report_uri = GURL( | 1204 expect_ct_state->report_uri = GURL( |
| 1203 g_hsts_source->expect_ct_report_uris[result.expect_ct_report_uri_id]); | 1205 g_hsts_source->expect_ct_report_uris[result.expect_ct_report_uri_id]); |
| 1204 return true; | 1206 return true; |
| 1205 } | 1207 } |
| 1206 | 1208 |
| 1209 void TransportSecurityState::MaybeNotifyExpectCTFailed( |
| 1210 const HostPortPair& host_port_pair, |
| 1211 const GURL& report_uri, |
| 1212 const X509Certificate* validated_certificate_chain, |
| 1213 const X509Certificate* served_certificate_chain, |
| 1214 const SignedCertificateTimestampAndStatusList& |
| 1215 signed_certificate_timestamps) { |
| 1216 // Do not send repeated reports to the same host/port pair within |
| 1217 // |kTimeToRememberReportsMins|. Theoretically, there could be scenarios in |
| 1218 // which the same host/port generates different reports and it would be useful |
| 1219 // to the server operator to receive those different reports, but such |
| 1220 // scenarios are not expected to arise very often in practice. |
| 1221 const std::string report_cache_key(host_port_pair.ToString()); |
| 1222 if (sent_expect_ct_reports_cache_.Get(report_cache_key, |
| 1223 base::TimeTicks::Now())) { |
| 1224 return; |
| 1225 } |
| 1226 sent_expect_ct_reports_cache_.Put( |
| 1227 report_cache_key, true, base::TimeTicks::Now(), |
| 1228 base::TimeTicks::Now() + |
| 1229 base::TimeDelta::FromMinutes(kTimeToRememberReportsMins)); |
| 1230 |
| 1231 expect_ct_reporter_->OnExpectCTFailed( |
| 1232 host_port_pair, report_uri, validated_certificate_chain, |
| 1233 served_certificate_chain, signed_certificate_timestamps); |
| 1234 } |
| 1235 |
| 1207 bool TransportSecurityState::GetStaticExpectStapleState( | 1236 bool TransportSecurityState::GetStaticExpectStapleState( |
| 1208 const std::string& host, | 1237 const std::string& host, |
| 1209 ExpectStapleState* expect_staple_state) const { | 1238 ExpectStapleState* expect_staple_state) const { |
| 1210 DCHECK(CalledOnValidThread()); | 1239 DCHECK(CalledOnValidThread()); |
| 1211 | 1240 |
| 1212 if (!IsBuildTimely()) | 1241 if (!IsBuildTimely()) |
| 1213 return false; | 1242 return false; |
| 1214 | 1243 |
| 1215 PreloadResult result; | 1244 PreloadResult result; |
| 1216 if (!DecodeHSTSPreload(host, &result)) | 1245 if (!DecodeHSTSPreload(host, &result)) |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1441 return; | 1470 return; |
| 1442 if (!ssl_info.is_issued_by_known_root) | 1471 if (!ssl_info.is_issued_by_known_root) |
| 1443 return; | 1472 return; |
| 1444 if (!ssl_info.ct_compliance_details_available) | 1473 if (!ssl_info.ct_compliance_details_available) |
| 1445 return; | 1474 return; |
| 1446 if (ssl_info.ct_cert_policy_compliance == | 1475 if (ssl_info.ct_cert_policy_compliance == |
| 1447 ct::CertPolicyCompliance::CERT_POLICY_COMPLIES_VIA_SCTS) | 1476 ct::CertPolicyCompliance::CERT_POLICY_COMPLIES_VIA_SCTS) |
| 1448 return; | 1477 return; |
| 1449 ExpectCTState state; | 1478 ExpectCTState state; |
| 1450 if (GetStaticExpectCTState(host_port_pair.host(), &state)) { | 1479 if (GetStaticExpectCTState(host_port_pair.host(), &state)) { |
| 1451 expect_ct_reporter_->OnExpectCTFailed( | 1480 MaybeNotifyExpectCTFailed(host_port_pair, state.report_uri, |
| 1452 host_port_pair, state.report_uri, ssl_info.cert.get(), | 1481 ssl_info.cert.get(), |
| 1453 ssl_info.unverified_cert.get(), | 1482 ssl_info.unverified_cert.get(), |
| 1454 ssl_info.signed_certificate_timestamps); | 1483 ssl_info.signed_certificate_timestamps); |
| 1455 } | 1484 } |
| 1456 return; | 1485 return; |
| 1457 } | 1486 } |
| 1458 | 1487 |
| 1459 // Otherwise, see if the site has sent a valid Expect-CT header to dynamically | 1488 // Otherwise, see if the site has sent a valid Expect-CT header to dynamically |
| 1460 // turn on reporting and/or enforcement. | 1489 // turn on reporting and/or enforcement. |
| 1461 if (!IsDynamicExpectCTEnabled()) | 1490 if (!IsDynamicExpectCTEnabled()) |
| 1462 return; | 1491 return; |
| 1463 base::Time now = base::Time::Now(); | 1492 base::Time now = base::Time::Now(); |
| 1464 base::TimeDelta max_age; | 1493 base::TimeDelta max_age; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1477 ExpectCTState state; | 1506 ExpectCTState state; |
| 1478 // If an Expect-CT header is observed over a non-compliant connection, the | 1507 // If an Expect-CT header is observed over a non-compliant connection, the |
| 1479 // site owner should be notified about the misconfiguration. If the site was | 1508 // site owner should be notified about the misconfiguration. If the site was |
| 1480 // already opted in to Expect-CT, this report would have been sent at | 1509 // already opted in to Expect-CT, this report would have been sent at |
| 1481 // connection setup time. If the host is not already a noted Expect-CT host, | 1510 // connection setup time. If the host is not already a noted Expect-CT host, |
| 1482 // however, the lack of CT compliance would not have been evaluated/reported | 1511 // however, the lack of CT compliance would not have been evaluated/reported |
| 1483 // at connection setup time, so it needs to be reported here while | 1512 // at connection setup time, so it needs to be reported here while |
| 1484 // processing the header. | 1513 // processing the header. |
| 1485 if (expect_ct_reporter_ && !report_uri.is_empty() && | 1514 if (expect_ct_reporter_ && !report_uri.is_empty() && |
| 1486 !GetDynamicExpectCTState(host_port_pair.host(), &state)) { | 1515 !GetDynamicExpectCTState(host_port_pair.host(), &state)) { |
| 1487 expect_ct_reporter_->OnExpectCTFailed( | 1516 MaybeNotifyExpectCTFailed(host_port_pair, report_uri, ssl_info.cert.get(), |
| 1488 host_port_pair, report_uri, ssl_info.cert.get(), | 1517 ssl_info.unverified_cert.get(), |
| 1489 ssl_info.unverified_cert.get(), | 1518 ssl_info.signed_certificate_timestamps); |
| 1490 ssl_info.signed_certificate_timestamps); | |
| 1491 } | 1519 } |
| 1492 return; | 1520 return; |
| 1493 } | 1521 } |
| 1494 AddExpectCTInternal(host_port_pair.host(), now, now + max_age, enforce, | 1522 AddExpectCTInternal(host_port_pair.host(), now, now + max_age, enforce, |
| 1495 report_uri); | 1523 report_uri); |
| 1496 } | 1524 } |
| 1497 | 1525 |
| 1498 // static | 1526 // static |
| 1499 void TransportSecurityState::SetShouldRequireCTForTesting(bool* required) { | 1527 void TransportSecurityState::SetShouldRequireCTForTesting(bool* required) { |
| 1500 if (!required) { | 1528 if (!required) { |
| 1501 g_ct_required_for_testing = 0; | 1529 g_ct_required_for_testing = 0; |
| 1502 return; | 1530 return; |
| 1503 } | 1531 } |
| 1504 g_ct_required_for_testing = *required ? 1 : -1; | 1532 g_ct_required_for_testing = *required ? 1 : -1; |
| 1505 } | 1533 } |
| 1506 | 1534 |
| 1535 void TransportSecurityState::ClearReportCachesForTesting() { |
| 1536 sent_hpkp_reports_cache_.Clear(); |
| 1537 sent_expect_ct_reports_cache_.Clear(); |
| 1538 } |
| 1539 |
| 1507 // static | 1540 // static |
| 1508 bool TransportSecurityState::IsBuildTimely() { | 1541 bool TransportSecurityState::IsBuildTimely() { |
| 1509 const base::Time build_time = base::GetBuildTime(); | 1542 const base::Time build_time = base::GetBuildTime(); |
| 1510 // We consider built-in information to be timely for 10 weeks. | 1543 // We consider built-in information to be timely for 10 weeks. |
| 1511 return (base::Time::Now() - build_time).InDays() < 70 /* 10 weeks */; | 1544 return (base::Time::Now() - build_time).InDays() < 70 /* 10 weeks */; |
| 1512 } | 1545 } |
| 1513 | 1546 |
| 1514 TransportSecurityState::PKPStatus | 1547 TransportSecurityState::PKPStatus |
| 1515 TransportSecurityState::CheckPublicKeyPinsImpl( | 1548 TransportSecurityState::CheckPublicKeyPinsImpl( |
| 1516 const HostPortPair& host_port_pair, | 1549 const HostPortPair& host_port_pair, |
| (...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1829 TransportSecurityState::PKPStateIterator::PKPStateIterator( | 1862 TransportSecurityState::PKPStateIterator::PKPStateIterator( |
| 1830 const TransportSecurityState& state) | 1863 const TransportSecurityState& state) |
| 1831 : iterator_(state.enabled_pkp_hosts_.begin()), | 1864 : iterator_(state.enabled_pkp_hosts_.begin()), |
| 1832 end_(state.enabled_pkp_hosts_.end()) { | 1865 end_(state.enabled_pkp_hosts_.end()) { |
| 1833 } | 1866 } |
| 1834 | 1867 |
| 1835 TransportSecurityState::PKPStateIterator::~PKPStateIterator() { | 1868 TransportSecurityState::PKPStateIterator::~PKPStateIterator() { |
| 1836 } | 1869 } |
| 1837 | 1870 |
| 1838 } // namespace | 1871 } // namespace |
| OLD | NEW |