Merge branch 'nora/texts' into 'main'
Add and improve help texts See merge request openpgp-card/openpgp-card!19
This commit is contained in:
commit
d689ceb1dc
13 changed files with 350 additions and 90 deletions
|
@ -20,7 +20,7 @@ sshkeys = "0.3.2"
|
|||
pem = "1"
|
||||
rpassword = "6"
|
||||
anyhow = "1"
|
||||
clap = { version = "3", features = ["derive"] }
|
||||
clap = { version = "3", features = ["derive", "wrap_help"] }
|
||||
env_logger = "0.9"
|
||||
log = "0.4"
|
||||
serde_json = "1.0.86"
|
||||
|
@ -28,6 +28,7 @@ serde = { version = "1.0.145", features = ["derive"] }
|
|||
semver = "1.0.14"
|
||||
serde_yaml = "0.9.13"
|
||||
thiserror = "1.0.37"
|
||||
indoc = "1"
|
||||
|
||||
[build-dependencies]
|
||||
subplot-build = "0.5.0"
|
||||
|
|
|
@ -33,10 +33,6 @@ pub struct Cli {
|
|||
|
||||
#[derive(Parser, Debug)]
|
||||
pub enum Command {
|
||||
/// Show all output versions that are supported. Mark the
|
||||
/// currently chosen one with a star.
|
||||
OutputVersions {},
|
||||
|
||||
/// Enumerate available OpenPGP cards
|
||||
List {},
|
||||
|
||||
|
@ -46,7 +42,7 @@ pub enum Command {
|
|||
/// Show technical details about a card
|
||||
Info(commands::info::InfoCommand),
|
||||
|
||||
/// Display a card's authentication key as an SSH public key
|
||||
/// Show a card's authentication key as an SSH public key
|
||||
Ssh(commands::ssh::SshCommand),
|
||||
|
||||
/// Export the key data on a card as an OpenPGP public key
|
||||
|
@ -56,20 +52,60 @@ pub enum Command {
|
|||
Admin(commands::admin::AdminCommand),
|
||||
|
||||
/// PIN management (change PINs, reset blocked PINs)
|
||||
#[clap(
|
||||
long_about = indoc::indoc! { "
|
||||
PIN management (change PINs, reset blocked PINs)
|
||||
|
||||
OpenPGP cards use PINs (numerical passwords) to verify that a user is allowed to \
|
||||
perform an operation. There are two PINs for regular operation, User PIN and Admin \
|
||||
PIN, and one optional Resetting Code.
|
||||
|
||||
The User PIN is required to use cryptographic operations on a card (such as \
|
||||
decryption or signing).
|
||||
The Admin PIN is needed to configure a card (for example to import an OpenPGP key \
|
||||
into the card) or to unblock the User PIN.
|
||||
The Resetting Code only allows unblocking the User PIN. This is useful if the user \
|
||||
doesn't have access to the Admin PIN.
|
||||
|
||||
By default, on unconfigured (or factory reset) cards, the User PIN is typically set to
|
||||
123456, and the Admin PIN is set to 12345678."
|
||||
},
|
||||
)]
|
||||
Pin(commands::pin::PinCommand),
|
||||
|
||||
/// Decrypt data using a card
|
||||
Decrypt(commands::decrypt::DecryptCommand),
|
||||
|
||||
/// Sign data using a card
|
||||
///
|
||||
/// Currently, only detached signatures are supported.
|
||||
Sign(commands::sign::SignCommand),
|
||||
|
||||
/// Attestation management (Yubico)
|
||||
/// Attestation management (Yubico only)
|
||||
///
|
||||
/// Yubico implements a proprietary extension to the OpenPGP card standard to
|
||||
/// cryptographically certify that a certain asymmetric key has been generated on device, and
|
||||
/// not imported.
|
||||
///
|
||||
/// This feature is available on YubiKey 5 devices with firmware version 5.2 or newer.
|
||||
Attestation(commands::attestation::AttestationCommand),
|
||||
|
||||
/// Completely reset a card (deletes all data, including the keys on the card!)
|
||||
/// Completely reset a card (deletes all data including keys!)
|
||||
FactoryReset(commands::factory_reset::FactoryResetCommand),
|
||||
|
||||
/// Change identity (applies only to Nitrokey Start)
|
||||
/// Change identity (Nitrokey Start only)
|
||||
///
|
||||
/// A Nitrokey Start device contains three distinct virtual OpenPGP cards, select the identity
|
||||
/// of the virtual card to activate.
|
||||
SetIdentity(commands::set_identity::SetIdentityCommand),
|
||||
|
||||
/// Show supported output format versions
|
||||
#[clap(
|
||||
long_about = indoc::indoc! { "
|
||||
Show supported output format versions for JSON and YAML output.
|
||||
|
||||
Mark the currently chosen one with a star."
|
||||
}
|
||||
)]
|
||||
OutputVersions {},
|
||||
}
|
||||
|
|
|
@ -30,10 +30,20 @@ use crate::{output, util, ENTER_ADMIN_PIN, ENTER_USER_PIN};
|
|||
|
||||
#[derive(Parser, Debug)]
|
||||
pub struct AdminCommand {
|
||||
#[clap(name = "card ident", short = 'c', long = "card")]
|
||||
#[clap(
|
||||
name = "card ident",
|
||||
short = 'c',
|
||||
long = "card",
|
||||
help = "Identifier of the card to use"
|
||||
)]
|
||||
pub ident: String,
|
||||
|
||||
#[clap(name = "Admin PIN file", short = 'P', long = "admin-pin")]
|
||||
#[clap(
|
||||
name = "Admin PIN file",
|
||||
short = 'P',
|
||||
long = "admin-pin",
|
||||
help = "Optionally, get Admin PIN from a file"
|
||||
)]
|
||||
pub admin_pin: Option<PathBuf>,
|
||||
|
||||
#[clap(subcommand)]
|
||||
|
@ -43,66 +53,118 @@ pub struct AdminCommand {
|
|||
#[derive(Parser, Debug)]
|
||||
pub enum AdminSubCommand {
|
||||
/// Set cardholder name
|
||||
Name { name: String },
|
||||
|
||||
/// Set cardholder URL
|
||||
Url { url: String },
|
||||
|
||||
/// Import a Key.
|
||||
///
|
||||
/// If no fingerprint is provided, the key will only be imported if
|
||||
/// there are zero or one (sub)keys for each key slot on the card.
|
||||
Import {
|
||||
keyfile: PathBuf,
|
||||
|
||||
#[clap(name = "Signature key fingerprint", short = 's', long = "sig-fp")]
|
||||
sig_fp: Option<String>,
|
||||
|
||||
#[clap(name = "Decryption key fingerprint", short = 'd', long = "dec-fp")]
|
||||
dec_fp: Option<String>,
|
||||
|
||||
#[clap(name = "Authentication key fingerprint", short = 'a', long = "auth-fp")]
|
||||
auth_fp: Option<String>,
|
||||
Name {
|
||||
#[clap(help = "cardholder name to set on the card")]
|
||||
name: String,
|
||||
},
|
||||
|
||||
/// Generate a Key.
|
||||
/// Set certificate URL
|
||||
Url {
|
||||
#[clap(help = "URL that provides the certificate for the key material on this card")]
|
||||
url: String,
|
||||
},
|
||||
|
||||
/// Import a Key onto the card.
|
||||
///
|
||||
/// Most keys can be imported without specifying subkey fingerprints. However, if the key
|
||||
/// contins more than one signing, decryption or authentication capable subkey, subkeys must be
|
||||
/// explicitly selected.
|
||||
///
|
||||
/// If any of the options is given, only the selected subkeys are imported into the selected
|
||||
/// slots.
|
||||
///
|
||||
/// Subkey capabilities must match the slot the key is imported into. The DEC slot can
|
||||
/// only be used for encryption capable subkeys. The SIG and AUT slots can be used for signing,
|
||||
/// certification and authentication capable subkeys.
|
||||
Import {
|
||||
#[clap(help = "File that contains the PGP private key")]
|
||||
keyfile: PathBuf,
|
||||
|
||||
/// Optionally, select the subkey to import in the SIG slot
|
||||
#[clap(name = "SIG subkey fingerprint", short = 's', long = "sig-fp")]
|
||||
sig_fp: Option<String>,
|
||||
|
||||
/// Optionally, select the subkey to import in the DEC slot
|
||||
#[clap(name = "DEC subkey fingerprint", short = 'd', long = "dec-fp")]
|
||||
dec_fp: Option<String>,
|
||||
|
||||
/// Optionally, select the subkey to import in the AUT slot
|
||||
#[clap(name = "AUT subkey fingerprint", short = 'a', long = "aut-fp")]
|
||||
aut_fp: Option<String>,
|
||||
},
|
||||
|
||||
/// Generate a Key on the card.
|
||||
///
|
||||
/// A signing key is always created, decryption and authentication keys
|
||||
/// are optional.
|
||||
Generate(AdminGenerateCommand),
|
||||
|
||||
/// Set touch policy
|
||||
/// Set the card's touch policy (if supported)
|
||||
///
|
||||
/// A touch policy defines if cryptographic operations on the card require user interaction
|
||||
/// with the card, for example by touching a button on the card.
|
||||
///
|
||||
/// Only some cards support this feature at all, not all cards support all policies.
|
||||
///
|
||||
/// Caution: Setting the ATT slot to Fixed or Cached-Fixed is permanent. Even a factory reset does
|
||||
/// not undo this setting.
|
||||
Touch {
|
||||
/// Key slot to set the touch policy for
|
||||
#[clap(name = "Key slot", short = 'k', long = "key", value_enum)]
|
||||
key: BasePlusAttKeySlot,
|
||||
|
||||
#[clap(name = "Policy", short = 'p', long = "policy", value_enum)]
|
||||
/// Touch policy to set on this key slot
|
||||
#[clap(
|
||||
name = "Policy",
|
||||
short = 'p',
|
||||
long = "policy",
|
||||
value_enum,
|
||||
long_help = "Touch policy to set on this key slot
|
||||
|
||||
Off: No touch confirmation required.
|
||||
On: Touch confirmation required for each operation.
|
||||
Fixed: Like 'On', but the policy can only be changed by a reset.
|
||||
Cached: Like 'On', but touch confirmation is valid for 15 seconds.
|
||||
Cached-Fixed: Combines 'Cached' and 'Fixed'."
|
||||
)]
|
||||
policy: TouchPolicy,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
pub struct AdminGenerateCommand {
|
||||
#[clap(name = "User PIN file", short = 'p', long = "user-pin")]
|
||||
user_pin: Option<PathBuf>,
|
||||
|
||||
/// Output file
|
||||
#[clap(name = "output", long = "output", short = 'o')]
|
||||
output_file: PathBuf,
|
||||
|
||||
#[clap(long = "no-decrypt", action = clap::ArgAction::SetFalse)]
|
||||
/// Do not create a key in the DEC slot
|
||||
#[clap(long = "no-dec", action = clap::ArgAction::SetFalse)]
|
||||
decrypt: bool,
|
||||
|
||||
#[clap(long = "no-auth", action = clap::ArgAction::SetFalse)]
|
||||
/// Do not create a key in the AUT slot
|
||||
#[clap(long = "no-aut", action = clap::ArgAction::SetFalse)]
|
||||
auth: bool,
|
||||
|
||||
/// Algorithm
|
||||
#[clap(value_enum)]
|
||||
/// Choose the algorithm for the key material to generate on the card.
|
||||
///
|
||||
/// If the parameter is not given, use the algorithm currently set on the card.
|
||||
///
|
||||
/// Specific cards support a set of algorithms that can differ between models. On modern cards,
|
||||
/// use 'opgpcard info' to see the list of supported algorithms.
|
||||
#[clap(name = "algorithm", value_enum)]
|
||||
algo: Option<Algo>,
|
||||
|
||||
/// User ID to add to the exported certificate representation
|
||||
#[clap(name = "User ID", short = 'u', long = "userid")]
|
||||
user_ids: Vec<String>,
|
||||
|
||||
#[clap(
|
||||
name = "User PIN file",
|
||||
short = 'p',
|
||||
long = "user-pin",
|
||||
help = "Optionally, get User PIN from a file"
|
||||
)]
|
||||
user_pin: Option<PathBuf>,
|
||||
}
|
||||
|
||||
#[derive(ValueEnum, Debug, Clone)]
|
||||
|
@ -161,7 +223,7 @@ pub enum Algo {
|
|||
Nistp256,
|
||||
Nistp384,
|
||||
Nistp521,
|
||||
Curve25519,
|
||||
Cv25519,
|
||||
}
|
||||
|
||||
impl From<Algo> for AlgoSimple {
|
||||
|
@ -173,7 +235,7 @@ impl From<Algo> for AlgoSimple {
|
|||
Algo::Nistp256 => AlgoSimple::NIST256,
|
||||
Algo::Nistp384 => AlgoSimple::NIST384,
|
||||
Algo::Nistp521 => AlgoSimple::NIST521,
|
||||
Algo::Curve25519 => AlgoSimple::Curve25519,
|
||||
Algo::Cv25519 => AlgoSimple::Curve25519,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -200,9 +262,9 @@ pub fn admin(
|
|||
keyfile,
|
||||
sig_fp,
|
||||
dec_fp,
|
||||
auth_fp,
|
||||
aut_fp,
|
||||
} => {
|
||||
import_command(keyfile, sig_fp, dec_fp, auth_fp, card, admin_pin.as_deref())?;
|
||||
import_command(keyfile, sig_fp, dec_fp, aut_fp, card, admin_pin.as_deref())?;
|
||||
}
|
||||
AdminSubCommand::Generate(cmd) => {
|
||||
generate_command(
|
||||
|
@ -238,14 +300,14 @@ fn keys_pick_explicit<'a>(
|
|||
policy: &'a dyn Policy,
|
||||
sig_fp: Option<String>,
|
||||
dec_fp: Option<String>,
|
||||
auth_fp: Option<String>,
|
||||
aut_fp: Option<String>,
|
||||
) -> Result<[Option<ValidErasedKeyAmalgamation<'a, SecretParts>>; 3]> {
|
||||
let key_by_fp = |fp: Option<String>| match fp {
|
||||
Some(fp) => sq_util::private_subkey_by_fingerprint(key, policy, &fp),
|
||||
None => Ok(None),
|
||||
};
|
||||
|
||||
Ok([key_by_fp(sig_fp)?, key_by_fp(dec_fp)?, key_by_fp(auth_fp)?])
|
||||
Ok([key_by_fp(sig_fp)?, key_by_fp(dec_fp)?, key_by_fp(aut_fp)?])
|
||||
}
|
||||
|
||||
fn gen_subkeys(
|
||||
|
@ -321,7 +383,7 @@ fn import_command(
|
|||
keyfile: PathBuf,
|
||||
sig_fp: Option<String>,
|
||||
dec_fp: Option<String>,
|
||||
auth_fp: Option<String>,
|
||||
aut_fp: Option<String>,
|
||||
mut card: Card<Transaction>,
|
||||
admin_pin: Option<&[u8]>,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
|
@ -330,12 +392,12 @@ fn import_command(
|
|||
let p = StandardPolicy::new();
|
||||
|
||||
// select the (sub)keys to upload
|
||||
let [sig, dec, auth] = match (&sig_fp, &dec_fp, &auth_fp) {
|
||||
let [sig, dec, auth] = match (&sig_fp, &dec_fp, &aut_fp) {
|
||||
// No fingerprint has been provided, try to autoselect keys
|
||||
// (this fails if there is more than one (sub)key for any keytype).
|
||||
(&None, &None, &None) => keys_pick_yolo(&key, &p)?,
|
||||
|
||||
_ => keys_pick_explicit(&key, &p, sig_fp, dec_fp, auth_fp)?,
|
||||
_ => keys_pick_explicit(&key, &p, sig_fp, dec_fp, aut_fp)?,
|
||||
};
|
||||
|
||||
let mut pws: Vec<String> = vec![];
|
||||
|
|
|
@ -23,30 +23,59 @@ pub struct AttestationCommand {
|
|||
|
||||
#[derive(Parser, Debug)]
|
||||
pub enum AttSubCommand {
|
||||
/// Print the card's "Attestation Certificate"
|
||||
/// Print the card's attestation certificate
|
||||
///
|
||||
/// New YubiKeys are preloaded with an attestation certificate issued by the Yubico CA.
|
||||
Cert {
|
||||
#[clap(name = "card ident", short = 'c', long = "card")]
|
||||
#[clap(
|
||||
name = "card ident",
|
||||
short = 'c',
|
||||
long = "card",
|
||||
help = "Identifier of the card to use"
|
||||
)]
|
||||
ident: Option<String>,
|
||||
},
|
||||
|
||||
/// Generate "Attestation Statement" for one of the key slots on the card
|
||||
/// Generate attestation statement for one of the key slots on the card
|
||||
///
|
||||
/// An attestation statement can only be generated for key slots that contain keys that were
|
||||
/// generated by the card. See 'opgpcard admin generate' and 'opgpcard status -v'.
|
||||
Generate {
|
||||
#[clap(name = "card ident", short = 'c', long = "card")]
|
||||
#[clap(
|
||||
name = "card ident",
|
||||
short = 'c',
|
||||
long = "card",
|
||||
help = "Identifier of the card to use"
|
||||
)]
|
||||
ident: String,
|
||||
|
||||
/// Key slot to use
|
||||
#[clap(name = "Key slot", short = 'k', long = "key", value_enum)]
|
||||
key: BaseKeySlot,
|
||||
|
||||
#[clap(name = "User PIN file", short = 'p', long = "user-pin")]
|
||||
#[clap(
|
||||
name = "User PIN file",
|
||||
short = 'p',
|
||||
long = "user-pin",
|
||||
help = "Optionally, get User PIN from a file"
|
||||
)]
|
||||
user_pin: Option<PathBuf>,
|
||||
},
|
||||
|
||||
/// Print a "cardholder certificate" from the card.
|
||||
/// This shows the "Attestation Statement", if one has been generated.
|
||||
/// Print the attestation statement for one of the key slots on the card
|
||||
///
|
||||
/// An attestation statement can only be printed after generating it. See 'opgpcard attestation
|
||||
/// generate'.
|
||||
Statement {
|
||||
#[clap(name = "card ident", short = 'c', long = "card")]
|
||||
#[clap(
|
||||
name = "card ident",
|
||||
short = 'c',
|
||||
long = "card",
|
||||
help = "Identifier of the card to reset"
|
||||
)]
|
||||
ident: Option<String>,
|
||||
|
||||
/// Key slot to use
|
||||
#[clap(name = "Key slot", short = 'k', long = "key", value_enum)]
|
||||
key: BaseKeySlot,
|
||||
},
|
||||
|
|
|
@ -17,10 +17,20 @@ use crate::util;
|
|||
|
||||
#[derive(Parser, Debug)]
|
||||
pub struct DecryptCommand {
|
||||
#[clap(name = "card ident", short = 'c', long = "card")]
|
||||
#[clap(
|
||||
name = "card ident",
|
||||
short = 'c',
|
||||
long = "card",
|
||||
help = "Identifier of the card to use"
|
||||
)]
|
||||
ident: String,
|
||||
|
||||
#[clap(name = "User PIN file", short = 'p', long = "user-pin")]
|
||||
#[clap(
|
||||
name = "User PIN file",
|
||||
short = 'p',
|
||||
long = "user-pin",
|
||||
help = "Optionally, get User PIN from a file"
|
||||
)]
|
||||
pin_file: Option<PathBuf>,
|
||||
|
||||
/// Input file (stdin if unset)
|
||||
|
|
|
@ -10,7 +10,12 @@ use crate::util;
|
|||
|
||||
#[derive(Parser, Debug)]
|
||||
pub struct FactoryResetCommand {
|
||||
#[clap(name = "card ident", short = 'c', long = "card")]
|
||||
#[clap(
|
||||
name = "card ident",
|
||||
short = 'c',
|
||||
long = "card",
|
||||
help = "Identifier of the card to use"
|
||||
)]
|
||||
ident: String,
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,12 @@ use crate::versioned_output::{OutputBuilder, OutputFormat, OutputVersion};
|
|||
|
||||
#[derive(Parser, Debug)]
|
||||
pub struct InfoCommand {
|
||||
#[clap(name = "card ident", short = 'c', long = "card")]
|
||||
#[clap(
|
||||
name = "card ident",
|
||||
short = 'c',
|
||||
long = "card",
|
||||
help = "Identifier of the card to use"
|
||||
)]
|
||||
pub ident: Option<String>,
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,12 @@ use crate::{ENTER_ADMIN_PIN, ENTER_USER_PIN};
|
|||
|
||||
#[derive(Parser, Debug)]
|
||||
pub struct PinCommand {
|
||||
#[clap(name = "card ident", short = 'c', long = "card")]
|
||||
#[clap(
|
||||
name = "card ident",
|
||||
short = 'c',
|
||||
long = "card",
|
||||
help = "Identifier of the card to use"
|
||||
)]
|
||||
pub ident: String,
|
||||
|
||||
#[clap(subcommand)]
|
||||
|
@ -25,49 +30,111 @@ pub struct PinCommand {
|
|||
#[derive(Parser, Debug)]
|
||||
pub enum PinSubCommand {
|
||||
/// Set User PIN
|
||||
///
|
||||
/// Set a new User PIN by providing the current User PIN.
|
||||
SetUser {
|
||||
#[clap(name = "User PIN file old", short = 'p', long = "user-pin-old")]
|
||||
#[clap(
|
||||
name = "User PIN file old",
|
||||
short = 'p',
|
||||
long = "user-pin-old",
|
||||
help = "Optionally, get old User PIN from a file"
|
||||
)]
|
||||
user_pin_old: Option<PathBuf>,
|
||||
|
||||
#[clap(name = "User PIN file new", short = 'q', long = "user-pin-new")]
|
||||
#[clap(
|
||||
name = "User PIN file new",
|
||||
short = 'q',
|
||||
long = "user-pin-new",
|
||||
help = "Optionally, get new User PIN from a file"
|
||||
)]
|
||||
user_pin_new: Option<PathBuf>,
|
||||
},
|
||||
|
||||
/// Set Admin PIN
|
||||
///
|
||||
/// Set a new Admin PIN by providing the current Admin PIN.
|
||||
SetAdmin {
|
||||
#[clap(name = "Admin PIN file old", short = 'P', long = "admin-pin-old")]
|
||||
#[clap(
|
||||
name = "Admin PIN file old",
|
||||
short = 'P',
|
||||
long = "admin-pin-old",
|
||||
help = "Optionally, get old Admin PIN from a file"
|
||||
)]
|
||||
admin_pin_old: Option<PathBuf>,
|
||||
|
||||
#[clap(name = "Admin PIN file new", short = 'Q', long = "admin-pin-new")]
|
||||
#[clap(
|
||||
name = "Admin PIN file new",
|
||||
short = 'Q',
|
||||
long = "admin-pin-new",
|
||||
help = "Optionally, get new Admin PIN from a file"
|
||||
)]
|
||||
admin_pin_new: Option<PathBuf>,
|
||||
},
|
||||
|
||||
/// Reset User PIN with Admin PIN
|
||||
///
|
||||
/// Set a new User PIN by providing the Admin PIN. This can also be used if the User PIN has
|
||||
/// been blocked.
|
||||
ResetUser {
|
||||
#[clap(name = "Admin PIN file", short = 'P', long = "admin-pin")]
|
||||
#[clap(
|
||||
name = "Admin PIN file",
|
||||
short = 'P',
|
||||
long = "admin-pin",
|
||||
help = "Optionally, get Admin PIN from a file"
|
||||
)]
|
||||
admin_pin: Option<PathBuf>,
|
||||
|
||||
#[clap(name = "User PIN file new", short = 'p', long = "user-pin-new")]
|
||||
#[clap(
|
||||
name = "User PIN file new",
|
||||
short = 'p',
|
||||
long = "user-pin-new",
|
||||
help = "Optionally, get new User PIN from a file"
|
||||
)]
|
||||
user_pin_new: Option<PathBuf>,
|
||||
},
|
||||
|
||||
/// Reset User PIN with Resetting Code
|
||||
///
|
||||
/// Set a new User PIN by providing the Resetting Code. This can also be used if the User PIN
|
||||
/// has been blocked.
|
||||
ResetUserRc {
|
||||
#[clap(
|
||||
name = "Resetting Code file",
|
||||
short = 'r',
|
||||
long = "reset-code",
|
||||
help = "Optionally, get the Resetting Code from a file"
|
||||
)]
|
||||
reset_code: Option<PathBuf>,
|
||||
|
||||
#[clap(
|
||||
name = "User PIN file new",
|
||||
short = 'p',
|
||||
long = "user-pin-new",
|
||||
help = "Optionally, get new User PIN from a file"
|
||||
)]
|
||||
user_pin_new: Option<PathBuf>,
|
||||
},
|
||||
|
||||
/// Set Resetting Code
|
||||
///
|
||||
/// Set a Resetting Code by providing the Admin PIN.
|
||||
SetReset {
|
||||
#[clap(name = "Admin PIN file", short = 'P', long = "admin-pin")]
|
||||
#[clap(
|
||||
name = "Admin PIN file",
|
||||
short = 'P',
|
||||
long = "admin-pin",
|
||||
help = "Optionally, get Admin PIN from a file"
|
||||
)]
|
||||
admin_pin: Option<PathBuf>,
|
||||
|
||||
#[clap(name = "Resetting code file", short = 'r', long = "reset-code")]
|
||||
#[clap(
|
||||
name = "Resetting Code file",
|
||||
short = 'r',
|
||||
long = "reset-code",
|
||||
help = "Optionally, get the Resetting Code from a file"
|
||||
)]
|
||||
reset_code: Option<PathBuf>,
|
||||
},
|
||||
|
||||
/// Reset User PIN with 'Resetting Code'
|
||||
ResetUserRc {
|
||||
#[clap(name = "Resetting Code file", short = 'r', long = "reset-code")]
|
||||
reset_code: Option<PathBuf>,
|
||||
|
||||
#[clap(name = "User PIN file new", short = 'p', long = "user-pin-new")]
|
||||
user_pin_new: Option<PathBuf>,
|
||||
},
|
||||
}
|
||||
|
||||
pub fn pin(ident: &str, cmd: PinSubCommand) -> Result<()> {
|
||||
|
|
|
@ -21,10 +21,20 @@ use crate::versioned_output::{OutputBuilder, OutputFormat, OutputVersion};
|
|||
|
||||
#[derive(Parser, Debug)]
|
||||
pub struct PubkeyCommand {
|
||||
#[clap(name = "card ident", short = 'c', long = "card")]
|
||||
#[clap(
|
||||
name = "card ident",
|
||||
short = 'c',
|
||||
long = "card",
|
||||
help = "Identifier of the card to use"
|
||||
)]
|
||||
ident: Option<String>,
|
||||
|
||||
#[clap(name = "User PIN file", short = 'p', long = "user-pin")]
|
||||
#[clap(
|
||||
name = "User PIN file",
|
||||
short = 'p',
|
||||
long = "user-pin",
|
||||
help = "Optionally, get User PIN from a file"
|
||||
)]
|
||||
user_pin: Option<PathBuf>,
|
||||
|
||||
/// User ID to add to the exported certificate representation
|
||||
|
|
|
@ -10,9 +10,15 @@ use crate::util;
|
|||
|
||||
#[derive(Parser, Debug)]
|
||||
pub struct SetIdentityCommand {
|
||||
#[clap(name = "card ident", short = 'c', long = "card")]
|
||||
#[clap(
|
||||
name = "card ident",
|
||||
short = 'c',
|
||||
long = "card",
|
||||
help = "Identifier of the card to use"
|
||||
)]
|
||||
ident: String,
|
||||
|
||||
/// Identity of the virtual card to activate
|
||||
#[clap(name = "identity", value_enum)]
|
||||
id: SetIdentityId,
|
||||
}
|
||||
|
|
|
@ -14,14 +14,28 @@ use crate::util;
|
|||
|
||||
#[derive(Parser, Debug)]
|
||||
pub struct SignCommand {
|
||||
#[clap(name = "card ident", short = 'c', long = "card")]
|
||||
#[clap(
|
||||
name = "card ident",
|
||||
short = 'c',
|
||||
long = "card",
|
||||
help = "Identifier of the card to use"
|
||||
)]
|
||||
pub ident: String,
|
||||
|
||||
/// User PIN file
|
||||
#[clap(short = 'p', long = "user-pin")]
|
||||
#[clap(
|
||||
name = "User PIN file",
|
||||
short = 'p',
|
||||
long = "user-pin",
|
||||
help = "Optionally, get User PIN from a file"
|
||||
)]
|
||||
pub user_pin: Option<PathBuf>,
|
||||
|
||||
#[clap(name = "detached", short = 'd', long = "detached")]
|
||||
#[clap(
|
||||
name = "detached",
|
||||
short = 'd',
|
||||
long = "detached",
|
||||
help = "Create a detached signature"
|
||||
)]
|
||||
pub detached: bool,
|
||||
|
||||
/// Input file (stdin if unset)
|
||||
|
|
|
@ -16,7 +16,12 @@ use crate::versioned_output::{OutputBuilder, OutputFormat, OutputVersion};
|
|||
|
||||
#[derive(Parser, Debug)]
|
||||
pub struct SshCommand {
|
||||
#[clap(name = "card ident", short = 'c', long = "card")]
|
||||
#[clap(
|
||||
name = "card ident",
|
||||
short = 'c',
|
||||
long = "card",
|
||||
help = "Identifier of the card to use"
|
||||
)]
|
||||
pub ident: Option<String>,
|
||||
}
|
||||
|
||||
|
|
|
@ -15,10 +15,20 @@ use crate::versioned_output::{OutputBuilder, OutputFormat, OutputVersion};
|
|||
|
||||
#[derive(Parser, Debug)]
|
||||
pub struct StatusCommand {
|
||||
#[clap(name = "card ident", short = 'c', long = "card")]
|
||||
#[clap(
|
||||
name = "card ident",
|
||||
short = 'c',
|
||||
long = "card",
|
||||
help = "Identifier of the card to use"
|
||||
)]
|
||||
pub ident: Option<String>,
|
||||
|
||||
#[clap(name = "verbose", short = 'v', long = "verbose")]
|
||||
#[clap(
|
||||
name = "verbose",
|
||||
short = 'v',
|
||||
long = "verbose",
|
||||
help = "Use verbose output"
|
||||
)]
|
||||
pub verbose: bool,
|
||||
|
||||
/// Print public key material for each key slot
|
||||
|
|
Loading…
Reference in a new issue