Esempio n. 1
0
    def _getChallenge(self,
                      ocrasuite,
                      bkey,
                      serial,
                      ocrapin='',
                      data=None,
                      count=0,
                      ttime=None):

        otp1 = None

        p = {
            "serial": serial,
            "data": "0105037311 Konto 50150850 BLZ 1752,03 Eur"
        }
        if data is not None:
            p[data] = data

        response = self.app.get(genUrl(controller='ocra', action='request'),
                                params=p)
        log.info("response %s\n", response)
        assert '"value": true' in response
        ''' -2b- from the response get the challenge '''
        jresp = json.loads(response.body)
        challenge1 = str(jresp.get('detail').get('challenge'))
        transid1 = str(jresp.get('detail').get('transactionid'))

        now = datetime.now()
        if ttime is not None:
            now = ttime
        stime = now.strftime("%s")
        itime = int(stime)

        param = {}
        param['C'] = count
        param['Q'] = challenge1
        param['P'] = ocrapin
        param['S'] = ''
        param['T'] = itime

        ocra = OcraSuite(ocrasuite)
        data = ocra.combineData(**param)
        otp1 = ocra.compute(data, bkey)

        return (otp1, transid1)
Esempio n. 2
0
    def _getChallenge(self, ocrasuite, bkey, serial, ocrapin='', data=None, count=0, ttime=None):

        otp1 = None

        p = {"serial"      : serial,
             "data"        : "0105037311 Konto 50150850 BLZ 1752,03 Eur"
            }
        if data is not None:
            p[data] = data

        response = self.app.get(genUrl(controller='ocra', action='request'), params=p)
        log.info("response %s\n", response)
        assert '"value": true' in response

        ''' -2b- from the response get the challenge '''
        jresp = json.loads(response.body)
        challenge1 = str(jresp.get('detail').get('challenge'))
        transid1 = str(jresp.get('detail').get('transactionid'))


        now = datetime.now()
        if ttime is not None:
            now = ttime
        stime = now.strftime("%s")
        itime = int(stime)

        param = {}
        param['C'] = count
        param['Q'] = challenge1
        param['P'] = ocrapin
        param['S'] = ''
        param['T'] = itime

        ocra = OcraSuite(ocrasuite)
        data = ocra.combineData(**param)
        otp1 = ocra.compute(data, bkey)

        return (otp1, transid1)
