Moved handling of cards and configuration of cards for testing to cards.rs

This commit is contained in:
Heiko Schaefer 2021-08-05 15:16:59 +02:00
parent f67501d0f9
commit 3effe39aa1
2 changed files with 106 additions and 87 deletions

View file

@ -0,0 +1,100 @@
// SPDX-FileCopyrightText: 2021 Heiko Schaefer <heiko@schaefer.name>
// 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<CardApp> {
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<Vec<String>>,
scdc: Option<Vec<String>>,
}
impl TestConfig {
pub fn open(file: &str) -> Result<Self> {
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<TestCard> {
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
}
}

View file

@ -25,75 +25,21 @@
//! The Yubikey 5 erroneously returns Status 0x6a80 ("Incorrect parameters in //! The Yubikey 5 erroneously returns Status 0x6a80 ("Incorrect parameters in
//! the command data field"). //! the command data field").
use anyhow::{anyhow, Error, Result}; use anyhow::{Error, Result};
use serde_derive::Deserialize;
use thiserror::Error; use thiserror::Error;
use sequoia_openpgp::parse::Parse; use sequoia_openpgp::parse::Parse;
use sequoia_openpgp::Cert; use sequoia_openpgp::Cert;
use openpgp_card::apdu::PcscClient;
use openpgp_card::card_app::CardApp; use openpgp_card::card_app::CardApp;
use openpgp_card::errors::{OcErrorStatus, OpenpgpCardError}; use openpgp_card::errors::{OcErrorStatus, OpenpgpCardError};
use openpgp_card::{CardClientBox, Sex}; use openpgp_card::Sex;
use openpgp_card_scdc::ScdClient;
use crate::cards::{TestCard, TestConfig};
mod cards;
mod util; mod util;
#[derive(Debug)]
enum TestCard {
Pcsc(String),
Scdc(String),
}
impl TestCard {
fn open(&self) -> Result<CardApp> {
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)] #[derive(Debug)]
enum TestResult { enum TestResult {
Status([u8; 2]), Status([u8; 2]),
@ -378,37 +324,10 @@ fn run_test(
t(&mut ca, param) t(&mut ca, param)
} }
#[derive(Debug, Deserialize)]
struct TestConfig {
pcsc: Option<Vec<String>>,
scdc: Option<Vec<String>>,
}
impl TestConfig {
fn get_cards(&self) -> Vec<TestCard> {
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<()> { fn main() -> Result<()> {
env_logger::init(); env_logger::init();
let config = std::fs::read_to_string("config/test-cards.toml")?; let config = TestConfig::open("config/test-cards.toml")?;
let config: TestConfig = toml::from_str(&config)?;
let cards = config.get_cards(); let cards = config.get_cards();