From 90ae9398ed357dbda98e9f16b426c7d774eef591 Mon Sep 17 00:00:00 2001 From: Heiko Schaefer Date: Fri, 12 Nov 2021 18:47:56 +0100 Subject: [PATCH] Adjust the backend API and interaction with openpgp-card some more. --- card-functionality/src/cards.rs | 11 ++--------- openpgp-card-sequoia/src/card.rs | 2 -- openpgp-card/src/card_app.rs | 13 +++++++------ pcsc/src/lib.rs | 21 +++++++++++---------- scdc/src/lib.rs | 7 ++++--- 5 files changed, 24 insertions(+), 30 deletions(-) diff --git a/card-functionality/src/cards.rs b/card-functionality/src/cards.rs index c1b8f90..5236a2b 100644 --- a/card-functionality/src/cards.rs +++ b/card-functionality/src/cards.rs @@ -112,15 +112,8 @@ impl TestCard { Err(anyhow!("Pcsc card {} not found", ident)) } Self::Scdc(serial) => { - let mut ca = ScdClient::open_by_serial(None, serial)?; - - // Set Card Capabilities (chaining, command length, ..) - let ard = ca.get_application_related_data()?; - ca.init_caps(&ard)?; - - // println!("opened scdc card {}", serial); - - Ok(ca) + // println!("open scdc card {}", serial); + Ok(ScdClient::open_by_serial(None, serial)?) } } } diff --git a/openpgp-card-sequoia/src/card.rs b/openpgp-card-sequoia/src/card.rs index 3493fb0..7b3af0a 100644 --- a/openpgp-card-sequoia/src/card.rs +++ b/openpgp-card-sequoia/src/card.rs @@ -50,8 +50,6 @@ impl<'a> Open<'a> { pub fn new(card_app: &'a mut CardApp) -> Result { let ard = card_app.get_application_related_data()?; - card_app.init_caps(&ard)?; - Ok(Self { card_app, ard, diff --git a/openpgp-card/src/card_app.rs b/openpgp-card/src/card_app.rs index 745c89e..dd7e0fe 100644 --- a/openpgp-card/src/card_app.rs +++ b/openpgp-card/src/card_app.rs @@ -35,11 +35,12 @@ pub struct CardApp { impl CardApp { /// Get a CardApp based on a CardClient. /// - /// It is expected that SELECT has already been performed on the card. + /// It is expected that SELECT has already been performed on the card + /// beforehand. /// - /// This fn calls CardClient::init_caps(). It should probably only be used - /// by backend implementations, not by user code. User Code should get - /// a fully initialized CardApp from their backend implementation. + /// This fn initializes the CardCaps by requesting + /// application_related_data from the card, and setting the + /// capabilities accordingly. pub fn initialize(card_client: CardClientBox) -> Result { let mut ca = Self { card_client }; @@ -49,7 +50,7 @@ impl CardApp { Ok(ca) } - /// Get the CardClient for this CardApp + /// Get the CardClient of this CardApp pub(crate) fn card_client(&mut self) -> &mut dyn CardClient { &mut *self.card_client } @@ -58,7 +59,7 @@ impl CardApp { /// from the data in `ard`. /// /// This should be done at an early point, soon after opening the card. - pub fn init_caps(&mut self, ard: &ApplicationRelatedData) -> Result<()> { + fn init_caps(&mut self, ard: &ApplicationRelatedData) -> Result<()> { // Determine chaining/extended length support from card // metadata and cache this information in CardApp (as a // CardCaps) diff --git a/pcsc/src/lib.rs b/pcsc/src/lib.rs index 35f3c0e..43671cb 100644 --- a/pcsc/src/lib.rs +++ b/pcsc/src/lib.rs @@ -86,8 +86,8 @@ impl PcscClient { /// Return all cards on which the OpenPGP application could be selected. /// - /// Each card is opened and has the OpenPGP application selected. - /// Cards are initialized via init_caps(). + /// Each card has the OpenPGP application selected, CardCaps have been + /// initialized. pub fn cards() -> Result> { let mut cards = vec![]; @@ -112,18 +112,19 @@ impl PcscClient { } /// Returns the OpenPGP card that matches `ident`, if it is available. - /// A fully initialized CardApp is returned: application has been - /// selected, init_caps() has been performed. + /// A fully initialized CardApp is returned: the OpenPGP application has + /// been selected, CardCaps have been set. pub fn open_by_ident(ident: &str) -> Result { for mut card in Self::unopened_cards()? { - Self::select(&mut card)?; - let mut ca = card.into_card_app()?; + if Self::select(&mut card).is_ok() { + let mut ca = card.into_card_app()?; - let ard = ca.get_application_related_data()?; - let aid = ard.get_application_id()?; + let ard = ca.get_application_related_data()?; + let aid = ard.get_application_id()?; - if aid.ident() == ident { - return Ok(ca); + if aid.ident() == ident { + return Ok(ca); + } } } diff --git a/scdc/src/lib.rs b/scdc/src/lib.rs index 4bff66e..d250759 100644 --- a/scdc/src/lib.rs +++ b/scdc/src/lib.rs @@ -14,7 +14,7 @@ use std::sync::Mutex; use tokio::runtime::Runtime; use openpgp_card::{CardApp, Error}; -use openpgp_card::{CardCaps, CardClient, CardClientBox}; +use openpgp_card::{CardCaps, CardClient}; lazy_static! { static ref RT: Mutex = @@ -108,9 +108,10 @@ impl ScdClient { /// Create a CardClientBox object that uses an scdaemon instance as its /// backend. If multiple cards are available, scdaemon implicitly /// selects one. - pub fn open(agent: Option) -> Result { + pub fn open(agent: Option) -> Result { let card = ScdClient::new(agent, true)?; - Ok(Box::new(card) as CardClientBox) + + Ok(CardApp::initialize(Box::new(card))?) } /// Create a CardClientBox object that uses an scdaemon instance as its