Esempio n. 3
0
    def ptest_OCRA_token_failcounterInc(self, tid=1):
        '''
            test_OCRA_token_failcounterInc: failcounter increment

            description:
                for all ocrasuites:
                   create and enroll token
                   verify the first otp
                   get some challenges
                   4 times:
                      verify a wrong otp
                      verify a wrong transaction
                      check status and if fail counter has incremented
        '''
        tcount = 0
        for test in self.tests:
            ocrasuite = test['ocrasuite']
            key = test['keyh']
            bkey = test['key']
            ocrapin = 'myocrapin'
            tid = tid
            serial = "QR_One_%r_%r_%r_%r" % (tid, tcount, int(time.time()), random.randint(0, 100))
            log.info("## serial: %s" % serial)
            count = 0
            tcount = tcount + 1

            ocra = OcraSuite(ocrasuite)
            pinlen = ocra.truncation
            ''' -1- create an ocra token '''
            parameters = {
                          "serial"      : serial,
                          "user"        : "root",
                          "pin"         : "pin",
                          "description" : "first QRToken",
                          'type'        : 'ocra',
                          'ocrapin'     : ocrapin,
                          'otpkey'      : key,
                          'ocrasuite'   : ocrasuite
                          }

            response = self.app.get(genUrl(controller='admin', action='init'), params=parameters)
            assert '"value": true' in response

            ## verify that the token is usable
            ''' -2- fetch the challenge '''
            p = {"serial"      : serial,
                 "data"        : "0105037311 Konto 50150850 BLZ 1752,03 Eur"
                }
            response = self.app.get(genUrl(controller='ocra', action='request'), params=p)
            log.info("response %s\n", response)
            if '"value": true' not in response:
                assert '"value": true' in response

            ''' -3.a- from the response get the challenge '''
            jresp = json.loads(response.body)
            challenge = str(jresp.get('detail').get('challenge'))
            transid = str(jresp.get('detail').get('transactionid'))

            param = {}
            param['C'] = count
            param['Q'] = challenge
            param['P'] = ocrapin
            param['S'] = ''
            if ocra.T is not None:
                '''    Default value for G is 1M, i.e., time-step size is one minute and the
                       T represents the number of minutes since epoch time [UT].
                '''
                now = datetime.now()
                stime = now.strftime("%s")
                itime = int(stime)
                param['T'] = itime

            ocra = OcraSuite(ocrasuite)
            data = ocra.combineData(**param)
            otp = ocra.compute(data, bkey)

            ppin = 'pin' + otp

            ''' -3.b- verify the correct otp value '''
            parameters = {"transactionid"   : transid,
                          "pass"            : ppin,
                          }
            response = self.app.get(genUrl(controller='ocra', action='check_t'), params=parameters)
            log.info("response %s\n", response)
            if '"result": true' not in response:
                assert '"result": true' in response

            # verify that the failcounter increments (max is 10)
            fcount = 0
            for count in range(1, 3):

                ## create more than one challenge
                chals = random.randint(2, 5)
                for cc in range(1, chals):
                    ''' -2- fetch the challenge '''
                    p = {"serial"      : serial,
                         "data"        : "0105037311 Konto 50150850 BLZ 1752,03 Eur"
                        }
                    response = self.app.get(genUrl(controller='ocra', action='request'), params=p)
                    log.info("response %s\n", response)
                    if '"value": true' not in response:
                        assert '"value": true' in response


                ''' -3.a- from the response get the challenge '''
                jresp = json.loads(response.body)
                challenge = str(jresp.get('detail').get('challenge'))
                transid = str(jresp.get('detail').get('transactionid'))

                ppin = 'pin' + 'a' * pinlen

                ''' -4- verify the wrong otp value '''
                parameters = {"transactionid"   : transid,
                              "pass"            : ppin,
                              }
                response = self.app.get(genUrl(controller='ocra', action='check_t'), params=parameters)
                log.info("response %s\n", response)
                if '"result": false' not in response:
                    assert '"result": false' in response
                fcount += 1

                ppin = 'pin' + '4' * pinlen

                ''' -5- verify the wrong otp value '''
                parameters = {"transactionid"   : transid,
                              "pass"            : ppin,
                              }
                response = self.app.get(genUrl(controller='ocra', action='check_t'), params=parameters)
                log.info("response %s\n", response)
                if not '"result": false' in response:
                    assert '"result": false' in response
                fcount += 1

                ''' -6- check if the failcounter has incremented  '''
                parameters = {"transactionid"   : transid,
                              }
                response = self.app.get(genUrl(controller='ocra', action='checkstatus'), params=parameters)
                log.info("response %s\n", response)
                assert '"status": true' in response
                assstring = '"failcount": %d,' % (fcount)
                log.info("assert %s\n", assstring)
                if assstring not in response:
                    log.error(response)
                    assert assstring in response

                sleep = random.uniform(0.0, 0.3)
                time.sleep(sleep)

            ''' -remove the ocra token '''
            parameters = {"serial"      : serial, }
            response = self.app.get(genUrl(controller='admin', action='remove'), params=parameters)
            log.info("response %s\n", response)
            assert '"value": 1' in response

            for _iii in range(0, 3):
                parameters = {"serial"      : serial, }
                response = self.app.get(genUrl(controller='admin', action='remove'), params=parameters)


        return response
