Last active
January 21, 2017 00:04
-
-
Save stefan2904/43a2646dd4da2796bc58888180399b01 to your computer and use it in GitHub Desktop.
[python-u2flib-server] <--[u2f_demo.py]--> [python-u2flib-host]
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# Copyright (0) 2017 Stefan <[email protected]> | |
# No rights reserved. | |
from u2flib_host import u2f as u2f_host | |
from u2flib_host.soft import SoftU2FDevice | |
from u2flib_server.jsapi import DeviceRegistration | |
from u2flib_server.u2f import (start_register, complete_register, | |
start_authenticate, verify_authenticate) | |
import logging | |
import json | |
logging.basicConfig(level=logging.DEBUG, format='%(name)s: %(message)s') | |
DEMO_USERNAME = 'stefan' | |
DEMO_FACET = 'https://u2f-demo.iaik.tugraz.at' | |
class U2FHost(): | |
def __init__(self): | |
self.log = logging.getLogger('Host').info | |
self.init_devices() | |
def init_devices(self): | |
self.log('Searching for U2F devices ...') | |
self.devices = u2f_host.list_devices() | |
if len(self.devices) < 1: | |
self.log('Found no devices. Loading soft device ...') | |
self.devices = [SoftU2FDevice('u2f_demo_softdevice.json')] | |
# for device in devices: | |
# with device as dev: | |
# print(dev) | |
def register(self, registrationRequest, facet): | |
self.log('register() ...') | |
device = self.devices[0] | |
registrationResponse = u2f_host.register( | |
device, registrationRequest, facet) | |
self.log(registrationResponse) | |
return registrationResponse | |
def authenticate(self, authenticationRequest, facet): | |
self.log('authenticate() ...') | |
device = self.devices[0] | |
authenticationResponse = u2f_host.authenticate( | |
device, authenticationRequest, facet) | |
self.log(authenticationResponse) | |
return authenticationResponse | |
class U2FServer(): | |
def __init__(self): | |
self.users = {} | |
self.app_id = DEMO_FACET | |
self.facet = self.app_id | |
self.log = logging.getLogger('Server').info | |
def enroll(self, username): | |
self.log('enroll() for user {} ...'.format(username)) | |
if username not in self.users: | |
self.users[username] = {} | |
user = self.users[username] | |
devices = [DeviceRegistration.wrap(device) | |
for device in user.get('_u2f_devices_', [])] | |
enroll = start_register(self.app_id, devices) | |
user['_u2f_enroll_'] = enroll.json | |
self.log('{}'.format(enroll.json)) | |
return enroll # .json | |
def bind(self, username, data): | |
self.log('bind() for user {} ...'.format(username)) | |
user = self.users[username] | |
binding, cert = complete_register(user.pop('_u2f_enroll_'), data, | |
[self.facet]) | |
devices = [DeviceRegistration.wrap(device) | |
for device in user.get('_u2f_devices_', [])] | |
devices.append(binding) | |
user['_u2f_devices_'] = [d.json for d in devices] | |
self.log("U2F device enrolled. Username: %s", username) | |
self.log('Binding successful, returning True!') | |
return True # json.dumps(True) | |
def sign(self, username): | |
self.log('sign() for user {} ...'.format(username)) | |
user = self.users[username] | |
devices = [DeviceRegistration.wrap(device) | |
for device in user.get('_u2f_devices_', [])] | |
challenge = start_authenticate(devices) | |
user['_u2f_challenge_'] = challenge.json | |
self.log('{}'.format(challenge.json)) | |
return challenge # .json | |
def verify(self, username, data): | |
self.log('verify() for user {} ...'.format(username)) | |
user = self.users[username] | |
devices = [DeviceRegistration.wrap(device) | |
for device in user.get('_u2f_devices_', [])] | |
challenge = user.pop('_u2f_challenge_') | |
c, t = verify_authenticate(devices, challenge, data, [self.facet]) | |
self.log("U2F device authenticated. Username: %s", username) | |
self.log('touched = {}, counter = {}'.format(t == b'\x01', c)) | |
return json.dumps({ | |
'touch': t == b'\x01', | |
'counter': c | |
}) | |
def main(username): | |
host = U2FHost() | |
server = U2FServer() | |
print() | |
# REGISTER: | |
# server: enroll -> RegisterRequest | |
register_request = server.enroll(username)['registerRequests'][0] | |
# host: register -> RegisterResponse | |
register_response = host.register(register_request, DEMO_FACET) | |
# server: bind -> ok | |
server.bind(username, register_response) | |
print() | |
# AUTHENTICATE: | |
# server: sign -> AuthenticateRequest | |
auth_request = server.sign(username)['authenticateRequests'][0] | |
# host: authenticate -> AuthenticateResponse | |
auth_response = host.authenticate(auth_request, DEMO_FACET) | |
# server:verify -> ok | |
server.verify(username, auth_response) | |
if __name__ == '__main__': | |
username = DEMO_USERNAME | |
main(username) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ python u2f_demo.py | |
Host: Searching for U2F devices ... | |
Host: Found no devices. Loading soft device ... | |
Server: enroll() for user stefan ... | |
Server: {"registerRequests": [{"version": "U2F_V2", "appId": "https://u2f-demo.iaik.tugraz.at", "challenge": "nvEBYF5z_P1LC72byXY0LaNONLcBQQhcfJHIXHeJ0go"}], "authenticateRequests": []} | |
Host: register() ... | |
Host: {'registrationData': 'BQS_7kXyrwLnWxNrANme0GW1NXzaj4QNdiIDCFT-f8lTuy4tX-ycjTEsWF1UoAUQKoGP-TeeW1m_QmZ4AB4a7dWsQEM2VF75WymW631SXKK2OMaZE37A17nawbYnV02waJsM0sqAkKY_MVvEl1aVg2dRvPuhqvnQh9I7CbNOYZ2at2MwggGHMIIBLqADAgECAgkAmb7osQyi7BwwCQYHKoZIzj0EATAhMR8wHQYDVQQDDBZZdWJpY28gVTJGIFNvZnQgRGV2aWNlMB4XDTEzMDcxNzE0MjEwM1oXDTE2MDcxNjE0MjEwM1owITEfMB0GA1UEAwwWWXViaWNvIFUyRiBTb2Z0IERldmljZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABDvhl91zfpg9n7DeCedcQ8gGXUnemiXoi-JEAxz-EIhkVsMPAyzhtJZ4V3CqMZ-MOUgICt2aMxacMX9cIa8dgS2jUDBOMB0GA1UdDgQWBBQNqL-TV04iaO6mS5tjGE6ShfexnjAfBgNVHSMEGDAWgBQNqL-TV04iaO6mS5tjGE6ShfexnjAMBgNVHRMEBTADAQH_MAkGByqGSM49BAEDSAAwRQIgXJWZdbvOWdhVaG7IJtn44o21Kmi8EHsDk4cAfnZ0r38CIQD6ZPi3Pl4lXxbY7BXFyrpkiOvCpdyNdLLYbSTbvIBQOTBFAiEAmYoK6icuvIpGl7kaINpX4WWDCe030pJuR5Gf1zP4nrACIAbigy1M1o8Q9t0l3WdbUgI1m3Nmchl8xTLdMeQcZ4wT', 'clientData': 'eyJ0eXAiOiAibmF2aWdhdG9yLmlkLmZpbmlzaEVucm9sbG1lbnQiLCAiY2hhbGxlbmdlIjogIm52RUJZRjV6X1AxTEM3MmJ5WFkwTGFOT05MY0JRUWhjZkpISVhIZUowZ28iLCAib3JpZ2luIjogImh0dHBzOi8vdTJmLWRlbW8uaWFpay50dWdyYXouYXQifQ'} | |
Server: bind() for user stefan ... | |
Server: U2F device enrolled. Username: stefan | |
Server: Binding successful, returning True! | |
Server: sign() for user stefan ... | |
Server: {"authenticateRequests": [{"version": "U2F_V2", "appId": "https://u2f-demo.iaik.tugraz.at", "keyHandle": "QzZUXvlbKZbrfVJcorY4xpkTfsDXudrBtidXTbBomwzSyoCQpj8xW8SXVpWDZ1G8-6Gq-dCH0jsJs05hnZq3Yw", "challenge": "iOC_NXsXFrNK0mm_DC1eiWrxTIhwz_dk2Xz9rFc1FuM"}]} | |
Host: authenticate() ... | |
Host: {'clientData': 'eyJ0eXAiOiAibmF2aWdhdG9yLmlkLmdldEFzc2VydGlvbiIsICJjaGFsbGVuZ2UiOiAiaU9DX05Yc1hGck5LMG1tX0RDMWVpV3J4VElod3pfZGsyWHo5ckZjMUZ1TSIsICJvcmlnaW4iOiAiaHR0cHM6Ly91MmYtZGVtby5pYWlrLnR1Z3Jhei5hdCJ9', 'signatureData': 'AQAAAAswRQIhAIZ0orDcQD1cLEOO_3R7dDXaINWyU9c6ha0RCoUrtw5UAiAGEe8q5hooQYkt-jd-B64w6huYoFhSzOpXGm6CDbzwRA', 'keyHandle': 'QzZUXvlbKZbrfVJcorY4xpkTfsDXudrBtidXTbBomwzSyoCQpj8xW8SXVpWDZ1G8-6Gq-dCH0jsJs05hnZq3Yw'} | |
Server: verify() for user stefan ... | |
Server: U2F device authenticated. Username: stefan | |
Server: touched = True, counter = 11 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment