From 1e2475b415d09f70e8f6f885377b2d0c3411ae9e Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Fri, 16 Apr 2021 00:16:00 +1200 Subject: [PATCH 1/4] Add instructions to README --- Cargo.toml | 2 +- README.md | 104 +++++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 99 insertions(+), 7 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 69c2d7e..48c4417 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "age-plugin-yubikey" -description = "[BETA] YubiKey plugin for age." +description = "[BETA] YubiKey plugin for age clients" version = "0.0.0" authors = ["Jack Grigg "] repository = "https://github.com/str4d/age-plugin-yubikey" diff --git a/README.md b/README.md index c9d5749..257af76 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,105 @@ -# YubiKey plugin for age +# YubiKey plugin for age clients -Work in progress. +`age-plugin-yubikey` is a plugin for [age](https://age-encryption.org/v1) clients +like [`age`](https://age-encryption.org) and [`rage`](https://str4d.xyz/rage), +which enables files to be encrypted to age identities stored on YubiKeys. -Do not use this yet with a YubiKey you care about. +This plugin is in **BETA**; we strongly recommend using this with a new YubiKey, +or one that you do not care about. -Not even at a 0.1 release yet. +## Installation -Do not assume we will keep support for anything this currently may do to your YubiKey! -We have a UX goal in mind, and will make breaking changes until we get there. +On Windows, Linux, and macOS, you can use the +[pre-built binaries](https://github.com/str4d/age-plugin-yubikey/releases). + +If your system has Rust 1.51+ installed (either via `rustup` or a system +package), you can build directly from source: + +``` +cargo install age-plugin-yubikey +``` + +Help from new packagers is very welcome. + +## Configuration + +There are two ways to configure a YubiKey as an `age` identity. You can run the +plugin binary directly to use a simple text interface, which will create an age +identity file: + +``` +$ age-plugin-yubikey +``` + +Or you can use command-line flags to programmatically generate an identity and +print it to standard output: + +``` +$ age-plugin-yubikey --generate \ + [--serial SERIAL] \ + [--slot SLOT] \ + [--name NAME] \ + [--pin-policy PIN-POLICY] \ + [--touch-policy TOUCH-POLICY] +``` + +Once an identity has been created, you can regenerate it later: + +``` +$ age-plugin-yubikey --identity [--serial SERIAL] --slot SLOT +``` + +## Usage + +The age recipients contained in all connected YubiKeys can be printed on +standard output: + +``` +$ age-plugin-yubikey --list +``` + +To encrypt files to these YubiKey recipients, ensure that `age-plugin-yubikey` +is accessible in your `PATH`, and then use the recipients with an age client as +normal (e.g. `rage -r age1yubikey1...`). + +The output of the `--list` command can also be used directly to encrypt files to +all recipients (e.g. `age -R filename.txt`). + +To decrypt files encrypted to a YubiKey identity, pass the identity file to the +age client as normal (e.g. `rage -d -i yubikey-identity.txt`). + +## Advanced topics + +### Agent support + +`age-plugin-yubikey` does not provide or interact with an agent for decryption. +As age plugin binaries have short lifetimes (they only run while the age client +is running), this means that YubiKey identities configured with a PIN policy of +`once` will actually prompt for the PIN on every decryption. + +A decryption agent will most likely be implemented as a separate age plugin that +interacts with [`yubikey-agent`](https://github.com/FiloSottile/yubikey-agent), +enabling YubiKeys to be used simultaneously with age and SSH. + +### Manual setup and technical details + +`age-plugin-yubikey` only officially supports YubiKeys set up either via the +text interface or the `--generate` flag. + +In practice, any PIV token with an ECDSA P-256 key and certificate in one of the +20 "retired" slots should work. You can list all age-compatible keys with: + +``` +$ age-plugin-yubikey --list-all +``` + +`age-plugin-yubikey` implements several automatic security management features: + +- If it detects that the default PIN is being used, it will prompt the user to + change the PIN. The PUK is then set to the same value as the PIN. +- If it detects that the default management key is being used, it generates a + random management key and stores it in PIN-protected metadata. + `age-plugin-yubikey` does not support custom management keys. ## License From 47a595213427d89bbd4984a8eac168fe024cf173 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Sun, 2 May 2021 10:15:39 +1200 Subject: [PATCH 2/4] Add WSL instructions to the README --- README.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/README.md b/README.md index 257af76..3f452f6 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,21 @@ cargo install age-plugin-yubikey Help from new packagers is very welcome. +### Windows Subsystem for Linux (WSL) + +WSL does not currently provide native support for USB devices. However, Windows +binaries installed on the host can be run from inside a WSL environment. This +means that you can encrypt or decrypt files inside a WSL environment with a +YubiKey: + +1. Install `age-plugin-yubikey` on the Windows host. +2. Install an age client inside the WSL environment. +3. Ensure that `age-plugin-yubikey.exe` is available in the WSL environment's + `PATH`. For default WSL setups, the Windows host's `PATH` is automatically + added to the WSL environment's `PATH` (see + [this Microsoft blog post](https://devblogs.microsoft.com/commandline/share-environment-vars-between-wsl-and-windows/) + for more details). + ## Configuration There are two ways to configure a YubiKey as an `age` identity. You can run the From cdeb930b529b6253431c9176aa80561245a2a3ed Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Sun, 2 May 2021 13:34:05 +1200 Subject: [PATCH 3/4] Upgrade to age-plugin 0.1.0 --- Cargo.lock | 66 ++++++++++++++++++++++++++++-------------------------- Cargo.toml | 8 ++----- 2 files changed, 36 insertions(+), 38 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 87e2629..4318d4d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,8 +17,9 @@ dependencies = [ [[package]] name = "age-core" -version = "0.5.0" -source = "git+https://github.com/str4d/rage.git?rev=4aa52a2dbb5feed86dcafa3afe8d554975ca5518#4aa52a2dbb5feed86dcafa3afe8d554975ca5518" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad65fc4325804de2e915f5a50dda38218ed49f97e1270750acef9ff8bb67ac36" dependencies = [ "base64", "c2-chacha", @@ -34,8 +35,9 @@ dependencies = [ [[package]] name = "age-plugin" -version = "0.0.0" -source = "git+https://github.com/str4d/rage.git?rev=4aa52a2dbb5feed86dcafa3afe8d554975ca5518#4aa52a2dbb5feed86dcafa3afe8d554975ca5518" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab66824efab6086bdd70e8be63323579bde82da2f336036b3db504ceb2b9dbac" dependencies = [ "age-core", "bech32", @@ -272,6 +274,16 @@ dependencies = [ "subtle", ] +[[package]] +name = "crypto-mac" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25fab6889090c8133f3deb8f73ba3c65a7f456f66436fc012a1b1e272b1e103e" +dependencies = [ + "generic-array", + "subtle", +] + [[package]] name = "data-encoding" version = "2.3.2" @@ -344,16 +356,6 @@ dependencies = [ "generic-array", ] -[[package]] -name = "ecdsa" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41fbdb4ff710acb4db8ca29f93b897529ea6d6a45626d5183b47e012aa6ae7e4" -dependencies = [ - "elliptic-curve", - "signature", -] - [[package]] name = "either" version = "1.6.1" @@ -505,12 +507,12 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hkdf" -version = "0.10.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51ab2f639c231793c5f6114bdb9bbe50a7dbbfcd7c7c6bd8475dec2d991e964f" +checksum = "01706d578d5c281058480e673ae4086a9f4710d8df1ad80a5b03e39ece5f886b" dependencies = [ "digest", - "hmac", + "hmac 0.11.0", ] [[package]] @@ -519,7 +521,17 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1441c6b1e930e2817404b5046f1f989899143a12bf92de603b69f4e0aee1e15" dependencies = [ - "crypto-mac", + "crypto-mac 0.10.0", + "digest", +] + +[[package]] +name = "hmac" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" +dependencies = [ + "crypto-mac 0.11.0", "digest", ] @@ -704,11 +716,10 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "p256" -version = "0.7.2" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ca0196a204bb3f33305ba4a48b38f6e6e621cba8603a4e0650e6532e0949de4" +checksum = "39f37a291d378ba3291c1fa4e925edb6729c8593d4c6064be79e4a4c12fa2d97" dependencies = [ - "ecdsa", "elliptic-curve", ] @@ -727,7 +738,7 @@ version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf916dd32dd26297907890d99dc2740e33f6bd9073965af4ccff2967962f5508" dependencies = [ - "crypto-mac", + "crypto-mac 0.10.0", ] [[package]] @@ -1027,15 +1038,6 @@ dependencies = [ "opaque-debug", ] -[[package]] -name = "signature" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29f060a7d147e33490ec10da418795238fd7545bba241504d6b31a409f2e6210" -dependencies = [ - "rand_core 0.5.1", -] - [[package]] name = "simple_asn1" version = "0.4.1" @@ -1306,7 +1308,7 @@ dependencies = [ "des", "elliptic-curve", "getrandom 0.1.16", - "hmac", + "hmac 0.10.1", "log", "nom", "num-bigint-dig", diff --git a/Cargo.toml b/Cargo.toml index 48c4417..f442d9f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,8 +22,8 @@ assets = [ ] [dependencies] -age-core = "0.5" -age-plugin = "0.0" +age-core = "0.6" +age-plugin = "0.1" base64 = "0.13" bech32 = "0.8" console = "0.14" @@ -45,7 +45,3 @@ yubikey-piv = { version = "0.3", features = ["untested"] } [dev-dependencies] flate2 = "1" man = "0.3" - -[patch.crates-io] -age-core = { git = "https://github.com/str4d/rage.git", rev = "4aa52a2dbb5feed86dcafa3afe8d554975ca5518" } -age-plugin = { git = "https://github.com/str4d/rage.git", rev = "4aa52a2dbb5feed86dcafa3afe8d554975ca5518" } From 6931a7419969c14403a2f0af94b97ccf41ca21f9 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Sun, 2 May 2021 13:35:41 +1200 Subject: [PATCH 4/4] v0.1.0 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4318d4d..7542213 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -47,7 +47,7 @@ dependencies = [ [[package]] name = "age-plugin-yubikey" -version = "0.0.0" +version = "0.1.0" dependencies = [ "age-core", "age-plugin", diff --git a/Cargo.toml b/Cargo.toml index f442d9f..51be049 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "age-plugin-yubikey" description = "[BETA] YubiKey plugin for age clients" -version = "0.0.0" +version = "0.1.0" authors = ["Jack Grigg "] repository = "https://github.com/str4d/age-plugin-yubikey" readme = "README.md"