From c8e5c9639832b568a9d1ca3eb8cfd2261d1d7e44 Mon Sep 17 00:00:00 2001 From: Carl Wallace Date: Sat, 30 Nov 2019 15:11:10 -0500 Subject: [PATCH 1/6] change cccid handling to target entire ccc object (a la yubico-piv-tool status action) --- src/cccid.rs | 29 ++++++++++++++++++++--------- src/consts.rs | 1 + 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/cccid.rs b/src/cccid.rs index d72c197..7db8aba 100644 --- a/src/cccid.rs +++ b/src/cccid.rs @@ -48,16 +48,27 @@ const CCC_TMPL: &[u8] = &[ 0x00, 0xfe, 0x00, ]; -/// Cardholder Capability Container (CCC) Identifier +/// Cardholder Capability Container (CCC) Identifier card ID #[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub struct CCCID(pub [u8; YKPIV_CCCID_SIZE]); +pub struct CccCardId(pub [u8; YKPIV_CCCID_SIZE]); + +/// Cardholder Capability Container (CCC) Identifier +#[derive(Copy, Clone)] +pub struct CCC(pub [u8; YKPIV_CCC_SIZE]); + +impl CCC { + /// Return CardId component of CHUID + pub fn cccid(&self) -> Result { + let mut cccid = [0u8; YKPIV_CCCID_SIZE]; + cccid.copy_from_slice(&self.0[CCC_ID_OFFS..(CCC_ID_OFFS + YKPIV_CCCID_SIZE)]); + Ok(CccCardId(cccid)) + } -impl CCCID { /// Generate a random CCCID - pub fn generate() -> Result { + pub fn generate() -> Result { let mut id = [0u8; YKPIV_CCCID_SIZE]; getrandom(&mut id).map_err(|_| Error::RandomnessError)?; - Ok(CCCID(id)) + Ok(CccCardId(id)) } /// Get Cardholder Capability Container (CCC) ID @@ -69,15 +80,15 @@ impl CCCID { return Err(Error::GenericError); } - let mut cccid = [0u8; YKPIV_CCCID_SIZE]; - cccid.copy_from_slice(&response[CCC_ID_OFFS..(CCC_ID_OFFS + YKPIV_CCCID_SIZE)]); - Ok(CCCID(cccid)) + let mut ccc = [0u8; YKPIV_CCC_SIZE]; + ccc.copy_from_slice(&response[0..YKPIV_CCC_SIZE]); + Ok(CCC { 0: ccc }) } /// Get Cardholder Capability Container (CCC) ID pub fn set(&self, yubikey: &mut YubiKey) -> Result<(), Error> { let mut buf = CCC_TMPL.to_vec(); - buf[CCC_ID_OFFS..(CCC_ID_OFFS + self.0.len())].copy_from_slice(&self.0); + buf[0..self.0.len()].copy_from_slice(&self.0); let txn = yubikey.begin_transaction()?; txn.save_object(YKPIV_OBJ_CAPABILITY, &buf) diff --git a/src/consts.rs b/src/consts.rs index 75ef5dd..8c79d8b 100644 --- a/src/consts.rs +++ b/src/consts.rs @@ -137,6 +137,7 @@ pub const YKPIV_FASCN_SIZE: usize = 25; pub const YKPIV_EXPIRATION_SIZE: usize = 8; pub const YKPIV_CCCID_SIZE: usize = 14; +pub const YKPIV_CCC_SIZE: usize = 51; pub const YKPIV_CERTINFO_UNCOMPRESSED: u8 = 0; pub const YKPIV_CERTINFO_GZIP: u8 = 1; From 2087e53109a5ddc757186d412ab97189e674ce6e Mon Sep 17 00:00:00 2001 From: Carl Wallace Date: Sun, 1 Dec 2019 14:59:21 -0500 Subject: [PATCH 2/6] add print cert info method in support of status action a la yubico-piv-tool --- Cargo.toml | 2 ++ src/certificate.rs | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) 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 From b9d6057d4e37c68e506d03a019a9e877a0635b0c Mon Sep 17 00:00:00 2001 From: Carl Wallace Date: Sun, 1 Dec 2019 15:12:05 -0500 Subject: [PATCH 3/6] address fmt issues --- src/certificate.rs | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/certificate.rs b/src/certificate.rs index ce2c866..d1a7e96 100644 --- a/src/certificate.rs +++ b/src/certificate.rs @@ -45,10 +45,10 @@ use ecdsa::{ }; use log::error; use rsa::{PublicKey, RSAPublicKey}; +use sha2::{Digest, Sha256}; 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"; @@ -422,12 +422,21 @@ pub fn print_cert_info(yubikey: &mut YubiKey, slot: SlotId) -> Result<(), Error> println!("Slot {:x}: ", slot_id); match parse_x509_der(&buf) { Ok((_rem, cert)) => { - println!("\tAlgorithm: {}", cert.tbs_certificate.subject_pki.algorithm.algorithm); + 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!( + "\tNot Before: {}", + cert.tbs_certificate.validity.not_before.asctime() + ); + println!( + "\tNot After: {}", + cert.tbs_certificate.validity.not_after.asctime() + ); } _ => { println!("Failed to parse certificate"); @@ -437,4 +446,4 @@ pub fn print_cert_info(yubikey: &mut YubiKey, slot: SlotId) -> Result<(), Error> } Ok(()) -} \ No newline at end of file +} From a1102899108ea8238c65b0bdfdfefeb67e47bff2 Mon Sep 17 00:00:00 2001 From: Carl Wallace Date: Sun, 1 Dec 2019 18:20:18 -0500 Subject: [PATCH 4/6] move print cert info to CLI --- src/certificate.rs | 45 --------------------------------------------- 1 file changed, 45 deletions(-) diff --git a/src/certificate.rs b/src/certificate.rs index d1a7e96..4541502 100644 --- a/src/certificate.rs +++ b/src/certificate.rs @@ -45,7 +45,6 @@ use ecdsa::{ }; use log::error; use rsa::{PublicKey, RSAPublicKey}; -use sha2::{Digest, Sha256}; use std::fmt; use x509_parser::{parse_x509_der, x509::SubjectPublicKeyInfo}; use zeroize::Zeroizing; @@ -402,48 +401,4 @@ 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(()) -} From bfd728d1ac09403afec53892b4731ecc5cde1baf Mon Sep 17 00:00:00 2001 From: Carl Wallace Date: Sun, 1 Dec 2019 18:22:18 -0500 Subject: [PATCH 5/6] remove sha2, which was rendered OBE as print cert info was moved to CLI --- Cargo.toml | 2 -- 1 file changed, 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 8856c90..b4ded39 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,7 +34,6 @@ sha-1 = "0.8" subtle = "2" x509-parser = "0.6" zeroize = "1" -sha2 = "0.8" [dev-dependencies] env_logger = "0.7" @@ -44,4 +43,3 @@ untested = [] [package.metadata.docs.rs] all-features = true - From a9e0363d09aa3810845a390fbc9d0266216e4486 Mon Sep 17 00:00:00 2001 From: Carl Wallace Date: Sun, 1 Dec 2019 18:23:32 -0500 Subject: [PATCH 6/6] remove spurious blank lines flagged by fmt --- src/certificate.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/certificate.rs b/src/certificate.rs index 4541502..e11b303 100644 --- a/src/certificate.rs +++ b/src/certificate.rs @@ -400,5 +400,3 @@ mod read_pki { } } } - -