Index: net/base/transport_security_state.cc |
=================================================================== |
--- net/base/transport_security_state.cc (revision 142157) |
+++ net/base/transport_security_state.cc (working copy) |
@@ -33,6 +33,7 @@ |
#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" |
@@ -218,58 +219,67 @@ |
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, |
- SHA1Fingerprint* out) { |
+ Fingerprint* out) { |
StringPair slash = Split(Strip(value), '/'); |
- if (slash.first != "sha1") |
+ |
+ if (slash.first == "sha1") |
+ out->tag = FINGERPRINT_SHA1; |
+ else if (slash.first == "sha256") |
+ out->tag = FINGERPRINT_SHA256; |
+ else |
return false; |
std::string decoded; |
if (!base::Base64Decode(slash.second, &decoded) || |
- decoded.size() != arraysize(out->data)) { |
+ decoded.size() != out->size()) { |
return false; |
} |
- memcpy(out->data, decoded.data(), arraysize(out->data)); |
+ memcpy(out->data(), decoded.data(), out->size()); |
return true; |
} |
static bool ParseAndAppendPin(const std::string& value, |
- FingerprintVector* 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. TODO(palmer): Support |
- // SHA256. |
+ // characters; 32 bytes base64'd is 44 characters. |
size_t size = value.size(); |
if (size != 30 || value[0] != '"' || value[size - 1] != '"') |
return false; |
std::string unquoted = HttpUtil::Unquote(value); |
std::string decoded; |
- SHA1Fingerprint fp; |
+ Fingerprint fp; |
- if (!base::Base64Decode(unquoted, &decoded) || |
- decoded.size() != arraysize(fp.data)) { |
+ // 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)) |
return false; |
- } |
- memcpy(fp.data, decoded.data(), arraysize(fp.data)); |
+ if (decoded.size() == 20) |
+ fp.tag = FINGERPRINT_SHA1; |
+ else if (decoded.size() == 32) |
+ fp.tag = FINGERPRINT_SHA256; |
+ else |
+ return false; |
+ |
+ memcpy(fp.data(), decoded.data(), fp.size()); |
fingerprints->push_back(fp); |
return true; |
} |
struct FingerprintsEqualPredicate { |
- explicit FingerprintsEqualPredicate(const SHA1Fingerprint& fingerprint) : |
+ explicit FingerprintsEqualPredicate(const Fingerprint& fingerprint) : |
fingerprint_(fingerprint) {} |
- bool operator()(const SHA1Fingerprint& other) const { |
+ bool operator()(const Fingerprint& other) const { |
return fingerprint_.Equals(other); |
} |
- const SHA1Fingerprint& fingerprint_; |
+ const Fingerprint& fingerprint_; |
}; |
// Returns true iff there is an item in |pins| which is not present in |
@@ -349,11 +359,10 @@ |
if (max_age_candidate > kMaxHSTSAgeSecs) |
max_age_candidate = kMaxHSTSAgeSecs; |
parsed_max_age = true; |
- } else if (LowerCaseEqualsASCII(equals.first, "pin-sha1")) { |
+ } else if (LowerCaseEqualsASCII(equals.first, "pin-sha1") || |
+ LowerCaseEqualsASCII(equals.first, "pin-sha256")) { |
if (!ParseAndAppendPin(equals.second, &pins)) |
return false; |
- } else if (LowerCaseEqualsASCII(equals.first, "pin-sha256")) { |
- // TODO(palmer) |
} else { |
// Silently ignore unknown directives for forward compatibility. |
} |
@@ -477,7 +486,7 @@ |
static bool AddHash(const std::string& type_and_base64, |
FingerprintVector* out) { |
- SHA1Fingerprint hash; |
+ Fingerprint hash; |
if (!TransportSecurityState::ParsePin(type_and_base64, &hash)) |
return false; |
@@ -743,8 +752,8 @@ |
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), |
- sizeof(i->data)); |
+ const std::string hash_str(reinterpret_cast<const char*>(i->data()), |
+ i->size()); |
base::Base64Encode(hash_str, &s); |
hashes_strs.push_back(s); |
} |