Exemplo n.º 1
0
    def challenge(self, data, session='', typ='raw', challenge=None):
        '''
        the challenge method is for creating an transaction / challenge object

        remark: the transaction has a maximum lifetime and a reference to
                the OcraSuite token (serial)

        :param data:     data, which is the base for the challenge or None
        :type data:     string or None
        :param session:  session support for ocratokens
        :type session:  string
        :type typ:      define, which kind of challenge base should be used
                         could be raw - take the data input as is
                               (extract chars accordind challenge definition Q)
                         or random    - will generate a random input
                         or hased     - will take the hash of the input data

        :return:    challenge response containing the transcation id and the
                    challenge for the ocrasuite
        :rtype :    tuple of (transId(string), challenge(string))


        '''
        log.debug('[challenge] %r: %r: %r' % (data, session, challenge))

        secretHOtp = self.token.getHOtpKey()
        ocraSuite = OcraSuite(self.getOcraSuiteSuite(), secretHOtp)

        if data is None or len(data) == 0:
            typ = 'random'

        if challenge is None:
            if typ == 'raw':
                challenge = ocraSuite.data2rawChallenge(data)
            elif typ == 'random':
                challenge = ocraSuite.data2randomChallenge(data)
            elif typ == 'hash':
                challenge = ocraSuite.data2hashChallenge(data)

        log.debug('[Ocra2TokenClass] challenge: %r ' % (challenge))

        counter = self.getOtpCount()

        ## set the pin onyl in the compliant hashed mode
        pin = ''
        if ocraSuite.P is not None:
            pinObj = self.token.getUserPin()
            pin = pinObj.getKey()

        try:
            param = {}
            param['C'] = counter
            param['Q'] = challenge
            param['P'] = pin
            param['S'] = session
            if ocraSuite.T is not None:
                now = datetime.datetime.now()
                stime = now.strftime("%s")
                itime = int(stime)
                param['T'] = itime

            ''' verify that the data is compliant with the OcraSuitesuite
                and the client is able to calc the otp
            '''
            c_data = ocraSuite.combineData(**param)
            ocraSuite.compute(c_data)

        except Exception as ex:
            log.error("[Ocra2TokenClass] %r" % (traceback.format_exc()))
            raise Exception('[Ocra2TokenClass] Failed to create ocrasuite '
                                                        'challenge: %r' % (ex))

        ##  create a non exisiting challenge
        try:

            (res, opt) = create_challenge(self, options={'messgae': data})

            transid = opt.get('transactionid')
            challenge = opt.get('challenge')

        except Exception as ex:
            ##  this might happen if we have a db problem or
            ##   the uniqnes constrain does not fit
            log.error("[Ocra2TokenClass] %r" % (traceback.format_exc()))
            raise Exception('[Ocra2TokenClass] Failed to create '
                                                'challenge object: %s' % (ex))

        realm = None
        realms = self.token.getRealms()
        if len(realms) > 0:
            realm = realms[0]

        url = ''
        if realm is not None:
            url = get_qrtan_url(realm.name)

        log.debug('[challenge]: %r: %r: %r' % (transid, challenge, url))
        return (transid, challenge, True, url)
