Skip to content

Commit 997dadc

Browse files
Fix support for PCSC smartcard readers
1 parent 4d2fafc commit 997dadc

File tree

2 files changed

+31
-43
lines changed

2 files changed

+31
-43
lines changed

ledgerblue/comm.py

Lines changed: 29 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424

2525
import hid
2626
import nfc
27+
from smartcard.System import readers
28+
from smartcard.util import toBytes
2729

2830
from .BleComm import BleDevice
2931
from .commException import CommException
@@ -68,13 +70,6 @@
6870
PCSC = None
6971
if "PCSC" in os.environ and len(os.environ["PCSC"]) != 0:
7072
PCSC = os.environ["PCSC"]
71-
if PCSC:
72-
try:
73-
from smartcard.System import readers
74-
from smartcard.util import toBytes
75-
except ImportError:
76-
PCSC = False
77-
7873

7974
def get_possible_error_cause(sw):
8075
cause_map = {
@@ -268,11 +263,11 @@ def __init__(self, device, debug=False):
268263

269264
def exchange(self, apdu, timeout=TIMEOUT):
270265
if self.debug:
271-
print("SC => %s" % apdu.hex())
272-
response, sw1, sw2 = self.device.transmit(toBytes(hexlify(apdu)))
266+
print(f"[SC] => {apdu.hex()}")
267+
response, sw1, sw2 = self.device.transmit(list(apdu))
273268
sw = (sw1 << 8) | sw2
274269
if self.debug:
275-
print("SC <= %s%.2x" % (response.hex(), sw))
270+
print("[SC] <= %s%.2x" % (bytes(response).hex(), sw))
276271
if sw != 0x9000 and (sw & 0xFF00) != 0x6100 and (sw & 0xFF00) != 0x6C00:
277272
raise CommException("Invalid status %04x" % sw, sw, bytearray(response))
278273
return bytearray(response)
@@ -286,7 +281,7 @@ def close(self):
286281
self.opened = False
287282

288283

289-
def getDongle(debug=False, selectCommand=None):
284+
def getDongle(debug=False):
290285
if APDUGEN:
291286
return HIDDongleHIDAPI(None, True, debug)
292287

@@ -300,45 +295,37 @@ def getDongle(debug=False, selectCommand=None):
300295
return DongleNFC(debug)
301296
elif BLE_PROXY:
302297
return DongleBLE(debug)
303-
dev = None
304-
hidDevicePath = None
305-
ledger = True
306-
for hidDevice in hid.enumerate(0, 0):
307-
if hidDevice["vendor_id"] == 0x2C97:
308-
if (
309-
"interface_number" in hidDevice and hidDevice["interface_number"] == 0
310-
) or ("usage_page" in hidDevice and hidDevice["usage_page"] == 0xFFA0):
311-
hidDevicePath = hidDevice["path"]
312-
313-
usb_port = os.getenv("LEDGER_PROXY_USB_PORT")
314-
if usb_port:
315-
hidDevicePath = usb_port.encode()
316-
if hidDevicePath is not None:
317-
dev = hid.device()
318-
dev.open_path(hidDevicePath)
319-
dev.set_nonblocking(True)
320-
return HIDDongleHIDAPI(dev, ledger, debug)
321-
if PCSC:
298+
elif PCSC:
299+
# Use the first pcsc reader with a card inserted
322300
connection = None
323301
for reader in readers():
324302
try:
325303
connection = reader.createConnection()
326304
connection.connect()
327-
if selectCommand is not None:
328-
response, sw1, sw2 = connection.transmit(
329-
toBytes("00A4040010FF4C4547522E57414C5430312E493031")
330-
)
331-
sw = (sw1 << 8) | sw2
332-
if sw == 0x9000:
333-
break
334-
else:
335-
connection.disconnect()
336-
connection = None
337-
else:
338-
break
339305
except Exception:
340306
connection = None
341307
pass
342308
if connection is not None:
343309
return DongleSmartcard(connection, debug)
310+
else:
311+
# USB HID by default
312+
dev = None
313+
hidDevicePath = None
314+
ledger = True
315+
for hidDevice in hid.enumerate(0, 0):
316+
if hidDevice["vendor_id"] == 0x2C97:
317+
if (
318+
"interface_number" in hidDevice and hidDevice["interface_number"] == 0
319+
) or ("usage_page" in hidDevice and hidDevice["usage_page"] == 0xFFA0):
320+
hidDevicePath = hidDevice["path"]
321+
322+
usb_port = os.getenv("LEDGER_PROXY_USB_PORT")
323+
if usb_port:
324+
hidDevicePath = usb_port.encode()
325+
if hidDevicePath is not None:
326+
dev = hid.device()
327+
dev.open_path(hidDevicePath)
328+
dev.set_nonblocking(True)
329+
return HIDDongleHIDAPI(dev, ledger, debug)
330+
344331
raise CommException("No dongle found")

pyproject.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ dependencies = [
4343
"nfcpy>=1.0.4",
4444
"bleak>=0.20.1",
4545
"pycryptodome>=3.18.0",
46-
"python-gnupg>=0.5.0"
46+
"python-gnupg>=0.5.0",
47+
"pyscard>=2.2.2"
4748
]
4849

4950
[tool.setuptools]

0 commit comments

Comments
 (0)