diff options
| author | J08nY | 2020-02-09 22:51:38 +0100 |
|---|---|---|
| committer | J08nY | 2020-02-09 22:52:26 +0100 |
| commit | 0d2311a18fd03c0d17393cf4cc92b05a2b8b4e45 (patch) | |
| tree | e6326f22eb1135d04aee10c3efe7b7345faa6089 /pyecsca/sca/target/PCSC.py | |
| parent | 2b8f3752505c3a03f617534ebfadd7fb70e09ba2 (diff) | |
| download | pyecsca-0d2311a18fd03c0d17393cf4cc92b05a2b8b4e45.tar.gz pyecsca-0d2311a18fd03c0d17393cf4cc92b05a2b8b4e45.tar.zst pyecsca-0d2311a18fd03c0d17393cf4cc92b05a2b8b4e45.zip | |
Diffstat (limited to 'pyecsca/sca/target/PCSC.py')
| -rw-r--r-- | pyecsca/sca/target/PCSC.py | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/pyecsca/sca/target/PCSC.py b/pyecsca/sca/target/PCSC.py new file mode 100644 index 0000000..78f92f2 --- /dev/null +++ b/pyecsca/sca/target/PCSC.py @@ -0,0 +1,46 @@ +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() |
