├── .cargo └── audit.toml ├── .github ├── actions │ └── ci_script │ │ └── action.yml └── workflows │ ├── ci.yml │ └── nightly.yml ├── .gitignore ├── .travis.yml.disabled ├── CHANGELOG.md ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── MAINTAINERS.toml ├── README.md ├── SECURITY.md ├── clippy.toml ├── patches └── rcgen+0.13.1.patch ├── src ├── cli │ └── mod.rs ├── common.rs ├── error.rs ├── lib.rs ├── main.rs ├── subcommands │ ├── create_csr.rs │ ├── create_ecc_key.rs │ ├── create_rsa_key.rs │ ├── decrypt.rs │ ├── delete_client.rs │ ├── delete_key.rs │ ├── encrypt.rs │ ├── export_public_key.rs │ ├── generate_random.rs │ ├── list_authenticators.rs │ ├── list_clients.rs │ ├── list_keys.rs │ ├── list_opcodes.rs │ ├── list_providers.rs │ ├── mod.rs │ ├── ping.rs │ └── sign.rs └── util.rs └── tests ├── ci.sh ├── parsec-cli-tests.sh └── test_config.toml /.cargo/audit.toml: -------------------------------------------------------------------------------- 1 | [advisories] 2 | ignore = [] 3 | informational_warnings = ["unmaintained"] # warn for categories of informational advisories 4 | severity_threshold = "low" # CVSS severity ("none", "low", "medium", "high", "critical") 5 | 6 | # Advisory Database Configuration 7 | [database] 8 | path = "/tmp/advisory-db" # Path where advisory git repo will be cloned 9 | url = "https://github.com/RustSec/advisory-db.git" # URL to git repo 10 | fetch = true # Perform a `git fetch` before auditing 11 | stale = false # Allow stale advisory DB (i.e. no commits for 90 days) 12 | 13 | # Output Configuration 14 | [output] 15 | deny = ["unmaintained"] # exit on error if unmaintained dependencies are found 16 | format = "terminal" # "terminal" (human readable report) or "json" 17 | quiet = false # Only print information on error 18 | show_tree = true # Show inverse dependency trees along with advisories 19 | 20 | # Target Configuration 21 | [target] 22 | os = "linux" # Ignore advisories for operating systems other than this one 23 | 24 | [yanked] 25 | enabled = true # Warn for yanked crates in Cargo.lock 26 | update_index = true # Auto-update the crates.io index 27 | -------------------------------------------------------------------------------- /.github/actions/ci_script/action.yml: -------------------------------------------------------------------------------- 1 | name: "CI script Tests" 2 | description: "Install and run Parsec with the Mbed Crypto provider" 3 | inputs: 4 | ci-flags: 5 | required: true 6 | default: "" 7 | description: "Flags with which to run the ci.sh tests" 8 | 9 | runs: 10 | using: "composite" 11 | steps: 12 | - name: Install and run Parsec with the Mbed Crypto provider 13 | run: | 14 | git clone https://github.com/parallaxsecond/parsec.git 15 | cd parsec 16 | cargo build --features "mbed-crypto-provider" 17 | ./target/debug/parsec -c ../tests/test_config.toml & 18 | shell: bash 19 | - name: Execute CI script 20 | run: ./tests/ci.sh ${{ inputs.ci-flags }} 21 | shell: bash 22 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: Continuous Integration 2 | 3 | on: [push, pull_request, workflow_dispatch] 4 | 5 | jobs: 6 | build: 7 | name: Execute CI script 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: actions/checkout@v3 11 | - name: Install latest Rust 12 | uses: actions-rust-lang/setup-rust-toolchain@v1 13 | with: 14 | toolchain: stable 15 | rustflags: "" 16 | - name: Execute CI script 17 | uses: ./.github/actions/ci_script 18 | 19 | build-msrv: 20 | name: MSRV - Execute CI script 21 | runs-on: ubuntu-latest 22 | steps: 23 | - uses: actions/checkout@v3 24 | - name: Install Rust MSRV 25 | uses: actions-rust-lang/setup-rust-toolchain@v1 26 | with: 27 | toolchain: 1.66.0 28 | rustflags: "" 29 | - name: Execute CI script 30 | uses: ./.github/actions/ci_script 31 | 32 | links: 33 | name: Check links 34 | runs-on: ubuntu-latest 35 | steps: 36 | - uses: actions/checkout@v2 37 | - name: Link Checker 38 | uses: peter-evans/link-checker@v1 39 | with: 40 | args: -v -r *.md 41 | - name: Fail if there were link errors 42 | run: exit ${{ steps.lc.outputs.exit_code }} 43 | 44 | mismatcher: 45 | name: Check for mismatched dependencies (those that have more than one version) 46 | runs-on: ubuntu-latest 47 | steps: 48 | - uses: actions/checkout@v3 49 | with: 50 | ref: "${{ github.event.inputs.rev }}" 51 | - name: Install latest Rust 52 | uses: actions-rust-lang/setup-rust-toolchain@v1 53 | with: 54 | toolchain: stable 55 | rustflags: "" 56 | - name: Execute CI script 57 | uses: ./.github/actions/ci_script 58 | with: 59 | ci-flags: "mismatcher" 60 | -------------------------------------------------------------------------------- /.github/workflows/nightly.yml: -------------------------------------------------------------------------------- 1 | name: Nightly Checks 2 | 3 | on: 4 | schedule: 5 | # Every night at midnight 6 | - cron: '0 0 * * *' 7 | workflow_dispatch: 8 | inputs: 9 | rev: 10 | description: "Revision hash to run against" 11 | required: false 12 | default: "" 13 | jobs: 14 | dependencies: 15 | name: Check for unused dependencies 16 | runs-on: ubuntu-latest 17 | steps: 18 | - uses: actions/checkout@v2 19 | with: 20 | ref: "${{ github.event.inputs.rev }}" 21 | - name: Install latest Rust 22 | uses: actions-rs/toolchain@v1 23 | with: 24 | toolchain: nightly 25 | - name: Install cargo udeps 26 | run: cargo install cargo-udeps --locked 27 | - name: Execute cargo udeps 28 | run: cargo +nightly udeps 29 | 30 | audit: 31 | name: Check for crates with security vulnerabilities 32 | runs-on: ubuntu-latest 33 | steps: 34 | - uses: actions/checkout@v2 35 | with: 36 | ref: "${{ github.event.inputs.rev }}" 37 | - name: Install latest Rust 38 | uses: actions-rs/toolchain@v1 39 | with: 40 | toolchain: nightly 41 | - name: Install cargo audit 42 | run: cargo install cargo-audit 43 | - name: Execute cargo audit 44 | run: cargo audit --ignore RUSTSEC-2024-0006 45 | 46 | build-next: 47 | name: Execute CI script with next branch 48 | runs-on: ubuntu-latest 49 | steps: 50 | - uses: actions/checkout@v3 51 | with: 52 | ref: "${{ github.event.inputs.rev }}" 53 | - name: Install Rust MSRV 54 | uses: actions-rust-lang/setup-rust-toolchain@v1 55 | with: 56 | toolchain: 1.66.0 57 | rustflags: "" 58 | - name: Execute CI script with next branch 59 | uses: ./.github/actions/ci_script 60 | with: 61 | ci-flags: "--test-next-branch-tracking" 62 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | .devcontainer 3 | -------------------------------------------------------------------------------- /.travis.yml.disabled: -------------------------------------------------------------------------------- 1 | # Executing our tests on Arm64 with Travis CI 2 | arch: arm64 3 | language: rust 4 | script: 5 | - ./ci.sh 6 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## [0.7.0](https://github.com/parallaxsecond/parsec-tool/tree/0.7.0) (2023-10-17) 4 | 5 | [Full Changelog](https://github.com/parallaxsecond/parsec-tool/compare/0.7.0-rc1...0.7.0) 6 | 7 | ## [0.7.0-rc1](https://github.com/parallaxsecond/parsec-tool/tree/0.7.0-rc1) (2023-10-17) 8 | 9 | [Full Changelog](https://github.com/parallaxsecond/parsec-tool/compare/0.6.0...0.7.0-rc1) 10 | 11 | **Closed issues:** 12 | 13 | - Intermittent test failure for test\_csr\(\) and test\_signing\(\) [\#101](https://github.com/parallaxsecond/parsec-tool/issues/101) 14 | 15 | **Merged pull requests:** 16 | 17 | - Remove unused atty dependency [\#110](https://github.com/parallaxsecond/parsec-tool/pull/110) ([tgonzalezorlandoarm](https://github.com/tgonzalezorlandoarm)) 18 | - Disable structopt default features [\#109](https://github.com/parallaxsecond/parsec-tool/pull/109) ([tgonzalezorlandoarm](https://github.com/tgonzalezorlandoarm)) 19 | - Update parsec-interface [\#108](https://github.com/parallaxsecond/parsec-tool/pull/108) ([gowthamsk-arm](https://github.com/gowthamsk-arm)) 20 | - Remove unmaintained ansi\_term, clap crates and update env\_logger [\#107](https://github.com/parallaxsecond/parsec-tool/pull/107) ([tgonzalezorlandoarm](https://github.com/tgonzalezorlandoarm)) 21 | - Align crates with parsec service [\#106](https://github.com/parallaxsecond/parsec-tool/pull/106) ([gowthamsk-arm](https://github.com/gowthamsk-arm)) 22 | - Bump parsec-client and other crates [\#105](https://github.com/parallaxsecond/parsec-tool/pull/105) ([gowthamsk-arm](https://github.com/gowthamsk-arm)) 23 | - ci: Add workflow dispatch [\#104](https://github.com/parallaxsecond/parsec-tool/pull/104) ([tgonzalezorlandoarm](https://github.com/tgonzalezorlandoarm)) 24 | - Bump ASN1 crates dependencies [\#102](https://github.com/parallaxsecond/parsec-tool/pull/102) ([anta5010](https://github.com/anta5010)) 25 | 26 | ## [0.6.0](https://github.com/parallaxsecond/parsec-tool/tree/0.6.0) (2023-03-27) 27 | 28 | [Full Changelog](https://github.com/parallaxsecond/parsec-tool/compare/0.6.0-rc2...0.6.0) 29 | 30 | ## [0.6.0-rc2](https://github.com/parallaxsecond/parsec-tool/tree/0.6.0-rc2) (2023-03-27) 31 | 32 | [Full Changelog](https://github.com/parallaxsecond/parsec-tool/compare/0.6.0-rc1...0.6.0-rc2) 33 | 34 | **Merged pull requests:** 35 | 36 | - Align crates version with parsec-service [\#99](https://github.com/parallaxsecond/parsec-tool/pull/99) ([gowthamsk-arm](https://github.com/gowthamsk-arm)) 37 | - Fix nightly CI and update lock [\#98](https://github.com/parallaxsecond/parsec-tool/pull/98) ([gowthamsk-arm](https://github.com/gowthamsk-arm)) 38 | 39 | ## [0.6.0-rc1](https://github.com/parallaxsecond/parsec-tool/tree/0.6.0-rc1) (2023-03-15) 40 | 41 | [Full Changelog](https://github.com/parallaxsecond/parsec-tool/compare/0.5.4...0.6.0-rc1) 42 | 43 | **Merged pull requests:** 44 | 45 | - Bump parsec-client [\#97](https://github.com/parallaxsecond/parsec-tool/pull/97) ([gowthamsk-arm](https://github.com/gowthamsk-arm)) 46 | - Add support for RSA OAEP into parsec-tool and parsec-cli-tests.sh [\#96](https://github.com/parallaxsecond/parsec-tool/pull/96) ([anta5010](https://github.com/anta5010)) 47 | - Update lib.rs to remove const\_err [\#95](https://github.com/parallaxsecond/parsec-tool/pull/95) ([marcsvll](https://github.com/marcsvll)) 48 | 49 | ## [0.5.4](https://github.com/parallaxsecond/parsec-tool/tree/0.5.4) (2022-10-12) 50 | 51 | [Full Changelog](https://github.com/parallaxsecond/parsec-tool/compare/0.5.3...0.5.4) 52 | 53 | **Closed issues:** 54 | 55 | - parsec-cli-tests.sh incorrectly fails with openssl 3.0.5 [\#90](https://github.com/parallaxsecond/parsec-tool/issues/90) 56 | 57 | **Merged pull requests:** 58 | 59 | - Create 0.5.4 point release [\#93](https://github.com/parallaxsecond/parsec-tool/pull/93) ([gowthamsk-arm](https://github.com/gowthamsk-arm)) 60 | - Make RSA key string generic [\#92](https://github.com/parallaxsecond/parsec-tool/pull/92) ([gowthamsk-arm](https://github.com/gowthamsk-arm)) 61 | 62 | ## [0.5.3](https://github.com/parallaxsecond/parsec-tool/tree/0.5.3) (2022-09-12) 63 | 64 | [Full Changelog](https://github.com/parallaxsecond/parsec-tool/compare/0.5.2...0.5.3) 65 | 66 | **Implemented enhancements:** 67 | 68 | - Support serialNumber attribute as part of DN for CSR [\#84](https://github.com/parallaxsecond/parsec-tool/issues/84) 69 | - Allow strength of RSA keys to be specified on the command-line [\#83](https://github.com/parallaxsecond/parsec-tool/issues/83) 70 | 71 | **Merged pull requests:** 72 | 73 | - Update Chanege log for the release 0.5.3 [\#89](https://github.com/parallaxsecond/parsec-tool/pull/89) ([mohamedasaker-arm](https://github.com/mohamedasaker-arm)) 74 | - Release prep 0.5.3 [\#88](https://github.com/parallaxsecond/parsec-tool/pull/88) ([mohamedasaker-arm](https://github.com/mohamedasaker-arm)) 75 | - Support a 'bits' argument for specifying the size/strength of RSA keys. [\#86](https://github.com/parallaxsecond/parsec-tool/pull/86) ([paulhowardarm](https://github.com/paulhowardarm)) 76 | - Support serialNumber field of Distinguished Name for CSRs. [\#85](https://github.com/parallaxsecond/parsec-tool/pull/85) ([paulhowardarm](https://github.com/paulhowardarm)) 77 | - Update cargo audit configuration [\#81](https://github.com/parallaxsecond/parsec-tool/pull/81) ([hug-dev](https://github.com/hug-dev)) 78 | - Add an encrypt command plus tests. [\#80](https://github.com/parallaxsecond/parsec-tool/pull/80) ([paulhowardarm](https://github.com/paulhowardarm)) 79 | 80 | ## [0.5.2](https://github.com/parallaxsecond/parsec-tool/tree/0.5.2) (2022-03-21) 81 | 82 | [Full Changelog](https://github.com/parallaxsecond/parsec-tool/compare/0.5.1...0.5.2) 83 | 84 | **Merged pull requests:** 85 | 86 | - Prepare 0.5.2 release [\#78](https://github.com/parallaxsecond/parsec-tool/pull/78) ([ionut-arm](https://github.com/ionut-arm)) 87 | - Update `regex` to 1.5.5 [\#77](https://github.com/parallaxsecond/parsec-tool/pull/77) ([ionut-arm](https://github.com/ionut-arm)) 88 | - Update version of `rcgen` we use [\#76](https://github.com/parallaxsecond/parsec-tool/pull/76) ([ionut-arm](https://github.com/ionut-arm)) 89 | 90 | ## [0.5.1](https://github.com/parallaxsecond/parsec-tool/tree/0.5.1) (2022-02-22) 91 | 92 | [Full Changelog](https://github.com/parallaxsecond/parsec-tool/compare/0.5.0...0.5.1) 93 | 94 | **Merged pull requests:** 95 | 96 | - Update changelog for 0.5.x [\#74](https://github.com/parallaxsecond/parsec-tool/pull/74) ([ionut-arm](https://github.com/ionut-arm)) 97 | - Update dependencies that have been yanked [\#73](https://github.com/parallaxsecond/parsec-tool/pull/73) ([ionut-arm](https://github.com/ionut-arm)) 98 | - Bump version of PSA Crypto crates [\#72](https://github.com/parallaxsecond/parsec-tool/pull/72) ([ionut-arm](https://github.com/ionut-arm)) 99 | 100 | ## [0.5.0](https://github.com/parallaxsecond/parsec-tool/tree/0.5.0) (2022-02-15) 101 | 102 | [Full Changelog](https://github.com/parallaxsecond/parsec-tool/compare/0.4.0...0.5.0) 103 | 104 | **Fixed bugs:** 105 | 106 | - Some commands should not need authentication [\#49](https://github.com/parallaxsecond/parsec-tool/issues/49) 107 | 108 | **Closed issues:** 109 | 110 | - Error detection broken in parsec-cli-tests.sh [\#66](https://github.com/parallaxsecond/parsec-tool/issues/66) 111 | 112 | **Merged pull requests:** 113 | 114 | - Prepare to release new version [\#71](https://github.com/parallaxsecond/parsec-tool/pull/71) ([ionut-arm](https://github.com/ionut-arm)) 115 | - Small output fixes [\#70](https://github.com/parallaxsecond/parsec-tool/pull/70) ([anta5010](https://github.com/anta5010)) 116 | - Support the creation of RSA signing keys as well as encryption keys [\#69](https://github.com/parallaxsecond/parsec-tool/pull/69) ([paulhowardarm](https://github.com/paulhowardarm)) 117 | - Early support for certificate request generation in parsec-tool [\#68](https://github.com/parallaxsecond/parsec-tool/pull/68) ([paulhowardarm](https://github.com/paulhowardarm)) 118 | - Avoid using pipes to run all test commands in the same sub-shell [\#67](https://github.com/parallaxsecond/parsec-tool/pull/67) ([anta5010](https://github.com/anta5010)) 119 | - fix \#49 [\#65](https://github.com/parallaxsecond/parsec-tool/pull/65) ([jn9e9](https://github.com/jn9e9)) 120 | - Upgrade client's version [\#64](https://github.com/parallaxsecond/parsec-tool/pull/64) ([hug-dev](https://github.com/hug-dev)) 121 | - Update CHANGELOG.md with 0.4.0 details [\#63](https://github.com/parallaxsecond/parsec-tool/pull/63) ([anta5010](https://github.com/anta5010)) 122 | 123 | ## [0.4.0](https://github.com/parallaxsecond/parsec-tool/tree/0.4.0) (2021-09-24) 124 | 125 | [Full Changelog](https://github.com/parallaxsecond/parsec-tool/compare/0.3.1...0.4.0) 126 | 127 | **Implemented enhancements:** 128 | 129 | - Add round-trip testing [\#47](https://github.com/parallaxsecond/parsec-tool/issues/47) 130 | 131 | **Merged pull requests:** 132 | 133 | - Bump version to 0.4.0 [\#62](https://github.com/parallaxsecond/parsec-tool/pull/62) ([anta5010](https://github.com/anta5010)) 134 | - Bash wrapper for parsec-tool to run basic e2e Parsec tests [\#61](https://github.com/parallaxsecond/parsec-tool/pull/61) ([anta5010](https://github.com/anta5010)) 135 | - Update CHaNGELOG [\#59](https://github.com/parallaxsecond/parsec-tool/pull/59) ([hug-dev](https://github.com/hug-dev)) 136 | 137 | ## [0.3.1](https://github.com/parallaxsecond/parsec-tool/tree/0.3.1) (2021-08-04) 138 | 139 | [Full Changelog](https://github.com/parallaxsecond/parsec-tool/compare/0.3.0...0.3.1) 140 | 141 | **Implemented enhancements:** 142 | 143 | - --provider option for list-opcodes is not consistent [\#53](https://github.com/parallaxsecond/parsec-tool/issues/53) 144 | - Use the implicit provider for list\_opcodes [\#54](https://github.com/parallaxsecond/parsec-tool/pull/54) ([hug-dev](https://github.com/hug-dev)) 145 | 146 | **Fixed bugs:** 147 | 148 | - Update sha2 version [\#57](https://github.com/parallaxsecond/parsec-tool/pull/57) ([hug-dev](https://github.com/hug-dev)) 149 | 150 | **Closed issues:** 151 | 152 | - Update the demo with most recent contents [\#44](https://github.com/parallaxsecond/parsec-tool/issues/44) 153 | 154 | **Merged pull requests:** 155 | 156 | - Prepare for the next release [\#58](https://github.com/parallaxsecond/parsec-tool/pull/58) ([hug-dev](https://github.com/hug-dev)) 157 | - Add cargo-audit config file [\#56](https://github.com/parallaxsecond/parsec-tool/pull/56) ([ionut-arm](https://github.com/ionut-arm)) 158 | - Update the CHANGELOG file [\#51](https://github.com/parallaxsecond/parsec-tool/pull/51) ([hug-dev](https://github.com/hug-dev)) 159 | 160 | ## [0.3.0](https://github.com/parallaxsecond/parsec-tool/tree/0.3.0) (2021-03-18) 161 | 162 | [Full Changelog](https://github.com/parallaxsecond/parsec-tool/compare/0.2.0...0.3.0) 163 | 164 | **Closed issues:** 165 | 166 | - Tag 0.2.0 and upload on crates.io [\#45](https://github.com/parallaxsecond/parsec-tool/issues/45) 167 | 168 | **Merged pull requests:** 169 | 170 | - Prepare for 0.3.0 release [\#50](https://github.com/parallaxsecond/parsec-tool/pull/50) ([hug-dev](https://github.com/hug-dev)) 171 | - Specify format of public keys in README [\#48](https://github.com/parallaxsecond/parsec-tool/pull/48) ([ionut-arm](https://github.com/ionut-arm)) 172 | 173 | ## [0.2.0](https://github.com/parallaxsecond/parsec-tool/tree/0.2.0) (2021-02-23) 174 | 175 | [Full Changelog](https://github.com/parallaxsecond/parsec-tool/compare/0.1.0...0.2.0) 176 | 177 | **Implemented enhancements:** 178 | 179 | - Make the output of export-public-key more useful. [\#28](https://github.com/parallaxsecond/parsec-tool/issues/28) 180 | - Add encrypt/decrypt support [\#27](https://github.com/parallaxsecond/parsec-tool/issues/27) 181 | - Format public key to PEM [\#38](https://github.com/parallaxsecond/parsec-tool/pull/38) ([ionut-arm](https://github.com/ionut-arm)) 182 | - Add BasicClient to ParsecToolApp [\#35](https://github.com/parallaxsecond/parsec-tool/pull/35) ([ionut-arm](https://github.com/ionut-arm)) 183 | 184 | **Fixed bugs:** 185 | 186 | - Review the default options [\#30](https://github.com/parallaxsecond/parsec-tool/issues/30) 187 | 188 | **Closed issues:** 189 | 190 | - Add basic CLI tests on the CI [\#42](https://github.com/parallaxsecond/parsec-tool/issues/42) 191 | - Check if it is possible to use the BasicClient for operations [\#36](https://github.com/parallaxsecond/parsec-tool/issues/36) 192 | - Add support for sign/verify [\#31](https://github.com/parallaxsecond/parsec-tool/issues/31) 193 | - Automatic key creation for some operations [\#29](https://github.com/parallaxsecond/parsec-tool/issues/29) 194 | - Rename commands to remove PSA prefix and make them more user-friendly [\#26](https://github.com/parallaxsecond/parsec-tool/issues/26) 195 | - Add support for ListClients and DeleteClient [\#22](https://github.com/parallaxsecond/parsec-tool/issues/22) 196 | 197 | **Merged pull requests:** 198 | 199 | - Add some CLI tests on the CI [\#46](https://github.com/parallaxsecond/parsec-tool/pull/46) ([hug-dev](https://github.com/hug-dev)) 200 | - Use log crate instead of custom logging logic [\#43](https://github.com/parallaxsecond/parsec-tool/pull/43) ([hug-dev](https://github.com/hug-dev)) 201 | - Add a timeout CLI option [\#41](https://github.com/parallaxsecond/parsec-tool/pull/41) ([hug-dev](https://github.com/hug-dev)) 202 | - Add decrypt/sign and simplify things [\#39](https://github.com/parallaxsecond/parsec-tool/pull/39) ([hug-dev](https://github.com/hug-dev)) 203 | - Rectify the key creation operations [\#34](https://github.com/parallaxsecond/parsec-tool/pull/34) ([hug-dev](https://github.com/hug-dev)) 204 | - Rename things with more friendly names [\#33](https://github.com/parallaxsecond/parsec-tool/pull/33) ([hug-dev](https://github.com/hug-dev)) 205 | - Replace default\_value with Option [\#32](https://github.com/parallaxsecond/parsec-tool/pull/32) ([hug-dev](https://github.com/hug-dev)) 206 | - Update the Rust client to the spiffe-less version [\#25](https://github.com/parallaxsecond/parsec-tool/pull/25) ([hug-dev](https://github.com/hug-dev)) 207 | - Add ListClients and DeleteClient operations [\#24](https://github.com/parallaxsecond/parsec-tool/pull/24) ([hug-dev](https://github.com/hug-dev)) 208 | - Update dependencies [\#23](https://github.com/parallaxsecond/parsec-tool/pull/23) ([ionut-arm](https://github.com/ionut-arm)) 209 | - Disable Travis CI builds and update Cargo.lock [\#21](https://github.com/parallaxsecond/parsec-tool/pull/21) ([ionut-arm](https://github.com/ionut-arm)) 210 | - Add project changelog [\#20](https://github.com/parallaxsecond/parsec-tool/pull/20) ([ionut-arm](https://github.com/ionut-arm)) 211 | - Remove unused anyhow [\#19](https://github.com/parallaxsecond/parsec-tool/pull/19) ([hug-dev](https://github.com/hug-dev)) 212 | - Upgrade the client's version to add SPIFFE support [\#18](https://github.com/parallaxsecond/parsec-tool/pull/18) ([hug-dev](https://github.com/hug-dev)) 213 | - Add list-authenticators subcommand [\#17](https://github.com/parallaxsecond/parsec-tool/pull/17) ([hug-dev](https://github.com/hug-dev)) 214 | 215 | ## [0.1.0](https://github.com/parallaxsecond/parsec-tool/tree/0.1.0) (2020-10-20) 216 | 217 | [Full Changelog](https://github.com/parallaxsecond/parsec-tool/compare/d36eb9f5d2e57fc29924c7e32c11da0c66b4ba4e...0.1.0) 218 | 219 | **Implemented enhancements:** 220 | 221 | - Make use of client bootstrapping functionality [\#16](https://github.com/parallaxsecond/parsec-tool/pull/16) ([ionut-arm](https://github.com/ionut-arm)) 222 | - Add the generate and destroy key operations [\#13](https://github.com/parallaxsecond/parsec-tool/pull/13) ([hug-dev](https://github.com/hug-dev)) 223 | - Upgrade the client version [\#12](https://github.com/parallaxsecond/parsec-tool/pull/12) ([hug-dev](https://github.com/hug-dev)) 224 | - Upgrade dependencies [\#10](https://github.com/parallaxsecond/parsec-tool/pull/10) ([hug-dev](https://github.com/hug-dev)) 225 | - Add asciinema demo [\#5](https://github.com/parallaxsecond/parsec-tool/pull/5) ([joechrisellis](https://github.com/joechrisellis)) 226 | - Add initial parsec-tool implementation [\#1](https://github.com/parallaxsecond/parsec-tool/pull/1) ([joechrisellis](https://github.com/joechrisellis)) 227 | 228 | **Closed issues:** 229 | 230 | - Use the bootstrapping client [\#15](https://github.com/parallaxsecond/parsec-tool/issues/15) 231 | - asciinema demo [\#2](https://github.com/parallaxsecond/parsec-tool/issues/2) 232 | 233 | **Merged pull requests:** 234 | 235 | - Add list-keys subcommand [\#14](https://github.com/parallaxsecond/parsec-tool/pull/14) ([joechrisellis](https://github.com/joechrisellis)) 236 | - Add psa-export-key subcommand [\#9](https://github.com/parallaxsecond/parsec-tool/pull/9) ([joechrisellis](https://github.com/joechrisellis)) 237 | - Add psa-export-public-key subcommand [\#8](https://github.com/parallaxsecond/parsec-tool/pull/8) ([joechrisellis](https://github.com/joechrisellis)) 238 | - List providers UUID fix [\#6](https://github.com/parallaxsecond/parsec-tool/pull/6) ([joechrisellis](https://github.com/joechrisellis)) 239 | - Move subcommand dispatching to `Subcommand` enum [\#4](https://github.com/parallaxsecond/parsec-tool/pull/4) ([joechrisellis](https://github.com/joechrisellis)) 240 | - Add psa-generate-random subcommand [\#3](https://github.com/parallaxsecond/parsec-tool/pull/3) ([joechrisellis](https://github.com/joechrisellis)) 241 | 242 | 243 | 244 | \* *This Changelog was automatically generated by [github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)* 245 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "aho-corasick" 7 | version = "1.1.2" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" 10 | dependencies = [ 11 | "memchr", 12 | ] 13 | 14 | [[package]] 15 | name = "anstream" 16 | version = "0.3.2" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163" 19 | dependencies = [ 20 | "anstyle", 21 | "anstyle-parse", 22 | "anstyle-query", 23 | "anstyle-wincon", 24 | "colorchoice", 25 | "is-terminal", 26 | "utf8parse", 27 | ] 28 | 29 | [[package]] 30 | name = "anstyle" 31 | version = "1.0.2" 32 | source = "registry+https://github.com/rust-lang/crates.io-index" 33 | checksum = "15c4c2c83f81532e5845a733998b6971faca23490340a418e9b72a3ec9de12ea" 34 | 35 | [[package]] 36 | name = "anstyle-parse" 37 | version = "0.2.1" 38 | source = "registry+https://github.com/rust-lang/crates.io-index" 39 | checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333" 40 | dependencies = [ 41 | "utf8parse", 42 | ] 43 | 44 | [[package]] 45 | name = "anstyle-query" 46 | version = "1.0.0" 47 | source = "registry+https://github.com/rust-lang/crates.io-index" 48 | checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" 49 | dependencies = [ 50 | "windows-sys 0.48.0", 51 | ] 52 | 53 | [[package]] 54 | name = "anstyle-wincon" 55 | version = "1.0.2" 56 | source = "registry+https://github.com/rust-lang/crates.io-index" 57 | checksum = "c677ab05e09154296dd37acecd46420c17b9713e8366facafa8fc0885167cf4c" 58 | dependencies = [ 59 | "anstyle", 60 | "windows-sys 0.48.0", 61 | ] 62 | 63 | [[package]] 64 | name = "anyhow" 65 | version = "1.0.75" 66 | source = "registry+https://github.com/rust-lang/crates.io-index" 67 | checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" 68 | 69 | [[package]] 70 | name = "asn1-rs" 71 | version = "0.3.1" 72 | source = "registry+https://github.com/rust-lang/crates.io-index" 73 | checksum = "30ff05a702273012438132f449575dbc804e27b2f3cbe3069aa237d26c98fa33" 74 | dependencies = [ 75 | "asn1-rs-derive", 76 | "asn1-rs-impl", 77 | "displaydoc", 78 | "nom 7.1.3", 79 | "num-traits", 80 | "rusticata-macros", 81 | "thiserror", 82 | "time", 83 | ] 84 | 85 | [[package]] 86 | name = "asn1-rs-derive" 87 | version = "0.1.0" 88 | source = "registry+https://github.com/rust-lang/crates.io-index" 89 | checksum = "db8b7511298d5b7784b40b092d9e9dcd3a627a5707e4b5e507931ab0d44eeebf" 90 | dependencies = [ 91 | "proc-macro2", 92 | "quote", 93 | "syn 1.0.109", 94 | "synstructure", 95 | ] 96 | 97 | [[package]] 98 | name = "asn1-rs-impl" 99 | version = "0.1.0" 100 | source = "registry+https://github.com/rust-lang/crates.io-index" 101 | checksum = "2777730b2039ac0f95f093556e61b6d26cebed5393ca6f152717777cec3a42ed" 102 | dependencies = [ 103 | "proc-macro2", 104 | "quote", 105 | "syn 1.0.109", 106 | ] 107 | 108 | [[package]] 109 | name = "autocfg" 110 | version = "1.1.0" 111 | source = "registry+https://github.com/rust-lang/crates.io-index" 112 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 113 | 114 | [[package]] 115 | name = "base64" 116 | version = "0.13.1" 117 | source = "registry+https://github.com/rust-lang/crates.io-index" 118 | checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" 119 | 120 | [[package]] 121 | name = "base64" 122 | version = "0.21.4" 123 | source = "registry+https://github.com/rust-lang/crates.io-index" 124 | checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" 125 | 126 | [[package]] 127 | name = "base64" 128 | version = "0.22.1" 129 | source = "registry+https://github.com/rust-lang/crates.io-index" 130 | checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" 131 | 132 | [[package]] 133 | name = "bincode" 134 | version = "1.3.3" 135 | source = "registry+https://github.com/rust-lang/crates.io-index" 136 | checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" 137 | dependencies = [ 138 | "serde", 139 | ] 140 | 141 | [[package]] 142 | name = "bindgen" 143 | version = "0.57.0" 144 | source = "registry+https://github.com/rust-lang/crates.io-index" 145 | checksum = "fd4865004a46a0aafb2a0a5eb19d3c9fc46ee5f063a6cfc605c69ac9ecf5263d" 146 | dependencies = [ 147 | "bitflags 1.3.2", 148 | "cexpr", 149 | "clang-sys", 150 | "lazy_static", 151 | "lazycell", 152 | "peeking_take_while", 153 | "proc-macro2", 154 | "quote", 155 | "regex", 156 | "rustc-hash", 157 | "shlex", 158 | ] 159 | 160 | [[package]] 161 | name = "bitflags" 162 | version = "1.3.2" 163 | source = "registry+https://github.com/rust-lang/crates.io-index" 164 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 165 | 166 | [[package]] 167 | name = "bitflags" 168 | version = "2.4.1" 169 | source = "registry+https://github.com/rust-lang/crates.io-index" 170 | checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" 171 | 172 | [[package]] 173 | name = "block-buffer" 174 | version = "0.9.0" 175 | source = "registry+https://github.com/rust-lang/crates.io-index" 176 | checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" 177 | dependencies = [ 178 | "generic-array", 179 | ] 180 | 181 | [[package]] 182 | name = "bumpalo" 183 | version = "3.14.0" 184 | source = "registry+https://github.com/rust-lang/crates.io-index" 185 | checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" 186 | 187 | [[package]] 188 | name = "bytes" 189 | version = "1.5.0" 190 | source = "registry+https://github.com/rust-lang/crates.io-index" 191 | checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" 192 | 193 | [[package]] 194 | name = "cc" 195 | version = "1.0.83" 196 | source = "registry+https://github.com/rust-lang/crates.io-index" 197 | checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" 198 | dependencies = [ 199 | "libc", 200 | ] 201 | 202 | [[package]] 203 | name = "cexpr" 204 | version = "0.4.0" 205 | source = "registry+https://github.com/rust-lang/crates.io-index" 206 | checksum = "f4aedb84272dbe89af497cf81375129abda4fc0a9e7c5d317498c15cc30c0d27" 207 | dependencies = [ 208 | "nom 5.1.3", 209 | ] 210 | 211 | [[package]] 212 | name = "cfg-if" 213 | version = "1.0.0" 214 | source = "registry+https://github.com/rust-lang/crates.io-index" 215 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 216 | 217 | [[package]] 218 | name = "clang-sys" 219 | version = "1.6.1" 220 | source = "registry+https://github.com/rust-lang/crates.io-index" 221 | checksum = "c688fc74432808e3eb684cae8830a86be1d66a2bd58e1f248ed0960a590baf6f" 222 | dependencies = [ 223 | "glob", 224 | "libc", 225 | "libloading", 226 | ] 227 | 228 | [[package]] 229 | name = "clap" 230 | version = "4.3.24" 231 | source = "registry+https://github.com/rust-lang/crates.io-index" 232 | checksum = "fb690e81c7840c0d7aade59f242ea3b41b9bc27bcd5997890e7702ae4b32e487" 233 | dependencies = [ 234 | "clap_builder", 235 | "clap_derive", 236 | "once_cell", 237 | ] 238 | 239 | [[package]] 240 | name = "clap_builder" 241 | version = "4.3.24" 242 | source = "registry+https://github.com/rust-lang/crates.io-index" 243 | checksum = "5ed2e96bc16d8d740f6f48d663eddf4b8a0983e79210fd55479b7bcd0a69860e" 244 | dependencies = [ 245 | "anstream", 246 | "anstyle", 247 | "clap_lex", 248 | "strsim", 249 | ] 250 | 251 | [[package]] 252 | name = "clap_derive" 253 | version = "4.3.12" 254 | source = "registry+https://github.com/rust-lang/crates.io-index" 255 | checksum = "54a9bb5758fc5dfe728d1019941681eccaf0cf8a4189b692a0ee2f2ecf90a050" 256 | dependencies = [ 257 | "heck", 258 | "proc-macro2", 259 | "quote", 260 | "syn 2.0.38", 261 | ] 262 | 263 | [[package]] 264 | name = "clap_lex" 265 | version = "0.5.0" 266 | source = "registry+https://github.com/rust-lang/crates.io-index" 267 | checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" 268 | 269 | [[package]] 270 | name = "cmake" 271 | version = "0.1.50" 272 | source = "registry+https://github.com/rust-lang/crates.io-index" 273 | checksum = "a31c789563b815f77f4250caee12365734369f942439b7defd71e18a48197130" 274 | dependencies = [ 275 | "cc", 276 | ] 277 | 278 | [[package]] 279 | name = "colorchoice" 280 | version = "1.0.0" 281 | source = "registry+https://github.com/rust-lang/crates.io-index" 282 | checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" 283 | 284 | [[package]] 285 | name = "const-oid" 286 | version = "0.7.1" 287 | source = "registry+https://github.com/rust-lang/crates.io-index" 288 | checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3" 289 | 290 | [[package]] 291 | name = "cpufeatures" 292 | version = "0.2.9" 293 | source = "registry+https://github.com/rust-lang/crates.io-index" 294 | checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" 295 | dependencies = [ 296 | "libc", 297 | ] 298 | 299 | [[package]] 300 | name = "data-encoding" 301 | version = "2.4.0" 302 | source = "registry+https://github.com/rust-lang/crates.io-index" 303 | checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" 304 | 305 | [[package]] 306 | name = "der" 307 | version = "0.5.1" 308 | source = "registry+https://github.com/rust-lang/crates.io-index" 309 | checksum = "6919815d73839e7ad218de758883aae3a257ba6759ce7a9992501efbb53d705c" 310 | dependencies = [ 311 | "const-oid", 312 | ] 313 | 314 | [[package]] 315 | name = "der-parser" 316 | version = "7.0.0" 317 | source = "registry+https://github.com/rust-lang/crates.io-index" 318 | checksum = "fe398ac75057914d7d07307bf67dc7f3f574a26783b4fc7805a20ffa9f506e82" 319 | dependencies = [ 320 | "asn1-rs", 321 | "displaydoc", 322 | "nom 7.1.3", 323 | "num-bigint", 324 | "num-traits", 325 | "rusticata-macros", 326 | ] 327 | 328 | [[package]] 329 | name = "derivative" 330 | version = "2.2.0" 331 | source = "registry+https://github.com/rust-lang/crates.io-index" 332 | checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" 333 | dependencies = [ 334 | "proc-macro2", 335 | "quote", 336 | "syn 1.0.109", 337 | ] 338 | 339 | [[package]] 340 | name = "digest" 341 | version = "0.9.0" 342 | source = "registry+https://github.com/rust-lang/crates.io-index" 343 | checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" 344 | dependencies = [ 345 | "generic-array", 346 | ] 347 | 348 | [[package]] 349 | name = "displaydoc" 350 | version = "0.2.4" 351 | source = "registry+https://github.com/rust-lang/crates.io-index" 352 | checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" 353 | dependencies = [ 354 | "proc-macro2", 355 | "quote", 356 | "syn 2.0.38", 357 | ] 358 | 359 | [[package]] 360 | name = "either" 361 | version = "1.9.0" 362 | source = "registry+https://github.com/rust-lang/crates.io-index" 363 | checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" 364 | 365 | [[package]] 366 | name = "env_logger" 367 | version = "0.10.0" 368 | source = "registry+https://github.com/rust-lang/crates.io-index" 369 | checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" 370 | dependencies = [ 371 | "humantime", 372 | "is-terminal", 373 | "log", 374 | "regex", 375 | "termcolor", 376 | ] 377 | 378 | [[package]] 379 | name = "errno" 380 | version = "0.3.5" 381 | source = "registry+https://github.com/rust-lang/crates.io-index" 382 | checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" 383 | dependencies = [ 384 | "libc", 385 | "windows-sys 0.48.0", 386 | ] 387 | 388 | [[package]] 389 | name = "form_urlencoded" 390 | version = "1.2.0" 391 | source = "registry+https://github.com/rust-lang/crates.io-index" 392 | checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" 393 | dependencies = [ 394 | "percent-encoding", 395 | ] 396 | 397 | [[package]] 398 | name = "futures" 399 | version = "0.3.28" 400 | source = "registry+https://github.com/rust-lang/crates.io-index" 401 | checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" 402 | dependencies = [ 403 | "futures-channel", 404 | "futures-core", 405 | "futures-executor", 406 | "futures-io", 407 | "futures-sink", 408 | "futures-task", 409 | "futures-util", 410 | ] 411 | 412 | [[package]] 413 | name = "futures-channel" 414 | version = "0.3.28" 415 | source = "registry+https://github.com/rust-lang/crates.io-index" 416 | checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" 417 | dependencies = [ 418 | "futures-core", 419 | "futures-sink", 420 | ] 421 | 422 | [[package]] 423 | name = "futures-core" 424 | version = "0.3.28" 425 | source = "registry+https://github.com/rust-lang/crates.io-index" 426 | checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" 427 | 428 | [[package]] 429 | name = "futures-executor" 430 | version = "0.3.28" 431 | source = "registry+https://github.com/rust-lang/crates.io-index" 432 | checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" 433 | dependencies = [ 434 | "futures-core", 435 | "futures-task", 436 | "futures-util", 437 | ] 438 | 439 | [[package]] 440 | name = "futures-io" 441 | version = "0.3.28" 442 | source = "registry+https://github.com/rust-lang/crates.io-index" 443 | checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" 444 | 445 | [[package]] 446 | name = "futures-macro" 447 | version = "0.3.28" 448 | source = "registry+https://github.com/rust-lang/crates.io-index" 449 | checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" 450 | dependencies = [ 451 | "proc-macro2", 452 | "quote", 453 | "syn 2.0.38", 454 | ] 455 | 456 | [[package]] 457 | name = "futures-sink" 458 | version = "0.3.28" 459 | source = "registry+https://github.com/rust-lang/crates.io-index" 460 | checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" 461 | 462 | [[package]] 463 | name = "futures-task" 464 | version = "0.3.28" 465 | source = "registry+https://github.com/rust-lang/crates.io-index" 466 | checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" 467 | 468 | [[package]] 469 | name = "futures-util" 470 | version = "0.3.28" 471 | source = "registry+https://github.com/rust-lang/crates.io-index" 472 | checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" 473 | dependencies = [ 474 | "futures-channel", 475 | "futures-core", 476 | "futures-io", 477 | "futures-macro", 478 | "futures-sink", 479 | "futures-task", 480 | "memchr", 481 | "pin-project-lite", 482 | "pin-utils", 483 | "slab", 484 | ] 485 | 486 | [[package]] 487 | name = "generic-array" 488 | version = "0.14.7" 489 | source = "registry+https://github.com/rust-lang/crates.io-index" 490 | checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" 491 | dependencies = [ 492 | "typenum", 493 | "version_check", 494 | ] 495 | 496 | [[package]] 497 | name = "getrandom" 498 | version = "0.2.14" 499 | source = "registry+https://github.com/rust-lang/crates.io-index" 500 | checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c" 501 | dependencies = [ 502 | "cfg-if", 503 | "libc", 504 | "wasi", 505 | ] 506 | 507 | [[package]] 508 | name = "glob" 509 | version = "0.3.1" 510 | source = "registry+https://github.com/rust-lang/crates.io-index" 511 | checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" 512 | 513 | [[package]] 514 | name = "grpcio" 515 | version = "0.9.1" 516 | source = "registry+https://github.com/rust-lang/crates.io-index" 517 | checksum = "24d99e00eed7e0a04ee2705112e7cfdbe1a3cc771147f22f016a8cd2d002187b" 518 | dependencies = [ 519 | "futures", 520 | "grpcio-sys", 521 | "libc", 522 | "log", 523 | "parking_lot", 524 | "protobuf", 525 | ] 526 | 527 | [[package]] 528 | name = "grpcio-sys" 529 | version = "0.9.1+1.38.0" 530 | source = "registry+https://github.com/rust-lang/crates.io-index" 531 | checksum = "9447d1a926beeef466606cc45717f80897998b548e7dc622873d453e1ecb4be4" 532 | dependencies = [ 533 | "bindgen", 534 | "cc", 535 | "cmake", 536 | "libc", 537 | "libz-sys", 538 | "pkg-config", 539 | "walkdir", 540 | ] 541 | 542 | [[package]] 543 | name = "heck" 544 | version = "0.4.1" 545 | source = "registry+https://github.com/rust-lang/crates.io-index" 546 | checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" 547 | 548 | [[package]] 549 | name = "hermit-abi" 550 | version = "0.3.3" 551 | source = "registry+https://github.com/rust-lang/crates.io-index" 552 | checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" 553 | 554 | [[package]] 555 | name = "humantime" 556 | version = "2.1.0" 557 | source = "registry+https://github.com/rust-lang/crates.io-index" 558 | checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" 559 | 560 | [[package]] 561 | name = "idna" 562 | version = "0.4.0" 563 | source = "registry+https://github.com/rust-lang/crates.io-index" 564 | checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" 565 | dependencies = [ 566 | "unicode-bidi", 567 | "unicode-normalization", 568 | ] 569 | 570 | [[package]] 571 | name = "instant" 572 | version = "0.1.12" 573 | source = "registry+https://github.com/rust-lang/crates.io-index" 574 | checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" 575 | dependencies = [ 576 | "cfg-if", 577 | ] 578 | 579 | [[package]] 580 | name = "is-terminal" 581 | version = "0.4.9" 582 | source = "registry+https://github.com/rust-lang/crates.io-index" 583 | checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" 584 | dependencies = [ 585 | "hermit-abi", 586 | "rustix", 587 | "windows-sys 0.48.0", 588 | ] 589 | 590 | [[package]] 591 | name = "itertools" 592 | version = "0.10.5" 593 | source = "registry+https://github.com/rust-lang/crates.io-index" 594 | checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" 595 | dependencies = [ 596 | "either", 597 | ] 598 | 599 | [[package]] 600 | name = "itoa" 601 | version = "1.0.9" 602 | source = "registry+https://github.com/rust-lang/crates.io-index" 603 | checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" 604 | 605 | [[package]] 606 | name = "js-sys" 607 | version = "0.3.64" 608 | source = "registry+https://github.com/rust-lang/crates.io-index" 609 | checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" 610 | dependencies = [ 611 | "wasm-bindgen", 612 | ] 613 | 614 | [[package]] 615 | name = "jsonwebkey" 616 | version = "0.3.5" 617 | source = "registry+https://github.com/rust-lang/crates.io-index" 618 | checksum = "c57c852b14147e2bd58c14fde40398864453403ef632b1101db130282ee6e2cc" 619 | dependencies = [ 620 | "base64 0.13.1", 621 | "bitflags 1.3.2", 622 | "generic-array", 623 | "jsonwebtoken", 624 | "num-bigint", 625 | "serde", 626 | "serde_json", 627 | "thiserror", 628 | "yasna 0.4.0", 629 | "zeroize", 630 | ] 631 | 632 | [[package]] 633 | name = "jsonwebtoken" 634 | version = "8.3.0" 635 | source = "registry+https://github.com/rust-lang/crates.io-index" 636 | checksum = "6971da4d9c3aa03c3d8f3ff0f4155b534aad021292003895a469716b2a230378" 637 | dependencies = [ 638 | "base64 0.21.4", 639 | "pem 1.1.1", 640 | "ring 0.16.20", 641 | "serde", 642 | "serde_json", 643 | "simple_asn1", 644 | ] 645 | 646 | [[package]] 647 | name = "lazy_static" 648 | version = "1.4.0" 649 | source = "registry+https://github.com/rust-lang/crates.io-index" 650 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 651 | 652 | [[package]] 653 | name = "lazycell" 654 | version = "1.3.0" 655 | source = "registry+https://github.com/rust-lang/crates.io-index" 656 | checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" 657 | 658 | [[package]] 659 | name = "libc" 660 | version = "0.2.149" 661 | source = "registry+https://github.com/rust-lang/crates.io-index" 662 | checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" 663 | 664 | [[package]] 665 | name = "libloading" 666 | version = "0.7.4" 667 | source = "registry+https://github.com/rust-lang/crates.io-index" 668 | checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" 669 | dependencies = [ 670 | "cfg-if", 671 | "winapi", 672 | ] 673 | 674 | [[package]] 675 | name = "libz-sys" 676 | version = "1.1.12" 677 | source = "registry+https://github.com/rust-lang/crates.io-index" 678 | checksum = "d97137b25e321a73eef1418d1d5d2eda4d77e12813f8e6dead84bc52c5870a7b" 679 | dependencies = [ 680 | "cc", 681 | "libc", 682 | "pkg-config", 683 | "vcpkg", 684 | ] 685 | 686 | [[package]] 687 | name = "linux-raw-sys" 688 | version = "0.4.10" 689 | source = "registry+https://github.com/rust-lang/crates.io-index" 690 | checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" 691 | 692 | [[package]] 693 | name = "lock_api" 694 | version = "0.4.10" 695 | source = "registry+https://github.com/rust-lang/crates.io-index" 696 | checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" 697 | dependencies = [ 698 | "autocfg", 699 | "scopeguard", 700 | ] 701 | 702 | [[package]] 703 | name = "log" 704 | version = "0.4.20" 705 | source = "registry+https://github.com/rust-lang/crates.io-index" 706 | checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" 707 | 708 | [[package]] 709 | name = "memchr" 710 | version = "2.6.4" 711 | source = "registry+https://github.com/rust-lang/crates.io-index" 712 | checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" 713 | 714 | [[package]] 715 | name = "minimal-lexical" 716 | version = "0.2.1" 717 | source = "registry+https://github.com/rust-lang/crates.io-index" 718 | checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" 719 | 720 | [[package]] 721 | name = "nom" 722 | version = "5.1.3" 723 | source = "registry+https://github.com/rust-lang/crates.io-index" 724 | checksum = "08959a387a676302eebf4ddbcbc611da04285579f76f88ee0506c63b1a61dd4b" 725 | dependencies = [ 726 | "memchr", 727 | "version_check", 728 | ] 729 | 730 | [[package]] 731 | name = "nom" 732 | version = "7.1.3" 733 | source = "registry+https://github.com/rust-lang/crates.io-index" 734 | checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" 735 | dependencies = [ 736 | "memchr", 737 | "minimal-lexical", 738 | ] 739 | 740 | [[package]] 741 | name = "num" 742 | version = "0.4.1" 743 | source = "registry+https://github.com/rust-lang/crates.io-index" 744 | checksum = "b05180d69e3da0e530ba2a1dae5110317e49e3b7f3d41be227dc5f92e49ee7af" 745 | dependencies = [ 746 | "num-bigint", 747 | "num-complex", 748 | "num-integer", 749 | "num-iter", 750 | "num-rational", 751 | "num-traits", 752 | ] 753 | 754 | [[package]] 755 | name = "num-bigint" 756 | version = "0.4.4" 757 | source = "registry+https://github.com/rust-lang/crates.io-index" 758 | checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" 759 | dependencies = [ 760 | "autocfg", 761 | "num-integer", 762 | "num-traits", 763 | ] 764 | 765 | [[package]] 766 | name = "num-complex" 767 | version = "0.4.4" 768 | source = "registry+https://github.com/rust-lang/crates.io-index" 769 | checksum = "1ba157ca0885411de85d6ca030ba7e2a83a28636056c7c699b07c8b6f7383214" 770 | dependencies = [ 771 | "num-traits", 772 | ] 773 | 774 | [[package]] 775 | name = "num-derive" 776 | version = "0.4.1" 777 | source = "registry+https://github.com/rust-lang/crates.io-index" 778 | checksum = "cfb77679af88f8b125209d354a202862602672222e7f2313fdd6dc349bad4712" 779 | dependencies = [ 780 | "proc-macro2", 781 | "quote", 782 | "syn 2.0.38", 783 | ] 784 | 785 | [[package]] 786 | name = "num-integer" 787 | version = "0.1.45" 788 | source = "registry+https://github.com/rust-lang/crates.io-index" 789 | checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" 790 | dependencies = [ 791 | "autocfg", 792 | "num-traits", 793 | ] 794 | 795 | [[package]] 796 | name = "num-iter" 797 | version = "0.1.43" 798 | source = "registry+https://github.com/rust-lang/crates.io-index" 799 | checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" 800 | dependencies = [ 801 | "autocfg", 802 | "num-integer", 803 | "num-traits", 804 | ] 805 | 806 | [[package]] 807 | name = "num-rational" 808 | version = "0.4.1" 809 | source = "registry+https://github.com/rust-lang/crates.io-index" 810 | checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" 811 | dependencies = [ 812 | "autocfg", 813 | "num-bigint", 814 | "num-integer", 815 | "num-traits", 816 | ] 817 | 818 | [[package]] 819 | name = "num-traits" 820 | version = "0.2.17" 821 | source = "registry+https://github.com/rust-lang/crates.io-index" 822 | checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" 823 | dependencies = [ 824 | "autocfg", 825 | ] 826 | 827 | [[package]] 828 | name = "oid" 829 | version = "0.2.1" 830 | source = "registry+https://github.com/rust-lang/crates.io-index" 831 | checksum = "9c19903c598813dba001b53beeae59bb77ad4892c5c1b9b3500ce4293a0d06c2" 832 | dependencies = [ 833 | "serde", 834 | ] 835 | 836 | [[package]] 837 | name = "oid-registry" 838 | version = "0.4.0" 839 | source = "registry+https://github.com/rust-lang/crates.io-index" 840 | checksum = "38e20717fa0541f39bd146692035c37bedfa532b3e5071b35761082407546b2a" 841 | dependencies = [ 842 | "asn1-rs", 843 | ] 844 | 845 | [[package]] 846 | name = "once_cell" 847 | version = "1.18.0" 848 | source = "registry+https://github.com/rust-lang/crates.io-index" 849 | checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" 850 | 851 | [[package]] 852 | name = "opaque-debug" 853 | version = "0.3.0" 854 | source = "registry+https://github.com/rust-lang/crates.io-index" 855 | checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" 856 | 857 | [[package]] 858 | name = "parking_lot" 859 | version = "0.11.2" 860 | source = "registry+https://github.com/rust-lang/crates.io-index" 861 | checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" 862 | dependencies = [ 863 | "instant", 864 | "lock_api", 865 | "parking_lot_core", 866 | ] 867 | 868 | [[package]] 869 | name = "parking_lot_core" 870 | version = "0.8.6" 871 | source = "registry+https://github.com/rust-lang/crates.io-index" 872 | checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" 873 | dependencies = [ 874 | "cfg-if", 875 | "instant", 876 | "libc", 877 | "redox_syscall", 878 | "smallvec", 879 | "winapi", 880 | ] 881 | 882 | [[package]] 883 | name = "parsec-client" 884 | version = "0.16.0" 885 | source = "registry+https://github.com/rust-lang/crates.io-index" 886 | checksum = "a36f9d8e27166cf0586913812454174286e094d594cc8b28d8a8d02d64406bbc" 887 | dependencies = [ 888 | "derivative", 889 | "libc", 890 | "log", 891 | "num", 892 | "parsec-interface", 893 | "spiffe", 894 | "url", 895 | "zeroize", 896 | ] 897 | 898 | [[package]] 899 | name = "parsec-interface" 900 | version = "0.29.1" 901 | source = "registry+https://github.com/rust-lang/crates.io-index" 902 | checksum = "cc706e09209b30f10baa35709d41b9cc01d4931b21c00679f59db96cd1650add" 903 | dependencies = [ 904 | "bincode", 905 | "derivative", 906 | "log", 907 | "num", 908 | "num-derive", 909 | "num-traits", 910 | "prost", 911 | "psa-crypto", 912 | "secrecy", 913 | "serde", 914 | "uuid", 915 | "zeroize", 916 | ] 917 | 918 | [[package]] 919 | name = "parsec-tool" 920 | version = "0.7.0" 921 | dependencies = [ 922 | "base64 0.13.1", 923 | "clap", 924 | "env_logger", 925 | "log", 926 | "oid", 927 | "parsec-client", 928 | "pem 1.1.1", 929 | "picky-asn1", 930 | "picky-asn1-der", 931 | "picky-asn1-x509", 932 | "rcgen", 933 | "serde", 934 | "sha2", 935 | "thiserror", 936 | ] 937 | 938 | [[package]] 939 | name = "peeking_take_while" 940 | version = "0.1.2" 941 | source = "registry+https://github.com/rust-lang/crates.io-index" 942 | checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" 943 | 944 | [[package]] 945 | name = "pem" 946 | version = "1.1.1" 947 | source = "registry+https://github.com/rust-lang/crates.io-index" 948 | checksum = "a8835c273a76a90455d7344889b0964598e3316e2a79ede8e36f16bdcf2228b8" 949 | dependencies = [ 950 | "base64 0.13.1", 951 | ] 952 | 953 | [[package]] 954 | name = "pem" 955 | version = "3.0.4" 956 | source = "registry+https://github.com/rust-lang/crates.io-index" 957 | checksum = "8e459365e590736a54c3fa561947c84837534b8e9af6fc5bf781307e82658fae" 958 | dependencies = [ 959 | "base64 0.22.1", 960 | "serde", 961 | ] 962 | 963 | [[package]] 964 | name = "percent-encoding" 965 | version = "2.3.0" 966 | source = "registry+https://github.com/rust-lang/crates.io-index" 967 | checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" 968 | 969 | [[package]] 970 | name = "picky-asn1" 971 | version = "0.8.0" 972 | source = "registry+https://github.com/rust-lang/crates.io-index" 973 | checksum = "295eea0f33c16be21e2a98b908fdd4d73c04dd48c8480991b76dbcf0cb58b212" 974 | dependencies = [ 975 | "oid", 976 | "serde", 977 | "serde_bytes", 978 | ] 979 | 980 | [[package]] 981 | name = "picky-asn1-der" 982 | version = "0.4.1" 983 | source = "registry+https://github.com/rust-lang/crates.io-index" 984 | checksum = "5df7873a9e36d42dadb393bea5e211fe83d793c172afad5fb4ec846ec582793f" 985 | dependencies = [ 986 | "picky-asn1", 987 | "serde", 988 | "serde_bytes", 989 | ] 990 | 991 | [[package]] 992 | name = "picky-asn1-x509" 993 | version = "0.12.0" 994 | source = "registry+https://github.com/rust-lang/crates.io-index" 995 | checksum = "2c5f20f71a68499ff32310f418a6fad8816eac1a2859ed3f0c5c741389dd6208" 996 | dependencies = [ 997 | "base64 0.21.4", 998 | "oid", 999 | "picky-asn1", 1000 | "picky-asn1-der", 1001 | "serde", 1002 | ] 1003 | 1004 | [[package]] 1005 | name = "pin-project-lite" 1006 | version = "0.2.13" 1007 | source = "registry+https://github.com/rust-lang/crates.io-index" 1008 | checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" 1009 | 1010 | [[package]] 1011 | name = "pin-utils" 1012 | version = "0.1.0" 1013 | source = "registry+https://github.com/rust-lang/crates.io-index" 1014 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 1015 | 1016 | [[package]] 1017 | name = "pkcs8" 1018 | version = "0.8.0" 1019 | source = "registry+https://github.com/rust-lang/crates.io-index" 1020 | checksum = "7cabda3fb821068a9a4fab19a683eac3af12edf0f34b94a8be53c4972b8149d0" 1021 | dependencies = [ 1022 | "der", 1023 | "spki", 1024 | ] 1025 | 1026 | [[package]] 1027 | name = "pkg-config" 1028 | version = "0.3.27" 1029 | source = "registry+https://github.com/rust-lang/crates.io-index" 1030 | checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" 1031 | 1032 | [[package]] 1033 | name = "proc-macro2" 1034 | version = "1.0.69" 1035 | source = "registry+https://github.com/rust-lang/crates.io-index" 1036 | checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" 1037 | dependencies = [ 1038 | "unicode-ident", 1039 | ] 1040 | 1041 | [[package]] 1042 | name = "prost" 1043 | version = "0.9.0" 1044 | source = "registry+https://github.com/rust-lang/crates.io-index" 1045 | checksum = "444879275cb4fd84958b1a1d5420d15e6fcf7c235fe47f053c9c2a80aceb6001" 1046 | dependencies = [ 1047 | "bytes", 1048 | "prost-derive", 1049 | ] 1050 | 1051 | [[package]] 1052 | name = "prost-derive" 1053 | version = "0.9.0" 1054 | source = "registry+https://github.com/rust-lang/crates.io-index" 1055 | checksum = "f9cc1a3263e07e0bf68e96268f37665207b49560d98739662cdfaae215c720fe" 1056 | dependencies = [ 1057 | "anyhow", 1058 | "itertools", 1059 | "proc-macro2", 1060 | "quote", 1061 | "syn 1.0.109", 1062 | ] 1063 | 1064 | [[package]] 1065 | name = "protobuf" 1066 | version = "2.28.0" 1067 | source = "registry+https://github.com/rust-lang/crates.io-index" 1068 | checksum = "106dd99e98437432fed6519dedecfade6a06a73bb7b2a1e019fdd2bee5778d94" 1069 | 1070 | [[package]] 1071 | name = "psa-crypto" 1072 | version = "0.12.0" 1073 | source = "registry+https://github.com/rust-lang/crates.io-index" 1074 | checksum = "89c2256e525b9a45ec3bbb3382a43dd8809240279e0aab8ea7ee220e9295445b" 1075 | dependencies = [ 1076 | "log", 1077 | "psa-crypto-sys", 1078 | "serde", 1079 | "zeroize", 1080 | ] 1081 | 1082 | [[package]] 1083 | name = "psa-crypto-sys" 1084 | version = "0.12.0" 1085 | source = "registry+https://github.com/rust-lang/crates.io-index" 1086 | checksum = "f170cac3a328e1678916b276067ec170a5a51db1b9b8b4c00b44c2839819a963" 1087 | dependencies = [ 1088 | "cc", 1089 | "cmake", 1090 | "regex", 1091 | "walkdir", 1092 | ] 1093 | 1094 | [[package]] 1095 | name = "quote" 1096 | version = "1.0.33" 1097 | source = "registry+https://github.com/rust-lang/crates.io-index" 1098 | checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" 1099 | dependencies = [ 1100 | "proc-macro2", 1101 | ] 1102 | 1103 | [[package]] 1104 | name = "rcgen" 1105 | version = "0.13.1" 1106 | dependencies = [ 1107 | "pem 3.0.4", 1108 | "ring 0.17.8", 1109 | "rustls-pki-types", 1110 | "time", 1111 | "yasna 0.5.2", 1112 | ] 1113 | 1114 | [[package]] 1115 | name = "redox_syscall" 1116 | version = "0.2.16" 1117 | source = "registry+https://github.com/rust-lang/crates.io-index" 1118 | checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" 1119 | dependencies = [ 1120 | "bitflags 1.3.2", 1121 | ] 1122 | 1123 | [[package]] 1124 | name = "regex" 1125 | version = "1.10.0" 1126 | source = "registry+https://github.com/rust-lang/crates.io-index" 1127 | checksum = "d119d7c7ca818f8a53c300863d4f87566aac09943aef5b355bb83969dae75d87" 1128 | dependencies = [ 1129 | "aho-corasick", 1130 | "memchr", 1131 | "regex-automata", 1132 | "regex-syntax", 1133 | ] 1134 | 1135 | [[package]] 1136 | name = "regex-automata" 1137 | version = "0.4.1" 1138 | source = "registry+https://github.com/rust-lang/crates.io-index" 1139 | checksum = "465c6fc0621e4abc4187a2bda0937bfd4f722c2730b29562e19689ea796c9a4b" 1140 | dependencies = [ 1141 | "aho-corasick", 1142 | "memchr", 1143 | "regex-syntax", 1144 | ] 1145 | 1146 | [[package]] 1147 | name = "regex-syntax" 1148 | version = "0.8.0" 1149 | source = "registry+https://github.com/rust-lang/crates.io-index" 1150 | checksum = "c3cbb081b9784b07cceb8824c8583f86db4814d172ab043f3c23f7dc600bf83d" 1151 | 1152 | [[package]] 1153 | name = "ring" 1154 | version = "0.16.20" 1155 | source = "registry+https://github.com/rust-lang/crates.io-index" 1156 | checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" 1157 | dependencies = [ 1158 | "cc", 1159 | "libc", 1160 | "once_cell", 1161 | "spin 0.5.2", 1162 | "untrusted 0.7.1", 1163 | "web-sys", 1164 | "winapi", 1165 | ] 1166 | 1167 | [[package]] 1168 | name = "ring" 1169 | version = "0.17.8" 1170 | source = "registry+https://github.com/rust-lang/crates.io-index" 1171 | checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" 1172 | dependencies = [ 1173 | "cc", 1174 | "cfg-if", 1175 | "getrandom", 1176 | "libc", 1177 | "spin 0.9.8", 1178 | "untrusted 0.9.0", 1179 | "windows-sys 0.52.0", 1180 | ] 1181 | 1182 | [[package]] 1183 | name = "rustc-hash" 1184 | version = "1.1.0" 1185 | source = "registry+https://github.com/rust-lang/crates.io-index" 1186 | checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" 1187 | 1188 | [[package]] 1189 | name = "rusticata-macros" 1190 | version = "4.1.0" 1191 | source = "registry+https://github.com/rust-lang/crates.io-index" 1192 | checksum = "faf0c4a6ece9950b9abdb62b1cfcf2a68b3b67a10ba445b3bb85be2a293d0632" 1193 | dependencies = [ 1194 | "nom 7.1.3", 1195 | ] 1196 | 1197 | [[package]] 1198 | name = "rustix" 1199 | version = "0.38.21" 1200 | source = "registry+https://github.com/rust-lang/crates.io-index" 1201 | checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3" 1202 | dependencies = [ 1203 | "bitflags 2.4.1", 1204 | "errno", 1205 | "libc", 1206 | "linux-raw-sys", 1207 | "windows-sys 0.48.0", 1208 | ] 1209 | 1210 | [[package]] 1211 | name = "rustls-pki-types" 1212 | version = "1.7.0" 1213 | source = "registry+https://github.com/rust-lang/crates.io-index" 1214 | checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" 1215 | 1216 | [[package]] 1217 | name = "ryu" 1218 | version = "1.0.15" 1219 | source = "registry+https://github.com/rust-lang/crates.io-index" 1220 | checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" 1221 | 1222 | [[package]] 1223 | name = "same-file" 1224 | version = "1.0.6" 1225 | source = "registry+https://github.com/rust-lang/crates.io-index" 1226 | checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" 1227 | dependencies = [ 1228 | "winapi-util", 1229 | ] 1230 | 1231 | [[package]] 1232 | name = "scopeguard" 1233 | version = "1.2.0" 1234 | source = "registry+https://github.com/rust-lang/crates.io-index" 1235 | checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" 1236 | 1237 | [[package]] 1238 | name = "secrecy" 1239 | version = "0.8.0" 1240 | source = "registry+https://github.com/rust-lang/crates.io-index" 1241 | checksum = "9bd1c54ea06cfd2f6b63219704de0b9b4f72dcc2b8fdef820be6cd799780e91e" 1242 | dependencies = [ 1243 | "serde", 1244 | "zeroize", 1245 | ] 1246 | 1247 | [[package]] 1248 | name = "serde" 1249 | version = "1.0.188" 1250 | source = "registry+https://github.com/rust-lang/crates.io-index" 1251 | checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" 1252 | dependencies = [ 1253 | "serde_derive", 1254 | ] 1255 | 1256 | [[package]] 1257 | name = "serde_bytes" 1258 | version = "0.11.12" 1259 | source = "registry+https://github.com/rust-lang/crates.io-index" 1260 | checksum = "ab33ec92f677585af6d88c65593ae2375adde54efdbf16d597f2cbc7a6d368ff" 1261 | dependencies = [ 1262 | "serde", 1263 | ] 1264 | 1265 | [[package]] 1266 | name = "serde_derive" 1267 | version = "1.0.188" 1268 | source = "registry+https://github.com/rust-lang/crates.io-index" 1269 | checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" 1270 | dependencies = [ 1271 | "proc-macro2", 1272 | "quote", 1273 | "syn 2.0.38", 1274 | ] 1275 | 1276 | [[package]] 1277 | name = "serde_json" 1278 | version = "1.0.107" 1279 | source = "registry+https://github.com/rust-lang/crates.io-index" 1280 | checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" 1281 | dependencies = [ 1282 | "itoa", 1283 | "ryu", 1284 | "serde", 1285 | ] 1286 | 1287 | [[package]] 1288 | name = "sha2" 1289 | version = "0.9.9" 1290 | source = "registry+https://github.com/rust-lang/crates.io-index" 1291 | checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" 1292 | dependencies = [ 1293 | "block-buffer", 1294 | "cfg-if", 1295 | "cpufeatures", 1296 | "digest", 1297 | "opaque-debug", 1298 | ] 1299 | 1300 | [[package]] 1301 | name = "shlex" 1302 | version = "0.1.1" 1303 | source = "registry+https://github.com/rust-lang/crates.io-index" 1304 | checksum = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2" 1305 | 1306 | [[package]] 1307 | name = "simple_asn1" 1308 | version = "0.6.2" 1309 | source = "registry+https://github.com/rust-lang/crates.io-index" 1310 | checksum = "adc4e5204eb1910f40f9cfa375f6f05b68c3abac4b6fd879c8ff5e7ae8a0a085" 1311 | dependencies = [ 1312 | "num-bigint", 1313 | "num-traits", 1314 | "thiserror", 1315 | "time", 1316 | ] 1317 | 1318 | [[package]] 1319 | name = "slab" 1320 | version = "0.4.9" 1321 | source = "registry+https://github.com/rust-lang/crates.io-index" 1322 | checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" 1323 | dependencies = [ 1324 | "autocfg", 1325 | ] 1326 | 1327 | [[package]] 1328 | name = "smallvec" 1329 | version = "1.11.1" 1330 | source = "registry+https://github.com/rust-lang/crates.io-index" 1331 | checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" 1332 | 1333 | [[package]] 1334 | name = "spiffe" 1335 | version = "0.2.1" 1336 | source = "registry+https://github.com/rust-lang/crates.io-index" 1337 | checksum = "f30161ecb25b9acc06eb61d750aaf1c4b3a536e22ff19fc2d250976537e93a11" 1338 | dependencies = [ 1339 | "futures", 1340 | "grpcio", 1341 | "jsonwebkey", 1342 | "jsonwebtoken", 1343 | "pkcs8", 1344 | "protobuf", 1345 | "serde", 1346 | "serde_json", 1347 | "simple_asn1", 1348 | "thiserror", 1349 | "time", 1350 | "url", 1351 | "x509-parser", 1352 | "zeroize", 1353 | ] 1354 | 1355 | [[package]] 1356 | name = "spin" 1357 | version = "0.5.2" 1358 | source = "registry+https://github.com/rust-lang/crates.io-index" 1359 | checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" 1360 | 1361 | [[package]] 1362 | name = "spin" 1363 | version = "0.9.8" 1364 | source = "registry+https://github.com/rust-lang/crates.io-index" 1365 | checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" 1366 | 1367 | [[package]] 1368 | name = "spki" 1369 | version = "0.5.4" 1370 | source = "registry+https://github.com/rust-lang/crates.io-index" 1371 | checksum = "44d01ac02a6ccf3e07db148d2be087da624fea0221a16152ed01f0496a6b0a27" 1372 | dependencies = [ 1373 | "der", 1374 | ] 1375 | 1376 | [[package]] 1377 | name = "strsim" 1378 | version = "0.10.0" 1379 | source = "registry+https://github.com/rust-lang/crates.io-index" 1380 | checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" 1381 | 1382 | [[package]] 1383 | name = "syn" 1384 | version = "1.0.109" 1385 | source = "registry+https://github.com/rust-lang/crates.io-index" 1386 | checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" 1387 | dependencies = [ 1388 | "proc-macro2", 1389 | "quote", 1390 | "unicode-ident", 1391 | ] 1392 | 1393 | [[package]] 1394 | name = "syn" 1395 | version = "2.0.38" 1396 | source = "registry+https://github.com/rust-lang/crates.io-index" 1397 | checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" 1398 | dependencies = [ 1399 | "proc-macro2", 1400 | "quote", 1401 | "unicode-ident", 1402 | ] 1403 | 1404 | [[package]] 1405 | name = "synstructure" 1406 | version = "0.12.6" 1407 | source = "registry+https://github.com/rust-lang/crates.io-index" 1408 | checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" 1409 | dependencies = [ 1410 | "proc-macro2", 1411 | "quote", 1412 | "syn 1.0.109", 1413 | "unicode-xid", 1414 | ] 1415 | 1416 | [[package]] 1417 | name = "termcolor" 1418 | version = "1.3.0" 1419 | source = "registry+https://github.com/rust-lang/crates.io-index" 1420 | checksum = "6093bad37da69aab9d123a8091e4be0aa4a03e4d601ec641c327398315f62b64" 1421 | dependencies = [ 1422 | "winapi-util", 1423 | ] 1424 | 1425 | [[package]] 1426 | name = "thiserror" 1427 | version = "1.0.49" 1428 | source = "registry+https://github.com/rust-lang/crates.io-index" 1429 | checksum = "1177e8c6d7ede7afde3585fd2513e611227efd6481bd78d2e82ba1ce16557ed4" 1430 | dependencies = [ 1431 | "thiserror-impl", 1432 | ] 1433 | 1434 | [[package]] 1435 | name = "thiserror-impl" 1436 | version = "1.0.49" 1437 | source = "registry+https://github.com/rust-lang/crates.io-index" 1438 | checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc" 1439 | dependencies = [ 1440 | "proc-macro2", 1441 | "quote", 1442 | "syn 2.0.38", 1443 | ] 1444 | 1445 | [[package]] 1446 | name = "time" 1447 | version = "0.3.23" 1448 | source = "registry+https://github.com/rust-lang/crates.io-index" 1449 | checksum = "59e399c068f43a5d116fedaf73b203fa4f9c519f17e2b34f63221d3792f81446" 1450 | dependencies = [ 1451 | "itoa", 1452 | "serde", 1453 | "time-core", 1454 | "time-macros", 1455 | ] 1456 | 1457 | [[package]] 1458 | name = "time-core" 1459 | version = "0.1.1" 1460 | source = "registry+https://github.com/rust-lang/crates.io-index" 1461 | checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" 1462 | 1463 | [[package]] 1464 | name = "time-macros" 1465 | version = "0.2.10" 1466 | source = "registry+https://github.com/rust-lang/crates.io-index" 1467 | checksum = "96ba15a897f3c86766b757e5ac7221554c6750054d74d5b28844fce5fb36a6c4" 1468 | dependencies = [ 1469 | "time-core", 1470 | ] 1471 | 1472 | [[package]] 1473 | name = "tinyvec" 1474 | version = "1.6.0" 1475 | source = "registry+https://github.com/rust-lang/crates.io-index" 1476 | checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" 1477 | dependencies = [ 1478 | "tinyvec_macros", 1479 | ] 1480 | 1481 | [[package]] 1482 | name = "tinyvec_macros" 1483 | version = "0.1.1" 1484 | source = "registry+https://github.com/rust-lang/crates.io-index" 1485 | checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" 1486 | 1487 | [[package]] 1488 | name = "typenum" 1489 | version = "1.17.0" 1490 | source = "registry+https://github.com/rust-lang/crates.io-index" 1491 | checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" 1492 | 1493 | [[package]] 1494 | name = "unicode-bidi" 1495 | version = "0.3.13" 1496 | source = "registry+https://github.com/rust-lang/crates.io-index" 1497 | checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" 1498 | 1499 | [[package]] 1500 | name = "unicode-ident" 1501 | version = "1.0.12" 1502 | source = "registry+https://github.com/rust-lang/crates.io-index" 1503 | checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" 1504 | 1505 | [[package]] 1506 | name = "unicode-normalization" 1507 | version = "0.1.22" 1508 | source = "registry+https://github.com/rust-lang/crates.io-index" 1509 | checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" 1510 | dependencies = [ 1511 | "tinyvec", 1512 | ] 1513 | 1514 | [[package]] 1515 | name = "unicode-xid" 1516 | version = "0.2.4" 1517 | source = "registry+https://github.com/rust-lang/crates.io-index" 1518 | checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" 1519 | 1520 | [[package]] 1521 | name = "untrusted" 1522 | version = "0.7.1" 1523 | source = "registry+https://github.com/rust-lang/crates.io-index" 1524 | checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" 1525 | 1526 | [[package]] 1527 | name = "untrusted" 1528 | version = "0.9.0" 1529 | source = "registry+https://github.com/rust-lang/crates.io-index" 1530 | checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" 1531 | 1532 | [[package]] 1533 | name = "url" 1534 | version = "2.4.1" 1535 | source = "registry+https://github.com/rust-lang/crates.io-index" 1536 | checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" 1537 | dependencies = [ 1538 | "form_urlencoded", 1539 | "idna", 1540 | "percent-encoding", 1541 | ] 1542 | 1543 | [[package]] 1544 | name = "utf8parse" 1545 | version = "0.2.1" 1546 | source = "registry+https://github.com/rust-lang/crates.io-index" 1547 | checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" 1548 | 1549 | [[package]] 1550 | name = "uuid" 1551 | version = "0.8.2" 1552 | source = "registry+https://github.com/rust-lang/crates.io-index" 1553 | checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" 1554 | 1555 | [[package]] 1556 | name = "vcpkg" 1557 | version = "0.2.15" 1558 | source = "registry+https://github.com/rust-lang/crates.io-index" 1559 | checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" 1560 | 1561 | [[package]] 1562 | name = "version_check" 1563 | version = "0.9.4" 1564 | source = "registry+https://github.com/rust-lang/crates.io-index" 1565 | checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" 1566 | 1567 | [[package]] 1568 | name = "walkdir" 1569 | version = "2.4.0" 1570 | source = "registry+https://github.com/rust-lang/crates.io-index" 1571 | checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" 1572 | dependencies = [ 1573 | "same-file", 1574 | "winapi-util", 1575 | ] 1576 | 1577 | [[package]] 1578 | name = "wasi" 1579 | version = "0.11.0+wasi-snapshot-preview1" 1580 | source = "registry+https://github.com/rust-lang/crates.io-index" 1581 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 1582 | 1583 | [[package]] 1584 | name = "wasm-bindgen" 1585 | version = "0.2.87" 1586 | source = "registry+https://github.com/rust-lang/crates.io-index" 1587 | checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" 1588 | dependencies = [ 1589 | "cfg-if", 1590 | "wasm-bindgen-macro", 1591 | ] 1592 | 1593 | [[package]] 1594 | name = "wasm-bindgen-backend" 1595 | version = "0.2.87" 1596 | source = "registry+https://github.com/rust-lang/crates.io-index" 1597 | checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" 1598 | dependencies = [ 1599 | "bumpalo", 1600 | "log", 1601 | "once_cell", 1602 | "proc-macro2", 1603 | "quote", 1604 | "syn 2.0.38", 1605 | "wasm-bindgen-shared", 1606 | ] 1607 | 1608 | [[package]] 1609 | name = "wasm-bindgen-macro" 1610 | version = "0.2.87" 1611 | source = "registry+https://github.com/rust-lang/crates.io-index" 1612 | checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" 1613 | dependencies = [ 1614 | "quote", 1615 | "wasm-bindgen-macro-support", 1616 | ] 1617 | 1618 | [[package]] 1619 | name = "wasm-bindgen-macro-support" 1620 | version = "0.2.87" 1621 | source = "registry+https://github.com/rust-lang/crates.io-index" 1622 | checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" 1623 | dependencies = [ 1624 | "proc-macro2", 1625 | "quote", 1626 | "syn 2.0.38", 1627 | "wasm-bindgen-backend", 1628 | "wasm-bindgen-shared", 1629 | ] 1630 | 1631 | [[package]] 1632 | name = "wasm-bindgen-shared" 1633 | version = "0.2.87" 1634 | source = "registry+https://github.com/rust-lang/crates.io-index" 1635 | checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" 1636 | 1637 | [[package]] 1638 | name = "web-sys" 1639 | version = "0.3.64" 1640 | source = "registry+https://github.com/rust-lang/crates.io-index" 1641 | checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" 1642 | dependencies = [ 1643 | "js-sys", 1644 | "wasm-bindgen", 1645 | ] 1646 | 1647 | [[package]] 1648 | name = "winapi" 1649 | version = "0.3.9" 1650 | source = "registry+https://github.com/rust-lang/crates.io-index" 1651 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 1652 | dependencies = [ 1653 | "winapi-i686-pc-windows-gnu", 1654 | "winapi-x86_64-pc-windows-gnu", 1655 | ] 1656 | 1657 | [[package]] 1658 | name = "winapi-i686-pc-windows-gnu" 1659 | version = "0.4.0" 1660 | source = "registry+https://github.com/rust-lang/crates.io-index" 1661 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 1662 | 1663 | [[package]] 1664 | name = "winapi-util" 1665 | version = "0.1.6" 1666 | source = "registry+https://github.com/rust-lang/crates.io-index" 1667 | checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" 1668 | dependencies = [ 1669 | "winapi", 1670 | ] 1671 | 1672 | [[package]] 1673 | name = "winapi-x86_64-pc-windows-gnu" 1674 | version = "0.4.0" 1675 | source = "registry+https://github.com/rust-lang/crates.io-index" 1676 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 1677 | 1678 | [[package]] 1679 | name = "windows-sys" 1680 | version = "0.48.0" 1681 | source = "registry+https://github.com/rust-lang/crates.io-index" 1682 | checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" 1683 | dependencies = [ 1684 | "windows-targets 0.48.5", 1685 | ] 1686 | 1687 | [[package]] 1688 | name = "windows-sys" 1689 | version = "0.52.0" 1690 | source = "registry+https://github.com/rust-lang/crates.io-index" 1691 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 1692 | dependencies = [ 1693 | "windows-targets 0.52.5", 1694 | ] 1695 | 1696 | [[package]] 1697 | name = "windows-targets" 1698 | version = "0.48.5" 1699 | source = "registry+https://github.com/rust-lang/crates.io-index" 1700 | checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" 1701 | dependencies = [ 1702 | "windows_aarch64_gnullvm 0.48.5", 1703 | "windows_aarch64_msvc 0.48.5", 1704 | "windows_i686_gnu 0.48.5", 1705 | "windows_i686_msvc 0.48.5", 1706 | "windows_x86_64_gnu 0.48.5", 1707 | "windows_x86_64_gnullvm 0.48.5", 1708 | "windows_x86_64_msvc 0.48.5", 1709 | ] 1710 | 1711 | [[package]] 1712 | name = "windows-targets" 1713 | version = "0.52.5" 1714 | source = "registry+https://github.com/rust-lang/crates.io-index" 1715 | checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" 1716 | dependencies = [ 1717 | "windows_aarch64_gnullvm 0.52.5", 1718 | "windows_aarch64_msvc 0.52.5", 1719 | "windows_i686_gnu 0.52.5", 1720 | "windows_i686_gnullvm", 1721 | "windows_i686_msvc 0.52.5", 1722 | "windows_x86_64_gnu 0.52.5", 1723 | "windows_x86_64_gnullvm 0.52.5", 1724 | "windows_x86_64_msvc 0.52.5", 1725 | ] 1726 | 1727 | [[package]] 1728 | name = "windows_aarch64_gnullvm" 1729 | version = "0.48.5" 1730 | source = "registry+https://github.com/rust-lang/crates.io-index" 1731 | checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" 1732 | 1733 | [[package]] 1734 | name = "windows_aarch64_gnullvm" 1735 | version = "0.52.5" 1736 | source = "registry+https://github.com/rust-lang/crates.io-index" 1737 | checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" 1738 | 1739 | [[package]] 1740 | name = "windows_aarch64_msvc" 1741 | version = "0.48.5" 1742 | source = "registry+https://github.com/rust-lang/crates.io-index" 1743 | checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" 1744 | 1745 | [[package]] 1746 | name = "windows_aarch64_msvc" 1747 | version = "0.52.5" 1748 | source = "registry+https://github.com/rust-lang/crates.io-index" 1749 | checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" 1750 | 1751 | [[package]] 1752 | name = "windows_i686_gnu" 1753 | version = "0.48.5" 1754 | source = "registry+https://github.com/rust-lang/crates.io-index" 1755 | checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" 1756 | 1757 | [[package]] 1758 | name = "windows_i686_gnu" 1759 | version = "0.52.5" 1760 | source = "registry+https://github.com/rust-lang/crates.io-index" 1761 | checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" 1762 | 1763 | [[package]] 1764 | name = "windows_i686_gnullvm" 1765 | version = "0.52.5" 1766 | source = "registry+https://github.com/rust-lang/crates.io-index" 1767 | checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" 1768 | 1769 | [[package]] 1770 | name = "windows_i686_msvc" 1771 | version = "0.48.5" 1772 | source = "registry+https://github.com/rust-lang/crates.io-index" 1773 | checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" 1774 | 1775 | [[package]] 1776 | name = "windows_i686_msvc" 1777 | version = "0.52.5" 1778 | source = "registry+https://github.com/rust-lang/crates.io-index" 1779 | checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" 1780 | 1781 | [[package]] 1782 | name = "windows_x86_64_gnu" 1783 | version = "0.48.5" 1784 | source = "registry+https://github.com/rust-lang/crates.io-index" 1785 | checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" 1786 | 1787 | [[package]] 1788 | name = "windows_x86_64_gnu" 1789 | version = "0.52.5" 1790 | source = "registry+https://github.com/rust-lang/crates.io-index" 1791 | checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" 1792 | 1793 | [[package]] 1794 | name = "windows_x86_64_gnullvm" 1795 | version = "0.48.5" 1796 | source = "registry+https://github.com/rust-lang/crates.io-index" 1797 | checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" 1798 | 1799 | [[package]] 1800 | name = "windows_x86_64_gnullvm" 1801 | version = "0.52.5" 1802 | source = "registry+https://github.com/rust-lang/crates.io-index" 1803 | checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" 1804 | 1805 | [[package]] 1806 | name = "windows_x86_64_msvc" 1807 | version = "0.48.5" 1808 | source = "registry+https://github.com/rust-lang/crates.io-index" 1809 | checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" 1810 | 1811 | [[package]] 1812 | name = "windows_x86_64_msvc" 1813 | version = "0.52.5" 1814 | source = "registry+https://github.com/rust-lang/crates.io-index" 1815 | checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" 1816 | 1817 | [[package]] 1818 | name = "x509-parser" 1819 | version = "0.13.2" 1820 | source = "registry+https://github.com/rust-lang/crates.io-index" 1821 | checksum = "9fb9bace5b5589ffead1afb76e43e34cff39cd0f3ce7e170ae0c29e53b88eb1c" 1822 | dependencies = [ 1823 | "asn1-rs", 1824 | "base64 0.13.1", 1825 | "data-encoding", 1826 | "der-parser", 1827 | "lazy_static", 1828 | "nom 7.1.3", 1829 | "oid-registry", 1830 | "rusticata-macros", 1831 | "thiserror", 1832 | "time", 1833 | ] 1834 | 1835 | [[package]] 1836 | name = "yasna" 1837 | version = "0.4.0" 1838 | source = "registry+https://github.com/rust-lang/crates.io-index" 1839 | checksum = "e262a29d0e61ccf2b6190d7050d4b237535fc76ce4c1210d9caa316f71dffa75" 1840 | dependencies = [ 1841 | "num-bigint", 1842 | ] 1843 | 1844 | [[package]] 1845 | name = "yasna" 1846 | version = "0.5.2" 1847 | source = "registry+https://github.com/rust-lang/crates.io-index" 1848 | checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd" 1849 | dependencies = [ 1850 | "time", 1851 | ] 1852 | 1853 | [[package]] 1854 | name = "zeroize" 1855 | version = "1.6.0" 1856 | source = "registry+https://github.com/rust-lang/crates.io-index" 1857 | checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" 1858 | dependencies = [ 1859 | "zeroize_derive", 1860 | ] 1861 | 1862 | [[package]] 1863 | name = "zeroize_derive" 1864 | version = "1.4.2" 1865 | source = "registry+https://github.com/rust-lang/crates.io-index" 1866 | checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" 1867 | dependencies = [ 1868 | "proc-macro2", 1869 | "quote", 1870 | "syn 2.0.38", 1871 | ] 1872 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "parsec-tool" 3 | version = "0.7.0" 4 | authors = ["Contributors to the Parsec project"] 5 | description = "Parsec Command Line Interface" 6 | license = "Apache-2.0" 7 | repository = "https://github.com/parallaxsecond/parsec-tool" 8 | readme = "README.md" 9 | keywords = ["parsec", "cli", "tool"] 10 | categories = ["development-tools", "command-line-utilities"] 11 | edition = "2018" 12 | documentation = "https://docs.rs/crate/parsec-tool" 13 | rust-version = "1.66.0" 14 | 15 | [dependencies] 16 | parsec-client = "0.16.0" 17 | # TODO: Fixed until the MSRV is bumped! 18 | clap = { version = "=4.3.24", features = ["derive", "std"] } 19 | thiserror = "1.0.20" 20 | env_logger = "0.10.0" 21 | oid = { version = "0.2", features = ["serde_support"] } 22 | pem = "1.1.0" 23 | base64 = "0.13.0" 24 | picky-asn1 = "0.8.0" 25 | picky-asn1-der = "0.4.1" 26 | picky-asn1-x509 = "0.12.0" 27 | serde = "1.0.123" 28 | sha2 = "0.9.9" 29 | log = "0.4.14" 30 | rcgen = { version = "0.13.1", features = ["pem"] } 31 | 32 | [package.metadata.patch] 33 | crates=["rcgen"] 34 | 35 | [patch.crates-io] 36 | rcgen = { path = './target/patch/rcgen-0.13.1' } 37 | 38 | [lib] 39 | name = "parsec_tool" 40 | path = "src/lib.rs" 41 | 42 | [[bin]] 43 | name = "parsec-tool" 44 | 45 | [features] 46 | default = [] 47 | spiffe-auth = ["parsec-client/spiffe"] 48 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /MAINTAINERS.toml: -------------------------------------------------------------------------------- 1 | # parsec-tool maintainers file 2 | # 3 | # This file lists the maintainers of the parallaxsecond/parsec-tool 4 | # project. 5 | # 6 | # Its structure is inspired from the maintainers files in the Docker Github 7 | # repositories. Please see the MAINTAINERS file in docker/opensource for more 8 | # information. 9 | 10 | [maintainers] 11 | 12 | # Core maintainers of the project. 13 | 14 | [maintainers.core] 15 | people = [ 16 | "hug-dev", 17 | "ionut-arm", 18 | "justincormack", 19 | "paulhowardarm", 20 | "joechrisellis", 21 | ] 22 | 23 | [people] 24 | 25 | # A reference list of all people associated with the project. 26 | 27 | [people.hug-dev] 28 | Name = "Hugues de Valon" 29 | Email = "hugues.devalon@arm.com" 30 | GitHub = "hug-dev" 31 | 32 | [people.ionut-arm] 33 | Name = "Ionut Mihalcea" 34 | Email = "ionut.mihalcea@docker.com" 35 | GitHub = "ionut-arm" 36 | 37 | [people.justincormack] 38 | Name = "Justin Cormack" 39 | Email = "justin.cormack@docker.com" 40 | GitHub = "justincormack" 41 | 42 | [people.paulhowardarm] 43 | Name = "Paul Howard" 44 | Email = "paul.howard@arm.com" 45 | GitHub = "paulhowardarm" 46 | 47 | [people.joechrisellis] 48 | Name = "Joe Ellis" 49 | Email = "joe.ellis@arm.com" 50 | GitHub = "joechrisellis" 51 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Parsec Tool 2 | 3 |

