From 3effe39aa11409a80525bf6c9f577194666a75ae Mon Sep 17 00:00:00 2001 From: Heiko Schaefer Date: Thu, 5 Aug 2021 15:16:59 +0200 Subject: [PATCH] Moved handling of cards and configuration of cards for testing to cards.rs --- card-functionality/src/cards.rs | 100 ++++++++++++++++++++++++++++++++ card-functionality/src/main.rs | 93 ++--------------------------- 2 files changed, 106 insertions(+), 87 deletions(-) create mode 100644 card-functionality/src/cards.rs diff --git a/card-functionality/src/cards.rs b/card-functionality/src/cards.rs new file mode 100644 index 0000000..65b2cc7 --- /dev/null +++ b/card-functionality/src/cards.rs @@ -0,0 +1,100 @@ +// SPDX-FileCopyrightText: 2021 Heiko Schaefer +// SPDX-License-Identifier: MIT OR Apache-2.0 + +//! Wrapping of cards for tests. Open a list of cards, based on a +//! TestConfig configuration file + +use anyhow::{anyhow, Result}; +use serde_derive::Deserialize; + +use openpgp_card::apdu::PcscClient; +use openpgp_card::card_app::CardApp; +use openpgp_card::CardClientBox; +use openpgp_card_scdc::ScdClient; + +#[derive(Debug)] +pub enum TestCard { + Pcsc(String), + Scdc(String), +} + +impl TestCard { + pub fn open(&self) -> Result { + match self { + Self::Pcsc(ident) => { + // Attempt to shutdown SCD, if it is running. + // Ignore any errors that occur during that shutdown attempt. + let res = ScdClient::shutdown_scd(None); + log::trace!(" Attempt to shutdown scd: {:?}", res); + + for card in PcscClient::list_cards()? { + let card_client = Box::new(card) as CardClientBox; + let mut ca = CardApp::new(card_client); + + // Select OpenPGP applet + let res = ca.select()?; + res.check_ok()?; + + // Set Card Capabilities (chaining, command length, ..) + let ard = ca.get_app_data()?; + let app_id = CardApp::get_aid(&ard)?; + + if app_id.ident().as_str() == ident { + ca.init_caps(&ard)?; + + // println!("opened pcsc card {}", ident); + + return Ok(ca); + } + } + + Err(anyhow!("Pcsc card {} not found", ident)) + } + Self::Scdc(serial) => { + let card_client = ScdClient::open_by_serial(None, serial)?; + let mut ca = CardApp::new(card_client); + + // Set Card Capabilities (chaining, command length, ..) + let ard = ca.get_app_data()?; + ca.init_caps(&ard)?; + + // println!("opened scdc card {}", serial); + + Ok(ca) + } + } + } +} + +#[derive(Debug, Deserialize)] +pub struct TestConfig { + pcsc: Option>, + scdc: Option>, +} + +impl TestConfig { + pub fn open(file: &str) -> Result { + let config_file = std::fs::read_to_string(file)?; + + let config: Self = toml::from_str(&config_file)?; + Ok(config) + } + + pub fn get_cards(&self) -> Vec { + let mut cards = vec![]; + + if let Some(pcsc) = &self.pcsc { + for card in pcsc { + cards.push(TestCard::Pcsc(card.to_string())); + } + } + + if let Some(scdc) = &self.scdc { + for card in scdc { + cards.push(TestCard::Scdc(card.to_string())); + } + } + + cards + } +} diff --git a/card-functionality/src/main.rs b/card-functionality/src/main.rs index 196d69f..e712712 100644 --- a/card-functionality/src/main.rs +++ b/card-functionality/src/main.rs @@ -25,75 +25,21 @@ //! The Yubikey 5 erroneously returns Status 0x6a80 ("Incorrect parameters in //! the command data field"). -use anyhow::{anyhow, Error, Result}; -use serde_derive::Deserialize; +use anyhow::{Error, Result}; use thiserror::Error; use sequoia_openpgp::parse::Parse; use sequoia_openpgp::Cert; -use openpgp_card::apdu::PcscClient; use openpgp_card::card_app::CardApp; use openpgp_card::errors::{OcErrorStatus, OpenpgpCardError}; -use openpgp_card::{CardClientBox, Sex}; -use openpgp_card_scdc::ScdClient; +use openpgp_card::Sex; +use crate::cards::{TestCard, TestConfig}; + +mod cards; mod util; -#[derive(Debug)] -enum TestCard { - Pcsc(String), - Scdc(String), -} - -impl TestCard { - fn open(&self) -> Result { - match self { - Self::Pcsc(ident) => { - // Attempt to shutdown SCD, if it is running. - // Ignore any errors that occur during that shutdown attempt. - let res = ScdClient::shutdown_scd(None); - log::trace!(" Attempt to shutdown scd: {:?}", res); - - for card in PcscClient::list_cards()? { - let card_client = Box::new(card) as CardClientBox; - let mut ca = CardApp::new(card_client); - - // Select OpenPGP applet - let res = ca.select()?; - res.check_ok()?; - - // Set Card Capabilities (chaining, command length, ..) - let ard = ca.get_app_data()?; - let app_id = CardApp::get_aid(&ard)?; - - if app_id.ident().as_str() == ident { - ca.init_caps(&ard)?; - - // println!("opened pcsc card {}", ident); - - return Ok(ca); - } - } - - Err(anyhow!("Pcsc card {} not found", ident)) - } - Self::Scdc(serial) => { - let card_client = ScdClient::open_by_serial(None, serial)?; - let mut ca = CardApp::new(card_client); - - // Set Card Capabilities (chaining, command length, ..) - let ard = ca.get_app_data()?; - ca.init_caps(&ard)?; - - // println!("opened scdc card {}", serial); - - Ok(ca) - } - } - } -} - #[derive(Debug)] enum TestResult { Status([u8; 2]), @@ -378,37 +324,10 @@ fn run_test( t(&mut ca, param) } -#[derive(Debug, Deserialize)] -struct TestConfig { - pcsc: Option>, - scdc: Option>, -} - -impl TestConfig { - fn get_cards(&self) -> Vec { - let mut cards = vec![]; - - if let Some(pcsc) = &self.pcsc { - for card in pcsc { - cards.push(TestCard::Pcsc(card.to_string())); - } - } - - if let Some(scdc) = &self.scdc { - for card in scdc { - cards.push(TestCard::Scdc(card.to_string())); - } - } - - cards - } -} - fn main() -> Result<()> { env_logger::init(); - let config = std::fs::read_to_string("config/test-cards.toml")?; - let config: TestConfig = toml::from_str(&config)?; + let config = TestConfig::open("config/test-cards.toml")?; let cards = config.get_cards();