diff --git a/tools/README.md b/tools/README.md index 368da87..e22c807 100644 --- a/tools/README.md +++ b/tools/README.md @@ -91,8 +91,7 @@ is plugged in): $ opgpcard status --card ABCD:01234567 ``` -Add `-v` for more verbose card status (including the list of supported -algorithms, if the card returns an algorithm list): +Add `-v` for more verbose card status (this prints public key data for each key slot): ``` $ opgpcard status -c ABCD:01234567 -v @@ -122,23 +121,6 @@ Signature counter: 3 Signature pin only valid once: true Password validation retry count: 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 @@ -214,6 +196,55 @@ In the example output above, this string is the ssh public key: `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 All `admin` commands need the admin PIN. It can be provided as a file, with `-P `, diff --git a/tools/src/bin/opgpcard/cli.rs b/tools/src/bin/opgpcard/cli.rs index 026c62d..f05dc6c 100644 --- a/tools/src/bin/opgpcard/cli.rs +++ b/tools/src/bin/opgpcard/cli.rs @@ -27,6 +27,10 @@ pub enum Command { #[clap(name = "verbose", short = 'v', long = "verbose")] verbose: bool, }, + Info { + #[clap(name = "card ident", short = 'c', long = "card")] + ident: Option, + }, Ssh { #[clap(name = "card ident", short = 'c', long = "card")] ident: Option, diff --git a/tools/src/bin/opgpcard/main.rs b/tools/src/bin/opgpcard/main.rs index 76da734..9489599 100644 --- a/tools/src/bin/opgpcard/main.rs +++ b/tools/src/bin/opgpcard/main.rs @@ -39,6 +39,9 @@ fn main() -> Result<(), Box> { cli::Command::Status { ident, verbose } => { print_status(ident, verbose)?; } + cli::Command::Info { ident } => { + print_info(ident)?; + } cli::Command::Ssh { ident } => { print_ssh(ident)?; } @@ -310,22 +313,48 @@ fn print_status(ident: Option, verbose: bool) -> Result<()> { pws.err_count_pw3(), ); - // FIXME: add General key info; login data; KDF setting + // FIXME: print "Login Data", "Key Information" - if verbose { - // Algorithm information (list of supported algorithms) - if let Ok(Some(ai)) = open.algorithm_information() { - println!(); - println!("Supported algorithms:"); - println!("{}", ai); - } + Ok(()) +} - // YubiKey specific (?) firmware version - if let Ok(ver) = open.firmware_version() { - let ver = ver.iter().map(u8::to_string).collect::>().join("."); +/// print metadata information about a card +fn print_info(ident: Option) -> Result<()> { + let mut card = pick_card_for_reading(ident)?; - println!("Firmware Version: {}", ver); - } + 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); + + // Algorithm information (list of supported algorithms) + if let Ok(Some(ai)) = open.algorithm_information() { + println!("Supported algorithms:"); + println!("{}", ai); + } + + // FIXME: print KDF info + + // YubiKey specific (?) firmware version + if let Ok(ver) = open.firmware_version() { + let ver = ver.iter().map(u8::to_string).collect::>().join("."); + + println!("Firmware Version: {}\n", ver); } Ok(())