From 901cc6726dd023a902fb4c2528768bfd32a5b7ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sosth=C3=A8ne=20Gu=C3=A9don?= Date: Mon, 16 Jan 2023 17:32:20 +0100 Subject: [PATCH] Fix key history object --- src/constants.rs | 24 ++++++++++++++++++++++++ src/container.rs | 9 +++++---- src/lib.rs | 36 +++++++++++++++++++++++++++++++++--- src/state.rs | 22 ++++++++++++++++++++++ 4 files changed, 84 insertions(+), 7 deletions(-) diff --git a/src/constants.rs b/src/constants.rs index 7e329fb..93f77a4 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -282,3 +282,27 @@ pub const DISCOVERY_OBJECT: [u8; 18] = hex!( 5f2f 02 // PIN usage Policy 4000" ); + +use crate::Container; +pub const RETIRED_CERTS: [Container; 20] = [ + Container::RetiredCert01, + Container::RetiredCert02, + Container::RetiredCert03, + Container::RetiredCert04, + Container::RetiredCert05, + Container::RetiredCert06, + Container::RetiredCert07, + Container::RetiredCert08, + Container::RetiredCert09, + Container::RetiredCert10, + Container::RetiredCert11, + Container::RetiredCert12, + Container::RetiredCert13, + Container::RetiredCert14, + Container::RetiredCert15, + Container::RetiredCert16, + Container::RetiredCert17, + Container::RetiredCert18, + Container::RetiredCert19, + Container::RetiredCert20, +]; diff --git a/src/container.rs b/src/container.rs index 65997cd..0a477a3 100644 --- a/src/container.rs +++ b/src/container.rs @@ -377,11 +377,10 @@ impl TryFrom<&[u8]> for Container { hex!("5FC106") => SecurityObject, hex!("5FC108") => CardholderFacialImage, hex!("5FC101") => X509CertificateFor9E, + hex!("5FC109") => PrintedInformation, hex!("5FC10A") => X509CertificateFor9C, hex!("5FC10B") => X509CertificateFor9D, - hex!("5FC109") => PrintedInformation, - hex!("7E") => DiscoveryObject, - + hex!("5FC10C") => KeyHistoryObject, hex!("5FC10D") => RetiredCert01, hex!("5FC10E") => RetiredCert02, hex!("5FC10F") => RetiredCert03, @@ -404,9 +403,11 @@ impl TryFrom<&[u8]> for Container { hex!("5FC120") => RetiredCert20, hex!("5FC121") => CardholderIrisImages, - hex!("7F61") => BiometricInformationTemplatesGroupTemplate, hex!("5FC122") => SecureMessagingCertificateSigner, hex!("5FC123") => PairingCodeReferenceDataContainer, + + hex!("7E") => DiscoveryObject, + hex!("7F61") => BiometricInformationTemplatesGroupTemplate, _ => return Err(()), }) } diff --git a/src/lib.rs b/src/lib.rs index e180e1e..640f07e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1089,9 +1089,12 @@ impl<'a, T: trussed::Client + trussed::client::Ed255> LoadedAuthenticator<'a, T> }; reply.expand(tag)?; let offset = reply.len(); - match ContainerStorage(container).load(self.trussed)? { - Some(data) => reply.expand(&data)?, - None => return Err(Status::NotFound), + match container { + Container::KeyHistoryObject => self.get_key_history_object(reply.lend())?, + _ => match ContainerStorage(container).load(self.trussed)? { + Some(data) => reply.expand(&data)?, + None => return Err(Status::NotFound), + }, } reply.prepend_len(offset)?; @@ -1133,4 +1136,31 @@ impl<'a, T: trussed::Client + trussed::client::Ed255> LoadedAuthenticator<'a, T> Ok(()) } + + fn get_key_history_object(&mut self, mut reply: Reply<'_, R>) -> Result { + let num_keys = self + .state + .persistent + .keys + .retired_keys + .iter() + .filter(|k| k.is_some()) + .count() as u8; + let mut num_certs = 0u8; + + use state::ContainerStorage; + + for c in RETIRED_CERTS { + if ContainerStorage(c).exists(self.trussed)? { + num_certs += 1; + } + } + + reply.expand(&[0xC1, 0x01])?; + reply.expand(&[num_certs])?; + reply.expand(&[0xC2, 0x01])?; + reply.expand(&[num_keys.saturating_sub(num_certs)])?; + reply.expand(&[0xFE, 0x00])?; + Ok(()) + } } diff --git a/src/state.rs b/src/state.rs index 7da22a4..6b5870c 100644 --- a/src/state.rs +++ b/src/state.rs @@ -665,6 +665,28 @@ impl ContainerStorage { } } + pub fn exists(self, client: &mut impl trussed::Client) -> Result { + match try_syscall!(client.entry_metadata(Location::Internal, self.path())) { + Ok(Metadata { metadata: None }) => Ok(false), + Ok(Metadata { + metadata: Some(metadata), + }) if metadata.is_file() => Ok(true), + Ok(Metadata { + metadata: Some(_metadata), + }) => { + error!( + "File {} exists but isn't a file: {_metadata:?}", + self.path() + ); + Err(Status::UnspecifiedPersistentExecutionError) + } + Err(_err) => { + error!("File {} couldn't be read: {_err:?}", self.path()); + Err(Status::UnspecifiedPersistentExecutionError) + } + } + } + pub fn load( self, client: &mut impl trussed::Client,