// 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;
alias GlobalIdHash = array<byte>:HASH_SIZE;
alias 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(fxbug.dev/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.
alias EncryptedAccountData = bytes:16000;