Esempio n. 4
0
class OcraOtp(object):

    def __init__(self, ocrapin=None):
        self.ocra = None
        self.bkey = None
        self.ocrapin = ocrapin
        self.activationkey = None
        self.sharedsecret = None
        self.ocrasuite = None
        self.serial = None
        self.counter = 0


    def init_1(self, response):
        ''' take the response of the first init to setup the OcraOtp'''

        jresp = json.loads(response.body)
        app_import = str(jresp.get('detail').get('app_import'))
        self.sharedsecret = str(jresp.get('detail').get('sharedsecret'))
        self.serial = str(jresp.get('detail').get('serial'))

        ''' now parse the appurl for the ocrasuite '''
        uri = urlparse(app_import.replace('lseqr://', 'http://'))
        qs = uri.query
        qdict = parse_qs(qs)

        ocrasuite = qdict.get('os', None)
        if ocrasuite is not None and len(ocrasuite) > 0:
            ocrasuite = ocrasuite[0]

        self.ocrasuite = ocrasuite

        return (self.ocrasuite, self.sharedsecret, self.serial)


    def init_2(self, response, activationKey):
        self.activationkey = activationKey

        jresp = json.loads(response.body)
        self.nonce = str(jresp.get('detail').get('nonce'))
        self.transid = str(jresp.get('detail').get('transactionid'))
        app_import = str(jresp.get('detail').get('app_import'))


        ''' now parse the appurl for the ocrasuite '''
        uri = urlparse(app_import.replace('lseqr://', 'http://'))
        qs = uri.query
        qdict = parse_qs(qs)
        nonce = qdict.get('no', None)
        if nonce is not None and len(nonce) > 0:
            nonce = nonce[0]

        challenge = qdict.get('ch', None)
        if challenge is not None and len(challenge) > 0:
            challenge = challenge[0]

        self.challenge = challenge
        self.ocra = None
        self.bkey = None

        return (self.challenge, self.transid)


    def _setup_(self):

        if self.ocra is not None and self.bkey is not None:
            return

        key_len = 20
        if self.ocrasuite.find('-SHA256'):
            key_len = 32
        elif self.ocrasuite.find('-SHA512'):
            key_len = 64

        self.bkey = kdf2(self.sharedsecret, self.nonce, self.activationkey, len=key_len)
        self.ocra = OcraSuite(self.ocrasuite)

        self.counter = 0

        return

    def callcOtp(self, challenge=None, ocrapin=None, counter= -1):

        if self.ocra is None:
            self._setup_()

        if ocrapin is None:
            ocrapin = self.ocrapin

        if challenge is None:
            challenge = self.challenge
        if counter == -1:
            counter = self.counter

        param = {}
        param['C'] = counter
        param['Q'] = challenge
        param['P'] = ocrapin
        param['S'] = ''
        if self.ocra.T is not None:
            '''    Default value for G is 1M, i.e., time-step size is one minute and the
                   T represents the number of minutes since epoch time [UT].
            '''
            now = datetime.now()
            stime = now.strftime("%s")
            itime = int(stime)
            param['T'] = itime

        data = self.ocra.combineData(**param)
        otp = self.ocra.compute(data, self.bkey)

        if counter == -1:
            self.counter += 1

        return otp
