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 retrieve(self, client_id, user_id, transaction_id): transaction_id = transaction_id.encode('hex') self._delete_expired() transaction = self._session.query(Transaction) \ .filter(Transaction.transaction_id == transaction_id).first() if transaction is None: raise BadInputException('Invalid transaction') if transaction.user.name != user_id or \ transaction.user.client_id != client_id: raise BadInputException('Transaction not valid for user_id: %s' % user_id) self._session.delete(transaction) return transaction.data
def _do_get_descriptor(self, user, handle): if user is not None: dev = self._session.query(Device) \ .filter(Device.user_id == user.id) \ .filter(Device.handle == handle).first() if user is None or dev is None: raise BadInputException('No device matches descriptor: %s' % handle) return dev.get_descriptor(self._metadata.get_metadata(dev))
def authenticate(self, request, controller, user_id): if request.method == 'GET': sign_requests = controller.authenticate_start(user_id) return AuthenticateRequestData(authenticateRequests=sign_requests) elif request.method == 'POST': data = AuthenticateResponseData(request.body) try: handle = controller.authenticate_complete( user_id, data.authenticateResponse) except KeyError: raise BadInputException('Malformed request') except ValueError as e: log.exception('Error in authenticate') raise BadInputException(e.message) controller.set_props(handle, data.properties) return controller.get_descriptor(user_id, handle) else: raise exc.HTTPMethodNotAllowed
def register_complete(self, username, resp): memkey = resp.clientData.challenge data = self._memstore.retrieve(self._client.id, username, memkey) bind, cert = complete_register(data['request'], resp, self._client.valid_facets) attestation = self._metadata.get_attestation(cert) if self._require_trusted and not attestation.trusted: raise BadInputException('Device type is not trusted') user = self._get_or_create_user(username) dev = user.add_device(bind.json, cert, attestation.transports) log.info('User: "******" - Device registered: "%s"', self._client.name, username, dev.handle) return dev.handle
def __call__(self, request): client_name = request.environ.get('REMOTE_USER') if not client_name: raise u2f_error(BadInputException('Client not specified')) try: resp = self.client(request, client_name) if not isinstance(resp, Response): resp = Response(json.dumps(resp), content_type='application/json') return resp except Exception as e: self._session.rollback() if isinstance(e, U2fException): e = u2f_error(e) elif isinstance(e, exc.HTTPException): pass else: log.exception('Server error') e = exc.HTTPServerError(e.args[0]) raise e finally: self._session.commit()
def _get_controller(self, client_name): try: return U2FController(self._session, self._memstore, client_name, self._metadata, self._require_trusted) except KeyError as e: raise BadInputException(e.args[0])