Print the auth key in ssh public key format, in the "status" output.
This commit is contained in:
parent
8a759f01f5
commit
984aa219bf
3 changed files with 114 additions and 1 deletions
|
@ -18,6 +18,7 @@ openpgp-card = { path = "../openpgp-card", version = "0.1" }
|
||||||
openpgp-card-pcsc = { path = "../pcsc", version = "0.1" }
|
openpgp-card-pcsc = { path = "../pcsc", version = "0.1" }
|
||||||
pcsc = "2"
|
pcsc = "2"
|
||||||
openpgp-card-sequoia = { path = "../openpgp-card-sequoia", version = "0.0.7" }
|
openpgp-card-sequoia = { path = "../openpgp-card-sequoia", version = "0.0.7" }
|
||||||
|
sshkeys = "0.3"
|
||||||
rpassword = "5"
|
rpassword = "5"
|
||||||
chrono = "0.4"
|
chrono = "0.4"
|
||||||
anyhow = "1"
|
anyhow = "1"
|
||||||
|
|
|
@ -178,6 +178,8 @@ fn print_status(ident: Option<String>, verbose: bool) -> Result<()> {
|
||||||
|
|
||||||
let mut open = Open::new(&mut txc)?;
|
let mut open = Open::new(&mut txc)?;
|
||||||
|
|
||||||
|
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()?;
|
||||||
|
@ -262,12 +264,20 @@ 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) = open.public_key(KeyType::Authentication) {
|
if let Ok(pkm) = pubkey {
|
||||||
println! {" public key material: {}", pkm};
|
println! {" public key material: {}", pkm};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
use anyhow::{anyhow, Context, Result};
|
use anyhow::{anyhow, Context, Result};
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
|
use openpgp_card::algorithm::{Algo, Curve};
|
||||||
|
use openpgp_card::crypto_data::{EccType, PublicKeyMaterial};
|
||||||
use openpgp_card::Error;
|
use openpgp_card::Error;
|
||||||
use openpgp_card_pcsc::PcscCard;
|
use openpgp_card_pcsc::PcscCard;
|
||||||
use openpgp_card_sequoia::card::{Admin, Open, Sign, User};
|
use openpgp_card_sequoia::card::{Admin, Open, Sign, User};
|
||||||
|
@ -110,3 +112,103 @@ pub(crate) fn open_or_stdout(
|
||||||
None => Ok(Box::new(std::io::stdout())),
|
None => Ok(Box::new(std::io::stdout())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_ssh_pubkey(
|
||||||
|
pkm: &PublicKeyMaterial,
|
||||||
|
ident: String,
|
||||||
|
) -> Result<sshkeys::PublicKey> {
|
||||||
|
let cardno = format!("cardno:{}", ident);
|
||||||
|
|
||||||
|
let (key_type, kind) = match pkm {
|
||||||
|
PublicKeyMaterial::R(rsa) => {
|
||||||
|
let key_type = sshkeys::KeyType::from_name("ssh-rsa")?;
|
||||||
|
|
||||||
|
let kind = sshkeys::PublicKeyKind::Rsa(sshkeys::RsaPublicKey {
|
||||||
|
e: rsa.v().to_vec(),
|
||||||
|
n: rsa.n().to_vec(),
|
||||||
|
});
|
||||||
|
|
||||||
|
Ok((key_type, kind))
|
||||||
|
}
|
||||||
|
PublicKeyMaterial::E(ecc) => {
|
||||||
|
if let Algo::Ecc(ecc_attrs) = ecc.algo() {
|
||||||
|
match ecc_attrs.ecc_type() {
|
||||||
|
EccType::EdDSA => {
|
||||||
|
let key_type =
|
||||||
|
sshkeys::KeyType::from_name("ssh-ed25519")?;
|
||||||
|
|
||||||
|
let kind = sshkeys::PublicKeyKind::Ed25519(
|
||||||
|
sshkeys::Ed25519PublicKey {
|
||||||
|
key: ecc.data().to_vec(),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok((key_type, kind))
|
||||||
|
}
|
||||||
|
EccType::ECDSA => {
|
||||||
|
let (curve, name) = match ecc_attrs.curve() {
|
||||||
|
Curve::NistP256r1 => Ok((
|
||||||
|
sshkeys::Curve::from_identifier("nistp256")?,
|
||||||
|
"ecdsa-sha2-nistp256",
|
||||||
|
)),
|
||||||
|
Curve::NistP384r1 => Ok((
|
||||||
|
sshkeys::Curve::from_identifier("nistp384")?,
|
||||||
|
"ecdsa-sha2-nistp384",
|
||||||
|
)),
|
||||||
|
Curve::NistP521r1 => Ok((
|
||||||
|
sshkeys::Curve::from_identifier("nistp521")?,
|
||||||
|
"ecdsa-sha2-nistp521",
|
||||||
|
)),
|
||||||
|
_ => Err(anyhow!(
|
||||||
|
"Unexpected ECDSA curve {:?}",
|
||||||
|
ecc_attrs.curve()
|
||||||
|
)),
|
||||||
|
}?;
|
||||||
|
|
||||||
|
let key_type = sshkeys::KeyType::from_name(name)?;
|
||||||
|
|
||||||
|
let kind = sshkeys::PublicKeyKind::Ecdsa(
|
||||||
|
sshkeys::EcdsaPublicKey {
|
||||||
|
curve,
|
||||||
|
key: ecc.data().to_vec(),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok((key_type, kind))
|
||||||
|
}
|
||||||
|
_ => Err(anyhow!(
|
||||||
|
"Unexpected EccType {:?}",
|
||||||
|
ecc_attrs.ecc_type()
|
||||||
|
)),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Err(anyhow!("Unexpected Algo in EccPub {:?}", ecc))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => Err(anyhow!("Unexpected PublicKeyMaterial type {:?}", pkm)),
|
||||||
|
}?;
|
||||||
|
|
||||||
|
let pk = sshkeys::PublicKey {
|
||||||
|
key_type,
|
||||||
|
comment: Some(cardno),
|
||||||
|
kind,
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(pk)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return a String representation of an ssh public key, in a form like:
|
||||||
|
/// "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAuTuxILMTvzTIRvaRqqUM3aRDoEBgz/JAoWKsD1ECxy cardno:FFFE:43194240"
|
||||||
|
pub(crate) fn get_ssh_pubkey_string(
|
||||||
|
pkm: &PublicKeyMaterial,
|
||||||
|
ident: String,
|
||||||
|
) -> Result<String> {
|
||||||
|
let pk = get_ssh_pubkey(pkm, ident)?;
|
||||||
|
|
||||||
|
let mut v = vec![];
|
||||||
|
pk.write(&mut v)?;
|
||||||
|
|
||||||
|
let s = String::from_utf8_lossy(&v).to_string();
|
||||||
|
|
||||||
|
Ok(s.trim().into())
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue