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

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

Issue 2066603004: Return enum from TransportSecurityState::CheckPublicKeyPins (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 6 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
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 10
(...skipping 638 matching lines...) Expand 10 before | Expand all | Expand 10 after
649 STSState static_sts_state; 649 STSState static_sts_state;
650 PKPState unused; 650 PKPState unused;
651 if (GetStaticDomainState(host, &static_sts_state, &unused) && 651 if (GetStaticDomainState(host, &static_sts_state, &unused) &&
652 static_sts_state.ShouldUpgradeToSSL()) { 652 static_sts_state.ShouldUpgradeToSSL()) {
653 return true; 653 return true;
654 } 654 }
655 655
656 return false; 656 return false;
657 } 657 }
658 658
659 bool TransportSecurityState::CheckPublicKeyPins( 659 TransportSecurityState::PKPStatus 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 only if the server actually has public key pins. 667 // Perform pin validation only if the server actually has public key pins.
668 if (!HasPublicKeyPins(host_port_pair.host())) { 668 if (!HasPublicKeyPins(host_port_pair.host())) {
669 return true; 669 return PKPStatus::OK;
670 } 670 }
671 671
672 bool pins_are_valid = CheckPublicKeyPinsImpl( 672 PKPStatus pin_validity = CheckPublicKeyPinsImpl(
673 host_port_pair, is_issued_by_known_root, public_key_hashes, 673 host_port_pair, is_issued_by_known_root, public_key_hashes,
674 served_certificate_chain, validated_certificate_chain, report_status, 674 served_certificate_chain, validated_certificate_chain, report_status,
675 pinning_failure_log); 675 pinning_failure_log);
676
676 // Don't track statistics when a local trust anchor would override the pinning 677 // Don't track statistics when a local trust anchor would override the pinning
677 // anyway. 678 // anyway.
678 if (!is_issued_by_known_root) 679 if (is_issued_by_known_root) {
679 return pins_are_valid; 680 if (pin_validity == PKPStatus::VIOLATED) {
680 681 LOG(ERROR) << *pinning_failure_log;
681 if (!pins_are_valid) { 682 ReportUMAOnPinFailure(host_port_pair.host());
682 LOG(ERROR) << *pinning_failure_log; 683 }
683 ReportUMAOnPinFailure(host_port_pair.host()); 684 bool pin_success = (pin_validity == PKPStatus::OK);
685 UMA_HISTOGRAM_BOOLEAN("Net.PublicKeyPinSuccess", pin_success);
684 } 686 }
685 687 return pin_validity;
Ryan Sleevi 2016/06/15 02:04:03 I'm not sure why you changed it, but we prefer to
estark 2016/06/15 02:35:00 Both |pinning_failure_log| and the UMA histograms
Ryan Sleevi 2016/06/15 02:44:36 In order for the histograms to be useful, the UMA
dadrian 2016/06/15 02:47:55 |pinning_failure_log| is added to the certificate
estark 2016/06/15 02:48:04 Ah, I see.
dadrian 2016/06/15 18:58:28 Added the bail-out-early, but am currently leaving
686 UMA_HISTOGRAM_BOOLEAN("Net.PublicKeyPinSuccess", pins_are_valid);
687 return pins_are_valid;
688 } 688 }
689 689
690 bool TransportSecurityState::HasPublicKeyPins(const std::string& host) { 690 bool TransportSecurityState::HasPublicKeyPins(const std::string& host) {
691 PKPState dynamic_state; 691 PKPState dynamic_state;
692 if (GetDynamicPKPState(host, &dynamic_state)) 692 if (GetDynamicPKPState(host, &dynamic_state))
693 return dynamic_state.HasPublicKeyPins(); 693 return dynamic_state.HasPublicKeyPins();
694 694
695 STSState unused; 695 STSState unused;
696 PKPState static_pkp_state; 696 PKPState static_pkp_state;
697 if (GetStaticDomainState(host, &unused, &static_pkp_state)) { 697 if (GetStaticDomainState(host, &unused, &static_pkp_state)) {
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
799 799
800 enabled_pkp_hosts_[HashHost(canonicalized_host)] = pkp_state; 800 enabled_pkp_hosts_[HashHost(canonicalized_host)] = pkp_state;
801 } else { 801 } else {
802 const std::string hashed_host = HashHost(canonicalized_host); 802 const std::string hashed_host = HashHost(canonicalized_host);
803 enabled_pkp_hosts_.erase(hashed_host); 803 enabled_pkp_hosts_.erase(hashed_host);
804 } 804 }
805 805
806 DirtyNotify(); 806 DirtyNotify();
807 } 807 }
808 808
809 bool TransportSecurityState::CheckPinsAndMaybeSendReport( 809 TransportSecurityState::PKPStatus
810 TransportSecurityState::CheckPinsAndMaybeSendReport(
810 const HostPortPair& host_port_pair, 811 const HostPortPair& host_port_pair,
811 bool is_issued_by_known_root, 812 bool is_issued_by_known_root,
812 const TransportSecurityState::PKPState& pkp_state, 813 const TransportSecurityState::PKPState& pkp_state,
813 const HashValueVector& hashes, 814 const HashValueVector& hashes,
814 const X509Certificate* served_certificate_chain, 815 const X509Certificate* served_certificate_chain,
815 const X509Certificate* validated_certificate_chain, 816 const X509Certificate* validated_certificate_chain,
816 const TransportSecurityState::PublicKeyPinReportStatus report_status, 817 const TransportSecurityState::PublicKeyPinReportStatus report_status,
817 std::string* failure_log) { 818 std::string* failure_log) {
818 if (pkp_state.CheckPublicKeyPins(hashes, failure_log)) 819 if (pkp_state.CheckPublicKeyPins(hashes, failure_log))
819 return true; 820 return PKPStatus::OK;
820 821
821 if (!report_sender_ || !is_issued_by_known_root || 822 // Don't report violations for certificates that chain to local roots.
823 if (!is_issued_by_known_root)
824 return PKPStatus::BYPASSED;
825
826 if (!report_sender_ ||
822 report_status != TransportSecurityState::ENABLE_PIN_REPORTS || 827 report_status != TransportSecurityState::ENABLE_PIN_REPORTS ||
823 pkp_state.report_uri.is_empty()) { 828 pkp_state.report_uri.is_empty()) {
824 return false; 829 return PKPStatus::VIOLATED;
825 } 830 }
826 831
827 DCHECK(pkp_state.report_uri.is_valid()); 832 DCHECK(pkp_state.report_uri.is_valid());
828 // Report URIs should not be used if they are the same host as the pin 833 // Report URIs should not be used if they are the same host as the pin
829 // and are HTTPS, to avoid going into a report-sending loop. 834 // and are HTTPS, to avoid going into a report-sending loop.
830 if (!IsReportUriValidForHost(pkp_state.report_uri, host_port_pair.host())) 835 if (!IsReportUriValidForHost(pkp_state.report_uri, host_port_pair.host()))
831 return false; 836 return PKPStatus::VIOLATED;
832 837
833 std::string serialized_report; 838 std::string serialized_report;
834 std::string report_cache_key; 839 std::string report_cache_key;
835 if (!GetHPKPReport(host_port_pair, pkp_state, served_certificate_chain, 840 if (!GetHPKPReport(host_port_pair, pkp_state, served_certificate_chain,
836 validated_certificate_chain, &serialized_report, 841 validated_certificate_chain, &serialized_report,
837 &report_cache_key)) { 842 &report_cache_key)) {
838 return false; 843 return PKPStatus::VIOLATED;
839 } 844 }
840 845
841 // Limit the rate at which duplicate reports are sent to the same 846 // Limit the rate at which duplicate reports are sent to the same
842 // report URI. The same report will not be sent within 847 // report URI. The same report will not be sent within
843 // |kTimeToRememberHPKPReportsMins|, which reduces load on servers and 848 // |kTimeToRememberHPKPReportsMins|, which reduces load on servers and
844 // also prevents accidental loops (a.com triggers a report to b.com 849 // also prevents accidental loops (a.com triggers a report to b.com
845 // which triggers a report to a.com). See section 2.1.4 of RFC 7469. 850 // which triggers a report to a.com). See section 2.1.4 of RFC 7469.
846 if (sent_reports_cache_.Get(report_cache_key, base::TimeTicks::Now())) 851 if (sent_reports_cache_.Get(report_cache_key, base::TimeTicks::Now()))
847 return false; 852 return PKPStatus::VIOLATED;
848 sent_reports_cache_.Put( 853 sent_reports_cache_.Put(
849 report_cache_key, true, base::TimeTicks::Now(), 854 report_cache_key, true, base::TimeTicks::Now(),
850 base::TimeTicks::Now() + 855 base::TimeTicks::Now() +
851 base::TimeDelta::FromMinutes(kTimeToRememberHPKPReportsMins)); 856 base::TimeDelta::FromMinutes(kTimeToRememberHPKPReportsMins));
852 857
853 report_sender_->Send(pkp_state.report_uri, serialized_report); 858 report_sender_->Send(pkp_state.report_uri, serialized_report);
854 return false; 859 return PKPStatus::VIOLATED;
855 } 860 }
856 861
857 bool TransportSecurityState::GetStaticExpectCTState( 862 bool TransportSecurityState::GetStaticExpectCTState(
858 const std::string& host, 863 const std::string& host,
859 ExpectCTState* expect_ct_state) const { 864 ExpectCTState* expect_ct_state) const {
860 DCHECK(CalledOnValidThread()); 865 DCHECK(CalledOnValidThread());
861 866
862 if (!IsBuildTimely()) 867 if (!IsBuildTimely())
863 return false; 868 return false;
864 869
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
1111 "Net.PublicKeyPinFailureDomain", result.domain_id); 1116 "Net.PublicKeyPinFailureDomain", result.domain_id);
1112 } 1117 }
1113 1118
1114 // static 1119 // static
1115 bool TransportSecurityState::IsBuildTimely() { 1120 bool TransportSecurityState::IsBuildTimely() {
1116 const base::Time build_time = base::GetBuildTime(); 1121 const base::Time build_time = base::GetBuildTime();
1117 // We consider built-in information to be timely for 10 weeks. 1122 // We consider built-in information to be timely for 10 weeks.
1118 return (base::Time::Now() - build_time).InDays() < 70 /* 10 weeks */; 1123 return (base::Time::Now() - build_time).InDays() < 70 /* 10 weeks */;
1119 } 1124 }
1120 1125
1121 bool TransportSecurityState::CheckPublicKeyPinsImpl( 1126 TransportSecurityState::PKPStatus
1127 TransportSecurityState::CheckPublicKeyPinsImpl(
1122 const HostPortPair& host_port_pair, 1128 const HostPortPair& host_port_pair,
1123 bool is_issued_by_known_root, 1129 bool is_issued_by_known_root,
1124 const HashValueVector& hashes, 1130 const HashValueVector& hashes,
1125 const X509Certificate* served_certificate_chain, 1131 const X509Certificate* served_certificate_chain,
1126 const X509Certificate* validated_certificate_chain, 1132 const X509Certificate* validated_certificate_chain,
1127 const PublicKeyPinReportStatus report_status, 1133 const PublicKeyPinReportStatus report_status,
1128 std::string* failure_log) { 1134 std::string* failure_log) {
1129 PKPState pkp_state; 1135 PKPState pkp_state;
1130 STSState unused; 1136 STSState unused;
1131 1137
1132 if (!GetDynamicPKPState(host_port_pair.host(), &pkp_state) && 1138 if (!GetDynamicPKPState(host_port_pair.host(), &pkp_state) &&
1133 !GetStaticDomainState(host_port_pair.host(), &unused, &pkp_state)) { 1139 !GetStaticDomainState(host_port_pair.host(), &unused, &pkp_state)) {
1134 // HasPublicKeyPins should have returned true in order for this method 1140 // 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. 1141 // to have been called, so if we fall through to here, it's an error.
1136 return false; 1142 return PKPStatus::VIOLATED;
estark 2016/06/15 02:48:04 This whole little block should really be a DCHECK,
dadrian 2016/06/15 18:58:28 Acknowledged.
1137 } 1143 }
1138 1144
1139 return CheckPinsAndMaybeSendReport( 1145 return CheckPinsAndMaybeSendReport(
1140 host_port_pair, is_issued_by_known_root, pkp_state, hashes, 1146 host_port_pair, is_issued_by_known_root, pkp_state, hashes,
1141 served_certificate_chain, validated_certificate_chain, report_status, 1147 served_certificate_chain, validated_certificate_chain, report_status,
1142 failure_log); 1148 failure_log);
1143 } 1149 }
1144 1150
1145 bool TransportSecurityState::GetStaticDomainState(const std::string& host, 1151 bool TransportSecurityState::GetStaticDomainState(const std::string& host,
1146 STSState* sts_state, 1152 STSState* sts_state,
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
1401 TransportSecurityState::PKPStateIterator::PKPStateIterator( 1407 TransportSecurityState::PKPStateIterator::PKPStateIterator(
1402 const TransportSecurityState& state) 1408 const TransportSecurityState& state)
1403 : iterator_(state.enabled_pkp_hosts_.begin()), 1409 : iterator_(state.enabled_pkp_hosts_.begin()),
1404 end_(state.enabled_pkp_hosts_.end()) { 1410 end_(state.enabled_pkp_hosts_.end()) {
1405 } 1411 }
1406 1412
1407 TransportSecurityState::PKPStateIterator::~PKPStateIterator() { 1413 TransportSecurityState::PKPStateIterator::~PKPStateIterator() {
1408 } 1414 }
1409 1415
1410 } // namespace 1416 } // namespace
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698