From 5f616fa5928381cc94d80d34ad7c46451a1138f2 Mon Sep 17 00:00:00 2001 From: Juliet Levesque Date: Tue, 27 Feb 2024 11:04:29 -0800 Subject: [PATCH] [Nearby Presence] Pass remote device and EndpointManager throughout connection flow In order to construct the `ConnectionsAuthenticationTransport` and authentication the connection with the `DeviceProvider`, the remote NearbyDevice and EndpointManager used in RequestConnectionV3() must be passed through the encryption protocol as parameters. This CL accomplishes this; it passes the remote NearbyDevice and EndpointManager through a successful encryption flow by introducting new functions to support this V3 protocol. They will be used in a follow up CL to authenticate the connection. See go/cros-nearby-presence-np-nc-authentication for details. PiperOrigin-RevId: 610810602 --- .../implementation/base_pcp_handler.cc | 112 ++++++++++++++++-- connections/implementation/base_pcp_handler.h | 15 +++ presence/presence_device_provider.cc | 5 +- 3 files changed, 122 insertions(+), 10 deletions(-) diff --git a/connections/implementation/base_pcp_handler.cc b/connections/implementation/base_pcp_handler.cc index 487b87a4..883b94ed 100644 --- a/connections/implementation/base_pcp_handler.cc +++ b/connections/implementation/base_pcp_handler.cc @@ -57,6 +57,7 @@ #include "connections/v3/listeners.h" #include "internal/flags/nearby_flags.h" #include "internal/interop/device.h" +#include "internal/interop/device_provider.h" #include "internal/platform/base64_utils.h" #include "internal/platform/bluetooth_adapter.h" #include "internal/platform/bluetooth_connection_info.h" @@ -505,11 +506,91 @@ EncryptionRunner::ResultListener BasePcpHandler::GetResultListener() { }; } +EncryptionRunner::ResultListener BasePcpHandler::GetResultListenerV3( + const NearbyDeviceProvider& device_provider, + const NearbyDevice& remote_device, + const EndpointChannel& endpoint_channel) { + return { + .on_success_cb = + [this, &device_provider, &remote_device, &endpoint_channel]( + const std::string& endpoint_id, + std::unique_ptr ukey2, + const std::string& auth_token, const ByteArray& raw_auth_token) { + RunOnPcpHandlerThread( + "encryption-success", + [this, &device_provider, &remote_device, &endpoint_channel, + raw_ukey2 = ukey2.release(), auth_token, + raw_auth_token]() RUN_ON_PCP_HANDLER_THREAD() mutable { + OnEncryptionSuccessRunnableV3( + remote_device, std::unique_ptr(raw_ukey2), + auth_token, raw_auth_token, endpoint_channel, + device_provider); + }); + }, + .on_failure_cb = + [this](const std::string& endpoint_id, EndpointChannel* channel) { + RunOnPcpHandlerThread( + "encryption-failure", + [this, endpoint_id, channel]() RUN_ON_PCP_HANDLER_THREAD() { + NEARBY_LOGS(ERROR) + << "Encryption failed for endpoint_id=" << endpoint_id + << " on medium=" + << location::nearby::proto::connections::Medium_Name( + channel->GetMedium()); + OnEncryptionFailureRunnable(endpoint_id, channel); + }); + }, + }; +} + +void BasePcpHandler::OnEncryptionSuccessRunnableV3( + const NearbyDevice& remote_device, std::unique_ptr ukey2, + std::string_view auth_token, const ByteArray& raw_auth_token, + const EndpointChannel& endpoint_channel, + const NearbyDeviceProvider& device_provider) { + // Quick fail if we've been removed from pending connections while we were + // busy running UKEY2. + // TODO(b/316421187): Add test coverage + auto it = pending_connections_.find(remote_device.GetEndpointId()); + if (it == pending_connections_.end()) { + NEARBY_LOGS(ERROR) + << __func__ + << ": Connection not found on UKEY negotination complete; endpoint_id=" + << remote_device.GetEndpointId(); + return; + } + + BasePcpHandler::PendingConnectionInfo& connection_info = it->second; + Medium medium = connection_info.channel->GetMedium(); + + if (!ukey2) { + // Fail early, if there is no crypto context. + ProcessPreConnectionInitiationFailure( + connection_info.client, medium, remote_device.GetEndpointId(), + connection_info.channel.get(), connection_info.is_incoming, + connection_info.start_time, {Status::kEndpointIoError}, + connection_info.result.lock().get()); + return; + } + + // TODO(b/282027237) Construct the `ConnectionsAuthenticationTransport` with + // |endpoint_channel|, and trigger authentication via + // |device_provider|. Set the returned result on the future in + // |connection_info|. + + RegisterDeviceAfterEncryptionSuccess( + /*endpoint_id=*/remote_device.GetEndpointId(), + /*ukey2=*/std::move(ukey2), /*auth_token=*/auth_token, + /*raw_auth_token=*/raw_auth_token, + /*connection_info=*/connection_info); +} + void BasePcpHandler::OnEncryptionSuccessRunnable( const std::string& endpoint_id, std::unique_ptr ukey2, const std::string& auth_token, const ByteArray& raw_auth_token) { // Quick fail if we've been removed from pending connections while we were // busy running UKEY2. + // TODO(b/316421187): Add test coverage auto it = pending_connections_.find(endpoint_id); if (it == pending_connections_.end()) { NEARBY_LOGS(INFO) @@ -531,6 +612,17 @@ void BasePcpHandler::OnEncryptionSuccessRunnable( return; } + RegisterDeviceAfterEncryptionSuccess( + /*endpoint_id=*/endpoint_id, + /*ukey2=*/std::move(ukey2), /*auth_token=*/auth_token, + /*raw_auth_token=*/raw_auth_token, + /*connection_info=*/connection_info); +} + +void BasePcpHandler::RegisterDeviceAfterEncryptionSuccess( + std::string_view endpoint_id, std::unique_ptr ukey2, + std::string_view auth_token, const ByteArray& raw_auth_token, + BasePcpHandler::PendingConnectionInfo& connection_info) { connection_info.SetCryptoContext(std::move(ukey2)); connection_info.connection_token = GetHashedConnectionToken(raw_auth_token); NEARBY_LOGS(INFO) @@ -546,12 +638,13 @@ void BasePcpHandler::OnEncryptionSuccessRunnable( // Now we register our endpoint so that we can listen for both sides to // accept. - LogConnectionAttemptSuccess(endpoint_id, connection_info); + // TODO(b/282027237): Populate authentication status. + LogConnectionAttemptSuccess(std::string(endpoint_id), connection_info); endpoint_manager_->RegisterEndpoint( - connection_info.client, endpoint_id, + connection_info.client, std::string(endpoint_id), { .remote_endpoint_info = connection_info.remote_endpoint_info, - .authentication_token = auth_token, + .authentication_token = std::string(auth_token), .raw_authentication_token = raw_auth_token, .is_incoming_connection = connection_info.is_incoming, }, @@ -883,15 +976,18 @@ Status BasePcpHandler::RequestConnectionV3( NEARBY_LOGS(INFO) << "Initiating secure connection: endpoint_id=" << endpoint_id; - // Next, we'll set up encryption. When it's done, our future will return - // and RequestConnection() will finish. - encryption_runner_.StartClient(client, endpoint_id, endpoint_channel, - GetResultListener()); + // Next, we'll set up encryption and authenticate the remote device. + // When it's done, our future will return and RequestConnectionV3() + // will finish. + encryption_runner_.StartClient( + client, endpoint_id, endpoint_channel, + GetResultListenerV3(*(client->GetLocalDeviceProvider()), + remote_device, *endpoint_channel)); }); NEARBY_LOGS(INFO) << "Waiting for connection to complete: endpoint_id=" << endpoint_id; auto status = - WaitForResult(absl::StrCat("RequestConnection(", endpoint_id, ")"), + WaitForResult(absl::StrCat("RequestConnectionV3(", endpoint_id, ")"), client->GetClientId(), result.get()); NEARBY_LOGS(INFO) << "Wait is complete: endpoint_id=" << endpoint_id << "; status=" << status.value; diff --git a/connections/implementation/base_pcp_handler.h b/connections/implementation/base_pcp_handler.h index b2f69ec2..8d5b19e8 100644 --- a/connections/implementation/base_pcp_handler.h +++ b/connections/implementation/base_pcp_handler.h @@ -469,13 +469,28 @@ class BasePcpHandler : public PcpHandler, EndpointChannel* channel); EncryptionRunner::ResultListener GetResultListener(); + EncryptionRunner::ResultListener GetResultListenerV3( + const NearbyDeviceProvider& device_provider, + const NearbyDevice& remote_device, + const EndpointChannel& endpoint_channel); void OnEncryptionSuccessRunnable( const std::string& endpoint_id, std::unique_ptr ukey2, const std::string& auth_token, const ByteArray& raw_auth_token); + void OnEncryptionSuccessRunnableV3( + const NearbyDevice& remote_device, + std::unique_ptr<::securegcm::UKey2Handshake> ukey2, + std::string_view auth_token, const ByteArray& raw_auth_token, + const EndpointChannel& endpoint_channel, + const NearbyDeviceProvider& device_provider); void OnEncryptionFailureRunnable(const std::string& endpoint_id, EndpointChannel* endpoint_channel); + void RegisterDeviceAfterEncryptionSuccess( + std::string_view endpoint_id, + std::unique_ptr<::securegcm::UKey2Handshake> ukey2, + std::string_view auth_token, const ByteArray& raw_auth_token, + BasePcpHandler::PendingConnectionInfo& connection_info); static Exception WriteConnectionRequestFrame( NearbyDevice::Type device_type, absl::string_view device_proto_bytes, diff --git a/presence/presence_device_provider.cc b/presence/presence_device_provider.cc index 2ed5cbd8..497fb541 100644 --- a/presence/presence_device_provider.cc +++ b/presence/presence_device_provider.cc @@ -17,10 +17,9 @@ #include #include #include - -#include "absl/types/variant.h" #include "absl/strings/string_view.h" #include "absl/time/time.h" +#include "absl/types/variant.h" #include "internal/interop/authentication_status.h" #include "internal/interop/authentication_transport.h" #include "internal/interop/device.h" @@ -51,6 +50,8 @@ std::string AuthenticationErrorToString(AuthenticationStatus status) { case AuthenticationStatus::kFailure: return "AuthenticationStatus::kFailure"; } + NEARBY_LOGS(ERROR) << "Unexpected value for AuthenticationStatus: " + << static_cast(status); return "AuthenticationStatus::kUnknown"; }