From d55980cef68fa6900d7fea6e17e3c603bfca9f80 Mon Sep 17 00:00:00 2001 From: Heiko Schaefer Date: Sun, 3 Sep 2023 22:13:22 +0200 Subject: [PATCH] openpgp-card-sequoia: add fingerprint, key_generation_time getters with key_type parameter --- openpgp-card-sequoia/src/lib.rs | 93 +++++++++++++++++++++------------ 1 file changed, 61 insertions(+), 32 deletions(-) diff --git a/openpgp-card-sequoia/src/lib.rs b/openpgp-card-sequoia/src/lib.rs index 8b325e6..360c661 100644 --- a/openpgp-card-sequoia/src/lib.rs +++ b/openpgp-card-sequoia/src/lib.rs @@ -476,20 +476,37 @@ impl<'a> Card> { unimplemented!() } - /// Get algorithm attributes for a key slot. - pub fn algorithm_attributes(&self, key_type: KeyType) -> Result { - self.state.ard.algorithm_attributes(key_type) - } - /// PW status Bytes pub fn pw_status_bytes(&self) -> Result { self.state.ard.pw_status_bytes() } + /// Get algorithm attributes for a key slot. + pub fn algorithm_attributes(&self, key_type: KeyType) -> Result { + self.state.ard.algorithm_attributes(key_type) + } + pub fn fingerprints(&self) -> Result, Error> { self.state.ard.fingerprints() } + pub fn fingerprint(&mut self, key_type: KeyType) -> Result, Error> { + let fp = match key_type { + KeyType::Signing => self.fingerprints()?.signature().cloned(), + KeyType::Decryption => self.fingerprints()?.decryption().cloned(), + KeyType::Authentication => self.fingerprints()?.authentication().cloned(), + KeyType::Attestation => self.state.ard.attestation_key_fingerprint()?, + _ => { + return Err(Error::UnsupportedFeature(format!( + "Can't get fingerprint for key_type {:?}", + key_type, + ))) + } + }; + + Ok(fp) + } + pub fn ca_fingerprints(&self) -> Result<[Option; 3], Error> { self.state.ard.ca_fingerprints() } @@ -498,6 +515,26 @@ impl<'a> Card> { self.state.ard.key_generation_times() } + pub fn key_generation_time( + &mut self, + key_type: KeyType, + ) -> Result, Error> { + let ts = match key_type { + KeyType::Signing => self.key_generation_times()?.signature().cloned(), + KeyType::Decryption => self.key_generation_times()?.decryption().cloned(), + KeyType::Authentication => self.key_generation_times()?.authentication().cloned(), + KeyType::Attestation => self.state.ard.attestation_key_generation_time()?, + _ => { + return Err(Error::UnsupportedFeature(format!( + "Can't get creation time for key_type {:?}", + key_type, + ))) + } + }; + + Ok(ts) + } + pub fn key_information(&self) -> Result, Error> { self.state.ard.key_information() } @@ -623,20 +660,6 @@ impl<'a> Card> { self.state.opt.attestation_certificate() } - pub fn attestation_key_fingerprint(&mut self) -> Result, Error> { - self.state.ard.attestation_key_fingerprint() - } - - pub fn attestation_key_algorithm_attributes( - &mut self, - ) -> Result, Error> { - self.state.ard.attestation_key_algorithm_attributes() - } - - pub fn attestation_key_generation_time(&mut self) -> Result, Error> { - self.state.ard.attestation_key_generation_time() - } - /// Firmware Version, YubiKey specific (?) pub fn firmware_version(&mut self) -> Result, Error> { self.state.opt.firmware_version() @@ -673,19 +696,26 @@ impl<'a> Card> { /// Get PublicKey representation for a key slot on the card pub fn public_key(&mut self, kt: KeyType) -> Result, Error> { - // FIXME: only read these once, if multiple subkeys are retrieved from the card - let times = self.key_generation_times()?; let fps = self.fingerprints()?; + let ts = self.key_generation_time(kt)?; + + let fp = match kt { + KeyType::Signing => fps.signature(), + KeyType::Decryption => fps.decryption(), + KeyType::Authentication => fps.authentication(), + _ => None, + }; + match kt { KeyType::Signing => { - if let Ok(pkm) = self.public_key_material(KeyType::Signing) { - if let Some(ts) = times.signature() { + if let Ok(pkm) = self.public_key_material(kt) { + if let Some(ts) = ts { return Ok(Some(public_key_material_and_fp_to_key( &pkm, KeyType::Signing, - ts, - fps.signature().expect("Signature fingerprint is unset"), + &ts, + fp.expect("Signature fingerprint is unset"), )?)); } } @@ -693,12 +723,12 @@ impl<'a> Card> { } KeyType::Decryption => { if let Ok(pkm) = self.public_key_material(KeyType::Decryption) { - if let Some(ts) = times.decryption() { + if let Some(ts) = ts { return Ok(Some(public_key_material_and_fp_to_key( &pkm, KeyType::Decryption, - ts, - fps.decryption().expect("Decryption fingerprint is unset"), + &ts, + fp.expect("Decryption fingerprint is unset"), )?)); } } @@ -706,13 +736,12 @@ impl<'a> Card> { } KeyType::Authentication => { if let Ok(pkm) = self.public_key_material(KeyType::Authentication) { - if let Some(ts) = times.authentication() { + if let Some(ts) = ts { return Ok(Some(public_key_material_and_fp_to_key( &pkm, KeyType::Authentication, - ts, - fps.authentication() - .expect("Authentication fingerprint is unset"), + &ts, + fp.expect("Authentication fingerprint is unset"), )?)); } }