Update SharedCredential definition

PiperOrigin-RevId: 506117150
This commit is contained in:
Janusz Sobczak
2023-02-03 16:34:34 -08:00
committed by Copybara-Service
parent 26973fada5
commit b9efeaa881
33 changed files with 398 additions and 402 deletions
-9
View File
@@ -24,15 +24,6 @@ proto_library(
],
)
java_lite_proto_library(
name = "offline_wire_formats_java_proto_lite",
visibility = [
"//java/com/google/android/gmscore/integ/modules/nearby:__subpackages__",
"//javatests/com/google/android/gmscore/integ/modules/nearby:__subpackages__",
],
deps = [":offline_wire_formats_proto"],
)
cc_proto_library(
name = "offline_wire_formats_cc_proto",
visibility = [
+1
View File
@@ -91,6 +91,7 @@ cc_library(
"//internal/platform:cancellation_flag",
"//internal/platform:uuid",
"//internal/proto:credential_cc_proto",
"//internal/proto:local_credential_cc_proto",
"@com_google_absl//absl/container:flat_hash_map",
"@com_google_absl//absl/functional:any_invocable",
"@com_google_absl//absl/status",
@@ -25,6 +25,7 @@
#include "absl/strings/str_format.h"
#include "absl/strings/string_view.h"
#include "internal/proto/credential.pb.h"
#include "internal/proto/local_credential.pb.h"
namespace nearby {
namespace presence {
@@ -72,7 +72,7 @@ void CredentialStorageImpl::SaveCredentials(
<< "]";
absl::MutexLock lock(&private_mutex_);
SaveLocalCredentialsLocked(manager_app_id, account_name,
private_credentials);
private_credentials);
}
if (public_credentials.empty()) {
@@ -121,7 +121,7 @@ void CredentialStorageImpl::UpdateLocalCredential(
GetLocalCredentialsLocked(CredentialSelector{
.manager_app_id = std::string(manager_app_id),
.account_name = std::string(account_name),
.identity_type = internal::IDENTITY_TYPE_UNSPECIFIED});
.identity_type = IdentityType::IDENTITY_TYPE_UNSPECIFIED});
if (!credentials.ok()) {
NEARBY_LOGS(WARNING) << credentials.status();
credentials = std::vector<LocalCredential>();
+27 -14
View File
@@ -1,20 +1,6 @@
proto_library(
name = "device_metadata_proto",
srcs = ["device_metadata.proto"],
)
cc_proto_library(
name = "device_metadata_cc_proto",
visibility = [
"//:__subpackages__",
],
deps = [":device_metadata_proto"],
)
proto_library(
name = "credential_proto",
srcs = ["credential.proto"],
deps = [":device_metadata_proto"],
)
cc_proto_library(
@@ -24,3 +10,30 @@ cc_proto_library(
],
deps = [":credential_proto"],
)
proto_library(
name = "local_credential_proto",
srcs = ["local_credential.proto"],
deps = [":credential_proto"],
)
cc_proto_library(
name = "local_credential_cc_proto",
visibility = [
"//:__subpackages__",
],
deps = [":local_credential_proto"],
)
proto_library(
name = "metadata_proto",
srcs = ["metadata.proto"],
)
cc_proto_library(
name = "metadata_cc_proto",
visibility = [
"//:__subpackages__",
],
deps = [":metadata_proto"],
)
-5
View File
@@ -36,11 +36,6 @@ cc_proto_library(
deps = [":connections_log_proto"],
)
java_lite_proto_library(
name = "connections_log_java_proto_lite",
deps = [":connections_log_proto"],
)
cc_test(
name = "proto_analytics_test",
size = "small",
+48 -57
View File
@@ -1,9 +1,23 @@
// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
syntax = "proto3";
package nearby.internal;
import "internal/proto/device_metadata.proto";
// option cc_api_version = 2;
// option java_api_version = 2;
option java_package = "com.google.nearby.presence";
enum IdentityType {
@@ -14,67 +28,44 @@ enum IdentityType {
IDENTITY_TYPE_PROVISIONED = 4;
}
// A proto to store the local device's private credential.
message LocalCredential {
optional IdentityType identity_type = 1;
// The unique id of (and hashed based on) a pair of secret
// key (LocalCredential.verification_key) and X509Certificate's public
// key (SharedCredential.verification_key).
optional bytes secret_id = 2;
// The aes key to encrypt personal fields in public certificates.
// A bytes representation of a Secret Key owned by contact, to decrypt the
// encrypted DeviceMetadata bytes stored within the advertisement.
optional bytes authenticity_key = 3;
// Bytes representation of a private key of X509Certificate, used in
// handshake during contact verification phase.
optional bytes verification_key = 4;
// The time in millis from epoch when this credential becomes effective.
optional uint64 start_time_millis = 5;
// The time in millis from epoch when this credential expires.
optional uint64 end_time_millis = 6;
// The set of 2-byte salts already used to encrypt the metadata key.
map<uint32, bool> consumed_salts = 7;
// The aes key to encrypt DeviceMetadata in public credential.
optional bytes metadata_encryption_key = 8;
// The device metadata relates to this private credential.
optional DeviceMetadata device_metadata = 9;
}
// The shared credential is derived from local credential, and distributed to
// remote devices based on the trust token for identity decryption and
// authentication.
message SharedCredential {
optional IdentityType identity_type = 1;
// The randomly generated unique id of the public credential.
bytes secret_id = 1;
// The unique id of (and hashed based on) a pair of secret
// key (LocalCredential.verification_key) and X509Certificate's public
// key (SharedCredential.verification_key).
optional bytes secret_id = 2;
// Bytes representation of a Secret Key owned by contact, to decrypt the
// metadata_key stored within the advertisement.
optional bytes authenticity_key = 3;
// Bytes representation of a public key of X509Certificate, used in
// handshake during contact verification phase.
optional bytes verification_key = 4;
// 32 bytes of secure random bytes used to derive any symmetric keys needed.
bytes key_seed = 2;
// The time in millis from epoch when this credential becomes effective.
optional uint64 start_time_millis = 5;
int64 start_time_millis = 3;
// The time in millis from epoch when this credential expires.
optional uint64 end_time_millis = 6;
// The time in millis from epoch when this credential expires.
int64 end_time_millis = 4;
// The encrypted DeviceMetadata in bytes, contains personal information of the
// device/user who created this certificate. Needs to be decrypted into bytes,
// and converted back to DeviceMetadata instance to access fields.
optional bytes encrypted_metadata_bytes = 7;
// The encrypted Metadata in bytes. Encrypted either by the v0 or v1
// metadata_encryption_key.
bytes encrypted_metadata_bytes = 5;
// The tag for verifying metadata_encryption_key.
optional bytes metadata_encryption_key_tag = 8;
bytes metadata_encryption_key_tag = 6;
// The public key is used to create a secure connection with the device.
bytes connection_signature_verification_key = 7;
// The public key is used to verify Advertisement Signature in BT5.0 (v1)
// specs.
bytes advertisement_signature_verification_key = 8;
// The trust type assigned to the credential. The credential is only
// accessible to contacts assigned with the same token. This field is only
// visible to the generating device and the server for distribution/provision
// purposes. Tokens are abstracted (with unnecessary details being removed)
// when returned to downloading devices.
IdentityType identity_type = 9;
// The version number of this SharedCredential, matches the corresponding
// protocol version.
bytes version = 10;
}
-34
View File
@@ -1,34 +0,0 @@
syntax = "proto3";
package nearby.internal;
// A proto to store the local device's metadata.
message DeviceMetadata {
// Stable device identifier that does not rotate for a few months.
optional string stable_device_id = 1;
// The account name which created the credential.
optional string account_name = 2;
// The name of the local device when the credential is created.
optional string device_name = 3;
// The icon url of the user whose device created the certificate.
optional string icon_url = 4;
// The Bluetooth MAC address of the device which created the certificate.
optional string bluetooth_mac_address = 5;
/** The types of the device. */
enum DeviceType {
UNSPECIFIED = 0;
PHONE = 1;
TABLET = 2;
DISPLAY = 3;
LAPTOP = 4;
TV = 5;
WATCH = 6;
}
optional DeviceType device_type = 6;
}
+68
View File
@@ -0,0 +1,68 @@
// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
syntax = "proto3";
package nearby.internal;
import "internal/proto/credential.proto";
// option cc_api_version = 2;
// option java_api_version = 2;
option java_package = "com.google.nearby.presence";
// The local credential contains information of a local device for
// identity encryption and authentication. It should never leave the generating
// device.
message LocalCredential {
// Private encryption key descriptor.
// Usually, either `certificate_alias` or `key` is set.
message PrivateKey {
// The associated alias of a X509Certificate.
string certificate_alias = 1;
// The private key
bytes key = 2;
}
// The unique id of (and hashed based on) a pair of Secret Key and
// X509Certificate's public key.
bytes secret_id = 1;
// Bytes representation of an AES Key owned by local device, to encrypt
// local device metadata.
bytes key_seed = 2;
// The time in millis from epoch when this credential becomes effective.
int64 start_time_millis = 3;
// The time in millis from epoch when this credential expires.
int64 end_time_millis = 4;
// The 14 or 16 bytes aes key to encrypt metadata in PublicCredential.
bytes metadata_encryption_key = 5;
// It is used for signing advertisement.
PrivateKey advertisement_signing_key = 6;
// It is used for connection authentication.
// nit: Content not included in this doc yet, since irreverent to the OTA
// specs. will add more details for implementations later.
PrivateKey connection_signing_key = 7;
// The trust type assigned to the credential.
IdentityType identity_type = 8;
// The set of 2-byte salts already used to encrypt the metadata key.
map<uint32, bool> consumed_salts = 9;
}
+39
View File
@@ -0,0 +1,39 @@
// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
syntax = "proto3";
package nearby.internal;
// The metadata of a device.
// Contains confidential data not to be broadcasted directly in OTA.
message Metadata {
// An identifier of the device.
string device_id = 1;
// The account name of the account who owns the device.
string account_name = 2;
// The name of the local device to be returned through credentials.
string device_name = 3;
// The name of the user who owns the device.
string user_name = 4;
// The profile url of the device.
string device_profile_url = 5;
// The Bluetooth MAC address of the device.
bytes bluetooth_mac_address = 6;
}
+2 -4
View File
@@ -62,14 +62,12 @@ cc_library(
deps = [
"//internal:device",
"//internal/crypto",
"//internal/platform:base",
"//internal/platform:connection_info",
"//internal/platform:logging",
"//internal/platform/implementation:types",
"//internal/proto:credential_cc_proto",
"//internal/proto:device_metadata_cc_proto",
"//internal/proto:metadata_cc_proto",
"@com_google_absl//absl/functional:any_invocable",
"@com_google_absl//absl/status",
"@com_google_absl//absl/strings",
"@com_google_absl//absl/time",
"@com_google_absl//absl/types:optional",
@@ -101,7 +99,6 @@ cc_test(
"//internal/platform:connection_info",
"//internal/platform:logging",
"//internal/proto:credential_cc_proto",
"//internal/proto:device_metadata_cc_proto",
] + select({
"//tools/cc_target_os:windows": [
"//internal/platform/implementation/windows",
@@ -125,6 +122,7 @@ cc_test(
"@com_google_googletest//:gtest_main",
"//internal/platform:uuid",
"//internal/proto:credential_cc_proto",
"//internal/proto:local_credential_cc_proto",
] + select({
"//tools/cc_target_os:windows": [
"//internal/platform/implementation/windows",
+6 -8
View File
@@ -20,15 +20,15 @@
#include "gtest/gtest.h"
#include "internal/platform/uuid.h"
#include "internal/proto/credential.pb.h"
#include "internal/proto/local_credential.pb.h"
namespace nearby {
namespace presence {
namespace {
using ::nearby::internal::DeviceMetadata;
using ::nearby::internal::LocalCredential;
using ::nearby::internal::SharedCredential;
using ::nearby::internal::IdentityType::IDENTITY_TYPE_PRIVATE;
using ::nearby::internal::IdentityType::IDENTITY_TYPE_PROVISIONED;
using ::nearby::internal::IdentityType::IDENTITY_TYPE_PUBLIC;
using ::protobuf_matchers::EqualsProto;
@@ -41,9 +41,9 @@ TEST(CredentialsTest, InitSharedCredential) {
SharedCredential pc1 = {};
SharedCredential pc2 = {};
EXPECT_THAT(pc1, EqualsProto(pc2));
pc1.set_identity_type(IDENTITY_TYPE_PUBLIC);
pc1.set_identity_type(IDENTITY_TYPE_PRIVATE);
EXPECT_THAT(pc1, ::testing::Not(EqualsProto(pc2)));
pc2.set_identity_type(IDENTITY_TYPE_PUBLIC);
pc2.set_identity_type(IDENTITY_TYPE_PRIVATE);
EXPECT_THAT(pc1, EqualsProto(pc2));
}
@@ -51,9 +51,9 @@ TEST(CredentialsTest, InitLocalCredential) {
LocalCredential pc1 = {};
LocalCredential pc2 = {};
EXPECT_THAT(pc1, EqualsProto(pc2));
pc1.set_identity_type(IDENTITY_TYPE_PUBLIC);
pc1.set_identity_type(IDENTITY_TYPE_PRIVATE);
EXPECT_THAT(pc1, ::testing::Not(EqualsProto(pc2)));
pc2.set_identity_type(IDENTITY_TYPE_PUBLIC);
pc2.set_identity_type(IDENTITY_TYPE_PRIVATE);
EXPECT_THAT(pc1, EqualsProto(pc2));
}
@@ -62,8 +62,6 @@ TEST(CredentialsTest, CopyLocalCredential) {
pc1.set_identity_type(IDENTITY_TYPE_PROVISIONED);
auto salts = pc1.mutable_consumed_salts();
salts->insert(std::pair<int32, bool>(15, true));
pc1.mutable_device_metadata()->set_device_name("Android Phone");
pc1.mutable_device_metadata()->set_device_type(DeviceMetadata::PHONE);
LocalCredential pc1_copy = {pc1};
EXPECT_THAT(pc1, EqualsProto(pc1_copy));
}
+3
View File
@@ -94,6 +94,8 @@ cc_library(
"//internal/platform/implementation:comm",
"//internal/platform/implementation:types",
"//internal/proto:credential_cc_proto",
"//internal/proto:local_credential_cc_proto",
"//internal/proto:metadata_cc_proto",
"//presence:types",
"//presence/implementation/mediums",
"@boringssl//:crypto",
@@ -231,6 +233,7 @@ cc_test(
"@com_github_protobuf_matchers//protobuf-matchers:protobuf-matchers",
"@com_google_googletest//:gtest_main",
"@com_google_absl//absl/types:variant",
"//internal/proto:credential_cc_proto",
"//presence:types",
] + select({
"//tools/cc_target_os:windows": [
@@ -218,9 +218,8 @@ absl::StatusOr<std::string> AdvertisementDecoder::DecryptLdt(
return absl::UnavailableError("No credentials");
}
for (const auto& credential : credentials) {
absl::StatusOr<LdtEncryptor> encryptor =
LdtEncryptor::Create(credential.authenticity_key(),
credential.metadata_encryption_key_tag());
absl::StatusOr<LdtEncryptor> encryptor = LdtEncryptor::Create(
credential.key_seed(), credential.metadata_encryption_key_tag());
if (encryptor.ok()) {
absl::StatusOr<std::string> result =
encryptor->DecryptAndVerify(data_elements, salt);
@@ -424,9 +423,10 @@ bool AdvertisementDecoder::MatchesScanFilter(
std::vector<CredentialSelector> AdvertisementDecoder::GetCredentialSelectors(
const ScanRequest& scan_request) {
std::vector<internal::IdentityType> all_types = {
internal::IDENTITY_TYPE_PRIVATE, internal::IDENTITY_TYPE_TRUSTED,
internal::IDENTITY_TYPE_PROVISIONED, internal::IDENTITY_TYPE_PUBLIC};
std::vector<IdentityType> all_types = {
IdentityType::IDENTITY_TYPE_PRIVATE, IdentityType::IDENTITY_TYPE_TRUSTED,
IdentityType::IDENTITY_TYPE_PUBLIC,
IdentityType::IDENTITY_TYPE_PROVISIONED};
std::vector<CredentialSelector> selectors(all_types.size());
for (auto identity_type :
(scan_request.identity_types.empty() ? all_types
@@ -42,9 +42,11 @@ struct Advertisement {
// Decodes BLE NP advertisements
class AdvertisementDecoder {
public:
using IdentityType = ::nearby::internal::IdentityType;
AdvertisementDecoder(
ScanRequest scan_request,
absl::flat_hash_map<internal::IdentityType,
absl::flat_hash_map<IdentityType,
std::vector<internal::SharedCredential>>* credentials)
: scan_request_(scan_request), credentials_(credentials) {
AddBannedDataTypes();
@@ -85,9 +87,8 @@ class AdvertisementDecoder {
const LegacyPresenceScanFilter& filter);
ScanRequest scan_request_;
absl::flat_hash_map<internal::IdentityType,
std::vector<internal::SharedCredential>>* credentials_ =
nullptr;
absl::flat_hash_map<IdentityType, std::vector<internal::SharedCredential>>*
credentials_ = nullptr;
absl::flat_hash_set<int> banned_data_types_;
Advertisement decoded_advertisement_;
};
@@ -34,7 +34,8 @@ namespace nearby {
namespace presence {
namespace {
using ::nearby::ByteArray; // NOLINT
using ::nearby::ByteArray; // NOLINT
using ::nearby::internal::IdentityType;
using ::nearby::internal::SharedCredential; // NOLINT
using ::testing::ElementsAre;
using ::protobuf_matchers::EqualsProto;
@@ -48,10 +49,10 @@ constexpr absl::string_view kAccountName = "test account";
ScanRequest GetScanRequest() {
return {.account_name = std::string(kAccountName),
.identity_types = {internal::IDENTITY_TYPE_PRIVATE,
internal::IDENTITY_TYPE_TRUSTED,
internal::IDENTITY_TYPE_PUBLIC,
internal::IDENTITY_TYPE_PROVISIONED}};
.identity_types = {IdentityType::IDENTITY_TYPE_PRIVATE,
IdentityType::IDENTITY_TYPE_TRUSTED,
IdentityType::IDENTITY_TYPE_PUBLIC,
IdentityType::IDENTITY_TYPE_PROVISIONED}};
}
#if USE_RUST_LDT == 1
@@ -60,10 +61,10 @@ ScanRequest GetScanRequest(std::vector<SharedCredential> credentials) {
credentials};
return ScanRequestBuilder()
.SetAccountName(kAccountName)
.AddIdentityType(internal::IDENTITY_TYPE_PRIVATE)
.AddIdentityType(internal::IDENTITY_TYPE_TRUSTED)
.AddIdentityType(internal::IDENTITY_TYPE_PUBLIC)
.AddIdentityType(internal::IDENTITY_TYPE_PROVISIONED)
.AddIdentityType(IdentityType::IDENTITY_TYPE_PRIVATE)
.AddIdentityType(IdentityType::IDENTITY_TYPE_TRUSTED)
.AddIdentityType(IdentityType::IDENTITY_TYPE_PUBLIC)
.AddIdentityType(IdentityType::IDENTITY_TYPE_PROVISIONED)
.AddScanFilter(scan_filter)
.Build();
}
@@ -77,7 +78,7 @@ SharedCredential GetPublicCredential() {
165, 34, 64, 181, 204, 44, 203, 95, 141, 82, 137,
163, 203, 100, 235, 53, 65, 202, 97, 75, 180});
SharedCredential public_credential;
public_credential.set_authenticity_key(seed.AsStringView());
public_credential.set_key_seed(seed.AsStringView());
public_credential.set_metadata_encryption_key_tag(known_mac.AsStringView());
return public_credential;
}
@@ -86,10 +87,10 @@ TEST(AdvertisementDecoder, DecodeBaseNpPrivateAdvertisement) {
std::string salt = "AB";
ByteArray metadata_key(
{205, 104, 63, 225, 161, 209, 248, 70, 84, 61, 10, 19, 212, 174});
absl::flat_hash_map<internal::IdentityType,
std::vector<internal::SharedCredential>>
absl::flat_hash_map<IdentityType, std::vector<internal::SharedCredential>>
credentials;
credentials[internal::IDENTITY_TYPE_PRIVATE].push_back(GetPublicCredential());
credentials[IdentityType::IDENTITY_TYPE_PRIVATE].push_back(
GetPublicCredential());
AdvertisementDecoder decoder(GetScanRequest(), &credentials);
absl::StatusOr<Advertisement> result = decoder.DecodeAdvertisement(
@@ -97,7 +98,7 @@ TEST(AdvertisementDecoder, DecodeBaseNpPrivateAdvertisement) {
ASSERT_OK(result);
EXPECT_EQ(result->metadata_key, metadata_key.AsStringView());
EXPECT_EQ(result->identity_type, internal::IDENTITY_TYPE_PRIVATE);
EXPECT_EQ(result->identity_type, IdentityType::IDENTITY_TYPE_PRIVATE);
EXPECT_THAT(result->data_elements,
ElementsAre(DataElement(DataElement::kSaltFieldType, salt),
DataElement(DataElement::kTxPowerFieldType,
@@ -120,7 +121,7 @@ TEST(AdvertisementDecoder,
ASSERT_OK(result);
EXPECT_EQ(result->metadata_key, metadata_key.AsStringView());
EXPECT_EQ(result->identity_type, internal::IDENTITY_TYPE_PRIVATE);
EXPECT_EQ(result->identity_type, IdentityType::IDENTITY_TYPE_PRIVATE);
EXPECT_THAT(result->data_elements,
ElementsAre(DataElement(DataElement::kSaltFieldType, salt),
DataElement(DataElement::kTxPowerFieldType,
@@ -133,10 +134,10 @@ TEST(AdvertisementDecoder, DecodeBaseNpTrustedAdvertisement) {
std::string salt = "AB";
ByteArray metadata_key(
{205, 104, 63, 225, 161, 209, 248, 70, 84, 61, 10, 19, 212, 174});
absl::flat_hash_map<internal::IdentityType,
std::vector<internal::SharedCredential>>
absl::flat_hash_map<IdentityType, std::vector<internal::SharedCredential>>
credentials;
credentials[internal::IDENTITY_TYPE_TRUSTED].push_back(GetPublicCredential());
credentials[IdentityType::IDENTITY_TYPE_TRUSTED].push_back(
GetPublicCredential());
AdvertisementDecoder decoder(GetScanRequest(), &credentials);
absl::StatusOr<Advertisement> result = decoder.DecodeAdvertisement(
@@ -144,7 +145,7 @@ TEST(AdvertisementDecoder, DecodeBaseNpTrustedAdvertisement) {
ASSERT_OK(result);
EXPECT_EQ(result->metadata_key, metadata_key.AsStringView());
EXPECT_EQ(result->identity_type, internal::IDENTITY_TYPE_TRUSTED);
EXPECT_EQ(result->identity_type, IdentityType::IDENTITY_TYPE_TRUSTED);
EXPECT_THAT(
result->data_elements,
UnorderedElementsAre(DataElement(DataElement::kSaltFieldType, salt),
@@ -160,10 +161,9 @@ TEST(AdvertisementDecoder, DecodeBaseNpProvisionedAdvertisement) {
std::string salt = "AB";
ByteArray metadata_key(
{205, 104, 63, 225, 161, 209, 248, 70, 84, 61, 10, 19, 212, 174});
absl::flat_hash_map<internal::IdentityType,
std::vector<internal::SharedCredential>>
absl::flat_hash_map<IdentityType, std::vector<internal::SharedCredential>>
credentials;
credentials[internal::IDENTITY_TYPE_PROVISIONED].push_back(
credentials[IdentityType::IDENTITY_TYPE_PROVISIONED].push_back(
GetPublicCredential());
AdvertisementDecoder decoder(GetScanRequest(), &credentials);
@@ -172,7 +172,7 @@ TEST(AdvertisementDecoder, DecodeBaseNpProvisionedAdvertisement) {
ASSERT_OK(result);
EXPECT_EQ(result->metadata_key, metadata_key.AsStringView());
EXPECT_EQ(result->identity_type, internal::IDENTITY_TYPE_PROVISIONED);
EXPECT_EQ(result->identity_type, IdentityType::IDENTITY_TYPE_PROVISIONED);
EXPECT_THAT(
result->data_elements,
UnorderedElementsAre(DataElement(DataElement::kSaltFieldType, salt),
@@ -188,10 +188,10 @@ TEST(AdvertisementDecoder, InvalidEncryptedContent) {
std::string salt = "AB";
ByteArray metadata_key(
{205, 104, 63, 225, 161, 209, 248, 70, 84, 61, 10, 19, 212, 174});
absl::flat_hash_map<internal::IdentityType,
std::vector<internal::SharedCredential>>
absl::flat_hash_map<IdentityType, std::vector<internal::SharedCredential>>
credentials;
credentials[internal::IDENTITY_TYPE_PRIVATE].push_back(GetPublicCredential());
credentials[IdentityType::IDENTITY_TYPE_PRIVATE].push_back(
GetPublicCredential());
AdvertisementDecoder decoder(GetScanRequest(), &credentials);
EXPECT_THAT(decoder.DecodeAdvertisement(absl::HexStringToBytes(
@@ -209,7 +209,7 @@ TEST(AdvertisementDecoder, DecodeBaseNpPublicAdvertisement) {
absl::HexStringToBytes("002041420337C1C2C31BEE"));
ASSERT_OK(result);
EXPECT_EQ(result->identity_type, internal::IDENTITY_TYPE_PUBLIC);
EXPECT_EQ(result->identity_type, IdentityType::IDENTITY_TYPE_PUBLIC);
EXPECT_EQ(result->version, 0);
EXPECT_THAT(
result->data_elements,
@@ -246,9 +246,9 @@ TEST(AdvertisementDecoder,
ScanForEncryptedIdentityIgnoresPublicIdentityAdvertisement) {
AdvertisementDecoder decoder(
{.account_name = std::string(kAccountName),
.identity_types = {internal::IDENTITY_TYPE_PRIVATE,
internal::IDENTITY_TYPE_TRUSTED,
internal::IDENTITY_TYPE_PROVISIONED}});
.identity_types = {IdentityType::IDENTITY_TYPE_PRIVATE,
IdentityType::IDENTITY_TYPE_TRUSTED,
IdentityType::IDENTITY_TYPE_PROVISIONED}});
EXPECT_THAT(decoder.DecodeAdvertisement(
absl::HexStringToBytes("00204142034650B04180")),
@@ -93,6 +93,11 @@ std::string SerializeAction(const Action& action) {
return output;
}
bool RequiresCredentials(IdentityType identity_type) {
return identity_type == IdentityType::IDENTITY_TYPE_PRIVATE ||
identity_type == IdentityType::IDENTITY_TYPE_TRUSTED ||
identity_type == IdentityType::IDENTITY_TYPE_PROVISIONED;
}
} // namespace
absl::StatusOr<AdvertisementData> AdvertisementFactory::CreateAdvertisement(
@@ -192,7 +197,7 @@ absl::StatusOr<std::string> AdvertisementFactory::EncryptDataElements(
// HMAC is not used during encryption, so we can pass an empty value.
absl::StatusOr<LdtEncryptor> encryptor =
LdtEncryptor::Create(credential.authenticity_key(), /*known_hmac=*/"");
LdtEncryptor::Create(credential.key_seed(), /*known_hmac=*/"");
if (!encryptor.ok()) {
return encryptor.status();
}
@@ -207,8 +212,7 @@ absl::StatusOr<CredentialSelector> AdvertisementFactory::GetCredentialSelector(
request.variant)) {
const auto& presence =
absl::get<BaseBroadcastRequest::BasePresence>(request.variant);
if (presence.credential_selector.identity_type !=
DataElement::kPublicIdentityFieldType) {
if (RequiresCredentials(presence.credential_selector.identity_type)) {
return presence.credential_selector;
}
}
@@ -51,7 +51,7 @@ LocalCredential CreateLocalCredential(IdentityType identity_type) {
LocalCredential private_credential;
private_credential.set_identity_type(identity_type);
private_credential.set_authenticity_key(seed.AsStringView());
private_credential.set_key_seed(seed.AsStringView());
private_credential.set_metadata_encryption_key(metadata_key.AsStringView());
return private_credential;
}
@@ -23,7 +23,6 @@
#include "absl/strings/string_view.h"
#include "absl/types/variant.h"
#include "internal/platform/implementation/credential_callbacks.h"
#include "internal/proto/credential.pb.h"
#include "presence/broadcast_request.h"
#include "presence/power_mode.h"
@@ -20,6 +20,7 @@
#include "protobuf-matchers/protocol-buffer-matchers.h"
#include "gtest/gtest.h"
#include "absl/types/variant.h"
#include "internal/proto/credential.pb.h"
#include "presence/broadcast_request.h"
#include "presence/data_element.h"
@@ -27,6 +28,7 @@ namespace nearby {
namespace presence {
namespace {
using ::nearby::internal::IdentityType;
using ::testing::status::StatusIs;
TEST(BroadcastRequestTest, CreateBasePresenceRequest) {
@@ -66,7 +68,7 @@ TEST(BroadcastRequestTest, CreateFromPresenceRequest) {
EXPECT_THAT(request->tx_power, kTxPower);
EXPECT_THAT(absl::get<BaseBroadcastRequest::BasePresence>(request->variant)
.credential_selector.identity_type,
internal::IDENTITY_TYPE_PUBLIC);
IdentityType::IDENTITY_TYPE_PUBLIC);
EXPECT_THAT(absl::get<BaseBroadcastRequest::BasePresence>(request->variant)
.action.action,
kExpectedAction);
+5 -5
View File
@@ -23,6 +23,7 @@
#include "absl/strings/string_view.h"
#include "internal/platform/implementation/credential_callbacks.h"
#include "internal/proto/credential.pb.h"
#include "internal/proto/metadata.pb.h"
namespace nearby {
namespace presence {
@@ -46,7 +47,7 @@ class CredentialManager {
// The users own public credentials wont be saved on local credential
// storage.
virtual void GenerateCredentials(
const nearby::internal::DeviceMetadata& device_metadata,
const nearby::internal::Metadata& metadata,
absl::string_view manager_app_id,
const std::vector<nearby::internal::IdentityType>& identity_types,
int credential_life_cycle_days, int contiguous_copy_of_credentials,
@@ -91,10 +92,9 @@ class CredentialManager {
// Decrypts the device metadata from a public credential.
// Returns an empty string if decryption fails.
virtual std::string DecryptDeviceMetadata(
absl::string_view device_metadata_encryption_key,
absl::string_view authenticity_key,
absl::string_view device_metadata_string) = 0;
virtual std::string DecryptMetadata(absl::string_view metadata_encryption_key,
absl::string_view key_seed,
absl::string_view metadata_string) = 0;
};
} // namespace presence
@@ -35,6 +35,7 @@
#include "internal/platform/implementation/crypto.h"
#include "internal/platform/logging.h"
#include "internal/proto/credential.pb.h"
#include "internal/proto/local_credential.pb.h"
#include "presence/implementation/base_broadcast_request.h"
#include "presence/implementation/ldt.h"
@@ -46,7 +47,6 @@ using ::nearby::Crypto;
using ::nearby::Exception;
using ::nearby::ExceptionOr;
using ::nearby::Future;
using ::nearby::internal::DeviceMetadata;
using ::nearby::internal::IdentityType;
using ::nearby::internal::LocalCredential;
using ::nearby::internal::SharedCredential;
@@ -70,7 +70,7 @@ std::string CustomizeBytesSize(absl::string_view bytes, size_t len) {
} // namespace
void CredentialManagerImpl::GenerateCredentials(
const DeviceMetadata& device_metadata, absl::string_view manager_app_id,
const Metadata& metadata, absl::string_view manager_app_id,
const std::vector<IdentityType>& identity_types,
int credential_life_cycle_days, int contiguous_copy_of_credentials,
GenerateCredentialsResultCallback credentials_generated_cb) {
@@ -80,10 +80,9 @@ void CredentialManagerImpl::GenerateCredentials(
for (auto identity_type : identity_types) {
absl::Time start_time = SystemClock::ElapsedRealtime();
absl::Duration gap = credential_life_cycle_days * absl::Hours(24);
for (int index = 0; index < contiguous_copy_of_credentials; index++) {
auto public_private_credentials = CreateLocalCredential(
device_metadata, identity_type, start_time, start_time + gap);
metadata, identity_type, start_time, start_time + gap);
if (public_private_credentials.second.identity_type() !=
IdentityType::IDENTITY_TYPE_UNSPECIFIED) {
private_credentials.push_back(public_private_credentials.first);
@@ -95,12 +94,12 @@ void CredentialManagerImpl::GenerateCredentials(
// Create credential_storage object and invoke SaveCredentials.
credential_storage_ptr_->SaveCredentials(
manager_app_id, device_metadata.account_name(), private_credentials,
manager_app_id, metadata.account_name(), private_credentials,
public_credentials, PublicCredentialType::kLocalPublicCredential,
SaveCredentialsResultCallback{
.credentials_saved_cb =
[this, manager_app_id = std::string(manager_app_id),
account_name = device_metadata.account_name(),
account_name = metadata.account_name(),
callback = std::move(credentials_generated_cb),
public_credentials](absl::Status status) mutable {
if (!status.ok()) {
@@ -155,9 +154,10 @@ void CredentialManagerImpl::UpdateRemotePublicCredentials(
}
std::pair<LocalCredential, SharedCredential>
CredentialManagerImpl::CreateLocalCredential(
const DeviceMetadata& device_metadata, IdentityType identity_type,
absl::Time start_time, absl::Time end_time) {
CredentialManagerImpl::CreateLocalCredential(const Metadata& metadata,
IdentityType identity_type,
absl::Time start_time,
absl::Time end_time) {
LocalCredential private_credential;
private_credential.set_start_time_millis(absl::ToUnixMillis(start_time));
private_credential.set_end_time_millis(absl::ToUnixMillis(end_time));
@@ -165,7 +165,7 @@ CredentialManagerImpl::CreateLocalCredential(
// Creates an AES key to encrypt the whole broadcast.
std::string secret_key = crypto::RandBytes(kAuthenticityKeyByteSize);
private_credential.set_authenticity_key(secret_key);
private_credential.set_key_seed(secret_key);
// Uses SHA-256 algorithm to generate the credential ID from the
// authenticity key
@@ -183,27 +183,23 @@ CredentialManagerImpl::CreateLocalCredential(
auto key_pair = crypto::ECPrivateKey::Create();
std::vector<uint8_t> private_key;
key_pair->ExportPrivateKey(&private_key);
private_credential.set_verification_key(
private_credential.mutable_connection_signing_key()->set_key(
std::string(private_key.begin(), private_key.end()));
// Create an AES key to encrypt the device metadata.
auto metadata_key = crypto::RandBytes(kBaseMetadataSize);
private_credential.set_metadata_encryption_key(metadata_key);
// set device meta data
*(private_credential.mutable_device_metadata()) = device_metadata;
// Generate the public credential
std::vector<uint8_t> public_key;
key_pair->ExportPublicKey(&public_key);
return std::pair<LocalCredential, SharedCredential>(
private_credential,
CreatePublicCredential(private_credential, public_key));
CreatePublicCredential(private_credential, metadata, public_key));
}
SharedCredential CredentialManagerImpl::CreatePublicCredential(
const LocalCredential& private_credential,
const LocalCredential& private_credential, const Metadata& metadata,
const std::vector<uint8_t>& public_key) {
// The start time in the public credential should be decreased by a random
// value in 0 - 3 hours range.
@@ -218,11 +214,12 @@ SharedCredential CredentialManagerImpl::CreatePublicCredential(
SharedCredential public_credential;
public_credential.set_identity_type(private_credential.identity_type());
public_credential.set_secret_id(private_credential.secret_id());
public_credential.set_authenticity_key(private_credential.authenticity_key());
public_credential.set_key_seed(private_credential.key_seed());
public_credential.set_start_time_millis(absl::ToUnixMillis(start_time));
public_credential.set_end_time_millis(absl::ToUnixMillis(end_time));
// set up the public key
public_credential.set_verification_key(
// Set up the public key. Note, we are setting the "connection" key but we are
// not setting the "advertisement" key because the latter is not used yet.
public_credential.set_connection_signature_verification_key(
std::string(public_key.begin(), public_key.end()));
auto metadata_encryption_key_tag =
@@ -231,10 +228,9 @@ SharedCredential CredentialManagerImpl::CreatePublicCredential(
std::string(metadata_encryption_key_tag.AsStringView()));
// Encrypt the device metadata
auto encrypted_meta_data = EncryptDeviceMetadata(
auto encrypted_meta_data = EncryptMetadata(
private_credential.metadata_encryption_key(),
private_credential.authenticity_key(),
private_credential.device_metadata().SerializeAsString());
private_credential.key_seed(), metadata.SerializeAsString());
if (encrypted_meta_data.empty()) {
NEARBY_LOGS(ERROR) << "Fails to encrypt the device metadata.";
@@ -247,23 +243,21 @@ SharedCredential CredentialManagerImpl::CreatePublicCredential(
return public_credential;
}
std::string CredentialManagerImpl::DecryptDeviceMetadata(
absl::string_view device_metadata_encryption_key,
absl::string_view authenticity_key,
absl::string_view device_metadata_string) {
std::string CredentialManagerImpl::DecryptMetadata(
absl::string_view metadata_encryption_key, absl::string_view key_seed,
absl::string_view metadata_string) {
crypto::Aead aead(crypto::Aead::AeadAlgorithm::AES_256_GCM);
std::vector<uint8_t> derived_key =
ExtendMetadataEncryptionKey(device_metadata_encryption_key);
ExtendMetadataEncryptionKey(metadata_encryption_key);
aead.Init(derived_key);
auto iv = CustomizeBytesSize(authenticity_key,
CredentialManagerImpl::kAesGcmIVSize);
auto iv = CustomizeBytesSize(key_seed, CredentialManagerImpl::kAesGcmIVSize);
std::vector<uint8_t> iv_bytes(iv.begin(), iv.end());
std::vector<uint8_t> encrypted_device_metadata_bytes(
device_metadata_string.begin(), device_metadata_string.end());
std::vector<uint8_t> encrypted_metadata_bytes(metadata_string.begin(),
metadata_string.end());
auto result = aead.Open(encrypted_device_metadata_bytes,
auto result = aead.Open(encrypted_metadata_bytes,
/*nonce=*/
iv_bytes,
/*additional_data=*/absl::Span<uint8_t>());
@@ -271,25 +265,24 @@ std::string CredentialManagerImpl::DecryptDeviceMetadata(
return std::string(result.value().begin(), result.value().end());
}
std::string CredentialManagerImpl::EncryptDeviceMetadata(
absl::string_view device_metadata_encryption_key,
absl::string_view authenticity_key,
absl::string_view device_metadata_string) {
std::string CredentialManagerImpl::EncryptMetadata(
absl::string_view metadata_encryption_key, absl::string_view key_seed,
absl::string_view metadata_string) {
crypto::Aead aead(crypto::Aead::AeadAlgorithm::AES_256_GCM);
std::vector<uint8_t> derived_key =
ExtendMetadataEncryptionKey(device_metadata_encryption_key);
ExtendMetadataEncryptionKey(metadata_encryption_key);
aead.Init(derived_key);
auto iv = CustomizeBytesSize(authenticity_key, kAesGcmIVSize);
auto iv = CustomizeBytesSize(key_seed, kAesGcmIVSize);
std::vector<uint8_t> iv_bytes(iv.begin(), iv.end());
std::vector<uint8_t> device_metadata_bytes(device_metadata_string.begin(),
device_metadata_string.end());
device_metadata_bytes.resize(device_metadata_string.size());
std::vector<uint8_t> metadata_bytes(metadata_string.begin(),
metadata_string.end());
metadata_bytes.resize(metadata_string.size());
auto encrypted = aead.Seal(device_metadata_bytes,
auto encrypted = aead.Seal(metadata_bytes,
/*nonce=*/
iv_bytes,
/*additional_data=*/absl::Span<uint8_t>());
@@ -298,10 +291,10 @@ std::string CredentialManagerImpl::EncryptDeviceMetadata(
}
std::vector<uint8_t> CredentialManagerImpl::ExtendMetadataEncryptionKey(
absl::string_view device_metadata_encryption_key) {
absl::string_view metadata_encryption_key) {
return crypto::HkdfSha256(
std::vector<uint8_t>(device_metadata_encryption_key.begin(),
device_metadata_encryption_key.end()),
std::vector<uint8_t>(metadata_encryption_key.begin(),
metadata_encryption_key.end()),
/*salt=*/absl::Span<uint8_t>(),
/*info=*/absl::Span<uint8_t>(), kNearbyPresenceNumBytesAesGcmKeySize);
}
@@ -310,7 +303,7 @@ void CredentialManagerImpl::GetLocalCredentials(
const CredentialSelector& credential_selector,
GetLocalCredentialsResultCallback callback) {
credential_storage_ptr_->GetLocalCredentials(credential_selector,
std::move(callback));
std::move(callback));
}
void CredentialManagerImpl::GetPublicCredentials(
@@ -325,17 +318,16 @@ ExceptionOr<std::vector<LocalCredential>>
CredentialManagerImpl::GetLocalCredentialsSync(
const CredentialSelector& credential_selector, absl::Duration timeout) {
Future<std::vector<LocalCredential>> result;
GetLocalCredentials(
credential_selector,
{.credentials_fetched_cb =
[result](absl::StatusOr<std::vector<LocalCredential>>
credentials) mutable {
if (!credentials.ok()) {
result.SetException({Exception::kFailed});
} else {
result.Set(std::move(*credentials));
}
}});
GetLocalCredentials(credential_selector,
{.credentials_fetched_cb =
[result](absl::StatusOr<std::vector<LocalCredential>>
credentials) mutable {
if (!credentials.ok()) {
result.SetException({Exception::kFailed});
} else {
result.Set(std::move(*credentials));
}
}});
return result.Get(timeout);
}
@@ -440,9 +432,8 @@ GetPublicCredentialsResultCallback
CredentialManagerImpl::CreateNotifySubscribersCallback(SubscriberKey key) {
return GetPublicCredentialsResultCallback{
.credentials_fetched_cb =
[this, key](
absl::StatusOr<std::vector<SharedCredential>>
credentials) {
[this,
key](absl::StatusOr<std::vector<SharedCredential>> credentials) {
if (!credentials.ok()) {
NEARBY_LOGS(WARNING)
<< "Failed to get public credentials: error code: "
@@ -459,8 +450,7 @@ CredentialManagerImpl::CreateNotifySubscribersCallback(SubscriberKey key) {
}
void CredentialManagerImpl::NotifySubscribers(
const SubscriberKey& key,
std::vector<SharedCredential> credentials) {
const SubscriberKey& key, std::vector<SharedCredential> credentials) {
// We are on `executor_` thread, so we can iterate over `subscribers_`
// without locking.
auto it = subscribers_.find(key);
@@ -39,6 +39,7 @@ namespace presence {
class CredentialManagerImpl : public CredentialManager {
public:
using IdentityType = ::nearby::internal::IdentityType;
using Metadata = ::nearby::internal::Metadata;
explicit CredentialManagerImpl(SingleThreadExecutor* executor)
: executor_(ABSL_DIE_IF_NULL(executor)) {
@@ -62,8 +63,7 @@ class CredentialManagerImpl : public CredentialManager {
static constexpr int kAesGcmIVSize = 12;
void GenerateCredentials(
const nearby::internal::DeviceMetadata& device_metadata,
absl::string_view manager_app_id,
const Metadata& metadata, absl::string_view manager_app_id,
const std::vector<nearby::internal::IdentityType>& identity_types,
int credential_life_cycle_days, int contiguous_copy_of_credentials,
GenerateCredentialsResultCallback credentials_generated_cb) override;
@@ -79,14 +79,13 @@ class CredentialManagerImpl : public CredentialManager {
nearby::internal::LocalCredential credential,
SaveCredentialsResultCallback result_callback) override;
void GetLocalCredentials(
const CredentialSelector& credential_selector,
GetLocalCredentialsResultCallback callback) override;
void GetLocalCredentials(const CredentialSelector& credential_selector,
GetLocalCredentialsResultCallback callback) override;
// Blocking version of `GetLocalCredentials`
nearby::ExceptionOr<std::vector<nearby::internal::LocalCredential>>
GetLocalCredentialsSync(const CredentialSelector& credential_selector,
absl::Duration timeout);
absl::Duration timeout);
// Used to fetch remote public creds when scanning.
void GetPublicCredentials(
@@ -107,29 +106,26 @@ class CredentialManagerImpl : public CredentialManager {
void UnsubscribeFromPublicCredentials(SubscriberId id) override;
std::string DecryptDeviceMetadata(
absl::string_view device_metadata_encryption_key,
absl::string_view authenticity_key,
absl::string_view device_metadata_string) override;
std::string DecryptMetadata(absl::string_view metadata_encryption_key,
absl::string_view key_seed,
absl::string_view metadata_string) override;
std::pair<nearby::internal::LocalCredential,
nearby::internal::SharedCredential>
CreateLocalCredential(
const nearby::internal::DeviceMetadata& device_metadata,
IdentityType identity_type, absl::Time start_time, absl::Time end_time);
CreateLocalCredential(const Metadata& metadata, IdentityType identity_type,
absl::Time start_time, absl::Time end_time);
nearby::internal::SharedCredential CreatePublicCredential(
const nearby::internal::LocalCredential& private_credential,
const std::vector<uint8_t>& public_key);
const Metadata& metadata, const std::vector<uint8_t>& public_key);
virtual std::string EncryptDeviceMetadata(
absl::string_view device_metadata_encryption_key,
absl::string_view authenticity_key,
absl::string_view device_metadata_string);
virtual std::string EncryptMetadata(absl::string_view metadata_encryption_key,
absl::string_view key_seed,
absl::string_view metadata_string);
// Extend the key from 16 bytes to 32 bytes.
std::vector<uint8_t> ExtendMetadataEncryptionKey(
absl::string_view device_metadata_encryption_key);
absl::string_view metadata_encryption_key);
private:
struct SubscriberKey {
@@ -40,9 +40,9 @@ namespace {
using ::nearby::CountDownLatch;
using ::nearby::Crypto;
using ::nearby::MediumEnvironment;
using ::nearby::internal::DeviceMetadata;
using ::nearby::internal::IdentityType;
using ::nearby::internal::LocalCredential;
using ::nearby::internal::Metadata;
using ::nearby::internal::SharedCredential;
using ::nearby::internal::IdentityType::IDENTITY_TYPE_PRIVATE;
using ::nearby::internal::IdentityType::IDENTITY_TYPE_TRUSTED;
@@ -53,16 +53,14 @@ using ::testing::status::StatusIs;
constexpr absl::string_view kManagerAppId = "TEST_MANAGER_APP";
constexpr absl::string_view kAccountName = "test account";
DeviceMetadata CreateTestDeviceMetadata(
absl::string_view account_name = kAccountName) {
DeviceMetadata device_metadata;
device_metadata.set_stable_device_id("test_device_id");
device_metadata.set_account_name(account_name);
device_metadata.set_device_name("NP test device");
device_metadata.set_icon_url("test_image.test.com");
device_metadata.set_bluetooth_mac_address("FF:FF:FF:FF:FF:FF");
device_metadata.set_device_type(internal::DeviceMetadata::PHONE);
return device_metadata;
Metadata CreateTestMetadata(absl::string_view account_name = kAccountName) {
Metadata metadata;
metadata.set_device_id("test_device_id");
metadata.set_account_name(account_name);
metadata.set_device_name("NP test device");
metadata.set_device_profile_url("test_image.test.com");
metadata.set_bluetooth_mac_address("FF:FF:FF:FF:FF:FF");
return metadata;
}
CredentialSelector BuildDefaultCredentialSelector() {
@@ -97,10 +95,9 @@ class CredentialManagerImplTest : public ::testing::Test {
public:
explicit MockCredentialManager(SingleThreadExecutor* executor)
: CredentialManagerImpl(executor) {}
MOCK_METHOD(std::string, EncryptDeviceMetadata,
(absl::string_view device_metadata_encryption_key,
absl::string_view authenticity_key,
absl::string_view device_metadata_string),
MOCK_METHOD(std::string, EncryptMetadata,
(absl::string_view metadata_encryption_key,
absl::string_view key_seed, absl::string_view metadata_string),
(override));
};
@@ -122,10 +119,10 @@ class CredentialManagerImplTest : public ::testing::Test {
void AddLocalIdentity(absl::string_view manager_app_id,
absl::string_view account_name,
IdentityType identity_type) {
DeviceMetadata device_metadata = CreateTestDeviceMetadata(account_name);
Metadata metadata = CreateTestMetadata(account_name);
credential_manager_.GenerateCredentials(
device_metadata, manager_app_id, {identity_type},
metadata, manager_app_id, {identity_type},
/*credential_life_cycle_days=*/1,
/*contigous_copy_of_credentials=*/1,
{[](absl::StatusOr<std::vector<SharedCredential>> credentials) {
@@ -140,25 +137,23 @@ class CredentialManagerImplTest : public ::testing::Test {
};
TEST_F(CredentialManagerImplTest, CreateOneCredentialSuccessfully) {
DeviceMetadata device_metadata = CreateTestDeviceMetadata();
Metadata metadata = CreateTestMetadata();
constexpr absl::Time kStartTime = absl::FromUnixSeconds(100000);
constexpr absl::Time kEndTime = absl::FromUnixSeconds(200000);
auto credentials = credential_manager_.CreateLocalCredential(
device_metadata, IDENTITY_TYPE_PRIVATE, kStartTime, kEndTime);
metadata, IDENTITY_TYPE_PRIVATE, kStartTime, kEndTime);
LocalCredential private_credential = credentials.first;
// Verify the private credential.
EXPECT_THAT(private_credential.device_metadata(),
EqualsProto(device_metadata));
EXPECT_EQ(private_credential.identity_type(), IDENTITY_TYPE_PRIVATE);
EXPECT_FALSE(private_credential.secret_id().empty());
EXPECT_EQ(private_credential.start_time_millis(),
absl::ToUnixMillis(kStartTime));
EXPECT_EQ(private_credential.end_time_millis(), absl::ToUnixMillis(kEndTime));
EXPECT_EQ(private_credential.authenticity_key().size(),
EXPECT_EQ(private_credential.key_seed().size(),
CredentialManagerImpl::kAuthenticityKeyByteSize);
EXPECT_FALSE(private_credential.verification_key().empty());
EXPECT_FALSE(private_credential.connection_signing_key().key().empty());
EXPECT_EQ(private_credential.metadata_encryption_key().size(),
kBaseMetadataSize);
@@ -166,8 +161,7 @@ TEST_F(CredentialManagerImplTest, CreateOneCredentialSuccessfully) {
// Verify the public credential.
EXPECT_EQ(public_credential.identity_type(), IDENTITY_TYPE_PRIVATE);
EXPECT_FALSE(public_credential.secret_id().empty());
EXPECT_EQ(private_credential.authenticity_key(),
public_credential.authenticity_key());
EXPECT_EQ(private_credential.key_seed(), public_credential.key_seed());
EXPECT_LE(public_credential.start_time_millis(),
absl::ToUnixMillis(kStartTime));
EXPECT_GE(public_credential.start_time_millis(),
@@ -178,32 +172,31 @@ TEST_F(CredentialManagerImplTest, CreateOneCredentialSuccessfully) {
EXPECT_EQ(Crypto::Sha256(private_credential.metadata_encryption_key())
.AsStringView(),
public_credential.metadata_encryption_key_tag());
EXPECT_FALSE(public_credential.verification_key().empty());
EXPECT_FALSE(
public_credential.connection_signature_verification_key().empty());
EXPECT_FALSE(public_credential.encrypted_metadata_bytes().empty());
// Decrypt the device metadata
auto decrypted_device_metadata = credential_manager_.DecryptDeviceMetadata(
auto decrypted_metadata = credential_manager_.DecryptMetadata(
private_credential.metadata_encryption_key(),
public_credential.authenticity_key(),
public_credential.key_seed(),
public_credential.encrypted_metadata_bytes());
EXPECT_EQ(private_credential.device_metadata().SerializeAsString(),
decrypted_device_metadata);
EXPECT_EQ(metadata.SerializeAsString(), decrypted_metadata);
}
TEST_F(CredentialManagerImplTest, GenerateCredentialsSuccessfully) {
constexpr int kLifeCycleDays = 1;
constexpr int kNumCredentials = 5;
DeviceMetadata device_metadata = CreateTestDeviceMetadata();
Metadata metadata = CreateTestMetadata();
absl::StatusOr<std::vector<SharedCredential>> public_credentials;
std::vector<IdentityType> identityTypes{IDENTITY_TYPE_PRIVATE};
absl::Time previous_start_time;
absl::Time previous_end_time;
credential_manager_.GenerateCredentials(
device_metadata, kManagerAppId, identityTypes, kLifeCycleDays,
kNumCredentials,
metadata, kManagerAppId, identityTypes, kLifeCycleDays, kNumCredentials,
{.credentials_generated_cb =
[&](absl::StatusOr<std::vector<SharedCredential>> credentials) {
public_credentials = std::move(credentials);
@@ -215,19 +208,20 @@ TEST_F(CredentialManagerImplTest, GenerateCredentialsSuccessfully) {
SharedCredential& public_credential = public_credentials->at(i);
EXPECT_EQ(public_credential.identity_type(), IDENTITY_TYPE_PRIVATE);
EXPECT_FALSE(public_credential.secret_id().empty());
absl::Time start_time =
absl::Time start_time_millis =
absl::FromUnixMillis(public_credential.start_time_millis());
absl::Time end_time =
absl::Time end_time_millis =
absl::FromUnixMillis(public_credential.end_time_millis());
if (i > 0) {
EXPECT_GT(start_time, previous_start_time);
EXPECT_GE(previous_end_time, start_time);
EXPECT_GT(end_time, previous_end_time);
EXPECT_GT(start_time_millis, previous_start_time);
EXPECT_GE(previous_end_time, start_time_millis);
EXPECT_GT(end_time_millis, previous_end_time);
}
EXPECT_LT(start_time + absl::Hours(24) * kLifeCycleDays, end_time);
EXPECT_LT(start_time_millis + absl::Hours(24) * kLifeCycleDays,
end_time_millis);
EXPECT_FALSE(public_credential.encrypted_metadata_bytes().empty());
previous_start_time = start_time;
previous_end_time = end_time;
previous_start_time = start_time_millis;
previous_end_time = end_time_millis;
}
}
@@ -314,7 +308,7 @@ TEST_F(CredentialManagerImplTest, NoCallbacksAfterUnsubscribe) {
TEST_F(CredentialManagerImplTest,
GenerateCredentialsSuccessfullyButStoreFailed) {
DeviceMetadata device_metadata = CreateTestDeviceMetadata();
Metadata metadata = CreateTestMetadata();
auto credential_storage_ptr =
std::make_unique<CredentialManagerImplTest::MockCredentialStorage>();
EXPECT_CALL(*credential_storage_ptr, SaveCredentials)
@@ -333,7 +327,7 @@ TEST_F(CredentialManagerImplTest,
std::vector<IdentityType> identityTypes{IDENTITY_TYPE_PRIVATE};
credential_manager_.GenerateCredentials(
device_metadata, kManagerAppId, identityTypes, 1, 2,
metadata, kManagerAppId, identityTypes, 1, 2,
{.credentials_generated_cb =
[&](absl::StatusOr<std::vector<SharedCredential>> credentials) {
public_credentials = std::move(credentials);
@@ -445,14 +439,14 @@ TEST_F(CredentialManagerImplTest, GetPublicCredentialsFailed) {
}
TEST_F(CredentialManagerImplTest, GetCredentialsSuccessfully) {
DeviceMetadata device_metadata = CreateTestDeviceMetadata();
Metadata metadata = CreateTestMetadata();
absl::StatusOr<std::vector<SharedCredential>> public_credentials;
std::vector<IdentityType> identity_types{IDENTITY_TYPE_PRIVATE};
absl::StatusOr<std::vector<LocalCredential>> private_credentials;
CredentialSelector credential_selector = BuildDefaultCredentialSelector();
credential_manager_.GenerateCredentials(
device_metadata, kManagerAppId, identity_types, 1, 1,
metadata, kManagerAppId, identity_types, 1, 1,
{.credentials_generated_cb =
[&](absl::StatusOr<std::vector<SharedCredential>> credentials) {
public_credentials = std::move(credentials);
@@ -471,20 +465,20 @@ TEST_F(CredentialManagerImplTest, GetCredentialsSuccessfully) {
}
TEST_F(CredentialManagerImplTest, PublicCredentialsFailEncryption) {
DeviceMetadata device_metadata = CreateTestDeviceMetadata();
Metadata metadata = CreateTestMetadata();
absl::StatusOr<std::vector<SharedCredential>> public_credentials;
auto credential_manager_ptr =
std::make_unique<CredentialManagerImplTest::MockCredentialManager>(
&executor_);
EXPECT_CALL(*credential_manager_ptr, EncryptDeviceMetadata)
EXPECT_CALL(*credential_manager_ptr, EncryptMetadata)
.WillOnce(::testing::Invoke(
[](absl::string_view device_metadata_encryption_key,
absl::string_view authenticity_key,
absl::string_view device_metadata_string) { return ""; }));
[](absl::string_view metadata_encryption_key,
absl::string_view key_seed,
absl::string_view metadata_string) { return ""; }));
std::vector<IdentityType> identity_types{IDENTITY_TYPE_PRIVATE};
credential_manager_ptr->GenerateCredentials(
device_metadata, kManagerAppId, identity_types, 1, 1,
metadata, kManagerAppId, identity_types, 1, 1,
{.credentials_generated_cb =
[&](absl::StatusOr<std::vector<SharedCredential>> credentials) {
public_credentials = std::move(credentials);
@@ -498,7 +492,7 @@ TEST_F(CredentialManagerImplTest, UpdateLocalCredential) {
constexpr int kSelectedCredentialId = 2;
constexpr uint16_t kSalt = 1000;
absl::Status update_status = absl::UnknownError("");
DeviceMetadata device_metadata = CreateTestDeviceMetadata();
Metadata metadata = CreateTestMetadata();
absl::StatusOr<std::vector<nearby::internal::SharedCredential>>
public_credentials;
std::vector<IdentityType> identity_types{IDENTITY_TYPE_PRIVATE,
@@ -507,7 +501,7 @@ TEST_F(CredentialManagerImplTest, UpdateLocalCredential) {
absl::StatusOr<std::vector<LocalCredential>> modified_private_credentials;
CredentialSelector credential_selector = BuildDefaultCredentialSelector();
credential_manager_.GenerateCredentials(
device_metadata, kManagerAppId, identity_types, 1, kNumCredentials,
metadata, kManagerAppId, identity_types, 1, kNumCredentials,
{.credentials_generated_cb =
[&](absl::StatusOr<std::vector<nearby::internal::SharedCredential>>
credentials) {
+1 -1
View File
@@ -115,7 +115,7 @@ void ScanManager::NotifyFoundBle(ScanSessionId id, BleAdvertisementData data,
if (it->second.decoder.MatchesScanFilter(advert->data_elements)) {
// TODO(b/256913915): Provide more information in PresenceDevice once
// fully implemented
internal::DeviceMetadata metadata;
internal::Metadata metadata;
metadata.set_bluetooth_mac_address(std::string(remote_address));
it->second.callback.on_discovered_cb(PresenceDevice(metadata));
}
+2 -3
View File
@@ -180,7 +180,7 @@ TEST_F(ScanManagerTest, TestNoFilter) {
EXPECT_EQ(manager.ScanningCallbacksLengthForTest(), 0);
}
TEST_F(ScanManagerTest, PresenceDeviceMetadataIsRetained) {
TEST_F(ScanManagerTest, PresenceMetadataIsRetained) {
Mediums mediums;
ScanManager manager(mediums, credential_manager_, executor_);
// Set up advertiser
@@ -198,8 +198,7 @@ TEST_F(ScanManagerTest, PresenceDeviceMetadataIsRetained) {
},
.on_discovered_cb =
[this, &address](PresenceDevice pd) {
if (pd.GetMetadata().has_bluetooth_mac_address() &&
pd.GetMetadata().bluetooth_mac_address() == address) {
if (pd.GetMetadata().bluetooth_mac_address() == address) {
found_latch_.CountDown();
}
}};
+5 -5
View File
@@ -31,23 +31,23 @@ std::string GenerateRandomEndpointId() {
}
} // namespace
PresenceDevice::PresenceDevice(DeviceMetadata device_metadata) noexcept
PresenceDevice::PresenceDevice(Metadata metadata) noexcept
: discovery_timestamp_(nearby::SystemClock::ElapsedRealtime()),
device_motion_(DeviceMotion()),
device_metadata_(device_metadata) {
metadata_(metadata) {
endpoint_id_ = GenerateRandomEndpointId();
}
PresenceDevice::PresenceDevice(DeviceMotion device_motion,
DeviceMetadata device_metadata) noexcept
Metadata metadata) noexcept
: discovery_timestamp_(nearby::SystemClock::ElapsedRealtime()),
device_motion_(device_motion),
device_metadata_(device_metadata) {
metadata_(metadata) {
endpoint_id_ = GenerateRandomEndpointId();
}
std::vector<nearby::ConnectionInfoVariant> PresenceDevice::GetConnectionInfos()
const {
return {nearby::BleConnectionInfo(device_metadata_.bluetooth_mac_address())};
return {nearby::BleConnectionInfo(metadata_.bluetooth_mac_address())};
}
} // namespace presence
} // namespace nearby
+6 -6
View File
@@ -22,7 +22,7 @@
#include "absl/time/time.h"
#include "absl/types/variant.h"
#include "internal/device.h"
#include "internal/proto/device_metadata.pb.h"
#include "internal/proto/metadata.pb.h"
#include "presence/device_motion.h"
namespace nearby {
@@ -31,12 +31,12 @@ namespace presence {
constexpr int kEndpointIdLength = 4;
class PresenceDevice : public nearby::NearbyDevice {
using DeviceMetadata = ::nearby::internal::DeviceMetadata;
using Metadata = ::nearby::internal::Metadata;
public:
explicit PresenceDevice(DeviceMetadata metadata) noexcept;
explicit PresenceDevice(Metadata metadata) noexcept;
explicit PresenceDevice(DeviceMotion device_motion,
DeviceMetadata metadata) noexcept;
Metadata metadata) noexcept;
absl::string_view GetEndpointId() const override { return endpoint_id_; };
void SetEndpointInfo(absl::string_view endpoint_info) {
endpoint_info_ = std::string(endpoint_info);
@@ -49,13 +49,13 @@ class PresenceDevice : public nearby::NearbyDevice {
std::vector<nearby::ConnectionInfoVariant> GetConnectionInfos()
const override;
DeviceMotion GetDeviceMotion() const { return device_motion_; }
DeviceMetadata GetMetadata() const { return device_metadata_; }
Metadata GetMetadata() const { return metadata_; }
absl::Time GetDiscoveryTimestamp() const { return discovery_timestamp_; }
private:
const absl::Time discovery_timestamp_;
const DeviceMotion device_motion_;
const DeviceMetadata device_metadata_;
const Metadata metadata_;
std::string endpoint_id_;
std::string endpoint_info_;
};
+14 -16
View File
@@ -22,13 +22,12 @@
#include "absl/types/variant.h"
#include "internal/platform/ble_connection_info.h"
#include "internal/platform/logging.h"
#include "internal/proto/device_metadata.pb.h"
namespace nearby {
namespace presence {
namespace {
using internal::DeviceMetadata;
using ::nearby::internal::Metadata;
constexpr DeviceMotion::MotionType kDefaultMotionType =
DeviceMotion::MotionType::kPointAndHold;
@@ -36,26 +35,25 @@ constexpr float kDefaultConfidence = 0;
constexpr float kTestConfidence = 0.1;
constexpr absl::string_view kMacAddr = "\x4C\x8B\x1D\xCE\xBA\xD1";
DeviceMetadata CreateTestDeviceMetadata() {
DeviceMetadata device_metadata;
device_metadata.set_stable_device_id("test_device_id");
device_metadata.set_account_name("test_account");
device_metadata.set_device_name("NP test device");
device_metadata.set_icon_url("test_image.test.com");
device_metadata.set_bluetooth_mac_address(kMacAddr);
device_metadata.set_device_type(internal::DeviceMetadata::PHONE);
return device_metadata;
Metadata CreateTestMetadata() {
Metadata metadata;
metadata.set_device_id("test_device_id");
metadata.set_account_name("test_account");
metadata.set_device_name("NP test device");
metadata.set_device_profile_url("test_image.test.com");
metadata.set_bluetooth_mac_address(kMacAddr);
return metadata;
}
TEST(PresenceDeviceTest, DefaultMotionEquals) {
DeviceMetadata metadata = CreateTestDeviceMetadata();
Metadata metadata = CreateTestMetadata();
PresenceDevice device1(metadata);
PresenceDevice device2(metadata);
EXPECT_EQ(device1, device2);
}
TEST(PresenceDeviceTest, ExplicitInitEquals) {
DeviceMetadata metadata = CreateTestDeviceMetadata();
Metadata metadata = CreateTestMetadata();
PresenceDevice device1 =
PresenceDevice({kDefaultMotionType, kTestConfidence}, metadata);
PresenceDevice device2 =
@@ -64,7 +62,7 @@ TEST(PresenceDeviceTest, ExplicitInitEquals) {
}
TEST(PresenceDeviceTest, ExplicitInitNotEquals) {
DeviceMetadata metadata = CreateTestDeviceMetadata();
Metadata metadata = CreateTestMetadata();
PresenceDevice device1 = PresenceDevice({kDefaultMotionType}, metadata);
PresenceDevice device2 =
PresenceDevice({kDefaultMotionType, kTestConfidence}, metadata);
@@ -72,7 +70,7 @@ TEST(PresenceDeviceTest, ExplicitInitNotEquals) {
}
TEST(PresenceDeviceTest, TestGetBluetoothAddress) {
DeviceMetadata metadata = CreateTestDeviceMetadata();
Metadata metadata = CreateTestMetadata();
PresenceDevice device = PresenceDevice({kDefaultMotionType}, metadata);
auto info = (device.GetConnectionInfos().at(0));
ASSERT_TRUE(absl::holds_alternative<nearby::BleConnectionInfo>(info));
@@ -82,7 +80,7 @@ TEST(PresenceDeviceTest, TestGetBluetoothAddress) {
}
TEST(PresenceDeviceTest, TestEndpointIdIsCorrectLength) {
DeviceMetadata metadata = CreateTestDeviceMetadata();
Metadata metadata = CreateTestMetadata();
PresenceDevice device = PresenceDevice({kDefaultMotionType}, metadata);
EXPECT_EQ(device.GetEndpointId().length(), kEndpointIdLength);
}
+1 -1
View File
@@ -107,7 +107,7 @@ inline bool operator!=(const LegacyPresenceScanFilter& a,
* An encapsulation of various parameters for requesting nearby scans.
*/
struct ScanRequest {
// Same as DeviceMetadata.account_name, to fetch private credential
// Same as Metadata.account_name, to fetch private credential
// to broadcast.
std::string account_name;
-10
View File
@@ -23,11 +23,6 @@ proto_library(
srcs = ["connections_enums.proto"],
)
java_lite_proto_library(
name = "connections_enums_java_proto_lite",
deps = [":connections_enums_proto"],
)
java_proto_library(
name = "connections_enums_java_proto",
deps = [":connections_enums_proto"],
@@ -53,11 +48,6 @@ cc_proto_library(
],
)
java_lite_proto_library(
name = "sharing_enums_java_proto_lite",
deps = [":sharing_enums_proto"],
)
java_proto_library(
name = "sharing_enums_java_proto",
deps = [":sharing_enums_proto"],
-5
View File
@@ -23,11 +23,6 @@ proto_library(
srcs = ["error_code_enums.proto"],
)
java_lite_proto_library(
name = "error_code_enums_java_proto_lite",
deps = [":error_code_enums_proto"],
)
cc_proto_library(
name = "error_code_enums_cc_proto",
deps = [":error_code_enums_proto"],
-36
View File
@@ -23,15 +23,6 @@ proto_library(
],
)
java_lite_proto_library(
name = "nfc_frames_java_proto_lite",
visibility = [
"//java/com/google/android/gmscore/integ/modules/nearby/src/com/google/android/gms/nearby/mediums:__subpackages__",
"//javatests/com/google/android/gmscore/integ/modules/nearby/src/com/google/android/gms/nearby/mediums:__subpackages__",
],
deps = [":nfc_frames_proto"],
)
proto_library(
name = "wifi_aware_frames_proto",
srcs = [
@@ -39,15 +30,6 @@ proto_library(
],
)
java_lite_proto_library(
name = "wifi_aware_frames_java_proto_lite",
visibility = [
"//java/com/google/android/gmscore/integ/modules/nearby/src/com/google/android/gms/nearby/mediums:__subpackages__",
"//javatests/com/google/android/gmscore/integ/modules/nearby/src/com/google/android/gms/nearby/mediums:__subpackages__",
],
deps = [":wifi_aware_frames_proto"],
)
proto_library(
name = "web_rtc_signaling_frames_proto",
srcs = [
@@ -61,15 +43,6 @@ cc_proto_library(
deps = [":web_rtc_signaling_frames_proto"],
)
java_lite_proto_library(
name = "web_rtc_signaling_frames_java_proto_lite",
visibility = [
"//java/com/google/android/gmscore/integ/modules/nearby/src/com/google/android/gms/nearby/mediums:__subpackages__",
"//javatests/com/google/android/gmscore/integ/modules/nearby/src/com/google/android/gms/nearby/mediums:__subpackages__",
],
deps = [":web_rtc_signaling_frames_proto"],
)
proto_library(
name = "ble_frames_proto",
srcs = [
@@ -77,15 +50,6 @@ proto_library(
],
)
java_lite_proto_library(
name = "ble_frames_java_proto_lite",
visibility = [
"//java/com/google/android/gmscore/integ/modules/nearby/src/com/google/android/gms/nearby/mediums:__subpackages__",
"//javatests/com/google/android/gmscore/integ/modules/nearby/src/com/google/android/gms/nearby/mediums:__subpackages__",
],
deps = [":ble_frames_proto"],
)
cc_proto_library(
name = "ble_frames_cc_proto",
deps = [