diff --git a/Cargo.toml b/Cargo.toml index b4ded39..8856c90 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,6 +34,7 @@ sha-1 = "0.8" subtle = "2" x509-parser = "0.6" zeroize = "1" +sha2 = "0.8" [dev-dependencies] env_logger = "0.7" @@ -43,3 +44,4 @@ untested = [] [package.metadata.docs.rs] all-features = true + diff --git a/src/certificate.rs b/src/certificate.rs index e11b303..ce2c866 100644 --- a/src/certificate.rs +++ b/src/certificate.rs @@ -48,6 +48,7 @@ use rsa::{PublicKey, RSAPublicKey}; use std::fmt; use x509_parser::{parse_x509_der, x509::SubjectPublicKeyInfo}; use zeroize::Zeroizing; +use sha2::{Sha256, Digest}; // TODO: Make these der_parser::oid::Oid constants when it has const fn support. const OID_RSA_ENCRYPTION: &str = "1.2.840.113549.1.1.1"; @@ -400,3 +401,40 @@ mod read_pki { } } } + +///Write information about certificate found in slot a la yubico-piv-tool output. +pub fn print_cert_info(yubikey: &mut YubiKey, slot: SlotId) -> Result<(), Error> { + let txn = yubikey.begin_transaction()?; + let buf = match read_certificate(&txn, slot) { + Ok(b) => b, + Err(e) => { + println!("error reading certificate in slot {:?}: {}", slot, e); + return Err(e); + } + }; + + if !buf.is_empty() { + let mut hasher = Sha256::new(); + hasher.input(buf.clone().to_vec()); + let fingerprint = hasher.result(); + + let slot_id: u8 = slot.into(); + println!("Slot {:x}: ", slot_id); + match parse_x509_der(&buf) { + Ok((_rem, cert)) => { + println!("\tAlgorithm: {}", cert.tbs_certificate.subject_pki.algorithm.algorithm); + println!("\tSubject: {}", cert.tbs_certificate.subject); + println!("\tIssuer: {}", cert.tbs_certificate.issuer); + println!("\tFingerprint: {:X}", fingerprint); + println!("\tNot Before: {}", cert.tbs_certificate.validity.not_before.asctime()); + println!("\tNot After: {}", cert.tbs_certificate.validity.not_after.asctime()); + } + _ => { + println!("Failed to parse certificate"); + return Err(Error::GenericError); + } + }; + } + + Ok(()) +} \ No newline at end of file