Commit 7c433da0 authored by Mohamed Amir Yosef's avatar Mohamed Amir Yosef Committed by Commit Bot

[Passwords] Introduce GaiaIdHash

This CL introduces the GaiaIdHash class. Follow up CLs will make use of
this class.

Bug: 1032992
Change-Id: Ic42333864260e22fb2fcd7aadbf8beb0c38dc95c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2126997
Commit-Queue: Mohamed Amir Yosef <mamir@chromium.org>
Reviewed-by: default avatarMarc Treib <treib@chromium.org>
Cr-Commit-Position: refs/heads/master@{#754874}
parent dcbe49dc
...@@ -98,6 +98,8 @@ jumbo_static_library("browser") { ...@@ -98,6 +98,8 @@ jumbo_static_library("browser") {
"form_saver_impl.cc", "form_saver_impl.cc",
"form_saver_impl.h", "form_saver_impl.h",
"form_submission_observer.h", "form_submission_observer.h",
"gaia_id_hash.cc",
"gaia_id_hash.h",
"generation/password_requirements_spec_fetcher.h", "generation/password_requirements_spec_fetcher.h",
"generation/password_requirements_spec_fetcher_impl.cc", "generation/password_requirements_spec_fetcher_impl.cc",
"generation/password_requirements_spec_fetcher_impl.h", "generation/password_requirements_spec_fetcher_impl.h",
...@@ -531,6 +533,7 @@ source_set("unit_tests") { ...@@ -531,6 +533,7 @@ source_set("unit_tests") {
"field_info_table_unittest.cc", "field_info_table_unittest.cc",
"form_fetcher_impl_unittest.cc", "form_fetcher_impl_unittest.cc",
"form_saver_impl_unittest.cc", "form_saver_impl_unittest.cc",
"gaia_id_hash_unittest.cc",
"generation/password_generator_unittest.cc", "generation/password_generator_unittest.cc",
"generation/password_requirements_spec_fetcher_unittest.cc", "generation/password_requirements_spec_fetcher_unittest.cc",
"http_auth_manager_unittest.cc", "http_auth_manager_unittest.cc",
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/password_manager/core/browser/gaia_id_hash.h"
#include "base/base64.h"
#include "crypto/sha2.h"
namespace password_manager {
// static
GaiaIdHash GaiaIdHash::FromGaiaId(const std::string& gaia_id) {
return FromBinary(crypto::SHA256HashString(gaia_id));
}
// static
GaiaIdHash GaiaIdHash::FromBinary(const std::string& gaia_id_hash) {
return GaiaIdHash(gaia_id_hash);
}
// static
GaiaIdHash GaiaIdHash::FromBase64(const std::string& gaia_id_base64_hash) {
std::string gaia_id_hash;
base::Base64Decode(gaia_id_base64_hash, &gaia_id_hash);
return FromBinary(gaia_id_hash);
}
GaiaIdHash::GaiaIdHash() = default;
GaiaIdHash::GaiaIdHash(const GaiaIdHash& other) = default;
GaiaIdHash::GaiaIdHash(GaiaIdHash&& other) = default;
GaiaIdHash::~GaiaIdHash() = default;
GaiaIdHash::GaiaIdHash(const std::string& gaia_id_hash)
: gaia_id_hash_(gaia_id_hash) {}
std::string GaiaIdHash::ToBinary() const {
return gaia_id_hash_;
}
std::string GaiaIdHash::ToBase64() const {
std::string gaia_id_base64_hash;
base::Base64Encode(gaia_id_hash_, &gaia_id_base64_hash);
return gaia_id_base64_hash;
}
bool GaiaIdHash::IsValid() const {
return gaia_id_hash_.size() == crypto::kSHA256Length;
}
bool operator==(const GaiaIdHash& lhs, const GaiaIdHash& rhs) {
return lhs.gaia_id_hash_ == rhs.gaia_id_hash_;
}
bool operator!=(const GaiaIdHash& lhs, const GaiaIdHash& rhs) {
return !(lhs == rhs);
}
} // namespace password_manager
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_GAIA_ID_HASH_H_
#define COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_GAIA_ID_HASH_H_
#include <string>
namespace password_manager {
// Represents the hash of the Gaia ID of a signed-in user. This is useful for
// storing Gaia-keyed information without storing sensitive information (like
// the email address).
class GaiaIdHash {
public:
static GaiaIdHash FromGaiaId(const std::string& gaia_id);
// |gaia_id_hash| is a string representing the binary hash of the gaia id. If
// the input isn't of length crypto::kSHA256Length, it returns an invalid
// GaiaIdHash object.
static GaiaIdHash FromBinary(const std::string& gaia_id_hash);
// If |gaia_id_base64_hash| isn't well-formed Base64 string, or doesn't decode
// to a hash of the correct length, it returns an invalid GaiaIdHash object.
static GaiaIdHash FromBase64(const std::string& gaia_id_base64_hash);
GaiaIdHash();
GaiaIdHash(const GaiaIdHash& other);
GaiaIdHash(GaiaIdHash&& other);
~GaiaIdHash();
std::string ToBinary() const;
std::string ToBase64() const;
bool IsValid() const;
friend bool operator==(const GaiaIdHash& lhs, const GaiaIdHash& rhs);
friend bool operator!=(const GaiaIdHash& lhs, const GaiaIdHash& rhs);
private:
explicit GaiaIdHash(const std::string& gaia_id_hash);
const std::string gaia_id_hash_;
};
} // namespace password_manager
#endif // COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_GAIA_ID_HASH_H_
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/password_manager/core/browser/gaia_id_hash.h"
#include "base/base64.h"
#include "crypto/sha2.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace password_manager {
TEST(GaiaIdHashTest, ShouldBeDeterministic) {
const std::string gaia_id = "user_gaia_id";
GaiaIdHash gaia_id_hash1 = GaiaIdHash::FromGaiaId(gaia_id);
GaiaIdHash gaia_id_hash2 = GaiaIdHash::FromGaiaId(gaia_id);
EXPECT_EQ(gaia_id_hash1.ToBinary(), gaia_id_hash2.ToBinary());
EXPECT_EQ(gaia_id_hash1.ToBase64(), gaia_id_hash2.ToBase64());
EXPECT_EQ(gaia_id_hash1, gaia_id_hash2);
}
TEST(GaiaIdHashTest, ShouldHash) {
const std::string gaia_id = "user_gaia_id";
const std::string gaia_id_hash = crypto::SHA256HashString(gaia_id);
std::string gaia_id_base64_hash;
base::Base64Encode(gaia_id_hash, &gaia_id_base64_hash);
GaiaIdHash hash = GaiaIdHash::FromGaiaId(gaia_id);
EXPECT_EQ(gaia_id_hash, hash.ToBinary());
EXPECT_EQ(gaia_id_base64_hash, hash.ToBase64());
}
TEST(GaiaIdHashTest, ShouldBase64EncodeDecode) {
const std::string gaia_id = "user_gaia_id";
GaiaIdHash hash1 = GaiaIdHash::FromGaiaId(gaia_id);
GaiaIdHash hash2 = GaiaIdHash::FromBase64(hash1.ToBase64());
EXPECT_EQ(hash1, hash2);
}
TEST(GaiaIdHashTest, ShouldBeInvalid) {
// Hash must be of length crypto::kSHA256Length.
GaiaIdHash hash1 = GaiaIdHash::FromBinary("too_short_hash");
EXPECT_FALSE(hash1.IsValid());
GaiaIdHash hash2 = GaiaIdHash::FromBase64("invalid_base64");
EXPECT_FALSE(hash2.IsValid());
}
} // namespace password_manager
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment