parsec_tool/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
6mod create_csr;
7mod create_ecc_key;
8mod create_rsa_key;
9mod decrypt;
10mod delete_client;
11mod delete_key;
12mod encrypt;
13mod export_public_key;
14mod generate_random;
15mod list_authenticators;
16mod list_clients;
17mod list_keys;
18mod list_opcodes;
19mod list_providers;
20mod ping;
21mod sign;
22
23use crate::error::{Error::ParsecClientError, Result};
24use 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};
31use parsec_client::BasicClient;
32use structopt::StructOpt;
33
34/// Command-line interface to Parsec operations.
35#[derive(Debug, StructOpt)]
36pub 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
86impl 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<String>) -> Result<BasicClient> {
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}