diff --git a/bitkeylib/client.py b/bitkeylib/client.py index 095c0e12a9..346a342aa7 100644 --- a/bitkeylib/client.py +++ b/bitkeylib/client.py @@ -1,8 +1,7 @@ import os import time -import bitkey_pb2 as proto -import random +import trezor_pb2 as proto def show_message(message): print "MESSAGE FROM DEVICE:", message @@ -40,8 +39,7 @@ class BitkeyClient(object): def init_device(self): self.master_public_key = None - self.session_id = ''.join([ chr(random.randrange(0, 255, 1)) for _ in xrange(0, 16) ]) - self.features = self.call(proto.Initialize(session_id=self.session_id)) + self.features = self.call(proto.Initialize()) self.uuid = self.get_uuid() def get_master_public_key(self): @@ -60,10 +58,9 @@ class BitkeyClient(object): def _pprint(self, msg): return "<%s>:\n%s" % (msg.__class__.__name__, msg) - def setup_debuglink(self, button=None, pin_correct=False, otp_correct=False): + def setup_debuglink(self, button=None, pin_correct=False): self.debug_button = button self.debug_pin = pin_correct - self.debug_otp = otp_correct def call(self, msg): if self.debug: @@ -79,40 +76,24 @@ class BitkeyClient(object): self.debuglink.press_button(self.debug_button) return self.call(proto.ButtonAck()) - - if isinstance(resp, proto.OtpRequest): + + if isinstance(resp, proto.PinMatrixRequest): if self.debuglink: - otp = self.debuglink.read_otp() - if self.debug_otp: - msg2 = otp - else: - msg2 = proto.OtpAck(otp='__42__') - else: - otp = self.input_func("OTP required: ", resp.message) - msg2 = proto.OtpAck(otp=otp) - - return self.call(msg2) - - if isinstance(resp, proto.PinRequest): - if self.debuglink: - pin = self.debuglink.read_pin() if self.debug_pin: - msg2 = pin + pin = self.debuglink.read_pin() + msg2 = proto.PinMatrixAck(pin=pin) else: - msg2 = proto.PinAck(pin='__42__') + msg2 = proto.PinMatrixAck(pin='__42__') else: pin = self.input_func("PIN required: ", resp.message) - msg2 = proto.PinAck(pin=pin) + msg2 = proto.PinMatrixAck(pin=pin) return self.call(msg2) if isinstance(resp, proto.Failure): self.message_func(resp.message) - if resp.code == 3: - raise OtpException("OTP is invalid") - - elif resp.code == 4: + if resp.code == 4: raise CallException("Action cancelled by user") elif resp.code == 6: @@ -233,15 +214,12 @@ class BitkeyClient(object): def reset_device(self): # Begin with device reset workflow + raise Exception("Not implemented") resp = self.call(proto.ResetDevice(random=self._get_local_entropy())) self.init_device() return isinstance(resp, proto.Success) - def load_device(self, algo, seed, otp, pin, spv): - if not self.debuglink: - raise Exception("DebugLink not available") - - if not self.debuglink.load_device(algo, seed, otp, pin, spv): - return False + def load_device(self, seed, pin): + resp = self.call(proto.LoadDevice(seed=seed, pin=pin)) self.init_device() - return True \ No newline at end of file + return isinstance(resp, proto.Success) \ No newline at end of file diff --git a/bitkeylib/debuglink.py b/bitkeylib/debuglink.py index b7043fd10a..0e459dac68 100644 --- a/bitkeylib/debuglink.py +++ b/bitkeylib/debuglink.py @@ -1,43 +1,35 @@ -import bitkey_pb2 as proto +import trezor_pb2 as proto from transport import NotImplementedException -def otp_info(otp): - print "Device asks for OTP %s" % otp.otp - def pin_info(pin): - print "Device asks for PIN %s" % pin.pin + print "Device asks for PIN %s" % pin def button_press(yes_no): print "User pressed", '"y"' if yes_no else '"n"' class DebugLink(object): - def __init__(self, transport, otp_func=otp_info, pin_func=pin_info, button_func=button_press): + def __init__(self, transport, pin_func=pin_info, button_func=button_press): self.transport = transport - self.otp_func = otp_func self.pin_func = pin_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 load_device(self, algo, seed, otp, pin, spv): - self.transport.write(proto.LoadDevice(algo=algo, seed=seed, otp=otp, pin=pin, spv=spv)) - resp = self.transport.read_blocking() - return isinstance(resp, proto.Success) - - def read_otp(self): - obj = self.get_state(otp=True).otp - print "Read OTP:", obj.otp - self.otp_func(obj) - return obj - def read_pin(self): - obj = self.get_state(pin=True).pin + self.transport.write(proto.DebugLinkGetState(pin=True, matrix=True)) + obj = self.transport.read_blocking() print "Read PIN:", obj.pin - self.pin_func(obj) - return obj + print "Read matrix:", obj.matrix + + # Now we have real PIN and PIN matrix. + # We have to encode that into encoded pin, + # because application must send back positions + # on keypad, not a real PIN. + pin_encoded = ''.join([ str(obj.matrix.index(p) + 1) for p in obj.pin]) + + print "Encoded PIN:", pin_encoded + self.pin_func(pin_encoded) + + return pin_encoded def press_button(self, yes_no): print "Pressing", yes_no