Return enum from TransportSecurityState::CheckPublicKeyPins
BUG=618775
Review-Url: https://codereview.chromium.org/2066603004
Cr-Commit-Position: refs/heads/master@{#401140}
diff --git a/net/http/http_security_headers_unittest.cc b/net/http/http_security_headers_unittest.cc
index 4c7bff3..e4904dd 100644
--- a/net/http/http_security_headers_unittest.cc
+++ b/net/http/http_security_headers_unittest.cc
@@ -710,9 +710,10 @@
std::string failure_log;
const bool is_issued_by_known_root = true;
HostPortPair domain_port(domain, 443);
- EXPECT_TRUE(state.CheckPublicKeyPins(
- domain_port, is_issued_by_known_root, hashes, nullptr, nullptr,
- TransportSecurityState::DISABLE_PIN_REPORTS, &failure_log));
+ EXPECT_EQ(TransportSecurityState::PKPStatus::OK,
+ state.CheckPublicKeyPins(
+ domain_port, is_issued_by_known_root, hashes, nullptr, nullptr,
+ TransportSecurityState::DISABLE_PIN_REPORTS, &failure_log));
TransportSecurityState::PKPState new_dynamic_pkp_state;
EXPECT_TRUE(state.GetDynamicPKPState(domain, &new_dynamic_pkp_state));
@@ -795,10 +796,11 @@
const bool is_issued_by_known_root = true;
HostPortPair domain_port(domain, 443);
- EXPECT_FALSE(state.CheckPublicKeyPins(
- domain_port, is_issued_by_known_root, new_static_pkp_state2.spki_hashes,
- nullptr, nullptr, TransportSecurityState::DISABLE_PIN_REPORTS,
- &failure_log));
+ EXPECT_EQ(TransportSecurityState::PKPStatus::VIOLATED,
+ state.CheckPublicKeyPins(
+ domain_port, is_issued_by_known_root,
+ new_static_pkp_state2.spki_hashes, nullptr, nullptr,
+ TransportSecurityState::DISABLE_PIN_REPORTS, &failure_log));
EXPECT_NE(0UL, failure_log.length());
}
@@ -831,9 +833,11 @@
std::string failure_log;
const bool is_issued_by_known_root = true;
HostPortPair domain_port(domain, 443);
- EXPECT_TRUE(state.CheckPublicKeyPins(
- domain_port, is_issued_by_known_root, saved_hashes, nullptr, nullptr,
- TransportSecurityState::DISABLE_PIN_REPORTS, &failure_log));
+ EXPECT_EQ(
+ TransportSecurityState::PKPStatus::OK,
+ state.CheckPublicKeyPins(
+ domain_port, is_issued_by_known_root, saved_hashes, nullptr, nullptr,
+ TransportSecurityState::DISABLE_PIN_REPORTS, &failure_log));
// Add an HPKP header, which should only update the dynamic state.
HashValue good_hash = GetTestHashValue(1, HASH_VALUE_SHA256);
@@ -853,9 +857,11 @@
EXPECT_TRUE(state.ShouldUpgradeToSSL(domain));
// The dynamic pins, which do not match |saved_hashes|, should take
// precedence over the static pins and cause the check to fail.
- EXPECT_FALSE(state.CheckPublicKeyPins(
- domain_port, is_issued_by_known_root, saved_hashes, nullptr, nullptr,
- TransportSecurityState::DISABLE_PIN_REPORTS, &failure_log));
+ EXPECT_EQ(
+ TransportSecurityState::PKPStatus::VIOLATED,
+ state.CheckPublicKeyPins(
+ domain_port, is_issued_by_known_root, saved_hashes, nullptr, nullptr,
+ TransportSecurityState::DISABLE_PIN_REPORTS, &failure_log));
}
// Tests that seeing an invalid HPKP header leaves the existing one alone.
@@ -880,9 +886,11 @@
std::string failure_log;
bool is_issued_by_known_root = true;
HostPortPair domain_port("example.com", 443);
- EXPECT_TRUE(state.CheckPublicKeyPins(
- domain_port, is_issued_by_known_root, ssl_info.public_key_hashes, nullptr,
- nullptr, TransportSecurityState::DISABLE_PIN_REPORTS, &failure_log));
+ EXPECT_EQ(TransportSecurityState::PKPStatus::OK,
+ state.CheckPublicKeyPins(
+ domain_port, is_issued_by_known_root,
+ ssl_info.public_key_hashes, nullptr, nullptr,
+ TransportSecurityState::DISABLE_PIN_REPORTS, &failure_log));
// Now assert an invalid one. This should fail.
EXPECT_FALSE(state.AddHPKPHeader(
@@ -891,9 +899,11 @@
// The old pins must still exist.
EXPECT_TRUE(state.HasPublicKeyPins("example.com"));
- EXPECT_TRUE(state.CheckPublicKeyPins(
- domain_port, is_issued_by_known_root, ssl_info.public_key_hashes, nullptr,
- nullptr, TransportSecurityState::DISABLE_PIN_REPORTS, &failure_log));
+ EXPECT_EQ(TransportSecurityState::PKPStatus::OK,
+ state.CheckPublicKeyPins(
+ domain_port, is_issued_by_known_root,
+ ssl_info.public_key_hashes, nullptr, nullptr,
+ TransportSecurityState::DISABLE_PIN_REPORTS, &failure_log));
}
}; // namespace net
diff --git a/net/http/transport_security_state.cc b/net/http/transport_security_state.cc
index 6ee15b0c..1348528 100644
--- a/net/http/transport_security_state.cc
+++ b/net/http/transport_security_state.cc
@@ -656,7 +656,7 @@
return false;
}
-bool TransportSecurityState::CheckPublicKeyPins(
+TransportSecurityState::PKPStatus TransportSecurityState::CheckPublicKeyPins(
const HostPortPair& host_port_pair,
bool is_issued_by_known_root,
const HashValueVector& public_key_hashes,
@@ -666,25 +666,26 @@
std::string* pinning_failure_log) {
// Perform pin validation only if the server actually has public key pins.
if (!HasPublicKeyPins(host_port_pair.host())) {
- return true;
+ return PKPStatus::OK;
}
- bool pins_are_valid = CheckPublicKeyPinsImpl(
+ PKPStatus pin_validity = CheckPublicKeyPinsImpl(
host_port_pair, is_issued_by_known_root, public_key_hashes,
served_certificate_chain, validated_certificate_chain, report_status,
pinning_failure_log);
+
// Don't track statistics when a local trust anchor would override the pinning
// anyway.
if (!is_issued_by_known_root)
- return pins_are_valid;
+ return pin_validity;
- if (!pins_are_valid) {
+ if (pin_validity == PKPStatus::VIOLATED) {
LOG(ERROR) << *pinning_failure_log;
ReportUMAOnPinFailure(host_port_pair.host());
}
-
- UMA_HISTOGRAM_BOOLEAN("Net.PublicKeyPinSuccess", pins_are_valid);
- return pins_are_valid;
+ UMA_HISTOGRAM_BOOLEAN("Net.PublicKeyPinSuccess",
+ pin_validity == PKPStatus::OK);
+ return pin_validity;
}
bool TransportSecurityState::HasPublicKeyPins(const std::string& host) {
@@ -806,7 +807,8 @@
DirtyNotify();
}
-bool TransportSecurityState::CheckPinsAndMaybeSendReport(
+TransportSecurityState::PKPStatus
+TransportSecurityState::CheckPinsAndMaybeSendReport(
const HostPortPair& host_port_pair,
bool is_issued_by_known_root,
const TransportSecurityState::PKPState& pkp_state,
@@ -816,26 +818,30 @@
const TransportSecurityState::PublicKeyPinReportStatus report_status,
std::string* failure_log) {
if (pkp_state.CheckPublicKeyPins(hashes, failure_log))
- return true;
+ return PKPStatus::OK;
- if (!report_sender_ || !is_issued_by_known_root ||
+ // Don't report violations for certificates that chain to local roots.
+ if (!is_issued_by_known_root)
+ return PKPStatus::BYPASSED;
+
+ if (!report_sender_ ||
report_status != TransportSecurityState::ENABLE_PIN_REPORTS ||
pkp_state.report_uri.is_empty()) {
- return false;
+ return PKPStatus::VIOLATED;
}
DCHECK(pkp_state.report_uri.is_valid());
// Report URIs should not be used if they are the same host as the pin
// and are HTTPS, to avoid going into a report-sending loop.
if (!IsReportUriValidForHost(pkp_state.report_uri, host_port_pair.host()))
- return false;
+ return PKPStatus::VIOLATED;
std::string serialized_report;
std::string report_cache_key;
if (!GetHPKPReport(host_port_pair, pkp_state, served_certificate_chain,
validated_certificate_chain, &serialized_report,
&report_cache_key)) {
- return false;
+ return PKPStatus::VIOLATED;
}
// Limit the rate at which duplicate reports are sent to the same
@@ -844,14 +850,14 @@
// also prevents accidental loops (a.com triggers a report to b.com
// which triggers a report to a.com). See section 2.1.4 of RFC 7469.
if (sent_reports_cache_.Get(report_cache_key, base::TimeTicks::Now()))
- return false;
+ return PKPStatus::VIOLATED;
sent_reports_cache_.Put(
report_cache_key, true, base::TimeTicks::Now(),
base::TimeTicks::Now() +
base::TimeDelta::FromMinutes(kTimeToRememberHPKPReportsMins));
report_sender_->Send(pkp_state.report_uri, serialized_report);
- return false;
+ return PKPStatus::VIOLATED;
}
bool TransportSecurityState::GetStaticExpectCTState(
@@ -1118,7 +1124,8 @@
return (base::Time::Now() - build_time).InDays() < 70 /* 10 weeks */;
}
-bool TransportSecurityState::CheckPublicKeyPinsImpl(
+TransportSecurityState::PKPStatus
+TransportSecurityState::CheckPublicKeyPinsImpl(
const HostPortPair& host_port_pair,
bool is_issued_by_known_root,
const HashValueVector& hashes,
@@ -1129,13 +1136,13 @@
PKPState pkp_state;
STSState unused;
- if (!GetDynamicPKPState(host_port_pair.host(), &pkp_state) &&
- !GetStaticDomainState(host_port_pair.host(), &unused, &pkp_state)) {
- // HasPublicKeyPins should have returned true in order for this method
- // to have been called, so if we fall through to here, it's an error.
- return false;
- }
+ bool found_state =
+ GetDynamicPKPState(host_port_pair.host(), &pkp_state) ||
+ GetStaticDomainState(host_port_pair.host(), &unused, &pkp_state);
+ // HasPublicKeyPins should have returned true in order for this method to have
+ // been called.
+ DCHECK(found_state);
return CheckPinsAndMaybeSendReport(
host_port_pair, is_issued_by_known_root, pkp_state, hashes,
served_certificate_chain, validated_certificate_chain, report_status,
diff --git a/net/http/transport_security_state.h b/net/http/transport_security_state.h
index aa92b43..168e879 100644
--- a/net/http/transport_security_state.h
+++ b/net/http/transport_security_state.h
@@ -99,6 +99,20 @@
std::map<std::string, STSState>::const_iterator end_;
};
+ // PKPStatus describes the result of a pinning check.
+ enum class PKPStatus {
+ // Pinning was enabled and the necessary pins were not present.
+ VIOLATED,
+
+ // Pinning was not enabled, or pinning was enabled and the certificate
+ // satisfied the pins.
+ OK,
+
+ // Pinning was enabled and the certificate did not satisfy the pins, but the
+ // violation was ignored due to local policy, such as a local trust anchor.
+ BYPASSED,
+ };
+
// A PKPState describes the public key pinning state.
class NET_EXPORT PKPState {
public:
@@ -247,13 +261,14 @@
// when is_issued_by_known_root is false.
bool ShouldSSLErrorsBeFatal(const std::string& host);
bool ShouldUpgradeToSSL(const std::string& host);
- bool CheckPublicKeyPins(const HostPortPair& host_port_pair,
- bool is_issued_by_known_root,
- const HashValueVector& hashes,
- const X509Certificate* served_certificate_chain,
- const X509Certificate* validated_certificate_chain,
- const PublicKeyPinReportStatus report_status,
- std::string* failure_log);
+ PKPStatus CheckPublicKeyPins(
+ const HostPortPair& host_port_pair,
+ bool is_issued_by_known_root,
+ const HashValueVector& hashes,
+ const X509Certificate* served_certificate_chain,
+ const X509Certificate* validated_certificate_chain,
+ const PublicKeyPinReportStatus report_status,
+ std::string* failure_log);
bool HasPublicKeyPins(const std::string& host);
// Assign a |Delegate| for persisting the transport security state. If
@@ -399,7 +414,7 @@
static bool IsBuildTimely();
// Helper method for actually checking pins.
- bool CheckPublicKeyPinsImpl(
+ PKPStatus CheckPublicKeyPinsImpl(
const HostPortPair& host_port_pair,
bool is_issued_by_known_root,
const HashValueVector& hashes,
@@ -440,7 +455,7 @@
// |report_status| says to), this method sends an HPKP violation
// report containing |served_certificate_chain| and
// |validated_certificate_chain|.
- bool CheckPinsAndMaybeSendReport(
+ PKPStatus CheckPinsAndMaybeSendReport(
const HostPortPair& host_port_pair,
bool is_issued_by_known_root,
const TransportSecurityState::PKPState& pkp_state,
diff --git a/net/http/transport_security_state_unittest.cc b/net/http/transport_security_state_unittest.cc
index 009c7d6..e5c1e63 100644
--- a/net/http/transport_security_state_unittest.cc
+++ b/net/http/transport_security_state_unittest.cc
@@ -1270,44 +1270,49 @@
EXPECT_EQ(std::string(), mock_report_sender.latest_report());
std::string failure_log;
- EXPECT_FALSE(state.CheckPublicKeyPins(
- host_port_pair, true, bad_hashes, cert1.get(), cert2.get(),
- TransportSecurityState::DISABLE_PIN_REPORTS, &failure_log));
+ EXPECT_EQ(TransportSecurityState::PKPStatus::VIOLATED,
+ state.CheckPublicKeyPins(
+ host_port_pair, true, bad_hashes, cert1.get(), cert2.get(),
+ TransportSecurityState::DISABLE_PIN_REPORTS, &failure_log));
// No report should have been sent because of the DISABLE_PIN_REPORTS
// argument.
EXPECT_EQ(GURL(), mock_report_sender.latest_report_uri());
EXPECT_EQ(std::string(), mock_report_sender.latest_report());
- EXPECT_TRUE(state.CheckPublicKeyPins(
- host_port_pair, true, good_hashes, cert1.get(), cert2.get(),
- TransportSecurityState::ENABLE_PIN_REPORTS, &failure_log));
+ EXPECT_EQ(TransportSecurityState::PKPStatus::OK,
+ state.CheckPublicKeyPins(
+ host_port_pair, true, good_hashes, cert1.get(), cert2.get(),
+ TransportSecurityState::ENABLE_PIN_REPORTS, &failure_log));
// No report should have been sent because there was no violation.
EXPECT_EQ(GURL(), mock_report_sender.latest_report_uri());
EXPECT_EQ(std::string(), mock_report_sender.latest_report());
- EXPECT_FALSE(state.CheckPublicKeyPins(
- host_port_pair, false, bad_hashes, cert1.get(), cert2.get(),
- TransportSecurityState::ENABLE_PIN_REPORTS, &failure_log));
+ EXPECT_EQ(TransportSecurityState::PKPStatus::BYPASSED,
+ state.CheckPublicKeyPins(
+ host_port_pair, false, bad_hashes, cert1.get(), cert2.get(),
+ TransportSecurityState::ENABLE_PIN_REPORTS, &failure_log));
// No report should have been sent because the certificate chained to a
// non-public root.
EXPECT_EQ(GURL(), mock_report_sender.latest_report_uri());
EXPECT_EQ(std::string(), mock_report_sender.latest_report());
- EXPECT_TRUE(state.CheckPublicKeyPins(
- host_port_pair, false, good_hashes, cert1.get(), cert2.get(),
- TransportSecurityState::ENABLE_PIN_REPORTS, &failure_log));
+ EXPECT_EQ(TransportSecurityState::PKPStatus::OK,
+ state.CheckPublicKeyPins(
+ host_port_pair, false, good_hashes, cert1.get(), cert2.get(),
+ TransportSecurityState::ENABLE_PIN_REPORTS, &failure_log));
// No report should have been sent because there was no violation, even though
// the certificate chained to a local trust anchor.
EXPECT_EQ(GURL(), mock_report_sender.latest_report_uri());
EXPECT_EQ(std::string(), mock_report_sender.latest_report());
- EXPECT_FALSE(state.CheckPublicKeyPins(
- host_port_pair, true, bad_hashes, cert1.get(), cert2.get(),
- TransportSecurityState::ENABLE_PIN_REPORTS, &failure_log));
+ EXPECT_EQ(TransportSecurityState::PKPStatus::VIOLATED,
+ state.CheckPublicKeyPins(
+ host_port_pair, true, bad_hashes, cert1.get(), cert2.get(),
+ TransportSecurityState::ENABLE_PIN_REPORTS, &failure_log));
// Now a report should have been sent. Check that it contains the
// right information.
@@ -1318,9 +1323,11 @@
cert1.get(), cert2.get(),
good_hashes));
mock_report_sender.Clear();
- EXPECT_FALSE(state.CheckPublicKeyPins(
- subdomain_host_port_pair, true, bad_hashes, cert1.get(), cert2.get(),
- TransportSecurityState::ENABLE_PIN_REPORTS, &failure_log));
+ EXPECT_EQ(TransportSecurityState::PKPStatus::VIOLATED,
+ state.CheckPublicKeyPins(subdomain_host_port_pair, true, bad_hashes,
+ cert1.get(), cert2.get(),
+ TransportSecurityState::ENABLE_PIN_REPORTS,
+ &failure_log));
// Now a report should have been sent for the subdomain. Check that it
// contains the right information.
@@ -1367,9 +1374,10 @@
state.AddHPKP(kHost, expiry, true, good_hashes, report_uri);
std::string failure_log;
- EXPECT_FALSE(state.CheckPublicKeyPins(
- host_port_pair, true, bad_hashes, cert1.get(), cert2.get(),
- TransportSecurityState::ENABLE_PIN_REPORTS, &failure_log));
+ EXPECT_EQ(TransportSecurityState::PKPStatus::VIOLATED,
+ state.CheckPublicKeyPins(
+ host_port_pair, true, bad_hashes, cert1.get(), cert2.get(),
+ TransportSecurityState::ENABLE_PIN_REPORTS, &failure_log));
// Check that the UMA histogram was updated when the report failed to
// send.
@@ -1553,9 +1561,10 @@
// Trigger a violation and check that it sends a report.
std::string failure_log;
- EXPECT_FALSE(state.CheckPublicKeyPins(
- host_port_pair, true, bad_hashes, cert1.get(), cert2.get(),
- TransportSecurityState::ENABLE_PIN_REPORTS, &failure_log));
+ EXPECT_EQ(TransportSecurityState::PKPStatus::VIOLATED,
+ state.CheckPublicKeyPins(
+ host_port_pair, true, bad_hashes, cert1.get(), cert2.get(),
+ TransportSecurityState::ENABLE_PIN_REPORTS, &failure_log));
EXPECT_EQ(report_uri, mock_report_sender.latest_report_uri());
@@ -1601,17 +1610,19 @@
// Trigger a violation and check that it does not send a report
// because the report-uri is HTTPS and same-host as the pins.
std::string failure_log;
- EXPECT_FALSE(state.CheckPublicKeyPins(
- host_port_pair, true, bad_hashes, cert1.get(), cert2.get(),
- TransportSecurityState::ENABLE_PIN_REPORTS, &failure_log));
+ EXPECT_EQ(TransportSecurityState::PKPStatus::VIOLATED,
+ state.CheckPublicKeyPins(
+ host_port_pair, true, bad_hashes, cert1.get(), cert2.get(),
+ TransportSecurityState::ENABLE_PIN_REPORTS, &failure_log));
EXPECT_TRUE(mock_report_sender.latest_report_uri().is_empty());
// An HTTP report uri to the same host should be okay.
state.AddHPKP("example.test", expiry, true, good_hashes, http_report_uri);
- EXPECT_FALSE(state.CheckPublicKeyPins(
- host_port_pair, true, bad_hashes, cert1.get(), cert2.get(),
- TransportSecurityState::ENABLE_PIN_REPORTS, &failure_log));
+ EXPECT_EQ(TransportSecurityState::PKPStatus::VIOLATED,
+ state.CheckPublicKeyPins(
+ host_port_pair, true, bad_hashes, cert1.get(), cert2.get(),
+ TransportSecurityState::ENABLE_PIN_REPORTS, &failure_log));
EXPECT_EQ(http_report_uri, mock_report_sender.latest_report_uri());
}
@@ -1649,9 +1660,10 @@
EXPECT_EQ(std::string(), mock_report_sender.latest_report());
std::string failure_log;
- EXPECT_FALSE(state.CheckPublicKeyPins(
- host_port_pair, true, bad_hashes, cert1.get(), cert2.get(),
- TransportSecurityState::ENABLE_PIN_REPORTS, &failure_log));
+ EXPECT_EQ(TransportSecurityState::PKPStatus::VIOLATED,
+ state.CheckPublicKeyPins(
+ host_port_pair, true, bad_hashes, cert1.get(), cert2.get(),
+ TransportSecurityState::ENABLE_PIN_REPORTS, &failure_log));
// A report should have been sent. Check that it contains the
// right information.
@@ -1665,9 +1677,10 @@
// Now trigger the same violation; a duplicative report should not be
// sent.
- EXPECT_FALSE(state.CheckPublicKeyPins(
- host_port_pair, true, bad_hashes, cert1.get(), cert2.get(),
- TransportSecurityState::ENABLE_PIN_REPORTS, &failure_log));
+ EXPECT_EQ(TransportSecurityState::PKPStatus::VIOLATED,
+ state.CheckPublicKeyPins(
+ host_port_pair, true, bad_hashes, cert1.get(), cert2.get(),
+ TransportSecurityState::ENABLE_PIN_REPORTS, &failure_log));
EXPECT_EQ(GURL(), mock_report_sender.latest_report_uri());
EXPECT_EQ(std::string(), mock_report_sender.latest_report());
@@ -1675,9 +1688,10 @@
// should be sent.
GURL report_uri2("http://report-example2.test/test");
state.AddHPKP(kHost, expiry, true, good_hashes, report_uri2);
- EXPECT_FALSE(state.CheckPublicKeyPins(
- host_port_pair, true, bad_hashes, cert1.get(), cert2.get(),
- TransportSecurityState::ENABLE_PIN_REPORTS, &failure_log));
+ EXPECT_EQ(TransportSecurityState::PKPStatus::VIOLATED,
+ state.CheckPublicKeyPins(
+ host_port_pair, true, bad_hashes, cert1.get(), cert2.get(),
+ TransportSecurityState::ENABLE_PIN_REPORTS, &failure_log));
EXPECT_EQ(report_uri2, mock_report_sender.latest_report_uri());
report = mock_report_sender.latest_report();
ASSERT_FALSE(report.empty());
diff --git a/net/quic/crypto/proof_verifier_chromium.cc b/net/quic/crypto/proof_verifier_chromium.cc
index dde1503..4598150 100644
--- a/net/quic/crypto/proof_verifier_chromium.cc
+++ b/net/quic/crypto/proof_verifier_chromium.cc
@@ -339,21 +339,29 @@
verify_details_->ct_verify_result.verified_scts, net_log_);
}
- if ((result == OK ||
- (IsCertificateError(result) && IsCertStatusMinorError(cert_status))) &&
- !transport_security_state_->CheckPublicKeyPins(
- HostPortPair(hostname_, port_),
- cert_verify_result.is_issued_by_known_root,
- cert_verify_result.public_key_hashes, cert_.get(),
- cert_verify_result.verified_cert.get(),
- TransportSecurityState::ENABLE_PIN_REPORTS,
- &verify_details_->pinning_failure_log)) {
- if (cert_verify_result.is_issued_by_known_root) {
- verify_details_->cert_verify_result.cert_status |=
- CERT_STATUS_PINNED_KEY_MISSING;
- result = ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN;
- } else {
- verify_details_->pkp_bypassed = true;
+ if (transport_security_state_ &&
+ (result == OK ||
+ (IsCertificateError(result) && IsCertStatusMinorError(cert_status)))) {
+ TransportSecurityState::PKPStatus pin_validity =
+ transport_security_state_->CheckPublicKeyPins(
+ HostPortPair(hostname_, port_),
+ cert_verify_result.is_issued_by_known_root,
+ cert_verify_result.public_key_hashes, cert_.get(),
+ cert_verify_result.verified_cert.get(),
+ TransportSecurityState::ENABLE_PIN_REPORTS,
+ &verify_details_->pinning_failure_log);
+ switch (pin_validity) {
+ case TransportSecurityState::PKPStatus::VIOLATED:
+ result = ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN;
+ verify_details_->cert_verify_result.cert_status |=
+ CERT_STATUS_PINNED_KEY_MISSING;
+ break;
+ case TransportSecurityState::PKPStatus::BYPASSED:
+ verify_details_->pkp_bypassed = true;
+ // Fall through.
+ case TransportSecurityState::PKPStatus::OK:
+ // Do nothing.
+ break;
}
}
diff --git a/net/socket/ssl_client_socket_impl.cc b/net/socket/ssl_client_socket_impl.cc
index 60a8fae4..01acc54 100644
--- a/net/socket/ssl_client_socket_impl.cc
+++ b/net/socket/ssl_client_socket_impl.cc
@@ -1328,18 +1328,27 @@
}
const CertStatus cert_status = server_cert_verify_result_.cert_status;
- if ((result == OK ||
- (IsCertificateError(result) && IsCertStatusMinorError(cert_status))) &&
- !transport_security_state_->CheckPublicKeyPins(
- host_and_port_, server_cert_verify_result_.is_issued_by_known_root,
- server_cert_verify_result_.public_key_hashes, server_cert_.get(),
- server_cert_verify_result_.verified_cert.get(),
- TransportSecurityState::ENABLE_PIN_REPORTS, &pinning_failure_log_)) {
- if (server_cert_verify_result_.is_issued_by_known_root) {
- server_cert_verify_result_.cert_status |= CERT_STATUS_PINNED_KEY_MISSING;
- result = ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN;
- } else {
- pkp_bypassed_ = true;
+ if (transport_security_state_ &&
+ (result == OK ||
+ (IsCertificateError(result) && IsCertStatusMinorError(cert_status)))) {
+ TransportSecurityState::PKPStatus pin_validity =
+ transport_security_state_->CheckPublicKeyPins(
+ host_and_port_, server_cert_verify_result_.is_issued_by_known_root,
+ server_cert_verify_result_.public_key_hashes, server_cert_.get(),
+ server_cert_verify_result_.verified_cert.get(),
+ TransportSecurityState::ENABLE_PIN_REPORTS, &pinning_failure_log_);
+ switch (pin_validity) {
+ case TransportSecurityState::PKPStatus::VIOLATED:
+ server_cert_verify_result_.cert_status |=
+ CERT_STATUS_PINNED_KEY_MISSING;
+ result = ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN;
+ break;
+ case TransportSecurityState::PKPStatus::BYPASSED:
+ pkp_bypassed_ = true;
+ // Fall through.
+ case TransportSecurityState::PKPStatus::OK:
+ // Do nothing.
+ break;
}
}
diff --git a/net/socket/ssl_client_socket_unittest.cc b/net/socket/ssl_client_socket_unittest.cc
index 6330774..48758ea 100644
--- a/net/socket/ssl_client_socket_unittest.cc
+++ b/net/socket/ssl_client_socket_unittest.cc
@@ -3316,6 +3316,7 @@
EXPECT_TRUE(sock_->IsConnected());
EXPECT_TRUE(ssl_info.pkp_bypassed);
+ EXPECT_FALSE(ssl_info.cert_status & CERT_STATUS_PINNED_KEY_MISSING);
}
TEST_F(SSLClientSocketTest, PKPEnforced) {
diff --git a/net/spdy/spdy_session.cc b/net/spdy/spdy_session.cc
index 5b4530cc..fc1d94f 100644
--- a/net/spdy/spdy_session.cc
+++ b/net/spdy/spdy_session.cc
@@ -658,12 +658,12 @@
// DISABLE_PIN_REPORTS is set here because this check can fail in
// normal operation without being indicative of a misconfiguration or
// attack. Port is left at 0 as it is never used.
- if (ssl_info.is_issued_by_known_root &&
- !transport_security_state->CheckPublicKeyPins(
+ if (transport_security_state->CheckPublicKeyPins(
HostPortPair(new_hostname, 0), ssl_info.is_issued_by_known_root,
ssl_info.public_key_hashes, ssl_info.unverified_cert.get(),
ssl_info.cert.get(), TransportSecurityState::DISABLE_PIN_REPORTS,
- &pinning_failure_log)) {
+ &pinning_failure_log) ==
+ TransportSecurityState::PKPStatus::VIOLATED) {
return false;
}