// Copyright 2019 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.

/// Defines protocols to manage and access key material that is consistent
/// across all devices provisioned with a particular identity.
///
/// Acheiving consistency implies synchonization between devices and this
/// synchronization is not instantaneous. For some implementations
/// synchronization may take many minutes, or even longer when devices are
/// offline. The library provides information about the progress of the
/// sychronization.
library fuchsia.identity.keys;

alias KeyId = uint32;

/// The maximum length of a `KeySingleton` or `KeySet` name, in bytes.
const uint32 MAX_NAME_LEN = 128;
/// The maximum length of metadata in a `KeySingleton` or `KeySet`, in bytes.
const uint32 MAX_METADATA_LEN = 128;
/// The maximum length of an unstructured random `Key`, in bytes.
const uint32 MAX_KEY_LEN = 64;

/// The maximum number of `Key` objects in a `KeySet`.
const uint32 MAX_KEYSET_SIZE = 64;
/// Two times the maximum number of `Key` objects in a `KeySet`.
const uint32 TWICE_MAX_KEYSET_SIZE = 128;

/// Specifies the reason that a `fuchsia.identity.keys` method failed.
enum Error {
    /// Some other problem occurred that cannot be classified using one of the
    /// more specific statuses. Retry is optional.
    UNKNOWN = 1;

    /// An internal error occurred. This usually indicates a bug within the
    /// account system itself. Retry is optional.
    INTERNAL = 2;

    /// The requested operation is not supported. This generally indicates that
    /// implementation of a new feature is not yet complete. The request should
    /// not be retried.
    UNSUPPORTED_OPERATION = 3;

    /// The request was malformed in some way, such as using an invalid key
    /// size. The request should not be retried.
    INVALID_REQUEST = 4;

    /// A local resource error occurred such as I/O, FIDL, or memory allocation
    /// failure. Retry, after a delay, is recommended.
    RESOURCE = 5;

    /// The requested key or key set is not present.  The request should not be
    /// retried.
    NOT_FOUND = 7;

    /// The request would require an illegal change to an entry that is in a
    /// frozen state.
    FROZEN = 8;
};

/// Summarizes the sychronization between the device's local state and the
/// master definition for some item (such as a `KeySingleton` or `KeySet`) in an
/// identity. Depending on the identity and implementation this "master
/// definition" might take one of many forms such as the device itself, a
/// server, a blockchain, a transparency directory, or a quorum of devices.
///
/// Synchronization follows the state machine illustrated below. Only `KeySet`
/// supports the `PENDING_FROZEN_ADDITION`, `PENDING_FREEZE`, and `FROZEN`
/// states:
/// ```
///             +------------------------+                 --\
///             |                        |                   |
///             |   +----------------+   | [commit           |
///             |   | PENDING_FROZEN |   |  success]         |
///             |   |   _ADDITION    |---|----------\        \ Present on
///             |   +----------------+   |          |        / local device
///             |     ^                  | Delete   |        |
///             |     | Freeze locally   | locally  |        |
///   Add       |     |                  |----------|--\     |
///   locally   |  +------------------+  | [commit  |  |     |
///   ----------|->| PENDING_ADDITION |  |  fail]   |  |     |
///             |  +------------------+  |          |  |     |
///             |          |             |          |  |     |
///   Add       +----------|-------------+          |  |     |
///   remotely             |                        |  |     |
///   ----------------+    | [commit success]       |  |     |
///                   |    |                        |  |     |  --\
///             +-----|----|------------+           |  |     |    |
///             |     v    v            |           |  |     |    |
///             |  +-----------------+  |           |  |     |    |
///   +----------->|     LIVE        |  |           |  |     |    |
///   |         |  +-----------------+  |           |  |     |    |
///   |         |         | ^           |           |  |     |    |
///   |         |  Freeze | | [commit   |           |  |     |    |
///   |         | locally | |  fail]    |           |  |     |    |
///   |         |         v |           | Delete    |  |     |    |
///   |         |  +-----------------+  | Remotely  |  |     |    |
///   |         |  | PENDING_FREEZE  |  |-----------|--+     |    |
///   |         |  +-----------------+  |           |  |     |    |
///   |         |          |            |           |  |     |    |
///   |         |          | [commit    |           |  |     |    |
///   |         |          |  success]  |           |  |     |    |
///   |         |          v            |           |  |     |    |
///   |         |  +-----------------+  |           |  |     |    |
///   | +--------->|    FROZEN       |<-------------/  |     |    |
///   | |       |  +-----------------+  |              |     |    |
///   | |       |    ^                  |              |     |    |
///   | |       |    | Freeze remotely  |              |     |    |
///   | |       |    |                  |              |     |    |
///   | |       +----+------------------+              |     |    |
///   | |                    |                         |     |    |
///   | | [previous state    | Delete                  |   --/    |
///   | |  == FROZEN]        | locally                 |          |
///   | |                    v            Delete       |          \ Present
///   | +----+      +------------------+  remotely     |          / in master
///   |      |      | PENDING_DELETION |---------------+          | definition
///   |      ^      +------------------+  [commit      |          |
///   |     / \              |             success]    |        --/
///   +----<   >-------------+                         V
/// [else]  \ /   [commit fail]                   +---------+
///          v                                    | INVALID |
///                                               +---------+
/// ```
enum SynchronizationState {
    /// The item is present and not frozen on the current device but has not yet
    /// been committed into the master definition. Items in this state might not
    /// reach other devices and might become invalid if committing the addition
    /// fails.
    PENDING_ADDITION = 1;

