// 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.identity.authentication;
using fuchsia.identity.external;
using fuchsia.kms;

const uint32 HASH_SIZE = 32;
const uint32 HASH_SALT_SIZE = 32;
using GlobalIdHash = array<byte>:HASH_SIZE;
using HashSalt = array<byte>:HASH_SALT_SIZE;

/// 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   |                    | Preload
///                 V                      |                    V
///       +------------------+             |           +------------------+
///       | PendingTransfer  |             |           |      Locked      |
///       +------------------+             |           +------------------+
///                 |                      |                    ^
///                 | PerformTransfer      |                    |
///                 V                      |                    |
///       +------------------+             |                    | LockAccount /
///       |   Transferred    |             | CreateAccount      | UnlockAccount
///       +------------------+             |                    |
///                 |                      |                    |
///                 | 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.
/// * `Locked` - the handler has loaded pre-authentication data, which lets it
/// unlock the account subsequently.
/// * `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.
// TODO(42836): Supply UI for system authentication.
[Discoverable]
protocol AccountHandlerControl {
    /// Creates a completely new Fuchsia account, optionally protecting the
    /// account with a single enrollment of an authentication mechanism.
    ///
    /// `auth_mechanism_id` An `AuthMechanismId` for a storage
    ///                     unlock-capable authentication mechanism. If
    ///                     provided, a single enrollment of that
    ///                     mechanism will be created for storage
    ///                     unlock.
    ///
    /// Fails with FAILED_PRECONDITION if the AccountHandler is not in the `Uninitialized`
    /// state.
    CreateAccount(
        fuchsia.identity.account.AuthMechanismId? auth_mechanism_id)
        -> () error fuchsia.identity.account.Error;

    /// Loads pre-auth data, which allows the account to be unlocked later.
    ///
    /// This moves the AccountHandler from the `Uninitialized` state to the `Locked` state.
    ///
    /// Fails with FAILED_PRECONDITION if the AccountHandler is not in the `Uninitialized`
    /// state.
    Preload() -> () error fuchsia.identity.account.Error;

    /// Reach the `Initialized` state, attempting authentication and unlocking the account where
    /// necessary.
    ///
    /// Fails with
    /// - FAILED_PRECONDITION if the AccountHandler is not in the `Locked` or `Initialized` state.
    /// - FAILED_AUTH_ATTEMPT if the authentication attempt failed.
    UnlockAccount()
        -> () error fuchsia.identity.account.Error;

    /// Reach the `Locked` state, closing any open `Account` and `Persona` channels for the account.
    ///
    /// Fails with FAILED_PRECONDITION if the AccountHandler is not in the `Initialized` or
    /// `Locked` state.
    LockAccount() -> () 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.
///
/// This service is supplied into the namespace of AccountHandler by the
/// component that launches it (i.e. the AccountManager).
[Discoverable]
protocol AccountHandlerContext {
    /// Connects to the `Oauth` implementation for a particular service provider,
    /// launching it if necessary.
    ///
    /// `auth_provider_type` An OAuth identity provider matching a configuration
    ///                      set in an AuthProviderConfig.auth_provider_type
    /// `oauth` The server end of an `Oauth` channel
    GetOauth(string auth_provider_type,
             request<fuchsia.identity.external.Oauth> oauth)
        -> () error fuchsia.identity.account.Error;

    /// Connects to the `OpenIdConnect` implementation for a particular service
    /// provider, launching it if necessary.
    ///
    /// `auth_provider_type` An OpenID Connect identity provider matching a
    ///                      configuration set in an
    ///                      AuthProviderConfig.auth_provider_type
    /// `open_id_connect` The server end of an `OpenIDConnect` channel
    GetOpenIdConnect(string auth_provider_type,
                     request<fuchsia.identity.external.OpenIdConnect> open_id_connect)
        -> () error fuchsia.identity.account.Error;

    /// Connects to the `OauthOpenIdConnect` implementation for a particular
    /// service provider, launching it if necessary.
    ///
    /// `auth_provider_type` An OpenID Connect identity provider matching a
    ///                      configuration set in an
    ///                      AuthProviderConfig.auth_provider_type
    /// `oauth_open_id_connect` The server end of an `OauthOpenIDConnect` channel
    GetOauthOpenIdConnect(string auth_provider_type,
                          request<fuchsia.identity.external.OauthOpenIdConnect> 
                          oauth_open_id_connect)
        -> () error fuchsia.identity.account.Error;

    /// Connects to a `StorageUnlockMechanism` implementation identified by its
    /// auth mechanism ID, launching the associated Authenticator if necessary.
    ///
    /// `auth_mechanism_id` An identifier matching an authentication mechanism
    ///                     configured by the account system.
    /// `storage_unlock_mechanism` The server end of an `StorageUnlockMechanism` channel
    GetStorageUnlockAuthMechanism(
        fuchsia.identity.account.AuthMechanismId auth_mechanism_id,
        request<fuchsia.identity.authentication.StorageUnlockMechanism> storage_unlock_mechanism)
        -> () 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;