Exemplo n.º 2
0
    def challenge(self, data, session='', typ='raw', challenge=None):
        '''
        the challenge method is for creating an transaction / challenge object

        remark: the transaction has a maximum lifetime and a reference to
                the OcraSuite token (serial)

        :param data:     data, which is the base for the challenge or None
        :type data:     string or None
        :param session:  session support for ocratokens
        :type session:  string
        :type typ:      define, which kind of challenge base should be used
                         could be raw - take the data input as is
                              (extract chars accordind challenge definition Q)
                         or random    - will generate a random input
                         or hased     - will take the hash of the input data

        :return:    challenge response containing the transcation id and
                    the challenge for the ocrasuite
        :rtype :    tuple of (transId(string), challenge(string))

        '''

        s_data = 'None'
        s_session = 'None'
        s_challenge = 'None'
        if data is not None:
            s_data = data
        if session is not None:
            s_session = session
        if challenge is None:
            s_challenge = challenge

        secObj = self._get_secret_object()
        ocraSuite = OcraSuite(self.getOcraSuiteSuite(), secObj)

        if not data:
            typ = 'random'

        if challenge is None:
            if typ == 'raw':
                challenge = ocraSuite.data2rawChallenge(data)
            elif typ == 'random':
                challenge = ocraSuite.data2randomChallenge(data)
            elif typ == 'hash':
                challenge = ocraSuite.data2hashChallenge(data)

        serial = self.getSerial()
        counter = self.getOtpCount()

        # set the pin onyl in the compliant hashed mode
        pin = ''
        if ocraSuite.P is not None:
            key, iv = self.token.getUserPin()
            secObj = SecretObj(key, iv, hsm=context.get('hsm'))
            pin = secObj.getKey()

        try:
            param = {}
            param['C'] = counter
            param['Q'] = challenge
            param['P'] = pin
            param['S'] = session
            if ocraSuite.T is not None:
                now = datetime.datetime.now()
                stime = now.strftime("%s")
                itime = int(stime)
                param['T'] = itime
            ''' verify that the data is compliant with the OcraSuitesuite
                and the client is able to calc the otp
            '''
            c_data = ocraSuite.combineData(**param)
            ocraSuite.compute(c_data)

        except Exception as ex:
            log.exception(
                "[OcraTokenClass] Failed to create ocrasuite challenge")
            raise Exception('[OcraTokenClass] Failed to create ocrasuite'
                            'challenge: %r' % (ex))

        #  save the object
        digits = '0123456789'
        transid = ''
        transactionIdLen = 12

        try:
            transactionIdLen = int(getFromConfig("OcraDefaultSuite", '12'))
        except:
            transactionIdLen = 12
            log.debug("[OcraTokenClass] Failed to set transactionId length"
                      " from config - using fallback %d" % (transactionIdLen))

        #  create a non exisiting challenge
        try:
            while True:
                for _c in range(0, transactionIdLen):
                    transid += urandom.choice(digits)

                chall = OcraTokenClass.getTransaction(transid)
                if chall is None:
                    break

            ddata = ''
            if data is not None:
                ddata = data

            chall = OcraChallenge(transid=transid,
                                  tokenserial=serial,
                                  challenge=typ + ':' + challenge,
                                  data=typ + ':' + ddata)
            chall.save()

        except Exception as ex:
            #  this might happen if we have a db problem or
            # the uniqnes constrain does not fit
            log.exception("[OcraTokenClass] Failed to create challenge")
            raise Exception('[OcraTokenClass] Failed to create challenge'
                            ' object: %s' % (ex))

        realms = []
        tokenrealms = self.token.getRealms()
        for realm in tokenrealms:
            realms.append(realm.name)

        url = get_qrtan_url(realms)

        return (transid, challenge, True, url)
Exemplo n.º 3
0
    def createChallenge(self, state, options=None):
        '''
        standard API to create an ocra challenge
        '''
        res = True

        ## which kind of challenge gen should be used
        typ = 'raw'

        input = None
        challenge = None
        session = None
        message = ""

        if options is not None:
            input = options.get('challenge', None)
            if input is None:
                input = options.get('message', None)
            if input is None:
                input = options.get('data', None)

            typ = options.get('challenge_type', 'raw')
            ## ocra token could contain a session attribute
            session = options.get('ocra_session', None)

        if input is None or len(input) == 0:
            typ = 'random'

        secretHOtp = self.token.getHOtpKey()
        ocraSuite = OcraSuite(self.getOcraSuiteSuite(), secretHOtp)

        if typ == 'raw':
            challenge = ocraSuite.data2rawChallenge(input)
        elif typ == 'random':
            challenge = ocraSuite.data2randomChallenge(input)
        elif typ == 'hash':
            challenge = ocraSuite.data2hashChallenge(input)

        log.debug('[Ocra2TokenClass] challenge: %r ' % (challenge))

        store_data = {
                'challenge' : "%s" % (challenge),
                'serial' : self.token.getSerial(),
                'input' : '',
                'url' : '',
                }

        if input is not None:
            store_data['input'] = input

        if session is not None:
            store_data["session"] = session

        res = self.verify_challenge_is_valid(challenge, session)

        ## add Info: so depending on the Info, the rendering could be done
        ##          as a callback into the token via
        ##          token.getQRImageData(opt=details)
        realms = self.token.getRealms()
        if len(realms) > 0:
            store_data["url"] = get_qrtan_url(realms[0].name)

        ## we will return a dict of all
        attributes = self.prepare_message(store_data, state)
        attributes['challenge'] = challenge

        if attributes != None and "data" in attributes:
            message = attributes.get("data")
            del attributes['data']

        return (res, message, store_data, attributes)
