// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
module ash.nearby.presence.mojom;
import "mojo/public/mojom/base/absl_status.mojom";
import "mojo/public/mojom/base/file.mojom";
// Request details to be passed to the Presence Library to inform the type of
// scan to be run.
struct ScanRequest {
string account_name;
array<IdentityType> identity_types;
array<PresenceScanFilter> scan_filters;
};
// Presence Identity Types used for scanning, values come from
// //third_party/nearby/src/internal/proto/credential.proto
enum IdentityType {
kIdentityTypeUnspecified = 0,
kIdentityTypePrivateGroup = 1,
kIdentityTypeContactsGroup = 2,
kIdentityTypePublic = 3,
};
// Private Credential encryption key descriptor, representing PrivateKey from
// //third_party/nearby/src/internal/proto/local_credential.proto.
struct PrivateKey {
string certificate_alias;
array<uint8> key;
};
// Presence filter used in the ScanRequest to specify the types of devices of
// interest.
struct PresenceScanFilter {
PresenceDeviceType device_type;
};
// Possible Presence Scan device types. These are defined in
// //third_party/src/nearby/internal/proto/metadata.proto and should be kept
// consistent with the types defined in `DeviceType`.
enum PresenceDeviceType {
// The type of the device found during the scan is unknown.
kUnknown = 0,
kPhone = 1,
kTablet = 2,
kDisplay = 3,
kLaptop = 4,
kTv = 5,
kWatch = 6,
kChromeos = 7,
kFoldable = 8,
};
// ActionTypes are defined in //third_party/nearby/src/presence/data_element.h
// and this enum should be kept consistent with the action types defined there
// and in //chromeos/ash/components/nearby/presence/nearby_presence_service.h.
enum ActionType {
kCallTransferAction = 4,
kActiveUnlockAction = 8,
kNearbyShareAction = 9,
kInstantTetheringAction = 10,
kPhoneHubAction = 11,
kPresenceManagerAction = 12,
kFinderAction = 13,
kFastPairSassAction = 14,
kTapToTransferAction = 15,
kLastAction,
};
// A mojo conversion of the PublicCredentialType which is defined in
// //third_party/nearby/src/internal/platform/implementation/credential_callbacks.h.
// This definition should be kept consistent with the afformentioned file.
enum PublicCredentialType {
kLocalPublicCredential = 1,
kRemotePublicCredential = 2,
};
// The metadata of a device. This struct should always match
// //third_party/nearby/src/internal/proto/metadata.proto.
struct Metadata {
PresenceDeviceType device_type;
string device_name;
array<uint8> bluetooth_mac_address;
// Maps to the DeviceIdentityMetaData proto message's `device_id` field.
// device_id type `bytes` and represents a 128-bit integer. Thus this byte
// (8-bits) array field should always be of length 16.
array<uint8> device_id;
};
// A mojo conversion of the CredentialType enum, which is defined in
// //third_party/nearby/src/internal/proto/credential.proto.
enum CredentialType {
kCredentialTypeUnknown = 0,
kCredentialTypeDevice = 1,
kCredentialTypeGaia = 2,
};
// The Nearby Presence library is responsible for generating and storing Shared
// Credentials for the local device and remote devices. These credentials
// are generated using information provided by ChromeOS. ChromeOS is responsible
// for:
// 1. Retrieving the local device's Shared Credentials from the Nearby
// Presence library and uploading them to the Nearby Presence server.
// 2. Downloading remote devices' Shared Credentials from the Nearby Presence
// server and and saving them to the Nearby Presence library.
// 3. Triggering (re)generation of Shared Credentials for the local device if
// device metadata changes.
// The Nearby Presence library uses the Shared Credentials for decrypting
// nearby devices' advertisements. This struct represents
// //third_party/nearby/src/internal/proto/credential.proto.
struct SharedCredential {
// 32 bytes of secure random bytes used to derive any symmetric keys needed.
array<uint8, 32> key_seed;
// The time in millis from epoch when this credential becomes effective.
int64 start_time_millis;
// The time in millis from epoch when this credential expires.
int64 end_time_millis;
// The encrypted Metadata in bytes. Encrypted by the v0
// metadata_encryption_key.
array<uint8> encrypted_metadata_bytes_v0;
// The tag for verifying metadata_encryption_key.
array<uint8> metadata_encryption_key_tag_v0;
// The public key is used to create a secure connection with the device.
array<uint8> connection_signature_verification_key;
// The public key is used to verify Advertisement Signature in BT5.0 (v1)
// specs.
array<uint8> advertisement_signature_verification_key;
// The trust type assigned to the credential. The credential is only
// accessible to contacts assigned with the same token. This field is only
// visible to the generating device and the server for distribution/provision
// purposes. Tokens are abstracted (with unnecessary details being removed)
// when returned to downloading devices.
IdentityType identity_type;
// The version number of this SharedCredential, matches the corresponding
// protocol version.
array<uint8> version;
// The type assigned to the credential. The CredentialType is used to
// determine whether a device identity credential or account based identity
// credential is used for decryption.
CredentialType credential_type;
// The encrypted Metadata in bytes. Encrypted by the v1.
// metadata_encryption_key.
array<uint8> encrypted_metadata_bytes_v1;
// The HMAC of the plaintext identity token included (in encrypted form) in an
// unsigned, short salt, V1 advertisement.
array<uint8> identity_token_short_salt_adv_hmac_key_v1;
// The randomly generated positive unique id of the shared credential.
int64 id;
// The Device User Session ID number related to the uploader of this shared
// credential. Debug purpose only.
string dusi;
// Signature algorithm version. Used to determine which algorithm to use to
// verify incoming signatures.
string signature_version;
// The HMAC of the plaintext identity token included (in encrypted form) in an
// unsigned, extended salt, V1 advertisement.
array<uint8> identity_token_extended_salt_adv_hmac_key_v1;
// The HMAC of the plaintext identity token included (in encrypted form) in a
// signed V1 advertisement.
array<uint8> identity_token_signed_adv_hmac_key_v1;
};
// Presence Device information to specify the device information when a device
// is found/lost/changed during a scan. This loosely represents
// //third_party/nearby/src/presence/presence_device.h.
struct PresenceDevice {
string endpoint_id;
array<ActionType> actions;
string? stable_device_id;
Metadata metadata;
SharedCredential? decrypt_shared_credential;
};
// Local Credentials are stored on device, and are used to encrypt and salt
// Nearby Presence advertisements. This struct represents
// //third_party/nearby/src/internal/proto/local_credential.proto.
struct LocalCredential {
// The unique id of (and hashed based on) a pair of Secret Key and
// X509Certificate's public key.
array<uint8> secret_id;
// Bytes representation of an AES Key owned by local device, to encrypt
// local device metadata.
array<uint8> key_seed;
// The time in millis from epoch when this credential becomes effective.
int64 start_time_millis;
// The time in millis from epoch when this credential expires.
int64 end_time_millis;
// The 14 bytes aes key to encrypt metadata in SharedCredential.
array<uint8> metadata_encryption_key_v0;
// Used for signing advertisement.
PrivateKey advertisement_signing_key;
// Used for connection authentication.
PrivateKey connection_signing_key;
// The trust type assigned to the credential.
IdentityType identity_type;
// The set of 2-byte salts already used to encrypt the metadata key.
map<uint32, bool> consumed_salts;
// 16 bytes of crypto-grade random data that the credential's identity
// provider can use to encrypt metadata in a DiscoveryCredential
// (SharedCredential).
array<uint8> identity_token_v1;
// The positive unique ID of (and hashed based on) a pair of Secret Key and
// X509Certificate's public key.
int64 id;
// Signature algorithm version. Used to determine which algorithm to use to
// sign data.
string signature_version;
};
// Intentionally left empty. The ScanSession remote is used by the client
// application to alert when to stop a scan session. The client application
// simply releases the ScanSession pointer to notify the utility process.
interface ScanSession {};
// Interface for the Presence Library to notify the client applications of
// device updates.
interface ScanObserver {
// Method for notifying that a device was found.
OnDeviceFound(PresenceDevice device);
// Method for notifying that a previously found device has new information
// available.
OnDeviceChanged(PresenceDevice device);
// Method for notify that a previously found device has been lost.
OnDeviceLost(PresenceDevice device);
};
// Main interface to control the NearbyPresence library. Implemented in a
// sandboxed process. This interface is used by the NearbyPresenceService
// running in the browser process to discover devices.
interface NearbyPresence {
// Starts a scan for Nearby Presence devices. Multiple scans can be ongoing
// at the same time.
// scan_request - Specifics of the scan used to determine what types of
// devices are being scanned for.
// scan_observer - Pending remote for the utility process to call with
// scan results.
StartScan(ScanRequest scan_request) =>
(pending_remote<ScanSession>? scan_session,
mojo_base.mojom.AbslStatusCode status);
// Sets the scan observer for the utility process to use to pass devices
// back to the browser process.
SetScanObserver(pending_remote<ScanObserver> scan_observer);
// Updates the `metadata` used in the Nearby Presence library. The NP library
// requires `metadata` to be set on startup since the library does not persist
// the `metadata`, and requires this function call to access the `metadata`,
// from which point the library will store in memory to be used throughout
// its lifetime. Does NOT (re)generate credentials.
UpdateLocalDeviceMetadata(Metadata metadata);
// Updates the `metadata` used in the Nearby Presence library. The NP library
// requires `metadata` to be set on startup since the library does not persist
// the `metadata`, and requires this function call to access the `metadata`,
// from which point the library will store in memory to be used throughout
// its lifetime. Additionally, should be called whenever user metadata
// changes (e.g., user name change).
//
// Also (re)generates user's private and public credentials based on
// `metadata`. The generated private credentials will be saved to credentials
// storage, and the generated public credentials will be returned inside the
// callback for CrOS to upload to the web.
UpdateLocalDeviceMetadataAndGenerateCredentials(Metadata metadata)
=> (array<SharedCredential> shared_credentials,
mojo_base.mojom.AbslStatusCode status);
// Updates the remote shared credentials downloaded from the NP server stored
// in the NP library.
UpdateRemoteSharedCredentials(array<SharedCredential> shared_credentials,
string account_name)
=> (mojo_base.mojom.AbslStatusCode status);
// Retrieves the local shared credentials saved and generated by the NP
// library. Upon return, these will be uploaded to the NP server if they
// have changed.
GetLocalSharedCredentials(string account_name)
=> (array<SharedCredential> shared_credentials,
mojo_base.mojom.AbslStatusCode status);
};