From 76a08d40e91c3db0779b22ded7ed58077bcd7e9e Mon Sep 17 00:00:00 2001 From: Francis Tsui Date: Fri, 10 Jul 2026 09:44:37 -0700 Subject: [PATCH] Update PaireKeyVerificationRunner to handle advertising under lock screen. PiperOrigin-RevId: 945756256 --- sharing/paired_key_verification_runner.cc | 61 +++++++++++-------- sharing/paired_key_verification_runner.h | 10 +-- .../paired_key_verification_runner_test.cc | 22 ++++--- 3 files changed, 58 insertions(+), 35 deletions(-) diff --git a/sharing/paired_key_verification_runner.cc b/sharing/paired_key_verification_runner.cc index 213d6799..d25006af 100644 --- a/sharing/paired_key_verification_runner.cc +++ b/sharing/paired_key_verification_runner.cc @@ -140,18 +140,8 @@ void PairedKeyVerificationRunner::OnReadPairedKeyEncryptionFrame( OSType::UNKNOWN_OS_TYPE); return; } - PairedKeyVerificationResult auth_token_hash_result = - VerifyAuthTokenHashWithPrivateCertificate(visibility_history_.visibility, - *frame); - - if (auth_token_hash_result != PairedKeyVerificationResult::kSuccess) { - if (IsVisibilityRecentlyUpdated()) { - auth_token_hash_result = VerifyAuthTokenHashWithPrivateCertificate( - visibility_history_.last_visibility, *frame); - } - } - + VerifyAuthTokenHashWithPrivateCertificates(*frame); if (auth_token_hash_result == PairedKeyVerificationResult::kUnable) { if (share_target_is_incoming_ && visibility_history_.visibility != @@ -255,9 +245,18 @@ void PairedKeyVerificationRunner::SendPairedKeyEncryptionFrame() { share_target_is_incoming_ ? kNearbyShareReceiverVerificationPrefix : kNearbyShareSenderVerificationPrefix, raw_token_); + DeviceVisibility primary_visibility; + DeviceVisibility secondary_visibility; + if (visibility_history_.screen_locked_advertising) { + primary_visibility = DeviceVisibility::DEVICE_VISIBILITY_SELF_SHARE; + secondary_visibility = visibility_history_.visibility; + } else { + primary_visibility = visibility_history_.visibility; + secondary_visibility = visibility_history_.last_visibility; + } std::optional> signature = - certificate_manager_.SignWithPrivateCertificate( - visibility_history_.visibility, padded_token); + certificate_manager_.SignWithPrivateCertificate(primary_visibility, + padded_token); if (!signature.has_value() || signature->empty()) { signature = GenerateRandomBytes(kNearbyShareNumBytesRandomSignature); } @@ -282,8 +281,8 @@ void PairedKeyVerificationRunner::SendPairedKeyEncryptionFrame() { LOG(INFO) << "Attempts to sign authentication token with a previous private key."; std::optional> optional_signature = - certificate_manager_.SignWithPrivateCertificate( - visibility_history_.last_visibility, padded_token); + certificate_manager_.SignWithPrivateCertificate(secondary_visibility, + padded_token); if (optional_signature.has_value()) { encryption_frame->set_optional_signed_data(optional_signature->data(), @@ -297,22 +296,36 @@ void PairedKeyVerificationRunner::SendPairedKeyEncryptionFrame() { } PairedKeyVerificationRunner::PairedKeyVerificationResult -PairedKeyVerificationRunner::VerifyAuthTokenHashWithPrivateCertificate( - DeviceVisibility visibility, +PairedKeyVerificationRunner::VerifyAuthTokenHashWithPrivateCertificates( const nearby::sharing::service::proto::V1Frame& frame) { - std::optional> hash = - certificate_manager_.HashAuthenticationTokenWithPrivateCertificate( - visibility, raw_token_); - const std::string& frame_hash = frame.paired_key_encryption().secret_id_hash(); std::vector frame_hash_data{frame_hash.begin(), frame_hash.end()}; - if (hash.has_value() && *hash == frame_hash_data) { - VLOG(1) << __func__ << ": Successfully verified remote public certificate."; - return PairedKeyVerificationResult::kSuccess; + std::vector visibilities_to_check; + // At most 3 visibilities to check. + visibilities_to_check.reserve(3); + // If we are advertising under lock screen then verify against self share + // private certificate first. + if (visibility_history_.screen_locked_advertising) { + visibilities_to_check.push_back( + DeviceVisibility::DEVICE_VISIBILITY_SELF_SHARE); } + visibilities_to_check.push_back(visibility_history_.visibility); + if (IsVisibilityRecentlyUpdated()) { + visibilities_to_check.push_back(visibility_history_.last_visibility); + } + for (const auto& visibility : visibilities_to_check) { + std::optional> hash = + certificate_manager_.HashAuthenticationTokenWithPrivateCertificate( + visibility, raw_token_); + if (hash.has_value() && *hash == frame_hash_data) { + VLOG(1) << __func__ + << ": Successfully verified remote public certificate."; + return PairedKeyVerificationResult::kSuccess; + } + } VLOG(1) << __func__ << ": Unable to verify remote public certificate."; return PairedKeyVerificationResult::kUnable; } diff --git a/sharing/paired_key_verification_runner.h b/sharing/paired_key_verification_runner.h index 372e656c..8a455b64 100644 --- a/sharing/paired_key_verification_runner.h +++ b/sharing/paired_key_verification_runner.h @@ -51,6 +51,8 @@ class PairedKeyVerificationRunner proto::DeviceVisibility visibility; proto::DeviceVisibility last_visibility; absl::Time last_visibility_time; + // Set to true if device is advertising under lock screen. + bool screen_locked_advertising = false; }; PairedKeyVerificationRunner( @@ -85,10 +87,10 @@ class PairedKeyVerificationRunner void OnReadPairedKeyResultFrame( std::optional frame); void SendPairedKeyResultFrame(PairedKeyVerificationResult result); - // Verifies auth token hash in frame using private certificate for visibility. - // Returns either kSuccess or kUnable. This function never returns kFail. - PairedKeyVerificationResult VerifyAuthTokenHashWithPrivateCertificate( - proto::DeviceVisibility visibility, + // Verifies auth token hash in frame using private certificates in + // `visibility_history_`. Returns either kSuccess or kUnable. This function + // never returns kFail. + PairedKeyVerificationResult VerifyAuthTokenHashWithPrivateCertificates( const nearby::sharing::service::proto::V1Frame& frame); PairedKeyVerificationResult VerifyPairedKeyEncryptionFrame( const nearby::sharing::service::proto::V1Frame& frame); diff --git a/sharing/paired_key_verification_runner_test.cc b/sharing/paired_key_verification_runner_test.cc index 6b02462d..2362f35f 100644 --- a/sharing/paired_key_verification_runner_test.cc +++ b/sharing/paired_key_verification_runner_test.cc @@ -126,9 +126,13 @@ GenerateVisibilityHistory() { DeviceVisibility::DEVICE_VISIBILITY_EVERYONE, }; std::list result; - for (DeviceVisibility visibility : kValidVisibilities) { - for (DeviceVisibility last_visibility : kValidVisibilities) { - result.push_back({visibility, last_visibility, absl::UnixEpoch()}); + for (bool screen_locked_advertising : {true, false}) { + for (DeviceVisibility visibility : kValidVisibilities) { + for (DeviceVisibility last_visibility : kValidVisibilities) { + result.push_back( + {visibility, last_visibility, absl::UnixEpoch(), + screen_locked_advertising}); + } } } return result; @@ -476,10 +480,12 @@ TEST_P(ParameterisedPairedKeyVerificationRunnerTest, std::get<2>(GetParam()); PairedKeyVerificationRunner::PairedKeyVerificationResult result = params.result; - // If our visibility has no certificates, then downgrade expected result to - // kUnable if it is not expected to fail. + // If our visibility has no certificates (i.e. EVERYONE and not under lock + // screen), then downgrade expected result to kUnable if it is not expected to + // fail. if ((visibility_history.visibility == - DeviceVisibility::DEVICE_VISIBILITY_EVERYONE) && + DeviceVisibility::DEVICE_VISIBILITY_EVERYONE && + !visibility_history.screen_locked_advertising) && !(visibility_history.last_visibility != DeviceVisibility::DEVICE_VISIBILITY_EVERYONE && (params.encryption_frame_type == @@ -511,7 +517,9 @@ TEST_P(ParameterisedPairedKeyVerificationRunnerTest, << ", expected_result=" << (int)expected_result << ", result_frame=" << (int)result_frame.status() << ", visibility=" << (int)visibility_history.visibility - << ", last_visibility=" << (int)visibility_history.last_visibility; + << ", last_visibility=" << (int)visibility_history.last_visibility + << ", screen_locked_advertising=" + << visibility_history.screen_locked_advertising; SetUpPairedKeyEncryptionFrame(params.encryption_frame_type); bool encryption_frame_timeout =