Files
nearby/presence/implementation/advertisement_decoder_new_format_test.cc
T
hai007 d1f3a91e24 Initial implementation of rust decoder
PiperOrigin-RevId: 624312324
2024-04-12 15:40:44 -07:00

157 lines
6.3 KiB
C++

// Copyright 2022 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.
#ifdef USE_RUST_DECODER
#include <string>
#include <vector>
#include "gmock/gmock.h"
#include "protobuf-matchers/protocol-buffer-matchers.h"
#include "gtest/gtest.h"
#include "absl/container/flat_hash_map.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/escaping.h"
#include "absl/strings/string_view.h"
#include "internal/platform/byte_array.h"
#include "internal/proto/credential.pb.h"
#include "presence/data_element.h"
#include "presence/implementation/advertisement_decoder.h"
#include "presence/implementation/advertisement_decoder_rust_impl.h"
namespace nearby {
namespace presence {
namespace {
using ::nearby::ByteArray; // NOLINT
using ::nearby::internal::IdentityType; // NOLINT
using ::nearby::internal::SharedCredential; // NOLINT
using ::testing::ElementsAre;
using ::testing::status::StatusIs;
TEST(AdvertisementDecoderImpl, DecodePublicAdvertisement) {
std::string V0AdvPlaintextBytes =
"00" // Adv Header V0 unencrypted
"1503"; // length 1 Tx Power DE value 3
AdvertisementDecoderImpl decoder = AdvertisementDecoderImpl();
absl::StatusOr<Advertisement> result =
decoder.DecodeAdvertisement(absl::HexStringToBytes(V0AdvPlaintextBytes));
ASSERT_OK(result);
EXPECT_EQ(result->identity_type, IdentityType::IDENTITY_TYPE_PUBLIC);
EXPECT_EQ(result->version, 0);
EXPECT_THAT(result->data_elements,
ElementsAre(DataElement(DataElement::kTxPowerFieldType,
absl::HexStringToBytes("03"))));
}
TEST(AdvertisementDecoderImpl, DecodePublicAdvertisementMultiDe) {
std::string V0AdvPlaintextMultiDeBytes =
"00" // Adv Header V0 unencrypted
"1505" // length 1 Tx Power DE value 5
"264040"; // length 2 actions de
AdvertisementDecoderImpl decoder = AdvertisementDecoderImpl();
absl::StatusOr<Advertisement> result = decoder.DecodeAdvertisement(
absl::HexStringToBytes(V0AdvPlaintextMultiDeBytes));
ASSERT_OK(result);
EXPECT_EQ(result->identity_type, IdentityType::IDENTITY_TYPE_PUBLIC);
EXPECT_EQ(result->version, 0);
EXPECT_THAT(result->data_elements,
ElementsAre(DataElement(DataElement::kTxPowerFieldType,
absl::HexStringToBytes("05")),
DataElement(DataElement::kActionFieldType,
absl::HexStringToBytes("00"))));
}
// V0 encrypted advertisement data - ripped out of np_adv/tests/examples_v0.rs
TEST(AdvertisementDecoderImpl, DecodeEncryptedAdvertisement) {
std::string V0AdvEncryptedBytes = "042222D82212EF16DBF872F2A3A7C0FA5248EC";
ByteArray seed({
0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
});
ByteArray known_mac({0x09, 0xFE, 0x9E, 0x81, 0xB7, 0x3E, 0x5E, 0xCC,
0x76, 0x59, 0x57, 0x71, 0xE0, 0x1F, 0xFB, 0x34,
0x38, 0xE7, 0x5F, 0x24, 0xA7, 0x69, 0x56, 0xA0,
0xB8, 0xEA, 0x67, 0xD1, 0x1C, 0x3E, 0x36, 0xFD});
SharedCredential public_credential;
public_credential.set_key_seed(seed.AsStringView());
public_credential.set_metadata_encryption_key_tag_v0(
known_mac.AsStringView());
absl::flat_hash_map<IdentityType, std::vector<internal::SharedCredential>>
credentials;
credentials[IdentityType::IDENTITY_TYPE_PRIVATE].push_back(public_credential);
AdvertisementDecoderImpl decoder = AdvertisementDecoderImpl(&credentials);
absl::StatusOr<Advertisement> result =
decoder.DecodeAdvertisement(absl::HexStringToBytes(V0AdvEncryptedBytes));
ASSERT_OK(result);
EXPECT_EQ(result->identity_type, IdentityType::IDENTITY_TYPE_PRIVATE);
EXPECT_EQ(result->version, 0);
EXPECT_THAT(result->data_elements,
ElementsAre(DataElement(DataElement::kSaltFieldType,
absl::HexStringToBytes("2222")),
DataElement(DataElement::kTxPowerFieldType,
absl::HexStringToBytes("03"))));
}
TEST(AdvertisementDecoderImpl, DecodeEncryptedAdvertisementNoCreds) {
std::string V0AdvEncryptedBytes = "042222D82212EF16DBF872F2A3A7C0FA5248EC";
AdvertisementDecoderImpl decoder = AdvertisementDecoderImpl();
absl::StatusOr<Advertisement> result =
decoder.DecodeAdvertisement(absl::HexStringToBytes(V0AdvEncryptedBytes));
EXPECT_THAT(result, StatusIs(absl::StatusCode::kUnavailable));
}
TEST(AdvertisementDecoderImpl, V1AdvCurrentlyUnsupported) {
std::string V1Adv =
"20" // Version header V1
"00" // format
"02" // section len
"1503"; // Tx power value 3
AdvertisementDecoderImpl decoder = AdvertisementDecoderImpl();
absl::StatusOr<Advertisement> result =
decoder.DecodeAdvertisement(absl::HexStringToBytes(V1Adv));
EXPECT_THAT(result, StatusIs(absl::StatusCode::kUnimplemented));
}
TEST(AdvertisementDecoderImpl, V0InvalidEmptyAdv) {
std::string V1Adv = "00";
AdvertisementDecoderImpl decoder = AdvertisementDecoderImpl();
absl::StatusOr<Advertisement> result =
decoder.DecodeAdvertisement(absl::HexStringToBytes(V1Adv));
EXPECT_THAT(result, StatusIs(absl::StatusCode::kInvalidArgument));
}
TEST(AdvertisementDecoderImpl, V0InvalidAdvContents) {
std::string invalid_v0_adv =
"00" // Adv Header V0 unencrypted
"3503"; // length 3 Tx Power DE with only 1 byte
AdvertisementDecoderImpl decoder = AdvertisementDecoderImpl();
absl::StatusOr<Advertisement> result =
decoder.DecodeAdvertisement(absl::HexStringToBytes(invalid_v0_adv));
EXPECT_THAT(result, StatusIs(absl::StatusCode::kInvalidArgument));
}
} // namespace
} // namespace presence
} // namespace nearby
#endif