Project import generated by Copybara. GitOrigin-RevId: 0ff286ff293d733f2763ca111b49e0467fe63f26 Change-Id: I26bf2cb36f08fb2e63ff9c6dfcb1d6964d0a03b2
diff --git a/nearby/Cargo.lock b/nearby/Cargo.lock index dd4f6ff..813de5f 100644 --- a/nearby/Cargo.lock +++ b/nearby/Cargo.lock
@@ -1377,7 +1377,6 @@ "np_hkdf", "rand", "rand_ext", - "rmp-serde", "serde", "serde_json", "sink", @@ -1585,12 +1584,6 @@ ] [[package]] -name = "paste" -version = "1.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" - -[[package]] name = "pkcs8" version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1893,28 +1886,6 @@ ] [[package]] -name = "rmp" -version = "0.8.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f9860a6cc38ed1da53456442089b4dfa35e7cedaa326df63017af88385e6b20" -dependencies = [ - "byteorder", - "num-traits", - "paste", -] - -[[package]] -name = "rmp-serde" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bffea85eea980d8a74453e5d02a8d93028f3c34725de143085a844ebe953258a" -dependencies = [ - "byteorder", - "rmp", - "serde", -] - -[[package]] name = "rstest" version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/nearby/connections/ukey2/ukey2_c_ffi/cpp/CMakeLists.txt b/nearby/connections/ukey2/ukey2_c_ffi/cpp/CMakeLists.txt index 165d861..a8b7b9d 100644 --- a/nearby/connections/ukey2/ukey2_c_ffi/cpp/CMakeLists.txt +++ b/nearby/connections/ukey2/ukey2_c_ffi/cpp/CMakeLists.txt
@@ -21,7 +21,9 @@ include_directories( ${CMAKE_SOURCE_DIR}/ukey2_c_ffi/cpp/) +include(GoogleTest) include(ExternalProject) + set_directory_properties(PROPERTIES EP_PREFIX ${CMAKE_BINARY_DIR}/target/tmp) ExternalProject_Add( ukey2_c_ffi @@ -35,11 +37,9 @@ set(CMAKE_CXX_STANDARD 20) if(UNIX) - add_compile_options(-Wall -Werror -Wextra -Wimplicit-fallthrough -Wextra-semi + add_compile_options(-Wall -Wextra -Wimplicit-fallthrough -Wextra-semi -Wno-missing-field-initializers -Wno-unused-parameter -Wno-psabi - -Wno-unneeded-internal-declaration - -Wno-ignored-pragma-optimize - -Wno-bitfield-constant-conversion -Wno-deprecated-this-capture -Wshadow + -Wshadow -Wsign-compare) elseif(MSVC) add_compile_options(-W4 -MD) @@ -83,5 +83,4 @@ ) endif() -include(GoogleTest) gtest_discover_tests(ffi_test)
diff --git a/nearby/connections/ukey2/ukey2_connections/fuzz/Cargo.lock b/nearby/connections/ukey2/ukey2_connections/fuzz/Cargo.lock index 3f72ae0..b4e08bd 100644 --- a/nearby/connections/ukey2/ukey2_connections/fuzz/Cargo.lock +++ b/nearby/connections/ukey2/ukey2_connections/fuzz/Cargo.lock
@@ -412,7 +412,7 @@ dependencies = [ "proc-macro2", "quote", - "syn 2.0.26", + "syn", ] [[package]] @@ -426,17 +426,6 @@ ] [[package]] -name = "derive-getters" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0122f262bf9c9a367829da84f808d9fb128c10ef283bbe7b0922a77cf07b2747" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] name = "derive_arbitrary" version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -444,7 +433,7 @@ dependencies = [ "proc-macro2", "quote", - "syn 2.0.26", + "syn", ] [[package]] @@ -1151,7 +1140,7 @@ dependencies = [ "proc-macro2", "quote", - "syn 2.0.26", + "syn", ] [[package]] @@ -1190,17 +1179,6 @@ [[package]] name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" version = "2.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "45c3457aacde3c65315de5031ec191ce46604304d2446e803d71ade03308d970" @@ -1247,7 +1225,7 @@ dependencies = [ "proc-macro2", "quote", - "syn 2.0.26", + "syn", ] [[package]] @@ -1310,7 +1288,6 @@ version = "0.1.0" dependencies = [ "crypto_provider", - "derive-getters", "log", "num-bigint", "rand", @@ -1376,7 +1353,7 @@ "once_cell", "proc-macro2", "quote", - "syn 2.0.26", + "syn", "wasm-bindgen-shared", ] @@ -1398,7 +1375,7 @@ dependencies = [ "proc-macro2", "quote", - "syn 2.0.26", + "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ]
diff --git a/nearby/presence/CMakeLists.txt b/nearby/presence/CMakeLists.txt index d2a251b..9670c34 100644 --- a/nearby/presence/CMakeLists.txt +++ b/nearby/presence/CMakeLists.txt
@@ -17,7 +17,7 @@ project(NearbyProtocol) # required for designated initializers on MSVC -set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD 20) # root directory of repo set(BETO_CORE_ROOT ${CMAKE_SOURCE_DIR}/../..)
diff --git a/nearby/presence/np_adv/Cargo.toml b/nearby/presence/np_adv/Cargo.toml index e502c35..9b576a6 100644 --- a/nearby/presence/np_adv/Cargo.toml +++ b/nearby/presence/np_adv/Cargo.toml
@@ -39,7 +39,6 @@ criterion.workspace = true crypto_provider_default = { workspace = true, features = ["std", "rustcrypto"] } np_ed25519 = { workspace = true, features = ["std"] } -rmp-serde = "1.1.2" sink = { workspace = true, features = ["std"] } [[bench]]
diff --git a/nearby/presence/np_adv/tests/examples_v1.rs b/nearby/presence/np_adv/tests/examples_v1.rs index 94b9d75..6e93a3d 100644 --- a/nearby/presence/np_adv/tests/examples_v1.rs +++ b/nearby/presence/np_adv/tests/examples_v1.rs
@@ -90,13 +90,13 @@ } impl IdentityMetadata { - /// Serialize this identity metadata to a MsgPack byte-string. + /// Serialize this identity metadata to a json byte-string. fn to_bytes(&self) -> Vec<u8> { - rmp_serde::to_vec(&self).expect("serialization should always succeed") + serde_json::to_vec(self).expect("Identity metadata serialization is infallible") } - /// Attempt to deserialize identity metadata from a MsgPack byte-string. + /// Attempt to deserialize identity metadata from a json byte-string. fn try_from_bytes(serialized: &[u8]) -> Option<Self> { - rmp_serde::from_slice(serialized).ok() + serde_json::from_slice(serialized).ok() } }
diff --git a/nearby/presence/np_cpp_ffi/include/nearby_protocol.h b/nearby/presence/np_cpp_ffi/include/nearby_protocol.h index 1e16eef..2cb410d 100644 --- a/nearby/presence/np_cpp_ffi/include/nearby_protocol.h +++ b/nearby/presence/np_cpp_ffi/include/nearby_protocol.h
@@ -19,6 +19,8 @@ #include "absl/strings/str_format.h" #include "np_cpp_ffi_types.h" +#include <span> + // This namespace provides a C++ API surface to the Rust nearby protocol // implementation. This is a wrapper over the np_ffi::internal namespace defined // in the headers np_cpp_ffi_functions.h and np_cpp_ffi_types.h which are @@ -50,9 +52,10 @@ namespace nearby_protocol { // Re-exporting cbindgen generated types which are used in the public API +using np_ffi::internal::AddCredentialToSlabResult; using np_ffi::internal::BooleanActionType; -using np_ffi::internal::CreateCredentialSlabResultKind; using np_ffi::internal::CreateCredentialBookResultKind; +using np_ffi::internal::CreateCredentialSlabResultKind; using np_ffi::internal::DeserializeAdvertisementResultKind; using np_ffi::internal::DeserializedV0AdvertisementKind; using np_ffi::internal::DeserializedV0IdentityKind; @@ -67,8 +70,12 @@ // All of the types defined in this header class RawAdvertisementPayload; class CredentialBook; +class CredentialSlab; class Deserializer; class DeserializeAdvertisementResult; +class MatchedCredentialData; +class V0MatchableCredential; +class V1MatchableCredential; // V0 Classes class DeserializedV0Advertisement; @@ -156,6 +163,13 @@ // Creates a new instance of a CredentialSlab, returns the CredentialSlab on // success or a Status code on failure [[nodiscard]] static absl::StatusOr<CredentialSlab> TryCreate(); + + // Adds a V0 credential to the slab + [[nodiscard]] absl::Status AddV0Credential(V0MatchableCredential v0_cred); + + // Adds a V1 credential to the slab + [[nodiscard]] absl::Status AddV1Credential(V1MatchableCredential v1_cred); + private: friend class CredentialBook; explicit CredentialSlab(np_ffi::internal::CredentialSlab credential_slab) @@ -189,7 +203,8 @@ // returning the CredentialBook on success or a Status code on failure. // The passed credential-slab will be deallocated if this operation // is successful. - [[nodiscard]] static absl::StatusOr<CredentialBook> TryCreateFromSlab(CredentialSlab &slab); + [[nodiscard]] static absl::StatusOr<CredentialBook> + TryCreateFromSlab(CredentialSlab &slab); private: friend class Deserializer; @@ -200,6 +215,64 @@ bool moved_; }; +// Holds data associated with a specific credential which will be returned to +// the caller when it is successfully matched with an advertisement. +class MatchedCredentialData { +public: + // Creates matched credential data from a provided credential_id used to + // correlate the data back to its full credential data, and the metadata byte + // buffer as copied from the given span over bytes. After calling + // this the bytes are copied into the rust code, so the + // encrypted_metadata_bytes_buffer can be freed. + // + // Safety: this is safe if the span is over a valid buffer of bytes. The copy + // from the memory address isn't atomic, so concurrent modification of the + // array from another thread would cause undefined behavior. + [[nodiscard]] MatchedCredentialData(uint32_t cred_id, + std::span<uint8_t> metadata_bytes); + +private: + np_ffi::internal::FfiMatchedCredential data_; + friend class V0MatchableCredential; + friend class V1MatchableCredential; +}; + +// Holds the v0 credential data needed by the deserializer to decrypt +// advertisements, along with some provided matched data that will be returned +// back to the caller upon a successful credential match. +class V0MatchableCredential { +public: + // Creates a new V0MatchableCredential from a key seed, its calculated hmac + // value and some match data. + [[nodiscard]] V0MatchableCredential( + std::array<uint8_t, 32> key_seed, + std::array<uint8_t, 32> legacy_metadata_key_hmac, + MatchedCredentialData matched_credential_data); + +private: + friend class CredentialSlab; + np_ffi::internal::V0MatchableCredential internal_{}; +}; + +// Holds the v1 credential data needed by the deserializer to decrypt +// advertisements, along with some provided matched data that will be returned +// back to the caller upon a successful credential match. +class V1MatchableCredential { +public: + // Creates a new V1MatchableCredential from key material, its calculated hmac + // value and some match data. + [[nodiscard]] V1MatchableCredential( + std::array<uint8_t, 32> key_seed, + std::array<uint8_t, 32> expected_unsigned_metadata_key_hmac, + std::array<uint8_t, 32> expected_signed_metadata_key_hmac, + std::array<uint8_t, 32> pub_key, + MatchedCredentialData matched_credential_data); + +private: + friend class CredentialSlab; + np_ffi::internal::V1MatchableCredential internal_; +}; + // Representation of a buffer of bytes returned from deserialization APIs template <size_t N> class ByteBuffer { public:
diff --git a/nearby/presence/np_cpp_ffi/nearby_protocol.cc b/nearby/presence/np_cpp_ffi/nearby_protocol.cc index 106eb77..b6730ef 100644 --- a/nearby/presence/np_cpp_ffi/nearby_protocol.cc +++ b/nearby/presence/np_cpp_ffi/nearby_protocol.cc
@@ -140,13 +140,47 @@ return *this; } -absl::StatusOr<CredentialBook> CredentialBook::TryCreateFromSlab(CredentialSlab &slab) { +absl::Status CredentialSlab::AddV0Credential(V0MatchableCredential v0_cred) { + assert_panic(!this->moved_); + auto result = np_ffi::internal::np_ffi_CredentialSlab_add_v0_credential( + this->credential_slab_, v0_cred.internal_); + switch (result) { + case AddCredentialToSlabResult::Success: { + return absl::OkStatus(); + } + case AddCredentialToSlabResult::InvalidHandle: { + return absl::InvalidArgumentError( + "invalid credential slab handle provided"); + } + } +} + +absl::Status CredentialSlab::AddV1Credential(V1MatchableCredential v1_cred) { + assert_panic(!this->moved_); + auto result = np_ffi::internal::np_ffi_CredentialSlab_add_v1_credential( + this->credential_slab_, v1_cred.internal_); + switch (result) { + case AddCredentialToSlabResult::Success: { + return absl::OkStatus(); + } + case AddCredentialToSlabResult::InvalidHandle: { + return absl::InvalidArgumentError( + "invalid credential slab handle provided"); + } + } +} + +absl::StatusOr<CredentialBook> +CredentialBook::TryCreateFromSlab(CredentialSlab &slab) { assert_panic(!slab.moved_); - auto result = np_ffi::internal::np_ffi_create_credential_book_from_slab(slab.credential_slab_); + auto result = np_ffi::internal::np_ffi_create_credential_book_from_slab( + slab.credential_slab_); auto kind = np_ffi::internal::np_ffi_CreateCredentialBookResult_kind(result); switch (kind) { case CreateCredentialBookResultKind::Success: { - auto book = np_ffi::internal::np_ffi_CreateCredentialBookResult_into_SUCCESS(result); + auto book = + np_ffi::internal::np_ffi_CreateCredentialBookResult_into_SUCCESS( + result); slab.moved_ = true; return CredentialBook(book); } @@ -343,10 +377,11 @@ } } -DeserializedV0IdentityKind LegibleDeserializedV0Advertisement::GetIdentityKind() { +DeserializedV0IdentityKind +LegibleDeserializedV0Advertisement::GetIdentityKind() { assert_panic(!this->moved_); - auto result = - np_ffi::internal::np_ffi_LegibleDeserializedV0Advertisement_get_identity_kind( + auto result = np_ffi::internal:: + np_ffi_LegibleDeserializedV0Advertisement_get_identity_kind( legible_v0_advertisement_); return result; } @@ -536,4 +571,40 @@ return ByteBuffer(v1_data_element_.generic._0.payload); } +MatchedCredentialData::MatchedCredentialData( + uint32_t cred_id, std::span<uint8_t> metadata_bytes) { + this->data_ = {cred_id, metadata_bytes.data(), metadata_bytes.size()}; +} + +template <typename T, size_t N> +static void CopyToRawArray(T (&dest)[N], const std::array<T, N> &src) { + memcpy(dest, src.data(), sizeof(T) * N); +} + +V0MatchableCredential::V0MatchableCredential( + std::array<uint8_t, 32> key_seed, + std::array<uint8_t, 32> legacy_metadata_key_hmac, + MatchedCredentialData matched_credential_data) { + np_ffi::internal::V0DiscoveryCredential discovery_cred{}; + CopyToRawArray(discovery_cred.key_seed, key_seed); + CopyToRawArray(discovery_cred.legacy_metadata_key_hmac, + legacy_metadata_key_hmac); + this->internal_ = {discovery_cred, matched_credential_data.data_}; +} + +V1MatchableCredential::V1MatchableCredential( + std::array<uint8_t, 32> key_seed, + std::array<uint8_t, 32> expected_unsigned_metadata_key_hmac, + std::array<uint8_t, 32> expected_signed_metadata_key_hmac, + std::array<uint8_t, 32> pub_key, + MatchedCredentialData matched_credential_data) { + np_ffi::internal::V1DiscoveryCredential discovery_cred{}; + CopyToRawArray(discovery_cred.key_seed, key_seed); + CopyToRawArray(discovery_cred.expected_unsigned_metadata_key_hmac, + expected_unsigned_metadata_key_hmac); + CopyToRawArray(discovery_cred.expected_signed_metadata_key_hmac, + expected_signed_metadata_key_hmac); + CopyToRawArray(discovery_cred.pub_key, pub_key); + this->internal_ = {discovery_cred, matched_credential_data.data_}; +} } // namespace nearby_protocol
diff --git a/nearby/presence/np_cpp_ffi/sample/main.cc b/nearby/presence/np_cpp_ffi/sample/main.cc index a02a523..1d273da 100644 --- a/nearby/presence/np_cpp_ffi/sample/main.cc +++ b/nearby/presence/np_cpp_ffi/sample/main.cc
@@ -81,10 +81,8 @@ auto v1_byte_string = "20" // V1 Advertisement header "04" // Section Header "03" // Public Identity DE header - "260046" // Length 2 Actions DE - "03" // Section Header - "03" // Public Identity DE header - "1505"; // Length 1 Tx Power DE with value 5 + "260046";// Length 2 Actions DE + auto v1_bytes = absl::HexStringToBytes(v1_byte_string); auto v1_buffer = nearby_protocol::ByteBuffer<255>::CopyFrom(v1_bytes); nearby_protocol::RawAdvertisementPayload v1_payload(v1_buffer.value());
diff --git a/nearby/presence/np_cpp_ffi/tests/CMakeLists.txt b/nearby/presence/np_cpp_ffi/tests/CMakeLists.txt index b5ff838..23d02a4 100644 --- a/nearby/presence/np_cpp_ffi/tests/CMakeLists.txt +++ b/nearby/presence/np_cpp_ffi/tests/CMakeLists.txt
@@ -17,7 +17,7 @@ deserialize_result_tests.cc deserialize_v0_tests.cc deserialize_v1_tests.cc - credential_slab_tests.cc + credential_slab_tests.cc credential_book_tests.cc byte_buffer_tests.cc np_cpp_test.h
diff --git a/nearby/presence/np_cpp_ffi/tests/byte_buffer_tests.cc b/nearby/presence/np_cpp_ffi/tests/byte_buffer_tests.cc index 15f262e..7e1a048 100644 --- a/nearby/presence/np_cpp_ffi/tests/byte_buffer_tests.cc +++ b/nearby/presence/np_cpp_ffi/tests/byte_buffer_tests.cc
@@ -13,12 +13,13 @@ // limitations under the License. #include "nearby_protocol.h" +#include "np_cpp_test.h" #include "shared_test_util.h" #include "absl/strings/escaping.h" #include "gtest/gtest.h" -TEST(ByteBufferTests, ByteBufferMaxLength) { +TEST_F(NpCppTest, ByteBufferMaxLength) { // Each hex byte takes up 2 characters so length 510 string = 255 bytes of hex auto str_bytes = generate_hex_string(510); auto bytes = absl::HexStringToBytes(str_bytes); @@ -28,7 +29,7 @@ ASSERT_EQ(bytes, string); } -TEST(ByteBufferTooLarge, ByteBufferInvalidLength) { +TEST_F(NpCppTest, ByteBufferInvalidLength) { // 256 bytes should fail auto str_bytes = generate_hex_string(512); auto bytes = absl::HexStringToBytes(str_bytes); @@ -36,26 +37,26 @@ ASSERT_FALSE(buffer.ok()); } -TEST(ByteBufferTests, ByteBufferRoundTrip) { +TEST_F(NpCppTest, ByteBufferRoundTrip) { auto bytes = absl::HexStringToBytes("2003031503"); auto buffer = nearby_protocol::ByteBuffer<255>::CopyFrom(bytes); auto string = buffer.value().ToString(); ASSERT_EQ(bytes, string); } -TEST(ByteBufferTests, ByteBufferPayloadWrongSize) { +TEST_F(NpCppTest, ByteBufferPayloadWrongSize) { auto bytes = absl::HexStringToBytes("1111111111111111111111"); auto buffer = nearby_protocol::ByteBuffer<10>::CopyFrom(bytes); ASSERT_FALSE(buffer.ok()); } -TEST(ByteBufferTests, ByteBufferEmptyString) { +TEST_F(NpCppTest, ByteBufferEmptyString) { auto bytes = absl::HexStringToBytes(""); auto buffer = nearby_protocol::ByteBuffer<10>::CopyFrom(bytes); ASSERT_TRUE(buffer.ok()); } -TEST(ByteBufferTests, ByteBufferToVector) { +TEST_F(NpCppTest, ByteBufferToVector) { auto bytes = absl::HexStringToBytes("1234567890"); auto buffer = nearby_protocol::ByteBuffer<100>::CopyFrom(bytes); auto vec = buffer.value().ToVector(); @@ -63,7 +64,7 @@ ASSERT_EQ(vec, expected); } -TEST(ByteBufferTests, ByteBufferEndToEndPayloadAsString) { +TEST_F(NpCppTest, ByteBufferEndToEndPayloadAsString) { std::string bytes = absl::HexStringToBytes("2003031503"); auto buffer = nearby_protocol::ByteBuffer<255>::CopyFrom(bytes); ASSERT_TRUE(buffer.ok()); @@ -71,7 +72,9 @@ nearby_protocol::RawAdvertisementPayload adv(buffer.value()); auto credential_slab = nearby_protocol::CredentialSlab::TryCreate().value(); - auto credential_book = nearby_protocol::CredentialBook::TryCreateFromSlab(credential_slab).value(); + auto credential_book = + nearby_protocol::CredentialBook::TryCreateFromSlab(credential_slab) + .value(); auto str = nearby_protocol::Deserializer::DeserializeAdvertisement( adv, credential_book) .IntoV1()
diff --git a/nearby/presence/np_cpp_ffi/tests/credential_book_tests.cc b/nearby/presence/np_cpp_ffi/tests/credential_book_tests.cc index dcaf421..af8fc0d 100644 --- a/nearby/presence/np_cpp_ffi/tests/credential_book_tests.cc +++ b/nearby/presence/np_cpp_ffi/tests/credential_book_tests.cc
@@ -37,7 +37,7 @@ ASSERT_TRUE(absl::IsResourceExhausted(book3_result.status())); } -TEST_F(NpCppTest, TestMoveConstructor) { +TEST_F(NpCppTest, TestBookMoveConstructor) { auto slab = nearby_protocol::CredentialSlab::TryCreate().value(); auto book = nearby_protocol::CredentialBook::TryCreateFromSlab(slab).value(); auto deserialize_result = @@ -69,7 +69,7 @@ ""); } -TEST_F(NpCppTest, TestMoveAssignment) { +TEST_F(NpCppTest, TestBookMoveAssignment) { auto slab = nearby_protocol::CredentialSlab::TryCreate().value(); auto book = nearby_protocol::CredentialBook::TryCreateFromSlab(slab).value(); auto deserialize_result =
diff --git a/nearby/presence/np_cpp_ffi/tests/credential_slab_tests.cc b/nearby/presence/np_cpp_ffi/tests/credential_slab_tests.cc index f715361..b99ab5e 100644 --- a/nearby/presence/np_cpp_ffi/tests/credential_slab_tests.cc +++ b/nearby/presence/np_cpp_ffi/tests/credential_slab_tests.cc
@@ -13,8 +13,8 @@ // limitations under the License. #include "nearby_protocol.h" -#include "shared_test_util.h" #include "np_cpp_test.h" +#include "shared_test_util.h" #include "gtest/gtest.h" @@ -41,16 +41,154 @@ // credential-book. nearby_protocol::CredentialSlab next_slab(std::move(slab)); - auto maybe_book = nearby_protocol::CredentialBook::TryCreateFromSlab(next_slab); + auto maybe_book = + nearby_protocol::CredentialBook::TryCreateFromSlab(next_slab); ASSERT_TRUE(maybe_book.ok()); // Now, both slabs should be moved-out-of, since `TryCreateFromSlab` takes // ownership. Verify that this is the case, and attempts to re-use the slabs // result in an assert failure. ASSERT_DEATH([[maybe_unused]] auto failure = - nearby_protocol::CredentialBook::TryCreateFromSlab(slab), //NOLINT(bugprone-use-after-move) + nearby_protocol::CredentialBook::TryCreateFromSlab( + slab), // NOLINT(bugprone-use-after-move) ""); + ASSERT_DEATH( + [[maybe_unused]] auto failure = + nearby_protocol::CredentialBook::TryCreateFromSlab(next_slab), + ""); +} + +TEST_F(NpCppTest, TestSlabDestructor) { + { + auto slab1_result = nearby_protocol::CredentialSlab::TryCreate(); + ASSERT_TRUE(slab1_result.ok()); + + auto slab2_result = nearby_protocol::CredentialSlab::TryCreate(); + ASSERT_TRUE(slab2_result.ok()); + + auto slab3_result = nearby_protocol::CredentialSlab::TryCreate(); + ASSERT_TRUE(slab3_result.ok()); + + auto slab4_result = nearby_protocol::CredentialSlab::TryCreate(); + + ASSERT_FALSE(slab4_result.ok()); + ASSERT_TRUE(absl::IsResourceExhausted(slab4_result.status())); + } + + // Now that the above variables have gone out of scope we should verify that + // the destructor succeeded in cleaning up those resources + auto slab_result = nearby_protocol::CredentialSlab::TryCreate(); + ASSERT_TRUE(slab_result.ok()); +} + +TEST_F(NpCppTest, TestSlabMoveAssignment) { + auto slab_result = nearby_protocol::CredentialSlab::TryCreate(); + ASSERT_TRUE(slab_result.ok()); + + // create a second slab + auto other_slab_result = nearby_protocol::CredentialSlab::TryCreate(); + ASSERT_TRUE(other_slab_result.ok()); + + // move assignment should override currently assigned slab with new one, + // freeing the existing one. + auto other_slab = std::move(slab_result.value()); + auto maybe_book = + nearby_protocol::CredentialBook::TryCreateFromSlab(other_slab); + ASSERT_TRUE(maybe_book.ok()); + + // The old object should now lead to use after moved assert failure ASSERT_DEATH([[maybe_unused]] auto failure = - nearby_protocol::CredentialBook::TryCreateFromSlab(next_slab), + nearby_protocol::CredentialBook::TryCreateFromSlab( + slab_result.value()), // NOLINT(bugprone-use-after-move) ""); + + // moving again should still lead to a use after moved assert failure + auto another_moved_book = std::move(slab_result.value()); + ASSERT_DEATH([[maybe_unused]] auto failure = + nearby_protocol::CredentialBook::TryCreateFromSlab( + another_moved_book), // NOLINT(bugprone-use-after-move) + ""); +} + +TEST_F(NpCppTest, TestAddV0Credential) { + auto slab_result = nearby_protocol::CredentialSlab::TryCreate(); + ASSERT_TRUE(slab_result.ok()); + + uint8_t metadata[] = {1, 2, 3}; + std::span<uint8_t> metadata_span(metadata); + + nearby_protocol::MatchedCredentialData match_data(111, metadata_span); + std::array<uint8_t, 32> key_seed {1, 2, 3}; + std::array<uint8_t, 32> legacy_metadata_key_hmac {1, 2, 3}; + + nearby_protocol::V0MatchableCredential v0_cred( + key_seed, legacy_metadata_key_hmac, match_data); + auto add_result = slab_result.value().AddV0Credential(v0_cred); + ASSERT_EQ(add_result, absl::OkStatus()); +} + +TEST_F(NpCppTest, TestAddV0CredentialAfterMoved) { + auto slab_result = nearby_protocol::CredentialSlab::TryCreate(); + ASSERT_TRUE(slab_result.ok()); + + // creating a book will move the slab + auto maybe_book = + nearby_protocol::CredentialBook::TryCreateFromSlab(slab_result.value()); + ASSERT_TRUE(maybe_book.ok()); + + uint8_t metadata[] = {1, 2, 3}; + std::span<uint8_t> metadata_span(metadata); + nearby_protocol::MatchedCredentialData match_data(111, metadata_span); + std::array<uint8_t, 32> key_seed {1, 2, 3}; + std::array<uint8_t, 32> legacy_metadata_key_hmac {1, 2, 3}; + nearby_protocol::V0MatchableCredential v0_cred( + key_seed, legacy_metadata_key_hmac, match_data); + + ASSERT_DEATH([[maybe_unused]] auto add_result = + slab_result.value().AddV0Credential(v0_cred); + , ""); +} + +TEST_F(NpCppTest, TestAddV1Credential) { + auto slab_result = nearby_protocol::CredentialSlab::TryCreate(); + ASSERT_TRUE(slab_result.ok()); + + uint8_t metadata[] = {1, 2, 3}; + std::span<uint8_t> metadata_span(metadata); + nearby_protocol::MatchedCredentialData match_data(111, metadata_span); + std::array<uint8_t, 32> key_seed {1, 2, 3}; + std::array<uint8_t, 32> expected_unsigned_metadata_key_hmac {1, 2, 3}; + std::array<uint8_t, 32> expected_signed_metadata_key_hmac {1, 2, 3}; + std::array<uint8_t, 32> pub_key {1, 2, 3}; + nearby_protocol::V1MatchableCredential v1_cred( + key_seed, expected_unsigned_metadata_key_hmac, + expected_signed_metadata_key_hmac, pub_key, match_data); + + auto add_result = slab_result.value().AddV1Credential(v1_cred); + ASSERT_EQ(add_result, absl::OkStatus()); +} + +TEST_F(NpCppTest, TestAddV1CredentialAfterMoved) { + auto slab_result = nearby_protocol::CredentialSlab::TryCreate(); + ASSERT_TRUE(slab_result.ok()); + + // creating a book will move the slab + auto maybe_book = + nearby_protocol::CredentialBook::TryCreateFromSlab(slab_result.value()); + ASSERT_TRUE(maybe_book.ok()); + + uint8_t metadata[] = {1, 2, 3}; + std::span<uint8_t> metadata_span(metadata); + nearby_protocol::MatchedCredentialData match_data(111, metadata_span); + std::array<uint8_t, 32> key_seed {1, 2, 3}; + std::array<uint8_t, 32> expected_unsigned_metadata_key_hmac {1, 2, 3}; + std::array<uint8_t, 32> expected_signed_metadata_key_hmac {1, 2, 3}; + std::array<uint8_t, 32> pub_key {1, 2, 3}; + nearby_protocol::V1MatchableCredential v1_cred( + key_seed, expected_unsigned_metadata_key_hmac, + expected_signed_metadata_key_hmac, pub_key, match_data); + + ASSERT_DEATH([[maybe_unused]] auto add_result = + slab_result.value().AddV1Credential(v1_cred); + , ""); }
diff --git a/nearby/presence/np_cpp_ffi/tests/deserialize_v0_tests.cc b/nearby/presence/np_cpp_ffi/tests/deserialize_v0_tests.cc index 54b17ab..3ed2d79 100644 --- a/nearby/presence/np_cpp_ffi/tests/deserialize_v0_tests.cc +++ b/nearby/presence/np_cpp_ffi/tests/deserialize_v0_tests.cc
@@ -15,7 +15,6 @@ #include "nearby_protocol.h" #include "shared_test_util.h" #include "np_cpp_test.h" - #include "gtest/gtest.h" TEST_F(NpCppTest, InvalidCast) {
diff --git a/nearby/src/license.rs b/nearby/src/license.rs index e479526..387ca27 100644 --- a/nearby/src/license.rs +++ b/nearby/src/license.rs
@@ -108,5 +108,6 @@ "**/.editorconfig", "**/*.class", "**/fuzz/artifacts/**", + "**/cmake-build-debug/**", ] }