Merge pull request #79 from carl-wallace/develop
move print cert info into new CLI project
This commit is contained in:
@@ -16,5 +16,9 @@ keywords = ["ecdsa", "rsa", "piv", "pcsc", "yubikey"]
|
||||
gumdrop = "0.7"
|
||||
env_logger = "0.7"
|
||||
lazy_static = "1"
|
||||
log = "0.4"
|
||||
sha2 = "0.8"
|
||||
subtle-encoding = "0.5"
|
||||
termcolor = "1"
|
||||
x509-parser = "0.6"
|
||||
yubikey-piv = { version = "0.0.3", path = ".." }
|
||||
|
||||
@@ -4,7 +4,9 @@ use crate::terminal::STDOUT;
|
||||
use gumdrop::Options;
|
||||
use std::io::{self, Write};
|
||||
use termcolor::{ColorSpec, StandardStreamLock, WriteColor};
|
||||
use yubikey_piv::YubiKey;
|
||||
use yubikey_piv::{key::*, YubiKey};
|
||||
|
||||
use crate::print_cert_info;
|
||||
|
||||
// String to use for `None`
|
||||
const NONE_STR: &str = "<none>";
|
||||
@@ -37,6 +39,10 @@ impl StatusCmd {
|
||||
|
||||
self.attr(&mut s, "PIN retries", yk.get_pin_retries().unwrap())
|
||||
.unwrap();
|
||||
|
||||
for slot in SLOTS.iter().cloned() {
|
||||
print_cert_info(&mut yk, slot, &mut s).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
/// Print a status attribute
|
||||
|
||||
@@ -12,3 +12,81 @@
|
||||
pub mod terminal;
|
||||
|
||||
pub mod commands;
|
||||
|
||||
use log::debug;
|
||||
use sha2::{Digest, Sha256};
|
||||
use std::io::{self, Write};
|
||||
use std::str;
|
||||
use subtle_encoding::hex;
|
||||
use termcolor::{ColorSpec, StandardStreamLock, WriteColor};
|
||||
use x509_parser::parse_x509_der;
|
||||
use yubikey_piv::{certificate::Certificate, key::*, YubiKey};
|
||||
|
||||
///Write information about certificate found in slot a la yubico-piv-tool output.
|
||||
pub fn print_cert_info(
|
||||
yubikey: &mut YubiKey,
|
||||
slot: SlotId,
|
||||
stream: &mut StandardStreamLock<'_>,
|
||||
) -> Result<(), io::Error> {
|
||||
let cert = match Certificate::read(yubikey, slot) {
|
||||
Ok(c) => c,
|
||||
Err(e) => {
|
||||
debug!("error reading certificate in slot {:?}: {}", slot, e);
|
||||
return Ok(());
|
||||
}
|
||||
};
|
||||
let buf = cert.into_buffer();
|
||||
|
||||
if !buf.is_empty() {
|
||||
let fingerprint = Sha256::digest(&buf);
|
||||
let slot_id: u8 = slot.into();
|
||||
print_cert_attr(stream, "Slot", format!("{:x}", slot_id))?;
|
||||
match parse_x509_der(&buf) {
|
||||
Ok((_rem, cert)) => {
|
||||
print_cert_attr(
|
||||
stream,
|
||||
"Algorithm",
|
||||
cert.tbs_certificate.subject_pki.algorithm.algorithm,
|
||||
)?;
|
||||
|
||||
print_cert_attr(stream, "Subject", cert.tbs_certificate.subject)?;
|
||||
print_cert_attr(stream, "Issuer", cert.tbs_certificate.issuer)?;
|
||||
print_cert_attr(
|
||||
stream,
|
||||
"Fingerprint",
|
||||
str::from_utf8(hex::encode(fingerprint).as_slice()).unwrap(),
|
||||
)?;
|
||||
print_cert_attr(
|
||||
stream,
|
||||
"Not Before",
|
||||
cert.tbs_certificate.validity.not_before.asctime(),
|
||||
)?;
|
||||
print_cert_attr(
|
||||
stream,
|
||||
"Not After",
|
||||
cert.tbs_certificate.validity.not_after.asctime(),
|
||||
)?;
|
||||
}
|
||||
_ => {
|
||||
println!("Failed to parse certificate");
|
||||
return Ok(());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Print a status attribute
|
||||
fn print_cert_attr(
|
||||
stream: &mut StandardStreamLock<'_>,
|
||||
name: &str,
|
||||
value: impl ToString,
|
||||
) -> Result<(), io::Error> {
|
||||
stream.set_color(ColorSpec::new().set_bold(true))?;
|
||||
write!(stream, "{:>12}:", name)?;
|
||||
stream.reset()?;
|
||||
writeln!(stream, " {}", value.to_string())?;
|
||||
stream.flush()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user