diff --git a/sharing/BUILD b/sharing/BUILD index fb9cdca7..436a0fe7 100644 --- a/sharing/BUILD +++ b/sharing/BUILD @@ -211,6 +211,7 @@ cc_library( "//sharing/internal/public:logging", "//sharing/proto:wire_format_cc_proto", "@com_google_absl//absl/container:flat_hash_map", + "@com_google_absl//absl/strings:str_format", "@com_google_absl//absl/strings:string_view", "@com_google_absl//absl/time", "@com_google_absl//absl/types:span", @@ -767,6 +768,7 @@ cc_test( ":attachments", ":connection_types", ":nearby_sharing_decoder_impl", + ":paired_key_verification_runner", ":share_session", ":test_support", ":transfer_metadata", @@ -788,17 +790,21 @@ cc_test( ":attachment_compare", ":attachments", ":connection_types", + ":nearby_sharing_decoder_impl", + ":paired_key_verification_runner", ":share_session", ":test_support", ":transfer_metadata", ":types", "//internal/platform/implementation/g3", # fixdeps: keep "//internal/test", + "//proto:sharing_enums_cc_proto", "//sharing/internal/public:logging", "//sharing/proto:wire_format_cc_proto", "//third_party/protobuf", "@com_github_protobuf_matchers//protobuf-matchers", "@com_google_absl//absl/strings:string_view", + "@com_google_absl//absl/time", "@com_google_googletest//:gtest_main", ], ) diff --git a/sharing/incoming_share_session.cc b/sharing/incoming_share_session.cc index a044afb2..e2a90a6c 100644 --- a/sharing/incoming_share_session.cc +++ b/sharing/incoming_share_session.cc @@ -35,6 +35,7 @@ #include "sharing/nearby_connection.h" #include "sharing/nearby_connections_manager.h" #include "sharing/nearby_connections_types.h" +#include "sharing/paired_key_verification_runner.h" #include "sharing/payload_tracker.h" #include "sharing/proto/wire_format.pb.h" #include "sharing/share_session.h" @@ -46,7 +47,9 @@ namespace nearby::sharing { namespace { +using ::location::nearby::proto::sharing::OSType; using ::nearby::sharing::service::proto::IntroductionFrame; +using ::nearby::sharing::service::proto::V1Frame; using ::nearby::sharing::service::proto::WifiCredentials; } // namespace @@ -147,6 +150,31 @@ IncomingShareSession::ProcessIntroduction( return std::nullopt; } +bool IncomingShareSession::ProcessKeyVerificationResult( + PairedKeyVerificationRunner::PairedKeyVerificationResult result, + OSType share_target_os_type, + std::function)> + introduction_callback) { + if (!HandleKeyVerificationResult(result, share_target_os_type)) { + return false; + } + NL_LOG(INFO) << __func__ << ": Waiting for introduction from " + << share_target().id; + + frames_reader()->ReadFrame( + V1Frame::INTRODUCTION, + [callback = + std::move(introduction_callback)](std::optional frame) { + if (!frame.has_value()) { + callback(std::nullopt); + } else { + callback(frame->introduction()); + } + }, + kReadFramesTimeout); + return true; +} + void IncomingShareSession::RegisterPayloadListener( Clock* clock, NearbyConnectionsManager& connections_manager, std::function update_callback) { diff --git a/sharing/incoming_share_session.h b/sharing/incoming_share_session.h index 2d3252c8..b07449a6 100644 --- a/sharing/incoming_share_session.h +++ b/sharing/incoming_share_session.h @@ -26,6 +26,7 @@ #include "internal/platform/task_runner.h" #include "sharing/nearby_connection.h" #include "sharing/nearby_connections_manager.h" +#include "sharing/paired_key_verification_runner.h" #include "sharing/proto/wire_format.pb.h" #include "sharing/share_session.h" #include "sharing/share_target.h" @@ -54,6 +55,17 @@ class IncomingShareSession : public ShareSession { const nearby::sharing::service::proto::IntroductionFrame& introduction_frame); + // Processes the PairedKeyVerificationResult. + // Returns true if verification was successful and the session is now waiting + // for the introduction frame. Calls |introduction_callback| when it is + // received. + bool ProcessKeyVerificationResult( + PairedKeyVerificationRunner::PairedKeyVerificationResult result, + location::nearby::proto::sharing::OSType share_target_os_type, + std::function)> + introduction_callback); + // Update file attachment paths with payload paths. bool UpdateFilePayloadPaths( const NearbyConnectionsManager& connections_manager); diff --git a/sharing/incoming_share_session_test.cc b/sharing/incoming_share_session_test.cc index fa6e7fc5..f3102e44 100644 --- a/sharing/incoming_share_session_test.cc +++ b/sharing/incoming_share_session_test.cc @@ -27,13 +27,18 @@ #include "protobuf-matchers/protocol-buffer-matchers.h" #include "gtest/gtest.h" #include "absl/strings/string_view.h" +#include "absl/time/clock.h" #include "internal/test/fake_clock.h" #include "internal/test/fake_task_runner.h" +#include "proto/sharing_enums.pb.h" #include "sharing/attachment_compare.h" // IWYU pragma: keep +#include "sharing/fake_nearby_connection.h" #include "sharing/fake_nearby_connections_manager.h" #include "sharing/file_attachment.h" #include "sharing/internal/public/logging.h" #include "sharing/nearby_connections_types.h" +#include "sharing/nearby_sharing_decoder_impl.h" +#include "sharing/paired_key_verification_runner.h" #include "sharing/proto/wire_format.pb.h" #include "sharing/share_target.h" #include "sharing/text_attachment.h" @@ -44,9 +49,11 @@ namespace nearby::sharing { namespace { +using ::location::nearby::proto::sharing::OSType; using ::nearby::sharing::service::proto::FileMetadata; using ::nearby::sharing::service::proto::IntroductionFrame; using ::nearby::sharing::service::proto::TextMetadata; +using ::nearby::sharing::service::proto::V1Frame; using ::nearby::sharing::service::proto::WifiCredentials; using ::nearby::sharing::service::proto::WifiCredentialsMetadata; using ::testing::Eq; @@ -140,7 +147,7 @@ class IncomingShareSessionTest : public ::testing::Test { } FakeClock clock_; - FakeTaskRunner task_runner_ {&clock_, 1}; + FakeTaskRunner task_runner_{&clock_, 1}; ShareTarget share_target_; IncomingShareSession session_; IntroductionFrame introduction_frame_; @@ -574,5 +581,146 @@ TEST_F(IncomingShareSessionTest, RegisterPayloadListenerSuccess) { } } +TEST_F(IncomingShareSessionTest, ProcessKeyVerificationResultSuccess) { + NearbySharingDecoderImpl decoder; + FakeNearbyConnection connection; + session_.OnConnected(decoder, absl::Now(), &connection); + session_.SetTokenForTests("1234"); + + bool introduction_received = false; + EXPECT_THAT( + session_.ProcessKeyVerificationResult( + PairedKeyVerificationRunner::PairedKeyVerificationResult::kSuccess, + OSType::WINDOWS, + [&introduction_received](std::optional) { + introduction_received = true; + }), + IsTrue()); + + EXPECT_THAT(session_.self_share(), IsFalse()); + EXPECT_THAT(session_.token(), Eq("1234")); + EXPECT_THAT(session_.os_type(), Eq(OSType::WINDOWS)); + EXPECT_THAT(introduction_received, IsFalse()); + + // Send Introduction frame + nearby::sharing::service::proto::Frame frame = + nearby::sharing::service::proto::Frame(); + frame.set_version(nearby::sharing::service::proto::Frame::V1); + V1Frame* v1frame = frame.mutable_v1(); + v1frame->set_type(service::proto::V1Frame::INTRODUCTION); + v1frame->mutable_introduction(); + std::vector data; + data.resize(frame.ByteSizeLong()); + EXPECT_THAT(frame.SerializeToArray(data.data(), data.size()), IsTrue()); + connection.AppendReadableData(std::move(data)); + + EXPECT_THAT(introduction_received, IsTrue()); +} + +TEST_F(IncomingShareSessionTest, ProcessKeyVerificationResultFail) { + NearbySharingDecoderImpl decoder; + FakeNearbyConnection connection; + session_.OnConnected(decoder, absl::Now(), &connection); + session_.SetTokenForTests("1234"); + + bool introduction_received = false; + EXPECT_THAT( + session_.ProcessKeyVerificationResult( + PairedKeyVerificationRunner::PairedKeyVerificationResult::kFail, + OSType::WINDOWS, + [&introduction_received](std::optional) { + introduction_received = true; + }), + IsFalse()); + + EXPECT_THAT(session_.token(), Eq("1234")); + EXPECT_THAT(session_.os_type(), Eq(OSType::WINDOWS)); + EXPECT_THAT(introduction_received, IsFalse()); + + // Send Introduction frame + nearby::sharing::service::proto::Frame frame = + nearby::sharing::service::proto::Frame(); + frame.set_version(nearby::sharing::service::proto::Frame::V1); + V1Frame* v1frame = frame.mutable_v1(); + v1frame->set_type(service::proto::V1Frame::INTRODUCTION); + v1frame->mutable_introduction(); + std::vector data; + data.resize(frame.ByteSizeLong()); + EXPECT_THAT(frame.SerializeToArray(data.data(), data.size()), IsTrue()); + connection.AppendReadableData(std::move(data)); + + EXPECT_THAT(introduction_received, IsFalse()); +} + +TEST_F(IncomingShareSessionTest, ProcessKeyVerificationResultUnable) { + NearbySharingDecoderImpl decoder; + FakeNearbyConnection connection; + session_.OnConnected(decoder, absl::Now(), &connection); + session_.SetTokenForTests("1234"); + + bool introduction_received = false; + EXPECT_THAT( + session_.ProcessKeyVerificationResult( + PairedKeyVerificationRunner::PairedKeyVerificationResult::kUnable, + OSType::WINDOWS, + [&introduction_received](std::optional) { + introduction_received = true; + }), + IsTrue()); + + EXPECT_THAT(session_.token(), Eq("1234")); + EXPECT_THAT(session_.os_type(), Eq(OSType::WINDOWS)); + EXPECT_THAT(introduction_received, IsFalse()); + + // Send Introduction frame + nearby::sharing::service::proto::Frame frame = + nearby::sharing::service::proto::Frame(); + frame.set_version(nearby::sharing::service::proto::Frame::V1); + V1Frame* v1frame = frame.mutable_v1(); + v1frame->set_type(service::proto::V1Frame::INTRODUCTION); + v1frame->mutable_introduction(); + std::vector data; + data.resize(frame.ByteSizeLong()); + EXPECT_THAT(frame.SerializeToArray(data.data(), data.size()), IsTrue()); + connection.AppendReadableData(std::move(data)); + + EXPECT_THAT(introduction_received, IsTrue()); +} + +TEST_F(IncomingShareSessionTest, ProcessKeyVerificationResultUnknown) { + NearbySharingDecoderImpl decoder; + FakeNearbyConnection connection; + session_.OnConnected(decoder, absl::Now(), &connection); + session_.SetTokenForTests("1234"); + + bool introduction_received = false; + EXPECT_THAT( + session_.ProcessKeyVerificationResult( + PairedKeyVerificationRunner::PairedKeyVerificationResult::kUnknown, + OSType::WINDOWS, + [&introduction_received](std::optional) { + introduction_received = true; + }), + IsFalse()); + + EXPECT_THAT(session_.token(), Eq("1234")); + EXPECT_THAT(session_.os_type(), Eq(OSType::WINDOWS)); + EXPECT_THAT(introduction_received, IsFalse()); + + // Send Introduction frame + nearby::sharing::service::proto::Frame frame = + nearby::sharing::service::proto::Frame(); + frame.set_version(nearby::sharing::service::proto::Frame::V1); + V1Frame* v1frame = frame.mutable_v1(); + v1frame->set_type(service::proto::V1Frame::INTRODUCTION); + v1frame->mutable_introduction(); + std::vector data; + data.resize(frame.ByteSizeLong()); + EXPECT_THAT(frame.SerializeToArray(data.data(), data.size()), IsTrue()); + connection.AppendReadableData(std::move(data)); + + EXPECT_THAT(introduction_received, IsFalse()); +} + } // namespace } // namespace nearby::sharing diff --git a/sharing/nearby_sharing_service_impl.cc b/sharing/nearby_sharing_service_impl.cc index 71764e26..217b3e18 100644 --- a/sharing/nearby_sharing_service_impl.cc +++ b/sharing/nearby_sharing_service_impl.cc @@ -118,6 +118,7 @@ using ::location::nearby::proto::sharing::SessionStatus; using ::nearby::sharing::api::SharingPlatform; using ::nearby::sharing::proto::DataUsage; using ::nearby::sharing::proto::DeviceVisibility; +using ::nearby::sharing::service::proto::IntroductionFrame; constexpr absl::Duration kBackgroundAdvertisementRotationDelayMin = absl::Minutes(12); @@ -2500,8 +2501,11 @@ void NearbySharingServiceImpl::OnOutgoingConnection( std::optional> token = nearby_connections_manager_->GetRawAuthenticationToken( session.endpoint_id()); - std::optional four_digit_token = TokenToFourDigitString(token); - + if (!token.has_value()) { + AbortAndCloseConnectionIfNecessary( + session, TransferMetadata::Status::kPairedKeyVerificationFailed); + return; + } session.RunPairedKeyVerification( context_->GetClock(), ToProtoOsType(device_info_.GetOsType()), { @@ -2509,18 +2513,13 @@ void NearbySharingServiceImpl::OnOutgoingConnection( .last_visibility = settings_->GetLastVisibility(), .last_visibility_time = settings_->GetLastVisibilityTimestamp(), }, - GetCertificateManager(), std::move(token), - [this, share_target_id, four_digit_token = std::move(four_digit_token)]( - PairedKeyVerificationRunner::PairedKeyVerificationResult result, - OSType remote_os_type) { - OnOutgoingConnectionKeyVerificationDone( - share_target_id, four_digit_token, result, remote_os_type); - }); + GetCertificateManager(), *token, + absl::bind_front( + &NearbySharingServiceImpl::OnOutgoingConnectionKeyVerificationDone, + this, share_target_id)); } -void NearbySharingServiceImpl::SendIntroduction( - OutgoingShareSession& session, - std::optional four_digit_token) { +void NearbySharingServiceImpl::SendIntroduction(OutgoingShareSession& session) { // We successfully connected! Now lets build up Payloads for all the files we // want to send them. We won't send any just yet, but we'll send the Payload // IDs in our introduction frame so that they know what to expect if they @@ -2580,12 +2579,6 @@ void NearbySharingServiceImpl::SendIntroduction( AbortAndCloseConnectionIfNecessary(*session, TransferMetadata::Status::kTimedOut); }); - - session.UpdateTransferMetadata( - TransferMetadataBuilder() - .set_status(TransferMetadata::Status::kAwaitingLocalConfirmation) - .set_token(four_digit_token) - .build()); } void NearbySharingServiceImpl::CreatePayloads( @@ -2728,11 +2721,6 @@ void NearbySharingServiceImpl::OnIncomingAdvertisementDecoded( absl::string_view endpoint_id, IncomingShareSession& session, std::unique_ptr advertisement) { int64_t placeholder_share_target_id = session.share_target().id; - if (!session.IsConnected()) { - NL_LOG(WARNING) << __func__ << ": Invalid connection for endpoint id - " - << endpoint_id; - return; - } if (!advertisement) { NL_LOG(WARNING) << __func__ @@ -2953,8 +2941,12 @@ void NearbySharingServiceImpl::OnIncomingDecryptedCertificate( std::optional> token = nearby_connections_manager_->GetRawAuthenticationToken( session.endpoint_id()); - std::optional four_digit_token = TokenToFourDigitString(token); + if (!token.has_value()) { + AbortAndCloseConnectionIfNecessary( + session, TransferMetadata::Status::kPairedKeyVerificationFailed); + return; + } session.RunPairedKeyVerification( context_->GetClock(), ToProtoOsType(device_info_.GetOsType()), { @@ -2962,19 +2954,14 @@ void NearbySharingServiceImpl::OnIncomingDecryptedCertificate( .last_visibility = settings_->GetLastVisibility(), .last_visibility_time = settings_->GetLastVisibilityTimestamp(), }, - GetCertificateManager(), std::move(token), - [this, share_target_id, four_digit_token = std::move(four_digit_token)]( - PairedKeyVerificationRunner::PairedKeyVerificationResult - verification_result, - OSType remote_os_type) { - OnIncomingConnectionKeyVerificationDone( - share_target_id, four_digit_token, verification_result, - remote_os_type); - }); + GetCertificateManager(), *token, + absl::bind_front( + &NearbySharingServiceImpl::OnIncomingConnectionKeyVerificationDone, + this, share_target_id)); } void NearbySharingServiceImpl::OnIncomingConnectionKeyVerificationDone( - int64_t share_target_id, std::optional four_digit_token, + int64_t share_target_id, PairedKeyVerificationRunner::PairedKeyVerificationResult result, OSType share_target_os_type) { IncomingShareSession* session = GetIncomingShareSession(share_target_id); @@ -2982,45 +2969,17 @@ void NearbySharingServiceImpl::OnIncomingConnectionKeyVerificationDone( NL_VLOG(1) << __func__ << ": Invalid connection or endpoint id"; return; } - - session->set_os_type(share_target_os_type); - - switch (result) { - case PairedKeyVerificationRunner::PairedKeyVerificationResult::kFail: - NL_VLOG(1) << __func__ << ": Paired key handshake failed for target " - << share_target_id << ". Disconnecting."; - AbortAndCloseConnectionIfNecessary( - *session, TransferMetadata::Status::kPairedKeyVerificationFailed); - return; - - case PairedKeyVerificationRunner::PairedKeyVerificationResult::kSuccess: - NL_VLOG(1) << __func__ << ": Paired key handshake succeeded for target - " - << share_target_id; - ReceiveIntroduction(*session, /*four_digit_token=*/std::nullopt); - break; - - case PairedKeyVerificationRunner::PairedKeyVerificationResult::kUnable: - NL_VLOG(1) << __func__ - << ": Unable to verify paired key encryption when " - "receiving connection from target - " - << share_target_id; - if (four_digit_token) session->set_token(*four_digit_token); - - ReceiveIntroduction(*session, std::move(four_digit_token)); - break; - - case PairedKeyVerificationRunner::PairedKeyVerificationResult::kUnknown: - NL_VLOG(1) << __func__ - << ": Unknown PairedKeyVerificationResult for target " - << share_target_id << ". Disconnecting."; - AbortAndCloseConnectionIfNecessary( - *session, TransferMetadata::Status::kPairedKeyVerificationFailed); - break; + if (!session->ProcessKeyVerificationResult( + result, share_target_os_type, + absl::bind_front(&NearbySharingServiceImpl::OnReceivedIntroduction, + this, share_target_id))) { + AbortAndCloseConnectionIfNecessary(*session, + TransferMetadata::Status::kPairedKeyVerificationFailed); } } void NearbySharingServiceImpl::OnOutgoingConnectionKeyVerificationDone( - int64_t share_target_id, std::optional four_digit_token, + int64_t share_target_id, PairedKeyVerificationRunner::PairedKeyVerificationResult result, OSType share_target_os_type) { OutgoingShareSession* session = GetOutgoingShareSession(share_target_id); @@ -3028,78 +2987,29 @@ void NearbySharingServiceImpl::OnOutgoingConnectionKeyVerificationDone( return; } - session->set_os_type(share_target_os_type); - - switch (result) { - case PairedKeyVerificationRunner::PairedKeyVerificationResult::kFail: - NL_VLOG(1) << __func__ << ": Paired key handshake failed for target " - << share_target_id << ". Disconnecting."; - AbortAndCloseConnectionIfNecessary( - *session, TransferMetadata::Status::kPairedKeyVerificationFailed); - return; - - case PairedKeyVerificationRunner::PairedKeyVerificationResult::kSuccess: - NL_VLOG(1) << __func__ << ": Paired key handshake succeeded for target - " - << share_target_id; - SendIntroduction(*session, /*four_digit_token=*/std::nullopt); - SendPayloads(*session); - return; - - case PairedKeyVerificationRunner::PairedKeyVerificationResult::kUnable: - NL_VLOG(1) << __func__ - << ": Unable to verify paired key encryption when " - "initiating connection to target - " - << share_target_id; - - if (four_digit_token) { - session->set_token(*four_digit_token); - } - - if (NearbyFlags::GetInstance().GetBoolFlag( - config_package_nearby::nearby_sharing_feature:: - kSenderSkipsConfirmation)) { - NL_VLOG(1) << __func__ - << ": Sender-side verification is disabled. Skipping " - "token comparison with " - << share_target_id; - SendIntroduction(*session, /*four_digit_token=*/std::nullopt); - SendPayloads(*session); - } else { - SendIntroduction(*session, std::move(four_digit_token)); - } - return; - - case PairedKeyVerificationRunner::PairedKeyVerificationResult::kUnknown: - NL_VLOG(1) << __func__ - << ": Unknown PairedKeyVerificationResult for target " - << share_target_id << ". Disconnecting."; - AbortAndCloseConnectionIfNecessary( - *session, TransferMetadata::Status::kPairedKeyVerificationFailed); - break; + if (!session->ProcessKeyVerificationResult(result, share_target_os_type)) { + AbortAndCloseConnectionIfNecessary( + *session, TransferMetadata::Status::kPairedKeyVerificationFailed); + return; + } + SendIntroduction(*session); + // SendPayloads if key verification is successful or skip sender confirmation. + if (session->token().empty() || + NearbyFlags::GetInstance().GetBoolFlag( + config_package_nearby::nearby_sharing_feature:: + kSenderSkipsConfirmation)) { + SendPayloads(*session); + } else { + session->UpdateTransferMetadata( + TransferMetadataBuilder() + .set_status(TransferMetadata::Status::kAwaitingLocalConfirmation) + .set_token(session->token()) + .build()); } } -void NearbySharingServiceImpl::ReceiveIntroduction( - const IncomingShareSession& session, - std::optional four_digit_token) { - NL_LOG(INFO) << __func__ << ": Receiving introduction from " - << session.share_target().id; - NL_DCHECK(session.IsConnected()); - - session.frames_reader()->ReadFrame( - nearby::sharing::service::proto::V1Frame::INTRODUCTION, - [this, share_target_id = session.share_target().id, - four_digit_token = std::move(four_digit_token)]( - std::optional frame) { - OnReceivedIntroduction(share_target_id, std::move(four_digit_token), - std::move(frame)); - }, - kReadFramesTimeout); -} - void NearbySharingServiceImpl::OnReceivedIntroduction( - int64_t share_target_id, std::optional four_digit_token, - std::optional frame) { + int64_t share_target_id, std::optional frame) { IncomingShareSession* session = GetIncomingShareSession(share_target_id); if (!session || !session->IsConnected()) { NL_LOG(WARNING) @@ -3118,7 +3028,7 @@ void NearbySharingServiceImpl::OnReceivedIntroduction( NL_LOG(INFO) << __func__ << ": Successfully read the introduction frame."; std::optional status = - session->ProcessIntroduction(frame->introduction()); + session->ProcessIntroduction(*frame); if (status.has_value()) { Fail(share_target_id, *status); return; @@ -3134,8 +3044,7 @@ void NearbySharingServiceImpl::OnReceivedIntroduction( if (!NearbyFlags::GetInstance().GetBoolFlag( sharing::config_package_nearby::nearby_sharing_feature:: kUpgradeBandwidthAfterAccept)) { - if (frame->introduction().has_start_transfer() && - frame->introduction().start_transfer()) { + if (frame->has_start_transfer() && frame->start_transfer()) { if (session->attachment_container().GetTotalAttachmentsSize() >= kAttachmentsSizeThresholdOverHighQualityMedium) { NL_LOG(INFO) @@ -3152,9 +3061,15 @@ void NearbySharingServiceImpl::OnReceivedIntroduction( bool is_out_of_storage = IsOutOfStorage(device_info_, download_path, session->attachment_container().GetStorageSize()); + if (is_out_of_storage) { + Fail(share_target_id, TransferMetadata::Status::kNotEnoughSpace); + NL_LOG(WARNING) << __func__ + << ": Not enough space on the receiver. We have informed " + << share_target_id; + return; + } - OnStorageCheckCompleted(share_target_id, std::move(four_digit_token), - is_out_of_storage); + OnStorageCheckCompleted(*session); } void NearbySharingServiceImpl::ReceiveConnectionResponse( @@ -3278,25 +3193,11 @@ void NearbySharingServiceImpl::OnReceiveConnectionResponse( } void NearbySharingServiceImpl::OnStorageCheckCompleted( - int64_t share_target_id, std::optional four_digit_token, - bool is_out_of_storage) { - if (is_out_of_storage) { - Fail(share_target_id, TransferMetadata::Status::kNotEnoughSpace); - NL_LOG(WARNING) << __func__ - << ": Not enough space on the receiver. We have informed " - << share_target_id; - return; - } - IncomingShareSession* session = GetIncomingShareSession(share_target_id); - if (!session || !session->IsConnected()) { - NL_LOG(WARNING) << __func__ << ": Invalid connection for share target - " - << share_target_id; - return; - } - + IncomingShareSession& session) { mutual_acceptance_timeout_alarm_ = std::make_unique( *service_thread_, "mutual_acceptance_timeout_alarm", - kReadResponseFrameTimeout, [this, share_target_id]() { + kReadResponseFrameTimeout, + [this, share_target_id = session.share_target().id]() { NL_VLOG(1) << __func__ << ": Incoming mutual acceptance timed out, closing connection for " @@ -3305,44 +3206,32 @@ void NearbySharingServiceImpl::OnStorageCheckCompleted( Fail(share_target_id, TransferMetadata::Status::kTimedOut); }); - bool is_self_share = !four_digit_token.has_value() && session->self_share(); - bool is_self_share_auto_accept = session->self_share(); - - if (!is_self_share_auto_accept) { + if (!session.self_share()) { TransferMetadataBuilder transfer_metadata_builder; transfer_metadata_builder.set_status( TransferMetadata::Status::kAwaitingLocalConfirmation); - transfer_metadata_builder.set_token(four_digit_token); - transfer_metadata_builder.set_is_self_share(is_self_share); + transfer_metadata_builder.set_token(session.token()); - session->UpdateTransferMetadata(transfer_metadata_builder.build()); + session.UpdateTransferMetadata(transfer_metadata_builder.build()); } else { // Don't need to send kAwaitingLocalConfirmation for auto accept of Self // share. OnTransferStarted(/*is_incoming=*/true); } - session->set_disconnect_status( + session.set_disconnect_status( TransferMetadata::Status::kUnexpectedDisconnection); - auto* frames_reader = session->frames_reader(); - if (!frames_reader) { - NL_LOG(WARNING) << __func__ - << ": Stopped reading further frames, due to no connection " - "established."; - return; - } - - if (is_self_share_auto_accept) { + if (session.self_share()) { NL_LOG(INFO) << __func__ << ": Auto-accepting self share."; - Accept(share_target_id, [](StatusCodes status_codes) { + Accept(session.share_target().id, [](StatusCodes status_codes) { NL_LOG(INFO) << __func__ << ": Auto-accepting result: " << static_cast(status_codes); }); } - frames_reader->ReadFrame( - [this, share_target_id]( + session.frames_reader()->ReadFrame( + [this, share_target_id = session.share_target().id]( std::optional frame) { OnFrameRead(share_target_id, std::move(frame)); }); diff --git a/sharing/nearby_sharing_service_impl.h b/sharing/nearby_sharing_service_impl.h index 720590a9..7b6e5eff 100644 --- a/sharing/nearby_sharing_service_impl.h +++ b/sharing/nearby_sharing_service_impl.h @@ -320,8 +320,7 @@ class NearbySharingServiceImpl void OnOutgoingConnection(absl::Time connect_start_time, NearbyConnection* connection, OutgoingShareSession& session); - void SendIntroduction(OutgoingShareSession& session, - std::optional four_digit_token); + void SendIntroduction(OutgoingShareSession& session); void CreatePayloads( OutgoingShareSession& session, @@ -343,25 +342,21 @@ class NearbySharingServiceImpl int64_t placeholder_share_target_id, std::optional certificate); void OnIncomingConnectionKeyVerificationDone( - int64_t share_target_id, std::optional four_digit_token, + int64_t share_target_id, PairedKeyVerificationRunner::PairedKeyVerificationResult result, ::location::nearby::proto::sharing::OSType share_target_os_type); void OnOutgoingConnectionKeyVerificationDone( - int64_t share_target_id, std::optional four_digit_token, + int64_t share_target_id, PairedKeyVerificationRunner::PairedKeyVerificationResult result, ::location::nearby::proto::sharing::OSType share_target_os_type); - void ReceiveIntroduction(const IncomingShareSession& session, - std::optional four_digit_token); void OnReceivedIntroduction( - int64_t share_target_id, std::optional four_digit_token, - std::optional frame); + int64_t share_target_id, + std::optional frame); void ReceiveConnectionResponse(ShareSession& session); void OnReceiveConnectionResponse( int64_t share_target_id, std::optional frame); - void OnStorageCheckCompleted(int64_t share_target_id, - std::optional four_digit_token, - bool is_out_of_storage); + void OnStorageCheckCompleted(IncomingShareSession& session); void OnFrameRead( int64_t share_target_id, std::optional frame); diff --git a/sharing/nearby_sharing_service_impl_test.cc b/sharing/nearby_sharing_service_impl_test.cc index c44d21b2..cd13ce25 100644 --- a/sharing/nearby_sharing_service_impl_test.cc +++ b/sharing/nearby_sharing_service_impl_test.cc @@ -992,7 +992,6 @@ class NearbySharingServiceImplTest : public testing::Test { MockTransferUpdateCallback& transfer_callback, int64_t share_target_id) { ExpectTransferUpdates(transfer_callback, share_target_id, {TransferMetadata::Status::kConnecting, - TransferMetadata::Status::kAwaitingLocalConfirmation, TransferMetadata::Status::kAwaitingRemoteAcceptance}, [] {}); @@ -2748,8 +2747,9 @@ TEST_F(NearbySharingServiceImplTest, EXPECT_TRUE(share_target.device_id); EXPECT_NE(share_target.device_id, kEndpointId); EXPECT_EQ(share_target.full_name, kTestMetadataFullName); - - EXPECT_FALSE(metadata.token().has_value()); + EXPECT_FALSE(share_target.for_self_share); + EXPECT_FALSE(metadata.is_self_share()); + EXPECT_TRUE(metadata.token().has_value()); notification.Notify(); })); @@ -3338,7 +3338,6 @@ TEST_F(NearbySharingServiceImplTest, RegisterReceiveSurfaceWhileSending) { absl::Notification notification; ExpectTransferUpdates(transfer_callback, target_id, {TransferMetadata::Status::kConnecting, - TransferMetadata::Status::kAwaitingLocalConfirmation, TransferMetadata::Status::kAwaitingRemoteAcceptance}, [&]() { notification.Notify(); }); EXPECT_CALL(*mock_app_info_, SetActiveFlag()); @@ -3363,7 +3362,6 @@ TEST_F(NearbySharingServiceImplTest, SendTextAlreadySending) { absl::Notification notification; ExpectTransferUpdates(transfer_callback, target_id, {TransferMetadata::Status::kConnecting, - TransferMetadata::Status::kAwaitingLocalConfirmation, TransferMetadata::Status::kAwaitingRemoteAcceptance}, [&]() { notification.Notify(); }); EXPECT_CALL(*mock_app_info_, SetActiveFlag()); @@ -3466,7 +3464,6 @@ TEST_F(NearbySharingServiceImplTest, SendTextUnableToVerifyKey) { absl::Notification notification; ExpectTransferUpdates(transfer_callback, target_id, {TransferMetadata::Status::kConnecting, - TransferMetadata::Status::kAwaitingLocalConfirmation, TransferMetadata::Status::kAwaitingRemoteAcceptance}, [&]() { notification.Notify(); }); @@ -3496,7 +3493,6 @@ TEST_P(NearbySharingServiceImplSendFailureTest, SendTextRemoteFailure) { absl::Notification notification; ExpectTransferUpdates(transfer_callback, target_id, {TransferMetadata::Status::kConnecting, - TransferMetadata::Status::kAwaitingLocalConfirmation, TransferMetadata::Status::kAwaitingRemoteAcceptance}, [&]() { notification.Notify(); }); EXPECT_CALL(*mock_app_info_, SetActiveFlag()); @@ -3549,7 +3545,6 @@ TEST_P(NearbySharingServiceImplSendFailureTest, SendFilesRemoteFailure) { absl::Notification notification; ExpectTransferUpdates(transfer_callback, target_id, {TransferMetadata::Status::kConnecting, - TransferMetadata::Status::kAwaitingLocalConfirmation, TransferMetadata::Status::kAwaitingRemoteAcceptance}, [&]() { notification.Notify(); }); EXPECT_CALL(*mock_app_info_, SetActiveFlag()); @@ -3590,7 +3585,6 @@ TEST_F(NearbySharingServiceImplTest, SendTextSuccess) { absl::Notification notification; ExpectTransferUpdates(transfer_callback, target_id, {TransferMetadata::Status::kConnecting, - TransferMetadata::Status::kAwaitingLocalConfirmation, TransferMetadata::Status::kAwaitingRemoteAcceptance}, [&]() { notification.Notify(); }); EXPECT_CALL(*mock_app_info_, SetActiveFlag()); @@ -3686,7 +3680,6 @@ TEST_F(NearbySharingServiceImplTest, SendFilesSuccess) { absl::Notification introduction_notification; ExpectTransferUpdates(transfer_callback, target_id, {TransferMetadata::Status::kConnecting, - TransferMetadata::Status::kAwaitingLocalConfirmation, TransferMetadata::Status::kAwaitingRemoteAcceptance}, [&]() { introduction_notification.Notify(); }); EXPECT_CALL(*mock_app_info_, SetActiveFlag()); @@ -3752,7 +3745,6 @@ TEST_F(NearbySharingServiceImplTest, SendWifiCredentialsSuccess) { absl::Notification introduction_notification; ExpectTransferUpdates(transfer_callback, target_id, {TransferMetadata::Status::kConnecting, - TransferMetadata::Status::kAwaitingLocalConfirmation, TransferMetadata::Status::kAwaitingRemoteAcceptance}, [&]() { introduction_notification.Notify(); }); EXPECT_CALL(*mock_app_info_, SetActiveFlag()); diff --git a/sharing/nearby_sharing_util.cc b/sharing/nearby_sharing_util.cc index 5e341c2c..3dc9a578 100644 --- a/sharing/nearby_sharing_util.cc +++ b/sharing/nearby_sharing_util.cc @@ -25,15 +25,12 @@ #include "absl/hash/hash.h" #include "absl/strings/str_cat.h" -#include "absl/strings/str_format.h" #include "absl/strings/string_view.h" -#include "internal/flags/nearby_flags.h" #include "internal/platform/device_info.h" #include "proto/sharing_enums.pb.h" #include "sharing/advertisement.h" #include "sharing/certificates/nearby_share_decrypted_public_certificate.h" #include "sharing/common/nearby_share_enums.h" -#include "sharing/flags/generated/nearby_sharing_feature_flags.h" #include "sharing/internal/base/encode.h" #include "sharing/internal/public/logging.h" #include "sharing/nearby_connections_types.h" @@ -45,10 +42,6 @@ namespace sharing { namespace { using ::location::nearby::proto::sharing::AttachmentTransmissionStatus; using ::location::nearby::proto::sharing::ConnectionLayerStatus; - -// Used to hash a token into a 4 digit string. -constexpr int kHashModulo = 9973; -constexpr int kHashBaseMultiplier = 31; } // namespace std::string ReceiveSurfaceStateToString( @@ -151,23 +144,6 @@ std::string GetDeviceId( return std::string(endpoint_id); } -std::optional TokenToFourDigitString( - const std::optional>& bytes) { - if (!bytes.has_value()) { - return std::nullopt; - } - - int hash = 0; - int multiplier = 1; - for (uint8_t byte : *bytes) { - // Java bytes are signed two's complement so cast to use the correct sign. - hash = (hash + static_cast(byte) * multiplier) % kHashModulo; - multiplier = (multiplier * kHashBaseMultiplier) % kHashModulo; - } - - return absl::StrFormat("%04d", std::abs(hash)); -} - bool IsOutOfStorage(DeviceInfo& device_info, std::filesystem::path file_path, int64_t storage_required) { std::optional available_storage = diff --git a/sharing/nearby_sharing_util.h b/sharing/nearby_sharing_util.h index 41d4ade8..2fdeeeda 100644 --- a/sharing/nearby_sharing_util.h +++ b/sharing/nearby_sharing_util.h @@ -51,10 +51,6 @@ std::optional GetDeviceName( const Advertisement& advertisement, const std::optional& certificate); -// Converts authentication token to four bytes digit string. -std::optional TokenToFourDigitString( - const std::optional>& bytes); - std::string ReceiveSurfaceStateToString( NearbySharingService::ReceiveSurfaceState state); diff --git a/sharing/outgoing_share_session.cc b/sharing/outgoing_share_session.cc index dddce775..0b4e999b 100644 --- a/sharing/outgoing_share_session.cc +++ b/sharing/outgoing_share_session.cc @@ -34,6 +34,7 @@ #include "sharing/nearby_connections_manager.h" #include "sharing/nearby_connections_types.h" #include "sharing/nearby_file_handler.h" +#include "sharing/paired_key_verification_runner.h" #include "sharing/payload_tracker.h" #include "sharing/share_session.h" #include "sharing/share_target.h" @@ -66,6 +67,12 @@ void OutgoingShareSession::InvokeTransferUpdateCallback( transfer_update_callback_(*this, metadata); } +bool OutgoingShareSession::ProcessKeyVerificationResult( + PairedKeyVerificationRunner::PairedKeyVerificationResult result, + location::nearby::proto::sharing::OSType share_target_os_type) { + return HandleKeyVerificationResult(result, share_target_os_type); +} + bool OutgoingShareSession::OnNewConnection(NearbyConnection* connection) { if (!connection) { NL_LOG(WARNING) << __func__ diff --git a/sharing/outgoing_share_session.h b/sharing/outgoing_share_session.h index 64e85ab6..ef85ab93 100644 --- a/sharing/outgoing_share_session.h +++ b/sharing/outgoing_share_session.h @@ -29,6 +29,7 @@ #include "sharing/nearby_connections_manager.h" #include "sharing/nearby_connections_types.h" #include "sharing/nearby_file_handler.h" +#include "sharing/paired_key_verification_runner.h" #include "sharing/share_session.h" #include "sharing/share_target.h" #include "sharing/transfer_metadata.h" @@ -71,6 +72,10 @@ class OutgoingShareSession : public ShareSession { connection_layer_status_ = status; } + bool ProcessKeyVerificationResult( + PairedKeyVerificationRunner::PairedKeyVerificationResult result, + location::nearby::proto::sharing::OSType share_target_os_type); + std::vector GetFilePaths() const; void CreateTextPayloads(); diff --git a/sharing/outgoing_share_session_test.cc b/sharing/outgoing_share_session_test.cc index 7d701de4..2ecc4d36 100644 --- a/sharing/outgoing_share_session_test.cc +++ b/sharing/outgoing_share_session_test.cc @@ -36,6 +36,7 @@ #include "sharing/nearby_connections_types.h" #include "sharing/nearby_file_handler.h" #include "sharing/nearby_sharing_decoder_impl.h" +#include "sharing/paired_key_verification_runner.h" #include "sharing/proto/wire_format.pb.h" #include "sharing/share_target.h" #include "sharing/text_attachment.h" @@ -44,6 +45,7 @@ namespace nearby::sharing { namespace { +using ::location::nearby::proto::sharing::OSType; using ::nearby::sharing::service::proto::Frame; using ::nearby::sharing::service::proto::IntroductionFrame; using ::nearby::sharing::service::proto::ProgressUpdateFrame; @@ -423,5 +425,35 @@ TEST_F(OutgoingShareSessionTest, WriteInProgressUpdateFrameSuccess) { EXPECT_THAT(progress_frame.progress(), Eq(0.5)); } +TEST_F(OutgoingShareSessionTest, ProcessKeyVerificationResultFail) { + FakeNearbyConnection connection; + session_.OnConnected(decoder_, absl::Now(), &connection); + session_.SetTokenForTests("1234"); + + EXPECT_THAT( + session_.ProcessKeyVerificationResult( + PairedKeyVerificationRunner::PairedKeyVerificationResult::kFail, + OSType::WINDOWS), + IsFalse()); + + EXPECT_THAT(session_.token(), Eq("1234")); + EXPECT_THAT(session_.os_type(), Eq(OSType::WINDOWS)); +} + +TEST_F(OutgoingShareSessionTest, ProcessKeyVerificationResultSuccess) { + FakeNearbyConnection connection; + session_.OnConnected(decoder_, absl::Now(), &connection); + session_.SetTokenForTests("1234"); + + EXPECT_THAT( + session_.ProcessKeyVerificationResult( + PairedKeyVerificationRunner::PairedKeyVerificationResult::kSuccess, + OSType::WINDOWS), + IsTrue()); + + EXPECT_THAT(session_.token(), Eq("1234")); + EXPECT_THAT(session_.os_type(), Eq(OSType::WINDOWS)); +} + } // namespace } // namespace nearby::sharing diff --git a/sharing/share_session.cc b/sharing/share_session.cc index 9bcbc4ba..4f6ed648 100644 --- a/sharing/share_session.cc +++ b/sharing/share_session.cc @@ -15,6 +15,7 @@ #include "sharing/share_session.h" #include +#include #include #include #include @@ -22,6 +23,7 @@ #include #include +#include "absl/strings/str_format.h" #include "absl/time/time.h" #include "internal/platform/clock.h" #include "internal/platform/task_runner.h" @@ -46,6 +48,23 @@ using ::nearby::sharing::service::proto::ConnectionResponseFrame; using ::nearby::sharing::service::proto::Frame; using ::nearby::sharing::service::proto::V1Frame; +// Used to hash a token into a 4 digit string. +constexpr int kHashModulo = 9973; +constexpr int kHashBaseMultiplier = 31; + +// Converts authentication token to four bytes digit string. +std::string TokenToFourDigitString(const std::vector& bytes) { + int hash = 0; + int multiplier = 1; + for (uint8_t byte : bytes) { + // Java bytes are signed two's complement so cast to use the correct sign. + hash = (hash + static_cast(byte) * multiplier) % kHashModulo; + multiplier = (multiplier * kHashBaseMultiplier) % kHashModulo; + } + + return absl::StrFormat("%04d", std::abs(hash)); +} + } // namespace ShareSession::ShareSession(TaskRunner& service_thread, std::string endpoint_id, @@ -101,22 +120,14 @@ void ShareSession::RunPairedKeyVerification( Clock* clock, OSType os_type, const PairedKeyVerificationRunner::VisibilityHistory& visibility_history, NearbyShareCertificateManager* certificate_manager, - std::optional> token, + const std::vector& token, std::function callback) { - if (!token) { - NL_VLOG(1) << __func__ - << ": Failed to read authentication token from endpoint - " - << endpoint_id_; - std::move(callback)( - PairedKeyVerificationRunner::PairedKeyVerificationResult::kFail, - OSType::UNKNOWN_OS_TYPE); - return; - } + token_ = TokenToFourDigitString(token); key_verification_runner_ = std::make_shared( - clock, os_type, IsIncoming(), visibility_history, *token, + clock, os_type, IsIncoming(), visibility_history, token, connection_, certificate_, certificate_manager, frames_reader_.get(), kReadFramesTimeout); key_verification_runner_->Run(std::move(callback)); @@ -177,4 +188,43 @@ void ShareSession::WriteCancelFrame() { WriteFrame(frame); } +bool ShareSession::HandleKeyVerificationResult( + PairedKeyVerificationRunner::PairedKeyVerificationResult result, + location::nearby::proto::sharing::OSType share_target_os_type) { + os_type_ = share_target_os_type; + + switch (result) { + case PairedKeyVerificationRunner::PairedKeyVerificationResult::kFail: + NL_LOG(WARNING) << __func__ << ": Paired key handshake failed for target " + << share_target().id << ". Disconnecting."; + return false; + + case PairedKeyVerificationRunner::PairedKeyVerificationResult::kSuccess: + NL_VLOG(1) << __func__ << ": Paired key handshake succeeded for target - " + << share_target().id; + // Clear out token if it is self-share since verification is successful. + if (self_share_) { + token_.resize(0); + } + break; + + case PairedKeyVerificationRunner::PairedKeyVerificationResult::kUnable: + NL_VLOG(1) << __func__ + << ": Unable to verify paired key encryption when " + "receiving connection from target - " + << share_target().id; + // If we are unable to verify the paired key, we should clear the self + // share flag. + self_share_ = false; + break; + + case PairedKeyVerificationRunner::PairedKeyVerificationResult::kUnknown: + NL_LOG(WARNING) << __func__ + << ": Unknown PairedKeyVerificationResult for target " + << share_target().id << ". Disconnecting."; + return false; + } + return true; +} + } // namespace nearby::sharing diff --git a/sharing/share_session.h b/sharing/share_session.h index e5bcf868..9a88e897 100644 --- a/sharing/share_session.h +++ b/sharing/share_session.h @@ -71,9 +71,7 @@ class ShareSession { void UpdateTransferMetadata(const TransferMetadata& transfer_metadata); - const std::optional& token() const { return token_; } - - void set_token(std::string token) { token_ = std::move(token); } + const std::string& token() const { return token_; } IncomingFramesReader* frames_reader() const { return frames_reader_.get(); } @@ -90,13 +88,7 @@ class ShareSession { return connection_start_time_; } - ::location::nearby::proto::sharing::OSType os_type() const { - return os_type_; - } - - void set_os_type(::location::nearby::proto::sharing::OSType os_type) { - os_type_ = os_type; - } + location::nearby::proto::sharing::OSType os_type() const { return os_type_; } bool self_share() const { return self_share_; } @@ -119,7 +111,7 @@ class ShareSession { Clock* clock, location::nearby::proto::sharing::OSType os_type, const PairedKeyVerificationRunner::VisibilityHistory& visibility_history, NearbyShareCertificateManager* certificate_manager, - std::optional> token, + const std::vector& token, std::function< void(PairedKeyVerificationRunner::PairedKeyVerificationResult, location::nearby::proto::sharing::OSType)> @@ -144,6 +136,8 @@ class ShareSession { response_status); void WriteCancelFrame(); + void SetTokenForTests(std::string token) { token_ = std::move(token); } + protected: virtual void InvokeTransferUpdateCallback( const TransferMetadata& metadata) = 0; @@ -159,13 +153,20 @@ class ShareSession { return attachment_container_; } void WriteFrame(const nearby::sharing::service::proto::Frame& frame); + // Processes the PairedKeyVerificationResult. + // Returns true if verification was successful. + bool HandleKeyVerificationResult( + PairedKeyVerificationRunner::PairedKeyVerificationResult result, + location::nearby::proto::sharing::OSType share_target_os_type); private: TaskRunner& service_thread_; std::string endpoint_id_; std::optional certificate_; NearbyConnection* connection_ = nullptr; - std::optional token_; + // If not empty, this is the 4 digit token used to verify the connection. + // If token is empty, it means self-share and verification is not needed. + std::string token_; std::shared_ptr frames_reader_; std::shared_ptr key_verification_runner_; std::shared_ptr payload_tracker_; diff --git a/sharing/share_session_test.cc b/sharing/share_session_test.cc index 959ea46f..017abfea 100644 --- a/sharing/share_session_test.cc +++ b/sharing/share_session_test.cc @@ -70,6 +70,13 @@ class TestShareSession : public ShareSession { ShareSession::SetAttachmentPayloadId(attachment_id, payload_id); } + bool HandleKeyVerificationResult( + PairedKeyVerificationRunner::PairedKeyVerificationResult result, + OSType share_target_os_type) { + return ShareSession::HandleKeyVerificationResult(result, + share_target_os_type); + } + protected: void InvokeTransferUpdateCallback(const TransferMetadata& metadata) override { ++transfer_update_count_; @@ -160,8 +167,7 @@ TEST(ShareSessionTest, IncomingRunPairedKeyVerificationSuccess) { NearbySharingDecoderImpl nearby_sharing_decoder; FakeNearbyShareCertificateManager certificate_manager; FakeNearbyConnection connection; - std::optional> token = - std::vector{0, 1, 2, 3, 4, 5}; + std::vector token = {0, 1, 2, 3, 4, 5}; ShareTarget share_target; share_target.is_incoming = true; TestShareSession session(std::string(kEndpointId), share_target); @@ -187,6 +193,8 @@ TEST(ShareSessionTest, IncomingRunPairedKeyVerificationSuccess) { verification_result = result; notification.Notify(); }); + // 8929 is the hash of the token. + EXPECT_EQ(session.token(), "8929"); // Receive PairedKeyEncryptionFrame from remote device. // This will fail verification. nearby::sharing::service::proto::Frame in_encryption_frame; @@ -287,5 +295,107 @@ TEST(ShareSessionTest, WriteCancelFrame) { EXPECT_EQ(frame.v1().type(), V1Frame::CANCEL); } +TEST(ShareSessionTest, HandleKeyVerificationResultFail) { + NearbySharingDecoderImpl nearby_sharing_decoder; + ShareTarget share_target; + TestShareSession session(std::string(kEndpointId), share_target); + FakeNearbyConnection connection; + EXPECT_TRUE( + session.OnConnected(nearby_sharing_decoder, absl::Now(), &connection)); + session.SetTokenForTests("9876"); + + EXPECT_FALSE(session.HandleKeyVerificationResult( + PairedKeyVerificationRunner::PairedKeyVerificationResult::kFail, + OSType::WINDOWS)); + EXPECT_EQ(session.os_type(), OSType::WINDOWS); + EXPECT_FALSE(session.token().empty()); +} + +TEST(ShareSessionTest, HandleKeyVerificationResultSelfShareSuccess) { + NearbySharingDecoderImpl nearby_sharing_decoder; + ShareTarget share_target; + share_target.for_self_share = true; + TestShareSession session(std::string(kEndpointId), share_target); + FakeNearbyConnection connection; + EXPECT_TRUE( + session.OnConnected(nearby_sharing_decoder, absl::Now(), &connection)); + session.SetTokenForTests("9876"); + + EXPECT_TRUE(session.HandleKeyVerificationResult( + PairedKeyVerificationRunner::PairedKeyVerificationResult::kSuccess, + OSType::WINDOWS)); + EXPECT_EQ(session.os_type(), OSType::WINDOWS); + EXPECT_TRUE(session.self_share()); + EXPECT_TRUE(session.token().empty()); +} + +TEST(ShareSessionTest, HandleKeyVerificationResultNotSelfShareSuccess) { + NearbySharingDecoderImpl nearby_sharing_decoder; + ShareTarget share_target; + TestShareSession session(std::string(kEndpointId), share_target); + FakeNearbyConnection connection; + EXPECT_TRUE( + session.OnConnected(nearby_sharing_decoder, absl::Now(), &connection)); + session.SetTokenForTests("9876"); + + EXPECT_TRUE(session.HandleKeyVerificationResult( + PairedKeyVerificationRunner::PairedKeyVerificationResult::kSuccess, + OSType::WINDOWS)); + EXPECT_EQ(session.os_type(), OSType::WINDOWS); + EXPECT_FALSE(session.self_share()); + EXPECT_FALSE(session.token().empty()); +} + +TEST(ShareSessionTest, HandleKeyVerificationResultSelfShareUnable) { + NearbySharingDecoderImpl nearby_sharing_decoder; + ShareTarget share_target; + share_target.for_self_share = true; + TestShareSession session(std::string(kEndpointId), share_target); + FakeNearbyConnection connection; + EXPECT_TRUE( + session.OnConnected(nearby_sharing_decoder, absl::Now(), &connection)); + session.SetTokenForTests("9876"); + + EXPECT_TRUE(session.HandleKeyVerificationResult( + PairedKeyVerificationRunner::PairedKeyVerificationResult::kUnable, + OSType::WINDOWS)); + EXPECT_EQ(session.os_type(), OSType::WINDOWS); + EXPECT_FALSE(session.self_share()); + EXPECT_FALSE(session.token().empty()); +} + +TEST(ShareSessionTest, HandleKeyVerificationResultNotSelfShareUnable) { + NearbySharingDecoderImpl nearby_sharing_decoder; + ShareTarget share_target; + TestShareSession session(std::string(kEndpointId), share_target); + FakeNearbyConnection connection; + EXPECT_TRUE( + session.OnConnected(nearby_sharing_decoder, absl::Now(), &connection)); + session.SetTokenForTests("9876"); + + EXPECT_TRUE(session.HandleKeyVerificationResult( + PairedKeyVerificationRunner::PairedKeyVerificationResult::kUnable, + OSType::WINDOWS)); + EXPECT_EQ(session.os_type(), OSType::WINDOWS); + EXPECT_FALSE(session.self_share()); + EXPECT_FALSE(session.token().empty()); +} + +TEST(ShareSessionTest, HandleKeyVerificationResultUnknown) { + NearbySharingDecoderImpl nearby_sharing_decoder; + ShareTarget share_target; + TestShareSession session(std::string(kEndpointId), share_target); + FakeNearbyConnection connection; + EXPECT_TRUE( + session.OnConnected(nearby_sharing_decoder, absl::Now(), &connection)); + session.SetTokenForTests("9876"); + + EXPECT_FALSE(session.HandleKeyVerificationResult( + PairedKeyVerificationRunner::PairedKeyVerificationResult::kUnknown, + OSType::WINDOWS)); + EXPECT_EQ(session.os_type(), OSType::WINDOWS); + EXPECT_FALSE(session.token().empty()); +} + } // namespace } // namespace nearby::sharing