Adjust the backend API and interaction with openpgp-card some more.

This commit is contained in:
Heiko Schaefer 2021-11-12 18:47:56 +01:00
parent 7a71f88eb6
commit 90ae9398ed
No known key found for this signature in database
GPG key ID: 4A849A1904CCBD7D
5 changed files with 24 additions and 30 deletions

View file

@ -112,15 +112,8 @@ impl TestCard {
Err(anyhow!("Pcsc card {} not found", ident)) Err(anyhow!("Pcsc card {} not found", ident))
} }
Self::Scdc(serial) => { Self::Scdc(serial) => {
let mut ca = ScdClient::open_by_serial(None, serial)?; // println!("open scdc card {}", serial);
Ok(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)
} }
} }
} }

View file

@ -50,8 +50,6 @@ impl<'a> Open<'a> {
pub fn new(card_app: &'a mut CardApp) -> Result<Self, Error> { pub fn new(card_app: &'a mut CardApp) -> Result<Self, Error> {
let ard = card_app.get_application_related_data()?; let ard = card_app.get_application_related_data()?;
card_app.init_caps(&ard)?;
Ok(Self { Ok(Self {
card_app, card_app,
ard, ard,

View file

@ -35,11 +35,12 @@ pub struct CardApp {
impl CardApp { impl CardApp {
/// Get a CardApp based on a CardClient. /// 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 /// This fn initializes the CardCaps by requesting
/// by backend implementations, not by user code. User Code should get /// application_related_data from the card, and setting the
/// a fully initialized CardApp from their backend implementation. /// capabilities accordingly.
pub fn initialize(card_client: CardClientBox) -> Result<Self> { pub fn initialize(card_client: CardClientBox) -> Result<Self> {
let mut ca = Self { card_client }; let mut ca = Self { card_client };
@ -49,7 +50,7 @@ impl CardApp {
Ok(ca) Ok(ca)
} }
/// Get the CardClient for this CardApp /// Get the CardClient of this CardApp
pub(crate) fn card_client(&mut self) -> &mut dyn CardClient { pub(crate) fn card_client(&mut self) -> &mut dyn CardClient {
&mut *self.card_client &mut *self.card_client
} }
@ -58,7 +59,7 @@ impl CardApp {
/// from the data in `ard`. /// from the data in `ard`.
/// ///
/// This should be done at an early point, soon after opening the card. /// 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 // Determine chaining/extended length support from card
// metadata and cache this information in CardApp (as a // metadata and cache this information in CardApp (as a
// CardCaps) // CardCaps)

View file

@ -86,8 +86,8 @@ impl PcscClient {
/// Return all cards on which the OpenPGP application could be selected. /// Return all cards on which the OpenPGP application could be selected.
/// ///
/// Each card is opened and has the OpenPGP application selected. /// Each card has the OpenPGP application selected, CardCaps have been
/// Cards are initialized via init_caps(). /// initialized.
pub fn cards() -> Result<Vec<CardApp>> { pub fn cards() -> Result<Vec<CardApp>> {
let mut cards = vec![]; let mut cards = vec![];
@ -112,11 +112,11 @@ impl PcscClient {
} }
/// Returns the OpenPGP card that matches `ident`, if it is available. /// Returns the OpenPGP card that matches `ident`, if it is available.
/// A fully initialized CardApp is returned: application has been /// A fully initialized CardApp is returned: the OpenPGP application has
/// selected, init_caps() has been performed. /// been selected, CardCaps have been set.
pub fn open_by_ident(ident: &str) -> Result<CardApp, Error> { pub fn open_by_ident(ident: &str) -> Result<CardApp, Error> {
for mut card in Self::unopened_cards()? { for mut card in Self::unopened_cards()? {
Self::select(&mut card)?; if Self::select(&mut card).is_ok() {
let mut ca = card.into_card_app()?; let mut ca = card.into_card_app()?;
let ard = ca.get_application_related_data()?; let ard = ca.get_application_related_data()?;
@ -126,6 +126,7 @@ impl PcscClient {
return Ok(ca); return Ok(ca);
} }
} }
}
Err(Error::Smartcard(SmartcardError::CardNotFound( Err(Error::Smartcard(SmartcardError::CardNotFound(
ident.to_string(), ident.to_string(),

View file

@ -14,7 +14,7 @@ use std::sync::Mutex;
use tokio::runtime::Runtime; use tokio::runtime::Runtime;
use openpgp_card::{CardApp, Error}; use openpgp_card::{CardApp, Error};
use openpgp_card::{CardCaps, CardClient, CardClientBox}; use openpgp_card::{CardCaps, CardClient};
lazy_static! { lazy_static! {
static ref RT: Mutex<Runtime> = static ref RT: Mutex<Runtime> =
@ -108,9 +108,10 @@ impl ScdClient {
/// Create a CardClientBox object that uses an scdaemon instance as its /// Create a CardClientBox object that uses an scdaemon instance as its
/// backend. If multiple cards are available, scdaemon implicitly /// backend. If multiple cards are available, scdaemon implicitly
/// selects one. /// selects one.
pub fn open(agent: Option<Agent>) -> Result<CardClientBox, Error> { pub fn open(agent: Option<Agent>) -> Result<CardApp, Error> {
let card = ScdClient::new(agent, true)?; 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 /// Create a CardClientBox object that uses an scdaemon instance as its