4 | Crates.io 5 | Code documentation 6 |

7 | 8 | This repository contains a tool to communicate with the [Parsec 9 | service](https://github.com/parallaxsecond/parsec) on the command-line. 10 | 11 | ## Getting started 12 | 13 | To compile and list the available commands: 14 | 15 | ``` 16 | $ cargo build 17 | $ cargo run 18 | ``` 19 | 20 | Ping the service: 21 | 22 | ``` 23 | $ cargo run -- ping 24 | ``` 25 | 26 | ## Modifying Parsec service endpoint 27 | 28 | For demos and to test the Parsec service, you might want to change the Parsec endpoint location. For 29 | that, set the `PARSEC_SERVICE_ENDPOINT` environment variable to correction endpoint. 30 | 31 | To set a Unix Domain Socket Listener endpoint at `/tmp/parsec.sock`: 32 | 33 | ``` 34 | $ export PARSEC_SERVICE_ENDPOINT=unix:/tmp/parsec.sock 35 | ``` 36 | 37 | ## Modifying logging output 38 | 39 | You can set the `RUST_LOG` environment variable to modify the logging outpout. See [the 40 | documentation](https://docs.rs/env_logger/0.8.3/env_logger/index.html) for more information. 41 | 42 | ## Data format 43 | 44 | Unless specified otherwise below, the data format expected by the commands is the same as describe 45 | in the [Parsec 46 | Book](https://parallaxsecond.github.io/parsec-book/parsec_client/operations/index.html). The 47 | `--help` option of commands might give more information about the expected format. 48 | 49 | - ECDSA signatures are formatted using the ASN.1 representation `Ecdsa-Sig-Value` described in [RFC 50 | 3279](https://tools.ietf.org/html/rfc3279#section-2.2.3). 51 | - Plaintext data is expected/shown as a UTF-8 string (input data of `sign`, output data of 52 | `decrypt`). 53 | - Ciphertext data is expected/shown as base 64 (output data of `sign`, input data of `decrypt`). 54 | - Exported public keys are encoded in PEM. By default PKCS#8 format 55 | is used for RSA [RFC 3279](https://datatracker.ietf.org/doc/html/rfc3279#section-2.3.1) 56 | and ECC [RFC 5480](https://datatracker.ietf.org/doc/html/rfc5480#section-2) 57 | public keys. With `--pkcs1` parameter RSA keys exported in PKCS#1 format 58 | [RFC 2313](https://datatracker.ietf.org/doc/html/rfc2313#section-7.1). 59 | 60 | ## SPIFFE based authenticator 61 | 62 | To be able to authenticate with the [JWT-SVID 63 | authenticator](https://parallaxsecond.github.io/parsec-book/parsec_service/authenticators.html#jwt-spiffe-verifiable-identity-document-authenticator), 64 | compile this crate with the `spiffe-auth` feature. 65 | 66 | # Demo 67 | 68 | [![asciicast](https://asciinema.org/a/RNPjvbgKDlQ0FRFUUKjjNUom6.svg)](https://asciinema.org/a/RNPjvbgKDlQ0FRFUUKjjNUom6) 69 | 70 | `tests/parsec-cli-tests.sh` can be used for end to end Parsec tests using parsec-tool. 71 | 72 | # License 73 | 74 | The software is provided under Apache-2.0. Contributions to this project are accepted under the same 75 | license. 76 | 77 | # Contributing 78 | 79 | Please check the [**Contribution 80 | Guidelines**](https://parallaxsecond.github.io/parsec-book/contributing/index.html) to know more 81 | about the contribution process. 82 | 83 | *Copyright 2020 Contributors to the Parsec project.* 84 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security policy 2 | 3 | Security is of paramount importance to the Parsec project. We do all we can to identify and fix 4 | issues, however some problems might slip through the cracks. Any efforts towards responsible 5 | disclosure of security problems are greatly appreciated and your contributions will be acknowledged. 6 | 7 | ## Supported versions 8 | 9 | Currently only the most recent version of the Parsec tool is eligible for patching. This could 10 | change in the future. 11 | 12 | | Version | Supported | 13 | |------------------|-----------| 14 | | 0.5.0 and higher | ✅ | 15 | | 0.4.0 and lower | ❌ | 16 | 17 | ## Our disclosure policy 18 | 19 | All security vulnerabilities affecting the Parsec service - including those reported using the steps 20 | highlighted below, those discovered during routine testing, and those found in our dependency tree 21 | either through `cargo-audit` or otherwise - will receive [security 22 | advisories](https://github.com/parallaxsecond/parsec-tool/security/advisories) in a timely manner. 23 | The advisories should include sufficient information about the cause, effect, and possible 24 | mitigations for the vulnerability. If any information is missing, or you would like to raise a 25 | question about the advisories, please open an issue in [our 26 | repo](https://github.com/parallaxsecond/parsec-tool). 27 | 28 | Efforts to mitigate for the reported vulnerabilities will be tracked using Github issues linked to 29 | the corresponding advisories. 30 | 31 | ## Reporting a vulnerability 32 | 33 | To report a vulnerability, please send an email to 34 | [cncf-parsec-maintainers@lists.cncf.io](mailto:cncf-parsec-maintainers@lists.cncf.io). We will reply 35 | to acknowledge your report and we'll strive to keep you in the loop as we try to reach a resolution. 36 | -------------------------------------------------------------------------------- /clippy.toml: -------------------------------------------------------------------------------- 1 | allowed-duplicate-crates = ["base64", "syn"] 2 | -------------------------------------------------------------------------------- /patches/rcgen+0.13.1.patch: -------------------------------------------------------------------------------- 1 | diff --git a/src/key_pair.rs b/src/key_pair.rs 2 | index 00beea6..1c71fc5 100644 3 | --- a/src/key_pair.rs 4 | +++ b/src/key_pair.rs 5 | @@ -252,6 +252,9 @@ impl KeyPair { 6 | } else if alg == &PKCS_RSA_PSS_SHA256 { 7 | let rsakp = RsaKeyPair::from_pkcs8(&serialized_der)._err()?; 8 | KeyPairKind::Rsa(rsakp, &signature::RSA_PSS_SHA256) 9 | + }else if alg == &PKCS_RSA_PSS_SHA384 { 10 | + let rsakp = RsaKeyPair::from_pkcs8(&serialized_der)._err()?; 11 | + KeyPairKind::Rsa(rsakp, &signature::RSA_PSS_SHA384) 12 | } else { 13 | #[cfg(feature = "aws_lc_rs")] 14 | if alg == &PKCS_ECDSA_P521_SHA512 { 15 | diff --git a/src/sign_algo.rs b/src/sign_algo.rs 16 | index 5d7052a..2c85d04 100644 17 | --- a/src/sign_algo.rs 18 | +++ b/src/sign_algo.rs 19 | @@ -89,6 +89,7 @@ impl SignatureAlgorithm { 20 | &PKCS_RSA_SHA384, 21 | &PKCS_RSA_SHA512, 22 | //&PKCS_RSA_PSS_SHA256, 23 | + //&PKCS_RSA_PSS_SHA384, 24 | &PKCS_ECDSA_P256_SHA256, 25 | &PKCS_ECDSA_P384_SHA384, 26 | #[cfg(feature = "aws_lc_rs")] 27 | @@ -151,21 +152,37 @@ pub(crate) mod algo { 28 | // support those: https://github.com/briansmith/ring/issues/1353 29 | // 30 | /// RSA signing with PKCS#1 2.1 RSASSA-PSS padding and SHA-256 hashing as per [RFC 4055](https://tools.ietf.org/html/rfc4055) 31 | - pub(crate) static PKCS_RSA_PSS_SHA256: SignatureAlgorithm = SignatureAlgorithm { 32 | + pub static PKCS_RSA_PSS_SHA256: SignatureAlgorithm = SignatureAlgorithm { 33 | // We could also use RSA_ENCRYPTION here, but it's recommended 34 | // to use ID-RSASSA-PSS if possible. 35 | oids_sign_alg: &[&RSASSA_PSS], 36 | #[cfg(feature = "crypto")] 37 | sign_alg: SignAlgo::Rsa(&signature::RSA_PSS_SHA256), 38 | - oid_components: RSASSA_PSS, //&[1, 2, 840, 113549, 1, 1, 13], 39 | + oid_components: RSASSA_PSS, //&[1, 2, 840, 113549, 1, 1, 10], 40 | // rSASSA-PSS-SHA256-Params in RFC 4055 41 | params: SignatureAlgorithmParams::RsaPss { 42 | // id-sha256 in https://datatracker.ietf.org/doc/html/rfc4055#section-2.1 43 | hash_algorithm: &[2, 16, 840, 1, 101, 3, 4, 2, 1], 44 | - salt_length: 20, 45 | + salt_length: 32, 46 | }, 47 | }; 48 | 49 | + /// RSA signing with PKCS#1 2.1 RSASSA-PSS padding and SHA-384 hashing as per [RFC 4055](https://tools.ietf.org/html/rfc4055) 50 | + pub static PKCS_RSA_PSS_SHA384 :SignatureAlgorithm = SignatureAlgorithm { 51 | + // We could also use OID_RSA_ENCRYPTION here, but it's recommended 52 | + // to use ID-RSASSA-PSS if possible. 53 | + oids_sign_alg: &[&RSASSA_PSS], 54 | + #[cfg(feature = "crypto")] 55 | + sign_alg :SignAlgo::Rsa(&signature::RSA_PSS_SHA384), 56 | + oid_components : RSASSA_PSS, //&[1, 2, 840, 113549, 1, 1, 10], 57 | + // rSASSA-PSS-SHA384-Params in RFC 4055 58 | + params : SignatureAlgorithmParams::RsaPss { 59 | + // id-sha384 in https://datatracker.ietf.org/doc/html/rfc4055#section-2.1 60 | + hash_algorithm : &[2, 16, 840, 1, 101, 3, 4, 2, 2], 61 | + salt_length : 48, 62 | + }, 63 | + }; 64 | + 65 | /// ECDSA signing using the P-256 curves and SHA-256 hashing as per [RFC 5758](https://tools.ietf.org/html/rfc5758#section-3.2) 66 | pub static PKCS_ECDSA_P256_SHA256: SignatureAlgorithm = SignatureAlgorithm { 67 | oids_sign_alg: &[&EC_PUBLIC_KEY, &EC_SECP_256_R1], 68 | -------------------------------------------------------------------------------- /src/cli/mod.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Contributors to the Parsec project. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! Base CLI implementation. 5 | 6 | use crate::common::{PROJECT_AUTHOR, PROJECT_DESC, PROJECT_NAME, PROJECT_VERSION}; 7 | use crate::subcommands::Subcommand; 8 | use clap::Parser; 9 | 10 | /// Struct representing the command-line interface of parsec-tool. 11 | #[derive(Debug, Parser)] 12 | #[structopt(name=PROJECT_NAME, about=PROJECT_DESC, author=PROJECT_AUTHOR, version=PROJECT_VERSION)] 13 | pub struct ParsecToolApp { 14 | /// The ID of the provider to target for the command. Will use the default provider if not specified. 15 | #[structopt(short = 'p', long = "provider")] 16 | pub provider: Option, 17 | 18 | /// The timeout time used for all commands in seconds. Will use the client's default if not specified. If 19 | /// set to 0, will not use any timeout and will block indefinitely. 20 | #[structopt(short = 't', long = "timeout")] 21 | pub timeout: Option, 22 | 23 | /// The subcommand -- e.g., ping. 24 | #[structopt(subcommand)] 25 | pub subcommand: Subcommand, 26 | } 27 | -------------------------------------------------------------------------------- /src/common.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Contributors to the Parsec project. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! Common variables. 5 | 6 | /// The project name from Cargo. 7 | pub const PROJECT_NAME: &str = env!("CARGO_PKG_NAME"); 8 | 9 | /// The project description from Cargo. 10 | pub const PROJECT_DESC: &str = env!("CARGO_PKG_DESCRIPTION"); 11 | 12 | /// The project author from Cargo. 13 | pub const PROJECT_AUTHOR: &str = env!("CARGO_PKG_AUTHORS"); 14 | 15 | /// The project version from Cargo. 16 | pub const PROJECT_VERSION: &str = env!("CARGO_PKG_VERSION"); 17 | -------------------------------------------------------------------------------- /src/error.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Contributors to the Parsec project. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! Error definitions/handling. 5 | 6 | use thiserror::Error; 7 | 8 | /// Errors in parsec-tool. 9 | #[derive(Error, Debug)] 10 | pub enum Error { 11 | /// Error emanating from the parsec_client crate. 12 | #[error(transparent)] 13 | IoError(#[from] std::io::Error), 14 | 15 | /// Error emanating from the parsec_client crate. 16 | #[error(transparent)] 17 | ParsecClientError(#[from] parsec_client::error::Error), 18 | 19 | /// Error emanating from the parsec_client::core::interface crate. 20 | #[error(transparent)] 21 | ParsecInterfaceError(#[from] parsec_client::core::interface::requests::ResponseStatus), 22 | 23 | /// Error emanating from the parsec-tool. 24 | #[error(transparent)] 25 | ParsecToolError(#[from] ToolErrorKind), 26 | 27 | /// Error emanating from the base64 crate. 28 | #[error(transparent)] 29 | Base64Decode(#[from] base64::DecodeError), 30 | 31 | /// Error emanating from the rcgen create (can occur when creating certificates or CSRs) 32 | #[error(transparent)] 33 | RcgenError(#[from] rcgen::Error), 34 | } 35 | 36 | /// Errors originating in the parsec-tool. 37 | #[derive(Error, Debug)] 38 | pub enum ToolErrorKind { 39 | /// Operation not supported by the parsec-tool 40 | #[error("Operation not supported by the parsec-tool")] 41 | NotSupported, 42 | 43 | /// They key was not created with the correct algorithm for this operation 44 | #[error("They key was not created with the correct algorithm for this operation")] 45 | WrongKeyAlgorithm, 46 | 47 | /// Expected input data was not given 48 | #[error("A command expected input data that was not given")] 49 | NoInput, 50 | 51 | /// Cannot serialise or deserialise data 52 | #[error("Incorrect data format")] 53 | IncorrectData, 54 | } 55 | 56 | /// A Result type with the Err variant set as a ParsecToolError 57 | pub type Result = std::result::Result; 58 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Contributors to the Parsec project. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! Source code for the `parsec-tool` project. This is a command-line interface for interacting 5 | //! with the Parsec service. 6 | 7 | #![deny( 8 | dead_code, 9 | improper_ctypes, 10 | missing_debug_implementations, 11 | missing_docs, 12 | no_mangle_generic_items, 13 | non_shorthand_field_patterns, 14 | nonstandard_style, 15 | overflowing_literals, 16 | path_statements, 17 | patterns_in_fns_without_body, 18 | private_bounds, 19 | private_interfaces, 20 | renamed_and_removed_lints, 21 | trivial_casts, 22 | trivial_numeric_casts, 23 | unconditional_recursion, 24 | unused, 25 | unused_allocation, 26 | unused_comparisons, 27 | unused_extern_crates, 28 | unused_import_braces, 29 | unused_parens, 30 | unused_qualifications, 31 | unused_results, 32 | while_true 33 | )] 34 | // This one is hard to avoid. 35 | #![allow(clippy::multiple_crate_versions)] 36 | 37 | pub mod cli; 38 | pub mod common; 39 | pub mod error; 40 | pub mod subcommands; 41 | pub mod util; 42 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Contributors to the Parsec project. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! parsec-tool: a tool for interfacing with the Parsec service from the command-line. 5 | 6 | use clap::Parser; 7 | use log::error; 8 | use parsec_tool::cli; 9 | use parsec_tool::common::PROJECT_NAME; 10 | use std::convert::TryInto; 11 | 12 | fn main() { 13 | let mut env_log_builder = env_logger::Builder::new(); 14 | // By default, only show the logs from this crate. 15 | env_log_builder.filter_level(log::LevelFilter::Info); 16 | env_log_builder.format_timestamp(None); 17 | env_log_builder.format_module_path(false); 18 | 19 | // Allows to still set configuration via the default environment variable 20 | env_log_builder.parse_default_env(); 21 | env_log_builder.init(); 22 | 23 | let matches = cli::ParsecToolApp::parse(); 24 | 25 | let mut client = match matches 26 | .subcommand 27 | .create_client(Some(PROJECT_NAME.to_string())) 28 | { 29 | Err(e) => { 30 | error!("Error spinning up the BasicClient: {}", e); 31 | std::process::exit(1); 32 | } 33 | Ok(client) => client, 34 | }; 35 | 36 | if let Some(provider) = matches.provider { 37 | let provider = match provider.try_into() { 38 | Err(_) => { 39 | error!("The provider ID entered does not map with an existing provider"); 40 | std::process::exit(1); 41 | } 42 | Ok(provider) => provider, 43 | }; 44 | client.set_implicit_provider(provider); 45 | } 46 | 47 | if let Some(timeout) = matches.timeout { 48 | let timeout = if timeout == 0 { 49 | None 50 | } else { 51 | Some(std::time::Duration::from_secs(timeout.into())) 52 | }; 53 | client.set_timeout(timeout); 54 | } 55 | 56 | if let Err(e) = matches.subcommand.run(client) { 57 | error!("Subcommand failed: {} ({:?})", e, e); 58 | std::process::exit(1); 59 | } 60 | 61 | std::process::exit(0); 62 | } 63 | -------------------------------------------------------------------------------- /src/subcommands/create_csr.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2021 Contributors to the Parsec project. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! Creates a Certificate Signing Request (CSR) from a keypair. 5 | 6 | use crate::error::{Error, Result, ToolErrorKind}; 7 | use crate::util::sign_message_with_policy; 8 | use clap::Parser; 9 | use log::error; 10 | use parsec_client::core::interface::operations::psa_algorithm::{ 11 | Algorithm, AsymmetricSignature, Hash, SignHash, 12 | }; 13 | use parsec_client::core::interface::operations::psa_key_attributes::{EccFamily, Type}; 14 | use parsec_client::BasicClient; 15 | use rcgen::Error as RcgenError; 16 | use rcgen::{ 17 | CertificateParams, DistinguishedName, DnType, KeyPair, RemoteKeyPair, SignatureAlgorithm, 18 | PKCS_ECDSA_P256_SHA256, PKCS_ECDSA_P384_SHA384, PKCS_RSA_PSS_SHA256, PKCS_RSA_PSS_SHA384, 19 | PKCS_RSA_SHA256, PKCS_RSA_SHA384, PKCS_RSA_SHA512, 20 | }; 21 | 22 | /// Creates an X509 Certificate Signing Request (CSR) from a keypair, using the signing algorithm 23 | /// that is associated with the key. 24 | /// 25 | /// The CSR is written to the standard output in PEM format by default. 26 | #[derive(Debug, Parser)] 27 | pub struct CreateCsr { 28 | /// The name of the key to use for signing. This must be an existing key that is accessible 29 | /// to the user, and it must be a signing key (either an RSA key or an elliptic curve key). 30 | /// 31 | /// Elliptic curve keys must use the NIST P256 or P384 curves. 32 | #[structopt(short = 'k', long = "key-name")] 33 | key_name: String, 34 | 35 | /// The common name to be used within the Distinguished Name (DN) specification of 36 | /// the CSR. 37 | #[structopt(long = "cn")] 38 | common_name: Option, 39 | 40 | /// The locality name to be used within the Distinguished Name (DN) specification of 41 | /// the CSR. 42 | #[structopt(long = "l")] 43 | locality: Option, 44 | 45 | /// The organization name to be used within the Distinguished Name (DN) specification of 46 | /// the CSR. 47 | #[structopt(long = "o")] 48 | organization: Option, 49 | 50 | /// The organizational unit name to be used within the Distinguished Name (DN) specification 51 | /// of the CSR. 52 | #[structopt(long = "ou")] 53 | organizational_unit: Option, 54 | 55 | /// The state name to be used within the Distinguished Name (DN) specification of the CSR. 56 | #[structopt(long = "st")] 57 | state: Option, 58 | 59 | /// The country name to be used within the Distinguished Name (DN) specification of the CSR. 60 | #[structopt(long = "c")] 61 | country: Option, 62 | 63 | /// The serial number to be used within the Distinguished Name (DN) specification of the CSR. 64 | #[structopt(long = "serialNumber")] 65 | serial_number: Option, 66 | 67 | /// A Subject Alternative Name (SAN) for the domain of the CSR. 68 | #[structopt(long = "san")] 69 | subject_alternative_name: Option>, 70 | } 71 | 72 | /// Short-lived structure to encapsulate the key name and the client, so that we can implement the 73 | /// RemoteKeyPair trait for rcgen. 74 | struct ParsecRemoteKeyPair { 75 | key_name: String, 76 | public_key_der: Vec, 77 | parsec_client: BasicClient, 78 | rcgen_algorithm: &'static SignatureAlgorithm, 79 | } 80 | 81 | impl CreateCsr { 82 | /// Creates a Certificate Signing Request (CSR) from a keypair. 83 | pub fn run(&self, basic_client: BasicClient) -> Result<()> { 84 | let public_key = basic_client.psa_export_public_key(&self.key_name)?; 85 | 86 | let rcgen_algorithm = self.get_rcgen_algorithm(&basic_client)?; 87 | 88 | let parsec_key_pair = ParsecRemoteKeyPair { 89 | key_name: self.key_name.clone(), 90 | public_key_der: public_key, 91 | // "Move" the client into the struct here. 92 | parsec_client: basic_client, 93 | rcgen_algorithm, 94 | }; 95 | 96 | let remote_key_pair = KeyPair::from_remote(Box::new(parsec_key_pair))?; 97 | 98 | let subject_alt_names = match &self.subject_alternative_name { 99 | Some(san) => san.to_owned(), 100 | None => Vec::new(), 101 | }; 102 | 103 | let mut dn = DistinguishedName::new(); 104 | 105 | if let Some(common_name) = &self.common_name { 106 | dn.push(DnType::CommonName, common_name.clone()); 107 | } 108 | 109 | if let Some(organizational_unit) = &self.organizational_unit { 110 | // NOTE: X509 permits multiple OUs, but the RCGEN crate only preserves one entry, so for now the 111 | // parsec-tool also only accepts one entry on the command-line. If this changes in the future, it 112 | // will be possible to evolve the command-line parser to accept multiple values without it being 113 | // a breaking change. 114 | dn.push(DnType::OrganizationalUnitName, organizational_unit.clone()); 115 | } 116 | 117 | if let Some(organization) = &self.organization { 118 | dn.push(DnType::OrganizationName, organization.clone()); 119 | } 120 | 121 | if let Some(locality) = &self.locality { 122 | dn.push(DnType::LocalityName, locality.clone()); 123 | } 124 | 125 | if let Some(state) = &self.state { 126 | dn.push(DnType::StateOrProvinceName, state.clone()); 127 | } 128 | 129 | if let Some(country) = &self.country { 130 | dn.push(DnType::CountryName, country.clone()); 131 | } 132 | 133 | if let Some(serial_number) = &self.serial_number { 134 | // Rcgen does not have a DnType::SerialNumber, so use DnType::CustomDnType and supply the 135 | // Object ID (OID) numerically. The OID for X509 serialNumber is 2.5.4.5 according to 136 | // https://www.alvestrand.no/objectid/2.5.4.5.html and other sources. 137 | dn.push( 138 | DnType::CustomDnType(vec![2, 5, 4, 5]), 139 | serial_number.clone(), 140 | ); 141 | } 142 | 143 | let mut params = CertificateParams::new(subject_alt_names)?; 144 | params.distinguished_name = dn; 145 | 146 | let cert = params.self_signed(&remote_key_pair)?; 147 | let csr = cert.params().serialize_request(&remote_key_pair)?; 148 | 149 | let pem_string = csr.pem()?; 150 | println!("{}", pem_string); 151 | 152 | Ok(()) 153 | } 154 | 155 | // Inspect the attributes of the signing key and map them down to one of rcgen's supported hash-and-sign 156 | // schemes (throwing an error if there isn't a suitable mapping). 157 | // 158 | // There's rather a lot of complexity here, because we need to map down lots of nested PSA properties onto a small number 159 | // of hash-and-sign schemes that RCGEN supports. 160 | fn get_rcgen_algorithm( 161 | &self, 162 | basic_client: &BasicClient, 163 | ) -> Result<&'static SignatureAlgorithm> { 164 | let attributes = basic_client.key_attributes(&self.key_name)?; 165 | 166 | if let Algorithm::AsymmetricSignature(alg) = attributes.policy.permitted_algorithms { 167 | match alg { 168 | AsymmetricSignature::RsaPkcs1v15Sign { hash_alg } => match hash_alg { 169 | SignHash::Specific(Hash::Sha256) => Ok(&PKCS_RSA_SHA256), 170 | SignHash::Specific(Hash::Sha384) => Ok(&PKCS_RSA_SHA384), 171 | SignHash::Specific(Hash::Sha512) => Ok(&PKCS_RSA_SHA512), 172 | SignHash::Any => Ok(&PKCS_RSA_SHA256), // Default hash algorithm for the tool. 173 | _ => { 174 | // The algorithm is specific, but not one that RCGEN can use, so fail the operation. 175 | error!("Signing key requires use of hashing algorithm ({:?}), which is not supported for certificate requests.", alg); 176 | Err(ToolErrorKind::NotSupported.into()) 177 | } 178 | }, 179 | AsymmetricSignature::RsaPkcs1v15SignRaw => { 180 | // Key policy specifies raw RSA signatures. RCGEN will always hash-and-sign, so fail. 181 | error!("Signing key specifies raw signing only, which is not supported for certificate requests."); 182 | Err(ToolErrorKind::NotSupported.into()) 183 | } 184 | AsymmetricSignature::RsaPss { hash_alg } => match hash_alg { 185 | SignHash::Specific(Hash::Sha256) => Ok(&PKCS_RSA_PSS_SHA256), 186 | SignHash::Specific(Hash::Sha384) => Ok(&PKCS_RSA_PSS_SHA384), 187 | SignHash::Any => Ok(&PKCS_RSA_PSS_SHA256), // Default hash algorithm for the tool. 188 | _ => { 189 | // The algorithm is specific, but not one that RCGEN can use, so fail the operation. 190 | error!("Signing key requires use of hashing algorithm ({:?}), which is not supported for certificate requests.", alg); 191 | Err(ToolErrorKind::NotSupported.into()) 192 | } 193 | }, 194 | AsymmetricSignature::Ecdsa { hash_alg } => { 195 | if !matches!( 196 | attributes.key_type, 197 | Type::EccKeyPair { 198 | curve_family: EccFamily::SecpR1 199 | } 200 | ) { 201 | error!( 202 | "Signing key must use curve family SecpR1 for certificate requests." 203 | ); 204 | return Err(ToolErrorKind::NotSupported.into()); 205 | }; 206 | 207 | match hash_alg { 208 | SignHash::Specific(Hash::Sha256) => { 209 | if attributes.bits == 256 { 210 | Ok(&PKCS_ECDSA_P256_SHA256) 211 | } else { 212 | error!("Signing key should have strength 256, but actually has strength {}.", attributes.bits); 213 | Err(ToolErrorKind::NotSupported.into()) 214 | } 215 | } 216 | SignHash::Specific(Hash::Sha384) => { 217 | if attributes.bits == 384 { 218 | Ok(&PKCS_ECDSA_P384_SHA384) 219 | } else { 220 | error!("Signing key should have strength 384, but actually has strength {}.", attributes.bits); 221 | Err(ToolErrorKind::NotSupported.into()) 222 | } 223 | } 224 | SignHash::Any => { 225 | match attributes.bits { 226 | 256 => Ok(&PKCS_ECDSA_P256_SHA256), 227 | _ => { 228 | // We have to fail this, because ParsecRemoteKeyPair::sign() defaults the hash to SHA-256, and RCGEN 229 | // doesn't support a hash algorithm that is different from the key strength. 230 | error!("Signing keys of strength other than 256-bit not supported without specific hash algorithm."); 231 | Err(ToolErrorKind::NotSupported.into()) 232 | } 233 | } 234 | } 235 | _ => { 236 | // The algorithm is specific, but not one that RCGEN can use, so fail the operation. 237 | error!("Signing key requires use of hashing algorithm ({:?}), which is not supported for certificate requests.", alg); 238 | Err(ToolErrorKind::NotSupported.into()) 239 | } 240 | } 241 | } 242 | _ => { 243 | // Unsupported algorithm. 244 | error!("The specified key is not supported for certificate requests."); 245 | Err(ToolErrorKind::NotSupported.into()) 246 | } 247 | } 248 | } else { 249 | error!("Specified key is not an asymmetric signing key, which is needed for certificate requests."); 250 | Err(ToolErrorKind::WrongKeyAlgorithm.into()) 251 | } 252 | } 253 | } 254 | 255 | impl RemoteKeyPair for ParsecRemoteKeyPair { 256 | fn public_key(&self) -> &[u8] { 257 | &self.public_key_der 258 | } 259 | 260 | fn sign(&self, msg: &[u8]) -> std::result::Result, RcgenError> { 261 | let signature = 262 | sign_message_with_policy(&self.parsec_client, &self.key_name, msg, Some(Hash::Sha256)) 263 | .map_err(RcgenError::from)?; 264 | Ok(signature) 265 | } 266 | 267 | fn algorithm(&self) -> &'static SignatureAlgorithm { 268 | self.rcgen_algorithm 269 | } 270 | } 271 | 272 | impl From for RcgenError { 273 | fn from(_e: Error) -> Self { 274 | // There isn't a suitable mapping, because RcgenError does not have a variant for the 275 | // case where RemoteKeyPair failed for third-party reasons. 276 | // See: https://github.com/est31/rcgen/issues/67 277 | // The crate will publish a new enum variant. When this change is released, we can rework this to be a 278 | // more suitable error. 279 | RcgenError::KeyGenerationUnavailable 280 | } 281 | } 282 | -------------------------------------------------------------------------------- /src/subcommands/create_ecc_key.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2021 Contributors to the Parsec project. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! Create an ECC key pair. 5 | //! 6 | use crate::error::Result; 7 | use clap::Parser; 8 | use log::info; 9 | /// The curve will be secp256r1. Used by default for asymmetric signing with ECDSA (SHA-256). 10 | use parsec_client::core::interface::operations::psa_algorithm::{AsymmetricSignature, Hash}; 11 | use parsec_client::core::interface::operations::psa_key_attributes::{ 12 | Attributes, EccFamily, Lifetime, Policy, Type, UsageFlags, 13 | }; 14 | use parsec_client::BasicClient; 15 | 16 | /// Create an ECC key pair. 17 | #[derive(Debug, Parser)] 18 | pub struct CreateEccKey { 19 | #[structopt(short = 'k', long = "key-name")] 20 | key_name: String, 21 | } 22 | 23 | impl CreateEccKey { 24 | /// Exports a key. 25 | pub fn run(&self, basic_client: BasicClient) -> Result<()> { 26 | info!("Creating ECC signing key..."); 27 | 28 | let attributes = Attributes { 29 | lifetime: Lifetime::Persistent, 30 | key_type: Type::EccKeyPair { 31 | curve_family: EccFamily::SecpR1, 32 | }, 33 | bits: 256, 34 | policy: Policy { 35 | usage_flags: { 36 | let mut usage_flags = UsageFlags::default(); 37 | let _ = usage_flags 38 | .set_sign_hash() 39 | .set_sign_message() 40 | .set_verify_hash() 41 | .set_verify_message(); 42 | usage_flags 43 | }, 44 | permitted_algorithms: AsymmetricSignature::Ecdsa { 45 | hash_alg: Hash::Sha256.into(), 46 | } 47 | .into(), 48 | }, 49 | }; 50 | 51 | basic_client.psa_generate_key(&self.key_name, attributes)?; 52 | 53 | info!("Key \"{}\" created.", self.key_name); 54 | Ok(()) 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/subcommands/create_rsa_key.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2021 Contributors to the Parsec project. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! Create a RSA key pair 5 | //! 6 | //! The key will be 2048 bits long. Used by default for asymmetric encryption with RSA PKCS#1 v1.5. 7 | 8 | use crate::error::Result; 9 | use clap::Parser; 10 | use log::info; 11 | use parsec_client::core::interface::operations::psa_algorithm::{ 12 | AsymmetricEncryption, AsymmetricSignature, Hash, SignHash, 13 | }; 14 | use parsec_client::core::interface::operations::psa_key_attributes::{ 15 | Attributes, Lifetime, Policy, Type, UsageFlags, 16 | }; 17 | use parsec_client::BasicClient; 18 | 19 | /// Create a RSA key pair. 20 | #[derive(Debug, Parser)] 21 | pub struct CreateRsaKey { 22 | #[structopt(short = 'k', long = "key-name")] 23 | key_name: String, 24 | 25 | /// This command creates RSA encryption keys by default. Supply this flag to create a signing key instead. 26 | /// Signing keys, by default, will specify the SHA-256 hash algorithm and use PKCS#1 v1.5. 27 | /// This has priority over ("r", "for-signing-pss") option. 28 | #[structopt(short = 's', long = "for-signing")] 29 | is_for_signing: bool, 30 | 31 | /// Supply this flag to create a signing key with PSS scheme and SHA-256 hash algorithm. 32 | #[structopt(short = 'r', long = "for-signing-pss")] 33 | is_for_signing_pss: bool, 34 | 35 | /// Specifies the size (strength) of the key in bits. The default size for RSA keys is 2048 bits. 36 | #[structopt(short = 'b', long = "bits")] 37 | bits: Option, 38 | 39 | /// Specifies if the RSA key should be created with permitted RSA OAEP (SHA256) encryption algorithm 40 | /// instead of the default RSA PKCS#1 v1.5 one. 41 | #[structopt(short = 'o', long = "oaep")] 42 | oaep: bool, 43 | } 44 | 45 | impl CreateRsaKey { 46 | /// Exports a key. 47 | pub fn run(&self, basic_client: BasicClient) -> Result<()> { 48 | let policy = if self.is_for_signing { 49 | // If both "-s" and "-r" flags are set, then "-s" takes precedence 50 | info!("Creating RSA signing key with PKCS1 v1.5 scheme..."); 51 | Policy { 52 | usage_flags: { 53 | let mut usage_flags = UsageFlags::default(); 54 | let _ = usage_flags 55 | .set_sign_hash() 56 | .set_verify_hash() 57 | .set_sign_message() 58 | .set_verify_message(); 59 | usage_flags 60 | }, 61 | permitted_algorithms: AsymmetricSignature::RsaPkcs1v15Sign { 62 | hash_alg: SignHash::Specific(Hash::Sha256), 63 | } 64 | .into(), 65 | } 66 | } else if self.is_for_signing_pss { 67 | info!("Creating RSA signing key with PSS scheme..."); 68 | Policy { 69 | usage_flags: { 70 | let mut usage_flags = UsageFlags::default(); 71 | let _ = usage_flags 72 | .set_sign_hash() 73 | .set_verify_hash() 74 | .set_sign_message() 75 | .set_verify_message(); 76 | usage_flags 77 | }, 78 | permitted_algorithms: AsymmetricSignature::RsaPss { 79 | hash_alg: SignHash::Specific(Hash::Sha256), 80 | } 81 | .into(), 82 | } 83 | } else { 84 | info!("Creating RSA encryption key..."); 85 | Policy { 86 | usage_flags: { 87 | let mut usage_flags = UsageFlags::default(); 88 | let _ = usage_flags.set_encrypt().set_decrypt(); 89 | usage_flags 90 | }, 91 | permitted_algorithms: if self.oaep { 92 | AsymmetricEncryption::RsaOaep { 93 | hash_alg: Hash::Sha256, 94 | } 95 | .into() 96 | } else { 97 | AsymmetricEncryption::RsaPkcs1v15Crypt.into() 98 | }, 99 | } 100 | }; 101 | 102 | let attributes = Attributes { 103 | lifetime: Lifetime::Persistent, 104 | key_type: Type::RsaKeyPair, 105 | // No prior validation of 'bits' argument. We have to let the service (and back-end hardware) 106 | // decide what is valid. The PSA specification does not enforce any minimum/maximum/supported 107 | // sizes for RSA keys. 108 | bits: self.bits.unwrap_or(2048), 109 | policy, 110 | }; 111 | 112 | basic_client.psa_generate_key(&self.key_name, attributes)?; 113 | 114 | info!("Key \"{}\" created.", self.key_name); 115 | Ok(()) 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /src/subcommands/decrypt.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2021 Contributors to the Parsec project. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! Decrypts data. 5 | //! 6 | //! Will use the algorithm set to the key's policy during creation. 7 | 8 | use crate::error::{Result, ToolErrorKind}; 9 | use clap::Parser; 10 | use log::{error, info}; 11 | use parsec_client::core::interface::operations::psa_algorithm::Algorithm; 12 | use parsec_client::BasicClient; 13 | 14 | /// Decrypts data. 15 | #[derive(Debug, Parser)] 16 | pub struct Decrypt { 17 | #[structopt(short = 'k', long = "key-name")] 18 | key_name: String, 19 | 20 | /// Ciphertext base64 encoded 21 | input_data: String, 22 | } 23 | 24 | impl Decrypt { 25 | /// Decrypts data. 26 | pub fn run(&self, basic_client: BasicClient) -> Result<()> { 27 | let input = base64::decode(self.input_data.as_bytes())?; 28 | 29 | let alg = basic_client 30 | .key_attributes(&self.key_name)? 31 | .policy 32 | .permitted_algorithms; 33 | 34 | let plaintext = match alg { 35 | Algorithm::AsymmetricEncryption(alg) => { 36 | info!("Decrypting data with {:?}...", alg); 37 | basic_client.psa_asymmetric_decrypt(&self.key_name, alg, &input, None)? 38 | } 39 | Algorithm::Cipher(_) | Algorithm::Aead(_) => { 40 | error!( 41 | "Key's algorithm is {:?} which is not currently supported for decryption.", 42 | alg 43 | ); 44 | return Err(ToolErrorKind::NotSupported.into()); 45 | } 46 | other => { 47 | error!( 48 | "Key's algorithm is {:?} which can not be used for decryption.", 49 | other 50 | ); 51 | return Err(ToolErrorKind::WrongKeyAlgorithm.into()); 52 | } 53 | }; 54 | 55 | let plaintext = String::from_utf8_lossy(&plaintext).to_string(); 56 | 57 | println!("{}", plaintext); 58 | 59 | Ok(()) 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/subcommands/delete_client.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2021 Contributors to the Parsec project. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! Delete all data a client has in the service (admin operation). 5 | 6 | use crate::error::Result; 7 | 8 | use clap::Parser; 9 | use log::info; 10 | use parsec_client::BasicClient; 11 | 12 | /// Delete all data a client has in the service (admin operation). 13 | #[derive(Debug, Parser)] 14 | pub struct DeleteClient { 15 | #[structopt(short = 'c', long = "client")] 16 | client: String, 17 | } 18 | 19 | impl DeleteClient { 20 | pub fn run(&self, basic_client: BasicClient) -> Result<()> { 21 | basic_client.delete_client(&self.client)?; 22 | 23 | info!("Client \"{}\" deleted.", self.client); 24 | Ok(()) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/subcommands/delete_key.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Contributors to the Parsec project. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! Delete a key. 5 | 6 | use crate::error::Result; 7 | use clap::Parser; 8 | use log::info; 9 | use parsec_client::BasicClient; 10 | 11 | /// Delete a key. 12 | #[derive(Debug, Parser)] 13 | pub struct DeleteKey { 14 | #[structopt(short = 'k', long = "key-name")] 15 | key_name: String, 16 | } 17 | 18 | impl DeleteKey { 19 | /// Destroys a key. 20 | pub fn run(&self, basic_client: BasicClient) -> Result<()> { 21 | info!("Deleting a key..."); 22 | 23 | basic_client.psa_destroy_key(&self.key_name)?; 24 | 25 | info!("Key \"{}\" deleted.", self.key_name); 26 | Ok(()) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/subcommands/encrypt.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Contributors to the Parsec project. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! Encrypts some plaintext data with a specified key. 5 | //! 6 | //! Will use the algorithm set to the key's policy during creation. Currently only 7 | //! supports asymmetric encryption such as RSA, in which case the specified key must 8 | //! be a public key or an asymmetric key pair (of which the public part will be 9 | //! used). It is not possible to encrypt data using the private part of an asymmetric 10 | //! key pair. Encryption with symmetric keys will be added in the future. 11 | //! 12 | //! No salt is used. 13 | //! 14 | //! The input is a plain text message string, which is treated as raw bytes. 15 | //! 16 | //! The output is base64-encoded ciphertext. 17 | 18 | use crate::error::{Result, ToolErrorKind}; 19 | use clap::Parser; 20 | use log::{error, info}; 21 | use parsec_client::core::interface::operations::psa_algorithm::Algorithm; 22 | use parsec_client::BasicClient; 23 | 24 | /// Encrypts data. 25 | #[derive(Debug, Parser)] 26 | pub struct Encrypt { 27 | #[structopt(short = 'k', long = "key-name")] 28 | key_name: String, 29 | 30 | /// Plaintext input string. 31 | input_data: String, 32 | } 33 | 34 | impl Encrypt { 35 | /// Encrypts data. 36 | pub fn run(&self, basic_client: BasicClient) -> Result<()> { 37 | let input = self.input_data.as_bytes(); 38 | 39 | let alg = basic_client 40 | .key_attributes(&self.key_name)? 41 | .policy 42 | .permitted_algorithms; 43 | 44 | let ciphertext = match alg { 45 | Algorithm::AsymmetricEncryption(alg) => { 46 | info!("Encrypting data with {:?}...", alg); 47 | basic_client.psa_asymmetric_encrypt(&self.key_name, alg, input, None)? 48 | } 49 | Algorithm::Cipher(_) | Algorithm::Aead(_) => { 50 | error!( 51 | "Key's algorithm is {:?} which is not currently supported for encryption.", 52 | alg 53 | ); 54 | return Err(ToolErrorKind::NotSupported.into()); 55 | } 56 | other => { 57 | error!( 58 | "Key's algorithm is {:?} which cannot be used for encryption.", 59 | other 60 | ); 61 | return Err(ToolErrorKind::WrongKeyAlgorithm.into()); 62 | } 63 | }; 64 | 65 | let ciphertext = base64::encode(ciphertext); 66 | 67 | println!("{}", ciphertext); 68 | 69 | Ok(()) 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/subcommands/export_public_key.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Contributors to the Parsec project. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! Exports a public key. 5 | 6 | use crate::error::{Result, ToolErrorKind}; 7 | use clap::Parser; 8 | use log::error; 9 | use oid::prelude::*; 10 | use parsec_client::core::interface::operations::psa_key_attributes::{EccFamily, Type}; 11 | use parsec_client::BasicClient; 12 | use picky_asn1::bit_string::BitString; 13 | use picky_asn1_x509::{ 14 | AlgorithmIdentifier, EcParameters, PublicKey, RsaPublicKey, SubjectPublicKeyInfo, 15 | }; 16 | 17 | /// Exports a PEM-encoded public key. 18 | #[derive(Debug, Parser)] 19 | pub struct ExportPublicKey { 20 | #[structopt(short = 'k', long = "key-name")] 21 | key_name: String, 22 | 23 | /// Export RSA Public Key in PKCS#1 format. 24 | #[structopt(long = "pkcs1")] 25 | pkcs1: bool, 26 | } 27 | 28 | impl ExportPublicKey { 29 | /// Exports a public key. 30 | pub fn run(&self, basic_client: BasicClient) -> Result<()> { 31 | let mut tag = String::from("PUBLIC KEY"); 32 | let mut psa_public_key = basic_client.psa_export_public_key(&self.key_name)?; 33 | let psa_key_attributes = basic_client.key_attributes(&self.key_name)?; 34 | 35 | match psa_key_attributes.key_type { 36 | Type::RsaKeyPair | Type::RsaPublicKey => { 37 | if self.pkcs1 { 38 | tag = String::from("RSA PUBLIC KEY"); 39 | } else { 40 | psa_public_key = picky_asn1_der::to_vec(&SubjectPublicKeyInfo { 41 | algorithm: AlgorithmIdentifier::new_rsa_encryption(), 42 | subject_public_key: PublicKey::Rsa( 43 | picky_asn1_der::from_bytes::(&psa_public_key) 44 | .map_err(|_| { 45 | error!("Could not deserialise RSA key"); 46 | ToolErrorKind::IncorrectData 47 | })? 48 | .into(), 49 | ), 50 | }) 51 | .map_err(|_| { 52 | error!("Could not serialise RSA key"); 53 | ToolErrorKind::IncorrectData 54 | })?; 55 | } 56 | } 57 | Type::EccKeyPair { 58 | curve_family: curve, 59 | } 60 | | Type::EccPublicKey { 61 | curve_family: curve, 62 | } => { 63 | if self.pkcs1 { 64 | error!("PKCS1 format doesn't support ECC keys"); 65 | return Err(ToolErrorKind::WrongKeyAlgorithm.into()); 66 | } else { 67 | psa_public_key = picky_asn1_der::to_vec(&SubjectPublicKeyInfo { 68 | algorithm: AlgorithmIdentifier::new_elliptic_curve( 69 | EcParameters::NamedCurve( 70 | curve_oid(curve, psa_key_attributes.bits)?.into(), 71 | ), 72 | ), 73 | subject_public_key: PublicKey::Ec( 74 | BitString::with_bytes(psa_public_key).into(), 75 | ), 76 | }) 77 | .map_err(|_| { 78 | error!("Could not serialise ECC key"); 79 | ToolErrorKind::IncorrectData 80 | })?; 81 | } 82 | } 83 | _ => { 84 | error!("Unsupported type of key"); 85 | return Err(ToolErrorKind::NotSupported.into()); 86 | } 87 | }; 88 | 89 | let pem_encoded = pem::encode_config( 90 | &pem::Pem { 91 | tag, 92 | contents: psa_public_key, 93 | }, 94 | pem::EncodeConfig { 95 | line_ending: pem::LineEnding::LF, 96 | }, 97 | ); 98 | 99 | print!("{}", pem_encoded); 100 | Ok(()) 101 | } 102 | } 103 | 104 | fn curve_oid(curve: EccFamily, key_bits: usize) -> Result { 105 | let curve_oid = match curve { 106 | // SEC random curves over prime fields. 107 | EccFamily::SecpR1 => match key_bits { 108 | 192 => picky_asn1_x509::oids::secp192r1(), 109 | 224 => picky_asn1_x509::oids::secp224r1(), 110 | 256 => picky_asn1_x509::oids::secp256r1(), 111 | 384 => picky_asn1_x509::oids::secp384r1(), 112 | 521 => picky_asn1_x509::oids::secp521r1(), 113 | _ => return print_error(curve, key_bits), 114 | }, 115 | // SEC Koblitz curves over prime fields. 116 | // OIDs are not defined in picky_asn1_x509::oids and in RFC5480. 117 | // Use values from https://www.secg.org/sec2-v2.pdf#subsection.A.2 118 | EccFamily::SecpK1 => match key_bits { 119 | 192 => ObjectIdentifier::try_from("1.3.132.0.31").unwrap(), 120 | 224 => ObjectIdentifier::try_from("1.3.132.0.32").unwrap(), 121 | 256 => ObjectIdentifier::try_from("1.3.132.0.10").unwrap(), 122 | _ => return print_error(curve, key_bits), 123 | }, 124 | // SEC Koblitz curves over binary fields 125 | EccFamily::SectK1 => match key_bits { 126 | 233 => picky_asn1_x509::oids::sect233k1(), 127 | 283 => picky_asn1_x509::oids::sect283k1(), 128 | 409 => picky_asn1_x509::oids::sect409k1(), 129 | 571 => picky_asn1_x509::oids::sect571k1(), 130 | _ => return print_error(curve, key_bits), 131 | }, 132 | // SEC random curves over binary fields 133 | EccFamily::SectR1 => match key_bits { 134 | 233 => picky_asn1_x509::oids::sect233r1(), 135 | 283 => picky_asn1_x509::oids::sect283r1(), 136 | 409 => picky_asn1_x509::oids::sect409r1(), 137 | 571 => picky_asn1_x509::oids::sect571r1(), 138 | _ => return print_error(curve, key_bits), 139 | }, 140 | _ => { 141 | error!("Unsupported Ecc family \"{}\"", curve); 142 | return Err(ToolErrorKind::NotSupported.into()); 143 | } 144 | }; 145 | Ok(curve_oid) 146 | } 147 | 148 | fn print_error(curve: EccFamily, key_bits: usize) -> Result { 149 | error!( 150 | "Unsupported number of bits {} for Ecc family \"{}\"", 151 | key_bits, curve 152 | ); 153 | Err(ToolErrorKind::NotSupported.into()) 154 | } 155 | -------------------------------------------------------------------------------- /src/subcommands/generate_random.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Contributors to the Parsec project. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! Generates a sequence of random bytes. 5 | 6 | use crate::error::Result; 7 | use clap::Parser; 8 | use log::info; 9 | use parsec_client::BasicClient; 10 | 11 | /// Generates a sequence of random bytes. 12 | #[derive(Debug, Parser)] 13 | pub struct GenerateRandom { 14 | #[structopt(short = 'n', long = "nbytes")] 15 | nbytes: usize, 16 | } 17 | 18 | impl GenerateRandom { 19 | /// Generates a sequence of random bytes. 20 | pub fn run(&self, basic_client: BasicClient) -> Result<()> { 21 | info!("Generating {} random bytes...", self.nbytes); 22 | 23 | let result = basic_client.psa_generate_random(self.nbytes)?; 24 | 25 | info!("Random bytes:"); 26 | for byte in result { 27 | print!("{:02X} ", byte); 28 | } 29 | println!(); 30 | Ok(()) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/subcommands/list_authenticators.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Contributors to the Parsec project. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! List the authenticators supported by the Parsec service. 5 | 6 | use crate::error::Result; 7 | use clap::Parser; 8 | use log::info; 9 | use parsec_client::BasicClient; 10 | 11 | /// List the authenticators supported by the Parsec service. 12 | #[derive(Debug, Parser)] 13 | pub struct ListAuthenticators {} 14 | 15 | impl ListAuthenticators { 16 | /// Lists the available authenticators supported by the Parsec service. 17 | pub fn run(&self, basic_client: BasicClient) -> Result<()> { 18 | let authenticators = basic_client.list_authenticators()?; 19 | 20 | info!("Available authenticators:"); 21 | for authenticator in authenticators { 22 | println!( 23 | "ID: 0x{:02x} ({})", 24 | authenticator.id as u32, authenticator.id 25 | ); 26 | println!("Description: {}", authenticator.description); 27 | println!( 28 | "Version: {}.{}.{}", 29 | authenticator.version_maj, authenticator.version_min, authenticator.version_rev 30 | ); 31 | println!(); 32 | } 33 | Ok(()) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/subcommands/list_clients.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2021 Contributors to the Parsec project. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! Lists all clients currently having data in the service (admin operation). 5 | 6 | use crate::error::Result; 7 | use clap::Parser; 8 | use log::info; 9 | use parsec_client::BasicClient; 10 | 11 | /// Lists all clients currently having data in the service (admin operation). 12 | #[derive(Debug, Parser)] 13 | pub struct ListClients {} 14 | 15 | impl ListClients { 16 | pub fn run(&self, basic_client: BasicClient) -> Result<()> { 17 | let clients = basic_client.list_clients()?; 18 | 19 | if clients.is_empty() { 20 | info!("No clients in the service."); 21 | return Ok(()); 22 | } 23 | info!("Parsec clients:"); 24 | for client in clients { 25 | println!("{}", client); 26 | } 27 | Ok(()) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/subcommands/list_keys.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Contributors to the Parsec project. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! Lists all keys belonging to the application. 5 | 6 | use crate::error::Result; 7 | use clap::Parser; 8 | use log::info; 9 | use parsec_client::BasicClient; 10 | 11 | /// Lists all keys belonging to the application. 12 | #[derive(Debug, Parser)] 13 | pub struct ListKeys {} 14 | 15 | impl ListKeys { 16 | /// Lists the available providers supported by the Parsec service. 17 | pub fn run(&self, basic_client: BasicClient) -> Result<()> { 18 | let keys = basic_client.list_keys()?; 19 | 20 | if keys.is_empty() { 21 | info!("No keys currently available."); 22 | return Ok(()); 23 | } 24 | info!("Available keys:"); 25 | for key in keys { 26 | println!( 27 | "* {} ({}, {:?}, {} bits, permitted algorithm: {:?})", 28 | key.name, 29 | key.provider_id, 30 | key.attributes.key_type, 31 | key.attributes.bits, 32 | key.attributes.policy.permitted_algorithms 33 | ); 34 | } 35 | Ok(()) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/subcommands/list_opcodes.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Contributors to the Parsec project. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! Lists the supported opcodes for a given provider. 5 | use crate::error::Result; 6 | use clap::Parser; 7 | use log::info; 8 | use parsec_client::BasicClient; 9 | use std::convert::TryInto; 10 | 11 | /// Lists the supported opcodes for a given provider. 12 | #[derive(Debug, Parser)] 13 | pub struct ListOpcodes { 14 | /// ID of the provider. 15 | #[structopt(short = 'p', long = "provider")] 16 | pub provider: Option, 17 | } 18 | 19 | impl ListOpcodes { 20 | /// Lists the supported opcodes for a given provider. 21 | pub fn run(&self, basic_client: BasicClient) -> Result<()> { 22 | let provider = match self.provider { 23 | Some(provider) => provider.try_into()?, 24 | None => basic_client.implicit_provider(), 25 | }; 26 | let opcodes = basic_client.list_opcodes(provider)?; 27 | 28 | info!("Available opcodes for {}:", provider); 29 | for provider_opcode in opcodes { 30 | println!("0x{:02x} ({:?})", provider_opcode as u32, provider_opcode); 31 | } 32 | Ok(()) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/subcommands/list_providers.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Contributors to the Parsec project. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! Lists the available providers supported by the Parsec service. 5 | 6 | use crate::error::Result; 7 | use clap::Parser; 8 | use log::info; 9 | use parsec_client::BasicClient; 10 | 11 | /// Lists the available providers supported by the Parsec service. 12 | #[derive(Debug, Parser)] 13 | pub struct ListProviders {} 14 | 15 | impl ListProviders { 16 | /// Lists the available providers supported by the Parsec service. 17 | pub fn run(&self, basic_client: BasicClient) -> Result<()> { 18 | let providers = basic_client.list_providers()?; 19 | 20 | info!("Available providers:"); 21 | for provider in providers { 22 | println!("ID: 0x{:02x} ({})", provider.id as u32, provider.id); 23 | println!("Description: {}", provider.description); 24 | println!( 25 | "Version: {}.{}.{}", 26 | provider.version_maj, provider.version_min, provider.version_rev 27 | ); 28 | println!( 29 | "Vendor: {}", 30 | if !provider.vendor.is_empty() { 31 | provider.vendor 32 | } else { 33 | "Unspecified".to_string() 34 | }, 35 | ); 36 | println!("UUID: {}", provider.uuid); 37 | println!(); 38 | } 39 | Ok(()) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/subcommands/mod.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Contributors to the Parsec project. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! Subcommand implementations. Interacts with parsec-client-rust. 5 | 6 | mod create_csr; 7 | mod create_ecc_key; 8 | mod create_rsa_key; 9 | mod decrypt; 10 | mod delete_client; 11 | mod delete_key; 12 | mod encrypt; 13 | mod export_public_key; 14 | mod generate_random; 15 | mod list_authenticators; 16 | mod list_clients; 17 | mod list_keys; 18 | mod list_opcodes; 19 | mod list_providers; 20 | mod ping; 21 | mod sign; 22 | 23 | use crate::error::{Error::ParsecClientError, Result}; 24 | use crate::subcommands::{ 25 | create_csr::CreateCsr, create_ecc_key::CreateEccKey, create_rsa_key::CreateRsaKey, 26 | decrypt::Decrypt, delete_client::DeleteClient, delete_key::DeleteKey, encrypt::Encrypt, 27 | export_public_key::ExportPublicKey, generate_random::GenerateRandom, 28 | list_authenticators::ListAuthenticators, list_clients::ListClients, list_keys::ListKeys, 29 | list_opcodes::ListOpcodes, list_providers::ListProviders, ping::Ping, sign::Sign, 30 | }; 31 | use clap::Parser; 32 | use parsec_client::BasicClient; 33 | 34 | /// Command-line interface to Parsec operations. 35 | #[derive(Debug, Parser)] 36 | pub enum Subcommand { 37 | /// Ping the Parsec service and prints the wire protocol version. 38 | Ping(Ping), 39 | 40 | /// List the available providers supported by the Parsec service. 41 | ListProviders(ListProviders), 42 | 43 | /// List the available authenticators supported by the Parsec service. 44 | ListAuthenticators(ListAuthenticators), 45 | 46 | /// List the supported opcodes for a given provider. 47 | ListOpcodes(ListOpcodes), 48 | 49 | /// List all keys belonging to the application. 50 | ListKeys(ListKeys), 51 | 52 | /// Generate a sequence of random bytes. 53 | GenerateRandom(GenerateRandom), 54 | 55 | /// Export the public part of the key pair in PEM format 56 | ExportPublicKey(ExportPublicKey), 57 | 58 | /// Create a RSA key pair (2048 bits). Used by default for asymmetric encryption with RSA PKCS#1 v1.5. 59 | CreateRsaKey(CreateRsaKey), 60 | 61 | /// Create a ECC key pair (curve secp256r1). Used by default for asymmetric signing with ECDSA (SHA-256). 62 | CreateEccKey(CreateEccKey), 63 | 64 | /// Decrypt data using the algorithm of the key 65 | Decrypt(Decrypt), 66 | 67 | /// Sign data using the algorithm of the key (base64 signature) 68 | Sign(Sign), 69 | 70 | /// Delete a key. 71 | DeleteKey(DeleteKey), 72 | 73 | /// Lists all clients currently having data in the service (admin operation). 74 | ListClients(ListClients), 75 | 76 | /// Delete all data a client has in the service (admin operation). 77 | DeleteClient(DeleteClient), 78 | 79 | /// Create a Certificate Signing Request (CSR) from a keypair. 80 | CreateCsr(CreateCsr), 81 | 82 | /// Encrypt data using the algorithm of the key 83 | Encrypt(Encrypt), 84 | } 85 | 86 | impl Subcommand { 87 | /// Runs the subcommand. 88 | pub fn run(&self, client: BasicClient) -> Result<()> { 89 | match &self { 90 | Subcommand::Ping(cmd) => cmd.run(client), 91 | Subcommand::ListProviders(cmd) => cmd.run(client), 92 | Subcommand::ListAuthenticators(cmd) => cmd.run(client), 93 | Subcommand::ListKeys(cmd) => cmd.run(client), 94 | Subcommand::ListClients(cmd) => cmd.run(client), 95 | Subcommand::DeleteClient(cmd) => cmd.run(client), 96 | Subcommand::ListOpcodes(cmd) => cmd.run(client), 97 | Subcommand::GenerateRandom(cmd) => cmd.run(client), 98 | Subcommand::ExportPublicKey(cmd) => cmd.run(client), 99 | Subcommand::CreateRsaKey(cmd) => cmd.run(client), 100 | Subcommand::CreateEccKey(cmd) => cmd.run(client), 101 | Subcommand::Sign(cmd) => cmd.run(client), 102 | Subcommand::Decrypt(cmd) => cmd.run(client), 103 | Subcommand::DeleteKey(cmd) => cmd.run(client), 104 | Subcommand::CreateCsr(cmd) => cmd.run(client), 105 | Subcommand::Encrypt(cmd) => cmd.run(client), 106 | } 107 | } 108 | /// Indicates if subcommand requires authentication 109 | fn authentication_required(&self) -> bool { 110 | // Subcommands below don't need authentication - all others do. 111 | !matches!( 112 | &self, 113 | Subcommand::Ping(_) 114 | | Subcommand::ListProviders(_) 115 | | Subcommand::ListAuthenticators(_) 116 | | Subcommand::ListOpcodes(_) 117 | ) 118 | } 119 | 120 | /// Get BasicClient for operation 121 | pub fn create_client(&self, app_name: Option) -> Result { 122 | let client_result = if self.authentication_required() { 123 | // BasicClient::new will do default config including setting up authenticator 124 | BasicClient::new(app_name) 125 | } else { 126 | // Create a naked client which should be set up for core operations with no authenticator 127 | BasicClient::new_naked() 128 | }; 129 | match client_result { 130 | Ok(client) => Ok(client), 131 | Err(err) => Err(ParsecClientError(err)), 132 | } 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /src/subcommands/ping.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Contributors to the Parsec project. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! Pings the Parsec service. 5 | 6 | use crate::error::Result; 7 | use clap::Parser; 8 | use log::info; 9 | use parsec_client::BasicClient; 10 | 11 | /// Pings the Parsec service. 12 | #[derive(Debug, Parser)] 13 | pub struct Ping {} 14 | 15 | impl Ping { 16 | /// Pings the Parsec service and prints the wire protocol version. 17 | pub fn run(&self, basic_client: BasicClient) -> Result<()> { 18 | let result = basic_client.ping()?; 19 | 20 | info!("Service wire protocol version",); 21 | println!("{}.{}", result.0, result.1); 22 | Ok(()) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/subcommands/sign.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2021 Contributors to the Parsec project. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! Signs data. 5 | //! 6 | //! Will use the algorithm set to the key's policy during creation. 7 | 8 | use crate::error::Result; 9 | use crate::util::sign_message_with_policy; 10 | use clap::Parser; 11 | use parsec_client::BasicClient; 12 | 13 | /// Signs data. 14 | #[derive(Debug, Parser)] 15 | pub struct Sign { 16 | #[structopt(short = 'k', long = "key-name")] 17 | key_name: String, 18 | 19 | /// String of UTF-8 text 20 | input_data: String, 21 | } 22 | 23 | impl Sign { 24 | /// Signs data. 25 | pub fn run(&self, basic_client: BasicClient) -> Result<()> { 26 | let signature = sign_message_with_policy( 27 | &basic_client, 28 | &self.key_name, 29 | self.input_data.as_bytes(), 30 | None, 31 | )?; 32 | 33 | let signature = base64::encode(signature); 34 | 35 | println!("{}", signature); 36 | 37 | Ok(()) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/util.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2021 Contributors to the Parsec project. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | //! Utility code that is shared by multiple subcommands; 5 | 6 | use crate::error::{Result, ToolErrorKind}; 7 | use log::{error, info}; 8 | use parsec_client::core::interface::operations::psa_algorithm::{Algorithm, Hash, SignHash}; 9 | use parsec_client::BasicClient; 10 | use picky_asn1::wrapper::IntegerAsn1; 11 | use serde::{Deserialize, Serialize}; 12 | use sha2::digest::{Digest, DynDigest}; 13 | 14 | #[derive(Serialize, Deserialize)] 15 | struct EccSignature { 16 | r: IntegerAsn1, 17 | s: IntegerAsn1, 18 | } 19 | 20 | /// Signs a given message using the hashing and signing policy that was associated with the given key when 21 | /// it was created. 22 | /// 23 | /// If the signing key allows for the use of any hashing algorithm, then a default hash can optionally be passed 24 | /// by the caller, and this hash will be used (otherwise the function will fail). 25 | pub fn sign_message_with_policy( 26 | basic_client: &BasicClient, 27 | key_name: &str, 28 | msg: &[u8], 29 | default_hash: Option, 30 | ) -> Result> { 31 | let alg = basic_client 32 | .key_attributes(key_name)? 33 | .policy 34 | .permitted_algorithms; 35 | 36 | let signature = match alg { 37 | Algorithm::AsymmetricSignature(alg) => { 38 | let hash = match alg.hash() { 39 | Some(SignHash::Specific(hash)) => hash_data(msg, hash)?, 40 | Some(SignHash::Any) => { 41 | if let Some(hash) = default_hash { 42 | hash_data(msg, hash)? 43 | } else { 44 | error!("Signing key allows any hashing algorithm, but no default was specified."); 45 | return Err(ToolErrorKind::NotSupported.into()); 46 | } 47 | } 48 | _ => { 49 | error!("Asymmetric signing algorithm ({:?}) is not supported", alg); 50 | return Err(ToolErrorKind::NotSupported.into()); 51 | } 52 | }; 53 | info!("Signing data with {:?}...", alg); 54 | let mut sig = basic_client.psa_sign_hash(key_name, &hash, alg)?; 55 | if alg.is_ecc_alg() { 56 | let s = IntegerAsn1::from_bytes_be_unsigned(sig.split_off(sig.len() / 2)); 57 | sig = picky_asn1_der::to_vec(&EccSignature { 58 | r: IntegerAsn1::from_bytes_be_unsigned(sig), 59 | s, 60 | }) 61 | .unwrap(); 62 | } 63 | 64 | sig 65 | } 66 | other => { 67 | error!( 68 | "Key's algorithm is {:?} which can not be used for signing.", 69 | other 70 | ); 71 | return Err(ToolErrorKind::WrongKeyAlgorithm.into()); 72 | } 73 | }; 74 | 75 | Ok(signature) 76 | } 77 | 78 | fn hash_data(data: &[u8], alg: Hash) -> Result> { 79 | let mut hasher: Box = match alg { 80 | Hash::Sha224 => Box::from(sha2::Sha224::new()), 81 | Hash::Sha256 => Box::from(sha2::Sha256::new()), 82 | Hash::Sha384 => Box::from(sha2::Sha384::new()), 83 | Hash::Sha512 => Box::from(sha2::Sha512::new()), 84 | _ => { 85 | error!("Hashing algorithm ({:?}) not supported", alg); 86 | return Err(ToolErrorKind::NotSupported.into()); 87 | } 88 | }; 89 | info!("Hashing data with {:?}...", alg); 90 | hasher.update(data); 91 | Ok(hasher.finalize().to_vec()) 92 | } 93 | -------------------------------------------------------------------------------- /tests/ci.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Copyright 2020 Contributors to the Parsec project. 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | set -xeuf -o pipefail 7 | 8 | error_msg () { 9 | echo "Error: $1" 10 | exit 1 11 | } 12 | 13 | # Points to Parsec's Unix Domain Socket on the CI 14 | export PARSEC_SERVICE_ENDPOINT="unix:/tmp/parsec.sock" 15 | export RUST_LOG=error 16 | 17 | #TODO: This applies the rcgen patch that exposes the PKCS_RSA_PSS_SHA256 and PKCS_RSA_PSS_SHA384 types. Remove this 18 | # when the corresponding patch gets merged. Also remove rcgen+0.9.3.patch. 19 | rustup install 1.77.1 # We know that this version works for patch-crate 20 | cargo +1.77.1 install patch-crate --version 0.1.9 21 | cargo patch-crate 22 | 23 | ################## 24 | # Get Parameters # 25 | ################## 26 | MISMATCHER= 27 | TEST_NEXT_BRANCH_TRACKING= 28 | while [ "$#" -gt 0 ]; do 29 | case "$1" in 30 | mismatcher ) 31 | MISMATCHER="True" 32 | ;; 33 | --test-next-branch-tracking ) 34 | TEST_NEXT_BRANCH_TRACKING="True" 35 | ;; 36 | *) 37 | error_msg "Unknown argument: $1" 38 | ;; 39 | esac 40 | shift 41 | done 42 | 43 | ######################### 44 | # Dependency mismatcher # 45 | ######################### 46 | if [ "$MISMATCHER" = "True" ]; then 47 | 48 | python3 $(pwd)/parsec/utils/dependency_cross_matcher.py --deps_dir $(pwd) 49 | 50 | python3 $(pwd)/parsec/utils/dependency_cross_matcher.py -c --deps_dir $(pwd)/parsec $(pwd) 51 | 52 | exit 0 53 | fi 54 | 55 | ######################### 56 | # Next branch tracking # 57 | ######################### 58 | if [ "$TEST_NEXT_BRANCH_TRACKING" ]; then 59 | echo "Track next branches for parallaxsecond repositories" 60 | python3 $(pwd)/parsec/utils/release_tracking.py $(pwd)/Cargo.toml 61 | fi 62 | ######### 63 | # Build # 64 | ######### 65 | rustup --version 66 | RUST_BACKTRACE=1 cargo build 67 | RUST_BACKTRACE=1 cargo build --features spiffe-auth 68 | 69 | ################# 70 | # Static checks # 71 | ################# 72 | # On native target clippy or fmt might not be available. 73 | if cargo fmt -h; then 74 | cargo fmt --all -- --check 75 | fi 76 | if cargo clippy -h; then 77 | cargo clippy --all-targets -- -D clippy::all -D clippy::cargo -A clippy::multiple_crate_versions 78 | fi 79 | 80 | ############# 81 | # CLI tests # 82 | ############# 83 | ./target/debug/parsec-tool --help 84 | 85 | PARSEC_TOOL="./target/debug/parsec-tool" tests/parsec-cli-tests.sh -d 86 | PARSEC_TOOL="./target/debug/parsec-tool" tests/parsec-cli-tests.sh -d --rsa-key-size 1024 87 | -------------------------------------------------------------------------------- /tests/parsec-cli-tests.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # Copyright 2021 Contributors to the Parsec project. 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | # Run simple end-two-end Parsec tests using parsec-tool and openssl 7 | 8 | ping_parsec() { 9 | echo "Checking Parsec service... " 10 | $PARSEC_TOOL ping 11 | } 12 | 13 | run_cmd() { 14 | "$@" 15 | EXIT_CODE=$(($EXIT_CODE+$?)) 16 | } 17 | 18 | debug() { 19 | if [ -n "$PARSEC_TOOL_DEBUG" ]; then 20 | "$@" 21 | fi 22 | } 23 | 24 | MY_TMP=$(mktemp -d) 25 | 26 | cleanup () { 27 | if [ -n "$MY_TMP" ]; then 28 | rm -rf -- "$MY_TMP" 29 | fi 30 | } 31 | 32 | trap cleanup EXIT 33 | 34 | delete_key() { 35 | # $1 - key type 36 | # $2 - key name 37 | KEY="$2" 38 | 39 | echo 40 | echo "- Deleting the $1 key" 41 | run_cmd $PARSEC_TOOL_CMD delete-key --key-name $KEY 42 | rm -f ${MY_TMP}/${KEY}.* 43 | } 44 | 45 | create_key() { 46 | # $1 - key type ("RSA" or "ECC") 47 | # $2 - key name 48 | # $3 - key usage ("SIGN_PKCS1_V15", "SIGN_PSS" or "OAEP"), only consulted if $1 == "RSA" 49 | KEY="$2" 50 | 51 | if [ "$3" = "SIGN_PKCS1_V15" -a "$1" = "RSA" ]; then 52 | EXTRA_CREATE_KEY_ARGS="--for-signing" 53 | elif [ "$3" = "SIGN_PSS" -a "$1" = "RSA" ]; then 54 | EXTRA_CREATE_KEY_ARGS="--for-signing-pss" 55 | elif [ "$3" = "OAEP" -a "$1" = "RSA" ]; then 56 | EXTRA_CREATE_KEY_ARGS="--oaep" 57 | else 58 | EXTRA_CREATE_KEY_ARGS="" 59 | fi 60 | 61 | if [ "$RSA_KEY_SIZE" -a "$1" = "RSA" ]; then 62 | KEY_LEN="--bits $RSA_KEY_SIZE" 63 | else 64 | KEY_LEN="" 65 | fi 66 | 67 | echo 68 | echo "- Creating an $1 key and exporting its public part" 69 | type_lower=$(echo $1 | tr '[:upper:]' '[:lower:]') 70 | run_cmd $PARSEC_TOOL_CMD create-${type_lower}-key --key-name $KEY $EXTRA_CREATE_KEY_ARGS $KEY_LEN 71 | 72 | if ! run_cmd $PARSEC_TOOL_CMD list-keys | tee /dev/stderr | grep -q "$KEY"; then 73 | echo "Error: $KEY is not listed" 74 | EXIT_CODE=$(($EXIT_CODE+1)) 75 | fi 76 | 77 | run_cmd $PARSEC_TOOL_CMD export-public-key --key-name $KEY >${MY_TMP}/${KEY}.pem 78 | } 79 | 80 | test_crypto_provider() { 81 | # $1 - provider ID 82 | 83 | PARSEC_TOOL_CMD="$PARSEC_TOOL -p $1" 84 | 85 | echo 86 | echo "- Test random number generation" 87 | if run_cmd $PARSEC_TOOL_CMD list-opcodes 2>/dev/null | grep -q "PsaGenerateRandom"; then 88 | run_cmd $PARSEC_TOOL_CMD generate-random --nbytes 10 89 | else 90 | echo "This provider doesn't support random number generation" 91 | fi 92 | 93 | if [ -z "$NO_PKCS1_V15" ]; then 94 | test_encryption "PKCS#1 v1.5" 95 | test_decryption "PKCS#1 v1.5" 96 | fi 97 | if [ -z "$NO_OAEP" ]; then 98 | test_encryption "OAEP" 99 | test_decryption "OAEP" 100 | fi 101 | 102 | test_signing "ECC" 103 | test_csr "RSA" "SIGN_PKCS1_V15" 104 | test_csr "RSA" "SIGN_PSS" 105 | test_csr "ECC" 106 | test_rsa_key_bits 107 | test_rsa_key_bits 1024 108 | } 109 | 110 | test_encryption() { 111 | # $1 - algorithm 112 | KEY="anta-key-rsa-encrypt" 113 | TEST_STR="$(date) Parsec public key encryption" 114 | ALG="$1" 115 | 116 | create_key "RSA" "$KEY" "$ALG" 117 | 118 | # If the key was successfully created and exported 119 | if [ -s ${MY_TMP}/${KEY}.pem ]; then 120 | debug cat ${MY_TMP}/${KEY}.pem 121 | 122 | echo 123 | echo "- Encrypting \"$TEST_STR\" string using Parsec public key RSA $ALG encryption" 124 | 125 | # Encrypt TEST_STR with the public key using Parsec rather than openssl 126 | # (No need to base64 encode this, because parsec-tool already does it) 127 | run_cmd $PARSEC_TOOL_CMD encrypt --key-name $KEY "$TEST_STR" > ${MY_TMP}/${KEY}.enc 128 | 129 | echo 130 | echo "- Using Parsec to decrypt the result (with the private key):" 131 | run_cmd $PARSEC_TOOL_CMD decrypt $(cat ${MY_TMP}/${KEY}.enc) --key-name $KEY \ 132 | >${MY_TMP}/${KEY}.enc_str 133 | cat ${MY_TMP}/${KEY}.enc_str 134 | if [ "$(cat ${MY_TMP}/${KEY}.enc_str)" != "$TEST_STR" ]; then 135 | echo "Error: The result is different from the initial string" 136 | EXIT_CODE=$(($EXIT_CODE+1)) 137 | fi 138 | fi 139 | 140 | delete_key "RSA" $KEY 141 | } 142 | 143 | test_decryption() { 144 | # $1 - algorithm 145 | KEY="anta-key-rsa-crypt" 146 | TEST_STR="$(date) Parsec decryption test" 147 | ALG="$1" 148 | 149 | create_key "RSA" "$KEY" "$ALG" 150 | 151 | # If the key was successfully created and exported 152 | if [ -s ${MY_TMP}/${KEY}.pem ]; then 153 | debug cat ${MY_TMP}/${KEY}.pem 154 | 155 | echo 156 | echo "- Encrypting \"$TEST_STR\" string using openssl with RSA $ALG algorithm and the exported public key" 157 | 158 | # Encrypt TEST_STR with the public key and base64-encode the result 159 | printf "$TEST_STR" >${MY_TMP}/${KEY}.test_str 160 | if [ "$ALG" = "OAEP" ]; then 161 | pkeyopt="-pkeyopt rsa_padding_mode:oaep -pkeyopt rsa_oaep_md:sha256" 162 | else 163 | pkeyopt="" 164 | fi 165 | run_cmd $OPENSSL pkeyutl -encrypt $pkeyopt -pubin -inkey ${MY_TMP}/${KEY}.pem \ 166 | -in ${MY_TMP}/${KEY}.test_str -out ${MY_TMP}/${KEY}.bin 167 | run_cmd $OPENSSL base64 -A -in ${MY_TMP}/${KEY}.bin -out ${MY_TMP}/${KEY}.enc 168 | debug cat ${MY_TMP}/${KEY}.enc 169 | 170 | echo 171 | echo "- Using Parsec to decrypt the result:" 172 | run_cmd $PARSEC_TOOL_CMD decrypt $(cat ${MY_TMP}/${KEY}.enc) --key-name $KEY \ 173 | >${MY_TMP}/${KEY}.enc_str 174 | cat ${MY_TMP}/${KEY}.enc_str 175 | if [ "$(cat ${MY_TMP}/${KEY}.enc_str)" != "$TEST_STR" ]; then 176 | echo "Error: The result is different from the initial string" 177 | EXIT_CODE=$(($EXIT_CODE+1)) 178 | fi 179 | fi 180 | 181 | delete_key "RSA" $KEY 182 | } 183 | 184 | test_signing() { 185 | # $1 - key type ("RSA" or "ECC") 186 | # $2 - RSA scheme ("SIGN_PKCS1_V15" or "SIGN_PSS") 187 | KEY="anta-key-sign" 188 | TEST_STR="$(date) Parsec signature test" 189 | 190 | create_key $1 $KEY $2 191 | 192 | EXTRA_VERIFY_ARGS= 193 | if [ "$2" = "SIGN_PSS" -a "$1" = "RSA" ]; then 194 | EXTRA_VERIFY_ARGS="-sigopt rsa_padding_mode:pss" 195 | fi 196 | 197 | # If the key was successfully created and exported 198 | if [ -s ${MY_TMP}/${KEY}.pem ]; then 199 | debug cat ${MY_TMP}/${KEY}.pem 200 | 201 | echo 202 | echo "- Signing \"$TEST_STR\" string using the created $1 key" 203 | run_cmd $PARSEC_TOOL_CMD sign "$TEST_STR" --key-name $KEY >${MY_TMP}/${KEY}.sign 204 | debug cat ${MY_TMP}/${KEY}.sign 205 | 206 | echo 207 | echo "- Using openssl and the exported public $1 key to verify the signature" 208 | # Parsec-tool produces base64-encoded signatures. Let's decode it before verifing. 209 | run_cmd $OPENSSL base64 -d -a -A -in ${MY_TMP}/${KEY}.sign -out ${MY_TMP}/${KEY}.bin 210 | 211 | printf "$TEST_STR" >${MY_TMP}/${KEY}.test_str 212 | run_cmd $OPENSSL dgst -sha256 -verify ${MY_TMP}/${KEY}.pem ${EXTRA_VERIFY_ARGS} \ 213 | -signature ${MY_TMP}/${KEY}.bin ${MY_TMP}/${KEY}.test_str 214 | fi 215 | 216 | delete_key $1 $KEY 217 | } 218 | 219 | test_csr() { 220 | # $1 - key type ("RSA" or "ECC") 221 | # $2 - RSA scheme ("SIGN_PKCS1_V15" or "SIGN_PSS") 222 | KEY="anta-key-csr" 223 | TEST_CN="parallaxsecond.com" 224 | TEST_SAN="localhost" 225 | TEST_SERIAL="EZ4U2CIXL" 226 | 227 | # CSR creation needs a signing key. 228 | create_key $1 $KEY $2 229 | 230 | # If the key was successfully created and exported 231 | if [ -s ${MY_TMP}/${KEY}.pem ]; then 232 | debug cat ${MY_TMP}/${KEY}.pem 233 | 234 | echo 235 | echo "- Creating a certificate signing request (CSR) from the test key." 236 | run_cmd $PARSEC_TOOL_CMD create-csr --cn ${TEST_CN} --san ${TEST_SAN} --serialNumber ${TEST_SERIAL} --key-name $KEY >${MY_TMP}/${KEY}.csr 237 | debug cat ${MY_TMP}/${KEY}.csr 238 | 239 | echo 240 | echo "- Using openssl to inspect the CSR content and verify the public key." 241 | run_cmd $OPENSSL req -text -noout -verify -in ${MY_TMP}/${KEY}.csr >${MY_TMP}/${KEY}.txt 242 | debug cat ${MY_TMP}/${KEY}.txt 243 | 244 | if ! cat ${MY_TMP}/${KEY}.txt | grep "Subject:" | grep -e "serialNumber = ${TEST_SERIAL}" -e "serialNumber=${TEST_SERIAL}"; then 245 | echo "Error: The CSR does not contain the serialNumber field of the Distinguished Name" 246 | EXIT_CODE=$(($EXIT_CODE+1)) 247 | fi 248 | fi 249 | 250 | delete_key $1 $KEY 251 | } 252 | 253 | test_rsa_key_bits() { 254 | KEY="anta-key-rsa-bits" 255 | 256 | if [ "$RSA_KEY_SIZE" ]; then 257 | key_size="$RSA_KEY_SIZE" 258 | key_param="--bits $RSA_KEY_SIZE" 259 | elif [ -n "$1" ]; then 260 | key_size=$1 261 | key_param="--bits $1" 262 | else 263 | key_size=2048 264 | key_param="" 265 | fi 266 | 267 | echo "Creating ${key_size}-bit RSA key." 268 | run_cmd $PARSEC_TOOL_CMD create-rsa-key --key-name $KEY $key_param 269 | run_cmd $PARSEC_TOOL_CMD export-public-key --key-name $KEY >${MY_TMP}/checksize-${KEY}.pem 270 | if ! run_cmd $OPENSSL rsa -pubin -text -noout -in ${MY_TMP}/checksize-${KEY}.pem | grep -q "Public-Key: (${key_size} bit)"; then 271 | echo "Error: create-rsa-key should have produced a ${key_size}-bit RSA key." 272 | EXIT_CODE=$(($EXIT_CODE+1)) 273 | fi 274 | delete_key "RSA" $KEY 275 | } 276 | 277 | PARSEC_TOOL_DEBUG= 278 | PROVIDER= 279 | 280 | # Test both RSA PKCS#1 v1.5 (default) and RSA OAEP encryption algorithms 281 | NO_OAEP= 282 | NO_PKCS1_V15= 283 | RSA_KEY_SIZE= 284 | while [ "$#" -gt 0 ]; do 285 | case "$1" in 286 | -[0-9]* ) 287 | PROVIDER=${1#-} 288 | ;; 289 | -d ) 290 | PARSEC_TOOL_DEBUG="True" 291 | RUST_LOG="${RUST_LOG:-trace}" 292 | set -x 293 | ;; 294 | --no-oaep ) 295 | NO_OAEP="true" 296 | ;; 297 | --no-v1.5 ) 298 | NO_PKCS1_V15="true" 299 | ;; 300 | --no-pss ) 301 | NO_PSS="true" 302 | ;; 303 | --rsa-key-size ) 304 | shift; RSA_KEY_SIZE=$1 305 | ;; 306 | *) 307 | cat </dev/null | grep "^ID:" | grep -v "0x00" \ 346 | >${MY_TMP}/providers.lst 347 | 348 | exec < ${MY_TMP}/providers.lst 349 | while IFS= read -r prv; do 350 | # Format of list-providers output: 351 | #ID: 0x01 (Mbed Crypto provider) 352 | #ID: 0x03 (TPM provider) 353 | prv_id=$(echo $prv | cut -f 2 -d ' ') 354 | prv_id=$(echo $(($prv_id))) # Hex -> decimal 355 | 356 | if [ -z "$PROVIDER" ] || [ "$PROVIDER" -eq "$prv_id" ]; then 357 | prv_name=${prv##*(} 358 | prv_name=${prv_name%)*} 359 | 360 | echo 361 | echo "Testing $prv_name" 362 | test_crypto_provider $prv_id 363 | fi 364 | done 365 | 366 | exit $EXIT_CODE 367 | -------------------------------------------------------------------------------- /tests/test_config.toml: -------------------------------------------------------------------------------- 1 | [core_settings] 2 | allow_root = true 3 | log_level = "error" 4 | log_timestamp = true 5 | log_error_details = true 6 | 7 | [listener] 8 | listener_type = "DomainSocket" 9 | timeout = 200 # in milliseconds 10 | socket_path = "/tmp/parsec.sock" 11 | 12 | [authenticator] 13 | auth_type = "UnixPeerCredentials" 14 | 15 | [[key_manager]] 16 | name = "on-disk-manager" 17 | manager_type = "OnDisk" 18 | store_path = "mappings" 19 | 20 | [[provider]] 21 | provider_type = "MbedCrypto" 22 | key_info_manager = "on-disk-manager" 23 | --------------------------------------------------------------------------------