// Copyright 2018 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. module chromeos.secure_channel.mojom; import "chromeos/services/device_sync/public/mojom/device_sync.mojom"; enum ConnectionAttemptFailureReason { // The local device could not authenticate with the remote device. This likely // means that one (or both) devices have not synced their keys recently. AUTHENTICATION_ERROR, // An advertisement could not be generated for this connection. This likely // means that one (or both) devices have not synced ntheir BeaconSeeds // recently. COULD_NOT_GENERATE_ADVERTISEMENT, // GATT connections were attempted, but they failed. This could be caused by // errors creating GATT connections, dropped GATT connections, or an issue // relating to GATT services being unavailable. GATT_CONNECTION_ERROR, // The provided local device does not have a public key set. LOCAL_DEVICE_INVALID_PUBLIC_KEY, // The provided local device does not have a persistent symmetric key set. LOCAL_DEVICE_INVALID_PSK, // The provided remote device does not have a public key set. REMOTE_DEVICE_INVALID_PUBLIC_KEY, // The provided remote device does not have a persistent symmetric key set. REMOTE_DEVICE_INVALID_PSK, // Timeouts occurred trying to contact the remote device. TIMEOUT_FINDING_DEVICE }; enum ConnectionCreationDetail { REMOTE_DEVICE_USED_BACKGROUND_BLE_ADVERTISING, REMOTE_DEVICE_USED_FOREGROUND_BLE_ADVERTISING }; // Determines the order in which connections are attempted when system resources // must be shared. For example, a device can only register a limited number of // BLE advertisements at a given time due to hardware constraints; in this // situation, a connection attempt with a higher priority will be allowed to // register an advertisement before an attempt with a lower priority. // // For connection mediums which do not require use of limited system resources, // ConnectionPriority is ignored. enum ConnectionPriority { // Should be used for connection attempts which do not have latency // requirements (e.g., background scans for nearby devices). LOW, // Should be used when the connection attempt should complete in a reasonable // amount of time but is not urgent (e.g., heartbeat/keep-alive messages). MEDIUM, // Should be used when the user is directly waiting on the result of the // connection (e.g., the user clicks a button and sees a spinner in the UI // until the connection succeeds). HIGH }; struct BluetoothConnectionMetadata { // RSSI at the exact time that this metadata was requested. Note that RSSI // may change drastically in a short period; this is only a snapshot. int32 current_rssi; }; struct ConnectionMetadata { // Details which describe how the connection was created. If no // ConnectionCreationDetails apply to this connection, the array is empty. array creation_details; // Only available for connections over Bluetooth. BluetoothConnectionMetadata? bluetooth_connection_metadata; // The responder auth message returned by the other device during the // cryptographic handshake that established the channel. These are serialized // bytes of a proto which contains an encrypted message, returned by the // remote device in the last step of a 3-step cryptographic handshake. These // bytes were publicly visible over BLE when the connection with the remote // device was being established. It is used by some clients for further // cryptographic communication. // Defined by //components/cryptauth/proto/securemessage.proto. string channel_binding_data; }; interface Channel { // If the connection is dropped (e.g., by the remote device or due to // connection instability), this reason is supplied to the // connection_error_with_reason_handler. const int32 kConnectionDroppedReason = 1; // Sends an encrypted message over the connection. The message is sent // along with metadata indicating the feature used to create this // connection. The callback is invoked when the message has been sent // successfully. If the message fails to be sent, the entire Channel is // disconnected with reason |kConnectionDroppedReason|, and the SendMessage() // callback is never invoked. SendMessage(string message) => (); GetConnectionMetadata() => (ConnectionMetadata metadata); }; interface MessageReceiver { // Invoked when a message is received over the connection. Only messages // corresponding to the feature used when creating the connection are // passed to this callback. OnMessageReceived(string message); }; // Delegate interface used to handle connection attempt successes/failures. Note // that this interface is intended to be implemented by clients of the // DeviceSync service. interface ConnectionDelegate { // Invoked when a connection attempt failed (i.e., the failure occurred before // a connection could be established). OnConnectionAttemptFailure(ConnectionAttemptFailureReason reason); // Invoked when a connection is established. The channel is authenticated // with account credentials, and all messages sent over the channel are // encrypted. Client should set a connection_error_with_reason_handler on // |channel| to be notified when it has been invalidated due to a dropped // connection. Note that clients are expected to hold the reference to // |channel| until they are done using the connection. OnConnection(Channel channel, MessageReceiver& message_receiver); }; // Brokers connections between the current Chromebook and remote devices, // allowing the sending/receiving of messages. All channels created via this API // are authenticated and all messages sent are encrypted via account-specific // keys. // // If multiple connections are requested to the same device, this service // creates only one connection and shares it among all clients; likewise, if // multiple clients are sharing a single connection and one client drops its // reference to the connection, the connection will stay active until each // client has invalidated its reference to the channel. // // All connections require metadata about the local device (i.e., the device on // which this code is running) in order to perform a cryptographic handshake // which ensures that both devices are owned by the same underlying account. // Note that each logged-in user on Chrome OS has its own set of keys; thus, the // provided local device is not the same each time the call is made. For // instance, at the sign-in (i.e., account-choosing) screen, EasyUnlock tries to // establish connections to phones belonging to each account on the device, so // each of these connection attempts uses a different local device. // // Note: Each API function results in either one connection (success case) // or zero connections (failure case). Clients wishing to initiate another // connection after the first one has completed should invoke the API again. interface SecureChannel { // Starts listening for an incoming connection attempt from |device|. // This function listens indefinitely until a connection is formed, at // which time |delegate|'s OnConnection() is invoked. |delegate|'s // OnConnectionFailure() is only invoked if the connection could not be // attempted at all (e.g., if |device| did not contain valid metadata). To // cancel a connection attempt (i.e., to stop listening for incoming // connections), disconnect |delegate|. ListenForConnectionFromDevice( chromeos.device_sync.mojom.RemoteDevice device_to_connect, chromeos.device_sync.mojom.RemoteDevice local_device, string feature, ConnectionPriority connection_priority, ConnectionDelegate delegate); // Initiates a connection to |device|, which is presumed to be listening // for incoming connections. This function attempts to create a connection // until it has succeeded or until it has failed several attempts. // |delegate|'s OnConnection() is called in the success case, and // OnConnectionFailure() is called if a connection could not be attempted or // if a connection was attempted and failed several retry attempts. To cancel // the connection attempt, disconnect |delegate|. InitiateConnectionToDevice( chromeos.device_sync.mojom.RemoteDevice device_to_connect, chromeos.device_sync.mojom.RemoteDevice local_device, string feature, ConnectionPriority connection_priority, ConnectionDelegate delegate); };