2019-01-04 01:01:59 +00:00
|
|
|
#!/usr/bin/env python
|
|
|
|
# -*- coding: utf-8 -*-
|
2018-12-17 00:05:33 +00:00
|
|
|
#
|
|
|
|
#
|
2018-07-10 03:50:21 +00:00
|
|
|
from __future__ import print_function, absolute_import, unicode_literals
|
2019-01-03 13:27:21 +00:00
|
|
|
from http.server import BaseHTTPRequestHandler, HTTPServer
|
2018-07-10 03:50:21 +00:00
|
|
|
|
|
|
|
from fido2.hid import CtapHidDevice, CTAPHID
|
|
|
|
from fido2.client import Fido2Client, ClientError
|
|
|
|
from fido2.ctap import CtapError
|
|
|
|
from fido2.ctap1 import CTAP1
|
|
|
|
from fido2.ctap2 import *
|
|
|
|
from fido2.cose import *
|
2018-07-15 05:23:38 +00:00
|
|
|
from fido2.utils import Timeout, sha256
|
2018-07-10 03:50:21 +00:00
|
|
|
|
2018-07-15 05:23:38 +00:00
|
|
|
from intelhex import IntelHex
|
|
|
|
|
|
|
|
from ecdsa import SigningKey, NIST256p
|
|
|
|
|
2019-01-03 13:27:21 +00:00
|
|
|
import socket, json, base64, ssl, array, binascii
|
2018-07-10 03:50:21 +00:00
|
|
|
|
2018-12-03 04:31:34 +00:00
|
|
|
from sign_firmware import *
|
|
|
|
|
2018-07-10 03:50:21 +00:00
|
|
|
httpport = 8080
|
|
|
|
udpport = 8111
|
|
|
|
|
2018-07-15 03:03:25 +00:00
|
|
|
HEX_FILE = '../efm32/GNU ARM v7.2.1 - Debug/EFM32.hex'
|
2018-07-10 03:50:21 +00:00
|
|
|
|
2019-01-03 13:27:21 +00:00
|
|
|
|
|
|
|
def ForceU2F(client, device):
|
2018-07-10 03:50:21 +00:00
|
|
|
client.ctap = CTAP1(device)
|
|
|
|
client.pin_protocol = None
|
|
|
|
client._do_make_credential = client._ctap1_make_credential
|
|
|
|
client._do_get_assertion = client._ctap1_get_assertion
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
2018-07-15 03:03:25 +00:00
|
|
|
try:
|
|
|
|
dev = next(CtapHidDevice.list_devices(), None)
|
|
|
|
print(dev)
|
|
|
|
if not dev:
|
|
|
|
raise RuntimeError('No FIDO device found')
|
|
|
|
client = Fido2Client(dev, 'https://example.com')
|
|
|
|
ForceU2F(client, dev)
|
|
|
|
ctap = client.ctap
|
|
|
|
except Exception as e:
|
|
|
|
print(e)
|
2018-07-10 03:50:21 +00:00
|
|
|
|
|
|
|
|
|
|
|
def write(data):
|
|
|
|
msg = from_websafe(data)
|
|
|
|
msg = base64.b64decode(msg)
|
2019-01-03 13:27:21 +00:00
|
|
|
chal = b'A' * 32
|
|
|
|
appid = b'A' * 32
|
|
|
|
# print (msg)
|
|
|
|
# print (msg.decode())
|
|
|
|
# print (str(msg))
|
|
|
|
# msg = msg.decode('ascii')
|
|
|
|
# print('ascii:',repr(msg))
|
|
|
|
# print('ascii:',(type(msg)))
|
|
|
|
# print(msg + chal)
|
|
|
|
|
|
|
|
# data = client_param + app_param + struct.pack('>B', len(key_handle)) + key_handle
|
|
|
|
# msg = str(msg.decode())
|
|
|
|
# print(msg.decode())
|
|
|
|
s = ctap.authenticate(chal, appid, msg)
|
2018-07-10 03:50:21 +00:00
|
|
|
print(s)
|
2019-01-03 13:27:21 +00:00
|
|
|
# sock.sendto(msg, ('127.0.0.1', udpport))
|
|
|
|
|
2018-07-10 03:50:21 +00:00
|
|
|
|
|
|
|
def read():
|
2019-01-03 13:27:21 +00:00
|
|
|
# msg = [0]*64
|
2018-07-10 03:50:21 +00:00
|
|
|
pkt, _ = sock.recvfrom(1000)
|
2019-01-03 13:27:21 +00:00
|
|
|
# for i,v in enumerate(pkt):
|
|
|
|
# msg[i] = ord(v)
|
2018-07-10 03:50:21 +00:00
|
|
|
msg = base64.b64encode(pkt)
|
|
|
|
msg = to_websafe(pkt)
|
|
|
|
return msg
|
|
|
|
|
2019-01-03 13:27:21 +00:00
|
|
|
|
2018-07-10 03:50:21 +00:00
|
|
|
class UDPBridge(BaseHTTPRequestHandler):
|
2019-01-03 13:27:21 +00:00
|
|
|
def end_headers(self):
|
2018-07-10 03:50:21 +00:00
|
|
|
self.send_header('Access-Control-Allow-Origin', '*')
|
|
|
|
BaseHTTPRequestHandler.end_headers(self)
|
|
|
|
|
|
|
|
def do_POST(self):
|
|
|
|
content_len = int(self.headers.get('Content-Length', 0))
|
|
|
|
post_body = self.rfile.read(content_len)
|
|
|
|
data = json.loads(post_body)['data']
|
|
|
|
|
|
|
|
print(data)
|
|
|
|
msg = from_websafe(data)
|
|
|
|
msg = base64.b64decode(msg)
|
2018-07-12 03:00:53 +00:00
|
|
|
chal = b"\xf6\xa2\x3c\xa4\x0a\xf9\xda\xd4\x5f\xdc\xba\x7d\xc9\xde\xcb\xed\xb5\x84\x64\x3a\x4c\x9f\x44\xc2\x04\xb0\x17\xd7\xf4\x3e\xe0\x3f"
|
2019-01-03 13:27:21 +00:00
|
|
|
appid = b'A' * 32
|
2018-07-10 03:50:21 +00:00
|
|
|
|
2019-01-03 13:27:21 +00:00
|
|
|
s = ctap.authenticate(chal, appid, msg)
|
2018-07-10 03:50:21 +00:00
|
|
|
|
2019-01-03 13:27:21 +00:00
|
|
|
data = (
|
|
|
|
struct.pack('B', s.user_presence)
|
|
|
|
+ struct.pack('>L', s.counter)
|
|
|
|
+ s.signature
|
|
|
|
)
|
2018-07-10 03:50:21 +00:00
|
|
|
data = base64.b64encode(data).decode('ascii')
|
|
|
|
data = to_websafe(data)
|
2019-01-03 13:27:21 +00:00
|
|
|
data = json.dumps({'data': data})
|
2018-07-10 03:50:21 +00:00
|
|
|
data = data.encode('ascii')
|
|
|
|
|
|
|
|
self.send_response(200)
|
2019-01-03 13:27:21 +00:00
|
|
|
self.send_header('Content-type', 'text/json')
|
2018-07-10 03:50:21 +00:00
|
|
|
self.end_headers()
|
|
|
|
self.wfile.write(data)
|
|
|
|
|
|
|
|
def do_GET(self):
|
|
|
|
self.send_response(200)
|
2019-01-03 13:27:21 +00:00
|
|
|
self.send_header('Content-type', 'text/json')
|
2018-07-10 03:50:21 +00:00
|
|
|
|
2019-01-03 13:27:21 +00:00
|
|
|
msg = get_firmware_object("signing_key.pem", HEX_FILE)
|
2018-07-15 03:03:25 +00:00
|
|
|
|
|
|
|
self.end_headers()
|
2018-07-10 03:50:21 +00:00
|
|
|
|
|
|
|
self.wfile.write(json.dumps(msg).encode())
|
|
|
|
|
2019-01-03 13:27:21 +00:00
|
|
|
|
2018-07-10 03:50:21 +00:00
|
|
|
try:
|
|
|
|
server = HTTPServer(('', httpport), UDPBridge)
|
2019-01-03 13:27:21 +00:00
|
|
|
print('Started httpserver on port ', httpport)
|
2018-07-10 03:50:21 +00:00
|
|
|
|
2019-01-03 13:27:21 +00:00
|
|
|
server.socket = ssl.wrap_socket(
|
|
|
|
server.socket,
|
|
|
|
keyfile="../web/localhost.key",
|
|
|
|
certfile='../web/localhost.crt',
|
|
|
|
server_side=True,
|
|
|
|
)
|
2018-07-10 03:50:21 +00:00
|
|
|
|
2018-09-04 23:27:27 +00:00
|
|
|
print('Saving signed firmware to firmware.json')
|
2019-01-03 13:27:21 +00:00
|
|
|
msg = get_firmware_object("signing_key.pem", HEX_FILE)
|
|
|
|
wfile = open('firmware.json', 'wb+')
|
2018-09-04 23:27:27 +00:00
|
|
|
wfile.write(json.dumps(msg).encode())
|
|
|
|
wfile.close()
|
|
|
|
|
2018-07-10 03:50:21 +00:00
|
|
|
server.serve_forever()
|
2018-09-04 23:27:27 +00:00
|
|
|
|
2018-07-10 03:50:21 +00:00
|
|
|
except KeyboardInterrupt:
|
|
|
|
server.socket.close()
|