Merge pull request #79 from carl-wallace/develop

move print cert info into new CLI project
This commit is contained in:
Tony Arcieri
2019-12-15 08:25:37 -08:00
committed by GitHub
3 changed files with 89 additions and 1 deletions
+4
View File
@@ -16,5 +16,9 @@ keywords = ["ecdsa", "rsa", "piv", "pcsc", "yubikey"]
gumdrop = "0.7" gumdrop = "0.7"
env_logger = "0.7" env_logger = "0.7"
lazy_static = "1" lazy_static = "1"
log = "0.4"
sha2 = "0.8"
subtle-encoding = "0.5"
termcolor = "1" termcolor = "1"
x509-parser = "0.6"
yubikey-piv = { version = "0.0.3", path = ".." } yubikey-piv = { version = "0.0.3", path = ".." }
+7 -1
View File
@@ -4,7 +4,9 @@ use crate::terminal::STDOUT;
use gumdrop::Options; use gumdrop::Options;
use std::io::{self, Write}; use std::io::{self, Write};
use termcolor::{ColorSpec, StandardStreamLock, WriteColor}; use termcolor::{ColorSpec, StandardStreamLock, WriteColor};
use yubikey_piv::YubiKey; use yubikey_piv::{key::*, YubiKey};
use crate::print_cert_info;
// String to use for `None` // String to use for `None`
const NONE_STR: &str = "<none>"; const NONE_STR: &str = "<none>";
@@ -37,6 +39,10 @@ impl StatusCmd {
self.attr(&mut s, "PIN retries", yk.get_pin_retries().unwrap()) self.attr(&mut s, "PIN retries", yk.get_pin_retries().unwrap())
.unwrap(); .unwrap();
for slot in SLOTS.iter().cloned() {
print_cert_info(&mut yk, slot, &mut s).unwrap();
}
} }
/// Print a status attribute /// Print a status attribute
+78
View File
@@ -12,3 +12,81 @@
pub mod terminal; pub mod terminal;
pub mod commands; 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(())
}