Tweak ergonomics of openpgp-card-pcsc usage and simplify client code.
This commit is contained in:
parent
635fa0e6ac
commit
e01c79e857
10 changed files with 47 additions and 44 deletions
|
@ -9,7 +9,7 @@ use pcsc::ShareMode;
|
|||
use serde_derive::Deserialize;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use openpgp_card::Error;
|
||||
use openpgp_card::{CardBackend, Error};
|
||||
use openpgp_card_pcsc::PcscCard;
|
||||
use openpgp_card_scdc::ScdClient;
|
||||
|
||||
|
@ -41,7 +41,7 @@ pub struct TestCardData {
|
|||
}
|
||||
|
||||
impl TestCardData {
|
||||
pub(crate) fn get_card(&self) -> Result<Box<PcscCard>> {
|
||||
pub(crate) fn get_card(&self) -> Result<Box<dyn CardBackend>> {
|
||||
self.tc.open()
|
||||
}
|
||||
|
||||
|
@ -92,7 +92,7 @@ pub enum TestCard {
|
|||
}
|
||||
|
||||
impl TestCard {
|
||||
pub fn open(&self) -> Result<Box<PcscCard>> {
|
||||
pub fn open(&self) -> Result<Box<dyn CardBackend>> {
|
||||
match self {
|
||||
Self::Pcsc(ident) => {
|
||||
// Attempt to shutdown SCD, if it is running.
|
||||
|
@ -103,11 +103,11 @@ impl TestCard {
|
|||
// Make three attempts to open the card before failing
|
||||
// (this can be useful in ShareMode::Exclusive)
|
||||
let mut i = 1;
|
||||
let card: Result<PcscCard, Error> = loop {
|
||||
let card: Result<Box<dyn CardBackend>, Error> = loop {
|
||||
let res = PcscCard::open_by_ident(ident, SHARE_MODE);
|
||||
|
||||
if i == 3 || res.is_ok() {
|
||||
break res;
|
||||
break res.map(Into::into);
|
||||
}
|
||||
|
||||
// sleep for 100ms
|
||||
|
@ -116,7 +116,7 @@ impl TestCard {
|
|||
i += 1;
|
||||
};
|
||||
|
||||
Ok(Box::new(card?))
|
||||
Ok(card?)
|
||||
}
|
||||
Self::Scdc(serial) => {
|
||||
unimplemented!();
|
||||
|
|
|
@ -11,7 +11,7 @@ fn main() -> Result<()> {
|
|||
println!("The following OpenPGP cards are connected to your system:");
|
||||
|
||||
for mut card in PcscCard::cards(None)? {
|
||||
let mut txc = <dyn CardBackend>::transaction(&mut card)?;
|
||||
let mut txc = card.transaction()?;
|
||||
|
||||
let open = Open::new(&mut *txc)?;
|
||||
println!(" {}", open.application_identifier()?.ident());
|
||||
|
|
|
@ -15,9 +15,7 @@ use sequoia_openpgp::Cert;
|
|||
use openpgp_card;
|
||||
use openpgp_card::algorithm::AlgoSimple;
|
||||
use openpgp_card::card_do::{KeyGenerationTime, Sex};
|
||||
use openpgp_card::{
|
||||
CardBackend, CardTransaction, Error, KeyType, StatusBytes,
|
||||
};
|
||||
use openpgp_card::{CardTransaction, Error, KeyType, StatusBytes};
|
||||
use openpgp_card_sequoia::card::Open;
|
||||
use openpgp_card_sequoia::util::{
|
||||
make_cert, public_key_material_to_key, public_to_fingerprint,
|
||||
|
@ -680,8 +678,7 @@ pub fn run_test(
|
|||
param: &[&str],
|
||||
) -> Result<TestOutput, TestError> {
|
||||
let mut card = tc.get_card()?;
|
||||
let mut txc =
|
||||
<dyn CardBackend>::transaction(&mut *card).map_err(|e| anyhow!(e))?;
|
||||
let mut txc = card.transaction().map_err(|e| anyhow!(e))?;
|
||||
|
||||
t(&mut *txc, param)
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
let cert_file = &args[2];
|
||||
|
||||
let mut card = PcscCard::open_by_ident(card_ident, None)?;
|
||||
let mut txc = <dyn CardBackend>::transaction(&mut card)?;
|
||||
let mut txc = card.transaction()?;
|
||||
|
||||
let mut open = Open::new(&mut *txc)?;
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
let cert_file = &args[2];
|
||||
|
||||
let mut card = PcscCard::open_by_ident(card_ident, None)?;
|
||||
let mut txc = <dyn CardBackend>::transaction(&mut card)?;
|
||||
let mut txc = card.transaction()?;
|
||||
|
||||
let mut open = Open::new(&mut *txc)?;
|
||||
|
||||
|
|
|
@ -12,13 +12,13 @@
|
|||
//! With `openpgp-card-pcsc` you can either open all available cards:
|
||||
//!
|
||||
//! ```no_run
|
||||
//! use openpgp_card_sequoia::card::Open;
|
||||
//! use openpgp_card_pcsc::PcscCard;
|
||||
//! use openpgp_card::CardBackend;
|
||||
//! use openpgp_card_sequoia::card::Open;
|
||||
//!
|
||||
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
//! # use openpgp_card::CardBackend;
|
||||
//! for mut card in PcscCard::cards(None)? {
|
||||
//! let mut txc = <dyn CardBackend>::transaction(&mut card)?;
|
||||
//! let mut txc = card.transaction()?;
|
||||
//! let open = Open::new(&mut *txc)?;
|
||||
//! println!("Found OpenPGP card with ident '{}'",
|
||||
//! open.application_identifier()?.ident());
|
||||
|
@ -30,13 +30,13 @@
|
|||
//! Or you can open one particular card, by ident:
|
||||
//!
|
||||
//! ```no_run
|
||||
//! use openpgp_card_sequoia::card::Open;
|
||||
//! use openpgp_card_pcsc::PcscCard;
|
||||
//! use openpgp_card::CardBackend;
|
||||
//! use openpgp_card_sequoia::card::Open;
|
||||
//!
|
||||
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
//! # use openpgp_card::CardBackend;
|
||||
//! let mut card = PcscCard::open_by_ident("abcd:12345678", None)?;
|
||||
//! let mut txc = <dyn CardBackend>::transaction(&mut card)?;
|
||||
//! let mut txc = card.transaction()?;
|
||||
//! let mut open = Open::new(&mut *txc)?;
|
||||
//! # Ok(())
|
||||
//! # }
|
||||
|
@ -52,15 +52,15 @@
|
|||
//! that corresponds to the private encryption key on the card:
|
||||
//!
|
||||
//! ```no_run
|
||||
//! use openpgp_card_sequoia::card::Open;
|
||||
//! use openpgp_card_pcsc::PcscCard;
|
||||
//! use openpgp_card::CardBackend;
|
||||
//! use openpgp_card_sequoia::card::Open;
|
||||
//!
|
||||
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
//! // Open card via PCSC
|
||||
//! use sequoia_openpgp::policy::StandardPolicy;
|
||||
//! # use openpgp_card::CardBackend;
|
||||
//! let mut card = PcscCard::open_by_ident("abcd:12345678", None)?;
|
||||
//! let mut txc = <dyn CardBackend>::transaction(&mut card)?;
|
||||
//! let mut txc = card.transaction()?;
|
||||
//! let mut open = Open::new(&mut *txc)?;
|
||||
//!
|
||||
//! // Get authorization for user access to the card with password
|
||||
|
@ -95,15 +95,15 @@
|
|||
//! user password before each signing operation!)
|
||||
//!
|
||||
//! ```no_run
|
||||
//! use openpgp_card_sequoia::card::Open;
|
||||
//! use openpgp_card_pcsc::PcscCard;
|
||||
//! use openpgp_card::CardBackend;
|
||||
//! use openpgp_card_sequoia::card::Open;
|
||||
//!
|
||||
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
//! # use openpgp_card::CardBackend;
|
||||
//! // Open card via PCSC
|
||||
//! use sequoia_openpgp::policy::StandardPolicy;
|
||||
//! let mut card = PcscCard::open_by_ident("abcd:12345678", None)?;
|
||||
//! let mut txc = <dyn CardBackend>::transaction(&mut card)?;
|
||||
//! let mut txc = card.transaction()?;
|
||||
//! let mut open = Open::new(&mut *txc)?;
|
||||
//!
|
||||
//! // Get authorization for signing access to the card with password
|
||||
|
@ -128,14 +128,14 @@
|
|||
//! # Setting up and configuring a card
|
||||
//!
|
||||
//! ```no_run
|
||||
//! use openpgp_card_sequoia::card::Open;
|
||||
//! use openpgp_card_pcsc::PcscCard;
|
||||
//! use openpgp_card::CardBackend;
|
||||
//! use openpgp_card_sequoia::card::Open;
|
||||
//!
|
||||
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
//! # use openpgp_card::CardBackend;
|
||||
//! // Open card via PCSC
|
||||
//! let mut card = PcscCard::open_by_ident("abcd:12345678", None)?;
|
||||
//! let mut txc = <dyn CardBackend>::transaction(&mut card)?;
|
||||
//! let mut txc = card.transaction()?;
|
||||
//! let mut open = Open::new(&mut *txc)?;
|
||||
//!
|
||||
//! // Get authorization for admin access to the card with password
|
||||
|
|
|
@ -10,8 +10,7 @@ use sequoia_openpgp::policy::StandardPolicy;
|
|||
use sequoia_openpgp::Cert;
|
||||
|
||||
use openpgp_card::card_do::Sex;
|
||||
use openpgp_card::CardBackend;
|
||||
use openpgp_card::KeyType;
|
||||
use openpgp_card::{CardBackend, KeyType};
|
||||
use openpgp_card_pcsc::PcscCard;
|
||||
|
||||
use openpgp_card_sequoia::card::Open;
|
||||
|
|
|
@ -40,6 +40,12 @@ pub struct PcscCard {
|
|||
reader_caps: HashMap<u8, Tlv>,
|
||||
}
|
||||
|
||||
impl From<PcscCard> for Box<dyn CardBackend> {
|
||||
fn from(card: PcscCard) -> Box<dyn CardBackend> {
|
||||
Box::new(card) as Box<dyn CardBackend>
|
||||
}
|
||||
}
|
||||
|
||||
/// An implementation of the CardTransaction trait that uses the PCSC lite
|
||||
/// middleware to access the OpenPGP card application on smart cards, via a
|
||||
/// PCSC "transaction".
|
||||
|
@ -446,11 +452,11 @@ impl CardTransaction for TxClient<'_> {
|
|||
}
|
||||
|
||||
impl PcscCard {
|
||||
pub fn card(&mut self) -> &mut Card {
|
||||
fn card(&mut self) -> &mut Card {
|
||||
&mut self.card
|
||||
}
|
||||
|
||||
pub fn mode(&self) -> ShareMode {
|
||||
fn mode(&self) -> ShareMode {
|
||||
self.mode
|
||||
}
|
||||
|
||||
|
@ -529,8 +535,8 @@ impl PcscCard {
|
|||
fn cards_filter(
|
||||
ident: Option<&str>,
|
||||
mode: ShareMode,
|
||||
) -> Result<Vec<PcscCard>, Error> {
|
||||
let mut cas: Vec<PcscCard> = vec![];
|
||||
) -> Result<Vec<Self>, Error> {
|
||||
let mut cards: Vec<Self> = vec![];
|
||||
|
||||
for mut card in
|
||||
Self::raw_pcsc_cards(mode).map_err(|sce| Error::Smartcard(sce))?
|
||||
|
@ -588,20 +594,20 @@ impl PcscCard {
|
|||
|
||||
if store_card {
|
||||
let pcsc = PcscCard::new(card, mode);
|
||||
cas.push(pcsc.initialize_card()?);
|
||||
cards.push(pcsc.initialize_card()?);
|
||||
}
|
||||
}
|
||||
|
||||
log::debug!("cards_filter: found {} cards", cas.len());
|
||||
log::debug!("cards_filter: found {} cards", cards.len());
|
||||
|
||||
Ok(cas)
|
||||
Ok(cards)
|
||||
}
|
||||
|
||||
/// Return all cards on which the OpenPGP application could be selected.
|
||||
///
|
||||
/// Each card has the OpenPGP application selected, card_caps and reader_caps have been
|
||||
/// initialized.
|
||||
pub fn cards(mode: Option<ShareMode>) -> Result<Vec<PcscCard>, Error> {
|
||||
pub fn cards(mode: Option<ShareMode>) -> Result<Vec<Self>, Error> {
|
||||
Self::cards_filter(None, default_mode(mode))
|
||||
}
|
||||
|
||||
|
@ -611,7 +617,7 @@ impl PcscCard {
|
|||
pub fn open_by_ident(
|
||||
ident: &str,
|
||||
mode: Option<ShareMode>,
|
||||
) -> Result<PcscCard, Error> {
|
||||
) -> Result<Self, Error> {
|
||||
log::debug!("open_by_ident for {:?}", ident);
|
||||
|
||||
let mut cards = Self::cards_filter(Some(ident), default_mode(mode))?;
|
||||
|
|
|
@ -12,7 +12,6 @@ use sequoia_openpgp::serialize::SerializeInto;
|
|||
use sequoia_openpgp::Cert;
|
||||
|
||||
use openpgp_card::algorithm::AlgoSimple;
|
||||
use openpgp_card::CardBackend;
|
||||
use openpgp_card::{card_do::Sex, KeyType};
|
||||
|
||||
use openpgp_card_sequoia::card::{Admin, Open};
|
||||
|
|
|
@ -6,16 +6,18 @@ use std::path::{Path, PathBuf};
|
|||
|
||||
use openpgp_card::algorithm::{Algo, Curve};
|
||||
use openpgp_card::crypto_data::{EccType, PublicKeyMaterial};
|
||||
use openpgp_card::Error;
|
||||
use openpgp_card::{CardBackend, Error};
|
||||
use openpgp_card_pcsc::PcscCard;
|
||||
use openpgp_card_sequoia::card::{Admin, Open, Sign, User};
|
||||
|
||||
pub(crate) fn cards() -> Result<Vec<PcscCard>, Error> {
|
||||
pub(crate) fn cards() -> Result<Vec<Box<dyn CardBackend>>, Error> {
|
||||
PcscCard::cards(None)
|
||||
.map(|cards| cards.into_iter().map(Into::into).collect())
|
||||
}
|
||||
|
||||
pub(crate) fn open_card(ident: &str) -> Result<PcscCard, Error> {
|
||||
pub(crate) fn open_card(ident: &str) -> Result<Box<dyn CardBackend>, Error> {
|
||||
PcscCard::open_by_ident(ident, None)
|
||||
.map(|pc| Box::new(pc) as Box<dyn CardBackend>)
|
||||
}
|
||||
|
||||
pub(crate) fn verify_to_user<'app, 'open>(
|
||||
|
|
Loading…
Reference in a new issue