Skip to content
This repository was archived by the owner on Oct 16, 2024. It is now read-only.

Commit 869287a

Browse files
committed
Add proxy transport for emulators and enclaves
1 parent 5fdf6fa commit 869287a

File tree

1 file changed

+60
-17
lines changed

1 file changed

+60
-17
lines changed

btchip/btchipComm.py

Lines changed: 60 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,16 @@
2121
from .btchipException import *
2222
from .ledgerWrapper import wrapCommandAPDU, unwrapResponseAPDU
2323
from binascii import hexlify
24-
import hid
2524
import time
25+
import os
26+
import struct
27+
import socket
28+
29+
try:
30+
import hid
31+
HID = True
32+
except ImportError:
33+
HID = False
2634

2735
try:
2836
from smartcard.Exceptions import NoCardException
@@ -165,29 +173,63 @@ def close(self):
165173
pass
166174
self.opened = False
167175

176+
class DongleServer(Dongle):
177+
178+
def __init__(self, server, port, debug=False):
179+
self.server = server
180+
self.port = port
181+
self.debug = debug
182+
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
183+
try:
184+
self.socket.connect((self.server, self.port))
185+
except:
186+
raise BTChipException("Proxy connection failed")
187+
188+
def exchange(self, apdu, timeout=20000):
189+
if self.debug:
190+
print("=> %s" % hexlify(apdu))
191+
self.socket.send(struct.pack(">I", len(apdu)))
192+
self.socket.send(apdu)
193+
size = struct.unpack(">I", self.socket.recv(4))[0]
194+
response = self.socket.recv(size)
195+
sw = struct.unpack(">H", self.socket.recv(2))[0]
196+
if self.debug:
197+
print("<= %s%.2x" % (hexlify(response), sw))
198+
if sw != 0x9000:
199+
raise BTChipException("Invalid status %04x" % sw, sw)
200+
return bytearray(response)
201+
202+
def close(self):
203+
try:
204+
self.socket.close()
205+
except:
206+
pass
207+
168208
def getDongle(debug=False):
169209
dev = None
170210
hidDevicePath = None
171-
ledger = False
172-
for hidDevice in hid.enumerate(0, 0):
173-
if hidDevice['vendor_id'] == 0x2581 and hidDevice['product_id'] == 0x2b7c:
174-
hidDevicePath = hidDevice['path']
175-
if hidDevice['vendor_id'] == 0x2581 and hidDevice['product_id'] == 0x3b7c:
176-
hidDevicePath = hidDevice['path']
177-
ledger = True
178-
if hidDevice['vendor_id'] == 0x2581 and hidDevice['product_id'] == 0x4b7c:
179-
hidDevicePath = hidDevice['path']
180-
ledger = True
181-
if hidDevice['vendor_id'] == 0x2c97:
182-
hidDevicePath = hidDevice['path']
183-
ledger = True
184-
if hidDevice['vendor_id'] == 0x2581 and hidDevice['product_id'] == 0x1807:
185-
hidDevicePath = hidDevice['path']
211+
ledger = False
212+
if HID:
213+
for hidDevice in hid.enumerate(0, 0):
214+
if hidDevice['vendor_id'] == 0x2581 and hidDevice['product_id'] == 0x2b7c:
215+
hidDevicePath = hidDevice['path']
216+
if hidDevice['vendor_id'] == 0x2581 and hidDevice['product_id'] == 0x3b7c:
217+
hidDevicePath = hidDevice['path']
218+
ledger = True
219+
if hidDevice['vendor_id'] == 0x2581 and hidDevice['product_id'] == 0x4b7c:
220+
hidDevicePath = hidDevice['path']
221+
ledger = True
222+
if hidDevice['vendor_id'] == 0x2c97:
223+
hidDevicePath = hidDevice['path']
224+
ledger = True
225+
if hidDevice['vendor_id'] == 0x2581 and hidDevice['product_id'] == 0x1807:
226+
hidDevicePath = hidDevice['path']
186227
if hidDevicePath is not None:
187228
dev = hid.device()
188229
dev.open_path(hidDevicePath)
189230
dev.set_nonblocking(True)
190231
return HIDDongleHIDAPI(dev, ledger, debug)
232+
191233
if SCARD:
192234
connection = None
193235
for reader in readers():
@@ -206,5 +248,6 @@ def getDongle(debug=False):
206248
pass
207249
if connection is not None:
208250
return DongleSmartcard(connection, debug)
251+
if (os.getenv("LEDGER_PROXY_ADDRESS") is not None) and (os.getenv("LEDGER_PROXY_PORT") is not None):
252+
return DongleServer(os.getenv("LEDGER_PROXY_ADDRESS"), int(os.getenv("LEDGER_PROXY_PORT")), debug)
209253
raise BTChipException("No dongle found")
210-

0 commit comments

Comments
 (0)