from typing import Union from public import public from smartcard.CardConnection import CardConnection from smartcard.System import readers from smartcard.pcsc.PCSCCardConnection import PCSCCardConnection from smartcard.pcsc.PCSCReader import PCSCReader from .ISO7816 import ISO7816Target, CommandAPDU, ResponseAPDU @public class PCSCTarget(ISO7816Target): # pragma: no cover """A smartcard target communicating via PCSC.""" def __init__(self, reader: Union[str, PCSCReader]): if isinstance(reader, str): rs = readers() for r in rs: if r.name == reader: self.reader = r break else: raise ValueError("Reader '{}' not found.".format(reader)) else: self.reader = reader self.connection: PCSCCardConnection = self.reader.createConnection() def connect(self): self.connection.connect(CardConnection.T0_protocol | CardConnection.T1_protocol) @property def atr(self) -> bytes: return bytes(self.connection.getATR()) def select(self, aid: bytes) -> bool: apdu = CommandAPDU(0x00, 0xa4, 0x04, 0x00, aid) resp = self.send_apdu(apdu) return resp.sw == 0x9000 def send_apdu(self, apdu: CommandAPDU) -> ResponseAPDU: resp, sw1, sw2 = self.connection.transmit(bytes(apdu)) return ResponseAPDU(bytes(resp), sw1 << 8 | sw2) def disconnect(self): self.connection.disconnect()