From d8eb198e97847d74d510ef61f549aca177934ba8 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Sat, 31 Dec 2022 18:47:39 +0000 Subject: [PATCH] Move certificate parsing into `Metadata::extract` --- src/builder.rs | 1 - src/key.rs | 3 +-- src/main.rs | 14 ++++---------- src/util.rs | 10 ++++++---- 4 files changed, 11 insertions(+), 17 deletions(-) diff --git a/src/builder.rs b/src/builder.rs index f01f131..72c91d7 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -134,7 +134,6 @@ impl IdentityBuilder { )], )?; - let (_, cert) = x509_parser::parse_x509_certificate(cert.as_ref()).unwrap(); let metadata = Metadata::extract(yubikey, slot, &cert, false).unwrap(); Ok(( diff --git a/src/key.rs b/src/key.rs index 8654b3e..a53d4e4 100644 --- a/src/key.rs +++ b/src/key.rs @@ -542,9 +542,8 @@ impl Connection { ) -> io::Result> { // Check if we can skip requesting a PIN. if self.cached_metadata.is_none() { - let (_, cert) = x509_parser::parse_x509_certificate(self.cert.as_ref()).unwrap(); self.cached_metadata = - match Metadata::extract(&mut self.yubikey, self.slot, &cert, true) { + match Metadata::extract(&mut self.yubikey, self.slot, &self.cert, true) { None => { return Ok(Err(identity::Error::Identity { index: self.identity_index, diff --git a/src/main.rs b/src/main.rs index 491fa9d..6817f12 100644 --- a/src/main.rs +++ b/src/main.rs @@ -211,10 +211,7 @@ fn print_single( .ok_or(Error::SlotHasNoIdentity(slot))?; let stub = key::Stub::new(yubikey.serial(), slot, &recipient); - let metadata = x509_parser::parse_x509_certificate(key.certificate().as_ref()) - .ok() - .and_then(|(_, cert)| util::Metadata::extract(&mut yubikey, slot, &cert, true)) - .unwrap(); + let metadata = util::Metadata::extract(&mut yubikey, slot, key.certificate(), true).unwrap(); printer(stub, recipient, metadata); @@ -252,9 +249,7 @@ fn print_multiple( }; let stub = key::Stub::new(yubikey.serial(), slot, &recipient); - let metadata = match x509_parser::parse_x509_certificate(key.certificate().as_ref()) - .ok() - .and_then(|(_, cert)| util::Metadata::extract(&mut yubikey, slot, &cert, all)) + let metadata = match util::Metadata::extract(&mut yubikey, slot, key.certificate(), all) { Some(res) => res, None => continue, @@ -479,10 +474,9 @@ fn main() -> Result<(), Error> { .interact()? { let stub = key::Stub::new(yubikey.serial(), slot, &recipient); - let (_, cert) = - x509_parser::parse_x509_certificate(key.certificate().as_ref()).unwrap(); let metadata = - util::Metadata::extract(&mut yubikey, slot, &cert, true).unwrap(); + util::Metadata::extract(&mut yubikey, slot, key.certificate(), true) + .unwrap(); ((stub, recipient, metadata), false) } else { diff --git a/src/util.rs b/src/util.rs index ce6460d..f907c5e 100644 --- a/src/util.rs +++ b/src/util.rs @@ -4,7 +4,7 @@ use std::iter; use x509_parser::{certificate::X509Certificate, der_parser::oid::Oid}; use yubikey::{ piv::{RetiredSlotId, SlotId}, - PinPolicy, Serial, TouchPolicy, YubiKey, + Certificate, PinPolicy, Serial, TouchPolicy, YubiKey, }; use crate::fl; @@ -112,9 +112,11 @@ impl Metadata { pub(crate) fn extract( yubikey: &mut YubiKey, slot: RetiredSlotId, - cert: &X509Certificate, + cert: &Certificate, all: bool, ) -> Option { + let (_, cert) = x509_parser::parse_x509_certificate(cert.as_ref()).ok()?; + // We store the PIN and touch policies for identities in their certificates // using the same certificate extension as PIV attestations. // https://developers.yubico.com/PIV/Introduction/PIV_attestation.html @@ -143,10 +145,10 @@ impl Metadata { .unwrap_or((None, None)) }; - extract_name(cert, all) + extract_name(&cert, all) .map(|(name, ours)| { if ours { - let (pin_policy, touch_policy) = policies(cert); + let (pin_policy, touch_policy) = policies(&cert); (name, pin_policy, touch_policy) } else { // We can extract the PIN and touch policies via an attestation. This