Esempio n. 5
0
class OcraOtp(object):
    def __init__(self, ocrapin=None):
        self.ocra = None
        self.bkey = None
        self.ocrapin = ocrapin
        self.activationkey = None
        self.sharedsecret = None
        self.ocrasuite = None
        self.serial = None
        self.counter = 0

    def init_1(self, response):
        ''' take the response of the first init to setup the OcraOtp'''

        jresp = json.loads(response.body)
        app_import = str(jresp.get('detail').get('app_import'))
        self.sharedsecret = str(jresp.get('detail').get('sharedsecret'))
        self.serial = str(jresp.get('detail').get('serial'))
        ''' now parse the appurl for the ocrasuite '''
        uri = urlparse(app_import.replace('lseqr://', 'http://'))
        qs = uri.query
        qdict = parse_qs(qs)

        ocrasuite = qdict.get('os', None)
        if ocrasuite is not None and len(ocrasuite) > 0:
            ocrasuite = ocrasuite[0]

        self.ocrasuite = ocrasuite

        return (self.ocrasuite, self.sharedsecret, self.serial)

    def init_2(self, response, activationKey):
        self.activationkey = activationKey

        jresp = json.loads(response.body)
        self.nonce = str(jresp.get('detail').get('nonce'))
        self.transid = str(jresp.get('detail').get('transactionid'))
        app_import = str(jresp.get('detail').get('app_import'))
        ''' now parse the appurl for the ocrasuite '''
        uri = urlparse(app_import.replace('lseqr://', 'http://'))
        qs = uri.query
        qdict = parse_qs(qs)
        nonce = qdict.get('no', None)
        if nonce is not None and len(nonce) > 0:
            nonce = nonce[0]

        challenge = qdict.get('ch', None)
        if challenge is not None and len(challenge) > 0:
            challenge = challenge[0]

        self.challenge = challenge
        self.ocra = None
        self.bkey = None

        return (self.challenge, self.transid)

    def _setup_(self):

        if self.ocra is not None and self.bkey is not None:
            return

        key_len = 20
        if self.ocrasuite.find('-SHA256'):
            key_len = 32
        elif self.ocrasuite.find('-SHA512'):
            key_len = 64

        self.bkey = kdf2(self.sharedsecret,
                         self.nonce,
                         self.activationkey,
                         len=key_len)
        self.ocra = OcraSuite(self.ocrasuite)

        self.counter = 0

        return

    def callcOtp(self, challenge=None, ocrapin=None, counter=-1):

        if self.ocra is None:
            self._setup_()

        if ocrapin is None:
            ocrapin = self.ocrapin

        if challenge is None:
            challenge = self.challenge
        if counter == -1:
            counter = self.counter

        param = {}
        param['C'] = counter
        param['Q'] = challenge
        param['P'] = ocrapin
        param['S'] = ''
        if self.ocra.T is not None:
            '''    Default value for G is 1M, i.e., time-step size is one minute and the
                   T represents the number of minutes since epoch time [UT].
            '''
            now = datetime.now()
            stime = now.strftime("%s")
            itime = int(stime)
            param['T'] = itime

        data = self.ocra.combineData(**param)
        otp = self.ocra.compute(data, self.bkey)

        if counter == -1:
            self.counter += 1

        return otp
