93 lines
2.6 KiB
Rust
93 lines
2.6 KiB
Rust
//! `yubikey` command-line utility
|
|
|
|
#![forbid(unsafe_code)]
|
|
#![warn(
|
|
missing_docs,
|
|
rust_2018_idioms,
|
|
unused_lifetimes,
|
|
unused_qualifications
|
|
)]
|
|
|
|
#[macro_use]
|
|
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(())
|
|
}
|