    /// The item is present and frozen on the current device but has not yet
    /// been committed into the master definition. Items in this state might not
    /// reach other devices and might become invalid if committing the addition
    /// fails. If committing the item succeeds it will enter the `FROZEN` state
    /// directly without passing through `LIVE`.
    PENDING_FROZEN_ADDITION = 2;

    /// The item is present and not frozen both on the current device and in the
    /// master definition of the identity. It should eventually be consistent
    /// across all devices with access to the identity.
    LIVE = 3;

    /// The item has been frozen on the current device but this operation has
    /// not yet been committed. Items in this state might return to the `LIVE`
    /// state if committing the freeze fails.
    PENDING_FREEZE = 4;

    /// The item is present and frozen both on the current device and in the
    /// master definition of the identity. Mutations are no longer possible
    /// but deletions are still allowed.
    FROZEN = 5;

    /// The item is present in the master definition of the identity, but has
    /// been deleted from the current device and this deletion has not yet been
    /// committed. Items in this state might return to the `LIVE` or `FROZEN`
    /// state if committing the deletion fails.
    PENDING_DELETION = 6;
};

/// `KeyManager` provides access to key material that is consistent across all
/// devices provisioned with the identity that the `KeyManager` was acquired
/// from, such as a Fuchsia Persona.
///
/// Acheiving consistency implies synchonization between devices and this
/// synchronization is not instantaneous. For some implementations
/// synchronization may take many minutes or even longer when devices are
/// offline. The `KeyManager` is able to report information about the progress
/// of this synchronization via `SynchonizationState`.
protocol KeyManager {
    /// Returns the `KeySingleton` with the name supplied in `properties` or
    /// creates a new `KeySingleton` if this name does not exist.
    ///
    /// This method follows the hanging get pattern and does not return until
    /// the response would be different than the previous request for the same
    /// name. Errors are always returned as soon as they are detected.
    ///
    /// `properties` The properties of the new `KeySingleton`.
    ///
    /// Returns: `properties` The `KeySingletonProperties` supplied at creation,
    ///                       with uid populated.
    ///          `state` The `SychronizationState` for the `KeySingleton`.
    ///          `key` The `Key` for the `KeySingleton`.
    WatchOrCreateKeySingleton(KeySingletonProperties properties)
        -> (KeySingletonProperties properties,
            SynchronizationState state,
            Key key) error Error;

