= Kync v1 :toc: == General Kync describes a **K**e**Y**e**NC**apsulation plugin API – a KyNc plugin performs the task of protecting your app's secret. The advantage of separating the app and the key storage is that the secret can be stored in a context specific and user defined way by simply loading another plugin – how the secret is protected becomes completely opaque to your app. == Plugin API To achieve a simple and cross-platform compatible API, we use dynamic libraries that expose a C API/ABI. === General Rules These rules apply to all functions: . All functions may fail. If they fail they return a pointer to a statically allocated, `\0`-terminated C string. Otherwise they return `NULL`. . All structs, callbacks etc. are passed as pointers; no ownership is transferred . An API-call *MUST NOT* take longer than 90 seconds before returning . If a callback fails, the operation must be canceled and the callback error *MUST* be propagated === API Overview These functions are defined by the API and *MUST* be implemented: . `init`: Initializes the library, sets the log level and checks if the requested API is supported . `id`: Queries the plugin/format ID . `configs`: Queries all possible plugin configurations (available algorithms, tokens etc.) . `auth_info`: Queries the authentication requirements for a specific configuration . `protect`: Protects a secret and generates the necessary public recovery information for it . `recover`: Recovers a secret using the public recovery information . `slice_t`: An immutable slice over some bytes . `write_t`: A write callback === `init` [source,cpp] ---- const char* init(uint16_t api, uint8_t log_level); ---- This function initializes the library, sets the `log_level` and checks if the requested `api` version is implemented. Parameters: . `api`: The requested API version (this document defines the API `0x01_00`) . `log_level`: The logging level the plugin should use (`0` means no logging). _Note: This applies to StdErr-logging only_ === `id` [source,cpp] ---- const char* id(write_t* sink); ---- This function writes the capsule UID to `sink` using a single `sink.write`-call. Parameters: . `sink`: The sink to write the ID to === `configs` [source,cpp] ---- const char* configs(write_t* sink); ---- This function writes all available configs to `sink` using a single `sink.write`-call for each config (e.g. three configs result in three `sink.write`-calls). Configs identify a specific algorithm/storage/token etc. There must at least be one config. Parameters: . `sink`: The sink to write the configs to === `set_context` [source,cpp] ---- const char* set_context(const slice_t* context); ---- This functions sets an optional application specific context. This makes it possible for the plugin to generate more meaningful names etc. Plugins may silently ignore a call to `set_context` and *MUST NOT* return an error unless they want to but cannot use the context. Parameters: . `context`: The application context (e.g. the application name and key usage) === `auth_info_protect`, `auth_info_recover` [source,cpp] ---- const char* auth_info_protect(uint8_t* is_required, uint64_t* retries, const slice_t* config); const char* auth_info_recover(uint8_t* is_required, uint64_t* retries, const slice_t* config); ---- These functions query the authentication requirements to protect/recover a secret for a specific config. The functions check *if* an authentication is necessary and get the number if retries left. Parameters: . `is_required`: Is set to `1` if an authentication is required, `0` otherwise . `retries`: Is set to the amount of retries left or `UINT64_MAX` if there is no limit . `config`: The config to get the authentication information for === `protect` [source,cpp] ---- const char* protect(write_t* sink, const slice_t* data, const slice_t* config, const slice_t* auth); ---- This function protects `data` and writes the public recovery information to `sink`. Parameters: . `sink`: The sink to write the public recovery information to . `data`: The secret data to protect . `config`: The configuration to use . `auth`: The authentication information or `NULL` if no authentication attempt should be performed === `recover` [source,cpp] ---- const char* recover(write_t* sink, const slice_t* data, const slice_t* auth); ---- This recovers a secret from the recovery `data` and writes it to `sink`. Parameters: . `sink`: The sink to write the public recovery information to . `data`: The secret data to protect . `auth`: The authentication information or `NULL` if no authentication attempt should be performed === `slice_t` [source,cpp] ---- typedef struct slice_t slice_t; /// A slice over some data struct slice_t { /// The data const uint8_t* ptr; /// The data length const size_t len; }; ---- An immutable slice over some data. Fields: . `ptr`: A pointer to the data . `len`: The length of the data === `write_t` [source,cpp] ---- typedef struct write_t write_t; /// A write callback struct write_t { /// An opaque handle to the data sink void* handle; /// Pushes a segment to `handle` and returns `NULL` on success or a pointer to a static error /// description const char* (*write)(void* handle, const slice_t* data); }; ---- A write callback to write some data to an opaque handle. The write function may be called multiple times – either to split the data into different logical segments (e.g. <>) or just because the data is not available at once (e.g. <> and <>). Fields: . `handle`: A pointer to an opaque handle . `write`: A pointer to a write implementation that writes `data` to `handle` and returns `NULL` on success or an error pointer on error