summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/net/chrome_fraudulent_certificate_reporter.cc22
-rw-r--r--net/http/transport_security_persister_unittest.cc9
-rw-r--r--net/http/transport_security_state.cc37
-rw-r--r--net/http/transport_security_state.h15
-rw-r--r--net/http/transport_security_state_unittest.cc8
-rw-r--r--net/socket/ssl_client_socket_nss.cc5
-rw-r--r--net/socket/ssl_client_socket_nss.h5
-rw-r--r--net/ssl/ssl_info.cc2
-rw-r--r--net/ssl/ssl_info.h5
9 files changed, 40 insertions, 68 deletions
diff --git a/chrome/browser/net/chrome_fraudulent_certificate_reporter.cc b/chrome/browser/net/chrome_fraudulent_certificate_reporter.cc
index 30fd547..f666c87 100644
--- a/chrome/browser/net/chrome_fraudulent_certificate_reporter.cc
+++ b/chrome/browser/net/chrome_fraudulent_certificate_reporter.cc
@@ -51,27 +51,7 @@ static std::string BuildReport(const std::string& hostname,
for (size_t i = 0; i < pem_encoded_chain.size(); ++i)
*cert_chain += pem_encoded_chain[i];
- for (net::HashValueVector::const_iterator i =
- ssl_info.public_key_hashes.begin(); i !=
- ssl_info.public_key_hashes.end(); ++i) {
- request.add_public_key_hash(i->ToString());
- }
-
- const char* const* required_pins;
- const char* const* excluded_pins;
- if (net::TransportSecurityState::GetPinsForDebugging(
- hostname, &required_pins, &excluded_pins)) {
- for (size_t i = 0; required_pins[i]; i++) {
- net::HashValue hash_value(net::HASH_VALUE_SHA1);
- memcpy(hash_value.data(), required_pins[i], hash_value.size());
- request.add_pin(hash_value.ToString());
- }
- for (size_t i = 0; excluded_pins[i]; i++) {
- net::HashValue hash_value(net::HASH_VALUE_SHA1);
- memcpy(hash_value.data(), excluded_pins[i], hash_value.size());
- request.add_pin("!" + hash_value.ToString());
- }
- }
+ request.add_pin(ssl_info.pinning_failure_log);
std::string out;
request.SerializeToString(&out);
diff --git a/net/http/transport_security_persister_unittest.cc b/net/http/transport_security_persister_unittest.cc
index 114e933..c7a8dc5 100644
--- a/net/http/transport_security_persister_unittest.cc
+++ b/net/http/transport_security_persister_unittest.cc
@@ -168,19 +168,20 @@ TEST_F(TransportSecurityPersisterTest, PublicKeyHashes) {
static const char kTestDomain[] = "example.com";
EXPECT_FALSE(state_.GetDomainState(kTestDomain, false, &domain_state));
net::HashValueVector hashes;
- EXPECT_FALSE(domain_state.CheckPublicKeyPins(hashes));
+ std::string failure_log;
+ EXPECT_FALSE(domain_state.CheckPublicKeyPins(hashes, &failure_log));
net::HashValue sha1(net::HASH_VALUE_SHA1);
memset(sha1.data(), '1', sha1.size());
domain_state.dynamic_spki_hashes.push_back(sha1);
- EXPECT_FALSE(domain_state.CheckPublicKeyPins(hashes));
+ EXPECT_FALSE(domain_state.CheckPublicKeyPins(hashes, &failure_log));
hashes.push_back(sha1);
- EXPECT_TRUE(domain_state.CheckPublicKeyPins(hashes));
+ EXPECT_TRUE(domain_state.CheckPublicKeyPins(hashes, &failure_log));
hashes[0].data()[0] = '2';
- EXPECT_FALSE(domain_state.CheckPublicKeyPins(hashes));
+ EXPECT_FALSE(domain_state.CheckPublicKeyPins(hashes, &failure_log));
const base::Time current_time(base::Time::Now());
const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
diff --git a/net/http/transport_security_state.cc b/net/http/transport_security_state.cc
index 8142e09..1bd55c6 100644
--- a/net/http/transport_security_state.cc
+++ b/net/http/transport_security_state.cc
@@ -718,21 +718,6 @@ bool TransportSecurityState::IsGooglePinnedProperty(const std::string& host,
}
// static
-bool TransportSecurityState::GetPinsForDebugging(
- const std::string& host,
- const char* const** out_required_pins,
- const char* const** out_excluded_pins) {
- const std::string canonicalized_host = CanonicalizeHost(host);
- const struct HSTSPreload* entry =
- GetHSTSPreload(canonicalized_host, kPreloadedSTS, kNumPreloadedSTS);
- if (!entry)
- return false;
- *out_required_pins = entry->pins.required_hashes;
- *out_excluded_pins = entry->pins.excluded_hashes;
- return true;
-}
-
-// static
void TransportSecurityState::ReportUMAOnPinFailure(const std::string& host) {
std::string canonicalized_host = CanonicalizeHost(host);
@@ -860,21 +845,21 @@ TransportSecurityState::DomainState::~DomainState() {
}
bool TransportSecurityState::DomainState::CheckPublicKeyPins(
- const HashValueVector& hashes) const {
+ const HashValueVector& hashes, std::string* failure_log) const {
// Validate that hashes is not empty. By the time this code is called (in
// production), that should never happen, but it's good to be defensive.
// And, hashes *can* be empty in some test scenarios.
if (hashes.empty()) {
- LOG(ERROR) << "Rejecting empty public key chain for public-key-pinned "
- "domain " << domain;
+ *failure_log = "Rejecting empty public key chain for public-key-pinned "
+ "domains: " + domain;
return false;
}
if (HashesIntersect(bad_static_spki_hashes, hashes)) {
- LOG(ERROR) << "Rejecting public key chain for domain " << domain
- << ". Validated chain: " << HashesToBase64String(hashes)
- << ", matches one or more bad hashes: "
- << HashesToBase64String(bad_static_spki_hashes);
+ *failure_log = "Rejecting public key chain for domain " + domain +
+ ". Validated chain: " + HashesToBase64String(hashes) +
+ ", matches one or more bad hashes: " +
+ HashesToBase64String(bad_static_spki_hashes);
return false;
}
@@ -887,10 +872,10 @@ bool TransportSecurityState::DomainState::CheckPublicKeyPins(
return true;
}
- LOG(ERROR) << "Rejecting public key chain for domain " << domain
- << ". Validated chain: " << HashesToBase64String(hashes)
- << ", expected: " << HashesToBase64String(dynamic_spki_hashes)
- << " or: " << HashesToBase64String(static_spki_hashes);
+ *failure_log = "Rejecting public key chain for domain " + domain +
+ ". Validated chain: " + HashesToBase64String(hashes) +
+ ", expected: " + HashesToBase64String(dynamic_spki_hashes) +
+ " or: " + HashesToBase64String(static_spki_hashes);
return false;
}
diff --git a/net/http/transport_security_state.h b/net/http/transport_security_state.h
index 8aaecb69..82a3c45 100644
--- a/net/http/transport_security_state.h
+++ b/net/http/transport_security_state.h
@@ -77,7 +77,8 @@ class NET_EXPORT TransportSecurityState
//
// |bad_static_spki_hashes| contains public keys that we don't want to
// trust.
- bool CheckPublicKeyPins(const HashValueVector& hashes) const;
+ bool CheckPublicKeyPins(const HashValueVector& hashes,
+ std::string* failure_log) const;
// Returns true if any of the HashValueVectors |static_spki_hashes|,
// |bad_static_spki_hashes|, or |dynamic_spki_hashes| contains any
@@ -248,18 +249,6 @@ class NET_EXPORT TransportSecurityState
static bool IsGooglePinnedProperty(const std::string& host,
bool sni_enabled);
- // GetPinsForDebugging finds the preloaded entry for the given host. If none
- // exists, it returns false. Otherwise it returns true and sets |out_pins|
- // and |out_bad_pins| to point to arrays of SHA-1 hashes, each 20 bytes long
- // with a NULL pointer signalling the end of the array, for the required and
- // excluded pins, respectively.
- // This is a temporary debugging measure to check for binary alteration /
- // corruption.
- static bool GetPinsForDebugging(
- const std::string& host,
- const char* const** out_pins,
- const char* const** out_bad_pins);
-
// The maximum number of seconds for which we'll cache an HSTS request.
static const long int kMaxHSTSAgeSecs;
diff --git a/net/http/transport_security_state_unittest.cc b/net/http/transport_security_state_unittest.cc
index c3d15da..dfcd50f 100644
--- a/net/http/transport_security_state_unittest.cc
+++ b/net/http/transport_security_state_unittest.cc
@@ -493,8 +493,9 @@ TEST_F(TransportSecurityStateTest, BuiltinCertPins) {
EXPECT_TRUE(HasPublicKeyPins("chrome.google.com"));
HashValueVector hashes;
+ std::string failure_log;
// Checks that a built-in list does exist.
- EXPECT_FALSE(domain_state.CheckPublicKeyPins(hashes));
+ EXPECT_FALSE(domain_state.CheckPublicKeyPins(hashes, &failure_log));
EXPECT_FALSE(HasPublicKeyPins("www.paypal.com"));
EXPECT_TRUE(HasPublicKeyPins("docs.google.com"));
@@ -579,8 +580,9 @@ TEST_F(TransportSecurityStateTest, PinValidationWithoutRejectedCerts) {
EXPECT_TRUE(state.GetDomainState("blog.torproject.org", true, &domain_state));
EXPECT_TRUE(domain_state.HasPublicKeyPins());
- EXPECT_TRUE(domain_state.CheckPublicKeyPins(good_hashes));
- EXPECT_FALSE(domain_state.CheckPublicKeyPins(bad_hashes));
+ std::string failure_log;
+ EXPECT_TRUE(domain_state.CheckPublicKeyPins(good_hashes, &failure_log));
+ EXPECT_FALSE(domain_state.CheckPublicKeyPins(bad_hashes, &failure_log));
}
TEST_F(TransportSecurityStateTest, OptionalHSTSCertPins) {
diff --git a/net/socket/ssl_client_socket_nss.cc b/net/socket/ssl_client_socket_nss.cc
index b3c8e0e..fd7e86c 100644
--- a/net/socket/ssl_client_socket_nss.cc
+++ b/net/socket/ssl_client_socket_nss.cc
@@ -2859,6 +2859,7 @@ bool SSLClientSocketNSS::GetSSLInfo(SSLInfo* ssl_info) {
ssl_info->client_cert_sent =
ssl_config_.send_client_cert && ssl_config_.client_cert.get();
ssl_info->channel_id_sent = WasChannelIDSent();
+ ssl_info->pinning_failure_log = pinning_failure_log_;
PRUint16 cipher_suite = SSLConnectionStatusToCipherSuite(
core_->state().ssl_connection_status);
@@ -3501,7 +3502,9 @@ int SSLClientSocketNSS::DoVerifyCertComplete(int result) {
&domain_state) &&
domain_state.HasPublicKeyPins()) {
if (!domain_state.CheckPublicKeyPins(
- server_cert_verify_result_.public_key_hashes)) {
+ server_cert_verify_result_.public_key_hashes,
+ &pinning_failure_log_)) {
+ LOG(ERROR) << pinning_failure_log_;
result = ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN;
UMA_HISTOGRAM_BOOLEAN("Net.PublicKeyPinSuccess", false);
TransportSecurityState::ReportUMAOnPinFailure(host);
diff --git a/net/socket/ssl_client_socket_nss.h b/net/socket/ssl_client_socket_nss.h
index acd5d37..853daa4 100644
--- a/net/socket/ssl_client_socket_nss.h
+++ b/net/socket/ssl_client_socket_nss.h
@@ -201,6 +201,11 @@ class SSLClientSocketNSS : public SSLClientSocket {
TransportSecurityState* transport_security_state_;
+ // pinning_failure_log contains a message produced by
+ // TransportSecurityState::DomainState::CheckPublicKeyPins in the event of a
+ // pinning failure. It is a (somewhat) human-readable string.
+ std::string pinning_failure_log_;
+
// The following two variables are added for debugging bug 65948. Will
// remove this code after fixing bug 65948.
// Added the following code Debugging in release mode.
diff --git a/net/ssl/ssl_info.cc b/net/ssl/ssl_info.cc
index 77ddb62..d2973d2 100644
--- a/net/ssl/ssl_info.cc
+++ b/net/ssl/ssl_info.cc
@@ -33,6 +33,7 @@ SSLInfo& SSLInfo::operator=(const SSLInfo& info) {
handshake_type = info.handshake_type;
public_key_hashes = info.public_key_hashes;
signed_certificate_timestamps = info.signed_certificate_timestamps;
+ pinning_failure_log = info.pinning_failure_log;
return *this;
}
@@ -48,6 +49,7 @@ void SSLInfo::Reset() {
handshake_type = HANDSHAKE_UNKNOWN;
public_key_hashes.clear();
signed_certificate_timestamps.clear();
+ pinning_failure_log.clear();
}
void SSLInfo::SetCertError(int error) {
diff --git a/net/ssl/ssl_info.h b/net/ssl/ssl_info.h
index 00a8815..154c4a0 100644
--- a/net/ssl/ssl_info.h
+++ b/net/ssl/ssl_info.h
@@ -80,6 +80,11 @@ class NET_EXPORT SSLInfo {
// each certificate in the chain.
HashValueVector public_key_hashes;
+ // pinning_failure_log contains a message produced by
+ // TransportSecurityState::DomainState::CheckPublicKeyPins in the event of a
+ // pinning failure. It is a (somewhat) human-readable string.
+ std::string pinning_failure_log;
+
// List of SignedCertificateTimestamps and their corresponding validation
// status.
SignedCertificateTimestampAndStatusList signed_certificate_timestamps;