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 | 10 |
(...skipping 646 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
657 } | 657 } |
658 | 658 |
659 bool TransportSecurityState::CheckPublicKeyPins( | 659 bool TransportSecurityState::CheckPublicKeyPins( |
660 const HostPortPair& host_port_pair, | 660 const HostPortPair& host_port_pair, |
661 bool is_issued_by_known_root, | 661 bool is_issued_by_known_root, |
662 const HashValueVector& public_key_hashes, | 662 const HashValueVector& public_key_hashes, |
663 const X509Certificate* served_certificate_chain, | 663 const X509Certificate* served_certificate_chain, |
664 const X509Certificate* validated_certificate_chain, | 664 const X509Certificate* validated_certificate_chain, |
665 const PublicKeyPinReportStatus report_status, | 665 const PublicKeyPinReportStatus report_status, |
666 std::string* pinning_failure_log) { | 666 std::string* pinning_failure_log) { |
667 // Perform pin validation if, and only if, all these conditions obtain: | 667 // Perform pin validation only if the server actually has public key pins. |
668 // | 668 if (!HasPublicKeyPins(host_port_pair.host())) { |
669 // * the server's certificate chain chains up to a known root (i.e. not a | |
670 // user-installed trust anchor); and | |
671 // * the server actually has public key pins. | |
672 if (!is_issued_by_known_root || !HasPublicKeyPins(host_port_pair.host())) { | |
673 return true; | 669 return true; |
674 } | 670 } |
675 | 671 |
676 bool pins_are_valid = CheckPublicKeyPinsImpl( | 672 bool pins_are_valid = CheckPublicKeyPinsImpl( |
677 host_port_pair, public_key_hashes, served_certificate_chain, | 673 host_port_pair, is_issued_by_known_root, public_key_hashes, |
678 validated_certificate_chain, report_status, pinning_failure_log); | 674 served_certificate_chain, validated_certificate_chain, report_status, |
| 675 pinning_failure_log); |
| 676 // Don't track statistics when a local trust anchor would override the pinning |
| 677 // anyway. |
| 678 if (!is_issued_by_known_root) { |
| 679 return pins_are_valid; |
| 680 } |
679 if (!pins_are_valid) { | 681 if (!pins_are_valid) { |
680 LOG(ERROR) << *pinning_failure_log; | 682 LOG(ERROR) << *pinning_failure_log; |
681 ReportUMAOnPinFailure(host_port_pair.host()); | 683 ReportUMAOnPinFailure(host_port_pair.host()); |
682 } | 684 } |
683 | 685 |
684 UMA_HISTOGRAM_BOOLEAN("Net.PublicKeyPinSuccess", pins_are_valid); | 686 UMA_HISTOGRAM_BOOLEAN("Net.PublicKeyPinSuccess", pins_are_valid); |
685 return pins_are_valid; | 687 return pins_are_valid; |
686 } | 688 } |
687 | 689 |
688 bool TransportSecurityState::HasPublicKeyPins(const std::string& host) { | 690 bool TransportSecurityState::HasPublicKeyPins(const std::string& host) { |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
799 } else { | 801 } else { |
800 const std::string hashed_host = HashHost(canonicalized_host); | 802 const std::string hashed_host = HashHost(canonicalized_host); |
801 enabled_pkp_hosts_.erase(hashed_host); | 803 enabled_pkp_hosts_.erase(hashed_host); |
802 } | 804 } |
803 | 805 |
804 DirtyNotify(); | 806 DirtyNotify(); |
805 } | 807 } |
806 | 808 |
807 bool TransportSecurityState::CheckPinsAndMaybeSendReport( | 809 bool TransportSecurityState::CheckPinsAndMaybeSendReport( |
808 const HostPortPair& host_port_pair, | 810 const HostPortPair& host_port_pair, |
| 811 bool is_issued_by_known_root, |
809 const TransportSecurityState::PKPState& pkp_state, | 812 const TransportSecurityState::PKPState& pkp_state, |
810 const HashValueVector& hashes, | 813 const HashValueVector& hashes, |
811 const X509Certificate* served_certificate_chain, | 814 const X509Certificate* served_certificate_chain, |
812 const X509Certificate* validated_certificate_chain, | 815 const X509Certificate* validated_certificate_chain, |
813 const TransportSecurityState::PublicKeyPinReportStatus report_status, | 816 const TransportSecurityState::PublicKeyPinReportStatus report_status, |
814 std::string* failure_log) { | 817 std::string* failure_log) { |
815 if (pkp_state.CheckPublicKeyPins(hashes, failure_log)) | 818 if (pkp_state.CheckPublicKeyPins(hashes, failure_log)) |
816 return true; | 819 return true; |
817 | 820 |
818 if (!report_sender_ || | 821 if (!report_sender_ || !is_issued_by_known_root || |
819 report_status != TransportSecurityState::ENABLE_PIN_REPORTS || | 822 report_status != TransportSecurityState::ENABLE_PIN_REPORTS || |
820 pkp_state.report_uri.is_empty()) { | 823 pkp_state.report_uri.is_empty()) { |
821 return false; | 824 return false; |
822 } | 825 } |
823 | 826 |
824 DCHECK(pkp_state.report_uri.is_valid()); | 827 DCHECK(pkp_state.report_uri.is_valid()); |
825 // Report URIs should not be used if they are the same host as the pin | 828 // Report URIs should not be used if they are the same host as the pin |
826 // and are HTTPS, to avoid going into a report-sending loop. | 829 // and are HTTPS, to avoid going into a report-sending loop. |
827 if (!IsReportUriValidForHost(pkp_state.report_uri, host_port_pair.host())) | 830 if (!IsReportUriValidForHost(pkp_state.report_uri, host_port_pair.host())) |
828 return false; | 831 return false; |
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1050 } | 1053 } |
1051 | 1054 |
1052 PKPState pkp_state; | 1055 PKPState pkp_state; |
1053 pkp_state.last_observed = now; | 1056 pkp_state.last_observed = now; |
1054 pkp_state.expiry = now; | 1057 pkp_state.expiry = now; |
1055 pkp_state.include_subdomains = include_subdomains; | 1058 pkp_state.include_subdomains = include_subdomains; |
1056 pkp_state.spki_hashes = spki_hashes; | 1059 pkp_state.spki_hashes = spki_hashes; |
1057 pkp_state.report_uri = report_uri; | 1060 pkp_state.report_uri = report_uri; |
1058 pkp_state.domain = DNSDomainToString(CanonicalizeHost(host_port_pair.host())); | 1061 pkp_state.domain = DNSDomainToString(CanonicalizeHost(host_port_pair.host())); |
1059 | 1062 |
1060 // Only perform pin validation if the cert chains up to a known root. | |
1061 if (!ssl_info.is_issued_by_known_root) | |
1062 return true; | |
1063 | |
1064 CheckPinsAndMaybeSendReport( | 1063 CheckPinsAndMaybeSendReport( |
1065 host_port_pair, pkp_state, ssl_info.public_key_hashes, | 1064 host_port_pair, ssl_info.is_issued_by_known_root, pkp_state, |
1066 ssl_info.unverified_cert.get(), ssl_info.cert.get(), ENABLE_PIN_REPORTS, | 1065 ssl_info.public_key_hashes, ssl_info.unverified_cert.get(), |
1067 &unused_failure_log); | 1066 ssl_info.cert.get(), ENABLE_PIN_REPORTS, &unused_failure_log); |
1068 return true; | 1067 return true; |
1069 } | 1068 } |
1070 | 1069 |
1071 void TransportSecurityState::ProcessExpectCTHeader( | 1070 void TransportSecurityState::ProcessExpectCTHeader( |
1072 const std::string& value, | 1071 const std::string& value, |
1073 const HostPortPair& host_port_pair, | 1072 const HostPortPair& host_port_pair, |
1074 const SSLInfo& ssl_info) { | 1073 const SSLInfo& ssl_info) { |
1075 DCHECK(CalledOnValidThread()); | 1074 DCHECK(CalledOnValidThread()); |
1076 | 1075 |
1077 if (!expect_ct_reporter_) | 1076 if (!expect_ct_reporter_) |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1114 | 1113 |
1115 // static | 1114 // static |
1116 bool TransportSecurityState::IsBuildTimely() { | 1115 bool TransportSecurityState::IsBuildTimely() { |
1117 const base::Time build_time = base::GetBuildTime(); | 1116 const base::Time build_time = base::GetBuildTime(); |
1118 // We consider built-in information to be timely for 10 weeks. | 1117 // We consider built-in information to be timely for 10 weeks. |
1119 return (base::Time::Now() - build_time).InDays() < 70 /* 10 weeks */; | 1118 return (base::Time::Now() - build_time).InDays() < 70 /* 10 weeks */; |
1120 } | 1119 } |
1121 | 1120 |
1122 bool TransportSecurityState::CheckPublicKeyPinsImpl( | 1121 bool TransportSecurityState::CheckPublicKeyPinsImpl( |
1123 const HostPortPair& host_port_pair, | 1122 const HostPortPair& host_port_pair, |
| 1123 bool is_issued_by_known_root, |
1124 const HashValueVector& hashes, | 1124 const HashValueVector& hashes, |
1125 const X509Certificate* served_certificate_chain, | 1125 const X509Certificate* served_certificate_chain, |
1126 const X509Certificate* validated_certificate_chain, | 1126 const X509Certificate* validated_certificate_chain, |
1127 const PublicKeyPinReportStatus report_status, | 1127 const PublicKeyPinReportStatus report_status, |
1128 std::string* failure_log) { | 1128 std::string* failure_log) { |
1129 PKPState pkp_state; | 1129 PKPState pkp_state; |
1130 STSState unused; | 1130 STSState unused; |
1131 | 1131 |
1132 if (!GetDynamicPKPState(host_port_pair.host(), &pkp_state) && | 1132 if (!GetDynamicPKPState(host_port_pair.host(), &pkp_state) && |
1133 !GetStaticDomainState(host_port_pair.host(), &unused, &pkp_state)) { | 1133 !GetStaticDomainState(host_port_pair.host(), &unused, &pkp_state)) { |
1134 // HasPublicKeyPins should have returned true in order for this method | 1134 // HasPublicKeyPins should have returned true in order for this method |
1135 // to have been called, so if we fall through to here, it's an error. | 1135 // to have been called, so if we fall through to here, it's an error. |
1136 return false; | 1136 return false; |
1137 } | 1137 } |
1138 | 1138 |
1139 return CheckPinsAndMaybeSendReport( | 1139 return CheckPinsAndMaybeSendReport( |
1140 host_port_pair, pkp_state, hashes, served_certificate_chain, | 1140 host_port_pair, is_issued_by_known_root, pkp_state, hashes, |
1141 validated_certificate_chain, report_status, failure_log); | 1141 served_certificate_chain, validated_certificate_chain, report_status, |
| 1142 failure_log); |
1142 } | 1143 } |
1143 | 1144 |
1144 bool TransportSecurityState::GetStaticDomainState(const std::string& host, | 1145 bool TransportSecurityState::GetStaticDomainState(const std::string& host, |
1145 STSState* sts_state, | 1146 STSState* sts_state, |
1146 PKPState* pkp_state) const { | 1147 PKPState* pkp_state) const { |
1147 DCHECK(CalledOnValidThread()); | 1148 DCHECK(CalledOnValidThread()); |
1148 | 1149 |
1149 sts_state->upgrade_mode = STSState::MODE_FORCE_HTTPS; | 1150 sts_state->upgrade_mode = STSState::MODE_FORCE_HTTPS; |
1150 sts_state->include_subdomains = false; | 1151 sts_state->include_subdomains = false; |
1151 pkp_state->include_subdomains = false; | 1152 pkp_state->include_subdomains = false; |
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1400 TransportSecurityState::PKPStateIterator::PKPStateIterator( | 1401 TransportSecurityState::PKPStateIterator::PKPStateIterator( |
1401 const TransportSecurityState& state) | 1402 const TransportSecurityState& state) |
1402 : iterator_(state.enabled_pkp_hosts_.begin()), | 1403 : iterator_(state.enabled_pkp_hosts_.begin()), |
1403 end_(state.enabled_pkp_hosts_.end()) { | 1404 end_(state.enabled_pkp_hosts_.end()) { |
1404 } | 1405 } |
1405 | 1406 |
1406 TransportSecurityState::PKPStateIterator::~PKPStateIterator() { | 1407 TransportSecurityState::PKPStateIterator::~PKPStateIterator() { |
1407 } | 1408 } |
1408 | 1409 |
1409 } // namespace | 1410 } // namespace |
OLD | NEW |