Removed OTP constructs.

Implements PinMatrix.
Codebase now reflects latest protobuf changes
pull/1/head
slush 11 years ago
parent 5db17b3a6d
commit 5b214bbed2

@ -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 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 isinstance(resp, proto.PinMatrixRequest):
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
return isinstance(resp, proto.Success)

@ -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

Loading…
Cancel
Save