support pc development with JS http bridge
This commit is contained in:
parent
4eeb99fb59
commit
689f0bd5f1
11
Makefile
11
Makefile
@ -9,16 +9,23 @@
|
|||||||
|
|
||||||
platform=2
|
platform=2
|
||||||
|
|
||||||
src = $(wildcard *.c) $(wildcard crypto/*.c) crypto/tiny-AES-c/aes.c
|
src = $(wildcard pc/*.c) $(wildcard fido2/*.c) $(wildcard crypto/sha256/*.c) crypto/tiny-AES-c/aes.c
|
||||||
obj = $(src:.c=.o) uECC.o
|
obj = $(src:.c=.o) uECC.o
|
||||||
|
|
||||||
LDFLAGS = -Wl,--gc-sections ./tinycbor/lib/libtinycbor.a
|
LDFLAGS = -Wl,--gc-sections ./tinycbor/lib/libtinycbor.a
|
||||||
CFLAGS = -O2 -fdata-sections -ffunction-sections -I./tinycbor/src -I./crypto -I./crypto/micro-ecc/ -Icrypto/tiny-AES-c/ -I.
|
CFLAGS = -O2 -fdata-sections -ffunction-sections
|
||||||
|
|
||||||
|
INCLUDES = -I./tinycbor/src -I./crypto/sha256 -I./crypto/micro-ecc/ -Icrypto/tiny-AES-c/ -I./fido2/ -I./pc
|
||||||
|
|
||||||
|
CFLAGS += $(INCLUDES)
|
||||||
|
|
||||||
name = main
|
name = main
|
||||||
|
|
||||||
all: main
|
all: main
|
||||||
|
|
||||||
|
cbor:
|
||||||
|
cd tinycbor/ && $(MAKE) clean && $(MAKE) -j8
|
||||||
|
|
||||||
test: testgcm
|
test: testgcm
|
||||||
|
|
||||||
efm8prog:
|
efm8prog:
|
||||||
|
18
pc/app.h
Normal file
18
pc/app.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
* app.h
|
||||||
|
*
|
||||||
|
* Created on: Jun 26, 2018
|
||||||
|
* Author: conor
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SRC_APP_H_
|
||||||
|
#define SRC_APP_H_
|
||||||
|
|
||||||
|
#define USING_DEV_BOARD
|
||||||
|
|
||||||
|
#define BRIDGE_TO_WALLET
|
||||||
|
|
||||||
|
void printing_init();
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* SRC_APP_H_ */
|
@ -95,12 +95,12 @@ void udp_close(int fd)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint64_t millis()
|
uint32_t millis()
|
||||||
{
|
{
|
||||||
struct timeval te;
|
struct timeval te;
|
||||||
gettimeofday(&te, NULL); // get current time
|
gettimeofday(&te, NULL); // get current time
|
||||||
uint64_t milliseconds = te.tv_sec*1000LL + te.tv_usec/1000; // calculate milliseconds
|
uint64_t milliseconds = te.tv_sec*1000LL + te.tv_usec/1000; // calculate milliseconds
|
||||||
return milliseconds;
|
return (uint32_t)milliseconds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
128
tools/http2udb.py
Normal file
128
tools/http2udb.py
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
from __future__ import print_function, absolute_import, unicode_literals
|
||||||
|
from http.server import BaseHTTPRequestHandler,HTTPServer
|
||||||
|
|
||||||
|
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 *
|
||||||
|
from fido2.utils import Timeout
|
||||||
|
|
||||||
|
import socket,json,base64,ssl
|
||||||
|
|
||||||
|
httpport = 8080
|
||||||
|
udpport = 8111
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def ForceU2F(client,device):
|
||||||
|
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__':
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
def to_websafe(data):
|
||||||
|
data = data.replace('+','-')
|
||||||
|
data = data.replace('/','_')
|
||||||
|
data = data.replace('=','')
|
||||||
|
return data
|
||||||
|
|
||||||
|
def from_websafe(data):
|
||||||
|
data = data.replace('-','+')
|
||||||
|
data = data.replace('_','/')
|
||||||
|
return data + '=='[:(3*len(data)) % 4]
|
||||||
|
|
||||||
|
def write(data):
|
||||||
|
msg = from_websafe(data)
|
||||||
|
msg = base64.b64decode(msg)
|
||||||
|
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,)
|
||||||
|
print(s)
|
||||||
|
#sock.sendto(msg, ('127.0.0.1', udpport))
|
||||||
|
|
||||||
|
def read():
|
||||||
|
#msg = [0]*64
|
||||||
|
pkt, _ = sock.recvfrom(1000)
|
||||||
|
#for i,v in enumerate(pkt):
|
||||||
|
#msg[i] = ord(v)
|
||||||
|
msg = base64.b64encode(pkt)
|
||||||
|
msg = to_websafe(pkt)
|
||||||
|
return msg
|
||||||
|
|
||||||
|
class UDPBridge(BaseHTTPRequestHandler):
|
||||||
|
def end_headers (self):
|
||||||
|
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)
|
||||||
|
chal = b'A'*32
|
||||||
|
appid = b'A'*32
|
||||||
|
|
||||||
|
s = ctap.authenticate(chal,appid,msg,)
|
||||||
|
|
||||||
|
data = struct.pack('B',s.user_presence) + struct.pack('>L',s.counter) + s.signature
|
||||||
|
data = base64.b64encode(data).decode('ascii')
|
||||||
|
data = to_websafe(data)
|
||||||
|
data = json.dumps({'data':data})
|
||||||
|
data = data.encode('ascii')
|
||||||
|
|
||||||
|
self.send_response(200)
|
||||||
|
self.send_header('Content-type','text/json')
|
||||||
|
self.end_headers()
|
||||||
|
self.wfile.write(data)
|
||||||
|
|
||||||
|
|
||||||
|
def do_GET(self):
|
||||||
|
self.send_response(200)
|
||||||
|
self.send_header('Content-type','text/json')
|
||||||
|
self.end_headers()
|
||||||
|
|
||||||
|
#msg = {'data': read()}
|
||||||
|
msg = {'data': 'rest'}
|
||||||
|
|
||||||
|
self.wfile.write(json.dumps(msg).encode())
|
||||||
|
|
||||||
|
try:
|
||||||
|
server = HTTPServer(('', httpport), UDPBridge)
|
||||||
|
print('Started httpserver on port ' , httpport)
|
||||||
|
|
||||||
|
server.socket = ssl.wrap_socket (server.socket,
|
||||||
|
keyfile="../web/localhost.key",
|
||||||
|
certfile='../web/localhost.crt', server_side=True)
|
||||||
|
|
||||||
|
server.serve_forever()
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
server.socket.close()
|
||||||
|
|
@ -162,7 +162,68 @@ var PIN = {
|
|||||||
getPinToken: 0x05,
|
getPinToken: 0x05,
|
||||||
};
|
};
|
||||||
|
|
||||||
function send_msg(data, func, timeout) {
|
// Create the XHR object.
|
||||||
|
function createCORSRequest(method, url) {
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
if ("withCredentials" in xhr) {
|
||||||
|
// XHR for Chrome/Firefox/Opera/Safari.
|
||||||
|
xhr.open(method, url, true);
|
||||||
|
} else if (typeof XDomainRequest != "undefined") {
|
||||||
|
// XDomainRequest for IE.
|
||||||
|
xhr = new XDomainRequest();
|
||||||
|
xhr.open(method, url);
|
||||||
|
} else {
|
||||||
|
// CORS not supported.
|
||||||
|
xhr = null;
|
||||||
|
}
|
||||||
|
return xhr;
|
||||||
|
}
|
||||||
|
|
||||||
|
function parse_device_response(arr)
|
||||||
|
{
|
||||||
|
var dataview = new DataView(arr.slice(1,5).buffer);
|
||||||
|
|
||||||
|
count = dataview.getUint32(0,true); // get count as 32 bit LE integer
|
||||||
|
|
||||||
|
data = null;
|
||||||
|
if (arr[5] == 0) {
|
||||||
|
data = arr.slice(6,arr.length);
|
||||||
|
}
|
||||||
|
return {count: count, status: error2string(arr[5]), data: data};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// For development purposes
|
||||||
|
function send_msg_http(data, func, timeout) {
|
||||||
|
var url = 'https://localhost:8080';
|
||||||
|
|
||||||
|
var req = JSON.stringify({data: array2websafe(data)});
|
||||||
|
|
||||||
|
var xhr = createCORSRequest('POST', url);
|
||||||
|
|
||||||
|
if (!xhr) {
|
||||||
|
console.log('CORS not supported');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Response handlers.
|
||||||
|
xhr.onload = function() {
|
||||||
|
var text = xhr.responseText;
|
||||||
|
var resp = JSON.parse(text);
|
||||||
|
arr = websafe2array(resp.data);
|
||||||
|
data = parse_device_response(arr);
|
||||||
|
if (func) func(data);
|
||||||
|
};
|
||||||
|
|
||||||
|
xhr.onerror = function() {
|
||||||
|
console.log('Woops, there was an error making the request.');
|
||||||
|
};
|
||||||
|
|
||||||
|
xhr.send(req);
|
||||||
|
}
|
||||||
|
//run_tests();
|
||||||
|
function send_msg_u2f(data, func, timeout) {
|
||||||
// Use key handle and signature response as comm channel
|
// Use key handle and signature response as comm channel
|
||||||
var d = new Date();
|
var d = new Date();
|
||||||
var t1 = d.getTime();
|
var t1 = d.getTime();
|
||||||
@ -186,28 +247,19 @@ function send_msg(data, func, timeout) {
|
|||||||
var d2 = new Date();
|
var d2 = new Date();
|
||||||
t2 = d2.getTime();
|
t2 = d2.getTime();
|
||||||
sig = websafe2array(res.signatureData)
|
sig = websafe2array(res.signatureData)
|
||||||
|
data = parse_device_response(sig);
|
||||||
//console.log(sig);
|
func(data);
|
||||||
//console.log(sig.slice(1,5));
|
|
||||||
var dataview = new DataView(sig.slice(1,5).buffer);
|
|
||||||
|
|
||||||
count = dataview.getUint32(0,true); // get count as 32 bit LE integer
|
|
||||||
|
|
||||||
//console.log('sig:',sig);
|
|
||||||
//console.log('count:',count);
|
|
||||||
data = null;
|
|
||||||
if (sig[5] == 0) {
|
|
||||||
data = sig.slice(6,sig.length);
|
|
||||||
}
|
|
||||||
func({count: count, status: error2string(sig[5]), data: data});
|
|
||||||
//console.log('response:', res);
|
|
||||||
//console.log('time:', t2-t1);
|
|
||||||
//i += 1;
|
|
||||||
|
|
||||||
},timeout);
|
},timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEVELOPMENT = 1
|
||||||
|
var send_msg;
|
||||||
|
if (DEVELOPMENT) {
|
||||||
|
send_msg = send_msg_http;
|
||||||
|
} else {
|
||||||
|
send_msg = send_msg_u2f;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Format a request message
|
// Format a request message
|
||||||
@ -405,4 +457,6 @@ function run_tests()
|
|||||||
|
|
||||||
|
|
||||||
EC = elliptic.ec
|
EC = elliptic.ec
|
||||||
run_tests();
|
|
||||||
|
run_tests()
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user