Esempio n. 6
0
    def ptest_OCRA_token_failcounterInc(self, tid=1):
        '''
            test_OCRA_token_failcounterInc: failcounter increment

            description:
                for all ocrasuites:
                   create and enroll token
                   verify the first otp
                   get some challenges
                   4 times:
                      verify a wrong otp
                      verify a wrong transaction
                      check status and if fail counter has incremented
        '''
        tcount = 0
        for test in self.tests:
            ocrasuite = test['ocrasuite']
            key = test['keyh']
            bkey = test['key']
            ocrapin = 'myocrapin'
            tid = tid
            serial = "QR_One_%r_%r_%r_%r" % (tid, tcount, int(
                time.time()), random.randint(0, 100))
            log.info("## serial: %s" % serial)
            count = 0
            tcount = tcount + 1

            ocra = OcraSuite(ocrasuite)
            pinlen = ocra.truncation
            ''' -1- create an ocra token '''
            parameters = {
                "serial": serial,
                "user": "******",
                "pin": "pin",
                "description": "first QRToken",
                'type': 'ocra',
                'ocrapin': ocrapin,
                'otpkey': key,
                'ocrasuite': ocrasuite
            }

            response = self.app.get(genUrl(controller='admin', action='init'),
                                    params=parameters)
            assert '"value": true' in response

            ## verify that the token is usable
            ''' -2- fetch the challenge '''
            p = {
                "serial": serial,
                "data": "0105037311 Konto 50150850 BLZ 1752,03 Eur"
            }
            response = self.app.get(genUrl(controller='ocra',
                                           action='request'),
                                    params=p)
            log.info("response %s\n", response)
            if '"value": true' not in response:
                assert '"value": true' in response
            ''' -3.a- from the response get the challenge '''
            jresp = json.loads(response.body)
            challenge = str(jresp.get('detail').get('challenge'))
            transid = str(jresp.get('detail').get('transactionid'))

            param = {}
            param['C'] = count
            param['Q'] = challenge
            param['P'] = ocrapin
            param['S'] = ''
            if ocra.T is not None:
                '''    Default value for G is 1M, i.e., time-step size is one minute and the
                       T represents the number of minutes since epoch time [UT].
                '''
                now = datetime.now()
                stime = now.strftime("%s")
                itime = int(stime)
                param['T'] = itime

            ocra = OcraSuite(ocrasuite)
            data = ocra.combineData(**param)
            otp = ocra.compute(data, bkey)

            ppin = 'pin' + otp
            ''' -3.b- verify the correct otp value '''
            parameters = {
                "transactionid": transid,
                "pass": ppin,
            }
            response = self.app.get(genUrl(controller='ocra',
                                           action='check_t'),
                                    params=parameters)
            log.info("response %s\n", response)
            if '"result": true' not in response:
                assert '"result": true' in response

            # verify that the failcounter increments (max is 10)
            fcount = 0
            for count in range(1, 3):

                ## create more than one challenge
                chals = random.randint(2, 5)
                for cc in range(1, chals):
                    ''' -2- fetch the challenge '''
                    p = {
                        "serial": serial,
                        "data": "0105037311 Konto 50150850 BLZ 1752,03 Eur"
                    }
                    response = self.app.get(genUrl(controller='ocra',
                                                   action='request'),
                                            params=p)
                    log.info("response %s\n", response)
                    if '"value": true' not in response:
                        assert '"value": true' in response
                ''' -3.a- from the response get the challenge '''
                jresp = json.loads(response.body)
                challenge = str(jresp.get('detail').get('challenge'))
                transid = str(jresp.get('detail').get('transactionid'))

                ppin = 'pin' + 'a' * pinlen
                ''' -4- verify the wrong otp value '''
                parameters = {
                    "transactionid": transid,
                    "pass": ppin,
                }
                response = self.app.get(genUrl(controller='ocra',
                                               action='check_t'),
                                        params=parameters)
                log.info("response %s\n", response)
                if '"result": false' not in response:
                    assert '"result": false' in response
                fcount += 1

                ppin = 'pin' + '4' * pinlen
                ''' -5- verify the wrong otp value '''
                parameters = {
                    "transactionid": transid,
                    "pass": ppin,
                }
                response = self.app.get(genUrl(controller='ocra',
                                               action='check_t'),
                                        params=parameters)
                log.info("response %s\n", response)
                if not '"result": false' in response:
                    assert '"result": false' in response
                fcount += 1
                ''' -6- check if the failcounter has incremented  '''
                parameters = {
                    "transactionid": transid,
                }
                response = self.app.get(genUrl(controller='ocra',
                                               action='checkstatus'),
                                        params=parameters)
                log.info("response %s\n", response)
                assert '"status": true' in response
                assstring = '"failcount": %d,' % (fcount)
                log.info("assert %s\n", assstring)
                if assstring not in response:
                    log.error(response)
                    assert assstring in response

                sleep = random.uniform(0.0, 0.3)
                time.sleep(sleep)
            ''' -remove the ocra token '''
            parameters = {
                "serial": serial,
            }
            response = self.app.get(genUrl(controller='admin',
                                           action='remove'),
                                    params=parameters)
            log.info("response %s\n", response)
            assert '"value": 1' in response

            for _iii in range(0, 3):
                parameters = {
                    "serial": serial,
                }
                response = self.app.get(genUrl(controller='admin',
                                               action='remove'),
                                        params=parameters)

        return response
