Move printing of ssh information into its own command

This commit is contained in:
Heiko Schaefer 2022-03-18 12:38:15 +01:00
parent 0b4a18b136
commit 4656394112
No known key found for this signature in database
GPG key ID: 4A849A1904CCBD7D
3 changed files with 47 additions and 14 deletions

View file

@ -5,7 +5,7 @@
name = "openpgp-card-tools" name = "openpgp-card-tools"
description = "CLI tools for OpenPGP cards" description = "CLI tools for OpenPGP cards"
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
version = "0.0.3" version = "0.0.4"
authors = ["Heiko Schaefer <heiko@schaefer.name>"] authors = ["Heiko Schaefer <heiko@schaefer.name>"]
edition = "2018" edition = "2018"
repository = "https://gitlab.com/hkos/openpgp-card" repository = "https://gitlab.com/hkos/openpgp-card"

View 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,
}, },
Ssh {
#[clap(name = "card ident", short = 'c', long = "card")]
ident: Option<String>,
},
FactoryReset { FactoryReset {
#[clap(name = "card ident", short = 'c', long = "card")] #[clap(name = "card ident", short = 'c', long = "card")]
ident: String, ident: String,

View file

@ -35,6 +35,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::Ssh { ident } => {
print_ssh(ident)?;
}
cli::Command::SetIdentity { ident, id } => { cli::Command::SetIdentity { ident, id } => {
set_identity(&ident, id)?; set_identity(&ident, id)?;
} }
@ -168,8 +171,6 @@ fn print_status(ident: Option<String>, verbose: bool) -> Result<()> {
let mut pgp = OpenPgp::new(&mut *card); let mut pgp = OpenPgp::new(&mut *card);
let mut open = Open::new(pgp.transaction()?)?; let mut open = Open::new(pgp.transaction()?)?;
let ident = open.application_identifier()?.ident();
print!("OpenPGP card {}", open.application_identifier()?.ident()); print!("OpenPGP card {}", open.application_identifier()?.ident());
let ai = open.application_identifier()?; let ai = open.application_identifier()?;
@ -228,7 +229,6 @@ fn print_status(ident: Option<String>, verbose: bool) -> Result<()> {
println! {" created: {}", kgt.formatted()}; println! {" created: {}", kgt.formatted()};
} }
println! {" algorithm: {}", open.algorithm_attributes(KeyType::Signing)?}; println! {" algorithm: {}", open.algorithm_attributes(KeyType::Signing)?};
if verbose { if verbose {
if let Ok(pkm) = open.public_key(KeyType::Signing) { if let Ok(pkm) = open.public_key(KeyType::Signing) {
println! {" public key material: {}", pkm}; println! {" public key material: {}", pkm};
@ -244,7 +244,6 @@ fn print_status(ident: Option<String>, verbose: bool) -> Result<()> {
println! {" created: {}", kgt.formatted()}; println! {" created: {}", kgt.formatted()};
} }
println! {" algorithm: {}", open.algorithm_attributes(KeyType::Decryption)?}; println! {" algorithm: {}", open.algorithm_attributes(KeyType::Decryption)?};
if verbose { if verbose {
if let Ok(pkm) = open.public_key(KeyType::Decryption) { if let Ok(pkm) = open.public_key(KeyType::Decryption) {
println! {" public key material: {}", pkm}; println! {" public key material: {}", pkm};
@ -256,20 +255,12 @@ fn print_status(ident: Option<String>, verbose: bool) -> Result<()> {
if let Some(fp) = fps.authentication() { if let Some(fp) = fps.authentication() {
println!(" fingerprint: {}", fp.to_spaced_hex()); println!(" fingerprint: {}", fp.to_spaced_hex());
} }
let pubkey = open.public_key(KeyType::Authentication);
if let Ok(pkm) = &pubkey {
if let Ok(ssh) = util::get_ssh_pubkey_string(pkm, ident) {
// print auth key as openssh public key string
println!(" {}", ssh);
}
}
if let Some(kgt) = kgt.authentication() { if let Some(kgt) = kgt.authentication() {
println! {" created: {}", kgt.formatted()}; println! {" created: {}", kgt.formatted()};
} }
println! {" algorithm: {}", open.algorithm_attributes(KeyType::Authentication)?}; println! {" algorithm: {}", open.algorithm_attributes(KeyType::Authentication)?};
if verbose { if verbose {
if let Ok(pkm) = pubkey { if let Ok(pkm) = open.public_key(KeyType::Authentication) {
println! {" public key material: {}", pkm}; println! {" public key material: {}", pkm};
} }
} }
@ -317,6 +308,44 @@ fn print_status(ident: Option<String>, verbose: bool) -> Result<()> {
Ok(()) Ok(())
} }
fn print_ssh(ident: Option<String>) -> Result<()> {
let mut card: Box<dyn CardBackend + Send + Sync> = if let Some(ident) = ident {
Box::new(util::open_card(&ident)?)
} else {
let mut cards = util::cards()?;
if cards.len() == 1 {
Box::new(cards.pop().unwrap())
} else {
return Err(anyhow::anyhow!("Found {} cards", cards.len()));
}
};
let mut pgp = OpenPgp::new(&mut *card);
let mut open = Open::new(pgp.transaction()?)?;
let ident = open.application_identifier()?.ident();
println!("OpenPGP card {}", open.application_identifier()?.ident());
// Print fingerprint of authentication subkey
let fps = open.fingerprints()?;
println!();
if let Some(fp) = fps.authentication() {
println!("Authentication subkey fingerprint:\n{}", fp);
}
// Show authentication subkey as openssh public key string
if let Ok(pkm) = open.public_key(KeyType::Authentication) {
if let Ok(ssh) = util::get_ssh_pubkey_string(&pkm, ident) {
println!();
println!("Authentication subkey as ssh public key:\n{}", ssh);
}
}
Ok(())
}
fn decrypt( fn decrypt(
ident: &str, ident: &str,
pin_file: Option<PathBuf>, pin_file: Option<PathBuf>,