Introduce the new CardBackend trait.
A CardBackend represents a card without an open transaction (a CardTransaction implementation can be acquired from a CardBackend).
This commit is contained in:
parent
5133051626
commit
c23f23c619
10 changed files with 66 additions and 43 deletions
|
@ -3,6 +3,7 @@
|
|||
|
||||
use anyhow::Result;
|
||||
|
||||
use openpgp_card::CardBackend;
|
||||
use openpgp_card_pcsc::PcscCard;
|
||||
use openpgp_card_sequoia::card::Open;
|
||||
|
||||
|
@ -10,9 +11,9 @@ fn main() -> Result<()> {
|
|||
println!("The following OpenPGP cards are connected to your system:");
|
||||
|
||||
for mut card in PcscCard::cards(None)? {
|
||||
let mut txc = card.transaction()?;
|
||||
let mut txc = <dyn CardBackend>::transaction(&mut card)?;
|
||||
|
||||
let open = Open::new(&mut txc)?;
|
||||
let open = Open::new(&mut *txc)?;
|
||||
println!(" {}", open.application_identifier()?.ident());
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,9 @@ use sequoia_openpgp::Cert;
|
|||
use openpgp_card;
|
||||
use openpgp_card::algorithm::AlgoSimple;
|
||||
use openpgp_card::card_do::{KeyGenerationTime, Sex};
|
||||
use openpgp_card::{CardTransaction, Error, KeyType, StatusBytes};
|
||||
use openpgp_card::{
|
||||
CardBackend, 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,
|
||||
|
@ -678,7 +680,8 @@ pub fn run_test(
|
|||
param: &[&str],
|
||||
) -> Result<TestOutput, TestError> {
|
||||
let mut card = tc.get_card()?;
|
||||
let mut txc = card.transaction().map_err(|e| anyhow!(e))?;
|
||||
let mut txc =
|
||||
<dyn CardBackend>::transaction(&mut *card).map_err(|e| anyhow!(e))?;
|
||||
|
||||
t(&mut txc, param)
|
||||
t(&mut *txc, param)
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
// SPDX-FileCopyrightText: 2021 Wiktor Kwapisiewicz <wiktor@metacode.biz>
|
||||
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||
|
||||
use openpgp_card::CardBackend;
|
||||
use openpgp_card_pcsc::PcscCard;
|
||||
|
||||
use openpgp_card_sequoia::card::Open;
|
||||
|
||||
use openpgp::parse::{stream::DecryptorBuilder, Parse};
|
||||
|
@ -23,9 +23,9 @@ 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 = card.transaction()?;
|
||||
let mut txc = <dyn CardBackend>::transaction(&mut card)?;
|
||||
|
||||
let mut open = Open::new(&mut txc)?;
|
||||
let mut open = Open::new(&mut *txc)?;
|
||||
|
||||
let pin = std::fs::read_to_string(pin_file)?;
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
// SPDX-FileCopyrightText: 2021 Wiktor Kwapisiewicz <wiktor@metacode.biz>
|
||||
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||
|
||||
use openpgp_card::CardBackend;
|
||||
use openpgp_card_pcsc::PcscCard;
|
||||
|
||||
use openpgp_card_sequoia::card::Open;
|
||||
|
||||
use openpgp::parse::Parse;
|
||||
|
@ -23,9 +23,9 @@ 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 = card.transaction()?;
|
||||
let mut txc = <dyn CardBackend>::transaction(&mut card)?;
|
||||
|
||||
let mut open = Open::new(&mut txc)?;
|
||||
let mut open = Open::new(&mut *txc)?;
|
||||
|
||||
let pin = std::fs::read_to_string(pin_file)?;
|
||||
|
||||
|
|
|
@ -16,9 +16,10 @@
|
|||
//! use openpgp_card_pcsc::PcscCard;
|
||||
//!
|
||||
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
//! # use openpgp_card::CardBackend;
|
||||
//! for mut card in PcscCard::cards(None)? {
|
||||
//! let mut txc = card.transaction()?;
|
||||
//! let open = Open::new(&mut txc)?;
|
||||
//! let mut txc = <dyn CardBackend>::transaction(&mut card)?;
|
||||
//! let open = Open::new(&mut *txc)?;
|
||||
//! println!("Found OpenPGP card with ident '{}'",
|
||||
//! open.application_identifier()?.ident());
|
||||
//! }
|
||||
|
@ -33,9 +34,10 @@
|
|||
//! use openpgp_card_pcsc::PcscCard;
|
||||
//!
|
||||
//! # 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 = card.transaction()?;
|
||||
//! let mut open = Open::new(&mut txc)?;
|
||||
//! let mut txc = <dyn CardBackend>::transaction(&mut card)?;
|
||||
//! let mut open = Open::new(&mut *txc)?;
|
||||
//! # Ok(())
|
||||
//! # }
|
||||
//! ```
|
||||
|
@ -56,9 +58,10 @@
|
|||
//! # 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 = card.transaction()?;
|
||||
//! let mut open = Open::new(&mut txc)?;
|
||||
//! let mut txc = <dyn CardBackend>::transaction(&mut card)?;
|
||||
//! let mut open = Open::new(&mut *txc)?;
|
||||
//!
|
||||
//! // Get authorization for user access to the card with password
|
||||
//! open.verify_user("123456")?;
|
||||
|
@ -96,11 +99,12 @@
|
|||
//! use openpgp_card_pcsc::PcscCard;
|
||||
//!
|
||||
//! # 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 = card.transaction()?;
|
||||
//! let mut open = Open::new(&mut txc)?;
|
||||
//! let mut txc = <dyn CardBackend>::transaction(&mut card)?;
|
||||
//! let mut open = Open::new(&mut *txc)?;
|
||||
//!
|
||||
//! // Get authorization for signing access to the card with password
|
||||
//! open.verify_user_for_signing("123456")?;
|
||||
|
@ -128,10 +132,11 @@
|
|||
//! use openpgp_card_pcsc::PcscCard;
|
||||
//!
|
||||
//! # 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 = card.transaction()?;
|
||||
//! let mut open = Open::new(&mut txc)?;
|
||||
//! let mut txc = <dyn CardBackend>::transaction(&mut card)?;
|
||||
//! let mut open = Open::new(&mut *txc)?;
|
||||
//!
|
||||
//! // Get authorization for admin access to the card with password
|
||||
//! open.verify_admin("12345678")?;
|
||||
|
|
|
@ -10,6 +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_pcsc::PcscCard;
|
||||
|
||||
|
@ -38,7 +39,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||
let mut card = PcscCard::open_by_ident(&test_card_ident, None)?;
|
||||
let mut txc = card.transaction()?;
|
||||
|
||||
let mut open = Open::new(&mut txc)?;
|
||||
let mut open = Open::new(&mut *txc)?;
|
||||
|
||||
// card metadata
|
||||
|
||||
|
@ -149,7 +150,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||
let mut card = PcscCard::open_by_ident(&test_card_ident, None)?;
|
||||
let mut txc = card.transaction()?;
|
||||
|
||||
let mut open = Open::new(&mut txc)?;
|
||||
let mut open = Open::new(&mut *txc)?;
|
||||
|
||||
// Check that we're still using the expected card
|
||||
let app_id = open.application_identifier()?;
|
||||
|
@ -190,7 +191,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||
let mut card = PcscCard::open_by_ident(&test_card_ident, None)?;
|
||||
let mut txc = card.transaction()?;
|
||||
|
||||
let mut open = Open::new(&mut txc)?;
|
||||
let mut open = Open::new(&mut *txc)?;
|
||||
|
||||
// Sign
|
||||
open.verify_user_for_signing("123456")?;
|
||||
|
@ -222,7 +223,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||
for mut card in PcscCard::cards(None)? {
|
||||
let mut txc = card.transaction()?;
|
||||
|
||||
let open = Open::new(&mut txc)?;
|
||||
let open = Open::new(&mut *txc)?;
|
||||
println!(" {}", open.application_identifier()?.ident());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,6 +55,12 @@ use crate::tlv::tag::Tag;
|
|||
use crate::tlv::value::Value;
|
||||
use crate::tlv::Tlv;
|
||||
|
||||
pub trait CardBackend {
|
||||
fn transaction(
|
||||
&mut self,
|
||||
) -> Result<Box<dyn CardTransaction + Send + Sync + '_>, Error>;
|
||||
}
|
||||
|
||||
/// The CardTransaction trait defines communication with an OpenPGP card via a
|
||||
/// backend implementation (e.g. the pcsc backend in the crate
|
||||
/// [openpgp-card-pcsc](https://crates.io/crates/openpgp-card-pcsc)),
|
||||
|
|
|
@ -12,7 +12,9 @@ use std::collections::HashMap;
|
|||
use std::convert::TryInto;
|
||||
|
||||
use openpgp_card::card_do::ApplicationRelatedData;
|
||||
use openpgp_card::{CardCaps, CardTransaction, Error, SmartcardError};
|
||||
use openpgp_card::{
|
||||
CardBackend, CardCaps, CardTransaction, Error, SmartcardError,
|
||||
};
|
||||
|
||||
const FEATURE_VERIFY_PIN_DIRECT: u8 = 0x06;
|
||||
const FEATURE_MODIFY_PIN_DIRECT: u8 = 0x07;
|
||||
|
@ -61,7 +63,7 @@ impl<'b> TxClient<'b> {
|
|||
/// `reselect` set to `false` is only used internally in this crate,
|
||||
/// during initial setup of cards. Otherwise it must be `true`, to
|
||||
/// cause a select() call on cards that have been reset.
|
||||
fn new(card: &'b mut PcscCard, reselect: bool) -> Result<Self> {
|
||||
fn new(card: &'b mut PcscCard, reselect: bool) -> Result<Self, Error> {
|
||||
use pcsc::Disposition;
|
||||
|
||||
let mut was_reset = false;
|
||||
|
@ -452,11 +454,6 @@ impl PcscCard {
|
|||
self.mode
|
||||
}
|
||||
|
||||
/// Get a TxClient for this PcscCard (this starts a transaction)
|
||||
pub fn transaction(&mut self) -> Result<TxClient> {
|
||||
TxClient::new(self, true)
|
||||
}
|
||||
|
||||
/// A list of "raw" opened PCSC Cards (without selecting the OpenPGP card
|
||||
/// application)
|
||||
fn raw_pcsc_cards(mode: ShareMode) -> Result<Vec<Card>, SmartcardError> {
|
||||
|
@ -647,7 +644,7 @@ impl PcscCard {
|
|||
|
||||
let mut h: HashMap<u8, Tlv> = HashMap::default();
|
||||
|
||||
let mut txc = self.transaction()?;
|
||||
let mut txc = TxClient::new(&mut self, true)?;
|
||||
|
||||
// Get Features from reader (pinpad verify/modify)
|
||||
if let Ok(feat) = txc.features() {
|
||||
|
@ -680,3 +677,12 @@ impl PcscCard {
|
|||
self.reader_caps.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl CardBackend for PcscCard {
|
||||
/// Get a TxClient for this PcscCard (this starts a transaction)
|
||||
fn transaction(
|
||||
&mut self,
|
||||
) -> Result<Box<dyn CardTransaction + Send + Sync + '_>, Error> {
|
||||
Ok(Box::new(TxClient::new(self, true)?))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
use anyhow::Result;
|
||||
use structopt::StructOpt;
|
||||
|
||||
use openpgp_card::{CardTransaction, Error, StatusBytes};
|
||||
use openpgp_card::{CardBackend, Error, StatusBytes};
|
||||
use openpgp_card_pcsc::PcscCard;
|
||||
use openpgp_card_sequoia::card::Open;
|
||||
|
||||
|
@ -21,7 +21,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
let pinpad_verify = txc.feature_pinpad_verify();
|
||||
let pinpad_modify = txc.feature_pinpad_modify();
|
||||
|
||||
let mut open = Open::new(&mut txc)?;
|
||||
let mut open = Open::new(&mut *txc)?;
|
||||
|
||||
match cli.cmd {
|
||||
cli::Command::SetUserPin {} => {
|
||||
|
|
|
@ -12,7 +12,8 @@ use sequoia_openpgp::serialize::SerializeInto;
|
|||
use sequoia_openpgp::Cert;
|
||||
|
||||
use openpgp_card::algorithm::AlgoSimple;
|
||||
use openpgp_card::{card_do::Sex, CardTransaction, KeyType};
|
||||
use openpgp_card::CardBackend;
|
||||
use openpgp_card::{card_do::Sex, KeyType};
|
||||
|
||||
use openpgp_card_sequoia::card::{Admin, Open};
|
||||
use openpgp_card_sequoia::util::{make_cert, public_key_material_to_key};
|
||||
|
@ -73,7 +74,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
let mut card = util::open_card(&ident)?;
|
||||
let mut txc = card.transaction()?;
|
||||
|
||||
let mut open = Open::new(&mut txc)?;
|
||||
let mut open = Open::new(&mut *txc)?;
|
||||
|
||||
match cmd {
|
||||
cli::AdminCommand::Name { name } => {
|
||||
|
@ -140,7 +141,7 @@ fn list_cards() -> Result<()> {
|
|||
for mut card in cards {
|
||||
let mut txc = card.transaction()?;
|
||||
|
||||
let open = Open::new(&mut txc)?;
|
||||
let open = Open::new(&mut *txc)?;
|
||||
println!(" {}", open.application_identifier()?.ident());
|
||||
}
|
||||
} else {
|
||||
|
@ -156,7 +157,7 @@ fn set_identity(
|
|||
let mut card = util::open_card(ident)?;
|
||||
let mut txc = card.transaction()?;
|
||||
|
||||
<dyn CardTransaction>::set_identity(&mut txc, id)?;
|
||||
txc.set_identity(id)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -175,7 +176,7 @@ fn print_status(ident: Option<String>, verbose: bool) -> Result<()> {
|
|||
|
||||
let mut txc = card.transaction()?;
|
||||
|
||||
let mut open = Open::new(&mut txc)?;
|
||||
let mut open = Open::new(&mut *txc)?;
|
||||
|
||||
let ident = open.application_identifier()?.ident();
|
||||
|
||||
|
@ -336,7 +337,7 @@ fn decrypt(
|
|||
let mut card = util::open_card(ident)?;
|
||||
let mut txc = card.transaction()?;
|
||||
|
||||
let mut open = Open::new(&mut txc)?;
|
||||
let mut open = Open::new(&mut *txc)?;
|
||||
|
||||
let mut user = util::verify_to_user(&mut open, pin_file)?;
|
||||
let d = user.decryptor(&cert)?;
|
||||
|
@ -362,7 +363,7 @@ fn sign_detached(
|
|||
let mut card = util::open_card(ident)?;
|
||||
let mut txc = card.transaction()?;
|
||||
|
||||
let mut open = Open::new(&mut txc)?;
|
||||
let mut open = Open::new(&mut *txc)?;
|
||||
|
||||
let mut sign = util::verify_to_sign(&mut open, pin_file)?;
|
||||
let s = sign.signer(&cert)?;
|
||||
|
@ -381,7 +382,7 @@ fn factory_reset(ident: &str) -> Result<()> {
|
|||
let mut card = util::open_card(ident)?;
|
||||
let mut txc = card.transaction()?;
|
||||
|
||||
Open::new(&mut txc)?.factory_reset()
|
||||
Open::new(&mut *txc)?.factory_reset()
|
||||
}
|
||||
|
||||
fn key_import_yolo(mut admin: Admin, key: &Cert) -> Result<()> {
|
||||
|
|
Loading…
Reference in a new issue