Esempio n. 7
0
    def calculateOtp(self):
        '''

        '''
        from linotp.lib.crypto import kdf2
        from linotp.tokens.ocra import OcraSuite
        from datetime import datetime

        from urlparse import urlparse
        from urlparse import parse_qs

        res = {}

        # description = 'ocra/calculateOtp: calculate the first
        # otp from the given init2 response '

        try:
            params = getLowerParams(request.params)
            log.debug("[calculateOtp]: %r" % params)

            checkPolicyPre('ocra', "calcOTP")

            sharedsecret = params.get('sharedsecret')
            activationcode = params.get('activationcode')
            nonce = params.get('nonce')
            ocrasuite = params.get('ocrasuite')
            challenge = params.get('challenge')
            counter = params.get('counter')
            ocrapin = params.get('ocrapin')

            nonce3 = params.get('no')
            ocrasuite3 = params.get('os')

            challenge = params.get('challenge')
            counter = params.get('counter')
            ocrapin = params.get('ocrapin')
            init1 = params.get('init1')
            init2 = params.get('init2')

            if init1 is not None:

                # now parse the appurl for the ocrasuite

                uri = urlparse(init1.replace('lseqr://', 'http://'))
                qs = uri.query
                qdict = parse_qs(qs)

                ocrasuite2 = qdict.get('os', None)
                if ocrasuite2 is not None and len(ocrasuite2) > 0:
                    ocrasuite2 = ocrasuite2[0]

                if ocrasuite is None:
                    ocrasuite = ocrasuite2

                sharedsecret2 = qdict.get('sh', None)
                if sharedsecret2 is not None and len(sharedsecret2) > 0:
                    sharedsecret2 = sharedsecret2[0]

                if sharedsecret is None:
                    sharedsecret = sharedsecret2

            # parse init1

            if init2 is not None:

                # now parse the appurl for the ocrasuite

                uri = urlparse(init2.replace('lseqr://', 'http://'))
                qs = uri.query
                qdict = parse_qs(qs)

                challenge2 = qdict.get('ch', None)
                if challenge2 is not None and len(challenge2) > 0:
                    challenge2 = challenge2[0]
                if challenge is None:
                    challenge = challenge2

                nonce2 = qdict.get('no', None)
                if nonce2 is not None and len(nonce2) > 0:
                    nonce2 = nonce2[0]
                if nonce is None:
                    nonce = nonce2

            if ocrapin is None:
                ocrapin = ''
            if counter is None:
                counter = 0

            if nonce3 is not None:
                nonce = unicode(nonce3)

            if ocrasuite3 is not None:
                ocrasuite = unicode(ocrasuite3)

            #  now we have all in place for the key derivation to create
            # the new key sharedsecret, activationcode and nonce

            key_len = 20
            if ocrasuite.find('-SHA256'):
                key_len = 32
            elif ocrasuite.find('-SHA512'):
                key_len = 64

            if sharedsecret is not None:
                sharedsecret = unicode(sharedsecret)
            if nonce is not None:
                nonce = unicode(nonce)
            if activationcode is not None:
                activationcode = unicode(activationcode)

            newkey = kdf2(sharedsecret, nonce, activationcode, len=key_len)
            ocra = OcraSuite(ocrasuite)

            param = {}
            param['C'] = int(counter)
            param['Q'] = unicode(challenge)
            param['P'] = unicode(ocrapin)
            param['S'] = ''

            if ocra.T is not None:

                # Default value for G is 1M, i.e., time-step size is
                # one minute and the T represents the number of minutes
                # since epoch time [UT].

                now = datetime.now()
                stime = now.strftime("%s")
                itime = int(stime)
                param['T'] = itime

            data = ocra.combineData(**param)
            otp = ocra.compute(data, newkey)

            res = {'otp': otp}

            Session.commit()
            return sendResult(response, res, 1)

        except PolicyException as pe:
            log.exception("[ocra/calculateOtp] policy failed: %r" % pe)
            Session.rollback()
            return sendError(response, pe)

        except Exception as e:
            log.exception("[ocra/calculateOtp] failed: %r" % e)
            Session.rollback()
            return sendError(response, unicode(e), 0)

        finally:
            Session.close()
