Commit 2a2103bf authored by Himanshu Jaju's avatar Himanshu Jaju Committed by Commit Bot

Integrate PairedKeyVerificationRunner in NearbyService.

Integrates PairedKeyVerificationRunner in NearbyServiceImpl to verify
remote device before receiving introduction and starting the transfer
flow.

Bug: 1085068
Change-Id: I73d42d9f85f3254007cdf3fdf46c6f5e05a48630
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2352799Reviewed-by: default avatarAlex Chau <alexchau@chromium.org>
Commit-Queue: Himanshu Jaju <himanshujaju@chromium.org>
Cr-Commit-Position: refs/heads/master@{#798649}
parent d008c023
...@@ -52,6 +52,10 @@ std::vector<uint8_t> FakeNearbyConnection::GetWrittenData() { ...@@ -52,6 +52,10 @@ std::vector<uint8_t> FakeNearbyConnection::GetWrittenData() {
return bytes; return bytes;
} }
bool FakeNearbyConnection::IsClosed() {
return closed_;
}
void FakeNearbyConnection::MaybeRunCallback() { void FakeNearbyConnection::MaybeRunCallback() {
DCHECK(!closed_); DCHECK(!closed_);
if (!callback_ || read_data_.empty()) if (!callback_ || read_data_.empty())
......
...@@ -24,6 +24,8 @@ class FakeNearbyConnection : public NearbyConnection { ...@@ -24,6 +24,8 @@ class FakeNearbyConnection : public NearbyConnection {
void AppendReadableData(std::vector<uint8_t> bytes); void AppendReadableData(std::vector<uint8_t> bytes);
std::vector<uint8_t> GetWrittenData(); std::vector<uint8_t> GetWrittenData();
bool IsClosed();
private: private:
void MaybeRunCallback(); void MaybeRunCallback();
......
...@@ -99,10 +99,20 @@ base::Optional<std::vector<uint8_t>> ...@@ -99,10 +99,20 @@ base::Optional<std::vector<uint8_t>>
FakeNearbyConnectionsManager::GetRawAuthenticationToken( FakeNearbyConnectionsManager::GetRawAuthenticationToken(
const std::string& endpoint_id) { const std::string& endpoint_id) {
DCHECK(!IsShutdown()); DCHECK(!IsShutdown());
// TODO(alexchau): Implement.
auto iter = endpoint_auth_tokens_.find(endpoint_id);
if (iter != endpoint_auth_tokens_.end())
return iter->second;
return base::nullopt; return base::nullopt;
} }
void FakeNearbyConnectionsManager::SetRawAuthenticationToken(
const std::string& endpoint_id,
std::vector<uint8_t> token) {
endpoint_auth_tokens_[endpoint_id] = std::move(token);
}
void FakeNearbyConnectionsManager::UpgradeBandwidth( void FakeNearbyConnectionsManager::UpgradeBandwidth(
const std::string& endpoint_id) { const std::string& endpoint_id) {
upgrade_bandwidth_endpoint_ids_.insert(endpoint_id); upgrade_bandwidth_endpoint_ids_.insert(endpoint_id);
......
...@@ -51,6 +51,9 @@ class FakeNearbyConnectionsManager ...@@ -51,6 +51,9 @@ class FakeNearbyConnectionsManager
const std::string& endpoint_id) override; const std::string& endpoint_id) override;
void UpgradeBandwidth(const std::string& endpoint_id) override; void UpgradeBandwidth(const std::string& endpoint_id) override;
void SetRawAuthenticationToken(const std::string& endpoint_id,
std::vector<uint8_t> token);
// mojom::EndpointDiscoveryListener: // mojom::EndpointDiscoveryListener:
void OnEndpointFound( void OnEndpointFound(
const std::string& endpoint_id, const std::string& endpoint_id,
...@@ -73,6 +76,7 @@ class FakeNearbyConnectionsManager ...@@ -73,6 +76,7 @@ class FakeNearbyConnectionsManager
DataUsage advertising_data_usage_ = DataUsage::kUnknown; DataUsage advertising_data_usage_ = DataUsage::kUnknown;
PowerLevel advertising_power_level_ = PowerLevel::kUnknown; PowerLevel advertising_power_level_ = PowerLevel::kUnknown;
std::set<std::string> upgrade_bandwidth_endpoint_ids_; std::set<std::string> upgrade_bandwidth_endpoint_ids_;
std::map<std::string, std::vector<uint8_t>> endpoint_auth_tokens_;
}; };
#endif // CHROME_BROWSER_NEARBY_SHARING_FAKE_NEARBY_CONNECTIONS_MANAGER_H_ #endif // CHROME_BROWSER_NEARBY_SHARING_FAKE_NEARBY_CONNECTIONS_MANAGER_H_
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/strings/stringprintf.h"
#include "base/task/post_task.h" #include "base/task/post_task.h"
#include "base/task_runner_util.h" #include "base/task_runner_util.h"
#include "base/threading/sequenced_task_runner_handle.h" #include "base/threading/sequenced_task_runner_handle.h"
...@@ -20,6 +21,7 @@ ...@@ -20,6 +21,7 @@
#include "chrome/browser/nearby_sharing/local_device_data/nearby_share_local_device_data_manager_impl.h" #include "chrome/browser/nearby_sharing/local_device_data/nearby_share_local_device_data_manager_impl.h"
#include "chrome/browser/nearby_sharing/logging/logging.h" #include "chrome/browser/nearby_sharing/logging/logging.h"
#include "chrome/browser/nearby_sharing/nearby_connections_manager.h" #include "chrome/browser/nearby_sharing/nearby_connections_manager.h"
#include "chrome/browser/nearby_sharing/paired_key_verification_runner.h"
#include "chrome/browser/nearby_sharing/transfer_metadata_builder.h" #include "chrome/browser/nearby_sharing/transfer_metadata_builder.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "chrome/browser/signin/identity_manager_factory.h" #include "chrome/browser/signin/identity_manager_factory.h"
...@@ -42,6 +44,10 @@ constexpr base::TimeDelta kIncomingRejectionDelay = ...@@ -42,6 +44,10 @@ constexpr base::TimeDelta kIncomingRejectionDelay =
constexpr base::TimeDelta kInvalidateDelay = constexpr base::TimeDelta kInvalidateDelay =
base::TimeDelta::FromMilliseconds(500); base::TimeDelta::FromMilliseconds(500);
// Used to hash a token into a 4 digit string.
constexpr int kHashModulo = 9973;
constexpr int kHashBaseMultiplier = 31;
std::string ReceiveSurfaceStateToString( std::string ReceiveSurfaceStateToString(
NearbySharingService::ReceiveSurfaceState state) { NearbySharingService::ReceiveSurfaceState state) {
switch (state) { switch (state) {
...@@ -93,6 +99,17 @@ std::string GetDeviceId( ...@@ -93,6 +99,17 @@ std::string GetDeviceId(
return std::string(certificate->id().begin(), certificate->id().end()); return std::string(certificate->id().begin(), certificate->id().end());
} }
std::string ToFourDigitString(const std::vector<uint8_t>& bytes) {
int hash = 0;
int multiplier = 1;
for (auto byte : bytes) {
hash = (hash + byte * multiplier) % kHashModulo;
multiplier = (multiplier * kHashBaseMultiplier) % kHashModulo;
}
return base::StringPrintf("%04d", std::abs(hash));
}
} // namespace } // namespace
NearbySharingServiceImpl::NearbySharingServiceImpl( NearbySharingServiceImpl::NearbySharingServiceImpl(
...@@ -456,12 +473,23 @@ void NearbySharingServiceImpl::OnIncomingConnection( ...@@ -456,12 +473,23 @@ void NearbySharingServiceImpl::OnIncomingConnection(
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(connection); DCHECK(connection);
ShareTarget placeholder_share_target;
auto& share_target_info =
GetIncomingShareTargetInfo(placeholder_share_target);
share_target_info.set_connection(connection);
share_target_info.set_endpoint_id(endpoint_id);
connection->SetDisconnectionListener(
base::BindOnce(&NearbySharingServiceImpl::RefreshUIOnDisconnection,
weak_ptr_factory_.GetWeakPtr(), placeholder_share_target));
process_manager_->GetOrStartNearbySharingDecoder(profile_) process_manager_->GetOrStartNearbySharingDecoder(profile_)
->DecodeAdvertisement( ->DecodeAdvertisement(
endpoint_info, endpoint_info,
base::BindOnce( base::BindOnce(
&NearbySharingServiceImpl::OnIncomingAdvertisementDecoded, &NearbySharingServiceImpl::OnIncomingAdvertisementDecoded,
weak_ptr_factory_.GetWeakPtr(), endpoint_id, connection)); weak_ptr_factory_.GetWeakPtr(), endpoint_id,
std::move(placeholder_share_target)));
} }
void NearbySharingServiceImpl::OnEndpointDiscovered( void NearbySharingServiceImpl::OnEndpointDiscovered(
...@@ -1259,8 +1287,16 @@ void NearbySharingServiceImpl::CloseConnection( ...@@ -1259,8 +1287,16 @@ void NearbySharingServiceImpl::CloseConnection(
void NearbySharingServiceImpl::OnIncomingAdvertisementDecoded( void NearbySharingServiceImpl::OnIncomingAdvertisementDecoded(
const std::string& endpoint_id, const std::string& endpoint_id,
NearbyConnection* connection, ShareTarget placeholder_share_target,
sharing::mojom::AdvertisementPtr advertisement) { sharing::mojom::AdvertisementPtr advertisement) {
NearbyConnection* connection =
GetIncomingConnection(placeholder_share_target);
if (!connection) {
NS_LOG(VERBOSE) << __func__ << ": Invalid connection for endoint id - "
<< endpoint_id;
return;
}
if (!advertisement) { if (!advertisement) {
NS_LOG(VERBOSE) << __func__ NS_LOG(VERBOSE) << __func__
<< "Failed to parse incoming connection from endpoint - " << "Failed to parse incoming connection from endpoint - "
...@@ -1274,15 +1310,28 @@ void NearbySharingServiceImpl::OnIncomingAdvertisementDecoded( ...@@ -1274,15 +1310,28 @@ void NearbySharingServiceImpl::OnIncomingAdvertisementDecoded(
GetCertificateManager()->GetDecryptedPublicCertificate( GetCertificateManager()->GetDecryptedPublicCertificate(
std::move(encrypted_metadata_key), std::move(encrypted_metadata_key),
base::BindOnce(&NearbySharingServiceImpl::OnIncomingDecryptedCertificate, base::BindOnce(&NearbySharingServiceImpl::OnIncomingDecryptedCertificate,
weak_ptr_factory_.GetWeakPtr(), endpoint_id, connection, weak_ptr_factory_.GetWeakPtr(), endpoint_id,
std::move(advertisement))); std::move(advertisement),
std::move(placeholder_share_target)));
} }
void NearbySharingServiceImpl::OnIncomingDecryptedCertificate( void NearbySharingServiceImpl::OnIncomingDecryptedCertificate(
const std::string& endpoint_id, const std::string& endpoint_id,
NearbyConnection* connection,
sharing::mojom::AdvertisementPtr advertisement, sharing::mojom::AdvertisementPtr advertisement,
ShareTarget placeholder_share_target,
base::Optional<NearbyShareDecryptedPublicCertificate> certificate) { base::Optional<NearbyShareDecryptedPublicCertificate> certificate) {
NearbyConnection* connection =
GetIncomingConnection(placeholder_share_target);
if (!connection) {
NS_LOG(VERBOSE) << __func__ << ": Invalid connection for endpoint id - "
<< endpoint_id;
return;
}
// Remove placeholder share target since we are creating the actual share
// target below.
incoming_share_target_info_map_.erase(placeholder_share_target.id);
base::Optional<ShareTarget> share_target = CreateShareTarget( base::Optional<ShareTarget> share_target = CreateShareTarget(
endpoint_id, advertisement, std::move(certificate), /*is_incoming=*/true); endpoint_id, advertisement, std::move(certificate), /*is_incoming=*/true);
...@@ -1305,10 +1354,98 @@ void NearbySharingServiceImpl::OnIncomingDecryptedCertificate( ...@@ -1305,10 +1354,98 @@ void NearbySharingServiceImpl::OnIncomingDecryptedCertificate(
connection->SetDisconnectionListener( connection->SetDisconnectionListener(
base::BindOnce(&NearbySharingServiceImpl::UnregisterShareTarget, base::BindOnce(&NearbySharingServiceImpl::UnregisterShareTarget,
weak_ptr_factory_.GetWeakPtr(), *share_target)); weak_ptr_factory_.GetWeakPtr(), *share_target));
base::Optional<std::vector<uint8_t>> token =
nearby_connections_manager_->GetRawAuthenticationToken(endpoint_id);
if (!token) {
NS_LOG(VERBOSE) << __func__
<< ": Failed to read authentication token from endpoint - "
<< endpoint_id;
OnIncomingConnectionKeyVerificationDone(
std::move(*share_target), std::move(token),
PairedKeyVerificationRunner::PairedKeyVerificationResult::kFail);
return;
}
// TODO(himanshujaju) - Implement RunPairedKeyVerification. share_target_info.set_frames_reader(std::make_unique<IncomingFramesReader>(
process_manager_, profile_, connection));
ReceiveIntroduction(std::move(*share_target), /*token=*/base::nullopt); bool restrict_to_contacts =
advertising_power_level_ != PowerLevel::kHighPower;
share_target_info.set_key_verification_runner(
std::make_unique<PairedKeyVerificationRunner>(
*share_target, endpoint_id, *token, connection,
share_target_info.certificate(), GetCertificateManager(),
settings_.GetVisibility(), restrict_to_contacts,
share_target_info.frames_reader(), kReadFramesTimeout));
share_target_info.key_verification_runner()->Run(base::BindOnce(
&NearbySharingServiceImpl::OnIncomingConnectionKeyVerificationDone,
weak_ptr_factory_.GetWeakPtr(), std::move(*share_target),
std::move(token)));
}
void NearbySharingServiceImpl::OnIncomingConnectionKeyVerificationDone(
ShareTarget share_target,
base::Optional<std::vector<uint8_t>> token,
PairedKeyVerificationRunner::PairedKeyVerificationResult result) {
NearbyConnection* connection = GetIncomingConnection(share_target);
const base::Optional<std::string>& endpoint_id =
GetIncomingShareTargetInfo(share_target).endpoint_id();
if (!connection || !endpoint_id) {
NS_LOG(VERBOSE) << __func__ << ": Invalid connection or endpoint id";
return;
}
base::Optional<std::string> token_string;
if (token)
token_string = ToFourDigitString(*token);
switch (result) {
case PairedKeyVerificationRunner::PairedKeyVerificationResult::kFail:
NS_LOG(VERBOSE) << __func__
<< ": Paired key handshake failed, disconnecting.";
connection->Close();
return;
case PairedKeyVerificationRunner::PairedKeyVerificationResult::kSuccess:
NS_LOG(VERBOSE) << __func__
<< ": Paired key handshake succeeded for target - "
<< share_target.device_name;
nearby_connections_manager_->UpgradeBandwidth(*endpoint_id);
ReceiveIntroduction(share_target, /*token=*/base::nullopt);
break;
case PairedKeyVerificationRunner::PairedKeyVerificationResult::kUnable:
NS_LOG(VERBOSE) << __func__
<< ": Unable to verify paired key encryption when "
"receiving connection from target - "
<< share_target.device_name;
if (advertising_power_level_ == PowerLevel::kHighPower)
nearby_connections_manager_->UpgradeBandwidth(*endpoint_id);
if (token_string)
GetIncomingShareTargetInfo(share_target).set_token(*token_string);
ReceiveIntroduction(share_target, std::move(token_string));
break;
case PairedKeyVerificationRunner::PairedKeyVerificationResult::kUnknown:
NS_LOG(VERBOSE)
<< __func__
<< ": Unknown PairedKeyVerificationResult, disconnecting.";
connection->Close();
break;
}
}
void NearbySharingServiceImpl::RefreshUIOnDisconnection(
ShareTarget share_target) {
OnIncomingTransferUpdate(
share_target,
TransferMetadataBuilder()
.set_status(TransferMetadata::Status::kAwaitingRemoteAcceptanceFailed)
.build());
UnregisterShareTarget(share_target);
} }
void NearbySharingServiceImpl::ReceiveIntroduction( void NearbySharingServiceImpl::ReceiveIntroduction(
...@@ -1326,8 +1463,6 @@ void NearbySharingServiceImpl::ReceiveIntroduction( ...@@ -1326,8 +1463,6 @@ void NearbySharingServiceImpl::ReceiveIntroduction(
} }
auto& share_target_info = GetIncomingShareTargetInfo(share_target); auto& share_target_info = GetIncomingShareTargetInfo(share_target);
share_target_info.set_frames_reader(std::make_unique<IncomingFramesReader>(
process_manager_, profile_, connection));
share_target_info.frames_reader()->ReadFrame( share_target_info.frames_reader()->ReadFrame(
sharing::mojom::V1Frame::Tag::INTRODUCTION, sharing::mojom::V1Frame::Tag::INTRODUCTION,
base::BindOnce(&NearbySharingServiceImpl::OnReceivedIntroduction, base::BindOnce(&NearbySharingServiceImpl::OnReceivedIntroduction,
...@@ -1426,6 +1561,7 @@ void NearbySharingServiceImpl::OnReceivedIntroduction( ...@@ -1426,6 +1561,7 @@ void NearbySharingServiceImpl::OnReceivedIntroduction(
share_target, share_target,
TransferMetadataBuilder() TransferMetadataBuilder()
.set_status(TransferMetadata::Status::kAwaitingLocalConfirmation) .set_status(TransferMetadata::Status::kAwaitingLocalConfirmation)
.set_token(std::move(token))
.build()); .build());
if (!incoming_share_target_info_map_.count(share_target.id)) { if (!incoming_share_target_info_map_.count(share_target.id)) {
...@@ -1606,6 +1742,9 @@ void NearbySharingServiceImpl::ClearOutgoingShareTargetInfoMap() { ...@@ -1606,6 +1742,9 @@ void NearbySharingServiceImpl::ClearOutgoingShareTargetInfoMap() {
void NearbySharingServiceImpl::UnregisterShareTarget( void NearbySharingServiceImpl::UnregisterShareTarget(
const ShareTarget& share_target) { const ShareTarget& share_target) {
NS_LOG(VERBOSE) << __func__ << ": Unregistering share target - "
<< share_target.device_name;
if (share_target.is_incoming) { if (share_target.is_incoming) {
incoming_share_target_info_map_.erase(share_target.id); incoming_share_target_info_map_.erase(share_target.id);
// Clear legacy incoming payloads to release resource // Clear legacy incoming payloads to release resource
......
...@@ -174,16 +174,21 @@ class NearbySharingServiceImpl ...@@ -174,16 +174,21 @@ class NearbySharingServiceImpl
StatusCodes StopScanning(); StatusCodes StopScanning();
void OnIncomingAdvertisementDecoded( void OnIncomingAdvertisementDecoded(
const std::string& endpoint_id, const std::string& endpoint_id,
NearbyConnection* connection, ShareTarget placeholder_share_target,
sharing::mojom::AdvertisementPtr advertisement); sharing::mojom::AdvertisementPtr advertisement);
void OnIncomingTransferUpdate(const ShareTarget& share_target, void OnIncomingTransferUpdate(const ShareTarget& share_target,
TransferMetadata metadata); TransferMetadata metadata);
void CloseConnection(const ShareTarget& share_target); void CloseConnection(const ShareTarget& share_target);
void OnIncomingDecryptedCertificate( void OnIncomingDecryptedCertificate(
const std::string& endpoint_id, const std::string& endpoint_id,
NearbyConnection* connection,
sharing::mojom::AdvertisementPtr advertisement, sharing::mojom::AdvertisementPtr advertisement,
ShareTarget placeholder_share_target,
base::Optional<NearbyShareDecryptedPublicCertificate> certificate); base::Optional<NearbyShareDecryptedPublicCertificate> certificate);
void OnIncomingConnectionKeyVerificationDone(
ShareTarget share_target,
base::Optional<std::vector<uint8_t>> token,
PairedKeyVerificationRunner::PairedKeyVerificationResult result);
void RefreshUIOnDisconnection(ShareTarget share_target);
void ReceiveIntroduction(ShareTarget share_target, void ReceiveIntroduction(ShareTarget share_target,
base::Optional<std::string> token); base::Optional<std::string> token);
void OnReceivedIntroduction(ShareTarget share_target, void OnReceivedIntroduction(ShareTarget share_target,
......
...@@ -176,6 +176,19 @@ const std::vector<uint8_t> kValidV1EndpointInfo = { ...@@ -176,6 +176,19 @@ const std::vector<uint8_t> kValidV1EndpointInfo = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 10, 100, 101, 118, 105, 99, 101, 78, 97, 109, 101}; 0, 0, 0, 10, 100, 101, 118, 105, 99, 101, 78, 97, 109, 101};
const std::vector<uint8_t> kToken = {0, 1, 2};
const char kFourDigitToken[] = "1953";
const std::vector<uint8_t> kPrivateCertificateHashAuthToken = {
0x8b, 0xcb, 0xa2, 0xf8, 0xe4, 0x06};
const std::vector<uint8_t> kIncomingConnectionSignedData = {
0x30, 0x45, 0x02, 0x20, 0x4f, 0x83, 0x72, 0xbd, 0x02, 0x70, 0xd9, 0xda,
0x62, 0x83, 0x5d, 0xb2, 0xdc, 0x6e, 0x3f, 0xa6, 0xa8, 0xa1, 0x4f, 0x5f,
0xd3, 0xe3, 0xd9, 0x1a, 0x5d, 0x2d, 0x61, 0xd2, 0x6c, 0xdd, 0x8d, 0xa5,
0x02, 0x21, 0x00, 0xd4, 0xe1, 0x1d, 0x14, 0xcb, 0x58, 0xf7, 0x02, 0xd5,
0xab, 0x48, 0xe2, 0x2f, 0xcb, 0xc0, 0x53, 0x41, 0x06, 0x50, 0x65, 0x95,
0x19, 0xa9, 0x22, 0x92, 0x00, 0x42, 0x01, 0x26, 0x25, 0xcb, 0x8c};
sharing::mojom::FramePtr GetValidIntroductionFrame() { sharing::mojom::FramePtr GetValidIntroductionFrame() {
std::vector<sharing::mojom::TextMetadataPtr> mojo_text_metadatas; std::vector<sharing::mojom::TextMetadataPtr> mojo_text_metadatas;
// TODO(himanshujaju) - Parameterise number of text and file metadatas. // TODO(himanshujaju) - Parameterise number of text and file metadatas.
...@@ -207,7 +220,8 @@ sharing::mojom::FramePtr GetEmptyIntroductionFrame() { ...@@ -207,7 +220,8 @@ sharing::mojom::FramePtr GetEmptyIntroductionFrame() {
class NearbySharingServiceImplTest : public testing::Test { class NearbySharingServiceImplTest : public testing::Test {
public: public:
NearbySharingServiceImplTest() { NearbySharingServiceImplTest()
: task_environment_(base::test::TaskEnvironment::TimeSource::MOCK_TIME) {
scoped_feature_list_.InitAndEnableFeature(features::kNearbySharing); scoped_feature_list_.InitAndEnableFeature(features::kNearbySharing);
RegisterNearbySharingPrefs(prefs_.registry()); RegisterNearbySharingPrefs(prefs_.registry());
} }
...@@ -269,6 +283,11 @@ class NearbySharingServiceImplTest : public testing::Test { ...@@ -269,6 +283,11 @@ class NearbySharingServiceImplTest : public testing::Test {
return service; return service;
} }
void SetVisibility(nearby_share::mojom::Visibility visibility) {
NearbyShareSettings settings(&prefs_);
settings.SetVisibility(visibility);
}
void SetFakeFastInitiationManagerFactory(bool should_succeed_on_start) { void SetFakeFastInitiationManagerFactory(bool should_succeed_on_start) {
fast_initiation_manager_factory_ = fast_initiation_manager_factory_ =
std::make_unique<FakeFastInitiationManagerFactory>( std::make_unique<FakeFastInitiationManagerFactory>(
...@@ -295,7 +314,8 @@ class NearbySharingServiceImplTest : public testing::Test { ...@@ -295,7 +314,8 @@ class NearbySharingServiceImplTest : public testing::Test {
return mock_nearby_process_manager_; return mock_nearby_process_manager_;
} }
void SetUpReceiveSurface(NiceMock<MockTransferUpdateCallback>& callback) { void SetUpForegroundReceiveSurface(
NiceMock<MockTransferUpdateCallback>& callback) {
NearbySharingService::StatusCodes result = service_->RegisterReceiveSurface( NearbySharingService::StatusCodes result = service_->RegisterReceiveSurface(
&callback, NearbySharingService::ReceiveSurfaceState::kForeground); &callback, NearbySharingService::ReceiveSurfaceState::kForeground);
EXPECT_EQ(result, NearbySharingService::StatusCodes::kOk); EXPECT_EQ(result, NearbySharingService::StatusCodes::kOk);
...@@ -326,6 +346,52 @@ class NearbySharingServiceImplTest : public testing::Test { ...@@ -326,6 +346,52 @@ class NearbySharingServiceImplTest : public testing::Test {
} }
} }
void SetUpKeyVerification(
sharing::mojom::PairedKeyResultFrame::Status status) {
SetVisibility(nearby_share::mojom::Visibility::kAllContacts);
std::string encryption_frame = "test_encryption_frame";
std::vector<uint8_t> encryption_bytes(encryption_frame.begin(),
encryption_frame.end());
EXPECT_CALL(mock_decoder_,
DecodeFrame(testing::Eq(encryption_bytes), testing::_))
.WillOnce(testing::Invoke(
[](const std::vector<uint8_t>& data,
MockNearbySharingDecoder::DecodeFrameCallback callback) {
sharing::mojom::V1FramePtr mojo_v1frame =
sharing::mojom::V1Frame::New();
mojo_v1frame->set_paired_key_encryption(
sharing::mojom::PairedKeyEncryptionFrame::New(
kIncomingConnectionSignedData,
kPrivateCertificateHashAuthToken));
sharing::mojom::FramePtr mojo_frame =
sharing::mojom::Frame::New();
mojo_frame->set_v1(std::move(mojo_v1frame));
std::move(callback).Run(std::move(mojo_frame));
}));
connection_.AppendReadableData(encryption_bytes);
std::string encryption_result = "test_encryption_result";
std::vector<uint8_t> result_bytes(encryption_result.begin(),
encryption_result.end());
EXPECT_CALL(mock_decoder_,
DecodeFrame(testing::Eq(result_bytes), testing::_))
.WillOnce(testing::Invoke(
[=](const std::vector<uint8_t>& data,
MockNearbySharingDecoder::DecodeFrameCallback callback) {
sharing::mojom::V1FramePtr mojo_v1frame =
sharing::mojom::V1Frame::New();
mojo_v1frame->set_paired_key_result(
sharing::mojom::PairedKeyResultFrame::New(status));
sharing::mojom::FramePtr mojo_frame =
sharing::mojom::Frame::New();
mojo_frame->set_v1(std::move(mojo_v1frame));
std::move(callback).Run(std::move(mojo_frame));
}));
connection_.AppendReadableData(result_bytes);
}
void SetUpAdvertisementDecoder(const std::vector<uint8_t>& endpoint_info, void SetUpAdvertisementDecoder(const std::vector<uint8_t>& endpoint_info,
bool return_empty_advertisement) { bool return_empty_advertisement) {
EXPECT_CALL(mock_decoder_, EXPECT_CALL(mock_decoder_,
...@@ -364,6 +430,8 @@ class NearbySharingServiceImplTest : public testing::Test { ...@@ -364,6 +430,8 @@ class NearbySharingServiceImplTest : public testing::Test {
ShareTarget SetUpIncomingConnection( ShareTarget SetUpIncomingConnection(
NiceMock<MockTransferUpdateCallback>& callback) { NiceMock<MockTransferUpdateCallback>& callback) {
fake_nearby_connections_manager_->SetRawAuthenticationToken(kEndpointId,
kToken);
SetUpAdvertisementDecoder(kValidV1EndpointInfo, SetUpAdvertisementDecoder(kValidV1EndpointInfo,
/*return_empty_advertisement=*/false); /*return_empty_advertisement=*/false);
SetUpIntroductionFrameDecoder(/*return_empty_introduction_frame=*/false); SetUpIntroductionFrameDecoder(/*return_empty_introduction_frame=*/false);
...@@ -381,16 +449,48 @@ class NearbySharingServiceImplTest : public testing::Test { ...@@ -381,16 +449,48 @@ class NearbySharingServiceImplTest : public testing::Test {
share_target = incoming_share_target; share_target = incoming_share_target;
run_loop.Quit(); run_loop.Quit();
})); }));
SetUpReceiveSurface(callback);
SetUpKeyVerification(sharing::mojom::PairedKeyResultFrame_Status::kSuccess);
SetUpForegroundReceiveSurface(callback);
service_->OnIncomingConnection(kEndpointId, kValidV1EndpointInfo, service_->OnIncomingConnection(kEndpointId, kValidV1EndpointInfo,
&connection_); &connection_);
ProcessLatestPublicCertificateDecryption(/*expected_num_calls=*/1, ProcessLatestPublicCertificateDecryption(/*expected_num_calls=*/1,
/*success=*/true); /*success=*/true);
run_loop.Run(); run_loop.Run();
EXPECT_TRUE(
fake_nearby_connections_manager_->DidUpgradeBandwidth(kEndpointId));
return share_target; return share_target;
} }
sharing::nearby::Frame GetWrittenFrame() {
std::vector<uint8_t> data = connection_.GetWrittenData();
sharing::nearby::Frame frame;
frame.ParseFromArray(data.data(), data.size());
return frame;
}
void ExpectPairedKeyEncryptionFrame() {
sharing::nearby::Frame frame = GetWrittenFrame();
ASSERT_TRUE(frame.has_v1());
ASSERT_TRUE(frame.v1().has_paired_key_encryption());
}
void ExpectPairedKeyResultFrame() {
sharing::nearby::Frame frame = GetWrittenFrame();
ASSERT_TRUE(frame.has_v1());
ASSERT_TRUE(frame.v1().has_paired_key_result());
}
void ExpectConnectionResponseFrame(
sharing::nearby::ConnectionResponseFrame::Status status) {
sharing::nearby::Frame frame = GetWrittenFrame();
ASSERT_TRUE(frame.has_v1());
ASSERT_TRUE(frame.v1().has_connection_response());
EXPECT_EQ(status, frame.v1().connection_response().status());
}
protected: protected:
FakeNearbyShareLocalDeviceDataManager* local_device_data_manager() { FakeNearbyShareLocalDeviceDataManager* local_device_data_manager() {
EXPECT_EQ(1u, local_device_data_manager_factory_.instances().size()); EXPECT_EQ(1u, local_device_data_manager_factory_.instances().size());
...@@ -1328,6 +1428,8 @@ TEST_F(NearbySharingServiceImplTest, UnregisterReceiveSurfaceNeverRegistered) { ...@@ -1328,6 +1428,8 @@ TEST_F(NearbySharingServiceImplTest, UnregisterReceiveSurfaceNeverRegistered) {
TEST_F(NearbySharingServiceImplTest, TEST_F(NearbySharingServiceImplTest,
IncomingConnection_ClosedReadingIntroduction) { IncomingConnection_ClosedReadingIntroduction) {
fake_nearby_connections_manager_->SetRawAuthenticationToken(kEndpointId,
kToken);
SetUpAdvertisementDecoder(kValidV1EndpointInfo, SetUpAdvertisementDecoder(kValidV1EndpointInfo,
/*return_empty_advertisement=*/false); /*return_empty_advertisement=*/false);
...@@ -1335,7 +1437,9 @@ TEST_F(NearbySharingServiceImplTest, ...@@ -1335,7 +1437,9 @@ TEST_F(NearbySharingServiceImplTest,
SetConnectionType(net::NetworkChangeNotifier::CONNECTION_WIFI); SetConnectionType(net::NetworkChangeNotifier::CONNECTION_WIFI);
NiceMock<MockTransferUpdateCallback> callback; NiceMock<MockTransferUpdateCallback> callback;
EXPECT_CALL(callback, OnTransferUpdate(testing::_, testing::_)).Times(0); EXPECT_CALL(callback, OnTransferUpdate(testing::_, testing::_)).Times(0);
SetUpReceiveSurface(callback);
SetUpKeyVerification(sharing::mojom::PairedKeyResultFrame_Status::kSuccess);
SetUpForegroundReceiveSurface(callback);
service_->OnIncomingConnection(kEndpointId, kValidV1EndpointInfo, service_->OnIncomingConnection(kEndpointId, kValidV1EndpointInfo,
&connection_); &connection_);
ProcessLatestPublicCertificateDecryption(/*expected_num_calls=*/1, ProcessLatestPublicCertificateDecryption(/*expected_num_calls=*/1,
...@@ -1350,6 +1454,8 @@ TEST_F(NearbySharingServiceImplTest, ...@@ -1350,6 +1454,8 @@ TEST_F(NearbySharingServiceImplTest,
TEST_F(NearbySharingServiceImplTest, TEST_F(NearbySharingServiceImplTest,
IncomingConnection_EmptyIntroductionFrame) { IncomingConnection_EmptyIntroductionFrame) {
fake_nearby_connections_manager_->SetRawAuthenticationToken(kEndpointId,
kToken);
SetUpAdvertisementDecoder(kValidV1EndpointInfo, SetUpAdvertisementDecoder(kValidV1EndpointInfo,
/*return_empty_advertisement=*/false); /*return_empty_advertisement=*/false);
SetUpIntroductionFrameDecoder(/*return_empty_introduction_frame=*/true); SetUpIntroductionFrameDecoder(/*return_empty_introduction_frame=*/true);
...@@ -1377,7 +1483,9 @@ TEST_F(NearbySharingServiceImplTest, ...@@ -1377,7 +1483,9 @@ TEST_F(NearbySharingServiceImplTest,
EXPECT_TRUE(metadata.is_final_status()); EXPECT_TRUE(metadata.is_final_status());
run_loop.Quit(); run_loop.Quit();
})); }));
SetUpReceiveSurface(callback);
SetUpKeyVerification(sharing::mojom::PairedKeyResultFrame_Status::kSuccess);
SetUpForegroundReceiveSurface(callback);
service_->OnIncomingConnection(kEndpointId, kValidV1EndpointInfo, service_->OnIncomingConnection(kEndpointId, kValidV1EndpointInfo,
&connection_); &connection_);
ProcessLatestPublicCertificateDecryption(/*expected_num_calls=*/1, ProcessLatestPublicCertificateDecryption(/*expected_num_calls=*/1,
...@@ -1385,15 +1493,10 @@ TEST_F(NearbySharingServiceImplTest, ...@@ -1385,15 +1493,10 @@ TEST_F(NearbySharingServiceImplTest,
run_loop.Run(); run_loop.Run();
// Check data written to connection_. // Check data written to connection_.
std::vector<uint8_t> data = connection_.GetWrittenData(); ExpectPairedKeyEncryptionFrame();
sharing::nearby::Frame frame; ExpectPairedKeyResultFrame();
frame.ParseFromArray(data.data(), data.size()); ExpectConnectionResponseFrame(
sharing::nearby::ConnectionResponseFrame::UNSUPPORTED_ATTACHMENT_TYPE);
EXPECT_TRUE(frame.has_v1());
EXPECT_TRUE(frame.v1().has_connection_response());
EXPECT_EQ(
sharing::nearby::ConnectionResponseFrame::UNSUPPORTED_ATTACHMENT_TYPE,
frame.v1().connection_response().status());
// To avoid UAF in OnIncomingTransferUpdate(). // To avoid UAF in OnIncomingTransferUpdate().
service_->UnregisterReceiveSurface(&callback); service_->UnregisterReceiveSurface(&callback);
...@@ -1401,6 +1504,8 @@ TEST_F(NearbySharingServiceImplTest, ...@@ -1401,6 +1504,8 @@ TEST_F(NearbySharingServiceImplTest,
TEST_F(NearbySharingServiceImplTest, TEST_F(NearbySharingServiceImplTest,
IncomingConnection_ValidIntroductionFrame_InvalidCertificate) { IncomingConnection_ValidIntroductionFrame_InvalidCertificate) {
fake_nearby_connections_manager_->SetRawAuthenticationToken(kEndpointId,
kToken);
SetUpAdvertisementDecoder(kValidV1EndpointInfo, SetUpAdvertisementDecoder(kValidV1EndpointInfo,
/*return_empty_advertisement=*/false); /*return_empty_advertisement=*/false);
SetUpIntroductionFrameDecoder(/*return_empty_introduction_frame=*/false); SetUpIntroductionFrameDecoder(/*return_empty_introduction_frame=*/false);
...@@ -1429,13 +1534,17 @@ TEST_F(NearbySharingServiceImplTest, ...@@ -1429,13 +1534,17 @@ TEST_F(NearbySharingServiceImplTest,
EXPECT_FALSE(metadata.is_final_status()); EXPECT_FALSE(metadata.is_final_status());
run_loop.Quit(); run_loop.Quit();
})); }));
SetUpReceiveSurface(callback);
SetUpKeyVerification(sharing::mojom::PairedKeyResultFrame_Status::kSuccess);
SetUpForegroundReceiveSurface(callback);
service_->OnIncomingConnection(kEndpointId, kValidV1EndpointInfo, service_->OnIncomingConnection(kEndpointId, kValidV1EndpointInfo,
&connection_); &connection_);
ProcessLatestPublicCertificateDecryption(/*expected_num_calls=*/1, ProcessLatestPublicCertificateDecryption(/*expected_num_calls=*/1,
/*success=*/false); /*success=*/false);
run_loop.Run(); run_loop.Run();
EXPECT_FALSE(connection_.IsClosed());
// To avoid UAF in OnIncomingTransferUpdate(). // To avoid UAF in OnIncomingTransferUpdate().
service_->UnregisterReceiveSurface(&callback); service_->UnregisterReceiveSurface(&callback);
} }
...@@ -1463,6 +1572,8 @@ TEST_F(NearbySharingServiceImplTest, ...@@ -1463,6 +1572,8 @@ TEST_F(NearbySharingServiceImplTest,
TEST_F(NearbySharingServiceImplTest, TEST_F(NearbySharingServiceImplTest,
IncomingConnection_ValidIntroductionFrame_ValidCertificate) { IncomingConnection_ValidIntroductionFrame_ValidCertificate) {
fake_nearby_connections_manager_->SetRawAuthenticationToken(kEndpointId,
kToken);
SetUpAdvertisementDecoder(kValidV1EndpointInfo, SetUpAdvertisementDecoder(kValidV1EndpointInfo,
/*return_empty_advertisement=*/false); /*return_empty_advertisement=*/false);
SetUpIntroductionFrameDecoder(/*return_empty_introduction_frame=*/false); SetUpIntroductionFrameDecoder(/*return_empty_introduction_frame=*/false);
...@@ -1487,18 +1598,24 @@ TEST_F(NearbySharingServiceImplTest, ...@@ -1487,18 +1598,24 @@ TEST_F(NearbySharingServiceImplTest,
EXPECT_NE(kEndpointId, share_target.device_id); EXPECT_NE(kEndpointId, share_target.device_id);
EXPECT_EQ(kTestMetadataFullName, share_target.full_name); EXPECT_EQ(kTestMetadataFullName, share_target.full_name);
EXPECT_FALSE(metadata.token().has_value());
EXPECT_EQ(TransferMetadata::Status::kAwaitingLocalConfirmation, EXPECT_EQ(TransferMetadata::Status::kAwaitingLocalConfirmation,
metadata.status()); metadata.status());
EXPECT_FALSE(metadata.is_final_status()); EXPECT_FALSE(metadata.is_final_status());
run_loop.Quit(); run_loop.Quit();
})); }));
SetUpReceiveSurface(callback);
SetUpKeyVerification(sharing::mojom::PairedKeyResultFrame_Status::kSuccess);
SetUpForegroundReceiveSurface(callback);
service_->OnIncomingConnection(kEndpointId, kValidV1EndpointInfo, service_->OnIncomingConnection(kEndpointId, kValidV1EndpointInfo,
&connection_); &connection_);
ProcessLatestPublicCertificateDecryption(/*expected_num_calls=*/1, ProcessLatestPublicCertificateDecryption(/*expected_num_calls=*/1,
/*success=*/true); /*success=*/true);
run_loop.Run(); run_loop.Run();
EXPECT_FALSE(connection_.IsClosed());
// To avoid UAF in OnIncomingTransferUpdate(). // To avoid UAF in OnIncomingTransferUpdate().
service_->UnregisterReceiveSurface(&callback); service_->UnregisterReceiveSurface(&callback);
} }
...@@ -1543,15 +1660,14 @@ TEST_F(NearbySharingServiceImplTest, AcceptValidShareTarget) { ...@@ -1543,15 +1660,14 @@ TEST_F(NearbySharingServiceImplTest, AcceptValidShareTarget) {
EXPECT_TRUE( EXPECT_TRUE(
fake_nearby_connections_manager_->DidUpgradeBandwidth(kEndpointId)); fake_nearby_connections_manager_->DidUpgradeBandwidth(kEndpointId));
// Check data written to connection_. // Check data written to connection_.
std::vector<uint8_t> data = connection_.GetWrittenData(); ExpectPairedKeyEncryptionFrame();
sharing::nearby::Frame frame; ExpectPairedKeyResultFrame();
frame.ParseFromArray(data.data(), data.size()); ExpectConnectionResponseFrame(
sharing::nearby::ConnectionResponseFrame::ACCEPT);
EXPECT_TRUE(frame.has_v1()); EXPECT_FALSE(connection_.IsClosed());
EXPECT_TRUE(frame.v1().has_connection_response());
EXPECT_EQ(sharing::nearby::ConnectionResponseFrame::ACCEPT,
frame.v1().connection_response().status());
// To avoid UAF in OnIncomingTransferUpdate(). // To avoid UAF in OnIncomingTransferUpdate().
service_->UnregisterReceiveSurface(&callback); service_->UnregisterReceiveSurface(&callback);
...@@ -1595,14 +1711,185 @@ TEST_F(NearbySharingServiceImplTest, RejectValidShareTarget) { ...@@ -1595,14 +1711,185 @@ TEST_F(NearbySharingServiceImplTest, RejectValidShareTarget) {
run_loop_reject.Run(); run_loop_reject.Run();
// Check data written to connection_. // Check data written to connection_.
std::vector<uint8_t> data = connection_.GetWrittenData(); ExpectPairedKeyEncryptionFrame();
sharing::nearby::Frame frame; ExpectPairedKeyResultFrame();
frame.ParseFromArray(data.data(), data.size()); ExpectConnectionResponseFrame(
sharing::nearby::ConnectionResponseFrame::REJECT);
EXPECT_TRUE(frame.has_v1());
EXPECT_TRUE(frame.v1().has_connection_response()); // TODO(himanshujaju) - Extract out to a common constant b/w impl and test.
EXPECT_EQ(sharing::nearby::ConnectionResponseFrame::REJECT, task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(2));
frame.v1().connection_response().status()); EXPECT_TRUE(connection_.IsClosed());
// To avoid UAF in OnIncomingTransferUpdate().
service_->UnregisterReceiveSurface(&callback);
}
TEST_F(NearbySharingServiceImplTest,
IncomingConnection_KeyVerificationRunnerStatusUnable) {
fake_nearby_connections_manager_->SetRawAuthenticationToken(kEndpointId,
kToken);
SetUpAdvertisementDecoder(kValidV1EndpointInfo,
/*return_empty_advertisement=*/false);
SetUpIntroductionFrameDecoder(/*return_empty_introduction_frame=*/false);
ui::ScopedSetIdleState unlocked(ui::IDLE_STATE_IDLE);
SetConnectionType(net::NetworkChangeNotifier::CONNECTION_WIFI);
NiceMock<MockTransferUpdateCallback> callback;
base::RunLoop run_loop;
EXPECT_CALL(callback, OnTransferUpdate(testing::_, testing::_))
.WillOnce(testing::Invoke([&run_loop](const ShareTarget& share_target,
TransferMetadata metadata) {
EXPECT_TRUE(share_target.is_incoming);
EXPECT_TRUE(share_target.is_known);
EXPECT_TRUE(share_target.has_attachments());
EXPECT_EQ(3u, share_target.text_attachments.size());
EXPECT_EQ(0u, share_target.file_attachments.size());
EXPECT_EQ(kDeviceName, share_target.device_name);
EXPECT_EQ(GURL(kTestMetadataIconUrl), share_target.image_url);
EXPECT_EQ(nearby_share::mojom::ShareTargetType::kUnknown,
share_target.type);
EXPECT_TRUE(share_target.device_id);
EXPECT_NE(kEndpointId, share_target.device_id);
EXPECT_EQ(kTestMetadataFullName, share_target.full_name);
EXPECT_EQ(kFourDigitToken, metadata.token());
EXPECT_EQ(TransferMetadata::Status::kAwaitingLocalConfirmation,
metadata.status());
EXPECT_FALSE(metadata.is_final_status());
run_loop.Quit();
}));
SetUpKeyVerification(sharing::mojom::PairedKeyResultFrame_Status::kUnable);
SetUpForegroundReceiveSurface(callback);
service_->OnIncomingConnection(kEndpointId, kValidV1EndpointInfo,
&connection_);
ProcessLatestPublicCertificateDecryption(/*expected_num_calls=*/1,
/*success=*/true);
run_loop.Run();
EXPECT_TRUE(
fake_nearby_connections_manager_->DidUpgradeBandwidth(kEndpointId));
EXPECT_FALSE(connection_.IsClosed());
// To avoid UAF in OnIncomingTransferUpdate().
service_->UnregisterReceiveSurface(&callback);
}
TEST_F(NearbySharingServiceImplTest,
IncomingConnection_KeyVerificationRunnerStatusUnable_LowPower) {
fake_nearby_connections_manager_->SetRawAuthenticationToken(kEndpointId,
kToken);
SetUpAdvertisementDecoder(kValidV1EndpointInfo,
/*return_empty_advertisement=*/false);
SetUpIntroductionFrameDecoder(/*return_empty_introduction_frame=*/false);
ui::ScopedSetIdleState unlocked(ui::IDLE_STATE_IDLE);
SetConnectionType(net::NetworkChangeNotifier::CONNECTION_WIFI);
NiceMock<MockTransferUpdateCallback> callback;
base::RunLoop run_loop;
EXPECT_CALL(callback, OnTransferUpdate(testing::_, testing::_))
.WillOnce(testing::Invoke([&run_loop](const ShareTarget& share_target,
TransferMetadata metadata) {
EXPECT_TRUE(share_target.is_incoming);
EXPECT_TRUE(share_target.is_known);
EXPECT_TRUE(share_target.has_attachments());
EXPECT_EQ(3u, share_target.text_attachments.size());
EXPECT_EQ(0u, share_target.file_attachments.size());
EXPECT_EQ(kDeviceName, share_target.device_name);
EXPECT_EQ(GURL(kTestMetadataIconUrl), share_target.image_url);
EXPECT_EQ(nearby_share::mojom::ShareTargetType::kUnknown,
share_target.type);
EXPECT_TRUE(share_target.device_id);
EXPECT_NE(kEndpointId, share_target.device_id);
EXPECT_EQ(kTestMetadataFullName, share_target.full_name);
EXPECT_EQ(kFourDigitToken, metadata.token());
EXPECT_EQ(TransferMetadata::Status::kAwaitingLocalConfirmation,
metadata.status());
EXPECT_FALSE(metadata.is_final_status());
run_loop.Quit();
}));
SetUpKeyVerification(sharing::mojom::PairedKeyResultFrame_Status::kUnable);
NearbySharingService::StatusCodes result = service_->RegisterReceiveSurface(
&callback, NearbySharingService::ReceiveSurfaceState::kBackground);
EXPECT_EQ(result, NearbySharingService::StatusCodes::kOk);
EXPECT_TRUE(fake_nearby_connections_manager_->IsAdvertising());
service_->OnIncomingConnection(kEndpointId, kValidV1EndpointInfo,
&connection_);
ProcessLatestPublicCertificateDecryption(/*expected_num_calls=*/1,
/*success=*/true);
run_loop.Run();
EXPECT_FALSE(
fake_nearby_connections_manager_->DidUpgradeBandwidth(kEndpointId));
EXPECT_FALSE(connection_.IsClosed());
// To avoid UAF in OnIncomingTransferUpdate().
service_->UnregisterReceiveSurface(&callback);
}
TEST_F(NearbySharingServiceImplTest,
IncomingConnection_KeyVerificationRunnerStatusFail) {
fake_nearby_connections_manager_->SetRawAuthenticationToken(kEndpointId,
kToken);
SetUpAdvertisementDecoder(kValidV1EndpointInfo,
/*return_empty_advertisement=*/false);
ui::ScopedSetIdleState unlocked(ui::IDLE_STATE_IDLE);
SetConnectionType(net::NetworkChangeNotifier::CONNECTION_WIFI);
NiceMock<MockTransferUpdateCallback> callback;
SetUpKeyVerification(sharing::mojom::PairedKeyResultFrame_Status::kFail);
SetUpForegroundReceiveSurface(callback);
// Ensures that introduction is never received for failed key verification.
std::string intro = "introduction_frame";
std::vector<uint8_t> bytes(intro.begin(), intro.end());
EXPECT_CALL(mock_decoder_, DecodeFrame(testing::Eq(bytes), testing::_))
.Times(0);
connection_.AppendReadableData(bytes);
service_->OnIncomingConnection(kEndpointId, kValidV1EndpointInfo,
&connection_);
ProcessLatestPublicCertificateDecryption(/*expected_num_calls=*/1,
/*success=*/true);
EXPECT_TRUE(connection_.IsClosed());
// To avoid UAF in OnIncomingTransferUpdate().
service_->UnregisterReceiveSurface(&callback);
}
TEST_F(NearbySharingServiceImplTest,
IncomingConnection_EmptyAuthToken_KeyVerificationRunnerStatusFail) {
SetUpAdvertisementDecoder(kValidV1EndpointInfo,
/*return_empty_advertisement=*/false);
ui::ScopedSetIdleState unlocked(ui::IDLE_STATE_IDLE);
SetConnectionType(net::NetworkChangeNotifier::CONNECTION_WIFI);
NiceMock<MockTransferUpdateCallback> callback;
SetUpForegroundReceiveSurface(callback);
// Ensures that introduction is never received for empty auth token.
std::string intro = "introduction_frame";
std::vector<uint8_t> bytes(intro.begin(), intro.end());
EXPECT_CALL(mock_decoder_, DecodeFrame(testing::Eq(bytes), testing::_))
.Times(0);
connection_.AppendReadableData(bytes);
service_->OnIncomingConnection(kEndpointId, kValidV1EndpointInfo,
&connection_);
ProcessLatestPublicCertificateDecryption(/*expected_num_calls=*/1,
/*success=*/true);
EXPECT_TRUE(connection_.IsClosed());
// To avoid UAF in OnIncomingTransferUpdate(). // To avoid UAF in OnIncomingTransferUpdate().
service_->UnregisterReceiveSurface(&callback); service_->UnregisterReceiveSurface(&callback);
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "base/optional.h" #include "base/optional.h"
#include "chrome/browser/nearby_sharing/certificates/nearby_share_decrypted_public_certificate.h" #include "chrome/browser/nearby_sharing/certificates/nearby_share_decrypted_public_certificate.h"
#include "chrome/browser/nearby_sharing/incoming_frames_reader.h" #include "chrome/browser/nearby_sharing/incoming_frames_reader.h"
#include "chrome/browser/nearby_sharing/paired_key_verification_runner.h"
class NearbyConnection; class NearbyConnection;
...@@ -55,12 +56,22 @@ class ShareTargetInfo { ...@@ -55,12 +56,22 @@ class ShareTargetInfo {
frames_reader_ = std::move(frames_reader); frames_reader_ = std::move(frames_reader);
} }
PairedKeyVerificationRunner* key_verification_runner() {
return key_verification_runner_.get();
}
void set_key_verification_runner(
std::unique_ptr<PairedKeyVerificationRunner> key_verification_runner) {
key_verification_runner_ = std::move(key_verification_runner);
}
private: private:
base::Optional<std::string> endpoint_id_; base::Optional<std::string> endpoint_id_;
base::Optional<NearbyShareDecryptedPublicCertificate> certificate_; base::Optional<NearbyShareDecryptedPublicCertificate> certificate_;
NearbyConnection* connection_ = nullptr; NearbyConnection* connection_ = nullptr;
base::Optional<std::string> token_; base::Optional<std::string> token_;
std::unique_ptr<IncomingFramesReader> frames_reader_; std::unique_ptr<IncomingFramesReader> frames_reader_;
std::unique_ptr<PairedKeyVerificationRunner> key_verification_runner_;
}; };
#endif // CHROME_BROWSER_NEARBY_SHARING_SHARE_TARGET_INFO_H_ #endif // CHROME_BROWSER_NEARBY_SHARING_SHARE_TARGET_INFO_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment