diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 07b3a93..7430cb6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,116 +23,42 @@ jobs: steps: - uses: actions/checkout@v3 - - uses: actions-rs/toolchain@v1 - with: - toolchain: 1.56.0 - override: true - name: Install build dependencies run: sudo apt install ${{ matrix.build_deps }} if: matrix.build_deps != '' - - name: cargo fetch - uses: actions-rs/cargo@v1 - with: - command: fetch + - name: Install test dependencies + run: cargo install rage + - run: cargo fetch - name: Build tests - uses: actions-rs/cargo@v1 - with: - command: build - args: --verbose --tests + run: cargo build --verbose --tests - name: Run tests - uses: actions-rs/cargo@v1 - with: - command: test - args: --verbose - - clippy: - name: Clippy (1.56.0) - timeout-minutes: 30 - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: actions-rs/toolchain@v1 - with: - toolchain: 1.56.0 - components: clippy - override: true - - name: Install build dependencies - run: sudo apt install libpcsclite-dev - - name: Run clippy - uses: actions-rs/clippy-check@v1 - with: - name: Clippy (1.56.0) - token: ${{ secrets.GITHUB_TOKEN }} - args: --all-features --all-targets -- -D warnings - - clippy-nightly: - name: Clippy (nightly) - timeout-minutes: 30 - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v3 - - uses: actions-rs/toolchain@v1 - with: - toolchain: nightly - components: clippy - override: true - - name: Install build dependencies - run: sudo apt install libpcsclite-dev - - name: Run Clippy (nightly) - uses: actions-rs/clippy-check@v1 - continue-on-error: true - with: - name: Clippy (nightly) - token: ${{ secrets.GITHUB_TOKEN }} - args: --all-features --all-targets + run: cargo test --verbose codecov: name: Code coverage runs-on: ubuntu-latest - steps: - uses: actions/checkout@v3 - # Use stable for this to ensure that cargo-tarpaulin can be built. - - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - override: true - name: Install build dependencies run: sudo apt install libpcsclite-dev + - name: Install coverage dependencies + run: cargo install cargo-tarpaulin - name: Generate coverage report - uses: actions-rs/tarpaulin@v0.1 - with: - args: --release --timeout 180 --out Xml + run: cargo tarpaulin --engine llvm --all-features --release --timeout 600 --out Xml - name: Upload coverage to Codecov uses: codecov/codecov-action@v3.1.1 - with: - token: ${{secrets.CODECOV_TOKEN}} doc-links: name: Intra-doc links runs-on: ubuntu-latest - steps: - uses: actions/checkout@v3 - - uses: actions-rs/toolchain@v1 - with: - toolchain: 1.56.0 - override: true - name: Install build dependencies run: sudo apt install libpcsclite-dev - - name: cargo fetch - uses: actions-rs/cargo@v1 - with: - command: fetch - - # Ensure intra-documentation links all resolve correctly - # Requires #![deny(intra_doc_link_resolution_failure)] in crates. + - run: cargo fetch + # Requires #![deny(rustdoc::broken_intra_doc_links)] in crates. - name: Check intra-doc links - uses: actions-rs/cargo@v1 - with: - command: doc - args: --document-private-items + run: cargo doc --document-private-items fmt: name: Rustfmt @@ -140,13 +66,5 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - uses: actions-rs/toolchain@v1 - with: - toolchain: 1.56.0 - components: rustfmt - override: true - name: Check formatting - uses: actions-rs/cargo@v1 - with: - command: fmt - args: -- --check + run: cargo fmt -- --check diff --git a/.github/workflows/lints-beta.yml b/.github/workflows/lints-beta.yml new file mode 100644 index 0000000..3129eca --- /dev/null +++ b/.github/workflows/lints-beta.yml @@ -0,0 +1,23 @@ +name: Beta lints + +# We only run these lints on trial-merges of PRs to reduce noise. +on: pull_request + +jobs: + clippy-beta: + name: Clippy (beta) + timeout-minutes: 30 + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: dtolnay/rust-toolchain@beta + id: toolchain + - run: rustup override set ${{steps.toolchain.outputs.name}} + - name: Install build dependencies + run: sudo apt install libpcsclite-dev + - name: Clippy (beta) + uses: actions-rs/clippy-check@v1 + with: + name: Clippy (beta) + token: ${{ secrets.GITHUB_TOKEN }} + args: --all-features --all-targets -- -W clippy::all diff --git a/.github/workflows/lints-stable.yml b/.github/workflows/lints-stable.yml new file mode 100644 index 0000000..d8bf84a --- /dev/null +++ b/.github/workflows/lints-stable.yml @@ -0,0 +1,20 @@ +name: Stable lints + +# We only run these lints on trial-merges of PRs to reduce noise. +on: pull_request + +jobs: + clippy: + name: Clippy (MSRV) + timeout-minutes: 30 + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Install build dependencies + run: sudo apt install libpcsclite-dev + - name: Run clippy + uses: actions-rs/clippy-check@v1 + with: + name: Clippy (MSRV) + token: ${{ secrets.GITHUB_TOKEN }} + args: --all-features --all-targets -- -D warnings diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2eb59a2..b68a221 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -87,7 +87,7 @@ jobs: if: matrix.name == 'windows' - name: Upload archive to release - uses: svenstaro/upload-release-action@2.3.0 + uses: svenstaro/upload-release-action@2.5.0 with: file: ${{ matrix.archive_name }} asset_name: age-plugin-yubikey-$tag-${{ matrix.asset_suffix }} @@ -146,7 +146,7 @@ jobs: args: --package age-plugin-yubikey --no-build --target ${{ matrix.target }} - name: Upload Debian package to release - uses: svenstaro/upload-release-action@2.3.0 + uses: svenstaro/upload-release-action@2.5.0 with: file: target/${{ matrix.target }}/debian/*.deb file_glob: true diff --git a/CHANGELOG.md b/CHANGELOG.md index 5bae3c7..cffa7a4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,24 @@ to 0.3.0 are beta releases. critical extensions in its certificate, to ensure it doesn't misuse a newer identity type. +## [0.4.0] - 2023-04-09 +### Changed +- MSRV is now 1.65.0. +- The YubiKey PIV PIN and touch caches are now preserved across processes in + most cases. See [README.md](README.md#agent-support) for exceptions. This has + several usability effects (not applicable to YubiKey 4 series): + - If a YubiKey's PIN is cached by an agent like `yubikey-agent`, and then + `age-plugin-yubikey` is run (either directly or as a plugin), the agent + won't request a PIN entry on its next use. + - If a YubiKey's PIN was requested by either a previous invocation of + `age-plugin-yubikey` or an agent like `yubikey-agent`, subsequent calls to + `age-plugin-yubikey` won't request a PIN entry to decrypt a file with an + identity that has a PIN policy of `once`. + +### Fixed +- Identities can now be generated with a PIN policy of "always" (in previous + versions of `age-plugin-yubikey` this would cause an error). + ## [0.3.3] - 2023-02-11 ### Fixed - When `age-plugin-yubikey` assists the user in changing their PIN from the diff --git a/Cargo.lock b/Cargo.lock index bcf9494..9c4b45c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10,20 +10,21 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "aead" -version = "0.4.3" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b613b8e1e3cf911a086f53f03bf286f52fd7a7258e4fa606f0ef220d39d8877" +checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" dependencies = [ + "crypto-common", "generic-array", ] [[package]] name = "age-core" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00a5c8d8a33abc74ad393896a6305351dd159d0e184788f4729e3c80e397fa45" +checksum = "e3d2e815ac879dc23c1139e720d21c6cd4d1276345c772587285d965a69b8f32" dependencies = [ - "base64", + "base64 0.13.1", "chacha20poly1305", "cookie-factory", "hkdf", @@ -31,29 +32,29 @@ dependencies = [ "nom", "rand", "secrecy", - "sha2 0.10.2", + "sha2", "tempfile", ] [[package]] name = "age-plugin" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad6dc325516aa4b1e06a858dcfa9c5c962d02fb801331f23214d21abd9e2346b" +checksum = "4564b93d746fc5947e08ee2b9b3f990df89133803857b6ee0dad8b0efeb8bc79" dependencies = [ "age-core", - "base64", + "base64 0.13.1", "bech32", "chrono", ] [[package]] name = "age-plugin-yubikey" -version = "0.3.4" +version = "0.4.0" dependencies = [ "age-core", "age-plugin", - "base64", + "base64 0.21.0", "bech32", "console", "dialoguer", @@ -70,8 +71,10 @@ dependencies = [ "pcsc", "rand", "rust-embed", - "sha2 0.9.9", + "sha2", "sysinfo", + "tempfile", + "test-with", "which", "x509", "x509-parser", @@ -80,31 +83,65 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "0.7.18" +version = "0.7.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" dependencies = [ "memchr", ] [[package]] -name = "atty" -version = "0.2.14" +name = "android_system_properties" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" dependencies = [ - "hermit-abi", "libc", - "winapi", ] [[package]] -name = "autocfg" -version = "0.1.8" +name = "arc-swap" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dde43e75fd43e8a1bf86103336bc699aa8d17ad1be60c76c0bdfd4828e19b78" +checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6" + +[[package]] +name = "asn1-rs" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6fd5ddaf0351dff5b8da21b2fb4ff8e08ddd02857f0bf69c47639106c0fff0" dependencies = [ - "autocfg 1.1.0", + "asn1-rs-derive", + "asn1-rs-impl", + "displaydoc", + "nom", + "num-traits", + "rusticata-macros", + "thiserror", + "time 0.3.20", +] + +[[package]] +name = "asn1-rs-derive" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "726535892e8eae7e70657b4c8ea93d26b8553afb1ce617caee529ef96d7dee6c" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", + "synstructure", +] + +[[package]] +name = "asn1-rs-impl" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2777730b2039ac0f95f093556e61b6d26cebed5393ca6f152717777cec3a42ed" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] @@ -114,22 +151,34 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] -name = "base64" -version = "0.13.0" +name = "base16ct" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "base64" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a" [[package]] name = "base64ct" -version = "1.1.1" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6b4d9b1225d28d360ec6a231d65af1fd99a2a095154c8040689617290569c5c" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "bech32" -version = "0.8.1" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9ff0bbfd639f15c74af777d81383cf53efb7c93613f6cab67c6c11e05bbf8b" +checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" [[package]] name = "bitflags" @@ -145,20 +194,27 @@ checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" [[package]] name = "block-buffer" -version = "0.9.0" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ "generic-array", ] [[package]] -name = "block-buffer" -version = "0.10.2" +name = "bumpalo" +version = "3.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324" +checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" + +[[package]] +name = "byte-unit" +version = "4.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da78b32057b8fdfc352504708feeba7216dcd65a2c9ab02978cbd288d1279b6c" dependencies = [ - "generic-array", + "serde", + "utf8-width", ] [[package]] @@ -167,6 +223,18 @@ version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +[[package]] +name = "bytes" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" + +[[package]] +name = "cc" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" + [[package]] name = "cfg-if" version = "1.0.0" @@ -175,21 +243,20 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chacha20" -version = "0.8.1" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01b72a433d0cf2aef113ba70f62634c56fddb0f244e6377185c56a7cadbd8f91" +checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" dependencies = [ "cfg-if", "cipher", "cpufeatures", - "zeroize", ] [[package]] name = "chacha20poly1305" -version = "0.9.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b84ed6d1d5f7aa9bdde921a5090e0ca4d934d250ea3b402a5fab3a994e28a2a" +checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" dependencies = [ "aead", "chacha20", @@ -200,46 +267,58 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.19" +version = "0.4.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" +checksum = "4e3c5919066adf22df73762e50cffcde3a758f2a848b113b586d1f86728b673b" dependencies = [ - "libc", + "iana-time-zone", + "js-sys", "num-integer", "num-traits", - "time", + "time 0.1.45", + "wasm-bindgen", "winapi", ] [[package]] name = "cipher" -version = "0.3.0" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" dependencies = [ - "generic-array", + "crypto-common", + "inout", + "zeroize", +] + +[[package]] +name = "codespan-reporting" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +dependencies = [ + "termcolor", + "unicode-width", ] [[package]] name = "console" -version = "0.15.0" +version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28b32d32ca44b70c3e4acd7db1babf555fa026e385fb95f18028f88848b3c31" +checksum = "c3d79fbe8970a77e3e34151cc13d3b3e248aa0faaecb9f6091fa07ebefe5ad60" dependencies = [ "encode_unicode", + "lazy_static", "libc", - "once_cell", - "regex", - "terminal_size", "unicode-width", - "winapi", + "windows-sys 0.42.0", ] [[package]] name = "const-oid" -version = "0.6.2" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d6f2aa4d0537bcc1c74df8755072bd31c1ef1a3a1b85a68e8404a8c353b7b8b" +checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" [[package]] name = "cookie-factory" @@ -248,16 +327,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "396de984970346b0d9e93d1415082923c679e5ae5c3ee3dcbd104f5610af126b" [[package]] -name = "core-foundation-sys" -version = "0.8.3" +name = "core-foundation" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" [[package]] name = "cpufeatures" -version = "0.2.2" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b" +checksum = "280a9f2d8b3a38871a3c8a46fb80db65e5e5ed97da80c4d08bf27fb63e35e181" dependencies = [ "libc", ] @@ -273,9 +362,9 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.6" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" +checksum = "cf2b3e8478797446514c91ef04bafcb59faba183e621ad488df88983cc14128c" dependencies = [ "cfg-if", "crossbeam-utils", @@ -283,9 +372,9 @@ dependencies = [ [[package]] name = "crossbeam-deque" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc" +checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" dependencies = [ "cfg-if", "crossbeam-epoch", @@ -294,11 +383,11 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.13" +version = "0.9.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a" +checksum = "46bd5f3f85273295a9d14aedfb86f6aadbff6d8f5295c4a9edb08e819dcf5695" dependencies = [ - "autocfg 1.1.0", + "autocfg", "cfg-if", "crossbeam-utils", "memoffset", @@ -307,18 +396,18 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.14" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f" +checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b" dependencies = [ "cfg-if", ] [[package]] name = "crypto-bigint" -version = "0.2.11" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f83bd3bb4314701c568e340cd8cf78c975aa0ca79e03d3f6d1677d5b0c9c0c03" +checksum = "7c2538c4e68e52548bacb3e83ac549f903d44f011ac9d5abb5e132e67d0808f7" dependencies = [ "generic-array", "rand_core", @@ -328,69 +417,96 @@ dependencies = [ [[package]] name = "crypto-common" -version = "0.1.3" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57952ca27b5e3606ff4dd79b0020231aaf9d6aa76dc05fd30137538c50bd3ce8" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", "typenum", ] [[package]] -name = "crypto-mac" -version = "0.11.1" +name = "cxx" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" +checksum = "f61f1b6389c3fe1c316bf8a4dccc90a38208354b330925bce1f74a6c4756eb93" dependencies = [ - "generic-array", - "subtle", + "cc", + "cxxbridge-flags", + "cxxbridge-macro", + "link-cplusplus", +] + +[[package]] +name = "cxx-build" +version = "1.0.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12cee708e8962df2aeb38f594aae5d827c022b6460ac71a7a3e2c3c2aae5a07b" +dependencies = [ + "cc", + "codespan-reporting", + "once_cell", + "proc-macro2", + "quote", + "scratch", + "syn 2.0.13", +] + +[[package]] +name = "cxxbridge-flags" +version = "1.0.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7944172ae7e4068c533afbb984114a56c46e9ccddda550499caa222902c7f7bb" + +[[package]] +name = "cxxbridge-macro" +version = "1.0.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2345488264226bf682893e25de0769f3360aac9957980ec49361b083ddaa5bc5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.13", ] [[package]] name = "dashmap" -version = "5.2.0" +version = "5.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c8858831f7781322e539ea39e72449c46b059638250c14344fec8d0aa6e539c" +checksum = "907076dfda823b0b36d2a1bb5f90c96660a5bbcd7729e10727f07858f22c4edc" dependencies = [ "cfg-if", - "num_cpus", - "parking_lot", + "hashbrown", + "lock_api", + "once_cell", + "parking_lot_core", ] [[package]] name = "data-encoding" -version = "2.3.2" +version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ee2393c4a91429dffb4bedf19f4d6abf27d8a732c8ce4980305d782e5426d57" +checksum = "23d8666cb01533c39dde32bcbab8e227b4ed6679b2c925eba05feabea39508fb" [[package]] name = "der" -version = "0.4.5" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79b71cca7d95d7681a4b3b9cdf63c8dbc3730d0584c2c74e31416d64a90493f4" +checksum = "82b10af9f9f9f2134a42d3f8aa74658660f2e0234b0eb81bd171df8aa32779ed" dependencies = [ "const-oid", - "crypto-bigint", -] - -[[package]] -name = "der-oid-macro" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c73af209b6a5dc8ca7cbaba720732304792cddc933cfea3d74509c2b1ef2f436" -dependencies = [ - "num-bigint", - "num-traits", - "syn", + "pem-rfc7468", + "zeroize", ] [[package]] name = "der-parser" -version = "6.0.1" +version = "8.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cddf120f700b411b2b02ebeb7f04dc0b7c8835909a6c2f52bf72ed0dd3433b2" +checksum = "dbd676fbbab537128ef0278adb5576cf363cff6aa22a7b24effe97347cfab61e" dependencies = [ - "der-oid-macro", + "asn1-rs", + "displaydoc", "nom", "num-bigint", "num-traits", @@ -399,76 +515,83 @@ dependencies = [ [[package]] name = "des" -version = "0.7.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac41dd49fb554432020d52c875fc290e110113f864c6b1b525cd62c7e7747a5d" +checksum = "ffdd80ce8ce993de27e9f063a444a4d53ce8e8db4c1f00cc03af5ad5a9867a1e" dependencies = [ - "byteorder", "cipher", - "opaque-debug", ] [[package]] name = "dialoguer" -version = "0.9.0" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61579ada4ec0c6031cfac3f86fdba0d195a7ebeb5e36693bd53cb5999a25beeb" +checksum = "59c6f2989294b9a498d3ad5491a79c6deb604617378e1cdc4bfc1c1361fe2f87" dependencies = [ "console", - "lazy_static", + "shell-words", "zeroize", ] [[package]] name = "digest" -version = "0.9.0" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" dependencies = [ - "generic-array", -] - -[[package]] -name = "digest" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" -dependencies = [ - "block-buffer 0.10.2", + "block-buffer", + "const-oid", "crypto-common", "subtle", ] [[package]] -name = "ecdsa" -version = "0.12.4" +name = "displaydoc" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43ee23aa5b4f68c7a092b5c3beb25f50c406adc75e2363634f242f28ab255372" +checksum = "3bf95dc3f046b9da4f2d51833c0d3547d8564ef6910f5c1ed130306a75b92886" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ecdsa" +version = "0.16.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "298d10b6d24e99de17b92bd41bfe33f4e8530ee7948233eb2a4158f4464d2046" dependencies = [ "der", + "digest", "elliptic-curve", - "hmac 0.11.0", + "rfc6979", "signature", ] [[package]] name = "either" -version = "1.6.1" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" +checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" [[package]] name = "elliptic-curve" -version = "0.10.6" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "beca177dcb8eb540133e7680baff45e7cc4d93bf22002676cec549f82343721b" +checksum = "75c71eaa367f2e5d556414a8eea812bc62985c879748d6403edabd9cb03f16e7" dependencies = [ + "base16ct", "crypto-bigint", + "digest", "ff", "generic-array", "group", + "hkdf", + "pem-rfc7468", "pkcs8", "rand_core", + "sec1", "subtle", "zeroize", ] @@ -480,32 +603,62 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" [[package]] -name = "env_logger" -version = "0.9.0" +name = "encoding_rs" +version = "0.8.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3" +checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "env_logger" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" dependencies = [ - "atty", "humantime", + "is-terminal", "log", "regex", "termcolor", ] [[package]] -name = "fastrand" -version = "1.7.0" +name = "errno" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf" +checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +dependencies = [ + "errno-dragonfly", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "fastrand" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" dependencies = [ "instant", ] [[package]] name = "ff" -version = "0.10.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0f40b2dcd8bc322217a5f6559ae5f9e9d1de202a2ecee2e9eafcbece7562a4f" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" dependencies = [ "rand_core", "subtle", @@ -522,13 +675,11 @@ dependencies = [ [[package]] name = "flate2" -version = "1.0.22" +version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f" +checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841" dependencies = [ - "cfg-if", "crc32fast", - "libc", "miniz_oxide", ] @@ -577,31 +728,110 @@ dependencies = [ ] [[package]] -name = "generic-array" -version = "0.14.5" +name = "fnv" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures-channel" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" + +[[package]] +name = "futures-io" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" + +[[package]] +name = "futures-sink" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" + +[[package]] +name = "futures-task" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" + +[[package]] +name = "futures-util" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +dependencies = [ + "futures-core", + "futures-io", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", + "zeroize", ] [[package]] name = "getrandom" -version = "0.2.5" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d39cd93900197114fa1fcb7ae84ca742095eed9442088988ae74fa744e930e77" +checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4" dependencies = [ "cfg-if", "libc", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", ] [[package]] name = "group" -version = "0.10.0" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c363a5301b8f153d80747126a04b3c82073b9fe3130571a9d170cacdeaf7912" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ "ff", "rand_core", @@ -625,17 +855,48 @@ checksum = "729f9bd3449d77e7831a18abfb7ba2f99ee813dfd15b8c2167c9a54ba20aa99d" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", +] + +[[package]] +name = "h2" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5be7b54589b581f624f566bf5d8eb2bab1db736c51528720b6bd36b96b55924d" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hermit-abi" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" +dependencies = [ + "libc", ] [[package]] name = "hermit-abi" -version = "0.1.19" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] +checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" [[package]] name = "hex" @@ -649,17 +910,7 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437" dependencies = [ - "hmac 0.12.1", -] - -[[package]] -name = "hmac" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" -dependencies = [ - "crypto-mac", - "digest 0.9.0", + "hmac", ] [[package]] @@ -668,9 +919,43 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest 0.10.3", + "digest", ] +[[package]] +name = "http" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" + [[package]] name = "humantime" version = "2.1.0" @@ -678,10 +963,47 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] -name = "i18n-config" -version = "0.4.2" +name = "hyper" +version = "0.14.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b62affcd43abfb51f3cbd8736f9407908dc5b44fc558a9be07460bbfd104d983" +checksum = "cc5e554ff619822309ffd57d8734d77cd5ce6238bc956f037ea06c58238c9899" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper", + "native-tls", + "tokio", + "tokio-native-tls", +] + +[[package]] +name = "i18n-config" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d9f93ceee6543011739bc81699b5e0cf1f23f3a80364649b6d80de8636bc8df" dependencies = [ "log", "serde", @@ -693,10 +1015,11 @@ dependencies = [ [[package]] name = "i18n-embed" -version = "0.13.4" +version = "0.13.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7f21ed76e44de8ac3dfa36bb37ab2e6480be0dc75c612474949be1f3cb2c253" +checksum = "2653dd1a8be0726315603f1c180b29f90e5b2a58f8b943d949d5170d9ad81101" dependencies = [ + "arc-swap", "fluent", "fluent-langneg", "fluent-syntax", @@ -714,9 +1037,9 @@ dependencies = [ [[package]] name = "i18n-embed-fl" -version = "0.6.4" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9420a9718ef9d0ab727840a398e25408ea0daff9ba3c681707ba05485face98e" +checksum = "4b5809e2295beeb55013705c3b947cbbe83b8cadf3c73a1e6dca06381927212a" dependencies = [ "dashmap", "find-crate", @@ -729,7 +1052,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn", + "syn 1.0.109", "unic-langid", ] @@ -743,7 +1066,60 @@ dependencies = [ "i18n-config", "proc-macro2", "quote", - "syn", + "syn 1.0.109", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0722cd7114b7de04316e7ea5456a0bbb20e4adb46fd27a3697adb812cff0f37c" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" +dependencies = [ + "cxx", + "cxx-build", +] + +[[package]] +name = "idna" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown", +] + +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "generic-array", ] [[package]] @@ -767,20 +1143,63 @@ dependencies = [ [[package]] name = "intl_pluralrules" -version = "7.0.1" +version = "7.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b18f988384267d7066cc2be425e6faf352900652c046b6971d2e228d3b1c5ecf" +checksum = "078ea7b7c29a2b4df841a7f6ac8775ff6074020c6776d48491ce2268e068f972" dependencies = [ - "tinystr", "unic-langid", ] +[[package]] +name = "io-lifetimes" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220" +dependencies = [ + "hermit-abi 0.3.1", + "libc", + "windows-sys 0.48.0", +] + [[package]] name = "io_tee" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4b3f7cef34251886990511df1c61443aa928499d598a9473929ab5a90a527304" +[[package]] +name = "ipnet" +version = "2.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12b6ee2129af8d4fb011108c73d99a1b83a85977f23b82460c0ae2e25bb4b57f" + +[[package]] +name = "is-terminal" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" +dependencies = [ + "hermit-abi 0.3.1", + "io-lifetimes", + "rustix", + "windows-sys 0.48.0", +] + +[[package]] +name = "itoa" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" + +[[package]] +name = "js-sys" +version = "0.3.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730" +dependencies = [ + "wasm-bindgen", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -792,15 +1211,30 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.121" +version = "0.2.141" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efaa7b300f3b5fe8eb6bf21ce3895e1751d9665086af2d64b42f19701015ff4f" +checksum = "3304a64d199bb964be99741b7a14d26972741915b3649639149b2479bb46f4b5" [[package]] name = "libm" -version = "0.2.2" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33a33a362ce288760ec6a508b94caaec573ae7d3bbbd91b87aa0bad4456839db" +checksum = "348108ab3fba42ec82ff6e9564fc4ca0247bdccdc68dd8af9764bbc79c3c8ffb" + +[[package]] +name = "link-cplusplus" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecd207c9c713c34f95a097a5b029ac2ce6010530c7b49d7fea24d977dede04f5" +dependencies = [ + "cc", +] + +[[package]] +name = "linux-raw-sys" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d59d8c75012853d2e872fb56bc8a2e53718e2cafe1a4c823143141c6d90c322f" [[package]] name = "locale_config" @@ -817,19 +1251,19 @@ dependencies = [ [[package]] name = "lock_api" -version = "0.4.7" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" +checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" dependencies = [ - "autocfg 1.1.0", + "autocfg", "scopeguard", ] [[package]] name = "log" -version = "0.4.14" +version = "0.4.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" dependencies = [ "cfg-if", ] @@ -854,19 +1288,25 @@ dependencies = [ [[package]] name = "memchr" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "memoffset" -version = "0.7.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" dependencies = [ - "autocfg 1.1.0", + "autocfg", ] +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + [[package]] name = "minimal-lexical" version = "0.2.1" @@ -875,19 +1315,48 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.4.4" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" +checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" dependencies = [ "adler", - "autocfg 1.1.0", +] + +[[package]] +name = "mio" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9" +dependencies = [ + "libc", + "log", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys 0.45.0", +] + +[[package]] +name = "native-tls" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", ] [[package]] name = "nom" -version = "7.1.1" +version = "7.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" dependencies = [ "memchr", "minimal-lexical", @@ -895,9 +1364,9 @@ dependencies = [ [[package]] name = "ntapi" -version = "0.3.7" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c28774a7fd2fbb4f0babd8237ce554b73af68021b5f695a3cebd6c59bac0980f" +checksum = "bc51db7b362b205941f71232e56c625156eb9a929f8cf74a428fd5bc094a4afc" dependencies = [ "winapi", ] @@ -908,18 +1377,17 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" dependencies = [ - "autocfg 1.1.0", + "autocfg", "num-integer", "num-traits", ] [[package]] name = "num-bigint-dig" -version = "0.7.0" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4547ee5541c18742396ae2c895d0717d0f886d8823b8399cdaf7b07d63ad0480" +checksum = "2399c9463abc5f909349d8aa9ba080e0b88b3ce2885389b60b993f39b1a56905" dependencies = [ - "autocfg 0.1.8", "byteorder", "lazy_static", "libm", @@ -934,42 +1402,42 @@ dependencies = [ [[package]] name = "num-integer" -version = "0.1.44" +version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" dependencies = [ - "autocfg 1.1.0", + "autocfg", "num-traits", ] [[package]] name = "num-iter" -version = "0.1.42" +version = "0.1.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59" +checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" dependencies = [ - "autocfg 1.1.0", + "autocfg", "num-integer", "num-traits", ] [[package]] name = "num-traits" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" dependencies = [ - "autocfg 1.1.0", + "autocfg", "libm", ] [[package]] name = "num_cpus" -version = "1.13.1" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" +checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" dependencies = [ - "hermit-abi", + "hermit-abi 0.2.6", "libc", ] @@ -1004,18 +1472,18 @@ dependencies = [ [[package]] name = "oid-registry" -version = "0.2.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe554cb2393bc784fd678c82c84cc0599c31ceadc7f03a594911f822cb8d1815" +checksum = "9bedf36ffb6ba96c2eb7144ef6270557b52e54b20c0a8e1eb2ff99a6c6959bff" dependencies = [ - "der-parser", + "asn1-rs", ] [[package]] name = "once_cell" -version = "1.10.0" +version = "1.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9" +checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" [[package]] name = "opaque-debug" @@ -1024,30 +1492,78 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] -name = "p256" -version = "0.9.0" +name = "openssl" +version = "0.10.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d053368e1bae4c8a672953397bd1bd7183dde1c72b0b7612a15719173148d186" +checksum = "4d2f106ab837a24e03672c59b1239669a0596406ff657c3c0835b6b7f0f35a33" +dependencies = [ + "bitflags", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.13", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-sys" +version = "0.9.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a20eace9dc2d82904039cb76dcf50fb1a0bba071cfd1629720b5d6f1ddba0fa" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "p256" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7270da3e5caa82afd3deb054cc237905853813aea3859544bc082c3fe55b8d47" dependencies = [ "ecdsa", "elliptic-curve", - "sha2 0.9.9", + "primeorder", + "sha2", ] [[package]] name = "p384" -version = "0.8.0" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f23bc88c404ccc881c8a1ad62ba5cd7d336a64ecbf46de4874f2ad955f67b157" +checksum = "70786f51bcc69f6a4c0360e063a4cac5419ef7c5cd5b3c99ad70f3be5ba79209" dependencies = [ + "ecdsa", "elliptic-curve", + "primeorder", + "sha2", ] [[package]] name = "parking_lot" -version = "0.12.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f5ec2493a61ac0506c0f4199f99070cbe83857b0337006a30f3e6719b8ef58" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ "lock_api", "parking_lot_core", @@ -1055,31 +1571,32 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.3" +version = "0.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929" +checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" dependencies = [ "cfg-if", "libc", - "redox_syscall", + "redox_syscall 0.2.16", "smallvec", - "windows-sys", + "windows-sys 0.45.0", ] [[package]] name = "pbkdf2" -version = "0.9.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f05894bce6a1ba4be299d0c5f29563e08af2bc18bb7d48313113bed71e904739" +checksum = "f0ca0b5a68607598bf3bad68f32227a8164f6254833f84eafaac409cd6746c31" dependencies = [ - "crypto-mac", + "digest", + "hmac", ] [[package]] name = "pcsc" -version = "2.7.0" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e29e4de78a433aeecd06fb5bd55a0f9fde11dc85a14c22d482972c7edc4fdc4" +checksum = "37cab0be9d04e808a8d8059fa54befcd71dc8b168f9f0c04bdb7e59832abbab4" dependencies = [ "bitflags", "pcsc-sys", @@ -1096,48 +1613,75 @@ dependencies = [ [[package]] name = "pem-rfc7468" -version = "0.2.4" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84e93a3b1cc0510b03020f33f21e62acdde3dcaef432edc95bea377fbd4c2cd4" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" dependencies = [ "base64ct", ] [[package]] -name = "pkcs1" -version = "0.2.4" +name = "percent-encoding" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "116bee8279d783c0cf370efa1a94632f2108e5ef0bb32df31f051647810a4e2c" +checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" + +[[package]] +name = "pin-project-lite" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "ping" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6370a87a1a5bacec2eb80fa24ff3b7f47a1d47404a96611230d3b0d2e0f51141" dependencies = [ - "der", - "pem-rfc7468", - "zeroize", + "rand", + "socket2", + "thiserror", ] [[package]] -name = "pkcs8" -version = "0.7.6" +name = "pkcs1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee3ef9b64d26bad0536099c816c6734379e45bbd5f14798def6809e5cc350447" +checksum = "575fd6eebed721a2929faa1ee1383a49788378083bbbd7f299af75dd84195cee" dependencies = [ "der", - "pem-rfc7468", - "pkcs1", + "pkcs8", "spki", "zeroize", ] [[package]] -name = "pkg-config" -version = "0.3.24" +name = "pkcs8" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "pkg-config" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" [[package]] name = "poly1305" -version = "0.7.2" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "048aeb476be11a4b6ca432ca569e375810de9294ae78f4774e78ea98a9246ede" +checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" dependencies = [ "cpufeatures", "opaque-debug", @@ -1146,9 +1690,18 @@ dependencies = [ [[package]] name = "ppv-lite86" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "primeorder" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7613fdcc0831c10060fa69833ea8fa2caa94b6456f51e25356a885b530a2e3d0" +dependencies = [ + "elliptic-curve", +] [[package]] name = "proc-macro-error" @@ -1159,7 +1712,7 @@ dependencies = [ "proc-macro-error-attr", "proc-macro2", "quote", - "syn", + "syn 1.0.109", "version_check", ] @@ -1176,18 +1729,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.36" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" +checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" dependencies = [ - "unicode-xid", + "unicode-ident", ] [[package]] name = "quote" -version = "1.0.16" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4af2ec4714533fcdf07e886f17025ace8b997b9ce51204ee69b6da831c3da57" +checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" dependencies = [ "proc-macro2", ] @@ -1215,18 +1768,18 @@ dependencies = [ [[package]] name = "rand_core" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ "getrandom", ] [[package]] name = "rayon" -version = "1.6.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db3a213adf02b3bcfd2d3846bb41cb22857d131789e01df434fb7e7bc0759b7" +checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" dependencies = [ "either", "rayon-core", @@ -1234,9 +1787,9 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.10.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cac410af5d00ab6884528b4ab69d1e8e146e8d471201800fa1b4524126de6ad3" +checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" dependencies = [ "crossbeam-channel", "crossbeam-deque", @@ -1246,18 +1799,27 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.2.11" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8380fe0152551244f0747b1bf41737e0f8a74f97a14ccefd1148187271634f3c" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags", +] + +[[package]] +name = "redox_syscall" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" dependencies = [ "bitflags", ] [[package]] name = "regex" -version = "1.5.5" +version = "1.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286" +checksum = "8b1f693b24f6ac912f4893ef08244d70b6067480d2f1a46e950c9691e6749d1d" dependencies = [ "aho-corasick", "memchr", @@ -1266,17 +1828,55 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.25" +version = "0.6.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] -name = "remove_dir_all" -version = "0.5.3" +name = "reqwest" +version = "0.11.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +checksum = "27b71749df584b7f4cac2c426c127a7c785a5106cc98f7a8feb044115f0fa254" dependencies = [ - "winapi", + "base64 0.21.0", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-tls", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "serde", + "serde_json", + "serde_urlencoded", + "tokio", + "tokio-native-tls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg", +] + +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", ] [[package]] @@ -1287,29 +1887,29 @@ checksum = "e33e4fb37ba46888052c763e4ec2acfedd8f00f62897b630cadb6298b833675e" [[package]] name = "rsa" -version = "0.5.0" +version = "0.9.0-pre.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e05c2603e2823634ab331437001b411b9ed11660fbc4066f3908c84a9439260d" +checksum = "a7bc1d34159d63536b4d89944e9ab5bb952f45db6fa0b8b03c2f8c09fb5b7171" dependencies = [ "byteorder", - "digest 0.9.0", - "lazy_static", + "digest", "num-bigint-dig", "num-integer", "num-iter", "num-traits", "pkcs1", "pkcs8", - "rand", + "rand_core", + "signature", "subtle", "zeroize", ] [[package]] name = "rust-embed" -version = "6.4.0" +version = "6.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a17e5ac65b318f397182ae94e532da0ba56b88dd1200b774715d36c4943b1c3" +checksum = "1b68543d5527e158213414a92832d2aab11a84d2571a5eb021ebe22c43aab066" dependencies = [ "rust-embed-impl", "rust-embed-utils", @@ -1318,24 +1918,24 @@ dependencies = [ [[package]] name = "rust-embed-impl" -version = "6.2.0" +version = "6.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94e763e24ba2bf0c72bc6be883f967f794a019fafd1b86ba1daff9c91a7edd30" +checksum = "4d4e0f0ced47ded9a68374ac145edd65a6c1fa13a96447b873660b2a568a0fd7" dependencies = [ "proc-macro2", "quote", "rust-embed-utils", - "syn", + "syn 1.0.109", "walkdir", ] [[package]] name = "rust-embed-utils" -version = "7.2.0" +version = "7.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "756feca3afcbb1487a1d01f4ecd94cf8ec98ea074c55a69e7136d29fb6166029" +checksum = "512b0ab6853f7e14e3c8754acb43d6f748bb9ced66aa5915a6553ac8213f7731" dependencies = [ - "sha2 0.9.9", + "sha2", "walkdir", ] @@ -1354,6 +1954,26 @@ dependencies = [ "nom", ] +[[package]] +name = "rustix" +version = "0.37.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85597d61f83914ddeba6a47b3b8ffe7365107221c2e557ed94426489fefb5f77" +dependencies = [ + "bitflags", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "windows-sys 0.48.0", +] + +[[package]] +name = "ryu" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" + [[package]] name = "same-file" version = "1.0.6" @@ -1363,12 +1983,41 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "schannel" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3" +dependencies = [ + "windows-sys 0.42.0", +] + [[package]] name = "scopeguard" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +[[package]] +name = "scratch" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1792db035ce95be60c3f8853017b3999209281c24e2ba5bc8e59bf97a0c590c1" + +[[package]] +name = "sec1" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48518a2b5775ba8ca5b46596aae011caa431e6ce7e4a67ead66d92f08884220e" +dependencies = [ + "base16ct", + "der", + "generic-array", + "pkcs8", + "subtle", + "zeroize", +] + [[package]] name = "secrecy" version = "0.8.0" @@ -1378,6 +2027,29 @@ dependencies = [ "zeroize", ] +[[package]] +name = "security-framework" +version = "2.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a332be01508d814fed64bf28f798a146d73792121129962fdf335bb3c49a4254" +dependencies = [ + "bitflags", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31c9bb296072e961fcbd8853511dd39c2d8be2deb1e17c6860b1d30732b323b4" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "self_cell" version = "0.10.2" @@ -1386,76 +2058,109 @@ checksum = "1ef965a420fe14fdac7dd018862966a4c14094f900e1650bbc71ddd7d580c8af" [[package]] name = "serde" -version = "1.0.136" +version = "1.0.159" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" +checksum = "3c04e8343c3daeec41f58990b9d77068df31209f2af111e059e9fe9646693065" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.136" +version = "1.0.159" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" +checksum = "4c614d17805b093df4b147b51339e7e44bf05ef59fba1e45d83500bcfb4d8585" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.13", ] [[package]] -name = "sha-1" -version = "0.9.8" +name = "serde_json" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" +checksum = "d721eca97ac802aa7777b701877c8004d950fc142651367300d21c1cc0194744" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha1" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" dependencies = [ - "block-buffer 0.9.0", "cfg-if", "cpufeatures", - "digest 0.9.0", - "opaque-debug", + "digest", ] [[package]] name = "sha2" -version = "0.9.9" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" dependencies = [ - "block-buffer 0.9.0", "cfg-if", "cpufeatures", - "digest 0.9.0", - "opaque-debug", + "digest", ] [[package]] -name = "sha2" -version = "0.10.2" +name = "shell-words" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55deaec60f81eefe3cce0dc50bda92d6d8e88f2a27df7c5033b42afeb1ed2676" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest 0.10.3", -] +checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" [[package]] name = "signature" -version = "1.3.2" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2807892cfa58e081aa1f1111391c7a0649d4fa127a4ffbe34bcbfb35a1171a4" +checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" dependencies = [ - "digest 0.9.0", + "digest", "rand_core", ] [[package]] -name = "smallvec" -version = "1.8.0" +name = "slab" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" +checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" + +[[package]] +name = "socket2" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" +dependencies = [ + "libc", + "winapi", +] [[package]] name = "spin" @@ -1465,10 +2170,11 @@ checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" [[package]] name = "spki" -version = "0.4.1" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c01a0c15da1b0b0e1494112e7af814a678fec9bd157881b49beac661e9b6f32" +checksum = "37a5be806ab6f127c3da44b7378837ebf01dadca8510a0e572460216b228bd0e" dependencies = [ + "base64ct", "der", ] @@ -1485,23 +2191,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] -name = "subtle-encoding" -version = "0.5.1" +name = "syn" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dcb1ed7b8330c5eed5441052651dd7a12c75e2ed88f2ec024ae1fa3a5e59945" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ - "zeroize", + "proc-macro2", + "quote", + "unicode-ident", ] [[package]] name = "syn" -version = "1.0.89" +version = "2.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea297be220d52398dcc07ce15a209fce436d361735ac1db700cab3b6cdfb9f54" +checksum = "4c9da457c5285ac1f936ebd076af6dac17a61cfe7826f2076b4d015cf47bc8ec" dependencies = [ "proc-macro2", "quote", - "unicode-xid", + "unicode-ident", ] [[package]] @@ -1512,15 +2220,15 @@ checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", "unicode-xid", ] [[package]] name = "sysinfo" -version = "0.26.3" +version = "0.28.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49086f670c15221b510c3f8c47e04e49714c56820d5ca78e2f58419e9fbb0f1b" +checksum = "b4c2f3ca6693feb29a89724516f016488e9aafc7f37264f898593ee4b942f31b" dependencies = [ "cfg-if", "core-foundation-sys", @@ -1533,82 +2241,209 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.3.0" +version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" +checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998" dependencies = [ "cfg-if", "fastrand", - "libc", - "redox_syscall", - "remove_dir_all", - "winapi", + "redox_syscall 0.3.5", + "rustix", + "windows-sys 0.45.0", ] [[package]] name = "termcolor" -version = "1.1.3" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" dependencies = [ "winapi-util", ] [[package]] -name = "terminal_size" -version = "0.1.17" +name = "test-with" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df" +checksum = "266e80e1c6d4f808d83c5e299b0946971e6043ee8e029c14caa1b43129705c78" dependencies = [ - "libc", - "winapi", + "byte-unit", + "num_cpus", + "ping", + "proc-macro-error", + "proc-macro2", + "quote", + "regex", + "reqwest", + "syn 2.0.13", + "sysinfo", + "users", + "which", ] [[package]] name = "thiserror" -version = "1.0.30" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" +checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.30" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" +checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.13", ] [[package]] name = "time" -version = "0.1.43" +version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" +checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" dependencies = [ "libc", + "wasi 0.10.0+wasi-snapshot-preview1", "winapi", ] [[package]] -name = "tinystr" -version = "0.3.4" +name = "time" +version = "0.3.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29738eedb4388d9ea620eeab9384884fc3f06f586a2eddb56bedc5885126c7c1" +checksum = "cd0cbfecb4d19b5ea75bb31ad904eb5b9fa13f21079c3b92017ebdf4999a5890" +dependencies = [ + "itoa", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" + +[[package]] +name = "time-macros" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd80a657e71da814b8e5d60d3374fc6d35045062245d80224748ae522dd76f36" +dependencies = [ + "time-core", +] + +[[package]] +name = "tinystr" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ac3f5b6856e931e15e07b478e98c8045239829a65f9156d4fa7e7788197a5ef" +dependencies = [ + "displaydoc", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0de47a4eecbe11f498978a9b29d792f0d2692d1dd003650c24c76510e3bc001" +dependencies = [ + "autocfg", + "bytes", + "libc", + "mio", + "num_cpus", + "pin-project-lite", + "socket2", + "windows-sys 0.45.0", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5427d89453009325de0d8f342c9490009f76e999cb7672d77e46267448f7e6b2" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] [[package]] name = "toml" -version = "0.5.9" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" dependencies = [ "serde", ] +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +dependencies = [ + "cfg-if", + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" +dependencies = [ + "once_cell", +] + +[[package]] +name = "try-lock" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" + [[package]] name = "type-map" version = "0.4.0" @@ -1620,60 +2455,114 @@ dependencies = [ [[package]] name = "typenum" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" [[package]] name = "unic-langid" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73328fcd730a030bdb19ddf23e192187a6b01cd98be6d3140622a89129459ce5" +checksum = "398f9ad7239db44fd0f80fe068d12ff22d78354080332a5077dc6f52f14dcf2f" dependencies = [ "unic-langid-impl", ] [[package]] name = "unic-langid-impl" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a4a8eeaf0494862c1404c95ec2f4c33a2acff5076f64314b465e3ddae1b934d" +checksum = "e35bfd2f2b8796545b55d7d3fd3e89a0613f68a0d1c8bc28cb7ff96b411a35ff" dependencies = [ "serde", "tinystr", ] [[package]] -name = "unicode-width" -version = "0.1.9" +name = "unicode-bidi" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" + +[[package]] +name = "unicode-ident" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-width" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" [[package]] name = "unicode-xid" -version = "0.2.2" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" [[package]] name = "universal-hash" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f214e8f697e925001e66ec2c6e37a4ef93f0f78c2eed7814394e10c62025b05" +checksum = "7d3160b73c9a19f7e2939a2fdad446c57c1bbbbf4d919d3213ff1267a580d8b5" dependencies = [ - "generic-array", + "crypto-common", "subtle", ] [[package]] -name = "uuid" -version = "0.8.2" +name = "url" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" +checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "users" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24cc0f6d6f267b73e5a2cadf007ba8f9bc39c6a6f9666f8cf25ea809a153b032" +dependencies = [ + "libc", + "log", +] + +[[package]] +name = "utf8-width" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5190c9442dcdaf0ddd50f37420417d219ae5261bbf5db120d0f9bab996c9cba1" + +[[package]] +name = "uuid" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b55a3fef2a1e3b3a00ce878640918820d3c51081576ac657d23af9fc7928fdb" dependencies = [ "getrandom", ] +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "version_check" version = "0.9.4" @@ -1682,30 +2571,121 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "walkdir" -version = "2.3.2" +version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" +checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698" dependencies = [ "same-file", - "winapi", "winapi-util", ] [[package]] -name = "wasi" -version = "0.10.2+wasi-snapshot-preview1" +name = "want" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" +checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" +dependencies = [ + "log", + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.10.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 1.0.109", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f219e0d211ba40266969f6dbdd90636da12f75bee4fc9d6c23d1260dadb51454" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d" + +[[package]] +name = "web-sys" +version = "0.3.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e33b99f4b23ba3eec1a53ac264e35a755f00e966e0065077d6027c0f575b0b97" +dependencies = [ + "js-sys", + "wasm-bindgen", +] [[package]] name = "which" -version = "4.2.5" +version = "4.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c4fb54e6113b6a8772ee41c3404fb0301ac79604489467e0a9ce1f3e97c24ae" +checksum = "2441c784c52b289a054b7201fc93253e288f094e2f4be9058343127c4226a269" dependencies = [ "either", - "lazy_static", "libc", + "once_cell", ] [[package]] @@ -1740,47 +2720,169 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] -name = "windows-sys" -version = "0.36.1" +name = "windows" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" +checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" dependencies = [ - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_msvc", + "windows-targets 0.48.0", ] [[package]] -name = "windows_aarch64_msvc" -version = "0.36.1" +name = "windows-sys" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.0", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-targets" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +dependencies = [ + "windows_aarch64_gnullvm 0.48.0", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", + "windows_x86_64_gnullvm 0.48.0", + "windows_x86_64_msvc 0.48.0", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" [[package]] name = "windows_i686_gnu" -version = "0.36.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" [[package]] name = "windows_i686_msvc" -version = "0.36.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" [[package]] name = "windows_x86_64_gnu" -version = "0.36.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" [[package]] name = "windows_x86_64_msvc" -version = "0.36.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" + +[[package]] +name = "winreg" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" +dependencies = [ + "winapi", +] [[package]] name = "x509" @@ -1794,12 +2896,12 @@ dependencies = [ [[package]] name = "x509-parser" -version = "0.12.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffc90836a84cb72e6934137b1504d0cae304ef5d83904beb0c8d773bbfe256ed" +checksum = "e0ecbeb7b67ce215e40e3cc7f2ff902f94a223acf44995934763467e7b1febc8" dependencies = [ - "base64", - "chrono", + "asn1-rs", + "base64 0.13.1", "data-encoding", "der-parser", "lazy_static", @@ -1807,20 +2909,22 @@ dependencies = [ "oid-registry", "rusticata-macros", "thiserror", + "time 0.3.20", ] [[package]] name = "yubikey" -version = "0.5.0" +version = "0.8.0-pre.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e82a7de0613c75d93e4330613e24d859cab51770b081fe92f1dae4a1e38d9177" +checksum = "71240be97248417e072ab49076573dbf96e886478453497e02b49968c0273790" dependencies = [ + "base16ct", "chrono", "cookie-factory", "der-parser", "des", "elliptic-curve", - "hmac 0.11.0", + "hmac", "log", "nom", "num-bigint-dig", @@ -1833,10 +2937,9 @@ dependencies = [ "rand_core", "rsa", "secrecy", - "sha-1", - "sha2 0.9.9", + "sha1", + "sha2", "subtle", - "subtle-encoding", "uuid", "x509", "x509-parser", @@ -1845,21 +2948,6 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.4.3" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d68d9dcec5f9b43a30d38c49f91dfedfaac384cb8f085faca366c26207dd1619" -dependencies = [ - "zeroize_derive", -] - -[[package]] -name = "zeroize_derive" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f8f187641dad4f680d25c4bfc4225b418165984179f26ca76ec4fb6441d3a17" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "synstructure", -] +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" diff --git a/Cargo.toml b/Cargo.toml index d56f949..95067e5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "age-plugin-yubikey" description = "YubiKey plugin for age clients" -version = "0.3.4" +version = "0.4.0" authors = ["Jack Grigg "] repository = "https://github.com/str4d/age-plugin-yubikey" readme = "README.md" @@ -9,7 +9,7 @@ keywords = ["age", "cli", "encryption", "yubikey"] categories = ["command-line-utilities", "cryptography"] license = "MIT OR Apache-2.0" edition = "2021" -rust-version = "1.56" # MSRV +rust-version = "1.65" # MSRV [package.metadata.deb] extended-description = """\ @@ -22,24 +22,24 @@ assets = [ ] [dependencies] -age-core = "0.8" -age-plugin = "0.3" -base64 = "0.13" -bech32 = "0.8" +age-core = "0.9" +age-plugin = "0.4" +base64 = "0.21" +bech32 = "0.9" console = { version = "0.15", default-features = false } -dialoguer = { version = "0.9", default-features = false, features = ["password"] } -env_logger = "0.9" +dialoguer = { version = "0.10", default-features = false, features = ["password"] } +env_logger = "0.10" gumdrop = "0.8" hex = "0.4" log = "0.4" -p256 = { version = "0.9", features = ["ecdh"] } +p256 = { version = "0.13", features = ["ecdh"] } pcsc = "2.4" rand = "0.8" -sha2 = "0.9" +sha2 = "0.10" which = "4.1" x509 = "0.2" -x509-parser = "0.12" -yubikey = { version = "0.5", features = ["untested"] } +x509-parser = "0.14" +yubikey = { version = "=0.8.0-pre.0", features = ["untested"] } # Translations i18n-embed = { version = "0.13", features = ["desktop-requester", "fluent-system"] } @@ -48,8 +48,11 @@ lazy_static = "1" rust-embed = "6" # GnuPG coexistence -sysinfo = ">=0.26, <0.26.4" +sysinfo = "0.28" [dev-dependencies] flate2 = "1" man = "0.3" +tempfile = "3" +test-with = "0.9" +which = "4" diff --git a/README.md b/README.md index 1227ad3..152066a 100644 --- a/README.md +++ b/README.md @@ -6,26 +6,34 @@ which enables files to be encrypted to age identities stored on YubiKeys. ## Installation +| Environment | CLI command | +|-------------|-------------| +| Cargo (Rust 1.65+) | `cargo install age-plugin-yubikey` | +| Homebrew (macOS or Linux) | `brew install age-plugin-yubikey` | + 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.56+ 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. ### Linux, BSD, etc. On non-Windows, non-macOS systems, you need to ensure that the `pcscd` service -is installed and running. On Debian or Ubuntu, you can do this with: +is installed and running. -``` -$ sudo apt-get install pcscd -``` +| Environment | CLI command | +|-------------|-------------| +| Debian or Ubuntu | `sudo apt-get install pcscd` | +| OpenBSD | As ```root``` do:
`pkg_add pcsc-lite ccid`
`rcctl enable pcscd`
`rcctl start pcscd` | +| FreeBSD | As ```root``` do:
`pkg install pcsc-lite libccid`
`service pcscd enable`
`service pcscd start` | + +When installing via Cargo, you also need to ensure that the development headers +for the `pcsc-lite` library are available, so that the `pcsc-sys` crate can be +compiled. + +| Environment | CLI command | +|-------------|-------------| +| Debian or Ubuntu | `sudo apt-get install libpcsclite-dev` | ### Windows Subsystem for Linux (WSL) @@ -44,7 +52,12 @@ YubiKey: ## Configuration -There are two ways to configure a YubiKey as an `age` identity. You can run the +`age-plugin-yubikey` identities have two parts: +- The secret key material, which is stored inside a YubiKey. +- An age identity file, which contains information that an age client can use to + figure out which YubiKey secret key should be used. + +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: @@ -70,6 +83,14 @@ Once an identity has been created, you can regenerate it later: $ age-plugin-yubikey --identity [--serial SERIAL] --slot SLOT ``` +To use the identity with an age client, it needs to be stored in a file. When +using the above programmatic flags, you can do this by redirecting standard +output to a file. On a Unix system like macOS or Ubuntu: + +``` +$ age-plugin-yubikey --identity --slot SLOT > yubikey-identity.txt +``` + ## Usage The age recipients contained in all connected YubiKeys can be printed on @@ -94,13 +115,27 @@ age client as normal (e.g. `rage -d -i yubikey-identity.txt`). ### 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. +It does however attempt to preserve the PIN cache by not soft-resetting the +YubiKey after a decryption or read-only operation, which enables YubiKey +identities configured with a PIN policy of `once` to not prompt for the PIN on +every decryption. **This does not work for YubiKey 4 series.** -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. +The session that corresponds to the `once` policy can be ended in several ways, +not all of which are necessarily intuitive: + +- Unplugging the YubiKey (the obvious way). +- Using a different applet (e.g. FIDO2). This causes the PIV applet to be closed + which clears its state. + - This is why the YubiKey 4 series does not support PIN cache preservation: + their serial can only be obtained by switching to the OTP applet. +- Generating a new age identity via `age-plugin-yubikey --generate` or the CLI + interface. This is to avoid leaving the YubiKey authenticated with the + management key. + +If the current PIN UX proves to be insufficient, 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 diff --git a/i18n/en-US/age_plugin_yubikey.ftl b/i18n/en-US/age_plugin_yubikey.ftl index a84e19c..42e115d 100644 --- a/i18n/en-US/age_plugin_yubikey.ftl +++ b/i18n/en-US/age_plugin_yubikey.ftl @@ -76,6 +76,14 @@ cli-setup-name-identity = 📛 Name this identity cli-setup-select-pin-policy = 🔤 Select a PIN policy cli-setup-select-touch-policy = 👆 Select a touch policy +cli-setup-yk4-pin-policy = + ⚠️ Your {-yubikey} is a {-yubikey} 4 series. With ephemeral applications like + {-age-plugin-yubikey}, a PIN policy of "Once" behaves like a PIN policy of + "Always", and your PIN will be requested for every decryption. However, you + might still benefit from a PIN policy of "Once" in long-running applications + like agents. +cli-setup-yk4-pin-policy-confirm = Use PIN policy of "Once" with {-yubikey} 4? + cli-setup-generate-new = Generate new identity in slot {$slot_index}? cli-setup-use-existing = Use existing identity in slot {$slot_index}? @@ -112,6 +120,7 @@ cli-setup-finished = open-yk-with-serial = ⏳ Please insert the {-yubikey} with serial {$yubikey_serial}. open-yk-without-serial = ⏳ Please insert the {-yubikey}. warn-yk-not-connected = Ignoring {$yubikey_name}: not connected +warn-yk-missing-applet = Ignoring {$yubikey_name}: Missing {$applet_name} applet print-recipient = Recipient: {$recipient} @@ -146,6 +155,12 @@ mgr-changing-mgmt-key-error = {" "}{$management_key} mgr-changing-mgmt-key-success = Success! +## YubiKey keygen + +builder-gen-key = 🎲 Generating key... +builder-gen-cert = 🔏 Generating certificate... +builder-touch-yk = 👆 Please touch the {-yubikey} + ## Plugin usage plugin-err-invalid-recipient = Invalid recipient @@ -172,8 +187,12 @@ plugin-err-pin-required = A PIN is required for {-yubikey} with serial {$yub ## Errors +err-mgmt-key-auth = Failed to authenticate with the PIN-protected management key. +rec-mgmt-key-auth = + Check whether your management key is using the TDES algorithm. + AES is not supported yet: {$aes_url} err-custom-mgmt-key = Custom unprotected non-TDES management keys are not supported. -rec-custom-mgmt-key = +rec-change-mgmt-key = You can use the {-yubikey} Manager CLI to change to a protected management key: {" "}{$cmd} @@ -205,16 +224,27 @@ rec-yk-no-service-pcscd = If you are on Debian or Ubuntu, you can install it with: {" "}{$apt} +rec-yk-no-service-pcscd-bsd = + You can install and run it as root with: + {" "}{$pkg} + {" "}{$service_enable} + {" "}{$service_start} + err-yk-no-service-win = The Smart Cards for Windows service is not running. rec-yk-no-service-win = See this troubleshooting guide for more help: {" "}{$url} err-yk-not-found = Please insert the {-yubikey} you want to set up -err-yk-wrong-pin = Invalid PIN ({$tries} tries remaining before it is blocked) err-yk-general = Error while communicating with {-yubikey}: {$err} err-yk-general-cause = Cause: {$inner_err} +err-yk-wrong-pin = Invalid {$pin_kind} ({$tries -> + [one] {$tries} try remaining + *[other] {$tries} tries remaining +} before it is blocked) +err-yk-pin-locked = {$pin_kind} locked + err-ux-A = Did this not do what you expected? Could an error be more useful? err-ux-B = Tell us # Put (len(A) - len(B) - 46) spaces here. diff --git a/rust-toolchain b/rust-toolchain deleted file mode 100644 index 47d5636..0000000 --- a/rust-toolchain +++ /dev/null @@ -1 +0,0 @@ -1.56.0 \ No newline at end of file diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 0000000..ce69938 --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,3 @@ +[toolchain] +channel = "1.65.0" +components = ["clippy", "rustfmt"] diff --git a/src/builder.rs b/src/builder.rs index 72c91d7..653789e 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -1,3 +1,4 @@ +use dialoguer::Password; use rand::{rngs::OsRng, RngCore}; use x509::RelativeDistinguishedName; use yubikey::{ @@ -8,6 +9,7 @@ use yubikey::{ use crate::{ error::Error, + fl, key::{self, Stub}, p256::Recipient, util::{Metadata, POLICY_EXTENSION_OID}, @@ -86,17 +88,13 @@ impl IdentityBuilder { let pin_policy = self.pin_policy.unwrap_or(DEFAULT_PIN_POLICY); let touch_policy = self.touch_policy.unwrap_or(DEFAULT_TOUCH_POLICY); + eprintln!("{}", fl!("builder-gen-key")); + // No need to ask for users to enter their PIN if the PIN policy requires it, // because here we _always_ require them to enter their PIN in order to access the // protected management key (which is necessary in order to generate identities). key::manage(yubikey)?; - if let TouchPolicy::Never = touch_policy { - // No need to touch YubiKey - } else { - eprintln!("👆 Please touch the YubiKey"); - } - // Generate a new key in the selected slot. let generated = yubikey_generate( yubikey, @@ -109,6 +107,9 @@ impl IdentityBuilder { let recipient = Recipient::from_spki(&generated).expect("YubiKey generates a valid pubkey"); let stub = Stub::new(yubikey.serial(), slot, &recipient); + eprintln!(); + eprintln!("{}", fl!("builder-gen-cert")); + // Pick a random serial for the new self-signed certificate. let mut serial = [0; 20]; OsRng.fill_bytes(&mut serial); @@ -117,6 +118,23 @@ impl IdentityBuilder { .name .unwrap_or(format!("age identity {}", hex::encode(stub.tag))); + if let PinPolicy::Always = pin_policy { + // We need to enter the PIN again. + let pin = Password::new() + .with_prompt(fl!( + "plugin-enter-pin", + yubikey_serial = yubikey.serial().to_string(), + )) + .report(true) + .interact()?; + yubikey.verify_pin(pin.as_bytes())?; + } + if let TouchPolicy::Never = touch_policy { + // No need to touch YubiKey + } else { + eprintln!("{}", fl!("builder-touch-yk")); + } + let cert = Certificate::generate_self_signed( yubikey, SlotId::Retired(slot), diff --git a/src/error.rs b/src/error.rs index 9b2ff2c..1674ffa 100644 --- a/src/error.rs +++ b/src/error.rs @@ -21,14 +21,17 @@ pub enum Error { InvalidSlot(u8), InvalidTouchPolicy(String), Io(io::Error), + ManagementKeyAuth, MultipleCommands, MultipleYubiKeys, NoEmptySlots(Serial), NoMatchingSerial(Serial), + PukLocked, SlotHasNoIdentity(RetiredSlotId), SlotIsNotEmpty(RetiredSlotId), TimedOut, UseListForSingleSlot, + WrongPuk(u8), YubiKey(yubikey::Error), } @@ -48,12 +51,19 @@ impl From for Error { // manually to provide the error output we want. impl fmt::Debug for Error { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + const CHANGE_MGMT_KEY_CMD: &str = + "ykman piv access change-management-key -a TDES --protect"; + const CHANGE_MGMT_KEY_URL: &str = "https://developers.yubico.com/yubikey-manager/"; + match self { Error::CustomManagementKey => { wlnfl!(f, "err-custom-mgmt-key")?; - let cmd = "ykman piv access change-management-key --protect"; - let url = "https://developers.yubico.com/yubikey-manager/"; - wlnfl!(f, "rec-custom-mgmt-key", cmd = cmd, url = url)?; + wlnfl!( + f, + "rec-change-mgmt-key", + cmd = CHANGE_MGMT_KEY_CMD, + url = CHANGE_MGMT_KEY_URL + )?; } Error::InvalidFlagCommand(flag, command) => wlnfl!( f, @@ -76,6 +86,17 @@ impl fmt::Debug for Error { expected = "always, cached, never", )?, Error::Io(e) => wlnfl!(f, "err-io", err = e.to_string())?, + Error::ManagementKeyAuth => { + let aes_url = "https://github.com/str4d/age-plugin-yubikey/issues/92"; + wlnfl!(f, "err-mgmt-key-auth")?; + wlnfl!(f, "rec-mgmt-key-auth", aes_url = aes_url)?; + wlnfl!( + f, + "rec-change-mgmt-key", + cmd = CHANGE_MGMT_KEY_CMD, + url = CHANGE_MGMT_KEY_URL + )?; + } Error::MultipleCommands => wlnfl!(f, "err-multiple-commands")?, Error::MultipleYubiKeys => wlnfl!(f, "err-multiple-yubikeys")?, Error::NoEmptySlots(serial) => { @@ -84,6 +105,7 @@ impl fmt::Debug for Error { Error::NoMatchingSerial(serial) => { wlnfl!(f, "err-no-matching-serial", serial = serial.to_string())? } + Error::PukLocked => wlnfl!(f, "err-yk-pin-locked", pin_kind = "PUK")?, Error::SlotHasNoIdentity(slot) => { wlnfl!(f, "err-slot-has-no-identity", slot = slot_to_ui(slot))? } @@ -92,6 +114,9 @@ impl fmt::Debug for Error { } Error::TimedOut => wlnfl!(f, "err-timed-out")?, Error::UseListForSingleSlot => wlnfl!(f, "err-use-list-for-single")?, + Error::WrongPuk(tries) => { + wlnfl!(f, "err-yk-wrong-pin", pin_kind = "PUK", tries = tries)? + } Error::YubiKey(e) => match e { yubikey::Error::NotFound => wlnfl!(f, "err-yk-not-found")?, yubikey::Error::PcscError { @@ -105,13 +130,40 @@ impl fmt::Debug for Error { wlnfl!(f, "err-yk-no-service-macos")?; let url = "https://apple.stackexchange.com/a/438198"; wlnfl!(f, "rec-yk-no-service-macos", url = url)?; + } else if cfg!(target_os = "openbsd") { + wlnfl!(f, "err-yk-no-service-pcscd")?; + let pkg = "pkg_add pcsc-lite ccid"; + let service_enable = "rcctl enable pcscd"; + let service_start = "rcctl start pcscd"; + wlnfl!( + f, + "rec-yk-no-service-pcscd-bsd", + pkg = pkg, + service_enable = service_enable, + service_start = service_start + )?; + } else if cfg!(target_os = "freebsd") { + wlnfl!(f, "err-yk-no-service-pcscd")?; + let pkg = "pkg install pcsc-lite libccid"; + let service_enable = "service pcscd enable"; + let service_start = "service pcscd start"; + wlnfl!( + f, + "rec-yk-no-service-pcscd-bsd", + pkg = pkg, + service_enable = service_enable, + service_start = service_start + )?; } else { wlnfl!(f, "err-yk-no-service-pcscd")?; let apt = "sudo apt-get install pcscd"; wlnfl!(f, "rec-yk-no-service-pcscd", apt = apt)?; } } - yubikey::Error::WrongPin { tries } => wlnfl!(f, "err-yk-wrong-pin", tries = tries)?, + yubikey::Error::PinLocked => wlnfl!(f, "err-yk-pin-locked", pin_kind = "PIN")?, + yubikey::Error::WrongPin { tries } => { + wlnfl!(f, "err-yk-wrong-pin", pin_kind = "PIN", tries = tries)? + } e => { wlnfl!(f, "err-yk-general", err = e.to_string())?; use std::error::Error; diff --git a/src/format.rs b/src/format.rs index 5128105..fb9ac4c 100644 --- a/src/format.rs +++ b/src/format.rs @@ -1,10 +1,15 @@ use age_core::{ format::{FileKey, Stanza}, - primitives::{aead_encrypt, hkdf}, + primitives::aead_encrypt, secrecy::ExposeSecret, }; -use p256::{ecdh::EphemeralSecret, elliptic_curve::sec1::ToEncodedPoint}; +use base64::{prelude::BASE64_STANDARD_NO_PAD, Engine}; +use p256::{ + ecdh::EphemeralSecret, + elliptic_curve::sec1::{FromEncodedPoint, ToEncodedPoint}, +}; use rand::rngs::OsRng; +use sha2::Sha256; use crate::{p256::Recipient, STANZA_TAG}; @@ -22,8 +27,12 @@ pub(crate) struct EphemeralKeyBytes(p256::EncodedPoint); impl EphemeralKeyBytes { fn from_bytes(bytes: [u8; EPK_BYTES]) -> Option { - let encoded = p256::EncodedPoint::from_bytes(&bytes).ok()?; - if encoded.is_compressed() && encoded.decompress().is_some() { + let encoded = p256::EncodedPoint::from_bytes(bytes).ok()?; + if encoded.is_compressed() + && p256::PublicKey::from_encoded_point(&encoded) + .is_some() + .into() + { Some(EphemeralKeyBytes(encoded)) } else { None @@ -39,9 +48,9 @@ impl EphemeralKeyBytes { } pub(crate) fn decompress(&self) -> p256::EncodedPoint { - self.0 - .decompress() - .expect("EphemeralKeyBytes is a valid compressed encoding by construction") + // EphemeralKeyBytes is a valid compressed encoding by construction. + let p = p256::PublicKey::from_encoded_point(&self.0).unwrap(); + p.to_encoded_point(false) } } @@ -57,8 +66,8 @@ impl From for Stanza { Stanza { tag: STANZA_TAG.to_owned(), args: vec![ - base64::encode_config(&r.tag, base64::STANDARD_NO_PAD), - base64::encode_config(r.epk_bytes.as_bytes(), base64::STANDARD_NO_PAD), + BASE64_STANDARD_NO_PAD.encode(r.tag), + BASE64_STANDARD_NO_PAD.encode(r.epk_bytes.as_bytes()), ], body: r.encrypted_file_key.to_vec(), } @@ -76,9 +85,10 @@ impl RecipientLine { return None; } - base64::decode_config_slice(arg, base64::STANDARD_NO_PAD, buf.as_mut()) + BASE64_STANDARD_NO_PAD + .decode_slice_unchecked(arg, buf.as_mut()) .ok() - .map(|_| buf) + .and_then(|len| (len == buf.as_mut().len()).then_some(buf)) } let (tag, epk_bytes) = match &s.args[..] { @@ -101,7 +111,7 @@ impl RecipientLine { } pub(crate) fn wrap_file_key(file_key: &FileKey, pk: &Recipient) -> Self { - let esk = EphemeralSecret::random(OsRng); + let esk = EphemeralSecret::random(&mut OsRng); let epk = esk.public_key(); let epk_bytes = EphemeralKeyBytes::from_public_key(&epk); @@ -111,7 +121,14 @@ impl RecipientLine { salt.extend_from_slice(epk_bytes.as_bytes()); salt.extend_from_slice(pk.to_encoded().as_bytes()); - let enc_key = hkdf(&salt, STANZA_KEY_LABEL, shared_secret.as_bytes()); + let enc_key = { + let mut okm = [0; 32]; + shared_secret + .extract::(Some(&salt)) + .expand(STANZA_KEY_LABEL, &mut okm) + .expect("okm is the correct length"); + okm + }; let encrypted_file_key = { let mut key = [0; ENCRYPTED_FILE_KEY_BYTES]; diff --git a/src/key.rs b/src/key.rs index 294f185..d3e7b55 100644 --- a/src/key.rs +++ b/src/key.rs @@ -53,7 +53,24 @@ pub(crate) fn filter_connected(reader: &Reader) -> bool { ); false } - _ => true, + Err(yubikey::Error::AppletNotFound { applet_name }) => { + warn!( + "{}", + fl!( + "warn-yk-missing-applet", + yubikey_name = reader.name(), + applet_name = applet_name, + ), + ); + false + } + Err(_) => true, + Ok(yubikey) => { + // We only connected as a side-effect of confirming that we can connect, so + // avoid resetting the YubiKey. + disconnect_without_reset(yubikey); + true + } } } @@ -185,6 +202,9 @@ fn open_by_serial(serial: Serial) -> Result { if serial == yubikey.serial() { return Ok(yubikey); + } else { + // We didn't want this YubiKey; don't reset it. + disconnect_without_reset(yubikey); } } @@ -241,6 +261,23 @@ pub(crate) fn open(serial: Option) -> Result { Ok(yubikey) } +/// Disconnect from the YubiKey without resetting it. +/// +/// This can be used to preserve the YubiKey's PIN and touch caches. There are two cases +/// where we want to do this: +/// +/// - We connected to this YubiKey in a read-only context, so we have not made any changes +/// to the YubiKey's state. However, we might have asked an agent to release the YubiKey +/// in `key::open_connection`, and we want to allow any state it may have left behind +/// (such as cached PINs or touches) to persist beyond our execution, for usability. +/// - We opened this connection in a decryption context, so the only changes to the +/// YubiKey's state were to potentially cache the PIN and/or touch (depending on the +/// policies of the slot). We want to allow these to persist beyond our execution, for +/// usability. +pub(crate) fn disconnect_without_reset(yubikey: YubiKey) { + let _ = yubikey.disconnect(pcsc::Disposition::LeaveCard); +} + fn request_pin( mut prompt: impl FnMut(Option) -> io::Result>, serial: Serial, @@ -277,6 +314,7 @@ pub(crate) fn manage(yubikey: &mut YubiKey) -> Result<(), Error> { yubikey_serial = yubikey.serial().to_string(), default_pin = DEFAULT_PIN, )) + .report(true) .interact()?; yubikey.verify_pin(pin.as_bytes())?; @@ -310,34 +348,45 @@ pub(crate) fn manage(yubikey: &mut YubiKey) -> Result<(), Error> { } }; let new_pin = new_pin.expose_secret(); - yubikey.change_puk(current_puk.as_bytes(), new_pin.as_bytes())?; + yubikey + .change_puk(current_puk.as_bytes(), new_pin.as_bytes()) + .map_err(|e| match e { + yubikey::Error::PinLocked => Error::PukLocked, + yubikey::Error::WrongPin { tries } => Error::WrongPuk(tries), + _ => Error::YubiKey(e), + })?; yubikey.change_pin(pin.as_bytes(), new_pin.as_bytes())?; } - if let Ok(mgm_key) = MgmKey::get_protected(yubikey) { - yubikey.authenticate(mgm_key)?; - } else { - // Try to authenticate with the default management key. - yubikey - .authenticate(MgmKey::default()) - .map_err(|_| Error::CustomManagementKey)?; + match MgmKey::get_protected(yubikey) { + Ok(mgm_key) => yubikey.authenticate(mgm_key).map_err(|e| match e { + yubikey::Error::AuthenticationError => Error::ManagementKeyAuth, + _ => e.into(), + })?, + Err(yubikey::Error::AuthenticationError) => Err(Error::ManagementKeyAuth)?, + _ => { + // Try to authenticate with the default management key. + yubikey + .authenticate(MgmKey::default()) + .map_err(|_| Error::CustomManagementKey)?; - // Migrate to a PIN-protected management key. - let mgm_key = MgmKey::generate(); - eprintln!(); - eprintln!("{}", fl!("mgr-changing-mgmt-key")); - eprint!("... "); - mgm_key.set_protected(yubikey).map_err(|e| { - eprintln!( - "{}", - fl!( - "mgr-changing-mgmt-key-error", - management_key = hex::encode(mgm_key.as_ref()), - ) - ); - e - })?; - eprintln!("{}", fl!("mgr-changing-mgmt-key-success")); + // Migrate to a PIN-protected management key. + let mgm_key = MgmKey::generate(); + eprintln!(); + eprintln!("{}", fl!("mgr-changing-mgmt-key")); + eprint!("... "); + mgm_key.set_protected(yubikey).map_err(|e| { + eprintln!( + "{}", + fl!( + "mgr-changing-mgmt-key-error", + management_key = hex::encode(mgm_key.as_ref()), + ) + ); + e + })?; + eprintln!("{}", fl!("mgr-changing-mgmt-key-success")); + } } Ok(()) @@ -642,13 +691,13 @@ impl Connection { metadata => metadata, }; } - if let Some(PinPolicy::Never) = self.cached_metadata.as_ref().and_then(|m| m.pin_policy) { - return Ok(Ok(())); + match self.cached_metadata.as_ref().and_then(|m| m.pin_policy) { + Some(PinPolicy::Never) => return Ok(Ok(())), + Some(PinPolicy::Once) if self.yubikey.verify_pin(&[]).is_ok() => return Ok(Ok(())), + _ => (), } // The policy requires a PIN, so request it. - // Note that we can't distinguish between PinPolicy::Once and PinPolicy::Always - // because this plugin is ephemeral, so we always request the PIN. let pin = match request_pin( |prev_error| { callbacks.request_secret(&format!( @@ -732,6 +781,13 @@ impl Connection { Err(_) => Err(()), } } + + /// Close this connection without resetting the YubiKey. + /// + /// This can be used to preserve the YubiKey's PIN and touch caches. + pub(crate) fn disconnect_without_reset(self) { + disconnect_without_reset(self.yubikey); + } } #[cfg(test)] diff --git a/src/main.rs b/src/main.rs index 5687a2a..757cab6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -181,6 +181,13 @@ fn generate(flags: PluginFlags) -> Result<(), Error> { util::print_identity(stub, recipient, metadata); + // We have written to the YubiKey, which means we've authenticated with the management + // key. Out of an abundance of caution, we let the YubiKey be reset on disconnect, + // which will clear its PIN and touch caches. This has as small negative UX effect, + // but identity generation is a relatively infrequent occurrence, and users are more + // likely to see their cached PINs reset due to switching applets (e.g. from PIV to + // FIDO2). + Ok(()) } @@ -200,6 +207,8 @@ fn print_single( printer(stub, recipient, metadata); + key::disconnect_without_reset(yubikey); + Ok(()) } @@ -233,6 +242,8 @@ fn print_multiple( println!(); } println!(); + + key::disconnect_without_reset(yubikey); } if printed > 1 { eprintln!("{}", fl!("printed-multiple", kind = kind, count = printed)); @@ -286,7 +297,7 @@ fn list(flags: PluginFlags, all: bool) -> Result<(), Error> { all, |_, recipient, metadata| { println!("{}", metadata); - println!("{}", recipient.to_string()); + println!("{}", recipient); }, ) } @@ -360,11 +371,13 @@ fn main() -> Result<(), Error> { .iter() .map(|reader| { key::open_connection(reader).map(|yk| { - fl!( + let name = fl!( "cli-setup-yk-name", yubikey_name = reader.name(), yubikey_serial = yk.serial().to_string(), - ) + ); + key::disconnect_without_reset(yk); + name }) }) .collect::, _>>()?; @@ -372,6 +385,7 @@ fn main() -> Result<(), Error> { .with_prompt(fl!("cli-setup-select-yk")) .items(&reader_names) .default(0) + .report(true) .interact_opt()? { Some(yk) => readers_list[yk].open()?, @@ -393,7 +407,11 @@ fn main() -> Result<(), Error> { x509_parser::parse_x509_certificate(key.certificate().as_ref()) .unwrap(); let (name, _) = util::extract_name(&cert, true).unwrap(); - let created = cert.validity().not_before.to_rfc2822(); + let created = cert + .validity() + .not_before + .to_rfc2822() + .unwrap_or_else(|e| format!("Invalid date: {}", e)); format!("{}, created: {}", name, created) }) @@ -426,6 +444,7 @@ fn main() -> Result<(), Error> { .with_prompt(fl!("cli-setup-select-slot")) .items(&slots) .default(0) + .report(true) .interact_opt()? { Some(slot) => { @@ -443,6 +462,7 @@ fn main() -> Result<(), Error> { if Confirm::new() .with_prompt(fl!("cli-setup-use-existing", slot_index = slot_index)) + .report(true) .interact()? { let stub = key::Stub::new(yubikey.serial(), slot, &recipient); @@ -450,8 +470,10 @@ fn main() -> Result<(), Error> { util::Metadata::extract(&mut yubikey, slot, key.certificate(), true) .unwrap(); + key::disconnect_without_reset(yubikey); ((stub, recipient, metadata), false) } else { + key::disconnect_without_reset(yubikey); return Ok(()); } } else { @@ -462,30 +484,57 @@ fn main() -> Result<(), Error> { flags.name.as_deref().unwrap_or("age identity TAG_HEX") )) .allow_empty(true) + .report(true) .interact_text()?; - let pin_policy = match Select::new() - .with_prompt(fl!("cli-setup-select-pin-policy")) - .items(&[ - fl!("pin-policy-always"), - fl!("pin-policy-once"), - fl!("pin-policy-never"), - ]) - .default( - [PinPolicy::Always, PinPolicy::Once, PinPolicy::Never] - .iter() - .position(|p| { - p == &flags.pin_policy.unwrap_or(builder::DEFAULT_PIN_POLICY) - }) - .unwrap(), - ) - .interact_opt()? - { - Some(0) => PinPolicy::Always, - Some(1) => PinPolicy::Once, - Some(2) => PinPolicy::Never, - Some(_) => unreachable!(), - None => return Ok(()), + let mut displayed_yk4_warning = false; + let pin_policy = loop { + let pin_policy = match Select::new() + .with_prompt(fl!("cli-setup-select-pin-policy")) + .items(&[ + fl!("pin-policy-always"), + fl!("pin-policy-once"), + fl!("pin-policy-never"), + ]) + .default( + [PinPolicy::Always, PinPolicy::Once, PinPolicy::Never] + .iter() + .position(|p| { + p == &flags.pin_policy.unwrap_or(builder::DEFAULT_PIN_POLICY) + }) + .unwrap(), + ) + .report(true) + .interact_opt()? + { + Some(0) => PinPolicy::Always, + Some(1) => PinPolicy::Once, + Some(2) => PinPolicy::Never, + Some(_) => unreachable!(), + None => return Ok(()), + }; + + // We can't preserve the PIN cache for YubiKey 4 series, because to + // retrieve the serial we switch to the OTP applet. + match (pin_policy, yubikey.version().major) { + (PinPolicy::Once, 4) => { + if !displayed_yk4_warning { + eprintln!(); + eprintln!("{}", fl!("cli-setup-yk4-pin-policy")); + eprintln!(); + displayed_yk4_warning = true; + } + + if Confirm::new() + .with_prompt(fl!("cli-setup-yk4-pin-policy-confirm")) + .report(true) + .interact()? + { + break pin_policy; + } + } + _ => break pin_policy, + } }; let touch_policy = match Select::new() @@ -503,6 +552,7 @@ fn main() -> Result<(), Error> { }) .unwrap(), ) + .report(true) .interact_opt()? { Some(0) => TouchPolicy::Always, @@ -514,6 +564,7 @@ fn main() -> Result<(), Error> { if Confirm::new() .with_prompt(fl!("cli-setup-generate-new", slot_index = slot_index)) + .report(true) .interact()? { eprintln!(); @@ -529,6 +580,7 @@ fn main() -> Result<(), Error> { true, ) } else { + key::disconnect_without_reset(yubikey); return Ok(()); } } @@ -541,6 +593,7 @@ fn main() -> Result<(), Error> { "age-yubikey-identity-{}.txt", hex::encode(stub.tag) )) + .report(true) .interact_text()?; let mut file = match OpenOptions::new() @@ -552,6 +605,7 @@ fn main() -> Result<(), Error> { Err(e) if e.kind() == io::ErrorKind::AlreadyExists => { if Confirm::new() .with_prompt(fl!("cli-setup-identity-file-exists")) + .report(true) .interact()? { File::create(&file_name)? diff --git a/src/p256.rs b/src/p256.rs index 1eeecad..1f4c607 100644 --- a/src/p256.rs +++ b/src/p256.rs @@ -60,7 +60,7 @@ impl Recipient { /// This accepts both compressed (as used by the plugin) and uncompressed (as used in /// the YubiKey certificate) encodings. fn from_encoded(encoded: &p256::EncodedPoint) -> Option { - p256::PublicKey::from_encoded_point(encoded).map(Recipient) + Option::from(p256::PublicKey::from_encoded_point(encoded)).map(Recipient) } /// Returns the compressed SEC-1 encoding of this recipient. diff --git a/src/plugin.rs b/src/plugin.rs index e29edf4..c0cd18b 100644 --- a/src/plugin.rs +++ b/src/plugin.rs @@ -249,6 +249,8 @@ impl IdentityPluginV1 for IdentityPlugin { } } } + + conn.disconnect_without_reset(); } Ok(file_keys) } diff --git a/src/util.rs b/src/util.rs index f907c5e..bf57573 100644 --- a/src/util.rs +++ b/src/util.rs @@ -122,7 +122,10 @@ impl Metadata { // https://developers.yubico.com/PIV/Introduction/PIV_attestation.html let policies = |c: &X509Certificate| { c.tbs_certificate - .find_extension(&Oid::from(POLICY_EXTENSION_OID).unwrap()) + .get_extension_unique(&Oid::from(POLICY_EXTENSION_OID).unwrap()) + // If the extension is duplicated, we assume it is invalid. + .ok() + .flatten() // If the encoded extension doesn't have 2 bytes, we assume it is invalid. .filter(|policy| policy.value.len() >= 2) .map(|policy| { @@ -170,7 +173,11 @@ impl Metadata { serial: yubikey.serial(), slot, name, - created: cert.validity().not_before.to_rfc2822(), + created: cert + .validity() + .not_before + .to_rfc2822() + .unwrap_or_else(|e| format!("Invalid date: {}", e)), pin_policy, touch_policy, }) diff --git a/tests/integration.rs b/tests/integration.rs new file mode 100644 index 0000000..284cc6c --- /dev/null +++ b/tests/integration.rs @@ -0,0 +1,125 @@ +use std::env; +use std::io::Write; +use std::path::Path; +use std::process::{Command, Stdio}; + +const PLUGIN_BIN: &str = env!("CARGO_BIN_EXE_age-plugin-yubikey"); + +#[test_with::env(YUBIKEY_SERIAL, YUBIKEY_SLOT)] +#[cfg_attr(all(unix, not(target_os = "macos")), test_with::executable(pcscd))] +#[test] +fn recipient_and_identity_match() { + let recipient = Command::new(PLUGIN_BIN) + .arg("--list") + .arg("--serial") + .arg(env::var("YUBIKEY_SERIAL").unwrap()) + .arg("--slot") + .arg(env::var("YUBIKEY_SLOT").unwrap()) + .output() + .unwrap(); + assert_eq!(recipient.status.code(), Some(0)); + + let identity = Command::new(PLUGIN_BIN) + .arg("--identity") + .arg("--serial") + .arg(env::var("YUBIKEY_SERIAL").unwrap()) + .arg("--slot") + .arg(env::var("YUBIKEY_SLOT").unwrap()) + .output() + .unwrap(); + assert_eq!(identity.status.code(), Some(0)); + + let recipient_file = String::from_utf8_lossy(&recipient.stdout); + let recipient = recipient_file.lines().last().unwrap(); + let identity = String::from_utf8_lossy(&identity.stdout); + assert!(identity.contains(recipient)); +} + +#[test_with::executable(rage)] +#[test] +fn plugin_encrypt() { + let enc_file = tempfile::NamedTempFile::new_in(env!("CARGO_TARGET_TMPDIR")).unwrap(); + + let mut process = Command::new(which::which("rage").unwrap()) + .arg("-r") + .arg("age1yubikey1q2w7u3vpya839jxxuq8g0sedh3d740d4xvn639sqhr95ejj8vu3hyfumptt") + .arg("-o") + .arg(enc_file.path()) + .stdin(Stdio::piped()) + .env("PATH", Path::new(PLUGIN_BIN).parent().unwrap()) + .spawn() + .unwrap(); + + // Scope to ensure stdin is closed. + { + let mut stdin = process.stdin.take().unwrap(); + stdin.write_all(b"Testing YubiKey encryption").unwrap(); + stdin.flush().unwrap(); + } + + let status = process.wait().unwrap(); + assert_eq!(status.code(), Some(0)); +} + +#[test_with::env(YUBIKEY_SERIAL, YUBIKEY_SLOT)] +#[test_with::executable(rage)] +#[cfg_attr(all(unix, not(target_os = "macos")), test_with::executable(pcscd))] +#[test] +fn plugin_decrypt() { + let mut identity_file = tempfile::NamedTempFile::new_in(env!("CARGO_TARGET_TMPDIR")).unwrap(); + let enc_file = tempfile::NamedTempFile::new_in(env!("CARGO_TARGET_TMPDIR")).unwrap(); + let plaintext = "Testing YubiKey encryption"; + + // Write an identity file corresponding to this YubiKey slot. + let identity = Command::new(PLUGIN_BIN) + .arg("--identity") + .arg("--serial") + .arg(env::var("YUBIKEY_SERIAL").unwrap()) + .arg("--slot") + .arg(env::var("YUBIKEY_SLOT").unwrap()) + .output() + .unwrap(); + assert_eq!(identity.status.code(), Some(0)); + identity_file.write_all(&identity.stdout).unwrap(); + identity_file.flush().unwrap(); + + // Encrypt to the YubiKey slot. + let mut enc_process = Command::new(which::which("rage").unwrap()) + .arg("-e") + .arg("-i") + .arg(identity_file.path()) + .arg("-o") + .arg(enc_file.path()) + .stdin(Stdio::piped()) + .env("PATH", Path::new(PLUGIN_BIN).parent().unwrap()) + .spawn() + .unwrap(); + + // Scope to ensure stdin is closed. + { + let mut stdin = enc_process.stdin.take().unwrap(); + stdin.write_all(plaintext.as_bytes()).unwrap(); + stdin.flush().unwrap(); + } + + let enc_status = enc_process.wait().unwrap(); + assert_eq!(enc_status.code(), Some(0)); + + // Decrypt with the YubiKey. + let dec_process = Command::new(which::which("rage").unwrap()) + .arg("-d") + .arg("-i") + .arg(identity_file.path()) + .arg(enc_file.path()) + .stdin(Stdio::piped()) + .env("PATH", Path::new(PLUGIN_BIN).parent().unwrap()) + .output() + .unwrap(); + + let stderr = String::from_utf8_lossy(&dec_process.stderr); + if !stderr.is_empty() { + assert!(stderr.contains("age-plugin-yubikey")); + assert!(stderr.ends_with("...\n")); + } + assert_eq!(String::from_utf8_lossy(&dec_process.stdout), plaintext); +}