Esempio n. 8
0
    def calculateOtp(self):
        '''

        '''
        from linotp.lib.crypto import kdf2
        from linotp.tokens.ocra import OcraSuite
        from datetime import datetime

        from urlparse import urlparse
        from urlparse import parse_qs

        res = {}

        # description = 'ocra/calculateOtp: calculate the first
        # otp from the given init2 response '

        try:
            params = getLowerParams(self.request_params)
            log.debug("[calculateOtp]: %r" % params)

            checkPolicyPre('ocra', "calcOTP")

            sharedsecret = params.get('sharedsecret')
            activationcode = params.get('activationcode')
            nonce = params.get('nonce')
            ocrasuite = params.get('ocrasuite')
            challenge = params.get('challenge')
            counter = params.get('counter')
            ocrapin = params.get('ocrapin')

            nonce3 = params.get('no')
            ocrasuite3 = params.get('os')

            challenge = params.get('challenge')
            counter = params.get('counter')
            ocrapin = params.get('ocrapin')
            init1 = params.get('init1')
            init2 = params.get('init2')

            if init1 is not None:

                # now parse the appurl for the ocrasuite

                uri = urlparse(init1.replace('lseqr://', 'http://'))
                qs = uri.query
                qdict = parse_qs(qs)

                ocrasuite2 = qdict.get('os', None)
                if ocrasuite2 is not None and len(ocrasuite2) > 0:
                    ocrasuite2 = ocrasuite2[0]

                if ocrasuite is None:
                    ocrasuite = ocrasuite2

                sharedsecret2 = qdict.get('sh', None)
                if sharedsecret2 is not None and len(sharedsecret2) > 0:
                    sharedsecret2 = sharedsecret2[0]

                if sharedsecret is None:
                    sharedsecret = sharedsecret2

            # parse init1

            if init2 is not None:

                # now parse the appurl for the ocrasuite

                uri = urlparse(init2.replace('lseqr://', 'http://'))
                qs = uri.query
                qdict = parse_qs(qs)

                challenge2 = qdict.get('ch', None)
                if challenge2 is not None and len(challenge2) > 0:
                    challenge2 = challenge2[0]
                if challenge is None:
                    challenge = challenge2

                nonce2 = qdict.get('no', None)
                if nonce2 is not None and len(nonce2) > 0:
                    nonce2 = nonce2[0]
                if nonce is None:
                    nonce = nonce2

            if ocrapin is None:
                ocrapin = ''
            if counter is None:
                counter = 0

            if nonce3 is not None:
                nonce = unicode(nonce3)

            if ocrasuite3 is not None:
                ocrasuite = unicode(ocrasuite3)

            #  now we have all in place for the key derivation to create
            # the new key sharedsecret, activationcode and nonce

            key_len = 20
            if ocrasuite.find('-SHA256'):
                key_len = 32
            elif ocrasuite.find('-SHA512'):
                key_len = 64

            if sharedsecret is not None:
                sharedsecret = unicode(sharedsecret)
            if nonce is not None:
                nonce = unicode(nonce)
            if activationcode is not None:
                activationcode = unicode(activationcode)

            newkey = kdf2(sharedsecret, nonce, activationcode, len=key_len)
            ocra = OcraSuite(ocrasuite)

            param = {}
            param['C'] = int(counter)
            param['Q'] = unicode(challenge)
            param['P'] = unicode(ocrapin)
            param['S'] = ''

            if ocra.T is not None:

                # Default value for G is 1M, i.e., time-step size is
                # one minute and the T represents the number of minutes
                # since epoch time [UT].

                now = datetime.now()
                stime = now.strftime("%s")
                itime = int(stime)
                param['T'] = itime

            data = ocra.combineData(**param)
            otp = ocra.compute(data, newkey)

            res = {'otp': otp}

            Session.commit()
            return sendResult(response, res, 1)

        except PolicyException as pe:
            log.exception("[ocra/calculateOtp] policy failed: %r" % pe)
            Session.rollback()
            return sendError(response, pe)

        except Exception as e:
            log.exception("[ocra/calculateOtp] failed: %r" % e)
            Session.rollback()
            return sendError(response, unicode(e), 0)

        finally:
            Session.close()