    /// Returns the `KeySingleton` with the specified name.
    ///
    /// Fails with `NOT_FOUND` if the requested name does not exist. This method
    /// follows the hanging get pattern and does not return until the response
    /// would be different than the previous request for the same name. Errors
    /// are always returned as soon as they are detected.
    ///
    /// `name` The name of the requested `KeySingleton`.
    ///
    /// Returns: `properties` The `KeySingletonProperties` supplied at creation,
    ///                       with uid populated.
    ///          `state` The `SychronizationState` for the `KeySingleton`.
    ///          `key` The `Key` for the `KeySingleton`.
    WatchKeySingleton(string:MAX_NAME_LEN name)
        -> (KeySingletonProperties properties,
            SynchronizationState state,
            Key key) error Error;

    /// Deletes a previously created `KeySingleton`.
    ///
    /// Fails with `NOT_FOUND` if the requested name does not exist. This method
    /// returns once the deletion has been recorded locally and this does not
    /// guarantee that the deletion will be successfully committed.
    ///
    /// `name` The name of the key singleton.
    DeleteKeySingleton(string:MAX_NAME_LEN name) -> () error Error;

    /// Connects a channel to the `KeySet` with the name supplied in
    /// `properties` or creates a new `KeySet` containing a single `Key` if this
    /// name does not exist.
    ///
    /// `properties` The properties of the new `KeySet`.
    /// `key_set_to_freeze` If this string is the name of another `KeySet` that
    ///                     is in the `LIVE` state, and if this method causes a
    ///                     new `KeySet` to be created, the other `KeySet` will
    ///                     be moved to the `FROZEN` state atomically with the
    ///                     new `KeySet` reaching the `LIVE` state.
    /// `key_set` The server end of a `KeySet` channel.
    GetOrCreateKeySet(
        KeySetProperties properties,
        string:MAX_NAME_LEN? key_set_to_freeze,
        request<KeySet> key_set)
        -> () error Error;

    /// Connects a channel to a previously created `KeySet`.
    ///
    /// Fails with `NOT_FOUND` if the requested name does not exist.
    ///
    /// `name` The name of the key set.
    /// `key_set` The server end of a `KeySet` channel.
    GetKeySet(string:MAX_NAME_LEN name, request<KeySet> key_set)
        -> () error Error;

    /// Freezes a previously created `KeySet`.
    ///
    /// Fails with `NOT_FOUND` if the requested name does not exist.  The method
    /// returns once the freeze has been recorded locally and this does not
    /// guarantee that the freeze will be successfully committed. If the
    /// `KeySet` is already in the `PENDING_FROZEN_ADDITION`, `PENDING_FREEZE`,
    /// or `FROZEN` state this operation has no effect.
    ///
    /// `name` The name of the key set.
    FreezeKeySet(string:MAX_NAME_LEN name) -> () error Error;

    /// Deletes a previously created `KeySet`.
    ///
    /// Fails with `NOT_FOUND` if the requested name does not exist. Once the
    /// deletion has been successfully committed any `KeySet` channels referring
    /// to it will be closed. The method returns once the deletion has been
    /// recorded locally and this does not guarantee that the deletion will
    /// be successfully committed.
    ///
    /// `name` The name of the key set.
    DeleteKeySet(string:MAX_NAME_LEN name) -> () error Error;
};

/// Defines the key material in a `KeySingleton` or each member of a `KeySet`.
///
/// Note: Currently all keys are defined as fixed length arrays of random data
///       but we use an xunion to potentially allow more structured key types
///       in a future version of the API.
flexible union Key {
    /// An unstructured random key of the length specified in
    /// `KeySingletonProperties.key_length` or `KeySetProperties.key_length`.
    1: bytes:MAX_KEY_LEN random_key;
};