Exemplo n.º 4
0
    def challenge(self, data, session='', typ='raw', challenge=None):
        '''
        the challenge method is for creating an transaction / challenge object

        remark: the transaction has a maximum lifetime and a reference to
                the OcraSuite token (serial)

        :param data:     data, which is the base for the challenge or None
        :type data:     string or None
        :param session:  session support for ocratokens
        :type session:  string
        :type typ:      define, which kind of challenge base should be used
                         could be raw - take the data input as is
                              (extract chars accordind challenge definition Q)
                         or random    - will generate a random input
                         or hased     - will take the hash of the input data

        :return:    challenge response containing the transcation id and
                    the challenge for the ocrasuite
        :rtype :    tuple of (transId(string), challenge(string))

        '''

        s_data = 'None'
        s_session = 'None'
        s_challenge = 'None'
        if data is not None:
            s_data = data
        if session is not None:
            s_session = session
        if challenge is None:
            s_challenge = challenge

        secObj = self._get_secret_object()
        ocraSuite = OcraSuite(self.getOcraSuiteSuite(), secObj)

        if not data:
            typ = 'random'

        if challenge is None:
            if typ == 'raw':
                challenge = ocraSuite.data2rawChallenge(data)
            elif typ == 'random':
                challenge = ocraSuite.data2randomChallenge(data)
            elif typ == 'hash':
                challenge = ocraSuite.data2hashChallenge(data)

        serial = self.getSerial()
        counter = self.getOtpCount()

        # set the pin onyl in the compliant hashed mode
        pin = ''
        if ocraSuite.P is not None:
            key, iv = self.token.getUserPin()
            secObj = SecretObj(key, iv, hsm=context.get('hsm'))
            pin = secObj.getKey()

        try:
            param = {}
            param['C'] = counter
            param['Q'] = challenge
            param['P'] = pin
            param['S'] = session
            if ocraSuite.T is not None:
                now = datetime.datetime.now()
                stime = now.strftime("%s")
                itime = int(stime)
                param['T'] = itime

            ''' verify that the data is compliant with the OcraSuitesuite
                and the client is able to calc the otp
            '''
            c_data = ocraSuite.combineData(**param)
            ocraSuite.compute(c_data)

        except Exception as ex:
            log.exception("[OcraTokenClass] Failed to create ocrasuite challenge")
            raise Exception('[OcraTokenClass] Failed to create ocrasuite'
                            'challenge: %r' % (ex))

        #  save the object
        digits = '0123456789'
        transid = ''
        transactionIdLen = 12

        try:
            transactionIdLen = int(getFromConfig("OcraDefaultSuite", '12'))
        except:
            transactionIdLen = 12
            log.debug("[OcraTokenClass] Failed to set transactionId length"
                      " from config - using fallback %d" % (transactionIdLen))

        #  create a non exisiting challenge
        try:
            while True:
                for _c in range(0, transactionIdLen):
                    transid += urandom.choice(digits)

                chall = OcraTokenClass.getTransaction(transid)
                if chall is None:
                    break

            ddata = ''
            if data is not None:
                ddata = data

            chall = OcraChallenge(transid=transid,
                                  tokenserial=serial,
                                  challenge=typ + ':' + challenge,
                                  data=typ + ':' + ddata)
            chall.save()

        except Exception as ex:
            #  this might happen if we have a db problem or
            # the uniqnes constrain does not fit
            log.exception("[OcraTokenClass] Failed to create challenge")
            raise Exception('[OcraTokenClass] Failed to create challenge'
                            ' object: %s' % (ex))

        realms = []
        tokenrealms = self.token.getRealms()
        for realm in tokenrealms:
            realms.append(realm.name)

        url = get_qrtan_url(realms)

        return (transid, challenge, True, url)