diff --git a/keyfork-user-guide/.gitignore b/keyfork-user-guide/.gitignore new file mode 100644 index 0000000..7585238 --- /dev/null +++ b/keyfork-user-guide/.gitignore @@ -0,0 +1 @@ +book diff --git a/keyfork-user-guide/book.toml b/keyfork-user-guide/book.toml new file mode 100644 index 0000000..a55514b --- /dev/null +++ b/keyfork-user-guide/book.toml @@ -0,0 +1,6 @@ +[book] +authors = ["ryan"] +language = "en" +multilingual = false +src = "src" +title = "Keyfork User Guide" diff --git a/keyfork-user-guide/src/INSTALL.md b/keyfork-user-guide/src/INSTALL.md new file mode 100644 index 0000000..19fc61d --- /dev/null +++ b/keyfork-user-guide/src/INSTALL.md @@ -0,0 +1,53 @@ +# Installing Keyfork + +Keyfork is hosted using the Distrust Cargo repository. For the fastest +installation path (this is not recommended), crates may be installed directly +from the Cargo repository: + +```sh +cargo install --index https://git.distrust.co/public/_cargo-index keyfork@0.1.0 +``` + +The index is managed by Distrust, but is not signed by developers when commits +are created, so a safer alternative may be to build from source. It is +recommended to perform these operations on a machine dedicated for the purpose +of building Rust binaries, to avoid the risk of building a compromised binary. + +```sh +git clone https://git.distrust.co/public/keyfork +cd keyfork +# git checkout keyfork-0.1.0 +git verify-commit HEAD +cargo install --locked --path keyfork +``` + +This will build Keyfork from source, using a local `Cargo.lock` file to ensure +dependencies are not updated automatically. + +## Installing Plumbing Binaries + +Keyfork offers "plumbing" binaries (as opposed to the "porcelain" `keyfork`) +that offer a smaller [SBOM], allowing users with a smaller feature requirement +to lessen the requirements for code review. Plumbing binaries can be installed +the same way Keyfork is installed, either through the registry or by building +locally. Plumbing binaries are grouped by crates of shared dependencies. For +instance, `keyfork-plumbing` includes all binaries using only shared +dependencies. Eventually, `keyfork-plumbing-openpgp` may contain all +dependencies relevant to OpenPGP (such as the `keyfork-shard` variants, +`keyfork-derive-openpgp`, and `keyfork-provision-openpgp-card`). There may also +be plumbing binaries that exist by themselves, without a plumbing package. +Unfortunately, Cargo offers no convenient way to install a binary from any +package on a workspace, so the information about which package contains which +binary must be known beforehand. + + + +```sh +cargo install --index https://git.distrust.co/public/_cargo-index keyfork-plumbing@0.1.0 +cargo install --locked --path keyfork-plumbing --bin keyfork-entropy +``` + +[SBOM]: https://en.wikipedia.org/wiki/SBOM diff --git a/keyfork-user-guide/src/SUMMARY.md b/keyfork-user-guide/src/SUMMARY.md new file mode 100644 index 0000000..0652333 --- /dev/null +++ b/keyfork-user-guide/src/SUMMARY.md @@ -0,0 +1,13 @@ + +# Summary + +- [Installing Keyfork](./INSTALL.md) +- [Common Usage](./usage.md) +- [Binaries](./bin/index.md) + - [keyfork](./bin/keyfork/index.md) + - [mnemonic](./bin/keyfork/mnemonic/index.md) + - [keyforkd](./bin/keyforkd.md) + - [keyfork-entropy](./bin/keyfork-plumbing/entropy.md) + - [keyfork-mnemonic-from-seed](./bin/keyfork-plumbing/mnemonic-from-seed.md) + - [keyfork-derive-key](./bin/keyfork-derive-key.md) + - [keyfork-derive-openpgp](./bin/keyfork-derive-openpgp.md) diff --git a/keyfork-user-guide/src/bin/index.md b/keyfork-user-guide/src/bin/index.md new file mode 100644 index 0000000..0100b4b --- /dev/null +++ b/keyfork-user-guide/src/bin/index.md @@ -0,0 +1 @@ +# Binaries diff --git a/keyfork-user-guide/src/bin/keyfork-derive-key.md b/keyfork-user-guide/src/bin/keyfork-derive-key.md new file mode 100644 index 0000000..c5be8af --- /dev/null +++ b/keyfork-user-guide/src/bin/keyfork-derive-key.md @@ -0,0 +1,20 @@ +# keyfork-derive-key + +Derive a key from a given derivation path. + +Requires [`keyforkd`] to be running. + +## Arguments + +`keyfork-derive-key algorithm path` + +* `algorithm`: A supported BIP-0032 algorithm, such as `secp256k1` or `ed25519` +* `path`: A BIP-0032 path, such as `m/44'/0'` + +It is recommended to use double quotes when writing a derivation path to avoid +the shell silently ignoring the single quotes in the derivation path. + +## Output + +Hex-encoded private key. Note that this is not the _extended_ private key, and +can't be used to derive further data. diff --git a/keyfork-user-guide/src/bin/keyfork-derive-openpgp.md b/keyfork-user-guide/src/bin/keyfork-derive-openpgp.md new file mode 100644 index 0000000..7bbfaaa --- /dev/null +++ b/keyfork-user-guide/src/bin/keyfork-derive-openpgp.md @@ -0,0 +1,30 @@ +# keyfork-derive-openpgp + +Derive a key from a given derivation path. + +Requires [`keyforkd`] to be running. + +Because OpenPGP fingerprints are partially based off the time a key was +created, all OpenPGP keys derived using Keyfork use a creation time of UNIX +epoch plus one, to avoid issues of zero being treated as a falsy value. + +## Arguments + +`keyfork-derive-openpgp path key_format default_userid` + +* `path`: A BIP-0032 path, such as `m/7366512'/0'` +* `key_format`: A list of comma-delimited OpenPGP key capabilities; `C` being + certify (required on the first key), `S` being sign, `E` being both + encrypt-for-transport and encrypt-for-storage, and `A` being authenticate. + For OpenPGP cards, an example could be `C,S,E,A`, resulting in one card per + slot and an off-key certifying key. +* `default_userid`: The default OpenPGP UserID, containing any combination of + an email, a full name, and a username, such as `"Ryan Heywood (RyanSquared) + "` + +It is recommended to use double quotes when writing a derivation path to avoid +the shell silently ignoring the single quotes in the derivation path. + +## Output + +OpenPGP ASCII armored key, signed to be valid for 24 hours. diff --git a/keyfork-user-guide/src/bin/keyfork-plumbing/entropy.md b/keyfork-user-guide/src/bin/keyfork-plumbing/entropy.md new file mode 100644 index 0000000..615a268 --- /dev/null +++ b/keyfork-user-guide/src/bin/keyfork-plumbing/entropy.md @@ -0,0 +1,19 @@ +# keyfork-entropy + +Retrieve system entropy, output in hex format. The machine must be running a +kernel with BLAKE2 entropy support and not be connected to the Internet. + +## Arguments + +`keyfork-entropy [size=256]` + +* `size`: Number of bits, must be divisible by 8 + +## Variables + +- `INSECURE_HARDWARE_ALLOWED=1`: Bypass system validation +- `SHOOT_SELF_IN_FOOT=1`: Bypass system validation + +## Output + +Hex-encoded system entropy, of length `size / 4` diff --git a/keyfork-user-guide/src/bin/keyfork-plumbing/mnemonic-from-seed.md b/keyfork-user-guide/src/bin/keyfork-plumbing/mnemonic-from-seed.md new file mode 100644 index 0000000..9527910 --- /dev/null +++ b/keyfork-user-guide/src/bin/keyfork-plumbing/mnemonic-from-seed.md @@ -0,0 +1,11 @@ +# keyfork-mnemonic-from-seed + +Generate a mnemonic from a seed passed by input. + +## Input + +Hex-encoded seed, ideally from `keyfork-entropy` or a `keyfork-shard` binary. + +## Output + +Mnemonic, from 12 to 24 words. diff --git a/keyfork-user-guide/src/bin/keyfork/index.md b/keyfork-user-guide/src/bin/keyfork/index.md new file mode 100644 index 0000000..c8c0ee6 --- /dev/null +++ b/keyfork-user-guide/src/bin/keyfork/index.md @@ -0,0 +1 @@ +# keyfork diff --git a/keyfork-user-guide/src/bin/keyfork/mnemonic/index.md b/keyfork-user-guide/src/bin/keyfork/mnemonic/index.md new file mode 100644 index 0000000..58fac96 --- /dev/null +++ b/keyfork-user-guide/src/bin/keyfork/mnemonic/index.md @@ -0,0 +1,22 @@ +# `keyfork mnemonic` + +Utilities for managing mnemonics. + +# `keyfork mnemonic generate` + +Generate a mnemonic using various forms of entropy (default: system). Forms of +entropy also include Tarot cards, playing cards, and dice rolls. Because +ensuring entropy is as random as possible while generating mnemonics, and to +ensure the mnemonic itself is not shared to malicious third parties, Keyfork +requires a system be both offline and running an up-to-date kernel before +generating a mnemonic. However, the command may be run with the variable +`INSECURE_HARDWARE_ALLOWED=1` to override system validation. + +## Usage + +``` +% keyfork mnemonic generate +ceiling talent smooth jealous dust render hello resource ripple crucial pepper tribe noble gate shield glad slide document pulse negative spider this fancy seven +% keyfork mnemonic generate --size 128 +sustain glory control silk gym argue jaguar citizen remember doctor depth senior +``` diff --git a/keyfork-user-guide/src/bin/keyforkd.md b/keyfork-user-guide/src/bin/keyforkd.md new file mode 100644 index 0000000..74eb52a --- /dev/null +++ b/keyfork-user-guide/src/bin/keyforkd.md @@ -0,0 +1,32 @@ +# keyforkd + +Keyforkd is the backend for deriving data using Keyfork. A mnemonic is loaded +to the server and requests are performed over a UNIX socket. After the server +has validated the request (using whatever approval methods are implemented), +the server will return an extended private key to the client. The extended +private key can then be used either as-is, or to derive further data. + +By default, the only validation provided for the request is to ensure the +request contains two indices. By requiring this, `keyforkd` can ensure the +master key is not leaked, and "general" keys (such as `m/44'`, see [BIP-0044]) +are not leaked. In the future, `keyforkd` could implement GUI or TTY approval +for users to approve the path requested by the client, such as `m/44'/0'` being +"Bitcoin", or `m/7366512'` being "OpenPGP". + +The protocol for the UNIX socket is a framed, [bincode] format. While it is +custom to Keyfork, it is easy to implement. The crate `keyfork-frame` provides +a sync (`Read`, `Write`) and Tokio-compatible async (`AsyncRead`, `AsyncWrite`) +pair of methods for encoding and decoding frames. + +The payload, binary data, starts with a big-endian u32 length for the rest of +the data. Next, a SHA-256 hash of the remaining data can be decoded. Lastly, +the data itself is stored as-is. Once the data is retrieved, it may be verified +using the previously-loaded SHA-256 hash. + +For encoding the data, the process is reversed. A SHA-256 hash is created, and +the length of the hash and the data is encoded to big-endian and written to the +stream. Then, the hash is written to the stream. Lastly, the data itself is +written as-is to the stream. + +[bincode]: https://docs.rs/bincode/latest/bincode/ +[BIP-0044]: https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki diff --git a/keyfork-user-guide/src/chapter_1.md b/keyfork-user-guide/src/chapter_1.md new file mode 100644 index 0000000..b743fda --- /dev/null +++ b/keyfork-user-guide/src/chapter_1.md @@ -0,0 +1 @@ +# Chapter 1 diff --git a/keyfork-user-guide/src/usage.md b/keyfork-user-guide/src/usage.md new file mode 100644 index 0000000..3e90e15 --- /dev/null +++ b/keyfork-user-guide/src/usage.md @@ -0,0 +1,38 @@ +# Common Usage + +Keyfork is a tool to help manage the creation and derivation of binary data +using [BIP-0039] mnemonics. A mnemonic is, in simple terms, a way of encoding a +random number between 128 and 256 bits large, as a list of 12 to 24 words that +can be easily stored or memorized. Once a user has a mnemonic, Keyfork utilizes +[BIP-0032] to derive cryptographic keys, which can be utilized by a variety of +applications. + +Once a user has generated a mnemonic with [`keyfork mnemonic generate`], the +mnemonic can be loaded to [`keyforkd`]. This is typically done automatically by +[`keyfork`], but plumbing binaries (commands that are not `keyfork`) require +the server to be started manually. + +**NOTE:** Anything beyond this point should be considered Design by +Documentation, and while the commands are not likely to change between now and +when they are released, there is no current stable interface for these +commands, and they may change at any time. + +Users can then "provision" keys, or automatically deploy generated keys to +specific endpoints. For OpenPGP smartcards (such as Yubikeys), `keyfork +provision openpgp-card` will automatically derive an OpenPGP key and provision +it to a smartcard. As previously mentioned, if `keyforkd` was not previously +started, a prompt will be provided by the provisioner for the mnemonic, and +`keyforkd` will be started in the background. + +Any usage of `keyfork provision` or `keyfork derive` can also be given the +`--save` flag, to modify a `keyfork.toml` file and record when the key was +derived, and for what purpose. This is useful, for instance, with OpenPGP, +where a key may be derived with certain capabilities that may not be remembered +otherwise. Later, the command `keyfork recover` can be used to automatically +re-provision each previously invoked provisioner, and re-derive all previously +invoked derivation, through an interactive prompt. + +[BIP-0039]: https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki +[BIP-0032]: https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki +[`keyfork mnemonic generate`]: ./bin/keyfork/mnemonic/index.md#generate +[`keyforkd`]: ./bin/keyforkd.md