# agree [![dependency status](https://deps.rs/repo/github/replicadse/agree/status.svg)](https://deps.rs/repo/github/replicadse/agree)\ `agree` is a CLI tool for easily applying multi-key-turn security via `Shamirs Secret Sharing`. ![](agree.png) ## Project state `agree` is **unstable**.\ Version semantics: `^([0-9]+\.[0-9]+\.[0-9]+)(-(alpha|beta)\.[0-9]+)?$`. ### Backwards compatibility Withing one major version (starting from the first stable release v1.0), there will be full backwards compatibility according to the semantic versioning standard. Note that in order to keep flexibility for development, newer major versions might not be able to work with old format / version archives. Use and install the according version in order to use those. Archives revisions (and their associated program version) can be inspected using the `info` command, assuming you use a version that is the same or newer than the one that was used to create the archive.\ __Note__: Prior to the first major version release (v1), backwards compatibility will only be guaranteed in the same minor version. ## Example ### Split a secret into _n_ shares (interactive) To split a secret (file) into shares, execute one of the following examples.: * Data is in a file (`Cargo.toml`): \ `agree split -i -s Cargo.toml` * Data is generated by an inline shell script and written to `STDOUT` (this approach uses process substitution): \ `agree split -i -s <(printf "secret")` This command is interactive and asks the user to provide data like s hare name, file path and optional password to encrypt the share data. ### Restore a secret from _n_ shares (interactive) In the following example, the secret was split into 2 shares. We need to provide exactly two shares in order to restore the secret and write it to `STDOUT`.\ This command is interactive as it might prompt for the password of the share if it's share dataa is encrypted. ``` agree restore -i -s ./share1.file -s ./share2.file ``` Note that if any password is encrypted and the `-i` flag is **not** provided, the command execution will fail since no password can be prompted from the user when in non-interactive mode. ### Split a secret into _n_ shares (via blueprint) The example below will split the secret into three shares with a restore threshold of two. Assuming the file is called `blueprint.yaml`, we can use the following command: ```bash agree split -s Cargo.toml -b blueprint.yaml ``` ```yaml threshold: 2 generate: - path: ./test/alice.share - path: ./test/bob.share name: bob encrypt: !plain example-bob info: true comment: example for bob - path: ./test/charlie.share name: charlie encrypt: shell: "printf example-charlie" ``` The same result can be achieved using the interactive mode: ```bash agree split -i -s Cargo.toml ``` ## Share composition and versions ### Note on good usage If you use this software to generate archives that are mission critical or contain anything you really want to be able to restore, you should not solely rely on the persistence of GitHub or crates.io. It is highly recommended to either fork the version of this software or store its binaries with the shares at some point. This way, even if the ecosystem is compromised, the software is no longer maintained or distributed or in similar cases, you will still be able to access your data assuming the shares can be used (/ decrypted with the correct password).\ For mission critical information, you should _always_ have contingency plans and never rely on single point of failures. ### v0.2 `v0.2` introduces a versioned `JSON` formatted archive. This archive contains the following information: * `$.version`: CLI version (`$major.$minor` format) that was used to create the archive * `$.uid`: Unique ID of this archive. * `$.pid`: Process ID of this archvie (used to make sure only archives that were created together can be used together) * `$.data`: `base64` encoded share data ``` /// |index |usage| /// |-------|-----| /// |0 - 15 |salt | /// |16 - 39|nonce| /// |40 - 55|mac | /// |56 - |data | ``` The password to the data is hashed via `argon2`. The hashed password is stored alongside the encrypted data to easily identify wrong passwords when the data is decrypted. The share now also contains a checksum to make sure that the restored secret is matching the original one. ### v0.1 Bytes `[0..36)` are reserved for the version ID of the archive.\ In the following schematics, only the data from index `[36..]` is used and shifted left to index `0` for convenience. ``` 1f2c6a6d-f711-4378-97b9-5f9e2f9f4271kldmf209fm0f944fwef98syf23f9h2fneuf2efhux... ^ -- -- VERSION ID -- -- ^ DATA => ``` `v0.1` is a yaml base64 encoded YAML file. The share information can be store either in plain text or can be protected with a password. The share data is always base64 encoded when stored in the YAML field.\ If encrypted with a password, a symmetric encryption algorithm with the following attributes is used (from the crate `simplecrypt v 1.0.2`): ``` /// |index |usage| /// |-------|-----| /// |0 - 15 |salt | /// |16 - 39|nonce| /// |40 - 55|mac | /// |56 - |data | ``` The password to the data is hashed via `argon2`. The hashed password is stored alongside the encrypted data to easily identify wrong passwords when the data is decrypted.