/// Specifies the properties of a `KeySingleton`. These properties are provided
/// when the `KeySingleton` is created and do not change during its lifetime.
table KeySingletonProperties {
    /// A name of the `KeySingleton`. Unique within the `KeyManager` that
    /// supplied it at a single point in time.
    1: string:MAX_NAME_LEN name;

    /// A numeric identifier for the `KeySingleton` that is unique within the
    /// `KeyManager` that created it. The same name might be reused for
    /// different key singletons during the lifetime of a `KeyManager` but these
    /// will have different `uid` values.
    ///
    /// This field is set by the account system and must not be supplied in
    /// `KeyManager.CreateKeySingleton`.
    2: uint64 uid;

    /// Optional metadata associated with the `KeySingleton`. This is supplied
    /// by the client and is opaque to the account system.
    3: bytes:MAX_METADATA_LEN metadata;

    /// The size of the key material in this `KeySingleton` in bytes. The value
    /// must be between one and MAX_KEY_LEN inclusive.
    4: uint32 key_length;
};

/// Specifies the properties of a `KeySet`. These properties are provided when
/// the `KeySet` is created and do not change during its lifetime.
table KeySetProperties {
    /// A name of the `KeySet`. Unique within the `KeyManager` that supplied it
    /// at a single point in time.
    1: string:MAX_NAME_LEN name;

    /// A numeric identifier for the `KeySet` that is unique within the
    /// `KeyManager` that created it. The same name might be reused for
    /// different key sets during the lifetime of a `KeyManager` but these will
    /// have different `uid` values.
    ///
    /// This field is set by the account system and must not be supplied in
    /// `KeyManager.CreateKeySet`.
    2: uint64 uid;

    /// Optional metadata associated with the `KeySet`. This is supplied by the
    /// client and is opaque to the account system.
    3: bytes:MAX_METADATA_LEN metadata;

    /// The size of the keys in this `KeySet` in bytes. The value must be
    /// between one and MAX_KEY_LEN inclusive.
    4: uint32 key_length;

    /// The maximum number of keys within this `KeySet`. Old keys will be
    /// automatically deleted to prevent this limit being exceeded. The value
    /// must be between one and MAX_KEYSET_SIZE inclusive.
    5: uint32 max_keys;

    /// If true, a new key will be added to this `KeySet` each time a device
    /// with access to the identity is remotely revoked.
    /// `automatic_rotation` and `manual_rotation` cannot both be false.
    6: bool automatic_rotation;

    /// If true, users of this KeySet may cause new keys to be added by calling
    /// `KeySet.AddKey`.
    /// `automatic_rotation` and `manual_rotation` cannot both be false.
    7: bool manual_rotation;
};

/// `KeySet` provides access to a set of keys that is consistent across devices
/// provisioned with the identity that it applies to.
///
/// The keys within a key set are typically all used for the same purpose, such
/// as encrypting a sensitive dataset. A recent key can be used to encrypt new
/// data but older keys remain available to decrypt older data.
///
/// All keys in the set are of the same size and each is identified by a
/// monotonically increasing `KeyId` starting at one. A new key is added into
/// the set on each rotation event. These rotation events may either occur
/// "automatically" or "manually":
/// * An automatic rotation occurs when a device's access to the identity is
///   remotely revoked (we trust a device that performs its own recovation to
///   also securely delete the key material it is holding). The newly added key
///   is not supplied to the device whose access was revoked. The account system
///   may combine the revocation of multiple devices into a single rotation
///   event.
/// * A manual rotation occurs when a client calls the `AddKey` method.
///
/// Old keys are deleted from the set automatically to avoid exceeding its
/// maximum size, clients may also delete keys using the `DeleteKey` method.
///
/// Optionally, a client may "mark" specific keys in the `KeySet` to track
/// its processing of individual keys. The account system will report the
/// latest key that has been marked on any device.
///
/// A key set may be frozen, after which no further keys will be added and no
/// further mark operations may be performed. Keys may still be deleted from a
/// frozen key set.
protocol KeySet {
    /// Returns the `SynchronizationState` for the entire `KeySet`. Refer to the
    /// documentation on `SynchronizationState` for the available states and
    /// state transitions.
    ///
    /// This method follows the hanging get pattern and does not return until
    /// the response would be different than the previous request.
    WatchSynchronizationState() -> (SynchronizationState state);

    /// Returns the `KeySetProperties` for this key set.
    ///
    /// These properties are fixed and will not change through the life of the
    /// key set.
    GetProperties() -> (KeySetProperties properties);

