Commit 96317f7f authored by Jan Wilken Dörrie's avatar Jan Wilken Dörrie Committed by Chromium LUCI CQ

[Passwords] Return Optional<string> from Encryption Utils

This change modifies encryption utils used for Password Check to return
base::Optional<std::string> instead of std::string. Now these methods
return a nullopt instead of an empty string in case there was an error
in the used Cipher, forcing callers to explicitly handle error cases.

Bug: 1157004
Change-Id: I21bea839020cd89e097fcf2a36efabe2adbed91a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2642144
Commit-Queue: Jan Wilken Dörrie <jdoerrie@chromium.org>
Reviewed-by: default avatarFriedrich [CET] <fhorschig@chromium.org>
Cr-Commit-Position: refs/heads/master@{#845597}
parent 8be5c1b9
...@@ -263,11 +263,11 @@ TEST_F(AuthenticatedLeakCheckTest, ParseResponse_DecryptionError) { ...@@ -263,11 +263,11 @@ TEST_F(AuthenticatedLeakCheckTest, ParseResponse_DecryptionError) {
std::string key_server; std::string key_server;
// Append trash bytes to force a decryption error. // Append trash bytes to force a decryption error.
response->reencrypted_lookup_hash = response->reencrypted_lookup_hash =
CipherReEncrypt(payload_and_callback.payload, &key_server) + *CipherReEncrypt(payload_and_callback.payload, &key_server) +
"trash_bytes"; "trash_bytes";
response->encrypted_leak_match_prefixes.push_back( response->encrypted_leak_match_prefixes.push_back(
crypto::SHA256HashString(CipherEncryptWithKey( crypto::SHA256HashString(*CipherEncryptWithKey(
ScryptHashUsernameAndPassword("another_username", kPassword), *ScryptHashUsernameAndPassword("another_username", kPassword),
key_server))); key_server)));
EXPECT_CALL(delegate(), OnLeakDetectionDone(false, GURL(kExampleCom), EXPECT_CALL(delegate(), OnLeakDetectionDone(false, GURL(kExampleCom),
...@@ -297,10 +297,10 @@ TEST_F(AuthenticatedLeakCheckTest, ParseResponse_NoLeak) { ...@@ -297,10 +297,10 @@ TEST_F(AuthenticatedLeakCheckTest, ParseResponse_NoLeak) {
auto response = std::make_unique<SingleLookupResponse>(); auto response = std::make_unique<SingleLookupResponse>();
std::string key_server; std::string key_server;
response->reencrypted_lookup_hash = response->reencrypted_lookup_hash =
CipherReEncrypt(payload_and_callback.payload, &key_server); *CipherReEncrypt(payload_and_callback.payload, &key_server);
response->encrypted_leak_match_prefixes.push_back( response->encrypted_leak_match_prefixes.push_back(
crypto::SHA256HashString(CipherEncryptWithKey( crypto::SHA256HashString(*CipherEncryptWithKey(
ScryptHashUsernameAndPassword("another_username", kPassword), *ScryptHashUsernameAndPassword("another_username", kPassword),
key_server))); key_server)));
EXPECT_CALL(delegate(), OnLeakDetectionDone(false, GURL(kExampleCom), EXPECT_CALL(delegate(), OnLeakDetectionDone(false, GURL(kExampleCom),
...@@ -337,10 +337,10 @@ TEST_F(AuthenticatedLeakCheckTest, ParseResponse_Leak) { ...@@ -337,10 +337,10 @@ TEST_F(AuthenticatedLeakCheckTest, ParseResponse_Leak) {
auto response = std::make_unique<SingleLookupResponse>(); auto response = std::make_unique<SingleLookupResponse>();
std::string key_server; std::string key_server;
response->reencrypted_lookup_hash = response->reencrypted_lookup_hash =
CipherReEncrypt(payload_and_callback.payload, &key_server); *CipherReEncrypt(payload_and_callback.payload, &key_server);
response->encrypted_leak_match_prefixes.push_back( response->encrypted_leak_match_prefixes.push_back(
crypto::SHA256HashString(CipherEncryptWithKey( crypto::SHA256HashString(*CipherEncryptWithKey(
ScryptHashUsernameAndPassword(canonicalized_username, kPassword), *ScryptHashUsernameAndPassword(canonicalized_username, kPassword),
key_server))); key_server)));
EXPECT_CALL(delegate(), OnLeakDetectionDone(true, GURL(kExampleCom), EXPECT_CALL(delegate(), OnLeakDetectionDone(true, GURL(kExampleCom),
......
...@@ -76,7 +76,7 @@ BulkLeakCheckImpl::BulkLeakCheckImpl( ...@@ -76,7 +76,7 @@ BulkLeakCheckImpl::BulkLeakCheckImpl(
: delegate_(delegate), : delegate_(delegate),
identity_manager_(identity_manager), identity_manager_(identity_manager),
url_loader_factory_(std::move(url_loader_factory)), url_loader_factory_(std::move(url_loader_factory)),
encryption_key_(CreateNewKey()), encryption_key_(CreateNewKey().value_or("")),
payload_task_runner_(base::ThreadPool::CreateSequencedTaskRunner( payload_task_runner_(base::ThreadPool::CreateSequencedTaskRunner(
{base::TaskPriority::USER_VISIBLE, {base::TaskPriority::USER_VISIBLE,
base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN})) { base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN})) {
......
...@@ -263,11 +263,11 @@ TEST_F(BulkLeakCheckTest, CheckCredentialsDecryptionError) { ...@@ -263,11 +263,11 @@ TEST_F(BulkLeakCheckTest, CheckCredentialsDecryptionError) {
std::string key_server; std::string key_server;
// Append trash bytes to force a decryption error. // Append trash bytes to force a decryption error.
response->reencrypted_lookup_hash = response->reencrypted_lookup_hash =
CipherReEncrypt(payload_and_callback.payload, &key_server) + *CipherReEncrypt(payload_and_callback.payload, &key_server) +
"trash_bytes"; "trash_bytes";
response->encrypted_leak_match_prefixes.push_back( response->encrypted_leak_match_prefixes.push_back(
crypto::SHA256HashString(CipherEncryptWithKey( crypto::SHA256HashString(*CipherEncryptWithKey(
ScryptHashUsernameAndPassword("another_username", kTestPassword), *ScryptHashUsernameAndPassword("another_username", kTestPassword),
key_server))); key_server)));
EXPECT_CALL(delegate(), OnError(LeakDetectionError::kHashingFailure)); EXPECT_CALL(delegate(), OnError(LeakDetectionError::kHashingFailure));
...@@ -292,10 +292,10 @@ TEST_F(BulkLeakCheckTest, CheckCredentialsNotLeaked) { ...@@ -292,10 +292,10 @@ TEST_F(BulkLeakCheckTest, CheckCredentialsNotLeaked) {
auto response = std::make_unique<SingleLookupResponse>(); auto response = std::make_unique<SingleLookupResponse>();
std::string key_server; std::string key_server;
response->reencrypted_lookup_hash = response->reencrypted_lookup_hash =
CipherReEncrypt(payload_and_callback.payload, &key_server); *CipherReEncrypt(payload_and_callback.payload, &key_server);
response->encrypted_leak_match_prefixes.push_back( response->encrypted_leak_match_prefixes.push_back(
crypto::SHA256HashString(CipherEncryptWithKey( crypto::SHA256HashString(*CipherEncryptWithKey(
ScryptHashUsernameAndPassword("another_username", kTestPassword), *ScryptHashUsernameAndPassword("another_username", kTestPassword),
key_server))); key_server)));
EXPECT_EQ(1u, bulk_check().GetPendingChecksCount()); EXPECT_EQ(1u, bulk_check().GetPendingChecksCount());
...@@ -325,10 +325,10 @@ TEST_F(BulkLeakCheckTest, CheckCredentialsLeaked) { ...@@ -325,10 +325,10 @@ TEST_F(BulkLeakCheckTest, CheckCredentialsLeaked) {
auto response = std::make_unique<SingleLookupResponse>(); auto response = std::make_unique<SingleLookupResponse>();
std::string key_server; std::string key_server;
response->reencrypted_lookup_hash = response->reencrypted_lookup_hash =
CipherReEncrypt(payload_and_callback.payload, &key_server); *CipherReEncrypt(payload_and_callback.payload, &key_server);
response->encrypted_leak_match_prefixes.push_back( response->encrypted_leak_match_prefixes.push_back(
crypto::SHA256HashString(CipherEncryptWithKey( crypto::SHA256HashString(*CipherEncryptWithKey(
ScryptHashUsernameAndPassword("abc", kTestPassword), key_server))); *ScryptHashUsernameAndPassword("abc", kTestPassword), key_server)));
EXPECT_EQ(1u, bulk_check().GetPendingChecksCount()); EXPECT_EQ(1u, bulk_check().GetPendingChecksCount());
leaked_credential = TestCredential("abc"); leaked_credential = TestCredential("abc");
......
...@@ -5,7 +5,9 @@ ...@@ -5,7 +5,9 @@
#include "components/password_manager/core/browser/leak_detection/encryption_utils.h" #include "components/password_manager/core/browser/leak_detection/encryption_utils.h"
#include <climits> #include <climits>
#include <utility>
#include "base/optional.h"
#include "base/stl_util.h" #include "base/stl_util.h"
#include "base/strings/strcat.h" #include "base/strings/strcat.h"
#include "base/strings/string_piece.h" #include "base/strings/string_piece.h"
...@@ -83,7 +85,7 @@ std::string BucketizeUsername(base::StringPiece canonicalized_username) { ...@@ -83,7 +85,7 @@ std::string BucketizeUsername(base::StringPiece canonicalized_username) {
return prefix; return prefix;
} }
std::string ScryptHashUsernameAndPassword( base::Optional<std::string> ScryptHashUsernameAndPassword(
base::StringPiece canonicalized_username, base::StringPiece canonicalized_username,
base::StringPiece password) { base::StringPiece password) {
// Constant salt added to the password hash on top of canonicalized_username. // Constant salt added to the password hash on top of canonicalized_username.
...@@ -118,68 +120,74 @@ std::string ScryptHashUsernameAndPassword( ...@@ -118,68 +120,74 @@ std::string ScryptHashUsernameAndPassword(
reinterpret_cast<const uint8_t*>(salt.data()), salt.size(), reinterpret_cast<const uint8_t*>(salt.data()), salt.size(),
kScryptCost, kScryptBlockSize, kScryptParallelization, kScryptCost, kScryptBlockSize, kScryptParallelization,
kScryptMaxMemory, key_data, kHashKeyLength); kScryptMaxMemory, key_data, kHashKeyLength);
return scrypt_ok == 1 ? std::move(result) : std::string(); return scrypt_ok == 1 ? base::make_optional(std::move(result))
: base::nullopt;
} }
std::string CipherEncrypt(const std::string& plaintext, std::string* key) { base::Optional<std::string> CipherEncrypt(const std::string& plaintext,
std::string* key) {
using ::private_join_and_compute::ECCommutativeCipher; using ::private_join_and_compute::ECCommutativeCipher;
auto cipher = ECCommutativeCipher::CreateWithNewKey( auto cipher = ECCommutativeCipher::CreateWithNewKey(
NID_X9_62_prime256v1, ECCommutativeCipher::SHA256); NID_X9_62_prime256v1, ECCommutativeCipher::SHA256);
if (cipher.ok()) { if (cipher.ok()) {
*key = cipher.ValueOrDie()->GetPrivateKeyBytes();
auto result = cipher.ValueOrDie()->Encrypt(plaintext); auto result = cipher.ValueOrDie()->Encrypt(plaintext);
if (result.ok()) if (result.ok()) {
return result.ValueOrDie(); *key = cipher.ValueOrDie()->GetPrivateKeyBytes();
return std::move(result).ValueOrDie();
}
} }
return std::string(); return base::nullopt;
} }
std::string CipherEncryptWithKey(const std::string& plaintext, base::Optional<std::string> CipherEncryptWithKey(const std::string& plaintext,
const std::string& key) { const std::string& key) {
using ::private_join_and_compute::ECCommutativeCipher; using ::private_join_and_compute::ECCommutativeCipher;
auto cipher = ECCommutativeCipher::CreateFromKey(NID_X9_62_prime256v1, key, auto cipher = ECCommutativeCipher::CreateFromKey(NID_X9_62_prime256v1, key,
ECCommutativeCipher::SHA256); ECCommutativeCipher::SHA256);
if (cipher.ok()) { if (cipher.ok()) {
auto result = cipher.ValueOrDie()->Encrypt(plaintext); auto result = cipher.ValueOrDie()->Encrypt(plaintext);
if (result.ok()) if (result.ok())
return result.ValueOrDie(); return std::move(result).ValueOrDie();
} }
return std::string(); return base::nullopt;
} }
std::string CipherReEncrypt(const std::string& already_encrypted, base::Optional<std::string> CipherReEncrypt(
std::string* key) { const std::string& already_encrypted,
std::string* key) {
using ::private_join_and_compute::ECCommutativeCipher; using ::private_join_and_compute::ECCommutativeCipher;
auto cipher = ECCommutativeCipher::CreateWithNewKey( auto cipher = ECCommutativeCipher::CreateWithNewKey(
NID_X9_62_prime256v1, ECCommutativeCipher::SHA256); NID_X9_62_prime256v1, ECCommutativeCipher::SHA256);
if (cipher.ok()) { if (cipher.ok()) {
*key = cipher.ValueOrDie()->GetPrivateKeyBytes();
auto result = cipher.ValueOrDie()->ReEncrypt(already_encrypted); auto result = cipher.ValueOrDie()->ReEncrypt(already_encrypted);
if (result.ok()) if (result.ok()) {
return result.ValueOrDie(); *key = cipher.ValueOrDie()->GetPrivateKeyBytes();
return std::move(result).ValueOrDie();
}
} }
return std::string(); return base::nullopt;
} }
std::string CipherDecrypt(const std::string& ciphertext, base::Optional<std::string> CipherDecrypt(const std::string& ciphertext,
const std::string& key) { const std::string& key) {
using ::private_join_and_compute::ECCommutativeCipher; using ::private_join_and_compute::ECCommutativeCipher;
auto cipher = ECCommutativeCipher::CreateFromKey(NID_X9_62_prime256v1, key, auto cipher = ECCommutativeCipher::CreateFromKey(NID_X9_62_prime256v1, key,
ECCommutativeCipher::SHA256); ECCommutativeCipher::SHA256);
if (cipher.ok()) { if (cipher.ok()) {
auto result = cipher.ValueOrDie()->Decrypt(ciphertext); auto result = cipher.ValueOrDie()->Decrypt(ciphertext);
if (result.ok()) if (result.ok())
return result.ValueOrDie(); return std::move(result).ValueOrDie();
} }
return std::string(); return base::nullopt;
} }
std::string CreateNewKey() { base::Optional<std::string> CreateNewKey() {
using ::private_join_and_compute::ECCommutativeCipher; using ::private_join_and_compute::ECCommutativeCipher;
auto cipher = ECCommutativeCipher::CreateWithNewKey( auto cipher = ECCommutativeCipher::CreateWithNewKey(
NID_X9_62_prime256v1, ECCommutativeCipher::SHA256); NID_X9_62_prime256v1, ECCommutativeCipher::SHA256);
return cipher.ok() ? cipher.ValueOrDie()->GetPrivateKeyBytes() if (cipher.ok())
: std::string(); return cipher.ValueOrDie()->GetPrivateKeyBytes();
return base::nullopt;
} }
} // namespace password_manager } // namespace password_manager
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <string> #include <string>
#include "base/optional.h"
#include "base/strings/string16.h" #include "base/strings/string16.h"
#include "base/strings/string_piece_forward.h" #include "base/strings/string_piece_forward.h"
...@@ -31,7 +32,8 @@ std::string BucketizeUsername(base::StringPiece canonicalized_username); ...@@ -31,7 +32,8 @@ std::string BucketizeUsername(base::StringPiece canonicalized_username);
// Produces the username/password pair hash using scrypt algorithm. // Produces the username/password pair hash using scrypt algorithm.
// |canonicalized_username| and |password| are UTF-8 strings. // |canonicalized_username| and |password| are UTF-8 strings.
std::string ScryptHashUsernameAndPassword( // Returns nullopt in case of encryption failure.
base::Optional<std::string> ScryptHashUsernameAndPassword(
base::StringPiece canonicalized_username, base::StringPiece canonicalized_username,
base::StringPiece password); base::StringPiece password);
...@@ -39,26 +41,35 @@ std::string ScryptHashUsernameAndPassword( ...@@ -39,26 +41,35 @@ std::string ScryptHashUsernameAndPassword(
// Encrypts |plaintext| with a new key. The key is returned via |key|. // Encrypts |plaintext| with a new key. The key is returned via |key|.
// Internally the function does some hashing first and then encrypts the result. // Internally the function does some hashing first and then encrypts the result.
std::string CipherEncrypt(const std::string& plaintext, std::string* key); // In case of an encryption failure this returns nullopt and does not modify
// |key|.
base::Optional<std::string> CipherEncrypt(const std::string& plaintext,
std::string* key);
// Encrypts |plaintext| with the existing key. // Encrypts |plaintext| with the existing key.
std::string CipherEncryptWithKey(const std::string& plaintext, // Returns nullopt in case of encryption failure.
const std::string& key); base::Optional<std::string> CipherEncryptWithKey(const std::string& plaintext,
const std::string& key);
// |already_encrypted| is an already encrypted string (output of CipherEncrypt). // |already_encrypted| is an already encrypted string (output of CipherEncrypt).
// Encrypts it again with a new key. The key is returned in |key|. // Encrypts it again with a new key. The key is returned in |key|.
// The function is different from CipherEncrypt() as it doesn't apply hashing on // The function is different from CipherEncrypt() as it doesn't apply hashing on
// the input. // the input.
std::string CipherReEncrypt(const std::string& already_encrypted, // In case of an encryption failure this returns nullopt and does not modify
std::string* key); // |key|.
base::Optional<std::string> CipherReEncrypt(
const std::string& already_encrypted,
std::string* key);
// Decrypts |ciphertext| using |key|. The result isn't the original string but a // Decrypts |ciphertext| using |key|. The result isn't the original string but a
// hash of it. // hash of it.
std::string CipherDecrypt(const std::string& ciphertext, // Returns nullopt in case of decryption failure.
const std::string& key); base::Optional<std::string> CipherDecrypt(const std::string& ciphertext,
const std::string& key);
// Returns a new key suitable for the encryption functions above. // Returns a new key suitable for the encryption functions above, or nullopt if
std::string CreateNewKey(); // the operation failed.
base::Optional<std::string> CreateNewKey();
} // namespace password_manager } // namespace password_manager
......
...@@ -77,21 +77,21 @@ TEST(EncryptionUtils, ScryptHashUsernameAndPassword) { ...@@ -77,21 +77,21 @@ TEST(EncryptionUtils, ScryptHashUsernameAndPassword) {
-56, -82, -38, 31, 114, 61, -7, 103, -56, -82, -38, 31, 114, 61, -7, 103,
76, 91, 52, -52, 47, -22, 107, 77, 76, 91, 52, -52, 47, -22, 107, 77,
118, 123, -14, -125, -123, 85, 115, -3}; 118, 123, -14, -125, -123, 85, 115, -3};
std::string result = ScryptHashUsernameAndPassword("user", "password123"); std::string result = *ScryptHashUsernameAndPassword("user", "password123");
EXPECT_THAT(result, ElementsAreArray(kExpected)); EXPECT_THAT(result, ElementsAreArray(kExpected));
} }
TEST(EncryptionUtils, EncryptAndDecrypt) { TEST(EncryptionUtils, EncryptAndDecrypt) {
constexpr char kRandomString[] = "very_secret"; constexpr char kRandomString[] = "very_secret";
std::string key; std::string key;
std::string cipher = CipherEncrypt(kRandomString, &key); std::string cipher = *CipherEncrypt(kRandomString, &key);
SCOPED_TRACE(testing::Message() SCOPED_TRACE(testing::Message()
<< "key=" << testing::PrintToString(StringAsArray(key))); << "key=" << testing::PrintToString(StringAsArray(key)));
EXPECT_NE(kRandomString, cipher); EXPECT_NE(kRandomString, cipher);
EXPECT_NE(std::string(), key); EXPECT_NE(std::string(), key);
EXPECT_THAT(CalculateECCurveHash(kRandomString), EXPECT_THAT(CalculateECCurveHash(kRandomString),
ElementsAreArray(CipherDecrypt(cipher, key))); ElementsAreArray(*CipherDecrypt(cipher, key)));
} }
TEST(EncryptionUtils, EncryptAndDecryptWithPredefinedKey) { TEST(EncryptionUtils, EncryptAndDecryptWithPredefinedKey) {
...@@ -109,10 +109,10 @@ TEST(EncryptionUtils, EncryptAndDecryptWithPredefinedKey) { ...@@ -109,10 +109,10 @@ TEST(EncryptionUtils, EncryptAndDecryptWithPredefinedKey) {
-112, -64, 58, -64, 76, -35, -117, -23, -100, -112, -64, 58, -64, 76, -35, -117, -23, -100,
25, 63, 37, 114, 74, 88}; 25, 63, 37, 114, 74, 88};
std::string cipher = CipherEncryptWithKey(kRandomString, kKey); std::string cipher = *CipherEncryptWithKey(kRandomString, kKey);
EXPECT_THAT(cipher, ElementsAreArray(kEncrypted)); EXPECT_THAT(cipher, ElementsAreArray(kEncrypted));
EXPECT_THAT(CalculateECCurveHash(kRandomString), EXPECT_THAT(CalculateECCurveHash(kRandomString),
ElementsAreArray(CipherDecrypt(cipher, kKey))); ElementsAreArray(*CipherDecrypt(cipher, kKey)));
} }
TEST(EncryptionUtils, CipherIsCommutative) { TEST(EncryptionUtils, CipherIsCommutative) {
...@@ -120,31 +120,31 @@ TEST(EncryptionUtils, CipherIsCommutative) { ...@@ -120,31 +120,31 @@ TEST(EncryptionUtils, CipherIsCommutative) {
// Client encrypts the string. // Client encrypts the string.
std::string key_client; std::string key_client;
std::string cipher = CipherEncrypt(kRandomString, &key_client); std::string cipher = *CipherEncrypt(kRandomString, &key_client);
SCOPED_TRACE(testing::Message() SCOPED_TRACE(testing::Message()
<< "key_client=" << "key_client="
<< testing::PrintToString(StringAsArray(key_client))); << testing::PrintToString(StringAsArray(key_client)));
// Server encrypts the result. // Server encrypts the result.
std::string key_server; std::string key_server;
cipher = CipherReEncrypt(cipher, &key_server); cipher = *CipherReEncrypt(cipher, &key_server);
SCOPED_TRACE(testing::Message() SCOPED_TRACE(testing::Message()
<< "key_server=" << "key_server="
<< testing::PrintToString(StringAsArray(key_server))); << testing::PrintToString(StringAsArray(key_server)));
EXPECT_THAT(CipherEncryptWithKey(kRandomString, key_server), EXPECT_THAT(*CipherEncryptWithKey(kRandomString, key_server),
ElementsAreArray(CipherDecrypt(cipher, key_client))); ElementsAreArray(*CipherDecrypt(cipher, key_client)));
} }
TEST(EncryptionUtils, CreateNewKey) { TEST(EncryptionUtils, CreateNewKey) {
const std::string key = CreateNewKey(); const std::string key = *CreateNewKey();
SCOPED_TRACE(testing::Message() SCOPED_TRACE(testing::Message()
<< "key=" << testing::PrintToString(StringAsArray(key))); << "key=" << testing::PrintToString(StringAsArray(key)));
constexpr char kRandomString[] = "very_secret"; constexpr char kRandomString[] = "very_secret";
std::string cipher = CipherEncryptWithKey(kRandomString, key); std::string cipher = *CipherEncryptWithKey(kRandomString, key);
EXPECT_THAT(CalculateECCurveHash(kRandomString), EXPECT_THAT(CalculateECCurveHash(kRandomString),
ElementsAreArray(CipherDecrypt(cipher, key))); ElementsAreArray(*CipherDecrypt(cipher, key)));
} }
} // namespace password_manager } // namespace password_manager
...@@ -14,7 +14,7 @@ namespace password_manager { ...@@ -14,7 +14,7 @@ namespace password_manager {
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
std::string payload(reinterpret_cast<const char*>(data), size); std::string payload(reinterpret_cast<const char*>(data), size);
std::string key; std::string key;
std::string cipher = password_manager::CipherEncrypt(payload, &key); std::string cipher = *password_manager::CipherEncrypt(payload, &key);
return 0; return 0;
} }
......
...@@ -32,7 +32,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { ...@@ -32,7 +32,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
return 0; return 0;
std::string payload(reinterpret_cast<const char*>(data), size); std::string payload(reinterpret_cast<const char*>(data), size);
std::string result = password_manager::CipherDecrypt(payload, key); std::string result = *password_manager::CipherDecrypt(payload, key);
return 0; return 0;
} }
......
...@@ -32,7 +32,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { ...@@ -32,7 +32,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
return 0; return 0;
std::string payload(reinterpret_cast<const char*>(data), size); std::string payload(reinterpret_cast<const char*>(data), size);
std::string result = password_manager::CipherEncryptWithKey(payload, key); std::string result = *password_manager::CipherEncryptWithKey(payload, key);
return 0; return 0;
} }
......
...@@ -9,7 +9,7 @@ namespace password_manager { ...@@ -9,7 +9,7 @@ namespace password_manager {
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
std::string payload(reinterpret_cast<const char*>(data), size); std::string payload(reinterpret_cast<const char*>(data), size);
std::string key; std::string key;
std::string result = password_manager::CipherEncrypt(payload, &key); std::string result = *password_manager::CipherEncrypt(payload, &key);
return 0; return 0;
} }
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "base/containers/span.h" #include "base/containers/span.h"
#include "base/debug/dump_without_crashing.h" #include "base/debug/dump_without_crashing.h"
#include "base/optional.h"
#include "base/strings/string_number_conversions.h" #include "base/strings/string_number_conversions.h"
#include "base/strings/string_piece_forward.h" #include "base/strings/string_piece_forward.h"
#include "base/strings/string_util.h" #include "base/strings/string_util.h"
...@@ -49,7 +50,8 @@ LookupSingleLeakPayload ProduceHashes(base::StringPiece username, ...@@ -49,7 +50,8 @@ LookupSingleLeakPayload ProduceHashes(base::StringPiece username,
LookupSingleLeakPayload payload; LookupSingleLeakPayload payload;
payload.username_hash_prefix = BucketizeUsername(canonicalized_username); payload.username_hash_prefix = BucketizeUsername(canonicalized_username);
payload.encrypted_payload = payload.encrypted_payload =
ScryptHashUsernameAndPassword(canonicalized_username, password); ScryptHashUsernameAndPassword(canonicalized_username, password)
.value_or("");
if (payload.encrypted_payload.empty()) if (payload.encrypted_payload.empty())
return LookupSingleLeakPayload(); return LookupSingleLeakPayload();
return payload; return payload;
...@@ -64,7 +66,8 @@ LookupSingleLeakData PrepareLookupSingleLeakData(base::StringPiece username, ...@@ -64,7 +66,8 @@ LookupSingleLeakData PrepareLookupSingleLeakData(base::StringPiece username,
if (data.payload.encrypted_payload.empty()) if (data.payload.encrypted_payload.empty())
return LookupSingleLeakData(); return LookupSingleLeakData();
data.payload.encrypted_payload = data.payload.encrypted_payload =
CipherEncrypt(data.payload.encrypted_payload, &data.encryption_key); CipherEncrypt(data.payload.encrypted_payload, &data.encryption_key)
.value_or("");
return data.payload.encrypted_payload.empty() ? LookupSingleLeakData() return data.payload.encrypted_payload.empty() ? LookupSingleLeakData()
: std::move(data); : std::move(data);
} }
...@@ -79,7 +82,8 @@ LookupSingleLeakPayload PrepareLookupSingleLeakDataWithKey( ...@@ -79,7 +82,8 @@ LookupSingleLeakPayload PrepareLookupSingleLeakDataWithKey(
if (payload.encrypted_payload.empty()) if (payload.encrypted_payload.empty())
return LookupSingleLeakPayload(); return LookupSingleLeakPayload();
payload.encrypted_payload = payload.encrypted_payload =
CipherEncryptWithKey(payload.encrypted_payload, encryption_key); CipherEncryptWithKey(payload.encrypted_payload, encryption_key)
.value_or("");
return payload.encrypted_payload.empty() ? LookupSingleLeakPayload() return payload.encrypted_payload.empty() ? LookupSingleLeakPayload()
: std::move(payload); : std::move(payload);
} }
...@@ -90,9 +94,9 @@ LookupSingleLeakPayload PrepareLookupSingleLeakDataWithKey( ...@@ -90,9 +94,9 @@ LookupSingleLeakPayload PrepareLookupSingleLeakDataWithKey(
AnalyzeResponseResult CheckIfCredentialWasLeaked( AnalyzeResponseResult CheckIfCredentialWasLeaked(
std::unique_ptr<SingleLookupResponse> response, std::unique_ptr<SingleLookupResponse> response,
const std::string& encryption_key) { const std::string& encryption_key) {
std::string decrypted_username_password = base::Optional<std::string> decrypted_username_password =
CipherDecrypt(response->reencrypted_lookup_hash, encryption_key); CipherDecrypt(response->reencrypted_lookup_hash, encryption_key);
if (decrypted_username_password.empty()) { if (!decrypted_username_password) {
DLOG(ERROR) << "Can't decrypt data=" DLOG(ERROR) << "Can't decrypt data="
<< base::HexEncode(base::as_bytes( << base::HexEncode(base::as_bytes(
base::make_span(response->reencrypted_lookup_hash))); base::make_span(response->reencrypted_lookup_hash)));
...@@ -100,7 +104,7 @@ AnalyzeResponseResult CheckIfCredentialWasLeaked( ...@@ -100,7 +104,7 @@ AnalyzeResponseResult CheckIfCredentialWasLeaked(
} }
std::string hash_username_password = std::string hash_username_password =
crypto::SHA256HashString(decrypted_username_password); crypto::SHA256HashString(*decrypted_username_password);
const ptrdiff_t matched_prefixes = const ptrdiff_t matched_prefixes =
std::count_if(response->encrypted_leak_match_prefixes.begin(), std::count_if(response->encrypted_leak_match_prefixes.begin(),
......
...@@ -93,10 +93,10 @@ TEST(LeakDetectionRequestUtils, AnalyzeResponseResult_NoLeak) { ...@@ -93,10 +93,10 @@ TEST(LeakDetectionRequestUtils, AnalyzeResponseResult_NoLeak) {
auto response = std::make_unique<SingleLookupResponse>(); auto response = std::make_unique<SingleLookupResponse>();
std::string key_client; std::string key_client;
std::string encrypted_username_password = std::string encrypted_username_password =
CipherEncrypt(kUsernamePasswordHash, &key_client); *CipherEncrypt(kUsernamePasswordHash, &key_client);
std::string key_server; std::string key_server;
response->reencrypted_lookup_hash = response->reencrypted_lookup_hash =
CipherReEncrypt(encrypted_username_password, &key_server); *CipherReEncrypt(encrypted_username_password, &key_server);
SCOPED_TRACE(testing::Message() SCOPED_TRACE(testing::Message()
<< "key_client=" << "key_client="
<< testing::PrintToString(StringToArray(key_client)) << testing::PrintToString(StringToArray(key_client))
...@@ -104,7 +104,7 @@ TEST(LeakDetectionRequestUtils, AnalyzeResponseResult_NoLeak) { ...@@ -104,7 +104,7 @@ TEST(LeakDetectionRequestUtils, AnalyzeResponseResult_NoLeak) {
<< testing::PrintToString(StringToArray(key_server))); << testing::PrintToString(StringToArray(key_server)));
response->encrypted_leak_match_prefixes.push_back(crypto::SHA256HashString( response->encrypted_leak_match_prefixes.push_back(crypto::SHA256HashString(
CipherEncryptWithKey("unrelated_trash", key_server))); *CipherEncryptWithKey("unrelated_trash", key_server)));
base::MockCallback<SingleLeakResponseAnalysisCallback> callback; base::MockCallback<SingleLeakResponseAnalysisCallback> callback;
AnalyzeResponse(std::move(response), key_client, callback.Get()); AnalyzeResponse(std::move(response), key_client, callback.Get());
...@@ -119,10 +119,10 @@ TEST(LeakDetectionRequestUtils, AnalyzeResponseResult_Leak) { ...@@ -119,10 +119,10 @@ TEST(LeakDetectionRequestUtils, AnalyzeResponseResult_Leak) {
auto response = std::make_unique<SingleLookupResponse>(); auto response = std::make_unique<SingleLookupResponse>();
std::string key_client; std::string key_client;
std::string encrypted_username_password = std::string encrypted_username_password =
CipherEncrypt(kUsernamePasswordHash, &key_client); *CipherEncrypt(kUsernamePasswordHash, &key_client);
std::string key_server; std::string key_server;
response->reencrypted_lookup_hash = response->reencrypted_lookup_hash =
CipherReEncrypt(encrypted_username_password, &key_server); *CipherReEncrypt(encrypted_username_password, &key_server);
SCOPED_TRACE(testing::Message() SCOPED_TRACE(testing::Message()
<< "key_client=" << "key_client="
<< testing::PrintToString(StringToArray(key_client)) << testing::PrintToString(StringToArray(key_client))
...@@ -133,10 +133,10 @@ TEST(LeakDetectionRequestUtils, AnalyzeResponseResult_Leak) { ...@@ -133,10 +133,10 @@ TEST(LeakDetectionRequestUtils, AnalyzeResponseResult_Leak) {
// The server can pick any value. // The server can pick any value.
constexpr int kPrefixLength = 30; constexpr int kPrefixLength = 30;
response->encrypted_leak_match_prefixes.push_back(crypto::SHA256HashString( response->encrypted_leak_match_prefixes.push_back(crypto::SHA256HashString(
CipherEncryptWithKey("unrelated_trash", key_server))); *CipherEncryptWithKey("unrelated_trash", key_server)));
response->encrypted_leak_match_prefixes.push_back( response->encrypted_leak_match_prefixes.push_back(
crypto::SHA256HashString( crypto::SHA256HashString(
CipherEncryptWithKey(kUsernamePasswordHash, key_server)) *CipherEncryptWithKey(kUsernamePasswordHash, key_server))
.substr(0, kPrefixLength)); .substr(0, kPrefixLength));
base::MockCallback<SingleLeakResponseAnalysisCallback> callback; base::MockCallback<SingleLeakResponseAnalysisCallback> callback;
......
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