1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-22 23:48:12 +00:00

Implemented Button* messages

This commit is contained in:
slush 2012-12-13 19:05:04 +00:00
parent 1409665302
commit e203d2ef53
2 changed files with 34 additions and 33 deletions

View File

@ -45,21 +45,26 @@ class BitkeyClient(object):
def _pprint(self, msg): def _pprint(self, msg):
return "<%s>:\n%s" % (msg.__class__.__name__, msg) return "<%s>:\n%s" % (msg.__class__.__name__, msg)
def setup_debuglink(self, pin_correct=False, otp_correct=False): def setup_debuglink(self, button=None, pin_correct=False, otp_correct=False):
self.debug_button = button
self.debug_pin = pin_correct self.debug_pin = pin_correct
self.debug_otp = otp_correct self.debug_otp = otp_correct
def call(self, msg, button=None, tries=1): def call(self, msg):
if self.debug: if self.debug:
print '----------------------' print '----------------------'
print "Sending", self._pprint(msg) print "Sending", self._pprint(msg)
self.transport.write(msg) self.transport.write(msg)
resp = self.transport.read_blocking()
if self.debuglink and button != None: if isinstance(resp, proto.ButtonRequest):
self.debuglink.press_button(button) if self.debuglink and self.debug_button:
print "Pressing button", self.debug_button
self.debuglink.press_button(self.debug_button)
resp = self.transport.read() self.transport.write(proto.ButtonAck())
resp = self.transport.read_blocking()
if isinstance(resp, proto.OtpRequest): if isinstance(resp, proto.OtpRequest):
if self.debuglink: if self.debuglink:
@ -72,7 +77,7 @@ class BitkeyClient(object):
otp = self.input_func("OTP required: ", resp.message) otp = self.input_func("OTP required: ", resp.message)
msg2 = proto.OtpAck(otp=otp) msg2 = proto.OtpAck(otp=otp)
return self.call(msg2, button, tries) return self.call(msg2)
if isinstance(resp, proto.PinRequest): if isinstance(resp, proto.PinRequest):
if self.debuglink: if self.debuglink:
@ -85,27 +90,20 @@ class BitkeyClient(object):
pin = self.input_func("PIN required: ", resp.message) pin = self.input_func("PIN required: ", resp.message)
msg2 = proto.PinAck(pin=pin) msg2 = proto.PinAck(pin=pin)
return self.call(msg2, button, tries) return self.call(msg2)
if isinstance(resp, proto.Failure): if isinstance(resp, proto.Failure):
self.message_func(resp.message) self.message_func(resp.message)
if resp.code == 3: if resp.code == 3:
if tries <= 1: raise Exception("OTP is invalid")
raise Exception("OTP is invalid, too many retries")
self.message_func("OTP is invalid, let's try again...")
elif resp.code == 4: elif resp.code == 4:
raise Exception("Action cancelled by user") raise Exception("Action cancelled by user")
elif resp.code == 6: elif resp.code == 6:
if tries <= 1: raise Exception("PIN is invalid")
raise Exception("PIN is invalid, too many retries")
self.message_func("PIN is invalid, let's try again...")
return self.call(msg, button, tries-1)
if isinstance(resp, proto.Failure):
raise Exception(resp.code, resp.message) raise Exception(resp.code, resp.message)
if self.debug: if self.debug:
@ -122,6 +120,7 @@ class BitkeyClient(object):
outputs: list of TxOutput outputs: list of TxOutput
''' '''
tx = proto.SignTx() tx = proto.SignTx()
tx.algo = self.algo # Choose BIP32 or ELECTRUM way for deterministic keys tx.algo = self.algo # Choose BIP32 or ELECTRUM way for deterministic keys
tx.random = os.urandom(256) # Provide additional entropy to the device tx.random = os.urandom(256) # Provide additional entropy to the device
@ -159,6 +158,7 @@ class BitkeyClient(object):
return s_inputs return s_inputs
''' '''
def load_device(self, seed, otp, pin, spv, button=None): def load_device(self, seed, otp, pin, spv):
self.call(proto.LoadDevice(seed=seed, otp=otp, pin=pin, spv=spv), button=button) resp = self.call(proto.LoadDevice(seed=seed, otp=otp, pin=pin, spv=spv))
self.init_device() self.init_device()
return isinstance(resp, proto.Success)

View File

@ -1,10 +1,10 @@
import bitkey_pb2 as proto import bitkey_pb2 as proto
def otp_info(otp): def otp_info(otp):
print "Device asks for OTP %s" % otp print "Device asks for OTP %s" % otp.otp
def pin_info(pin): def pin_info(pin):
print "Device asks for PIN %s" % pin print "Device asks for PIN %s" % pin.pin
def button_press(yes_no): def button_press(yes_no):
print "User pressed", '"y"' if yes_no else '"n"' print "User pressed", '"y"' if yes_no else '"n"'
@ -12,30 +12,31 @@ def button_press(yes_no):
class DebugLink(object): class DebugLink(object):
def __init__(self, transport, otp_func=otp_info, pin_func=pin_info, button_func=button_press): def __init__(self, transport, otp_func=otp_info, pin_func=pin_info, button_func=button_press):
self.transport = transport self.transport = transport
self.otp_func = otp_func self.otp_func = otp_func
self.pin_func = pin_func self.pin_func = pin_func
self.button_func = button_func self.button_func = button_func
def get_state(self, otp=False, pin=False):
self.transport.write(proto.DebugLinkGetState(otp=otp, pin=pin))
return self.transport.read_blocking()
def read_otp(self): def read_otp(self):
obj = self.transport.read() obj = self.get_state(otp=True).otp
if not isinstance(obj, proto.OtpAck): print "Read OTP:", obj.otp
raise Exception("Expected OtpAck object, got %s" % obj)
self.otp_func(obj) self.otp_func(obj)
return obj return obj
def read_pin(self): def read_pin(self):
obj = self.transport.read() obj = self.get_state(pin=True).pin
if not isinstance(obj, proto.PinAck): print "Read PIN:", obj.pin
raise Exception("Expected PinAck object, got %s" % obj)
self.pin_func(obj) self.pin_func(obj)
return obj return obj
def press_button(self, yes_no): def press_button(self, yes_no):
print "Pressing", yes_no
self.button_func(yes_no) self.button_func(yes_no)
self.transport.write(proto.DebugLinkDecision(yes_no=yes_no)) self.transport.write(proto.DebugLinkDecision(yes_no=yes_no))
#obj = self.transport.read()
#if not isinstance(obj, proto.Success):
# raise Exception("Expected Success object, got %s" % obj)
def press_yes(self): def press_yes(self):
self.press_button(True) self.press_button(True)