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 630 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
641 } | 641 } |
642 | 642 |
643 bool TransportSecurityState::CheckPublicKeyPins( | 643 bool TransportSecurityState::CheckPublicKeyPins( |
644 const HostPortPair& host_port_pair, | 644 const HostPortPair& host_port_pair, |
645 bool is_issued_by_known_root, | 645 bool is_issued_by_known_root, |
646 const HashValueVector& public_key_hashes, | 646 const HashValueVector& public_key_hashes, |
647 const X509Certificate* served_certificate_chain, | 647 const X509Certificate* served_certificate_chain, |
648 const X509Certificate* validated_certificate_chain, | 648 const X509Certificate* validated_certificate_chain, |
649 const PublicKeyPinReportStatus report_status, | 649 const PublicKeyPinReportStatus report_status, |
650 std::string* pinning_failure_log) { | 650 std::string* pinning_failure_log) { |
651 // Perform pin validation if, and only if, all these conditions obtain: | 651 // Perform pin validation only if the server actually has public key pins. |
652 // | 652 if (!HasPublicKeyPins(host_port_pair.host())) { |
653 // * the server's certificate chain chains up to a known root (i.e. not a | |
654 // user-installed trust anchor); and | |
655 // * the server actually has public key pins. | |
656 if (!is_issued_by_known_root || !HasPublicKeyPins(host_port_pair.host())) { | |
657 return true; | 653 return true; |
658 } | 654 } |
659 | 655 |
660 bool pins_are_valid = CheckPublicKeyPinsImpl( | 656 bool pins_are_valid = CheckPublicKeyPinsImpl( |
661 host_port_pair, public_key_hashes, served_certificate_chain, | 657 host_port_pair, is_issued_by_known_root, public_key_hashes, |
662 validated_certificate_chain, report_status, pinning_failure_log); | 658 served_certificate_chain, validated_certificate_chain, report_status, |
| 659 pinning_failure_log); |
| 660 // Don't track statistics when a local trust anchor would override the pinning |
| 661 // anyway. |
| 662 if (!is_issued_by_known_root) { |
| 663 return pins_are_valid; |
| 664 } |
663 if (!pins_are_valid) { | 665 if (!pins_are_valid) { |
664 LOG(ERROR) << *pinning_failure_log; | 666 LOG(ERROR) << *pinning_failure_log; |
665 ReportUMAOnPinFailure(host_port_pair.host()); | 667 ReportUMAOnPinFailure(host_port_pair.host()); |
666 } | 668 } |
667 | 669 |
668 UMA_HISTOGRAM_BOOLEAN("Net.PublicKeyPinSuccess", pins_are_valid); | 670 UMA_HISTOGRAM_BOOLEAN("Net.PublicKeyPinSuccess", pins_are_valid); |
669 return pins_are_valid; | 671 return pins_are_valid; |
670 } | 672 } |
671 | 673 |
672 bool TransportSecurityState::HasPublicKeyPins(const std::string& host) { | 674 bool TransportSecurityState::HasPublicKeyPins(const std::string& host) { |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
783 } else { | 785 } else { |
784 const std::string hashed_host = HashHost(canonicalized_host); | 786 const std::string hashed_host = HashHost(canonicalized_host); |
785 enabled_pkp_hosts_.erase(hashed_host); | 787 enabled_pkp_hosts_.erase(hashed_host); |
786 } | 788 } |
787 | 789 |
788 DirtyNotify(); | 790 DirtyNotify(); |
789 } | 791 } |
790 | 792 |
791 bool TransportSecurityState::CheckPinsAndMaybeSendReport( | 793 bool TransportSecurityState::CheckPinsAndMaybeSendReport( |
792 const HostPortPair& host_port_pair, | 794 const HostPortPair& host_port_pair, |
| 795 bool is_issued_by_known_root, |
793 const TransportSecurityState::PKPState& pkp_state, | 796 const TransportSecurityState::PKPState& pkp_state, |
794 const HashValueVector& hashes, | 797 const HashValueVector& hashes, |
795 const X509Certificate* served_certificate_chain, | 798 const X509Certificate* served_certificate_chain, |
796 const X509Certificate* validated_certificate_chain, | 799 const X509Certificate* validated_certificate_chain, |
797 const TransportSecurityState::PublicKeyPinReportStatus report_status, | 800 const TransportSecurityState::PublicKeyPinReportStatus report_status, |
798 std::string* failure_log) { | 801 std::string* failure_log) { |
799 if (pkp_state.CheckPublicKeyPins(hashes, failure_log)) | 802 if (pkp_state.CheckPublicKeyPins(hashes, failure_log)) |
800 return true; | 803 return true; |
801 | 804 |
802 if (!report_sender_ || | 805 if (!report_sender_ || !is_issued_by_known_root || |
803 report_status != TransportSecurityState::ENABLE_PIN_REPORTS || | 806 report_status != TransportSecurityState::ENABLE_PIN_REPORTS || |
804 pkp_state.report_uri.is_empty()) { | 807 pkp_state.report_uri.is_empty()) { |
805 return false; | 808 return false; |
806 } | 809 } |
807 | 810 |
808 DCHECK(pkp_state.report_uri.is_valid()); | 811 DCHECK(pkp_state.report_uri.is_valid()); |
809 // Report URIs should not be used if they are the same host as the pin | 812 // Report URIs should not be used if they are the same host as the pin |
810 // and are HTTPS, to avoid going into a report-sending loop. | 813 // and are HTTPS, to avoid going into a report-sending loop. |
811 if (!IsReportUriValidForHost(pkp_state.report_uri, host_port_pair.host())) | 814 if (!IsReportUriValidForHost(pkp_state.report_uri, host_port_pair.host())) |
812 return false; | 815 return false; |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1011 } | 1014 } |
1012 | 1015 |
1013 PKPState pkp_state; | 1016 PKPState pkp_state; |
1014 pkp_state.last_observed = now; | 1017 pkp_state.last_observed = now; |
1015 pkp_state.expiry = now; | 1018 pkp_state.expiry = now; |
1016 pkp_state.include_subdomains = include_subdomains; | 1019 pkp_state.include_subdomains = include_subdomains; |
1017 pkp_state.spki_hashes = spki_hashes; | 1020 pkp_state.spki_hashes = spki_hashes; |
1018 pkp_state.report_uri = report_uri; | 1021 pkp_state.report_uri = report_uri; |
1019 pkp_state.domain = DNSDomainToString(CanonicalizeHost(host_port_pair.host())); | 1022 pkp_state.domain = DNSDomainToString(CanonicalizeHost(host_port_pair.host())); |
1020 | 1023 |
1021 // Only perform pin validation if the cert chains up to a known root. | |
1022 if (!ssl_info.is_issued_by_known_root) | |
1023 return true; | |
1024 | |
1025 CheckPinsAndMaybeSendReport( | 1024 CheckPinsAndMaybeSendReport( |
1026 host_port_pair, pkp_state, ssl_info.public_key_hashes, | 1025 host_port_pair, ssl_info.is_issued_by_known_root, pkp_state, |
1027 ssl_info.unverified_cert.get(), ssl_info.cert.get(), ENABLE_PIN_REPORTS, | 1026 ssl_info.public_key_hashes, ssl_info.unverified_cert.get(), |
1028 &unused_failure_log); | 1027 ssl_info.cert.get(), ENABLE_PIN_REPORTS, &unused_failure_log); |
1029 return true; | 1028 return true; |
1030 } | 1029 } |
1031 | 1030 |
1032 void TransportSecurityState::ProcessExpectCTHeader( | 1031 void TransportSecurityState::ProcessExpectCTHeader( |
1033 const std::string& value, | 1032 const std::string& value, |
1034 const HostPortPair& host_port_pair, | 1033 const HostPortPair& host_port_pair, |
1035 const SSLInfo& ssl_info) { | 1034 const SSLInfo& ssl_info) { |
1036 DCHECK(CalledOnValidThread()); | 1035 DCHECK(CalledOnValidThread()); |
1037 | 1036 |
1038 if (!expect_ct_reporter_) | 1037 if (!expect_ct_reporter_) |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1075 | 1074 |
1076 // static | 1075 // static |
1077 bool TransportSecurityState::IsBuildTimely() { | 1076 bool TransportSecurityState::IsBuildTimely() { |
1078 const base::Time build_time = base::GetBuildTime(); | 1077 const base::Time build_time = base::GetBuildTime(); |
1079 // We consider built-in information to be timely for 10 weeks. | 1078 // We consider built-in information to be timely for 10 weeks. |
1080 return (base::Time::Now() - build_time).InDays() < 70 /* 10 weeks */; | 1079 return (base::Time::Now() - build_time).InDays() < 70 /* 10 weeks */; |
1081 } | 1080 } |
1082 | 1081 |
1083 bool TransportSecurityState::CheckPublicKeyPinsImpl( | 1082 bool TransportSecurityState::CheckPublicKeyPinsImpl( |
1084 const HostPortPair& host_port_pair, | 1083 const HostPortPair& host_port_pair, |
| 1084 bool is_issued_by_known_root, |
1085 const HashValueVector& hashes, | 1085 const HashValueVector& hashes, |
1086 const X509Certificate* served_certificate_chain, | 1086 const X509Certificate* served_certificate_chain, |
1087 const X509Certificate* validated_certificate_chain, | 1087 const X509Certificate* validated_certificate_chain, |
1088 const PublicKeyPinReportStatus report_status, | 1088 const PublicKeyPinReportStatus report_status, |
1089 std::string* failure_log) { | 1089 std::string* failure_log) { |
1090 PKPState pkp_state; | 1090 PKPState pkp_state; |
1091 STSState unused; | 1091 STSState unused; |
1092 | 1092 |
1093 if (!GetDynamicPKPState(host_port_pair.host(), &pkp_state) && | 1093 if (!GetDynamicPKPState(host_port_pair.host(), &pkp_state) && |
1094 !GetStaticDomainState(host_port_pair.host(), &unused, &pkp_state)) { | 1094 !GetStaticDomainState(host_port_pair.host(), &unused, &pkp_state)) { |
1095 // HasPublicKeyPins should have returned true in order for this method | 1095 // HasPublicKeyPins should have returned true in order for this method |
1096 // to have been called, so if we fall through to here, it's an error. | 1096 // to have been called, so if we fall through to here, it's an error. |
1097 return false; | 1097 return false; |
1098 } | 1098 } |
1099 | 1099 |
1100 return CheckPinsAndMaybeSendReport( | 1100 return CheckPinsAndMaybeSendReport( |
1101 host_port_pair, pkp_state, hashes, served_certificate_chain, | 1101 host_port_pair, is_issued_by_known_root, pkp_state, hashes, |
1102 validated_certificate_chain, report_status, failure_log); | 1102 served_certificate_chain, validated_certificate_chain, report_status, |
| 1103 failure_log); |
1103 } | 1104 } |
1104 | 1105 |
1105 bool TransportSecurityState::GetStaticDomainState(const std::string& host, | 1106 bool TransportSecurityState::GetStaticDomainState(const std::string& host, |
1106 STSState* sts_state, | 1107 STSState* sts_state, |
1107 PKPState* pkp_state) const { | 1108 PKPState* pkp_state) const { |
1108 DCHECK(CalledOnValidThread()); | 1109 DCHECK(CalledOnValidThread()); |
1109 | 1110 |
1110 sts_state->upgrade_mode = STSState::MODE_FORCE_HTTPS; | 1111 sts_state->upgrade_mode = STSState::MODE_FORCE_HTTPS; |
1111 sts_state->include_subdomains = false; | 1112 sts_state->include_subdomains = false; |
1112 pkp_state->include_subdomains = false; | 1113 pkp_state->include_subdomains = false; |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1356 TransportSecurityState::PKPStateIterator::PKPStateIterator( | 1357 TransportSecurityState::PKPStateIterator::PKPStateIterator( |
1357 const TransportSecurityState& state) | 1358 const TransportSecurityState& state) |
1358 : iterator_(state.enabled_pkp_hosts_.begin()), | 1359 : iterator_(state.enabled_pkp_hosts_.begin()), |
1359 end_(state.enabled_pkp_hosts_.end()) { | 1360 end_(state.enabled_pkp_hosts_.end()) { |
1360 } | 1361 } |
1361 | 1362 |
1362 TransportSecurityState::PKPStateIterator::~PKPStateIterator() { | 1363 TransportSecurityState::PKPStateIterator::~PKPStateIterator() { |
1363 } | 1364 } |
1364 | 1365 |
1365 } // namespace | 1366 } // namespace |
OLD | NEW |