diff --git a/openpgp-card-sequoia/src/lib.rs b/openpgp-card-sequoia/src/lib.rs index 48b8460..3c27656 100644 --- a/openpgp-card-sequoia/src/lib.rs +++ b/openpgp-card-sequoia/src/lib.rs @@ -226,7 +226,7 @@ impl Card { let aid = { let tx = card.transaction()?; - tx.state.ard.application_id()? + tx.state.ard().application_id()? }; if aid.ident() == ident.to_ascii_uppercase() { @@ -269,13 +269,7 @@ impl<'a> Card> { let ard = opt.application_related_data()?; Ok(Self { - state: Transaction { - opt, - ard, - pw1: false, - pw1_sign: false, - pw3: false, - }, + state: Transaction::new(opt, ard), }) } @@ -286,7 +280,11 @@ impl<'a> Card> { /// see these changes reflected in `self.ard`. pub fn reload_ard(&mut self) -> Result<(), Error> { // FIXME: this should be implemented internally, transparent to users - self.state.ard = self.state.opt.application_related_data()?; + + let ard = self.state.opt.application_related_data()?; + + self.state.set_ard(ard); + Ok(()) } @@ -478,16 +476,16 @@ impl<'a> Card> { /// PW status Bytes pub fn pw_status_bytes(&self) -> Result { - self.state.ard.pw_status_bytes() + 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) + self.state.ard().algorithm_attributes(key_type) } pub fn fingerprints(&self) -> Result, Error> { - self.state.ard.fingerprints() + self.state.ard().fingerprints() } pub fn fingerprint(&mut self, key_type: KeyType) -> Result, Error> { @@ -495,7 +493,7 @@ impl<'a> Card> { 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()?, + KeyType::Attestation => self.state.ard().attestation_key_fingerprint()?, _ => { return Err(Error::UnsupportedFeature(format!( "Can't get fingerprint for key_type {:?}", @@ -508,11 +506,11 @@ impl<'a> Card> { } pub fn ca_fingerprints(&self) -> Result<[Option; 3], Error> { - self.state.ard.ca_fingerprints() + self.state.ard().ca_fingerprints() } pub fn key_generation_times(&self) -> Result, Error> { - self.state.ard.key_generation_times() + self.state.ard().key_generation_times() } pub fn key_generation_time( @@ -523,7 +521,7 @@ impl<'a> Card> { 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()?, + KeyType::Attestation => self.state.ard().attestation_key_generation_time()?, _ => { return Err(Error::UnsupportedFeature(format!( "Can't get creation time for key_type {:?}", @@ -536,7 +534,7 @@ impl<'a> Card> { } pub fn key_information(&self) -> Result, Error> { - self.state.ard.key_information() + self.state.ard().key_information() } pub fn user_interaction_flag( @@ -544,10 +542,10 @@ impl<'a> Card> { key_type: KeyType, ) -> Result, Error> { match key_type { - KeyType::Signing => self.state.ard.uif_pso_cds(), - KeyType::Decryption => self.state.ard.uif_pso_dec(), - KeyType::Authentication => self.state.ard.uif_pso_aut(), - KeyType::Attestation => self.state.ard.uif_attestation(), + KeyType::Signing => self.state.ard().uif_pso_cds(), + KeyType::Decryption => self.state.ard().uif_pso_dec(), + KeyType::Authentication => self.state.ard().uif_pso_aut(), + KeyType::Attestation => self.state.ard().uif_attestation(), _ => Err(Error::UnsupportedFeature(format!( "Can't get UIF for key_type {:?}", key_type, @@ -846,7 +844,7 @@ impl<'app, 'open> Card> { // Touch is required if: // - the card supports the feature // - and the policy is set to a value other than 'Off' - if let Some(uif) = self.state.tx.state.ard.uif_attestation()? { + if let Some(uif) = self.state.tx.state.ard().uif_attestation()? { if uif.touch_policy().touch_required() { (touch_prompt)(); } @@ -938,10 +936,10 @@ impl Card> { policy: TouchPolicy, ) -> Result<(), Error> { let uif = match key { - KeyType::Signing => self.state.tx.state.ard.uif_pso_cds()?, - KeyType::Decryption => self.state.tx.state.ard.uif_pso_dec()?, - KeyType::Authentication => self.state.tx.state.ard.uif_pso_aut()?, - KeyType::Attestation => self.state.tx.state.ard.uif_attestation()?, + KeyType::Signing => self.state.tx.state.ard().uif_pso_cds()?, + KeyType::Decryption => self.state.tx.state.ard().uif_pso_dec()?, + KeyType::Authentication => self.state.tx.state.ard().uif_pso_aut()?, + KeyType::Attestation => self.state.tx.state.ard().uif_attestation()?, _ => unimplemented!(), }; diff --git a/openpgp-card-sequoia/src/state.rs b/openpgp-card-sequoia/src/state.rs index c33e023..046aa86 100644 --- a/openpgp-card-sequoia/src/state.rs +++ b/openpgp-card-sequoia/src/state.rs @@ -42,7 +42,7 @@ pub struct Transaction<'a> { // // This field should probably be an Option<> that gets invalidated when appropriate and // re-fetched lazily. - pub(crate) ard: ApplicationRelatedData, + ard: ApplicationRelatedData, // verify status of pw1 pub(crate) pw1: bool, @@ -54,6 +54,26 @@ pub struct Transaction<'a> { pub(crate) pw3: bool, } +impl<'a> Transaction<'a> { + pub(crate) fn new(opt: openpgp_card::Transaction<'a>, ard: ApplicationRelatedData) -> Self { + Transaction { + opt, + ard, + pw1: false, + pw1_sign: false, + pw3: false, + } + } + + pub(crate) fn ard(&self) -> &ApplicationRelatedData { + &self.ard + } + + pub(crate) fn set_ard(&mut self, ard: ApplicationRelatedData) { + self.ard = ard + } +} + /// State of an OpenPGP card after successfully verifying the User PIN /// (this verification allow user operations other than signing). ///