Commit afe8f695 authored by Vasilii Sukhanov's avatar Vasilii Sukhanov Committed by Commit Bot

Write a helper for preparing the leak detection data asynchronously.

Bug: 986298
Change-Id: Ia6950462efa1ed9128892059abca965fb9aeb86a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1751725
Commit-Queue: Vasilii Sukhanov <vasilii@chromium.org>
Reviewed-by: default avatarIoana Pandele <ioanap@chromium.org>
Cr-Commit-Position: refs/heads/master@{#686499}
parent d980ff89
......@@ -24,7 +24,7 @@ std::string CanonicalizeUsername(base::StringPiece username);
std::string HashUsername(base::StringPiece canonicalized_username);
// Bucketizes |canonicalized_username| by hashing it and returning a prefix of
// 24 bits.
// |kUsernameHashPrefixLength| bits.
std::string BucketizeUsername(base::StringPiece canonicalized_username);
// Produces the username/password pair hash using scrypt algorithm.
......
......@@ -8,15 +8,30 @@
#include "base/containers/span.h"
#include "base/strings/string_number_conversions.h"
#include "base/task/post_task.h"
#include "components/password_manager/core/browser/leak_detection/encryption_utils.h"
#include "components/password_manager/core/browser/leak_detection/leak_detection_api.pb.h"
#include "components/password_manager/core/browser/leak_detection/single_lookup_response.h"
namespace password_manager {
namespace {
using google::internal::identity::passwords::leak::check::v1::
LookupSingleLeakRequest;
// Despite the function is short, it executes long. That's why it should be done
// asynchronously.
LookupSingleLeakData PrepareLookupSingleLeakData(const std::string& username,
const std::string& password) {
LookupSingleLeakData data;
data.username_hash_prefix = BucketizeUsername(CanonicalizeUsername(username));
data.encrypted_payload = CipherEncrypt(
ScryptHashUsernameAndPassword(username, password), &data.encryption_key);
return data;
}
} // namespace
LookupSingleLeakRequest MakeLookupSingleLeakRequest(
base::StringPiece username,
base::StringPiece password) {
......@@ -38,6 +53,17 @@ LookupSingleLeakRequest MakeLookupSingleLeakRequest(
return request;
}
void PrepareSingleLeakRequestData(const std::string& username,
const std::string& password,
SingleLeakRequestDataCallback callback) {
base::PostTaskAndReplyWithResult(
FROM_HERE,
{base::ThreadPool(), base::TaskPriority::USER_VISIBLE,
base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
base::BindOnce(&PrepareLookupSingleLeakData, username, password),
std::move(callback));
}
bool ParseLookupSingleLeakResponse(const SingleLookupResponse& response) {
// TODO(crbug.com/086298): Implement decrypting the response and checking
// whether the credential was actually leaked.
......
......@@ -5,6 +5,7 @@
#ifndef COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_LEAK_DETECTION_LEAK_DETECTION_REQUEST_UTILS_H_
#define COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_LEAK_DETECTION_LEAK_DETECTION_REQUEST_UTILS_H_
#include "base/callback.h"
#include "base/strings/string_piece_forward.h"
namespace google {
......@@ -27,12 +28,38 @@ namespace password_manager {
struct SingleLookupResponse;
// Stores all the data needed for one credential lookup.
struct LookupSingleLeakData {
LookupSingleLeakData() = default;
LookupSingleLeakData(LookupSingleLeakData&& other) = default;
LookupSingleLeakData& operator=(LookupSingleLeakData&& other) = default;
~LookupSingleLeakData() = default;
LookupSingleLeakData(const LookupSingleLeakData&) = delete;
LookupSingleLeakData& operator=(const LookupSingleLeakData&) = delete;
std::string username_hash_prefix;
std::string encrypted_payload;
std::string encryption_key;
};
using SingleLeakRequestDataCallback =
base::OnceCallback<void(LookupSingleLeakData)>;
// Constructs a LookupSingleLeakRequest from the provided |username| and
// |password|.
google::internal::identity::passwords::leak::check::v1::LookupSingleLeakRequest
MakeLookupSingleLeakRequest(base::StringPiece username,
base::StringPiece password);
// Asynchronously creates a data payload for single credential check.
// Callback is invoked on the calling thread with the protobuf and the
// encryption key used.
void PrepareSingleLeakRequestData(const std::string& username,
const std::string& password,
SingleLeakRequestDataCallback callback);
// Processes the provided |response| and returns whether the relevant credential
// was leaked.
bool ParseLookupSingleLeakResponse(const SingleLookupResponse& response);
......
......@@ -5,12 +5,17 @@
#include "components/password_manager/core/browser/leak_detection/leak_detection_request_utils.h"
#include "base/strings/string_piece.h"
#include "base/test/mock_callback.h"
#include "base/test/scoped_task_environment.h"
#include "components/password_manager/core/browser/leak_detection/leak_detection_api.pb.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace password_manager {
using ::testing::ElementsAre;
using ::testing::Field;
TEST(LeakDetectionRequestUtils, MakeLookupSingleLeakRequest) {
// Derived from test case used by the server-side implementation:
// go/passwords-leak-test
......@@ -19,4 +24,19 @@ TEST(LeakDetectionRequestUtils, MakeLookupSingleLeakRequest) {
::testing::ElementsAreArray({0x3D, 0x70, 0xD3}));
}
TEST(LeakDetectionRequestUtils, PrepareSingleLeakRequestData) {
base::test::ScopedTaskEnvironment task_env;
base::MockCallback<SingleLeakRequestDataCallback> callback;
PrepareSingleLeakRequestData("jonsnow", "1234", callback.Get());
EXPECT_CALL(
callback,
Run(AllOf(
Field(&LookupSingleLeakData::username_hash_prefix,
ElementsAre(61, 112, -45)),
Field(&LookupSingleLeakData::encrypted_payload, testing::Ne("")),
Field(&LookupSingleLeakData::encryption_key, testing::Ne("")))));
task_env.RunUntilIdle();
}
} // 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