mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-14 14:46:12 -04:00
Create fast pair data encryptor with Accountkey
PiperOrigin-RevId: 534908947
This commit is contained in:
committed by
Copybara-Service
parent
ecca9c1d19
commit
1d5abfcc0f
@@ -26,6 +26,8 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "fastpair/common/account_key.h"
|
||||
#include "fastpair/common/constant.h"
|
||||
#include "fastpair/common/protocol.h"
|
||||
#include "fastpair/crypto/decrypted_passkey.h"
|
||||
@@ -78,9 +80,7 @@ void FastPairDataEncryptorImpl::Factory::CreateAsync(
|
||||
device.GetProtocol() == Protocol::kFastPairRetroactivePairing) {
|
||||
CreateAsyncWithKeyExchange(device, std::move(on_get_instance_callback));
|
||||
} else {
|
||||
NEARBY_LOGS(INFO) << __func__
|
||||
<< ": Can't create FP encryptor. Invalid protocol.";
|
||||
on_get_instance_callback(nullptr);
|
||||
CreateAsyncWithAccountKey(device, std::move(on_get_instance_callback));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,19 +104,36 @@ void FastPairDataEncryptorImpl::Factory::DeviceMetadataRetrieved(
|
||||
absl::AnyInvocable<void(std::unique_ptr<FastPairDataEncryptor>)>
|
||||
on_get_instance_callback,
|
||||
DeviceMetadata& device_metadata) {
|
||||
NEARBY_LOGS(INFO) << __func__;
|
||||
DCHECK(&device_metadata);
|
||||
std::optional<KeyPair> key_pair =
|
||||
FastPairEncryption::GenerateKeysWithEcdhKeyAgreement(
|
||||
device_metadata.GetDetails().anti_spoofing_key_pair().public_key());
|
||||
if (!key_pair.has_value()) {
|
||||
NEARBY_LOGS(INFO) << "Fail to generate key pair";
|
||||
on_get_instance_callback(nullptr);
|
||||
std::move(on_get_instance_callback)(nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
std::unique_ptr<FastPairDataEncryptor> data_encryptor =
|
||||
auto data_encryptor =
|
||||
std::make_unique<FastPairDataEncryptorImpl>(key_pair.value());
|
||||
on_get_instance_callback(std::move(data_encryptor));
|
||||
std::move(on_get_instance_callback)(std::move(data_encryptor));
|
||||
}
|
||||
|
||||
void FastPairDataEncryptorImpl::Factory::CreateAsyncWithAccountKey(
|
||||
const FastPairDevice& device,
|
||||
absl::AnyInvocable<void(std::unique_ptr<FastPairDataEncryptor>)>
|
||||
on_get_instance_callback) {
|
||||
NEARBY_LOGS(INFO) << __func__;
|
||||
absl::string_view account_key = device.GetAccountKey().GetAsBytes();
|
||||
CHECK_EQ(account_key.size(), static_cast<size_t>(kSharedSecretKeyByteSize));
|
||||
std::array<uint8_t, kSharedSecretKeyByteSize> shared_secret_key;
|
||||
std::copy_n(account_key.begin(), kSharedSecretKeyByteSize,
|
||||
shared_secret_key.begin());
|
||||
|
||||
std::move(on_get_instance_callback)(
|
||||
std::make_unique<FastPairDataEncryptorImpl>(
|
||||
std::move(shared_secret_key)));
|
||||
}
|
||||
|
||||
// FastPairDataEncryptorImpl
|
||||
|
||||
@@ -64,6 +64,11 @@ class FastPairDataEncryptorImpl : public FastPairDataEncryptor {
|
||||
absl::AnyInvocable<void(std::unique_ptr<FastPairDataEncryptor>)>
|
||||
on_get_instance_callback,
|
||||
DeviceMetadata& device_metadata);
|
||||
|
||||
static void CreateAsyncWithAccountKey(
|
||||
const FastPairDevice& device,
|
||||
absl::AnyInvocable<void(std::unique_ptr<FastPairDataEncryptor>)>
|
||||
on_get_instance_callback);
|
||||
};
|
||||
|
||||
std::array<uint8_t, kAesBlockByteSize> EncryptBytes(
|
||||
|
||||
@@ -24,9 +24,12 @@
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/functional/bind_front.h"
|
||||
#include "absl/strings/escaping.h"
|
||||
#include "fastpair/common/account_key.h"
|
||||
#include "fastpair/common/constant.h"
|
||||
#include "fastpair/common/protocol.h"
|
||||
#include "fastpair/crypto/fast_pair_encryption.h"
|
||||
#include "fastpair/dataparser/fast_pair_data_parser.h"
|
||||
#include "fastpair/handshake/fast_pair_data_encryptor.h"
|
||||
#include "fastpair/server_access/fake_fast_pair_repository.h"
|
||||
#include "internal/platform/count_down_latch.h"
|
||||
|
||||
@@ -54,7 +57,7 @@ class FastPairDataEncryptorImplTest : public testing::Test {
|
||||
public:
|
||||
void TearDown() override { data_encryptor_.reset(); }
|
||||
|
||||
void FailedSetUpNoMetadata() {
|
||||
void FailedSetUpRepositoryWithNoDeviceMetadata() {
|
||||
CountDownLatch latch(1);
|
||||
repository_ = std::make_unique<FakeFastPairRepository>();
|
||||
FastPairDevice device(kValidModelId, kTestAddress,
|
||||
@@ -66,7 +69,7 @@ class FastPairDataEncryptorImplTest : public testing::Test {
|
||||
EXPECT_FALSE(latch.Await(kWaitTimeout).GetResult());
|
||||
}
|
||||
|
||||
void FailedSetUpNoKeyPair() {
|
||||
void FailedSetUpRepositoryWithNoPublicKey() {
|
||||
repository_ = std::make_unique<FakeFastPairRepository>();
|
||||
proto::Device metadata;
|
||||
std::string decoded_key;
|
||||
@@ -83,7 +86,7 @@ class FastPairDataEncryptorImplTest : public testing::Test {
|
||||
latch.Await();
|
||||
}
|
||||
|
||||
void SuccessfulSetUp() {
|
||||
void SuccessCreateFastPairDataEncryptorWithKeyExchange() {
|
||||
repository_ = std::make_unique<FakeFastPairRepository>();
|
||||
proto::Device metadata;
|
||||
std::string decoded_key;
|
||||
@@ -100,6 +103,22 @@ class FastPairDataEncryptorImplTest : public testing::Test {
|
||||
latch.Await();
|
||||
}
|
||||
|
||||
void SuccessCreateFastPairDataEncryptorWithAccountKey() {
|
||||
FastPairDevice device(kValidModelId, kTestAddress,
|
||||
Protocol::kFastPairSubsequentPairing);
|
||||
const std::vector<uint8_t> kAccountKey{0x11, 0x22, 0x33, 0x44, 0x55, 0x66,
|
||||
0x77, 0x88, 0x99, 0x00, 0xAA, 0xBB,
|
||||
0xCC, 0xDD, 0xEE, 0xFF};
|
||||
device.SetAccountKey(
|
||||
AccountKey(std::string(kAccountKey.begin(), kAccountKey.end())));
|
||||
CountDownLatch latch(1);
|
||||
FastPairDataEncryptorImpl::Factory::CreateAsync(
|
||||
device, absl::bind_front(
|
||||
&FastPairDataEncryptorImplTest::OnDataEncryptorCreateAsync,
|
||||
this, latch));
|
||||
latch.Await();
|
||||
}
|
||||
|
||||
void OnDataEncryptorCreateAsync(
|
||||
CountDownLatch latch,
|
||||
std::unique_ptr<FastPairDataEncryptor> fast_pair_data_encryptor) {
|
||||
@@ -153,6 +172,21 @@ class FastPairDataEncryptorImplTest : public testing::Test {
|
||||
latch.Await();
|
||||
}
|
||||
|
||||
void ParseDecryptedPasskeyWithAccountKey() {
|
||||
const std::array<uint8_t, kSharedSecretKeyByteSize> kAccountKey{
|
||||
0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
|
||||
0x99, 0x00, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF};
|
||||
|
||||
auto bytes = FastPairEncryption::EncryptBytes(kAccountKey, kPasskeyBytes);
|
||||
CountDownLatch latch(1);
|
||||
data_encryptor_->ParseDecryptPasskey(
|
||||
std::vector<uint8_t>(bytes.begin(), bytes.end()),
|
||||
absl::bind_front(
|
||||
&FastPairDataEncryptorImplTest::ParseDecryptPasskeyCallback, this,
|
||||
latch));
|
||||
latch.Await();
|
||||
}
|
||||
|
||||
void ParseDecryptedPasskeyInvalidBytes() {
|
||||
const std::array<uint8_t, kAesBlockByteSize> bytes =
|
||||
data_encryptor_->EncryptBytes(kPasskeyBytes);
|
||||
@@ -189,36 +223,55 @@ class FastPairDataEncryptorImplTest : public testing::Test {
|
||||
|
||||
TEST_F(FastPairDataEncryptorImplTest, FailedSetUpNoMetadata) {
|
||||
EXPECT_FALSE(data_encryptor_);
|
||||
FailedSetUpNoMetadata();
|
||||
FailedSetUpRepositoryWithNoDeviceMetadata();
|
||||
EXPECT_FALSE(data_encryptor_);
|
||||
}
|
||||
|
||||
TEST_F(FastPairDataEncryptorImplTest, NoKeyPair) {
|
||||
FailedSetUpNoKeyPair();
|
||||
FailedSetUpRepositoryWithNoPublicKey();
|
||||
EXPECT_FALSE(data_encryptor_);
|
||||
}
|
||||
|
||||
TEST_F(FastPairDataEncryptorImplTest, SuccessfulSetUp) {
|
||||
TEST_F(FastPairDataEncryptorImplTest,
|
||||
SuccessCreateFastPairDataEncryptorWithKeyExchange) {
|
||||
EXPECT_FALSE(data_encryptor_);
|
||||
SuccessfulSetUp();
|
||||
SuccessCreateFastPairDataEncryptorWithKeyExchange();
|
||||
EXPECT_TRUE(data_encryptor_);
|
||||
}
|
||||
|
||||
TEST_F(FastPairDataEncryptorImplTest,
|
||||
SuccessCreateFastPairDataEncryptorWithAccountKey) {
|
||||
EXPECT_FALSE(data_encryptor_);
|
||||
SuccessCreateFastPairDataEncryptorWithAccountKey();
|
||||
EXPECT_TRUE(data_encryptor_);
|
||||
}
|
||||
|
||||
TEST_F(FastPairDataEncryptorImplTest, GetPublicKey) {
|
||||
SuccessfulSetUp();
|
||||
SuccessCreateFastPairDataEncryptorWithKeyExchange();
|
||||
EXPECT_TRUE(data_encryptor_);
|
||||
ParseDecryptedPasskey();
|
||||
EXPECT_NE(data_encryptor_->GetPublicKey(), std::nullopt);
|
||||
}
|
||||
|
||||
TEST_F(FastPairDataEncryptorImplTest, EncryptBytes) {
|
||||
SuccessfulSetUp();
|
||||
TEST_F(FastPairDataEncryptorImplTest, GetNoPublicKey) {
|
||||
SuccessCreateFastPairDataEncryptorWithAccountKey();
|
||||
EXPECT_TRUE(data_encryptor_);
|
||||
EXPECT_EQ(data_encryptor_->GetPublicKey(), std::nullopt);
|
||||
}
|
||||
|
||||
TEST_F(FastPairDataEncryptorImplTest, EncryptBytesWithKeyExchange) {
|
||||
SuccessCreateFastPairDataEncryptorWithKeyExchange();
|
||||
EXPECT_TRUE(data_encryptor_);
|
||||
EXPECT_FALSE(EncryptBytes().empty());
|
||||
}
|
||||
|
||||
TEST_F(FastPairDataEncryptorImplTest, ParseDecryptedResponse) {
|
||||
SuccessfulSetUp();
|
||||
TEST_F(FastPairDataEncryptorImplTest, EncryptBytesWithAccountKey) {
|
||||
SuccessCreateFastPairDataEncryptorWithAccountKey();
|
||||
EXPECT_TRUE(data_encryptor_);
|
||||
EXPECT_FALSE(EncryptBytes().empty());
|
||||
}
|
||||
|
||||
TEST_F(FastPairDataEncryptorImplTest, ParseDecryptedResponseWithKeyExchange) {
|
||||
SuccessCreateFastPairDataEncryptorWithKeyExchange();
|
||||
EXPECT_TRUE(data_encryptor_);
|
||||
ParseDecryptedResponse();
|
||||
EXPECT_TRUE(response_);
|
||||
@@ -229,15 +282,27 @@ TEST_F(FastPairDataEncryptorImplTest, ParseDecryptedResponse) {
|
||||
FastPairMessageType::kKeyBasedPairingResponse);
|
||||
}
|
||||
|
||||
TEST_F(FastPairDataEncryptorImplTest, ParseDecryptedResponse_InvalidInputSize) {
|
||||
SuccessfulSetUp();
|
||||
TEST_F(FastPairDataEncryptorImplTest, ParseDecryptedResponseWithAccountKey) {
|
||||
SuccessCreateFastPairDataEncryptorWithAccountKey();
|
||||
EXPECT_TRUE(data_encryptor_);
|
||||
ParseDecryptedResponse();
|
||||
EXPECT_TRUE(response_);
|
||||
const std::array<uint8_t, kDecryptedResponseAddressByteSize> kAddressBytes = {
|
||||
0x5E, 0x3F, 0x45, 0x61, 0xC3, 0x32};
|
||||
EXPECT_EQ(response_->address_bytes, kAddressBytes);
|
||||
EXPECT_EQ(response_->message_type,
|
||||
FastPairMessageType::kKeyBasedPairingResponse);
|
||||
}
|
||||
|
||||
TEST_F(FastPairDataEncryptorImplTest, ParseDecryptedResponseInvalidInputSize) {
|
||||
SuccessCreateFastPairDataEncryptorWithKeyExchange();
|
||||
EXPECT_TRUE(data_encryptor_);
|
||||
ParseDecryptedResponseInvalidBytes();
|
||||
EXPECT_FALSE(response_);
|
||||
}
|
||||
|
||||
TEST_F(FastPairDataEncryptorImplTest, ParseDecryptedPasskey) {
|
||||
SuccessfulSetUp();
|
||||
TEST_F(FastPairDataEncryptorImplTest, ParseDecryptedPasskeyWithKeyExchange) {
|
||||
SuccessCreateFastPairDataEncryptorWithKeyExchange();
|
||||
EXPECT_TRUE(data_encryptor_);
|
||||
ParseDecryptedPasskey();
|
||||
EXPECT_TRUE(passkey_);
|
||||
@@ -251,8 +316,23 @@ TEST_F(FastPairDataEncryptorImplTest, ParseDecryptedPasskey) {
|
||||
EXPECT_EQ(passkey_->message_type, FastPairMessageType::kSeekersPasskey);
|
||||
}
|
||||
|
||||
TEST_F(FastPairDataEncryptorImplTest, ParseDecryptedPasskey_InvalidInputSize) {
|
||||
SuccessfulSetUp();
|
||||
TEST_F(FastPairDataEncryptorImplTest, ParseDecryptedPasskeyWithAccountKey) {
|
||||
SuccessCreateFastPairDataEncryptorWithAccountKey();
|
||||
EXPECT_TRUE(data_encryptor_);
|
||||
ParseDecryptedPasskeyWithAccountKey();
|
||||
EXPECT_TRUE(passkey_);
|
||||
// Passkey bytes.
|
||||
std::array<uint8_t, 3> passkey_bytes = {0x5E, 0x3F, 0x45};
|
||||
uint32_t passkey = passkey_bytes[2];
|
||||
passkey += passkey_bytes[1] << 8;
|
||||
passkey += passkey_bytes[0] << 16;
|
||||
|
||||
EXPECT_EQ(passkey_->passkey, passkey);
|
||||
EXPECT_EQ(passkey_->message_type, FastPairMessageType::kSeekersPasskey);
|
||||
}
|
||||
|
||||
TEST_F(FastPairDataEncryptorImplTest, ParseDecryptedPasskeyInvalidInputSize) {
|
||||
SuccessCreateFastPairDataEncryptorWithKeyExchange();
|
||||
EXPECT_TRUE(data_encryptor_);
|
||||
ParseDecryptedPasskeyInvalidBytes();
|
||||
EXPECT_FALSE(passkey_);
|
||||
|
||||
Reference in New Issue
Block a user