Implement an "info" command that prints capabilities/metadata for a card (the output format is currently not very nice, it would benefit from working on https://gitlab.com/hkos/openpgp-card/-/issues/9).
This commit is contained in:
parent
2f903f5907
commit
58b8454e33
3 changed files with 96 additions and 32 deletions
|
@ -91,8 +91,7 @@ is plugged in):
|
||||||
$ opgpcard status --card ABCD:01234567
|
$ opgpcard status --card ABCD:01234567
|
||||||
```
|
```
|
||||||
|
|
||||||
Add `-v` for more verbose card status (including the list of supported
|
Add `-v` for more verbose card status (this prints public key data for each key slot):
|
||||||
algorithms, if the card returns an algorithm list):
|
|
||||||
|
|
||||||
```
|
```
|
||||||
$ opgpcard status -c ABCD:01234567 -v
|
$ opgpcard status -c ABCD:01234567 -v
|
||||||
|
@ -122,23 +121,6 @@ Signature counter: 3
|
||||||
Signature pin only valid once: true
|
Signature pin only valid once: true
|
||||||
Password validation retry count:
|
Password validation retry count:
|
||||||
user pw: 3, reset: 3, admin pw: 3
|
user pw: 3, reset: 3, admin pw: 3
|
||||||
|
|
||||||
Supported algorithms:
|
|
||||||
SIG: RSA 2048 [e 32]
|
|
||||||
SIG: RSA 4096 [e 32]
|
|
||||||
SIG: Secp256k1 (ECDSA)
|
|
||||||
SIG: Ed25519 (EdDSA)
|
|
||||||
SIG: Ed448 (EdDSA)
|
|
||||||
DEC: RSA 2048 [e 32]
|
|
||||||
DEC: RSA 4096 [e 32]
|
|
||||||
DEC: Secp256k1 (ECDSA)
|
|
||||||
DEC: Cv25519 (ECDH)
|
|
||||||
DEC: X448 (ECDH)
|
|
||||||
AUT: RSA 2048 [e 32]
|
|
||||||
AUT: RSA 4096 [e 32]
|
|
||||||
AUT: Secp256k1 (ECDSA)
|
|
||||||
AUT: Ed25519 (EdDSA)
|
|
||||||
AUT: Ed448 (EdDSA)
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Get OpenPGP public key
|
### Get OpenPGP public key
|
||||||
|
@ -214,6 +196,55 @@ In the example output above, this string is the ssh public key:
|
||||||
|
|
||||||
`ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAII2dcYBqMCamidT5MpE3Cl3MIKcYMBekGXbK2aaN6JaH opgpcard:ABCD:01234567`
|
`ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAII2dcYBqMCamidT5MpE3Cl3MIKcYMBekGXbK2aaN6JaH opgpcard:ABCD:01234567`
|
||||||
|
|
||||||
|
### Show OpenPGP card metadata
|
||||||
|
|
||||||
|
Print information about the capabilities of a card, including the list of supported algorithms (if the card returns
|
||||||
|
that list).
|
||||||
|
|
||||||
|
Most of the output is probably not of interest to regular users.
|
||||||
|
|
||||||
|
```
|
||||||
|
$ opgpcard info
|
||||||
|
OpenPGP card FF06:00002001 (card version 2.0)
|
||||||
|
|
||||||
|
CardCapabilities {
|
||||||
|
command_chaining: true,
|
||||||
|
extended_lc_le: false,
|
||||||
|
extended_length_information: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
ExtendedCapabilities {
|
||||||
|
secure_messaging: true,
|
||||||
|
get_challenge: true,
|
||||||
|
key_import: true,
|
||||||
|
pw_status_change: true,
|
||||||
|
private_use_dos: true,
|
||||||
|
algo_attrs_changeable: false,
|
||||||
|
aes: false,
|
||||||
|
kdf_do: false,
|
||||||
|
sm_algo: 0,
|
||||||
|
max_len_challenge: 255,
|
||||||
|
max_len_cardholder_cert: 1216,
|
||||||
|
max_cmd_len: Some(
|
||||||
|
255,
|
||||||
|
),
|
||||||
|
max_resp_len: Some(
|
||||||
|
255,
|
||||||
|
),
|
||||||
|
max_len_special_do: None,
|
||||||
|
pin_block_2_format_support: None,
|
||||||
|
mse_command_support: None,
|
||||||
|
}
|
||||||
|
|
||||||
|
Firmware Version: 1.0.18
|
||||||
|
```
|
||||||
|
|
||||||
|
Or to query a specific card:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ opgpcard info --card ABCD:01234567
|
||||||
|
```
|
||||||
|
|
||||||
### Admin commands
|
### Admin commands
|
||||||
|
|
||||||
All `admin` commands need the admin PIN. It can be provided as a file, with `-P <admin-pin-file>`,
|
All `admin` commands need the admin PIN. It can be provided as a file, with `-P <admin-pin-file>`,
|
||||||
|
|
|
@ -27,6 +27,10 @@ pub enum Command {
|
||||||
#[clap(name = "verbose", short = 'v', long = "verbose")]
|
#[clap(name = "verbose", short = 'v', long = "verbose")]
|
||||||
verbose: bool,
|
verbose: bool,
|
||||||
},
|
},
|
||||||
|
Info {
|
||||||
|
#[clap(name = "card ident", short = 'c', long = "card")]
|
||||||
|
ident: Option<String>,
|
||||||
|
},
|
||||||
Ssh {
|
Ssh {
|
||||||
#[clap(name = "card ident", short = 'c', long = "card")]
|
#[clap(name = "card ident", short = 'c', long = "card")]
|
||||||
ident: Option<String>,
|
ident: Option<String>,
|
||||||
|
|
|
@ -39,6 +39,9 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
cli::Command::Status { ident, verbose } => {
|
cli::Command::Status { ident, verbose } => {
|
||||||
print_status(ident, verbose)?;
|
print_status(ident, verbose)?;
|
||||||
}
|
}
|
||||||
|
cli::Command::Info { ident } => {
|
||||||
|
print_info(ident)?;
|
||||||
|
}
|
||||||
cli::Command::Ssh { ident } => {
|
cli::Command::Ssh { ident } => {
|
||||||
print_ssh(ident)?;
|
print_ssh(ident)?;
|
||||||
}
|
}
|
||||||
|
@ -310,22 +313,48 @@ fn print_status(ident: Option<String>, verbose: bool) -> Result<()> {
|
||||||
pws.err_count_pw3(),
|
pws.err_count_pw3(),
|
||||||
);
|
);
|
||||||
|
|
||||||
// FIXME: add General key info; login data; KDF setting
|
// FIXME: print "Login Data", "Key Information"
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// print metadata information about a card
|
||||||
|
fn print_info(ident: Option<String>) -> Result<()> {
|
||||||
|
let mut card = pick_card_for_reading(ident)?;
|
||||||
|
|
||||||
|
let mut pgp = OpenPgp::new(&mut *card);
|
||||||
|
let mut open = Open::new(pgp.transaction()?)?;
|
||||||
|
|
||||||
|
print!("OpenPGP card {}", open.application_identifier()?.ident());
|
||||||
|
|
||||||
|
let ai = open.application_identifier()?;
|
||||||
|
let version = ai.version().to_be_bytes();
|
||||||
|
println!(" (card version {}.{})\n", version[0], version[1]);
|
||||||
|
|
||||||
|
if let Some(cc) = open.historical_bytes()?.card_capabilities() {
|
||||||
|
println!("{:#?}\n", cc);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(eli) = open.extended_length_information()? {
|
||||||
|
println!("{:#?}\n", eli);
|
||||||
|
}
|
||||||
|
|
||||||
|
let ec = open.extended_capabilities()?;
|
||||||
|
println!("{:#?}\n", ec);
|
||||||
|
|
||||||
if verbose {
|
|
||||||
// Algorithm information (list of supported algorithms)
|
// Algorithm information (list of supported algorithms)
|
||||||
if let Ok(Some(ai)) = open.algorithm_information() {
|
if let Ok(Some(ai)) = open.algorithm_information() {
|
||||||
println!();
|
|
||||||
println!("Supported algorithms:");
|
println!("Supported algorithms:");
|
||||||
println!("{}", ai);
|
println!("{}", ai);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: print KDF info
|
||||||
|
|
||||||
// YubiKey specific (?) firmware version
|
// YubiKey specific (?) firmware version
|
||||||
if let Ok(ver) = open.firmware_version() {
|
if let Ok(ver) = open.firmware_version() {
|
||||||
let ver = ver.iter().map(u8::to_string).collect::<Vec<_>>().join(".");
|
let ver = ver.iter().map(u8::to_string).collect::<Vec<_>>().join(".");
|
||||||
|
|
||||||
println!("Firmware Version: {}", ver);
|
println!("Firmware Version: {}\n", ver);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
Loading…
Reference in a new issue