blob: 6d7344f1b251c4fc53298b64bfc77a14ba07a134 [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
library fuchsia.identity.internal;
using fuchsia.auth;
using fuchsia.identity.account;
using fuchsia.kms;
using GlobalIdHash = array<byte>:32;
using HashSalt = array<byte>:32;
/// The control channel for an AccountHandler component.
///
/// This interface is intended only for use by the AccountManager component that
/// starts instances of AccountHandler. We define which account the handler
/// should be handling one time via this channel rather than via startup flags to
/// provide additional flexibility given the range of scenarios:
/// * The account is completely new
/// * The account is being added to the current device for the first time
/// * Account information is already present on the local disk and is readable
/// * Account information is already present on the local disk but is not yet
/// readable because the disk is not yet decrypted.
///
/// A given Account Handler progresses through the following state machine:
/// ```
/// |
/// V
/// +---------------+
/// +--------------| Uninitialized |
/// | +---------------+
/// | |
/// | PrepareForTransfer |
/// V |
/// +------------------+ |
/// | PendingTransfer | |
/// +------------------+ |
/// | |
/// | PerformTransfer | CreateAccount/
/// V | LoadAccount
/// +------------------+ |
/// | Transferred | |
/// +------------------+ |
/// | |
/// | FinalizeTransfer |
/// | V
/// | +---------------+
/// +------------->| Initialized |
/// +---------------+
/// |
/// | Terminate
/// V
/// +---------------+
/// | Finished |
/// +---------------+
/// ```
///
/// * `Uninitialized` - the handler has just been instantiated and contains no
/// account information.
/// * `PendingTranfer` - the handler is awaiting an account transfer. It has
/// created a public key pair that will be associated with the account on this
/// device, but contains no other account information.
/// * `Transferred` - the handler has received transferred account information
/// and is holding it in memory. In this state, the account transfer is not
/// yet known to be valid, and is pending further validation from account
/// manager. The account is not available for use, and regardless of the
/// intended lifetime of the account on this device, the account is not
/// saved to disk.
/// * `Initialized` - the handler has loaded account information and is ready
/// to serve requests for the `Account` interface. If the account is
/// persistent on this device, then it is saved to disk.
/// * `Finished` - the handler is in the process of shutting down and will soon
/// terminate.
[Discoverable]
protocol AccountHandlerControl {
/// Creates a completely new Fuchsia account.
///
/// `context` An `AccountHandlerContext` that can supply account and
/// authentication services and contextual state.
/// `id` The new account's local identifier.
///
/// Fails with FAILED_PRECONDITION if the AccountHandler is not in the `Uninitialized`
/// state.
CreateAccount(
AccountHandlerContext context,
fuchsia.identity.account.LocalAccountId id)
-> () error fuchsia.identity.account.Error;
/// Loads information about a Fuchsia account that was previously provisioned
/// on the current device.
///
/// `context` An `AccountHandlerContext` that can supply account and
/// authentication services and contextual state.
/// `id` The account's local identifier.
///
/// Fails with FAILED_PRECONDITION if the AccountHandler is not in the `Uninitialized`
/// state.
LoadAccount(
AccountHandlerContext context,
fuchsia.identity.account.LocalAccountId id)
-> () error fuchsia.identity.account.Error;
/// Prepares the AccountHandler to receive an account from another device through
/// direct transfer. This moves the AccountHandler from the `Uninitialized`
/// state to the `PendingTransfer` state.
///
/// `PrepareForAccountTransfer` should be used in conjunction with
/// `PerformAccountTransfer`, `FinalizeAccountTransfer`, and
/// `EncryptAccountData` to provision an existing account on another device
/// (source) to this device (target).
///
/// The expected sequence of calls to setup an AccountHandler with a transferred
/// account is as follows:
/// 1. `PrepareForAccountTransfer` is called on the target device.
/// 2. The public key for the target device is retrieved using `GetPublicKey`
/// and handed to the source device.
/// 3. Account data is encrypted on the source device using the public key
/// with `EncryptAccountData`.
/// 4. The encrypted account data is passed in to AccountHandler on the target
/// device with `PerformAccountTransfer`.
/// 5. After any validation, the transfer is finalized on the target device
/// with a call to `FinalizeAccountTransfer`.
///
/// Fails with FAILED_PRECONDITION if the AccountHandler is not in the `Uninitialized`
/// state.
PrepareForAccountTransfer() -> () error fuchsia.identity.account.Error;
// TODO(satsukiu): investigate using VMOs or pagination over Overnet for
// when account size exceeds what FIDL can handle.
/// Loads the encrypted account into memory, but does not make it available
/// for use yet. The account data passed in is expected to be serialized as
/// an `AccountTransferContainer` and encrypted using the public key
/// retrieved from `GetPublicKey`. This format of account data is provided
/// by `EncryptAccountData` on the source device.
///
/// Moves the AccountHandler from the `PendingTransfer` state to the
/// `Transferred` state.
///
/// `encrypted_account_data` Account data retrieved on the source device
/// using `EncryptAccountData`.
///
/// Fails with FAILED_PRECONDITION if the AccountHandler is not in the
/// `PendingTransfer` state.
PerformAccountTransfer(EncryptedAccountData encrypted_account_data)
-> () error fuchsia.identity.account.Error;
/// Completes the account transfer started through
/// `PrepareForAccountTransfer` and `PerformAccountTransfer`. This saves
/// the account to disk if the account is persistent and makes it available
/// for use.
///
/// Moves the AccountHandler from the `Transferred` state to the
/// `Initialized` state.
///
/// Fails with FAILED_PRECONDITION if the AccountHandler is not in the `Transferred`
/// state.
FinalizeAccountTransfer() -> () error fuchsia.identity.account.Error;
// TODO(fxr/37227) - update encrypt/decrypt APIs to handle data given by KMS.
/// Serializes and encrypts the account contained in the AccountHandler for
/// transfer. The account will be serialized as `AccountData` and
/// encrypted using `target_public_key`. The resulting
/// `EncryptedAccountData` should be passed to AccountHandler on the target
/// device using `PerformAccountTransfer`.
///
/// `target_public_key` The public key used to encrypt the account data.
///
/// Returns: `encrypted_account_data` Bytes containing the encrypted account
///
/// Fails with FAILED_PRECONDITION if the AccountHandler is not in the `Initialized`
/// state.
EncryptAccountData(fuchsia.kms.PublicKey target_public_key)
-> (EncryptedAccountData encrypted_account_data) error fuchsia.identity.account.Error;
/// Deletes all persistent information about the Fuchsia account handled by
/// this handler, including all credentials and global identifiers.
/// Credential revocation is attempted before deletion. After a
/// successful call to RemoveAccount, all other open interfaces for this
/// account handler will be closed and any subsequent calls on the current
/// interface will fail.
///
/// `force` If true, continues removing the account even if revocation of
/// credentials fails. If false, any revocation failure will result
/// in an error and the account will remain. In this case, a subset
/// of the credentials may have been deleted.
RemoveAccount(bool force) -> () error fuchsia.identity.account.Error;
// TODO(jsankey): Add methods to cover adding an existing account and
// handling an account where the disk is not yet decrypted.
/// Connects an interface to read properties of and perform operations on
/// the account handled by this handler. The AccountHandler must be in the
/// `Initialized` state.
///
/// `context_provider` An `AuthenticationContextProvider` capable of
/// supplying UI contexts used for interactive
/// authentication on this account
/// `account` The server end of an `Account` channel
///
/// Fails with FAILED_PRECONDITION if the AccountHandler is not in the `Initialized`
/// state.
GetAccount(
fuchsia.auth.AuthenticationContextProvider auth_context_provider,
request<fuchsia.identity.account.Account> account)
-> () error fuchsia.identity.account.Error;
/// Retrieves the public key associated with this account on this device.
/// The public key is exposed so that the target AccountHandler's key can
/// be distributed to the source AccountHandler during an account transfer.
/// This allows the source AccountHandler to encrypt account data such that
/// only the target AccountHandler can decrypt the data.
///
/// Returns: `public_key` Public key in an asymmetric key pair associated
/// with this account on this device.
///
/// Fails with FAILED_PRECONDITION is the AccountHandler is not in one of
/// `PendingTransfer`, `Transferred`, or `Initialized` states.
GetPublicKey() -> (fuchsia.kms.PublicKey public_key) error fuchsia.identity.account.Error;
/// Generates a hash of the global account ID using the provided salt.
/// Returning a hash of the global ID lets the account system determine
/// whether two locally provisioned accounts represent the same account
/// without storing every account's global ID. A salt is added so that
/// accounts cannot be easily correlated across devices.
///
/// The AccountHandler must be in either the `Transferred` or `Initialized`
/// states.
///
/// `salt` Bytes used as a salt while hashing global ID.
///
/// Returns: `id_hash` A hash of the global ID of the contained account
///
/// Fails with FAILED_PRECONDITION if the AccountHandler is not in one of
/// `Transferred` or `Initialized` states.
GetGlobalIdHash(HashSalt salt) -> (GlobalIdHash id_hash) error fuchsia.identity.account.Error;
/// Signals that the AccountHandler should tear itself down. After the
/// receiver responds by closing its handle, the caller may terminate the
/// component if it hasn't already exited.
Terminate();
};
/// An interface that supplies the account and authentication services that
/// an AccountHandler needs to perform its role in the system.
///
/// In the v2 Component architecture this service will be supplied into the
/// namespace of AccountHandler by the component that launches it (i.e. the
/// AccountManager). Until then an AccountHandlerContext is supplied explicitly
/// in the initialization calls on the AccountHandlerControl interface.
protocol AccountHandlerContext {
/// Connects an interface to a particular AuthProvider, launching it if
/// necessary.
///
/// `auth_provider_type` An OAuth identity provider matching a configuration
/// set in an AuthProviderConfig.auth_provider_type
/// `auth_provider` The server end of an `AuthProvider` channel
GetAuthProvider(string auth_provider_type,
request<fuchsia.auth.AuthProvider> auth_provider)
-> () error fuchsia.identity.account.Error;
};
/// Contents of an account, used for serialization during account transfer.
table AccountData {
/// A globally unique identifier for the account.
1: fuchsia.identity.account.GlobalAccountId global_id;
};
/// Encrypted form of AccountData.
using EncryptedAccountData = bytes:16000;