Make ShareMode an optional parameter when opening cards via pcsc.
This commit is contained in:
parent
e92cad5b6a
commit
7573361836
9 changed files with 67 additions and 43 deletions
|
@ -5,12 +5,15 @@
|
||||||
//! TestConfig configuration file
|
//! TestConfig configuration file
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
use pcsc::ShareMode;
|
||||||
use serde_derive::Deserialize;
|
use serde_derive::Deserialize;
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
use openpgp_card_pcsc::PcscCard;
|
use openpgp_card_pcsc::PcscCard;
|
||||||
use openpgp_card_scdc::ScdClient;
|
use openpgp_card_scdc::ScdClient;
|
||||||
|
|
||||||
|
const SHARE_MODE: Option<ShareMode> = Some(ShareMode::Shared);
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
pub struct TestConfig {
|
pub struct TestConfig {
|
||||||
card: BTreeMap<String, Card>,
|
card: BTreeMap<String, Card>,
|
||||||
|
@ -96,7 +99,7 @@ impl TestCard {
|
||||||
let res = ScdClient::shutdown_scd(None);
|
let res = ScdClient::shutdown_scd(None);
|
||||||
log::trace!(" Attempt to shutdown scd: {:?}", res);
|
log::trace!(" Attempt to shutdown scd: {:?}", res);
|
||||||
|
|
||||||
Ok(Box::new(PcscCard::open_by_ident(ident)?))
|
Ok(Box::new(PcscCard::open_by_ident(ident, SHARE_MODE)?))
|
||||||
}
|
}
|
||||||
Self::Scdc(serial) => {
|
Self::Scdc(serial) => {
|
||||||
unimplemented!();
|
unimplemented!();
|
||||||
|
|
|
@ -9,7 +9,7 @@ use openpgp_card_sequoia::card::Open;
|
||||||
fn main() -> Result<()> {
|
fn main() -> Result<()> {
|
||||||
println!("The following OpenPGP cards are connected to your system:");
|
println!("The following OpenPGP cards are connected to your system:");
|
||||||
|
|
||||||
for mut card in PcscCard::cards()? {
|
for mut card in PcscCard::cards(None)? {
|
||||||
let mut txc: TxClient = openpgp_card_pcsc::get_txc!(card)?;
|
let mut txc: TxClient = openpgp_card_pcsc::get_txc!(card)?;
|
||||||
|
|
||||||
let open = Open::new(&mut txc)?;
|
let open = Open::new(&mut txc)?;
|
||||||
|
|
|
@ -22,7 +22,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let pin_file = &args[1];
|
let pin_file = &args[1];
|
||||||
let cert_file = &args[2];
|
let cert_file = &args[2];
|
||||||
|
|
||||||
let mut card = PcscCard::open_by_ident(card_ident)?;
|
let mut card = PcscCard::open_by_ident(card_ident, None)?;
|
||||||
let mut txc = get_txc!(card)?;
|
let mut txc = get_txc!(card)?;
|
||||||
|
|
||||||
let mut open = Open::new(&mut txc)?;
|
let mut open = Open::new(&mut txc)?;
|
||||||
|
|
|
@ -22,7 +22,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let pin_file = &args[1];
|
let pin_file = &args[1];
|
||||||
let cert_file = &args[2];
|
let cert_file = &args[2];
|
||||||
|
|
||||||
let mut card = PcscCard::open_by_ident(card_ident)?;
|
let mut card = PcscCard::open_by_ident(card_ident, None)?;
|
||||||
let mut txc = get_txc!(card)?;
|
let mut txc = get_txc!(card)?;
|
||||||
|
|
||||||
let mut open = Open::new(&mut txc)?;
|
let mut open = Open::new(&mut txc)?;
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
//! use openpgp_card_pcsc::{get_txc, PcscCard, TxClient};
|
//! use openpgp_card_pcsc::{get_txc, PcscCard, TxClient};
|
||||||
//!
|
//!
|
||||||
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
|
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
//! for mut card in PcscCard::cards()? {
|
//! for mut card in PcscCard::cards(None)? {
|
||||||
//! let mut txc = get_txc!(card)?;
|
//! let mut txc = get_txc!(card)?;
|
||||||
//! let open = Open::new(&mut txc)?;
|
//! let open = Open::new(&mut txc)?;
|
||||||
//! println!("Found OpenPGP card with ident '{}'",
|
//! println!("Found OpenPGP card with ident '{}'",
|
||||||
|
@ -33,7 +33,7 @@
|
||||||
//! use openpgp_card_pcsc::{get_txc, PcscCard, TxClient};
|
//! use openpgp_card_pcsc::{get_txc, PcscCard, TxClient};
|
||||||
//!
|
//!
|
||||||
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
|
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
//! let mut card = PcscCard::open_by_ident("abcd:12345678")?;
|
//! let mut card = PcscCard::open_by_ident("abcd:12345678", None)?;
|
||||||
//! let mut txc = get_txc!(card)?;
|
//! let mut txc = get_txc!(card)?;
|
||||||
//! let mut open = Open::new(&mut txc)?;
|
//! let mut open = Open::new(&mut txc)?;
|
||||||
//! # Ok(())
|
//! # Ok(())
|
||||||
|
@ -56,7 +56,7 @@
|
||||||
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
|
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
//! // Open card via PCSC
|
//! // Open card via PCSC
|
||||||
//! use sequoia_openpgp::policy::StandardPolicy;
|
//! use sequoia_openpgp::policy::StandardPolicy;
|
||||||
//! let mut card = PcscCard::open_by_ident("abcd:12345678")?;
|
//! let mut card = PcscCard::open_by_ident("abcd:12345678", None)?;
|
||||||
//! let mut txc = get_txc!(card)?;
|
//! let mut txc = get_txc!(card)?;
|
||||||
//! let mut open = Open::new(&mut txc)?;
|
//! let mut open = Open::new(&mut txc)?;
|
||||||
//!
|
//!
|
||||||
|
@ -98,7 +98,7 @@
|
||||||
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
|
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
//! // Open card via PCSC
|
//! // Open card via PCSC
|
||||||
//! use sequoia_openpgp::policy::StandardPolicy;
|
//! use sequoia_openpgp::policy::StandardPolicy;
|
||||||
//! let mut card = PcscCard::open_by_ident("abcd:12345678")?;
|
//! let mut card = PcscCard::open_by_ident("abcd:12345678", None)?;
|
||||||
//! let mut txc = get_txc!(card)?;
|
//! let mut txc = get_txc!(card)?;
|
||||||
//! let mut open = Open::new(&mut txc)?;
|
//! let mut open = Open::new(&mut txc)?;
|
||||||
//!
|
//!
|
||||||
|
@ -129,7 +129,7 @@
|
||||||
//!
|
//!
|
||||||
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
|
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
//! // Open card via PCSC
|
//! // Open card via PCSC
|
||||||
//! let mut card = PcscCard::open_by_ident("abcd:12345678")?;
|
//! let mut card = PcscCard::open_by_ident("abcd:12345678", None)?;
|
||||||
//! let mut txc = get_txc!(card)?;
|
//! let mut txc = get_txc!(card)?;
|
||||||
//! let mut open = Open::new(&mut txc)?;
|
//! let mut open = Open::new(&mut txc)?;
|
||||||
//!
|
//!
|
||||||
|
|
|
@ -35,7 +35,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||||
let test_card_ident = env::var("TEST_CARD_IDENT");
|
let test_card_ident = env::var("TEST_CARD_IDENT");
|
||||||
|
|
||||||
if let Ok(test_card_ident) = test_card_ident {
|
if let Ok(test_card_ident) = test_card_ident {
|
||||||
let mut card = PcscCard::open_by_ident(&test_card_ident)?;
|
let mut card = PcscCard::open_by_ident(&test_card_ident, None)?;
|
||||||
let mut txc = openpgp_card_pcsc::get_txc!(card)?;
|
let mut txc = openpgp_card_pcsc::get_txc!(card)?;
|
||||||
|
|
||||||
let mut open = Open::new(&mut txc)?;
|
let mut open = Open::new(&mut txc)?;
|
||||||
|
@ -146,7 +146,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||||
// -----------------------------
|
// -----------------------------
|
||||||
// Open fresh Card for decrypt
|
// Open fresh Card for decrypt
|
||||||
// -----------------------------
|
// -----------------------------
|
||||||
let mut card = PcscCard::open_by_ident(&test_card_ident)?;
|
let mut card = PcscCard::open_by_ident(&test_card_ident, None)?;
|
||||||
let mut txc = openpgp_card_pcsc::get_txc!(card)?;
|
let mut txc = openpgp_card_pcsc::get_txc!(card)?;
|
||||||
|
|
||||||
let mut open = Open::new(&mut txc)?;
|
let mut open = Open::new(&mut txc)?;
|
||||||
|
@ -187,7 +187,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||||
// -----------------------------
|
// -----------------------------
|
||||||
// Open fresh Card for signing
|
// Open fresh Card for signing
|
||||||
// -----------------------------
|
// -----------------------------
|
||||||
let mut card = PcscCard::open_by_ident(&test_card_ident)?;
|
let mut card = PcscCard::open_by_ident(&test_card_ident, None)?;
|
||||||
let mut txc = openpgp_card_pcsc::get_txc!(card)?;
|
let mut txc = openpgp_card_pcsc::get_txc!(card)?;
|
||||||
|
|
||||||
let mut open = Open::new(&mut txc)?;
|
let mut open = Open::new(&mut txc)?;
|
||||||
|
@ -219,7 +219,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||||
|
|
||||||
println!("The following OpenPGP cards are connected to your system:");
|
println!("The following OpenPGP cards are connected to your system:");
|
||||||
|
|
||||||
for mut card in PcscCard::cards()? {
|
for mut card in PcscCard::cards(None)? {
|
||||||
let mut txc = openpgp_card_pcsc::get_txc!(card)?;
|
let mut txc = openpgp_card_pcsc::get_txc!(card)?;
|
||||||
|
|
||||||
let open = Open::new(&mut txc)?;
|
let open = Open::new(&mut txc)?;
|
||||||
|
|
|
@ -22,7 +22,7 @@ const FEATURE_MODIFY_PIN_DIRECT: u8 = 0x07;
|
||||||
macro_rules! get_txc {
|
macro_rules! get_txc {
|
||||||
($card:expr $(, $reselect:expr)? ) => {{
|
($card:expr $(, $reselect:expr)? ) => {{
|
||||||
use openpgp_card::{Error, SmartcardError};
|
use openpgp_card::{Error, SmartcardError};
|
||||||
use pcsc::{Disposition, Protocols, ShareMode};
|
use pcsc::{Disposition, Protocols};
|
||||||
|
|
||||||
#[allow(unused_assignments)]
|
#[allow(unused_assignments)]
|
||||||
let mut reselect = true;
|
let mut reselect = true;
|
||||||
|
@ -34,6 +34,8 @@ macro_rules! get_txc {
|
||||||
|
|
||||||
let card_caps = $card.card_caps();
|
let card_caps = $card.card_caps();
|
||||||
let reader_caps = $card.reader_caps().clone();
|
let reader_caps = $card.reader_caps().clone();
|
||||||
|
let mode = $card.mode();
|
||||||
|
|
||||||
let c = $card.card();
|
let c = $card.card();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
|
@ -78,7 +80,7 @@ macro_rules! get_txc {
|
||||||
|
|
||||||
{
|
{
|
||||||
c.reconnect(
|
c.reconnect(
|
||||||
ShareMode::Shared,
|
mode,
|
||||||
Protocols::ANY,
|
Protocols::ANY,
|
||||||
Disposition::ResetCard,
|
Disposition::ResetCard,
|
||||||
)
|
)
|
||||||
|
@ -105,6 +107,14 @@ macro_rules! get_txc {
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn default_mode(mode: Option<ShareMode>) -> ShareMode {
|
||||||
|
if let Some(mode) = mode {
|
||||||
|
mode
|
||||||
|
} else {
|
||||||
|
ShareMode::Shared
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// An opened PCSC Card (without open transaction).
|
/// An opened PCSC Card (without open transaction).
|
||||||
/// The OpenPGP application on the card is `select`-ed while setting up a PcscCard object.
|
/// The OpenPGP application on the card is `select`-ed while setting up a PcscCard object.
|
||||||
///
|
///
|
||||||
|
@ -113,6 +123,7 @@ macro_rules! get_txc {
|
||||||
/// `TxClient` object needs to be obtained (via the `get_txc!()` macro).
|
/// `TxClient` object needs to be obtained (via the `get_txc!()` macro).
|
||||||
pub struct PcscCard {
|
pub struct PcscCard {
|
||||||
card: Card,
|
card: Card,
|
||||||
|
mode: ShareMode,
|
||||||
card_caps: Option<CardCaps>,
|
card_caps: Option<CardCaps>,
|
||||||
reader_caps: HashMap<u8, Tlv>,
|
reader_caps: HashMap<u8, Tlv>,
|
||||||
}
|
}
|
||||||
|
@ -453,9 +464,13 @@ impl PcscCard {
|
||||||
&mut self.card
|
&mut self.card
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn mode(&self) -> ShareMode {
|
||||||
|
self.mode
|
||||||
|
}
|
||||||
|
|
||||||
/// A list of "raw" opened PCSC Cards (without selecting the OpenPGP card
|
/// A list of "raw" opened PCSC Cards (without selecting the OpenPGP card
|
||||||
/// application)
|
/// application)
|
||||||
fn raw_pcsc_cards() -> Result<Vec<Card>, SmartcardError> {
|
fn raw_pcsc_cards(mode: ShareMode) -> Result<Vec<Card>, SmartcardError> {
|
||||||
let ctx = match Context::establish(Scope::User) {
|
let ctx = match Context::establish(Scope::User) {
|
||||||
Ok(ctx) => ctx,
|
Ok(ctx) => ctx,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
|
@ -488,23 +503,22 @@ impl PcscCard {
|
||||||
log::debug!("Checking reader: {:?}", reader);
|
log::debug!("Checking reader: {:?}", reader);
|
||||||
|
|
||||||
// Try connecting to card in this reader
|
// Try connecting to card in this reader
|
||||||
let card =
|
let card = match ctx.connect(reader, mode, Protocols::ANY) {
|
||||||
match ctx.connect(reader, ShareMode::Shared, Protocols::ANY) {
|
Ok(card) => card,
|
||||||
Ok(card) => card,
|
Err(pcsc::Error::NoSmartcard) => {
|
||||||
Err(pcsc::Error::NoSmartcard) => {
|
log::debug!("No Smartcard");
|
||||||
log::debug!("No Smartcard");
|
|
||||||
|
|
||||||
continue; // try next reader
|
continue; // try next reader
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
log::warn!(
|
log::warn!(
|
||||||
"Error connecting to card in reader: {:x?}",
|
"Error connecting to card in reader: {:x?}",
|
||||||
err
|
err
|
||||||
);
|
);
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
log::debug!("Found card");
|
log::debug!("Found card");
|
||||||
|
|
||||||
|
@ -522,11 +536,14 @@ impl PcscCard {
|
||||||
/// application identity with `ident` (if `ident` is None, all Cards are
|
/// application identity with `ident` (if `ident` is None, all Cards are
|
||||||
/// returned). Returns fully initialized PcscCard structs for all matching
|
/// returned). Returns fully initialized PcscCard structs for all matching
|
||||||
/// cards.
|
/// cards.
|
||||||
fn cards_filter(ident: Option<&str>) -> Result<Vec<PcscCard>, Error> {
|
fn cards_filter(
|
||||||
|
ident: Option<&str>,
|
||||||
|
mode: ShareMode,
|
||||||
|
) -> Result<Vec<PcscCard>, Error> {
|
||||||
let mut cas: Vec<PcscCard> = vec![];
|
let mut cas: Vec<PcscCard> = vec![];
|
||||||
|
|
||||||
for mut card in
|
for mut card in
|
||||||
Self::raw_pcsc_cards().map_err(|sce| Error::Smartcard(sce))?
|
Self::raw_pcsc_cards(mode).map_err(|sce| Error::Smartcard(sce))?
|
||||||
{
|
{
|
||||||
log::debug!("cards_filter: next card");
|
log::debug!("cards_filter: next card");
|
||||||
|
|
||||||
|
@ -537,7 +554,7 @@ impl PcscCard {
|
||||||
{
|
{
|
||||||
// start transaction
|
// start transaction
|
||||||
log::debug!("1");
|
log::debug!("1");
|
||||||
let mut p = PcscCard::new(card);
|
let mut p = PcscCard::new(card, mode);
|
||||||
let mut txc: TxClient = get_txc!(p, false)?;
|
let mut txc: TxClient = get_txc!(p, false)?;
|
||||||
|
|
||||||
log::debug!("3");
|
log::debug!("3");
|
||||||
|
@ -607,7 +624,7 @@ impl PcscCard {
|
||||||
}
|
}
|
||||||
|
|
||||||
if store_card {
|
if store_card {
|
||||||
let pcsc = PcscCard::new(card);
|
let pcsc = PcscCard::new(card, mode);
|
||||||
cas.push(pcsc.initialize_card()?);
|
cas.push(pcsc.initialize_card()?);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -621,17 +638,20 @@ impl PcscCard {
|
||||||
///
|
///
|
||||||
/// Each card has the OpenPGP application selected, card_caps and reader_caps have been
|
/// Each card has the OpenPGP application selected, card_caps and reader_caps have been
|
||||||
/// initialized.
|
/// initialized.
|
||||||
pub fn cards() -> Result<Vec<PcscCard>, Error> {
|
pub fn cards(mode: Option<ShareMode>) -> Result<Vec<PcscCard>, Error> {
|
||||||
Self::cards_filter(None)
|
Self::cards_filter(None, default_mode(mode))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the OpenPGP card that matches `ident`, if it is available.
|
/// Returns the OpenPGP card that matches `ident`, if it is available.
|
||||||
/// A fully initialized PcscCard is returned: the OpenPGP application has
|
/// A fully initialized PcscCard is returned: the OpenPGP application has
|
||||||
/// been selected, card_caps and reader_caps have been initialized.
|
/// been selected, card_caps and reader_caps have been initialized.
|
||||||
pub fn open_by_ident(ident: &str) -> Result<PcscCard, Error> {
|
pub fn open_by_ident(
|
||||||
|
ident: &str,
|
||||||
|
mode: Option<ShareMode>,
|
||||||
|
) -> Result<PcscCard, Error> {
|
||||||
log::debug!("open_by_ident for {:?}", ident);
|
log::debug!("open_by_ident for {:?}", ident);
|
||||||
|
|
||||||
let mut cards = Self::cards_filter(Some(ident))?;
|
let mut cards = Self::cards_filter(Some(ident), default_mode(mode))?;
|
||||||
|
|
||||||
if !cards.is_empty() {
|
if !cards.is_empty() {
|
||||||
// FIXME: handle >1 cards found
|
// FIXME: handle >1 cards found
|
||||||
|
@ -644,9 +664,10 @@ impl PcscCard {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new(card: Card) -> Self {
|
fn new(card: Card, mode: ShareMode) -> Self {
|
||||||
Self {
|
Self {
|
||||||
card,
|
card,
|
||||||
|
mode,
|
||||||
card_caps: None,
|
card_caps: None,
|
||||||
reader_caps: HashMap::new(),
|
reader_caps: HashMap::new(),
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
|
||||||
let cli = cli::Cli::from_args();
|
let cli = cli::Cli::from_args();
|
||||||
|
|
||||||
let mut card = PcscCard::open_by_ident(&cli.ident)?;
|
let mut card = PcscCard::open_by_ident(&cli.ident, None)?;
|
||||||
let mut txc = get_txc!(card)?;
|
let mut txc = get_txc!(card)?;
|
||||||
|
|
||||||
let pinpad_verify = txc.feature_pinpad_verify();
|
let pinpad_verify = txc.feature_pinpad_verify();
|
||||||
|
|
|
@ -9,11 +9,11 @@ use openpgp_card_pcsc::PcscCard;
|
||||||
use openpgp_card_sequoia::card::{Admin, Open, Sign, User};
|
use openpgp_card_sequoia::card::{Admin, Open, Sign, User};
|
||||||
|
|
||||||
pub(crate) fn cards() -> Result<Vec<PcscCard>, Error> {
|
pub(crate) fn cards() -> Result<Vec<PcscCard>, Error> {
|
||||||
PcscCard::cards()
|
PcscCard::cards(None)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn open_card(ident: &str) -> Result<PcscCard, Error> {
|
pub(crate) fn open_card(ident: &str) -> Result<PcscCard, Error> {
|
||||||
PcscCard::open_by_ident(ident)
|
PcscCard::open_by_ident(ident, None)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn verify_to_user<'app, 'open>(
|
pub(crate) fn verify_to_user<'app, 'open>(
|
||||||
|
|
Loading…
Reference in a new issue