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)
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)
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
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
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
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
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()
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()