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

Removed OTP constructs.

Implements PinMatrix.
Codebase now reflects latest protobuf changes
This commit is contained in:
slush 2013-09-01 02:46:53 +02:00
parent 5db17b3a6d
commit 5b214bbed2
2 changed files with 31 additions and 61 deletions

View File

@ -1,8 +1,7 @@
import os import os
import time import time
import bitkey_pb2 as proto import trezor_pb2 as proto
import random
def show_message(message): def show_message(message):
print "MESSAGE FROM DEVICE:", message print "MESSAGE FROM DEVICE:", message
@ -40,8 +39,7 @@ class BitkeyClient(object):
def init_device(self): def init_device(self):
self.master_public_key = None 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())
self.features = self.call(proto.Initialize(session_id=self.session_id))
self.uuid = self.get_uuid() self.uuid = self.get_uuid()
def get_master_public_key(self): def get_master_public_key(self):
@ -60,10 +58,9 @@ 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, button=None, pin_correct=False, otp_correct=False): def setup_debuglink(self, button=None, pin_correct=False):
self.debug_button = button self.debug_button = button
self.debug_pin = pin_correct self.debug_pin = pin_correct
self.debug_otp = otp_correct
def call(self, msg): def call(self, msg):
if self.debug: if self.debug:
@ -79,40 +76,24 @@ class BitkeyClient(object):
self.debuglink.press_button(self.debug_button) self.debuglink.press_button(self.debug_button)
return self.call(proto.ButtonAck()) return self.call(proto.ButtonAck())
if isinstance(resp, proto.OtpRequest): if isinstance(resp, proto.PinMatrixRequest):
if self.debuglink: 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: if self.debug_pin:
msg2 = pin pin = self.debuglink.read_pin()
msg2 = proto.PinMatrixAck(pin=pin)
else: else:
msg2 = proto.PinAck(pin='__42__') msg2 = proto.PinMatrixAck(pin='__42__')
else: else:
pin = self.input_func("PIN required: ", resp.message) pin = self.input_func("PIN required: ", resp.message)
msg2 = proto.PinAck(pin=pin) msg2 = proto.PinMatrixAck(pin=pin)
return self.call(msg2) 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 == 4:
raise OtpException("OTP is invalid")
elif resp.code == 4:
raise CallException("Action cancelled by user") raise CallException("Action cancelled by user")
elif resp.code == 6: elif resp.code == 6:
@ -233,15 +214,12 @@ class BitkeyClient(object):
def reset_device(self): def reset_device(self):
# Begin with device reset workflow # Begin with device reset workflow
raise Exception("Not implemented")
resp = self.call(proto.ResetDevice(random=self._get_local_entropy())) resp = self.call(proto.ResetDevice(random=self._get_local_entropy()))
self.init_device() self.init_device()
return isinstance(resp, proto.Success) return isinstance(resp, proto.Success)
def load_device(self, algo, seed, otp, pin, spv): def load_device(self, seed, pin):
if not self.debuglink: resp = self.call(proto.LoadDevice(seed=seed, pin=pin))
raise Exception("DebugLink not available")
if not self.debuglink.load_device(algo, seed, otp, pin, spv):
return False
self.init_device() self.init_device()
return True return isinstance(resp, proto.Success)

View File

@ -1,43 +1,35 @@
import bitkey_pb2 as proto import trezor_pb2 as proto
from transport import NotImplementedException from transport import NotImplementedException
def otp_info(otp):
print "Device asks for OTP %s" % otp.otp
def pin_info(pin): def pin_info(pin):
print "Device asks for PIN %s" % pin.pin print "Device asks for PIN %s" % 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"'
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, pin_func=pin_info, button_func=button_press):
self.transport = transport self.transport = transport
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 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): 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 print "Read PIN:", obj.pin
self.pin_func(obj) print "Read matrix:", obj.matrix
return obj
# 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): def press_button(self, yes_no):
print "Pressing", yes_no print "Pressing", yes_no