From f3bfecd18539b638571eb4ba42918485eec810d8 Mon Sep 17 00:00:00 2001 From: Heiko Schaefer Date: Wed, 25 Aug 2021 21:25:20 +0200 Subject: [PATCH] Use the openpgp_card::card_do::Fingerprint type instead of [u8; 20]. Add a TryFrom<&[u8]> implementation to Fingerprint. --- openpgp-card-sequoia/src/lib.rs | 13 ++++--------- openpgp-card/src/card_app.rs | 11 ++++++----- openpgp-card/src/card_do/fingerprint.rs | 20 ++++++++++++++++++++ openpgp-card/src/crypto_data.rs | 4 +++- openpgp-card/src/keys.rs | 7 ++++--- 5 files changed, 37 insertions(+), 18 deletions(-) diff --git a/openpgp-card-sequoia/src/lib.rs b/openpgp-card-sequoia/src/lib.rs index 9e6f31e..5021965 100644 --- a/openpgp-card-sequoia/src/lib.rs +++ b/openpgp-card-sequoia/src/lib.rs @@ -364,11 +364,9 @@ impl CardUploadableKey for SequoiaKey { ts.into() } - fn get_fp(&self) -> [u8; 20] { + fn get_fp(&self) -> Result { let fp = self.key.fingerprint(); - assert_eq!(fp.as_bytes().len(), 20); - - fp.as_bytes().try_into().unwrap() + fp.as_bytes().try_into() } } @@ -539,16 +537,13 @@ pub fn public_to_fingerprint( pkm: &PublicKeyMaterial, ts: SystemTime, kt: KeyType, -) -> Result<[u8; 20]> { +) -> Result { // Transform PublicKeyMaterial into a Sequoia Key let key = public_key_material_to_key(pkm, kt, ts)?; // Get fingerprint from the Sequoia Key let fp = key.fingerprint(); - let fp = fp.as_bytes(); - - assert_eq!(fp.len(), 20); - Ok(fp.try_into()?) + fp.as_bytes().try_into() } // -------- diff --git a/openpgp-card/src/card_app.rs b/openpgp-card/src/card_app.rs index 2c433f3..f048a47 100644 --- a/openpgp-card/src/card_app.rs +++ b/openpgp-card/src/card_app.rs @@ -11,7 +11,8 @@ use anyhow::{anyhow, Result}; use crate::algorithm::{Algo, AlgoInfo, AlgoSimple, RsaAttrs}; use crate::apdu::{commands, response::Response}; use crate::card_do::{ - ApplicationRelatedData, Cardholder, PWStatus, SecuritySupportTemplate, Sex, + ApplicationRelatedData, Cardholder, Fingerprint, PWStatus, + SecuritySupportTemplate, Sex, }; use crate::crypto_data::{ CardUploadableKey, Cryptogram, EccType, Hash, PublicKeyMaterial, @@ -487,12 +488,12 @@ impl CardApp { pub fn set_fingerprint( &mut self, - fp: [u8; 20], + fp: Fingerprint, key_type: KeyType, ) -> Result { let fp_cmd = commands::put_data( &[key_type.get_fingerprint_put_tag()], - fp.to_vec(), + fp.as_bytes().to_vec(), ); apdu::send_command(self.card(), fp_cmd, false)?.try_into() @@ -620,7 +621,7 @@ impl CardApp { &PublicKeyMaterial, SystemTime, KeyType, - ) -> Result<[u8; 20]>, + ) -> Result, key_type: KeyType, algo: Option<&Algo>, ) -> Result<(PublicKeyMaterial, u32), OpenpgpCardError> { @@ -635,7 +636,7 @@ impl CardApp { &PublicKeyMaterial, SystemTime, KeyType, - ) -> Result<[u8; 20]>, + ) -> Result, key_type: KeyType, algo: AlgoSimple, ) -> Result<(PublicKeyMaterial, u32), OpenpgpCardError> { diff --git a/openpgp-card/src/card_do/fingerprint.rs b/openpgp-card/src/card_do/fingerprint.rs index 7ce5f02..1e4fdf5 100644 --- a/openpgp-card/src/card_do/fingerprint.rs +++ b/openpgp-card/src/card_do/fingerprint.rs @@ -3,6 +3,8 @@ use anyhow::anyhow; use nom::{bytes::complete as bytes, combinator, sequence}; +use std::convert::TryFrom; +use std::convert::TryInto; use std::fmt; use crate::card_do::{Fingerprint, KeySet}; @@ -14,6 +16,24 @@ impl From<[u8; 20]> for Fingerprint { } } +impl TryFrom<&[u8]> for Fingerprint { + type Error = OpenpgpCardError; + + fn try_from(input: &[u8]) -> Result { + log::trace!( + "Fingerprint from input: {:x?}, len {}", + input, + input.len() + ); + + // FIXME: return error + assert_eq!(input.len(), 20); + + let array: [u8; 20] = input.try_into().unwrap(); + Ok(array.into()) + } +} + impl Fingerprint { pub fn as_bytes(&self) -> &[u8] { &self.0 diff --git a/openpgp-card/src/crypto_data.rs b/openpgp-card/src/crypto_data.rs index 05645cd..c26f286 100644 --- a/openpgp-card/src/crypto_data.rs +++ b/openpgp-card/src/crypto_data.rs @@ -8,6 +8,8 @@ use anyhow::Result; use crate::algorithm::Algo; +use crate::card_do::Fingerprint; +use crate::errors::OpenpgpCardError; /// A hash value that can be signed by the card. pub enum Hash<'a> { @@ -67,7 +69,7 @@ pub trait CardUploadableKey { fn get_ts(&self) -> u32; /// fingerprint - fn get_fp(&self) -> [u8; 20]; + fn get_fp(&self) -> Result; } /// Algorithm-independent container for private key material to upload to diff --git a/openpgp-card/src/keys.rs b/openpgp-card/src/keys.rs index d043f88..817b997 100644 --- a/openpgp-card/src/keys.rs +++ b/openpgp-card/src/keys.rs @@ -11,6 +11,7 @@ use crate::algorithm::{Algo, AlgoInfo, Curve, EccAttrs, RsaAttrs}; use crate::apdu::command::Command; use crate::apdu::commands; use crate::card_app::CardApp; +use crate::card_do::Fingerprint; use crate::crypto_data::{ CardUploadableKey, EccKey, EccPub, PrivateKeyMaterial, PublicKeyMaterial, RSAKey, RSAPub, @@ -27,7 +28,7 @@ pub(crate) fn gen_key_with_metadata( &PublicKeyMaterial, SystemTime, KeyType, - ) -> Result<[u8; 20]>, + ) -> Result, key_type: KeyType, algo: Option<&Algo>, ) -> Result<(PublicKeyMaterial, u32), OpenpgpCardError> { @@ -210,7 +211,7 @@ pub(crate) fn upload_key( card_app, key_type, key.get_ts(), - key.get_fp(), + key.get_fp()?, &algo, key_cmd, )?; @@ -427,7 +428,7 @@ fn copy_key_to_card( card_app: &mut CardApp, key_type: KeyType, ts: u32, - fp: [u8; 20], + fp: Fingerprint, algo: &Algo, key_cmd: Command, ) -> Result<(), OpenpgpCardError> {