    /// Return a vector of the `KeyId` for all keys in the key set with
    /// `SynchronizationState == LIVE`.
    ///
    /// The returned vector is ordered by id. This method follows the hanging
    /// get pattern and does not return until the response would be different
    /// than the previous request.
    WatchSynchronizedIds() -> (vector<KeyId>:MAX_KEYSET_SIZE ids) error Error;

    /// Return a vector of the `KeyId` for all keys in the key set, whatever
    /// their `SynchronizationState`.
    ///
    /// The returned vector is ordered by id. This method follows the hanging
    /// get pattern and does not return until the response would be different
    /// than the previous request.
    ///
    /// Note: Worst case this vector will be twice the maximum size of the key
    ///       set. Consider a full key set that contains N `LIVE` keys.
    ///       N manual rotations are now performed before the first succeeds.
    ///       Each rotation moves a key from the `LIVE` state to the
    ///       `PENDING_DELETION` state and adds a new key in the
    ///       `PENDING_ADDITION` state.
    WatchAllIds() -> (vector<KeyId>:TWICE_MAX_KEYSET_SIZE ids) error Error;

    /// Returns a `Key` from the key set.
    ///
    /// Fails with `NOT_FOUND` if the requested key does not exist. This method
    /// follows the hanging get pattern and does not return until the response
    /// would be different than the previous request for this `id`.
    ///
    /// `id` The `KeyId` of the requested key.
    ///
    /// Returns: `key` The requested `Key`.
    ///          `state` The current `SynchronizationState` of the key. Note
    ///                  that keys in `PENDING_ADDITION` are not final: they
    ///                  might never reach other devices and the same `KeyId`
    ///                  might be reused for a different `Key` in the future.
    WatchKey(KeyId id) -> (Key key, SynchronizationState state) error Error;

    /// Deletes a `Key` from the key set.
    ///
    /// Fails with `NOT_FOUND` if the requested key does not exist. The method
    /// returns once the deletion has been recorded locally and this does not
    /// guarantee that the deletion will be successfully committed.
    ///
    /// `id` The `KeyId` of the requested key.
    DeleteKey(KeyId id) -> () error Error;

    /// Adds a new `Key` to the key set, i.e. performs a manual key rotation.
    ///
    /// The method returns once the addition has been recorded locally and this
    /// does not guarantee that the addition will be successfully committed.
    ///
    /// Fails with `UNSUPPORTED_OPERATION` if `KeySetProperties.manual_rotation`
    /// is false or with `FROZEN` if the key set has been frozen.
    AddKey() -> () error Error;

    /// Performs a "Mark" operation on a key, such that it is eligible to be
    /// returned by `GetMaxMarkedId`.
    ///
    /// The largest `KeyId` on which a mark operation has been performed is
    /// synchronized across devices.
    ///
    /// Fails with `FROZEN` if the key set has been frozen.
    ///
    /// `id` The `KeyId` of the requested key. The method will fail with
    ///      NOT_FOUND if this key does not exist.
    MarkId(KeyId id) -> () error Error;

    /// Returns the maximum `KeyId` on which `MarkId` has been called and
    /// successfully commited.
    ///
    /// This method follows the hanging get pattern and does not return until
    /// the response would be different than the previous request.
    ///
    /// Returns: `id` The largest `KeyId` for which a `MarkId` call has been
    ///               made and successfully committed, or zero if no `MarkId`
    ///               calls have been committed.
    WatchMaxCommittedMarkedId() -> (KeyId id) error Error;

    /// Returns the maximum `KeyId` on which `MarkId` has been called, even if
    /// this has not yet been successfully committed.
    ///
    /// This method follows the hanging get pattern and does not return until
    /// the response would be different than the previous request.
    ///
    /// Returns: `id` The largest `KeyId` for which a `MarkId` call has been
    ///               made, or zero if no `MarkId` calls have been made.
    WatchMaxPendingMarkedId() -> (KeyId id) error Error;
};
