def create_challenge(self, transactionid=None, options=None): """ This method creates a challenge, which is submitted to the user. The submitted challenge will be preserved in the challenge database. If no transaction id is given, the system will create a transaction id and return it, so that the response can refer to this transaction. :param transactionid: the id of this challenge :param options: the request context parameters / data :type options: dict :return: tuple of (bool, message, transactionid, attributes) :rtype: tuple The return tuple builds up like this: ``bool`` if submit was successful; ``message`` which is displayed in the JSON response; additional ``attributes``, which are displayed in the JSON response. """ options = options or {} message = 'Please scan the QR Code' # Get ValidityTime=120s. Maybe there is a TIQRChallengeValidityTime... validity = int(get_from_config('DefaultChallengeValidityTime', 120)) tokentype = self.get_tokentype().lower() lookup_for = tokentype.capitalize() + 'ChallengeValidityTime' validity = int(get_from_config(lookup_for, validity)) # We need to set the user ID user_identifier, user_displayname = self.get_user_displayname() service_identifier = get_from_config("tiqr.serviceIdentifier") or \ "org.privacyidea" # Get the OCRASUITE from the token information ocrasuite = self.get_tokeninfo("ocrasuite") or OCRA_DEFAULT_SUITE # Depending on the OCRA-SUITE we create the challenge os = OCRASuite(ocrasuite) challenge = os.create_challenge() # Create the challenge in the database db_challenge = Challenge(self.token.serial, transaction_id=None, challenge=challenge, data=None, session=options.get("session"), validitytime=validity) db_challenge.save() authurl = "tiqrauth://%s@%s/%s/%s" % (user_identifier, service_identifier, db_challenge.transaction_id, challenge) attributes = {"img": create_img(authurl, width=250), "value": authurl, "poll": True, "hideResponseInput": True} return True, message, db_challenge.transaction_id, attributes
def create_challenge(self, transactionid=None, options=None): """ This method creates a challenge, which is submitted to the user. The submitted challenge will be preserved in the challenge database. If no transaction id is given, the system will create a transaction id and return it, so that the response can refer to this transaction. :param transactionid: the id of this challenge :param options: the request context parameters / data :type options: dict :return: tuple of (bool, message, transactionid, attributes) :rtype: tuple The return tuple builds up like this: ``bool`` if submit was successful; ``message`` which is displayed in the JSON response; additional ``attributes``, which are displayed in the JSON response. """ options = options or {} message = 'Please scan the QR Code' # Get ValidityTime=120s. Maybe there is a TIQRChallengeValidityTime... validity = int(get_from_config('DefaultChallengeValidityTime', 120)) tokentype = self.get_tokentype().lower() lookup_for = tokentype.capitalize() + 'ChallengeValidityTime' validity = int(get_from_config(lookup_for, validity)) # We need to set the user ID user_identifier, user_displayname = self.get_user_displayname() service_identifier = get_from_config("tiqr.serviceIdentifier") or \ "org.privacyidea" # Get the OCRASUITE from the token information ocrasuite = self.get_tokeninfo("ocrasuite") or OCRA_DEFAULT_SUITE # Depending on the OCRA-SUITE we create the challenge os = OCRASuite(ocrasuite) challenge = os.create_challenge() # Create the challenge in the database db_challenge = Challenge(self.token.serial, transaction_id=None, challenge=challenge, data=None, session=options.get("session"), validitytime=validity) db_challenge.save() authurl = "tiqrauth://{0!s}@{1!s}/{2!s}/{3!s}".format(user_identifier, service_identifier, db_challenge.transaction_id, challenge) attributes = {"img": create_img(authurl, width=250), "value": authurl, "poll": True, "hideResponseInput": True} return True, message, db_challenge.transaction_id, attributes
def test_01_ocrasuite_success(self): os = OCRASuite("OCRA-1:HOTP-SHA1-6:QH10-S128") self.assertEqual(os.algorithm, "OCRA-1") self.assertEqual(os.sha, "SHA1") self.assertEqual(os.truncation, 6) self.assertEqual(os.challenge_type, "QH") self.assertEqual(os.challenge_length, 10) self.assertEqual(os.signature_type, "S") self.assertEqual(os.session_length, 128) os = OCRASuite("OCRA-1:HOTP-SHA512-8:C-QN08-PSHA1") self.assertEqual(os.sha, "SHA512") self.assertEqual(os.truncation, 8) self.assertEqual(os.counter, "C") self.assertEqual(os.challenge_type, "QN") self.assertEqual(os.signature_hash, "SHA1") os = OCRASuite("OCRA-1:HOTP-SHA256-6:QA10-T1M") self.assertEqual(os.time_frame, "M") self.assertEqual(os.time_value, 1) os = OCRASuite("OCRA-1:HOTP-SHA1-4:QH8-S512")
def test_02_create_challenge(self): # test creation of hex challenge os = OCRASuite("OCRA-1:HOTP-SHA1-6:QH10-S128") c = os.create_challenge() self.assertEqual(len(c), 20) self.assertTrue("G" not in c, c) # test creation of alphanum challenge os = OCRASuite("OCRA-1:HOTP-SHA1-6:QA10-S128") c = os.create_challenge() self.assertEqual(len(c), 10) self.assertTrue("-" not in c, c) # test creation of numeric challenge os = OCRASuite("OCRA-1:HOTP-SHA1-6:QN10-S128") c = os.create_challenge() self.assertEqual(len(c), 10) # Test, if this is a number i_c = int(c)
def update(self, param): """ This method is called during the initialization process. :param param: parameters from the token init :type param: dict :return: None """ # We should only initialize such a token, when the user is # immediately given in the init process, since the token on the # smartphone needs to contain a userId. if not self.user: # The user and realms should have already been set in init_token() raise ParameterError("Missing parameter: {0!r}".format("user"), id=905) ocrasuite = get_from_config("tiqr.ocrasuite") or OCRA_DEFAULT_SUITE OCRASuite(ocrasuite) self.add_tokeninfo("ocrasuite", ocrasuite) TokenClass.update(self, param)
def update(self, param): """ This method is called during the initialization process. :param param: parameters from the token init :type param: dict :return: None """ user_object = get_user_from_param(param, optional) if user_object: self.add_user(user_object) ocrasuite = getParam(param, "ocrasuite", default=OCRA_DEFAULT_SUITE) OCRASuite(ocrasuite) self.add_tokeninfo("ocrasuite", ocrasuite) TokenClass.update(self, param) if user_object: # We have to set the realms here, since the token DB object does not # have an ID before TokenClass.update. self.set_realms([user_object.realm])
def update(self, param): """ This method is called during the initialization process. :param param: parameters from the token init :type param: dict :return: None """ # We should only initialize such a token, when the user is # immediately given in the init process, since the token on the # smartphone needs to contain a userId. user_object = get_user_from_param(param, required) self.set_user(user_object) ocrasuite = get_from_config("tiqr.ocrasuite") or OCRA_DEFAULT_SUITE OCRASuite(ocrasuite) self.add_tokeninfo("ocrasuite", ocrasuite) TokenClass.update(self, param) # We have to set the realms here, since the token DB object does not # have an ID before TokenClass.update. self.set_realms([user_object.realm])
def create_challenge(self, transactionid=None, options=None): """ This method creates a challenge, which is submitted to the user. The submitted challenge will be preserved in the challenge database. If no transaction id is given, the system will create a transaction id and return it, so that the response can refer to this transaction. :param transactionid: the id of this challenge :param options: the request context parameters / data :type options: dict :return: tuple of (bool, message, transactionid, reply_dict) :rtype: tuple The return tuple builds up like this: ``bool`` if submit was successful; ``message`` which is displayed in the JSON response; additional challenge ``reply_dict``, which are displayed in the JSON challenges response. """ options = options or {} message = 'Please answer the challenge' attributes = {} # Get ValidityTime=120s. Maybe there is a OCRAChallengeValidityTime... validity = int(get_from_config('DefaultChallengeValidityTime', 120)) tokentype = self.get_tokentype().lower() lookup_for = tokentype.capitalize() + 'ChallengeValidityTime' validity = int(get_from_config(lookup_for, validity)) # Get the OCRASUITE from the token information ocrasuite = self.get_tokeninfo("ocrasuite") or OCRA_DEFAULT_SUITE challenge = options.get("challenge") # TODO: we could add an additional parameter to hash the challenge # cleartext -> sha1 if not challenge: # If no challenge is given in the Request, we create a random # challenge based on the OCRA-SUITE os = OCRASuite(ocrasuite) challenge = os.create_challenge() else: # Add a random challenge if options.get("addrandomchallenge"): challenge += get_alphanum_str( int(options.get("addrandomchallenge"))) attributes["original_challenge"] = challenge attributes["qrcode"] = create_img(challenge) if options.get("hashchallenge", "").lower() == "sha256": challenge = hexlify_and_unicode( hashlib.sha256(to_bytes(challenge)).digest()) elif options.get("hashchallenge", "").lower() == "sha512": challenge = hexlify_and_unicode( hashlib.sha512(to_bytes(challenge)).digest()) elif options.get("hashchallenge"): challenge = hexlify_and_unicode( hashlib.sha1(to_bytes(challenge)).digest()) # Create the challenge in the database db_challenge = Challenge(self.token.serial, transaction_id=None, challenge=challenge, data=None, session=None, validitytime=validity) db_challenge.save() attributes["challenge"] = challenge reply_dict = {"attributes": attributes} return True, message, db_challenge.transaction_id, reply_dict
def create_challenge(self, transactionid=None, options=None): """ This method creates a challenge, which is submitted to the user. The submitted challenge will be preserved in the challenge database. If no transaction id is given, the system will create a transaction id and return it, so that the response can refer to this transaction. :param transactionid: the id of this challenge :param options: the request context parameters / data :type options: dict :return: tuple of (bool, message, transactionid, attributes) :rtype: tuple The return tuple builds up like this: ``bool`` if submit was successful; ``message`` which is displayed in the JSON response; additional ``attributes``, which are displayed in the JSON response. """ options = options or {} message = 'Please answer the challenge' attributes = {} # Get ValidityTime=120s. Maybe there is a OCRAChallengeValidityTime... validity = int(get_from_config('DefaultChallengeValidityTime', 120)) tokentype = self.get_tokentype().lower() lookup_for = tokentype.capitalize() + 'ChallengeValidityTime' validity = int(get_from_config(lookup_for, validity)) # Get the OCRASUITE from the token information ocrasuite = self.get_tokeninfo("ocrasuite") or OCRA_DEFAULT_SUITE challenge = options.get("challenge") # TODO: we could add an additional parameter to hash the challenge # cleartext -> sha1 if not challenge: # If no challenge is given in the Request, we create a random # challenge based on the OCRA-SUITE os = OCRASuite(ocrasuite) challenge = os.create_challenge() else: # Add a random challenge if options.get("addrandomchallenge"): challenge += get_alphanum_str(int(options.get( "addrandomchallenge"))) attributes["original_challenge"] = challenge attributes["qrcode"] = create_img(challenge) if options.get("hashchallenge", "").lower() == "sha256": challenge = binascii.hexlify(hashlib.sha256(challenge).digest()) elif options.get("hashchallenge", "").lower() == "sha512": challenge = binascii.hexlify(hashlib.sha512(challenge).digest()) elif options.get("hashchallenge"): challenge = binascii.hexlify(hashlib.sha1(challenge).digest()) # Create the challenge in the database db_challenge = Challenge(self.token.serial, transaction_id=None, challenge=challenge, data=None, session=None, validitytime=validity) db_challenge.save() attributes["challenge"] = challenge return True, message, db_challenge.transaction_id, attributes