diff options
Diffstat (limited to 'nearby/presence/np_cpp_ffi/nearby_protocol.cc')
-rw-r--r-- | nearby/presence/np_cpp_ffi/nearby_protocol.cc | 349 |
1 files changed, 266 insertions, 83 deletions
diff --git a/nearby/presence/np_cpp_ffi/nearby_protocol.cc b/nearby/presence/np_cpp_ffi/nearby_protocol.cc index 106eb77..c2f8566 100644 --- a/nearby/presence/np_cpp_ffi/nearby_protocol.cc +++ b/nearby/presence/np_cpp_ffi/nearby_protocol.cc @@ -27,7 +27,7 @@ namespace nearby_protocol { static void panic_handler(PanicReason reason); struct PanicHandler { - void (*handler)(PanicReason); + void (* handler)(PanicReason); bool set_by_client; }; @@ -43,7 +43,7 @@ static void panic_handler(PanicReason reason) { std::abort(); } -static void _assert_panic(bool condition, const char *func, const char *file, +static void _assert_panic(bool condition, const char* func, const char* file, int line) { if (!condition) { std::cout << "Assert failed: \n function: " << func << "\n file: " << file @@ -54,7 +54,7 @@ static void _assert_panic(bool condition, const char *func, const char *file, #define assert_panic(e) _assert_panic(e, __func__, __ASSERT_FILE_NAME, __LINE__) -bool GlobalConfig::SetPanicHandler(void (*handler)(PanicReason)) { +bool GlobalConfig::SetPanicHandler(void (* handler)(PanicReason)) { if (!gPanicHandler.set_by_client) { gPanicHandler.handler = handler; gPanicHandler.set_by_client = true; @@ -80,15 +80,15 @@ void GlobalConfig::SetMaxNumCredentialBooks(uint32_t max_num_credential_books) { void GlobalConfig::SetMaxNumDeserializedV0Advertisements( uint32_t max_num_deserialized_v0_advertisements) { np_ffi::internal:: - np_ffi_global_config_set_max_num_deserialized_v0_advertisements( - max_num_deserialized_v0_advertisements); + np_ffi_global_config_set_max_num_deserialized_v0_advertisements( + max_num_deserialized_v0_advertisements); } void GlobalConfig::SetMaxNumDeserializedV1Advertisements( uint32_t max_num_deserialized_v1_advertisements) { np_ffi::internal:: - np_ffi_global_config_set_max_num_deserialized_v1_advertisements( - max_num_deserialized_v1_advertisements); + np_ffi_global_config_set_max_num_deserialized_v1_advertisements( + max_num_deserialized_v1_advertisements); } absl::StatusOr<CredentialSlab> CredentialSlab::TryCreate() { @@ -96,16 +96,16 @@ absl::StatusOr<CredentialSlab> CredentialSlab::TryCreate() { auto kind = np_ffi::internal::np_ffi_CreateCredentialSlabResult_kind(result); switch (kind) { - case CreateCredentialSlabResultKind::Success: { - auto slab = CredentialSlab( - np_ffi::internal::np_ffi_CreateCredentialSlabResult_into_SUCCESS( - result)); - return slab; - } - case CreateCredentialSlabResultKind::NoSpaceLeft: { - return absl::ResourceExhaustedError( - "No space left to create credential slab"); - } + case CreateCredentialSlabResultKind::Success: { + auto slab = CredentialSlab( + np_ffi::internal::np_ffi_CreateCredentialSlabResult_into_SUCCESS( + result)); + return slab; + } + case CreateCredentialSlabResultKind::NoSpaceLeft: { + return absl::ResourceExhaustedError( + "No space left to create credential slab"); + } } } @@ -117,13 +117,13 @@ CredentialSlab::~CredentialSlab() { } } -CredentialSlab::CredentialSlab(CredentialSlab &&other) noexcept +CredentialSlab::CredentialSlab(CredentialSlab&& other) noexcept : credential_slab_(other.credential_slab_), moved_(other.moved_) { other.credential_slab_ = {}; other.moved_ = true; } -CredentialSlab &CredentialSlab::operator=(CredentialSlab &&other) noexcept { +CredentialSlab& CredentialSlab::operator=(CredentialSlab&& other) noexcept { if (this != &other) { if (!this->moved_) { auto result = np_ffi::internal::np_ffi_deallocate_credential_slab( @@ -140,24 +140,58 @@ CredentialSlab &CredentialSlab::operator=(CredentialSlab &&other) noexcept { 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); - slab.moved_ = true; - return CredentialBook(book); - } - case CreateCredentialBookResultKind::NoSpaceLeft: { - return absl::ResourceExhaustedError( - "No space left to create credential book"); - } - case CreateCredentialBookResultKind::InvalidSlabHandle: { - return absl::NotFoundError( - "The slab referenced by the given handle was not found."); - } + case CreateCredentialBookResultKind::Success: { + auto book = + np_ffi::internal::np_ffi_CreateCredentialBookResult_into_SUCCESS( + result); + slab.moved_ = true; + return CredentialBook(book); + } + case CreateCredentialBookResultKind::NoSpaceLeft: { + return absl::ResourceExhaustedError( + "No space left to create credential book"); + } + case CreateCredentialBookResultKind::InvalidSlabHandle: { + return absl::NotFoundError( + "The slab referenced by the given handle was not found."); + } } } @@ -169,13 +203,13 @@ CredentialBook::~CredentialBook() { } } -CredentialBook::CredentialBook(CredentialBook &&other) noexcept +CredentialBook::CredentialBook(CredentialBook&& other) noexcept : credential_book_(other.credential_book_), moved_(other.moved_) { other.credential_book_ = {}; other.moved_ = true; } -CredentialBook &CredentialBook::operator=(CredentialBook &&other) noexcept { +CredentialBook& CredentialBook::operator=(CredentialBook&& other) noexcept { if (this != &other) { if (!this->moved_) { auto result = np_ffi::internal::np_ffi_deallocate_credential_book( @@ -193,8 +227,8 @@ CredentialBook &CredentialBook::operator=(CredentialBook &&other) noexcept { } DeserializeAdvertisementResult -Deserializer::DeserializeAdvertisement(RawAdvertisementPayload &payload, - const CredentialBook &credential_book) { +Deserializer::DeserializeAdvertisement(RawAdvertisementPayload& payload, + const CredentialBook& credential_book) { assert_panic(!credential_book.moved_); auto result = np_ffi::internal::np_ffi_deserialize_advertisement( {payload.buffer_.internal_}, credential_book.credential_book_); @@ -232,14 +266,14 @@ DeserializeAdvertisementResult::~DeserializeAdvertisementResult() { } DeserializeAdvertisementResult::DeserializeAdvertisementResult( - DeserializeAdvertisementResult &&other) noexcept + DeserializeAdvertisementResult&& other) noexcept : result_(other.result_), moved_(other.moved_) { other.result_ = {}; other.moved_ = true; } -DeserializeAdvertisementResult &DeserializeAdvertisementResult::operator=( - DeserializeAdvertisementResult &&other) noexcept { +DeserializeAdvertisementResult& DeserializeAdvertisementResult::operator=( + DeserializeAdvertisementResult&& other) noexcept { if (this != &other) { if (!this->moved_) { auto result = @@ -258,14 +292,14 @@ DeserializeAdvertisementResult &DeserializeAdvertisementResult::operator=( // V0 Stuff DeserializedV0Advertisement::DeserializedV0Advertisement( - DeserializedV0Advertisement &&other) noexcept + DeserializedV0Advertisement&& other) noexcept : v0_advertisement_(other.v0_advertisement_), moved_(other.moved_) { other.v0_advertisement_ = {}; other.moved_ = true; } -DeserializedV0Advertisement &DeserializedV0Advertisement::operator=( - DeserializedV0Advertisement &&other) noexcept { +DeserializedV0Advertisement& DeserializedV0Advertisement::operator=( + DeserializedV0Advertisement&& other) noexcept { if (this != &other) { if (!this->moved_) { auto result = @@ -309,16 +343,16 @@ LegibleDeserializedV0Advertisement DeserializedV0Advertisement::IntoLegible() { } LegibleDeserializedV0Advertisement::LegibleDeserializedV0Advertisement( - LegibleDeserializedV0Advertisement &&other) noexcept + LegibleDeserializedV0Advertisement&& other) noexcept : legible_v0_advertisement_(other.legible_v0_advertisement_), moved_(other.moved_) { other.moved_ = true; other.legible_v0_advertisement_ = {}; } -LegibleDeserializedV0Advertisement & +LegibleDeserializedV0Advertisement& LegibleDeserializedV0Advertisement::operator=( - LegibleDeserializedV0Advertisement &&other) noexcept { + LegibleDeserializedV0Advertisement&& other) noexcept { if (this != &other) { if (!this->moved_) { auto result = @@ -343,19 +377,20 @@ LegibleDeserializedV0Advertisement::~LegibleDeserializedV0Advertisement() { } } -DeserializedV0IdentityKind LegibleDeserializedV0Advertisement::GetIdentityKind() { +DeserializedV0IdentityKind +LegibleDeserializedV0Advertisement::GetIdentityKind() { assert_panic(!this->moved_); - auto result = - np_ffi::internal::np_ffi_LegibleDeserializedV0Advertisement_get_identity_kind( - legible_v0_advertisement_); + auto result = np_ffi::internal:: + np_ffi_LegibleDeserializedV0Advertisement_get_identity_kind( + legible_v0_advertisement_); return result; } uint8_t LegibleDeserializedV0Advertisement::GetNumberOfDataElements() { assert_panic(!this->moved_); return np_ffi::internal:: - np_ffi_LegibleDeserializedV0Advertisement_get_num_des( - legible_v0_advertisement_); + np_ffi_LegibleDeserializedV0Advertisement_get_num_des( + legible_v0_advertisement_); } V0Payload LegibleDeserializedV0Advertisement::IntoPayload() { @@ -366,13 +401,13 @@ V0Payload LegibleDeserializedV0Advertisement::IntoPayload() { return V0Payload(result); } -V0Payload::V0Payload(V0Payload &&other) noexcept +V0Payload::V0Payload(V0Payload&& other) noexcept : v0_payload_(other.v0_payload_), moved_(other.moved_) { other.v0_payload_ = {}; other.moved_ = true; } -V0Payload &V0Payload::operator=(V0Payload &&other) noexcept { +V0Payload& V0Payload::operator=(V0Payload&& other) noexcept { if (this != &other) { if (!this->moved_) { auto result = @@ -401,16 +436,75 @@ absl::StatusOr<V0DataElement> V0Payload::TryGetDataElement(uint8_t index) { auto result = np_ffi::internal::np_ffi_V0Payload_get_de(v0_payload_, index); auto kind = np_ffi::internal::np_ffi_GetV0DEResult_kind(result); switch (kind) { - case GetV0DEResultKind::Success: { - auto de = np_ffi_GetV0DEResult_into_SUCCESS(result); - return V0DataElement(de); + case GetV0DEResultKind::Success: { + auto de = np_ffi_GetV0DEResult_into_SUCCESS(result); + return V0DataElement(de); + } + case GetV0DEResultKind::Error: { + return absl::OutOfRangeError("Invalid Data Element index"); + } } - case GetV0DEResultKind::Error: { - return absl::OutOfRangeError("Invalid Data Element index"); +} + +static absl::StatusOr<std::vector<uint8_t>> +MetadataResultToVec(np_ffi::internal::DecryptMetadataResult decrypt_result) { + auto kind = + np_ffi::internal::np_ffi_DecryptMetadataResult_kind(decrypt_result); + switch (kind) { + case np_ffi::internal::DecryptMetadataResultKind::Success: { + auto metadata = + np_ffi::internal::np_ffi_DecryptMetadataResult_into_SUCCESS( + decrypt_result); + auto parts_result = + np_ffi::internal::np_ffi_DecryptedMetadata_get_metadata_buffer_parts( + metadata); + // The handle is guaranteed to be valid by the C++ wrapper so this should + // never fail + assert_panic(np_ffi::internal::np_ffi_GetMetadataBufferPartsResult_kind( + parts_result) == + np_ffi::internal::GetMetadataBufferPartsResultKind::Success); + auto parts = + np_ffi::internal::np_ffi_GetMetadataBufferPartsResult_into_SUCCESS( + parts_result); + std::vector<uint8_t> result(parts.ptr, parts.ptr + parts.len); + + // Now that the contents have been copied into the vec, the underlying + // handle can be de-allocated + auto deallocate_result = + np_ffi::internal::np_ffi_deallocate_DecryptedMetadata(metadata); + assert_panic(deallocate_result == + np_ffi::internal::DeallocateResult::Success); + return result; + } + case np_ffi::internal::DecryptMetadataResultKind::Error: { + return absl::InvalidArgumentError("Invalid V0 payload handle"); + } } +} + +absl::StatusOr<DeserializedV0IdentityDetails> V0Payload::GetIdentityDetails() { + assert_panic(!this->moved_); + auto result = np_ffi::internal::np_ffi_V0Payload_get_identity_details( + this->v0_payload_); + auto kind = np_ffi::internal::np_ffi_GetV0IdentityDetailsResult_kind(result); + switch (kind) { + case np_ffi::internal::GetV0IdentityDetailsResultKind::Error: { + return absl::InvalidArgumentError("Invalid handle"); + } + case np_ffi::internal::GetV0IdentityDetailsResultKind::Success: { + return np_ffi::internal::np_ffi_GetV0IdentityDetailsResult_into_SUCCESS( + result); + } } } +absl::StatusOr<std::vector<uint8_t>> V0Payload::DecryptMetadata() { + assert_panic(!this->moved_); + auto decrypt_result = + np_ffi::internal::np_ffi_V0Payload_decrypt_metadata(this->v0_payload_); + return MetadataResultToVec(decrypt_result); +} + V0DataElementKind V0DataElement::GetKind() { return np_ffi::internal::np_ffi_V0DataElement_kind(v0_data_element_); } @@ -440,7 +534,7 @@ uint8_t V0Actions::GetContextSyncSequenceNumber() { // This is called after all references to the shared_ptr have gone out of scope auto DeallocateV1Adv( - np_ffi::internal::DeserializedV1Advertisement *v1_advertisement) { + np_ffi::internal::DeserializedV1Advertisement* v1_advertisement) { auto result = np_ffi::internal::np_ffi_deallocate_deserialized_V1_advertisement( *v1_advertisement); @@ -457,11 +551,11 @@ DeserializedV1Advertisement::DeserializedV1Advertisement( } DeserializedV1Advertisement::DeserializedV1Advertisement( - DeserializedV1Advertisement &&other) noexcept + DeserializedV1Advertisement&& other) noexcept : v1_advertisement_(std::move(other.v1_advertisement_)) {} -DeserializedV1Advertisement &DeserializedV1Advertisement::operator=( - DeserializedV1Advertisement &&other) noexcept { +DeserializedV1Advertisement& DeserializedV1Advertisement::operator=( + DeserializedV1Advertisement&& other) noexcept { if (this != &other) { this->v1_advertisement_ = std::move(other.v1_advertisement_); } @@ -472,15 +566,15 @@ DeserializedV1Advertisement &DeserializedV1Advertisement::operator=( uint8_t DeserializedV1Advertisement::GetNumLegibleSections() { assert_panic(this->v1_advertisement_ != nullptr); return np_ffi::internal:: - np_ffi_DeserializedV1Advertisement_get_num_legible_sections( - *v1_advertisement_); + np_ffi_DeserializedV1Advertisement_get_num_legible_sections( + *v1_advertisement_); } uint8_t DeserializedV1Advertisement::GetNumUndecryptableSections() { assert_panic(this->v1_advertisement_ != nullptr); return np_ffi::internal:: - np_ffi_DeserializedV1Advertisement_get_num_undecryptable_sections( - *v1_advertisement_); + np_ffi_DeserializedV1Advertisement_get_num_undecryptable_sections( + *v1_advertisement_); } absl::StatusOr<DeserializedV1Section> @@ -491,14 +585,14 @@ DeserializedV1Advertisement::TryGetSection(uint8_t section_index) { *v1_advertisement_, section_index); auto kind = np_ffi::internal::np_ffi_GetV1SectionResult_kind(result); switch (kind) { - case np_ffi::internal::GetV1SectionResultKind::Error: { - return absl::OutOfRangeError("Invalid section index"); - } - case np_ffi::internal::GetV1SectionResultKind::Success: { - auto section = - np_ffi::internal::np_ffi_GetV1SectionResult_into_SUCCESS(result); - return DeserializedV1Section(section, v1_advertisement_); - } + case np_ffi::internal::GetV1SectionResultKind::Error: { + return absl::OutOfRangeError("Invalid section index"); + } + case np_ffi::internal::GetV1SectionResultKind::Success: { + auto section = + np_ffi::internal::np_ffi_GetV1SectionResult_into_SUCCESS(result); + return DeserializedV1Section(section, v1_advertisement_); + } } } @@ -517,23 +611,112 @@ DeserializedV1Section::TryGetDataElement(uint8_t index) { np_ffi::internal::np_ffi_DeserializedV1Section_get_de(section_, index); auto kind = np_ffi::internal::np_ffi_GetV1DEResult_kind(result); switch (kind) { - case np_ffi::internal::GetV1DEResultKind::Error: { - return absl::OutOfRangeError("Invalid data element index for this section"); + case np_ffi::internal::GetV1DEResultKind::Error: { + return absl::OutOfRangeError("Invalid data element index for this section"); + } + case np_ffi::internal::GetV1DEResultKind::Success: { + return V1DataElement( + np_ffi::internal::np_ffi_GetV1DEResult_into_SUCCESS(result)); + } } - case np_ffi::internal::GetV1DEResultKind::Success: { - return V1DataElement( - np_ffi::internal::np_ffi_GetV1DEResult_into_SUCCESS(result)); +} + +absl::StatusOr<std::vector<uint8_t>> DeserializedV1Section::DecryptMetadata() { + assert_panic(this->owning_v1_advertisement_ != nullptr); + auto decrypt_result = + np_ffi::internal::np_ffi_DeserializedV1Section_decrypt_metadata( + this->section_); + return MetadataResultToVec(decrypt_result); +} + +absl::StatusOr<DeserializedV1IdentityDetails> +DeserializedV1Section::GetIdentityDetails() { + assert_panic(this->owning_v1_advertisement_ != nullptr); + auto result = + np_ffi::internal::np_ffi_DeserializedV1Section_get_identity_details( + this->section_); + auto kind = np_ffi::internal::np_ffi_GetV1IdentityDetailsResult_kind(result); + switch (kind) { + case np_ffi::internal::GetV1IdentityDetailsResultKind::Error: { + return absl::InvalidArgumentError("Invalid handle"); + } + case np_ffi::internal::GetV1IdentityDetailsResultKind::Success: { + return np_ffi::internal::np_ffi_GetV1IdentityDetailsResult_into_SUCCESS( + result); + } } +} + +absl::StatusOr<std::array<uint8_t, 16>> DeserializedV1Section::DeriveSaltForOffset( + uint8_t offset) { + auto result = + np_ffi::internal::np_ffi_DeserializedV1Section_derive_16_byte_salt_for_offset( + this->section_, + offset); + auto kind = np_ffi::internal::np_ffi_GetV1DE16ByteSaltResult_kind(result); + switch (kind) { + case np_ffi::internal::GetV1DE16ByteSaltResultKind::Error: { + return absl::InvalidArgumentError("Failed to derive salt for offset"); + } + case np_ffi::internal::GetV1DE16ByteSaltResultKind::Success: { + auto buffer = np_ffi::internal::np_ffi_GetV1DE16ByteSaltResult_into_SUCCESS(result); + return std::to_array(buffer._0); + } } } uint32_t V1DataElement::GetDataElementTypeCode() const { return np_ffi::internal::np_ffi_V1DEType_to_uint32_t( - v1_data_element_.generic._0.de_type); + np_ffi::internal::np_ffi_V1DataElement_to_generic(this->v1_data_element_) + .de_type); } ByteBuffer<127> V1DataElement::GetPayload() const { - return ByteBuffer(v1_data_element_.generic._0.payload); + return ByteBuffer( + np_ffi::internal::np_ffi_V1DataElement_to_generic(this->v1_data_element_) + .payload); } +uint8_t V1DataElement::GetOffset() const { + return np_ffi::internal::np_ffi_V1DataElement_to_generic( + this->v1_data_element_) + .offset; +} + +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 |