feat: v1.7.1
This commit is contained in:
@@ -1,13 +1,23 @@
|
||||
use clap::{App, ArgMatches, SubCommand};
|
||||
use clap::{App, Arg, ArgMatches, SubCommand};
|
||||
use rust_util::util_clap::{Command, CommandError};
|
||||
use rust_util::XResult;
|
||||
use spki::der::Encode;
|
||||
use tabled::{Table, Tabled};
|
||||
use x509_parser::parse_x509_certificate;
|
||||
use yubikey::{Certificate, YubiKey};
|
||||
use yubikey::piv::SlotId;
|
||||
|
||||
use crate::pivutil::get_algorithm_id;
|
||||
|
||||
#[derive(Tabled)]
|
||||
struct PivSlot {
|
||||
name: String,
|
||||
id: String,
|
||||
algorithm: String,
|
||||
subject: String,
|
||||
}
|
||||
|
||||
|
||||
pub struct CommandImpl;
|
||||
|
||||
impl Command for CommandImpl {
|
||||
@@ -15,9 +25,14 @@ impl Command for CommandImpl {
|
||||
|
||||
fn subcommand<'a>(&self) -> App<'a, 'a> {
|
||||
SubCommand::with_name(self.name()).about("PIV subcommand")
|
||||
.arg(Arg::with_name("table").long("table").help("Show table"))
|
||||
.arg(Arg::with_name("all").long("all").help("Show all"))
|
||||
}
|
||||
|
||||
fn run(&self, _arg_matches: &ArgMatches, _sub_arg_matches: &ArgMatches) -> CommandError {
|
||||
fn run(&self, _arg_matches: &ArgMatches, sub_arg_matches: &ArgMatches) -> CommandError {
|
||||
let show_table = sub_arg_matches.is_present("table");
|
||||
let show_all = sub_arg_matches.is_present("all");
|
||||
|
||||
let mut yk = opt_result!(YubiKey::open(), "YubiKey not found: {}");
|
||||
success!("Name: {}", yk.name());
|
||||
information!("Version: {}", yk.version());
|
||||
@@ -42,35 +57,53 @@ impl Command for CommandImpl {
|
||||
Err(e) => failure!("Get PIV keys failed: {}", e)
|
||||
}
|
||||
|
||||
let mut piv_slots = vec![];
|
||||
for slot in yubikey::piv::SLOTS {
|
||||
print_summary_info(&mut yk, slot).ok();
|
||||
print_summary_info(&mut yk, slot, &mut piv_slots, show_all, show_table).ok();
|
||||
}
|
||||
if show_table {
|
||||
println!("{}", Table::new(piv_slots).to_string());
|
||||
}
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
fn print_summary_info(yubikey: &mut YubiKey, slot: SlotId) -> XResult<()> {
|
||||
fn print_summary_info(yubikey: &mut YubiKey, slot: SlotId, piv_slots: &mut Vec<PivSlot>, show_all: bool, show_table: bool) -> XResult<()> {
|
||||
let slot_id: u8 = slot.into();
|
||||
let cert = match Certificate::read(yubikey, slot) {
|
||||
Ok(c) => c,
|
||||
Err(e) => {
|
||||
warning!("Slot: {:?}, id: {:x}, certificate not found", slot, slot_id);
|
||||
if show_all {
|
||||
if show_table {
|
||||
piv_slots.push(PivSlot {
|
||||
name: slot.to_string(),
|
||||
id: format!("{:x}", slot_id),
|
||||
algorithm: "N/A".to_string(),
|
||||
subject: "N/A".to_string(),
|
||||
});
|
||||
} else {
|
||||
warning!("Slot: {:?}, id: {:x}, certificate not found", slot, slot_id);
|
||||
}
|
||||
}
|
||||
return simple_error!("error reading certificate in slot {:?}: {}", slot, e);
|
||||
}
|
||||
};
|
||||
let buf_vec = cert.cert.to_der()?;
|
||||
let buf: &[u8] = buf_vec.as_ref();
|
||||
if buf.is_empty() {
|
||||
warning!("Slot: {:?}, id: {:x}, certificate buffer empty", slot, slot_id);
|
||||
let algorithm_id = get_algorithm_id(&cert.cert.tbs_certificate.subject_public_key_info)
|
||||
.map(|aid| format!("{:?}", aid))
|
||||
.unwrap_or_else(|e| format!("Error: {}", e));
|
||||
let cert_subject = match parse_x509_certificate(&buf_vec) {
|
||||
Ok((_rem, cert)) => cert.subject.to_string(),
|
||||
_ => cert.cert.tbs_certificate.subject.to_string(),
|
||||
};
|
||||
if show_table {
|
||||
piv_slots.push(PivSlot {
|
||||
name: slot.to_string(),
|
||||
id: format!("{:x}", slot_id),
|
||||
algorithm: algorithm_id,
|
||||
subject: cert_subject,
|
||||
});
|
||||
} else {
|
||||
let slot_id: u8 = slot.into();
|
||||
let algorithm_id = get_algorithm_id(&cert.cert.tbs_certificate.subject_public_key_info)
|
||||
.map(|aid| format!("{:?}", aid))
|
||||
.unwrap_or_else(|e| format!("Error: {}", e));
|
||||
let cert_subject = match parse_x509_certificate(buf) {
|
||||
Ok((_rem, cert)) => cert.subject.to_string(),
|
||||
_ => cert.cert.tbs_certificate.subject.to_string(),
|
||||
};
|
||||
success!("Slot: {:?}, id: {:x}, algorithm: {}, subject: {}", slot, slot_id, algorithm_id, cert_subject);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user