aboutsummaryrefslogtreecommitdiff
path: root/pyecsca/sca/target/PCSC.py
diff options
context:
space:
mode:
authorJ08nY2020-02-09 22:51:38 +0100
committerJ08nY2020-02-09 22:52:26 +0100
commit0d2311a18fd03c0d17393cf4cc92b05a2b8b4e45 (patch)
treee6326f22eb1135d04aee10c3efe7b7345faa6089 /pyecsca/sca/target/PCSC.py
parent2b8f3752505c3a03f617534ebfadd7fb70e09ba2 (diff)
downloadpyecsca-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.py46
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()