def verify(self, username, password, data): user = self._get_user(username, password) binding = user.attributes['_u2f_binding_'] challenge = user.attributes['_u2f_challenge_'] c, t = verify_authenticate(binding, challenge, data, [self.origin]) return json.dumps({'touch': t, 'counter': c})
def test_authenticate_fixed_values(self): device = { 'publicKey': 'BBCcnAOknoMgokEGuTdfpNLQ-uylwlKp_xbEW8urjJsXKv9XZSL-V8C2nwcPEckav1mKZFr5K96uAoLtuxOUf-E', 'keyHandle': 'BIarIKfyMqyf4bEI6tOqGInAfHrrQkMA2eyPJlNnInbAG1tXNpdRs48ef92_b1-mfN4VhaTWxo1SGoxT6CIanw', 'appId': 'http://www.example.com/appid' } challenge = { 'challenge': 'oIeu-nPxx9DcF7L_DCE3kvYox-c4UuvFb8lNG6th10o', 'version': 'U2F_V2', 'keyHandle': 'BIarIKfyMqyf4bEI6tOqGInAfHrrQkMA2eyPJlNnInbAG1tXNpdRs48ef92_b1-mfN4VhaTWxo1SGoxT6CIanw', 'appId': 'http://www.example.com/appid' } response = { 'keyHandle': 'BIarIKfyMqyf4bEI6tOqGInAfHrrQkMA2eyPJlNnInbAG1tXNpdRs48ef92_b1-mfN4VhaTWxo1SGoxT6CIanw', 'signatureData': 'AAAAAAEwRQIhAJrcBSpaDprFzXmVw60r6x-_gOZ0t-8v7DGiiKmar0SAAiAYKKEX41nWUCLLoKiBYuHYdPP1MPPNQ0cX_JIybPtThA', 'clientData': 'eyJvcmlnaW4iOiAiaHR0cHM6Ly93d3cuZXhhbXBsZS5jb20iLCAiY2hhbGxlbmdlIjogIm9JZXUtblB4eDlEY0Y3TF9EQ0Uza3ZZb3gtYzRVdXZGYjhsTkc2dGgxMG8iLCAidHlwIjogIm5hdmlnYXRvci5pZC5nZXRBc3NlcnRpb24ifQ' } assert u2f.verify_authenticate(device, challenge, response)
def form_valid(self, form): response = json.loads(form.cleaned_data['response']) challenges = self.request.session['u2f_authentication_challenges'] try: # find the right challenge, the based on the key the user inserted challenge = [ c for c in challenges if c['keyHandle'] == response['keyHandle'] ][0] device = self.user.u2f_keys.get(key_handle=response['keyHandle']) login_counter, touch_asserted = u2f.verify_authenticate( device.to_json(), challenge, response, ) except Exception as e: form.add_error('__all__', str(e)) return self.form_invalid(form) # TODO: store login_counter and verify it's increasing device.last_used_at = timezone.now() device.save() auth.login(self.request, self.user) del self.request.session['u2f_authentication_challenges'] del self.request.session['u2f_pre_verify_user_pk'] del self.request.session['u2f_pre_verify_user_backend'] redirect_to = self.request.REQUEST.get(auth.REDIRECT_FIELD_NAME, '') if not is_safe_url(url=redirect_to, host=self.request.get_host()): redirect_to = resolve_url(settings.LOGIN_REDIRECT_URL) return HttpResponseRedirect(redirect_to)
def authenticate_complete(self, username, resp): memkey = resp.clientData.challenge challenges = self._memstore.retrieve(self._client.id, username, memkey) user = self._get_user(username) for handle, data in challenges.items(): if data['keyHandle'] == resp.keyHandle: dev = user.devices[handle] if dev.compromised: raise BadInputException('Device is compromised') counter, presence = verify_authenticate( dev.bind_data, data['challenge'], resp, self._client.valid_facets ) if presence == chr(0): raise Exception('User presence byte not set!') if counter > (dev.counter or -1): dev.counter = counter dev.authenticated_at = datetime.now() return handle dev.compromised = True raise DeviceCompromisedException('Device counter mismatch', dev.get_descriptor()) else: raise BadInputException('No device found for keyHandle: %s' % resp.keyHandle)
def form_valid(self, form): response = json.loads(form.cleaned_data['response']) challenges = self.request.session['u2f_authentication_challenges'] try: # find the right challenge, the based on the key the user inserted challenge = [c for c in challenges if c['keyHandle'] == response['keyHandle']][0] device = self.user.u2f_keys.get(key_handle=response['keyHandle']) login_counter, touch_asserted = u2f.verify_authenticate( device.to_json(), challenge, response, ) except Exception as e: form.add_error('__all__', str(e)) return self.form_invalid(form) # TODO: store login_counter and verify it's increasing device.last_used_at = timezone.now() device.save() auth.login(self.request, self.user) del self.request.session['u2f_authentication_challenges'] del self.request.session['u2f_pre_verify_user_pk'] del self.request.session['u2f_pre_verify_user_backend'] redirect_to = self.request.REQUEST.get(auth.REDIRECT_FIELD_NAME, '') if not is_safe_url(url=redirect_to, host=self.request.get_host()): redirect_to = resolve_url(settings.LOGIN_REDIRECT_URL) return HttpResponseRedirect(redirect_to)
def twofactor(request): print("All u2f keys") user = User.objects.get(pk=request.session['authuser']) print("The user is: %s" % user) challenges = [ u2f.start_authenticate(u2f_key.to_json()) for u2f_key in user.u2f_keys.all() ] if request.method == 'POST': u2f_response = KeyResponseForm(request.POST) if u2f_response.is_valid(): print('----------2------------------') device_response = u2f_response.cleaned_data['response'] challenge = request.session['u2f_authentication_challenges'][0] device = user.u2f_keys.get( ) #key_handle=device_response['keyHandle']) print("Check this: %s" % device) # u2f_response_json = json.dumps(u2f_response.cleaned_data['response']) u2f_response_json = u2f_response.cleaned_data['response'] login_counter, touch_asserted = u2f.verify_authenticate( device.to_json(), challenge, u2f_response_json, ) print("Touch asserted: %s" % touch_asserted) # device.last_used_at = timezone.now() # device.save() try: del request.session['u2f_authentication_challenges'] user.backend = request.session['backend'] del request.session['backend'] auth.login(request, user=user) return HttpResponseRedirect('/dashboard/') except: return HttpResponseRedirect('/login/') else: print('----------1------------------') u2f_response = KeyResponseForm() print("The user is currently: %s" % user) # challenges = [user.u2f_keys.get().to_json()] # print(challenges) challenges = [u2f.start_authenticate(user.u2f_keys.get().to_json())] print(challenges) request.session['u2f_authentication_challenges'] = challenges # challenges = [u2f.start_authenticate(u2f_key.to_json()) for u2f_key in user.u2f_keys.all()] print("Final: %s" % str(json.dumps(challenges))) context = { 'u2f_response': u2f_response, 'challenges': json.dumps(challenges) } return render(request, 'u2f/twofactor.html', context)
def verify(self, username, password, data): user = self._get_user(username, password) binding = user.attributes['_u2f_binding_'] challenge = user.attributes['_u2f_challenge_'] c, t = verify_authenticate(binding, challenge, data, [self.origin]) return json.dumps({ 'touch': t, 'counter': c })
def verify(self, username, data): user = self.users[username] binding = user['_u2f_binding_'] challenge = user['_u2f_challenge_'] c, t = verify_authenticate(binding, challenge, data, [self.facet]) return json.dumps({ 'touch': t, 'counter': c })
def test_authenticate_soft_u2f(self): token = SoftU2FDevice() request = u2f.start_register(APP_ID) response = token.register(request.json, FACET) device, cert = u2f.complete_register(request, response) challenge1 = u2f.start_authenticate(device) challenge2 = u2f.start_authenticate(device) response2 = token.getAssertion(challenge2.json, FACET) response1 = token.getAssertion(challenge1.json, FACET) assert u2f.verify_authenticate(device, challenge1, response1) assert u2f.verify_authenticate(device, challenge2, response2) try: u2f.verify_authenticate(device, challenge1, response2) except: pass else: assert False, "Incorrect validation should fail!" try: u2f.verify_authenticate(device, challenge2, response1) except: pass else: assert False, "Incorrect validation should fail!"
def verify_authenticate(devices, request_data, response, valid_facets=None): request_data = AuthenticateRequestData.wrap(request_data) response = SignResponse.wrap(response) sign_request = request_data.getAuthenticateRequest(response) device = next(d for d in devices if d.keyHandle == sign_request.keyHandle) return u2f_v2.verify_authenticate( device, sign_request, response, valid_facets )
def test_wrong_facet(self): token = SoftU2FDevice() request = u2f.start_register(APP_ID) response = token.register(request.json, "http://wrongfacet.com") try: u2f.complete_register(request, response, FACETS) except: pass else: assert False, "Incorrect facet should fail!" response2 = token.register(request.json, FACET) device, cert = u2f.complete_register(request, response2) challenge = u2f.start_authenticate(device) response = token.getAssertion(challenge.json, "http://notright.com") try: u2f.verify_authenticate(device, challenge, response, FACETS) except: pass else: assert False, "Incorrect facet should fail!"
def twofactor(request): print("All u2f keys") user = User.objects.get(pk=request.session['authuser']) print("The user is: %s" % user) challenges = [u2f.start_authenticate(u2f_key.to_json()) for u2f_key in user.u2f_keys.all()] if request.method == 'POST': u2f_response = KeyResponseForm(request.POST) if u2f_response.is_valid(): device_response = u2f_response.cleaned_data['response'] challenge = request.session['u2f_authentication_challenges'][0] device = user.u2f_keys.get() #key_handle=device_response['keyHandle']) print("Check this: %s" % device) # u2f_response_json = json.dumps(u2f_response.cleaned_data['response']) u2f_response_json = u2f_response.cleaned_data['response'] login_counter, touch_asserted = u2f.verify_authenticate(device.to_json(), challenge, u2f_response_json,) print("Touch asserted: %s" % touch_asserted) # device.last_used_at = timezone.now() # device.save() del request.session['u2f_authentication_challenges'] user.backend = request.session['backend'] del request.session['backend'] auth.login(request, user=user) return HttpResponseRedirect('/dashboard/') else: u2f_response = KeyResponseForm() print("The user is currently: %s" % user) # challenges = [user.u2f_keys.get().to_json()] # print(challenges) challenges = [u2f.start_authenticate(user.u2f_keys.get().to_json())] print(challenges) request.session['u2f_authentication_challenges'] = challenges # challenges = [u2f.start_authenticate(u2f_key.to_json()) for u2f_key in user.u2f_keys.all()] print("Final: %s" % str(json.dumps(challenges))) context = {'u2f_response': u2f_response, 'challenges': json.dumps(challenges)} return render(request, 'u2f/twofactor.html', context)
def validate_second_factor(self): response = json.loads(self.cleaned_data['response']) try: # find the right challenge, the based on the key the user inserted challenge = [ c for c in self.challenges if c['keyHandle'] == response['keyHandle'] ][0] device = self.user.u2f_keys.get(key_handle=response['keyHandle']) login_counter, touch_asserted = u2f.verify_authenticate( device.to_json(), challenge, response, ) # TODO: store login_counter and verify it's increasing device.last_used_at = timezone.now() device.save() del self.request.session['u2f_authentication_challenges'] return True except InvalidSignature: self.add_error('__all__', 'U2F validation failed -- bad signature.') return False
def test_authenticate_fixed_values(self): device = {'publicKey': 'BBCcnAOknoMgokEGuTdfpNLQ-uylwlKp_xbEW8urjJsXKv9XZSL-V8C2nwcPEckav1mKZFr5K96uAoLtuxOUf-E', 'keyHandle': 'BIarIKfyMqyf4bEI6tOqGInAfHrrQkMA2eyPJlNnInbAG1tXNpdRs48ef92_b1-mfN4VhaTWxo1SGoxT6CIanw', 'appId': 'http://www.example.com/appid'} challenge = {'challenge': 'oIeu-nPxx9DcF7L_DCE3kvYox-c4UuvFb8lNG6th10o', 'version': 'U2F_V2', 'keyHandle': 'BIarIKfyMqyf4bEI6tOqGInAfHrrQkMA2eyPJlNnInbAG1tXNpdRs48ef92_b1-mfN4VhaTWxo1SGoxT6CIanw', 'appId': 'http://www.example.com/appid'} response = {'keyHandle': 'BIarIKfyMqyf4bEI6tOqGInAfHrrQkMA2eyPJlNnInbAG1tXNpdRs48ef92_b1-mfN4VhaTWxo1SGoxT6CIanw', 'signatureData': 'AAAAAAEwRQIhAJrcBSpaDprFzXmVw60r6x-_gOZ0t-8v7DGiiKmar0SAAiAYKKEX41nWUCLLoKiBYuHYdPP1MPPNQ0cX_JIybPtThA', 'clientData': 'eyJvcmlnaW4iOiAiaHR0cHM6Ly93d3cuZXhhbXBsZS5jb20iLCAiY2hhbGxlbmdlIjogIm9JZXUtblB4eDlEY0Y3TF9EQ0Uza3ZZb3gtYzRVdXZGYjhsTkc2dGgxMG8iLCAidHlwIjogIm5hdmlnYXRvci5pZC5nZXRBc3NlcnRpb24ifQ'} assert u2f.verify_authenticate(device, challenge, response)