Update PaireKeyVerificationRunner to handle advertising under lock screen.

PiperOrigin-RevId: 945756256
This commit is contained in:
Francis Tsui
2026-07-10 09:46:37 -07:00
committed by Copybara-Service
parent 9e6f47f6f0
commit 76a08d40e9
3 changed files with 58 additions and 35 deletions
+37 -24
View File
@@ -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<std::vector<uint8_t>> 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<std::vector<uint8_t>> 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<std::vector<uint8_t>> hash =
certificate_manager_.HashAuthenticationTokenWithPrivateCertificate(
visibility, raw_token_);
const std::string& frame_hash =
frame.paired_key_encryption().secret_id_hash();
std::vector<uint8_t> 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<DeviceVisibility> 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<std::vector<uint8_t>> 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;
}
+6 -4
View File
@@ -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<nearby::sharing::service::proto::V1Frame> 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);
+15 -7
View File
@@ -126,9 +126,13 @@ GenerateVisibilityHistory() {
DeviceVisibility::DEVICE_VISIBILITY_EVERYONE,
};
std::list<PairedKeyVerificationRunner::VisibilityHistory> 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 =