pcsc: add fn PcscBackend::activate_terminated_card()

This commit is contained in:
Heiko Schaefer 2023-05-01 18:06:43 +02:00
parent 806918b939
commit cf5090bbc6
No known key found for this signature in database
GPG key ID: 4A849A1904CCBD7D
2 changed files with 33 additions and 1 deletions

View file

@ -12,7 +12,7 @@ repository = "https://gitlab.com/openpgp-card/openpgp-card"
documentation = "https://docs.rs/crate/openpgp-card-pcsc" documentation = "https://docs.rs/crate/openpgp-card-pcsc"
[dependencies] [dependencies]
openpgp-card = { path = "../openpgp-card", version = "0.3" } openpgp-card = { path = "../openpgp-card", version = "0.3.5" }
iso7816-tlv = "0.4" iso7816-tlv = "0.4"
pcsc = "2.7" pcsc = "2.7"
log = "0.4" log = "0.4"

View file

@ -646,6 +646,38 @@ impl PcscBackend {
fn reader_caps(&self) -> HashMap<u8, Tlv> { fn reader_caps(&self) -> HashMap<u8, Tlv> {
self.reader_caps.clone() self.reader_caps.clone()
} }
/// This command will try to activate an OpenPGP card, if:
/// - exactly one card is connected to the system
/// - that card replies to SELECT with Status 6285
///
/// See OpenPGP card spec (version 3.4.1): 7.2.17 ACTIVATE FILE
pub fn activate_terminated_card() -> Result<(), Error> {
let mut cards =
Self::raw_pcsc_cards(pcsc::ShareMode::Exclusive).map_err(Error::Smartcard)?;
if cards.len() != 1 {
return Err(Error::InternalError(format!(
"This command is only allowed if exactly one card is connected, found {}.",
cards.len()
)));
}
let card = cards.pop().unwrap();
let mut backend = PcscBackend::new(card, pcsc::ShareMode::Exclusive);
let mut card_tx = Box::new(PcscTransaction::new(&mut backend, false)?);
match <dyn CardTransaction>::select(&mut card_tx) {
Err(Error::CardStatus(openpgp_card::StatusBytes::TerminationState)) => {
let _ = <dyn CardTransaction>::activate_file(&mut card_tx)?;
Ok(())
}
_ => Err(Error::InternalError(
"Card doesn't appear to be terminated.".to_string(),
)),
}
}
} }
impl CardBackend for PcscBackend { impl CardBackend for PcscBackend {