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

Unified Diff: chrome/browser/prefs/pref_hash_calculator.cc

Issue 110523006: Fix the hash generation algorithm to be consistent with prior implementation. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Validates -> Verifies. Created 6 years, 11 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
Index: chrome/browser/prefs/pref_hash_calculator.cc
diff --git a/chrome/browser/prefs/pref_hash_calculator.cc b/chrome/browser/prefs/pref_hash_calculator.cc
index 4a787a8a1abb699d8a3447c3a34caf3eee638bb8..e965d2ac31387b26747cf23c7a9db13e0bf06650 100644
--- a/chrome/browser/prefs/pref_hash_calculator.cc
+++ b/chrome/browser/prefs/pref_hash_calculator.cc
@@ -16,6 +16,32 @@
namespace {
+// Calculates an HMAC of |message| using |key|, encoded as a hexadecimal string.
+std::string GetDigestString(const std::string& key,
+ const std::string& message) {
+ crypto::HMAC hmac(crypto::HMAC::SHA256);
+ std::vector<uint8> digest(hmac.DigestLength());
+ if (!hmac.Init(key) || !hmac.Sign(message, &digest[0], digest.size())) {
+ NOTREACHED();
+ return std::string();
+ }
+ return base::HexEncode(digest.data(), digest.size());
+}
+
+// Verifies that |digest_string| is a valid HMAC of |message| using |key|.
+// |digest_string| must be encoded as a hexadecimal string.
+bool VerifyDigestString(const std::string& key,
+ const std::string& message,
+ const std::string& digest_string) {
+ crypto::HMAC hmac(crypto::HMAC::SHA256);
+ std::vector<uint8> digest;
+ return base::HexStringToBytes(digest_string, &digest) &&
+ hmac.Init(key) &&
+ hmac.Verify(message,
+ base::StringPiece(reinterpret_cast<char*>(&digest[0]),
+ digest.size()));
+}
+
// Renders |value| as a string. |value| may be NULL, in which case the result
// is an empty string.
std::string ValueAsString(const base::Value* value) {
@@ -38,53 +64,63 @@ std::string ValueAsString(const base::Value* value) {
}
// Common helper for all hash algorithms.
-std::string CalculateFromValueAndComponents(
- const std::string& seed,
+std::string GetMessageFromValueAndComponents(
const base::Value* value,
const std::vector<std::string>& extra_components) {
- static const size_t kSHA256DigestSize = 32;
+ return JoinString(extra_components, "") + ValueAsString(value);
+}
- std::string message = JoinString(extra_components, "") + ValueAsString(value);
- crypto::HMAC hmac(crypto::HMAC::SHA256);
- unsigned char digest[kSHA256DigestSize];
- if (!hmac.Init(seed) || !hmac.Sign(message, digest, arraysize(digest))) {
- NOTREACHED();
+// Generates a device ID based on the input device ID. The derived device ID has
+// no useful properties beyond those of the input device ID except that it is
+// consistent with previous implementations.
+std::string GenerateDeviceIdLikePrefMetricsServiceDid(
+ const std::string& original_device_id) {
+ if (original_device_id.empty())
return std::string();
- }
+ return StringToLowerASCII(
+ GetDigestString(original_device_id, "PrefMetricsService"));
+}
- return base::HexEncode(digest, arraysize(digest));
+// Verifies a hash using a deprecated hash algorithm. For validating old
+// hashes during migration.
+bool VerifyLegacyHash(const std::string& seed,
+ const base::Value* value,
+ const std::string& digest_string) {
+ return VerifyDigestString(
+ seed,
+ GetMessageFromValueAndComponents(value, std::vector<std::string>()),
+ digest_string);
}
} // namespace
PrefHashCalculator::PrefHashCalculator(const std::string& seed,
const std::string& device_id)
- : seed_(seed), device_id_(device_id) {}
+ : seed_(seed),
+ device_id_(GenerateDeviceIdLikePrefMetricsServiceDid(device_id)) {}
std::string PrefHashCalculator::Calculate(const std::string& path,
const base::Value* value) const {
- std::vector<std::string> components;
- if (!device_id_.empty())
- components.push_back(device_id_);
- components.push_back(path);
- return CalculateFromValueAndComponents(seed_, value, components);
+ return GetDigestString(seed_, GetMessage(path, value));
}
PrefHashCalculator::ValidationResult PrefHashCalculator::Validate(
const std::string& path,
const base::Value* value,
- const std::string& hash) const {
- if (hash == Calculate(path, value))
+ const std::string& digest_string) const {
+ if (VerifyDigestString(seed_, GetMessage(path, value), digest_string))
return VALID;
- if (hash == CalculateLegacyHash(path, value))
+ if (VerifyLegacyHash(seed_, value, digest_string))
Ryan Sleevi 2014/01/10 19:24:52 There's a slight cryptographic risk in that you're
return VALID_LEGACY;
return INVALID;
}
-std::string PrefHashCalculator::CalculateLegacyHash(
- const std::string& path, const base::Value* value) const {
- return CalculateFromValueAndComponents(seed_,
- value,
- std::vector<std::string>());
+std::string PrefHashCalculator::GetMessage(const std::string& path,
+ const base::Value* value) const {
+ std::vector<std::string> components;
+ if (!device_id_.empty())
+ components.push_back(device_id_);
+ components.push_back(path);
+ return GetMessageFromValueAndComponents(value, components);
}

Powered by Google App Engine
This is Rietveld 408576698