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

Unified Diff: net/base/transport_security_state.cc

Issue 10836150: Revert 150375 - Implement SHA-256 fingerprint support (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 4 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/base/transport_security_state.h ('k') | net/base/transport_security_state_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/base/transport_security_state.cc
===================================================================
--- net/base/transport_security_state.cc (revision 150506)
+++ net/base/transport_security_state.cc (working copy)
@@ -33,7 +33,6 @@
#include "googleurl/src/gurl.h"
#include "net/base/dns_util.h"
#include "net/base/ssl_info.h"
-#include "net/base/x509_cert_types.h"
#include "net/base/x509_certificate.h"
#include "net/http/http_util.h"
@@ -219,78 +218,69 @@
return pair;
}
+// TODO(palmer): Support both sha256 and sha1. This will require additional
+// infrastructure code changes and can come in a later patch.
+//
// static
bool TransportSecurityState::ParsePin(const std::string& value,
- HashValue* out) {
+ SHA1Fingerprint* out) {
StringPair slash = Split(Strip(value), '/');
-
- if (slash.first == "sha1")
- out->tag = HASH_VALUE_SHA1;
- else if (slash.first == "sha256")
- out->tag = HASH_VALUE_SHA256;
- else
+ if (slash.first != "sha1")
return false;
std::string decoded;
if (!base::Base64Decode(slash.second, &decoded) ||
- decoded.size() != out->size()) {
+ decoded.size() != arraysize(out->data)) {
return false;
}
- memcpy(out->data(), decoded.data(), out->size());
+ memcpy(out->data, decoded.data(), arraysize(out->data));
return true;
}
static bool ParseAndAppendPin(const std::string& value,
- HashValueVector* fingerprints) {
+ FingerprintVector* fingerprints) {
// The base64'd fingerprint MUST be a quoted-string. 20 bytes base64'd is 28
- // characters; 32 bytes base64'd is 44 characters.
+ // characters; 32 bytes base64'd is 44 characters. TODO(palmer): Support
+ // SHA256.
size_t size = value.size();
- if ((size != 30 && size != 46) || value[0] != '"' || value[size - 1] != '"')
+ if (size != 30 || value[0] != '"' || value[size - 1] != '"')
return false;
std::string unquoted = HttpUtil::Unquote(value);
std::string decoded;
- HashValue fp;
+ SHA1Fingerprint fp;
- // This code has to assume that 32 bytes is SHA-256 and 20 bytes is SHA-1.
- // Currently, those are the only two possibilities, so the assumption is
- // valid.
- if (!base::Base64Decode(unquoted, &decoded))
+ if (!base::Base64Decode(unquoted, &decoded) ||
+ decoded.size() != arraysize(fp.data)) {
return false;
+ }
- if (decoded.size() == 20)
- fp.tag = HASH_VALUE_SHA1;
- else if (decoded.size() == 32)
- fp.tag = HASH_VALUE_SHA256;
- else
- return false;
-
- memcpy(fp.data(), decoded.data(), fp.size());
+ memcpy(fp.data, decoded.data(), arraysize(fp.data));
fingerprints->push_back(fp);
return true;
}
-struct HashValuesEqualPredicate {
- explicit HashValuesEqualPredicate(const HashValue& fingerprint) :
+struct FingerprintsEqualPredicate {
+ explicit FingerprintsEqualPredicate(const SHA1Fingerprint& fingerprint) :
fingerprint_(fingerprint) {}
- bool operator()(const HashValue& other) const {
+ bool operator()(const SHA1Fingerprint& other) const {
return fingerprint_.Equals(other);
}
- const HashValue& fingerprint_;
+ const SHA1Fingerprint& fingerprint_;
};
// Returns true iff there is an item in |pins| which is not present in
// |from_cert_chain|. Such an SPKI hash is called a "backup pin".
-static bool IsBackupPinPresent(const HashValueVector& pins,
- const HashValueVector& from_cert_chain) {
- for (HashValueVector::const_iterator
+static bool IsBackupPinPresent(const FingerprintVector& pins,
+ const FingerprintVector& from_cert_chain) {
+ for (FingerprintVector::const_iterator
i = pins.begin(); i != pins.end(); ++i) {
- HashValueVector::const_iterator j =
+ FingerprintVector::const_iterator j =
std::find_if(from_cert_chain.begin(), from_cert_chain.end(),
- HashValuesEqualPredicate(*i));
+ FingerprintsEqualPredicate(*i));
if (j == from_cert_chain.end())
return true;
}
@@ -298,12 +288,12 @@
return false;
}
-static bool HashesIntersect(const HashValueVector& a,
- const HashValueVector& b) {
- for (HashValueVector::const_iterator
+static bool HashesIntersect(const FingerprintVector& a,
+ const FingerprintVector& b) {
+ for (FingerprintVector::const_iterator
i = a.begin(); i != a.end(); ++i) {
- HashValueVector::const_iterator j =
- std::find_if(b.begin(), b.end(), HashValuesEqualPredicate(*i));
+ FingerprintVector::const_iterator j =
+ std::find_if(b.begin(), b.end(), FingerprintsEqualPredicate(*i));
if (j != b.end())
return true;
}
@@ -316,30 +306,17 @@
// backup pin is a pin intended for disaster recovery, not day-to-day use, and
// thus must be absent from the certificate chain. The Public-Key-Pins header
// specification requires both.
-static bool IsPinListValid(const HashValueVector& pins,
+static bool IsPinListValid(const FingerprintVector& pins,
const SSLInfo& ssl_info) {
- // Fast fail: 1 live + 1 backup = at least 2 pins. (Check for actual
- // liveness and backupness below.)
if (pins.size() < 2)
return false;
- // Site operators might pin a key using either the SHA-1 or SHA-256 hash
- // of the SPKI. So check for success using either hash function.
- //
- // TODO(palmer): Make this generic so that it works regardless of what
- // HashValueTags are defined in the future.
- const HashValueVector& from_cert_chain_sha1 =
- ssl_info.public_key_hashes[HASH_VALUE_SHA1];
- const HashValueVector& from_cert_chain_sha256 =
- ssl_info.public_key_hashes[HASH_VALUE_SHA256];
-
- if (from_cert_chain_sha1.empty() && from_cert_chain_sha256.empty())
+ const FingerprintVector& from_cert_chain = ssl_info.public_key_hashes;
+ if (from_cert_chain.empty())
return false;
- return (IsBackupPinPresent(pins, from_cert_chain_sha1) ||
- IsBackupPinPresent(pins, from_cert_chain_sha256)) &&
- (HashesIntersect(pins, from_cert_chain_sha1) ||
- HashesIntersect(pins, from_cert_chain_sha256));
+ return IsBackupPinPresent(pins, from_cert_chain) &&
+ HashesIntersect(pins, from_cert_chain);
}
// "Public-Key-Pins" ":"
@@ -351,7 +328,7 @@
const SSLInfo& ssl_info) {
bool parsed_max_age = false;
int max_age_candidate = 0;
- HashValueVector pins;
+ FingerprintVector pins;
std::string source = value;
@@ -372,10 +349,11 @@
if (max_age_candidate > kMaxHSTSAgeSecs)
max_age_candidate = kMaxHSTSAgeSecs;
parsed_max_age = true;
- } else if (LowerCaseEqualsASCII(equals.first, "pin-sha1") ||
- LowerCaseEqualsASCII(equals.first, "pin-sha256")) {
+ } else if (LowerCaseEqualsASCII(equals.first, "pin-sha1")) {
if (!ParseAndAppendPin(equals.second, &pins))
return false;
+ } else if (LowerCaseEqualsASCII(equals.first, "pin-sha256")) {
+ // TODO(palmer)
} else {
// Silently ignore unknown directives for forward compatibility.
}
@@ -391,7 +369,7 @@
dynamic_spki_hashes.clear();
if (max_age_candidate > 0) {
- for (HashValueVector::const_iterator i = pins.begin();
+ for (FingerprintVector::const_iterator i = pins.begin();
i != pins.end(); ++i) {
dynamic_spki_hashes.push_back(*i);
}
@@ -498,8 +476,8 @@
}
static bool AddHash(const std::string& type_and_base64,
- HashValueVector* out) {
- HashValue hash;
+ FingerprintVector* out) {
+ SHA1Fingerprint hash;
if (!TransportSecurityState::ParsePin(type_and_base64, &hash))
return false;
@@ -765,13 +743,13 @@
}
static std::string HashesToBase64String(
- const HashValueVector& hashes) {
+ const FingerprintVector& hashes) {
std::vector<std::string> hashes_strs;
- for (HashValueVector::const_iterator
+ for (FingerprintVector::const_iterator
i = hashes.begin(); i != hashes.end(); i++) {
std::string s;
- const std::string hash_str(reinterpret_cast<const char*>(i->data()),
- i->size());
+ const std::string hash_str(reinterpret_cast<const char*>(i->data),
+ sizeof(i->data));
base::Base64Encode(hash_str, &s);
hashes_strs.push_back(s);
}
@@ -789,43 +767,24 @@
}
bool TransportSecurityState::DomainState::IsChainOfPublicKeysPermitted(
- const std::vector<HashValueVector>& hashes) 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.
- bool empty = true;
- for (size_t i = 0; i < hashes.size(); ++i) {
- if (hashes[i].size()) {
- empty = false;
- break;
- }
- }
- if (empty) {
- LOG(ERROR) << "Rejecting empty certificate chain for public key pinned "
- "domain " << domain;
+ const FingerprintVector& hashes) const {
+ 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);
return false;
}
- for (size_t i = 0; i < hashes.size(); ++i) {
- if (HashesIntersect(bad_static_spki_hashes, hashes[i])) {
- LOG(ERROR) << "Rejecting public key chain for domain " << domain
- << ". Validated chain: " << HashesToBase64String(hashes[i])
- << ", matches one or more bad hashes: "
- << HashesToBase64String(bad_static_spki_hashes);
- return false;
- }
+ if (!(dynamic_spki_hashes.empty() && static_spki_hashes.empty()) &&
+ !HashesIntersect(dynamic_spki_hashes, hashes) &&
+ !HashesIntersect(static_spki_hashes, hashes)) {
+ LOG(ERROR) << "Rejecting public key chain for domain " << domain
+ << ". Validated chain: " << HashesToBase64String(hashes)
+ << ", expected: " << HashesToBase64String(dynamic_spki_hashes)
+ << " or: " << HashesToBase64String(static_spki_hashes);
- if (!(dynamic_spki_hashes.empty() && static_spki_hashes.empty()) &&
- hashes[i].size() > 0 &&
- !HashesIntersect(dynamic_spki_hashes, hashes[i]) &&
- !HashesIntersect(static_spki_hashes, hashes[i])) {
- LOG(ERROR) << "Rejecting public key chain for domain " << domain
- << ". Validated chain: " << HashesToBase64String(hashes[i])
- << ", expected: " << HashesToBase64String(dynamic_spki_hashes)
- << " or: " << HashesToBase64String(static_spki_hashes);
-
- return false;
- }
+ return false;
}
return true;
« no previous file with comments | « net/base/transport_security_state.h ('k') | net/base/transport_security_state_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698