diff --git a/openpgp-card-sequoia/Cargo.toml b/openpgp-card-sequoia/Cargo.toml index 1936c47..fdccf11 100644 --- a/openpgp-card-sequoia/Cargo.toml +++ b/openpgp-card-sequoia/Cargo.toml @@ -5,13 +5,14 @@ name = "openpgp-card-sequoia" description = "Wrapper of openpgp-card for use with Sequoia PGP" license = "MIT OR Apache-2.0" -version = "0.1.5" +version = "0.2.0-pre" authors = ["Heiko Schaefer "] edition = "2018" repository = "https://gitlab.com/openpgp-card/openpgp-card" documentation = "https://docs.rs/crate/openpgp-card-sequoia" [dependencies] +card-backend = { path = "../card-backend", version = "0.1" } sequoia-openpgp = { version = "1.4", default-features = false } openpgp-card = { path = "../openpgp-card", version = "0.4" } chrono = "0.4" @@ -21,8 +22,8 @@ log = "0.4" rsa = "0.8.1" [dev-dependencies] -openpgp-card-pcsc = { path = "../pcsc", version = "0.3" } -#openpgp-card-scdc = { path = "../scdc", version = "0.3" } +card-backend-pcsc = { path = "../pcsc", version = "0.4" } +#card-backend-scdc = { path = "../scdc", version = "0.4" } env_logger = "0.10" testresult = "0.3.0" diff --git a/openpgp-card-sequoia/src/lib.rs b/openpgp-card-sequoia/src/lib.rs index 8b7b07c..2a3accc 100644 --- a/openpgp-card-sequoia/src/lib.rs +++ b/openpgp-card-sequoia/src/lib.rs @@ -16,17 +16,17 @@ //! # Backends //! //! To make use of this crate, you need to use a backend for communication -//! with cards. The suggested default backend is `openpgp-card-pcsc`. +//! with cards. The suggested default backend is `card-backend-pcsc`. //! -//! With `openpgp-card-pcsc` you can either open all available cards: +//! With `card-backend-pcsc` you can either open all available cards: //! //! ```no_run -//! use openpgp_card_pcsc::PcscBackend; +//! use card_backend_pcsc::PcscBackend; //! use openpgp_card_sequoia::{state::Open, Card}; //! //! # fn main() -> Result<(), Box> { //! for backend in PcscBackend::cards(None)? { -//! let mut card: Card = backend.into(); +//! let mut card = Card::::new(backend?)?; //! let mut transaction = card.transaction()?; //! println!( //! "Found OpenPGP card with ident '{}'", @@ -40,12 +40,12 @@ //! Or you can open one particular card, by ident: //! //! ```no_run -//! use openpgp_card_pcsc::PcscBackend; +//! use card_backend_pcsc::PcscBackend; //! use openpgp_card_sequoia::{state::Open, Card}; //! //! # fn main() -> Result<(), Box> { -//! let backend = PcscBackend::open_by_ident("abcd:01234567", None)?; -//! let mut card: Card = backend.into(); +//! let cards = PcscBackend::card_backends(None)?; +//! let mut card = Card::::open_by_ident(cards, "abcd:01234567")?; //! let mut transaction = card.transaction()?; //! # Ok(()) //! # } @@ -60,13 +60,13 @@ //! implementation can then be obtained: //! //! ```no_run -//! use openpgp_card_pcsc::PcscBackend; +//! use card_backend_pcsc::PcscBackend; //! use openpgp_card_sequoia::{state::Open, Card}; //! # fn main() -> Result<(), Box> { //! // Open card via PCSC //! use sequoia_openpgp::policy::StandardPolicy; -//! let backend = PcscBackend::open_by_ident("abcd:01234567", None)?; -//! let mut card: Card = backend.into(); +//! let cards = PcscBackend::card_backends(None)?; +//! let mut card = Card::::open_by_ident(cards, "abcd:01234567")?; //! let mut transaction = card.transaction()?; //! //! // Get authorization for user access to the card with password @@ -95,13 +95,13 @@ //! user password before each signing operation!) //! //! ```no_run -//! use openpgp_card_pcsc::PcscBackend; +//! use card_backend_pcsc::PcscBackend; //! use openpgp_card_sequoia::{state::Open, Card}; //! //! # fn main() -> Result<(), Box> { //! // Open card via PCSC -//! let backend = PcscBackend::open_by_ident("abcd:01234567", None)?; -//! let mut card: Card = backend.into(); +//! let cards = PcscBackend::card_backends(None)?; +//! let mut card = Card::::open_by_ident(cards, "abcd:01234567")?; //! let mut transaction = card.transaction()?; //! //! // Get authorization for signing access to the card with password @@ -121,13 +121,13 @@ //! # Setting up and configuring a card //! //! ```no_run -//! use openpgp_card_pcsc::PcscBackend; +//! use card_backend_pcsc::PcscBackend; //! use openpgp_card_sequoia::{state::Open, Card}; //! //! # fn main() -> Result<(), Box> { //! // Open card via PCSC -//! let backend = PcscBackend::open_by_ident("abcd:01234567", None)?; -//! let mut card: Card = backend.into(); +//! let cards = PcscBackend::card_backends(None)?; +//! let mut card = Card::::open_by_ident(cards, "abcd:01234567")?; //! let mut transaction = card.transaction()?; //! //! // Get authorization for admin access to the card with password @@ -142,6 +142,7 @@ //! # } //! ``` +use card_backend::{CardBackend, SmartcardError}; use openpgp_card::algorithm::{Algo, AlgoInfo, AlgoSimple}; use openpgp_card::card_do::{ ApplicationIdentifier, CardholderRelatedData, ExtendedCapabilities, ExtendedLengthInfo, @@ -149,7 +150,7 @@ use openpgp_card::card_do::{ SecuritySupportTemplate, Sex, TouchPolicy, UIF, }; use openpgp_card::crypto_data::PublicKeyMaterial; -use openpgp_card::{CardBackend, Error, KeySet, KeyType, OpenPgp, OpenPgpTransaction}; +use openpgp_card::{Error, KeySet, KeyType, OpenPgp, OpenPgpTransaction}; use sequoia_openpgp::cert::prelude::ValidErasedKeyAmalgamation; use sequoia_openpgp::packet::key::SecretParts; use sequoia_openpgp::packet::{key, Key}; @@ -188,20 +189,38 @@ where state: S, } -impl From for Card -where - B: Into>, -{ - fn from(backend: B) -> Self { - let pgp = OpenPgp::new(backend.into()); - - Card:: { - state: Open { pgp }, - } - } -} - impl Card { + pub fn open_by_ident( + cards: impl Iterator, SmartcardError>>, + ident: &str, + ) -> Result { + for b in cards.filter_map(|c| c.ok()) { + let mut card = Self::new(b)?; + + let aid = { + let tx = card.transaction()?; + tx.state.ard.application_id()? + }; + + if aid.ident() == ident.to_ascii_uppercase() { + return Ok(card); + } + } + + Err(Error::NotFound(format!("Couldn't find card {}", ident))) + } + + pub fn new(backend: B) -> Result + where + B: Into>, + { + let pgp = OpenPgp::new(backend)?; + + Ok(Card:: { + state: Open { pgp }, + }) + } + pub fn transaction(&mut self) -> Result, Error> { let opt = self.state.pgp.transaction()?; diff --git a/openpgp-card-sequoia/src/types.rs b/openpgp-card-sequoia/src/types.rs index dfe0764..1bad2b2 100644 --- a/openpgp-card-sequoia/src/types.rs +++ b/openpgp-card-sequoia/src/types.rs @@ -6,4 +6,4 @@ pub use openpgp_card::algorithm::{Algo, AlgoSimple, Curve}; pub use openpgp_card::card_do::{Sex, TouchPolicy}; pub use openpgp_card::crypto_data::{EccType, PublicKeyMaterial}; -pub use openpgp_card::{CardBackend, Error, KeyType, StatusBytes}; +pub use openpgp_card::{Error, KeyType, StatusBytes};