Skip to content

Instantly share code, notes, and snippets.

@stefan2904
Last active January 21, 2017 00:04
Show Gist options
  • Save stefan2904/43a2646dd4da2796bc58888180399b01 to your computer and use it in GitHub Desktop.
Save stefan2904/43a2646dd4da2796bc58888180399b01 to your computer and use it in GitHub Desktop.
[python-u2flib-server] <--[u2f_demo.py]--> [python-u2flib-host]
#!/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)
$ 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