def setPin(self, pin, param=None): """ set the PIN. The optional parameter "param" can hold the information, if the PIN is encrypted or hashed. :param pin: the pin value :param param: the additional request parameters, which could contain the 'encryptpin' value, that triggers, that the token secret are stored in an encrypted form :return: - nothing - """ if param is None: param = {} storeHashed = True enc = param.get("encryptpin", None) if enc is not None and "true" == enc.lower(): storeHashed = False if storeHashed is True: iv, hashed_pin = SecretObj.hash_pin(pin) self.token.set_hashed_pin(hashed_pin, iv) else: enc_pin = SecretObj.encrypt_pin(pin) iv = enc_pin.split(":")[0] self.token.set_encrypted_pin(enc_pin.encode("utf-8"), binascii.unhexlify(iv))
def checkPin(self, pin, options=None): ''' checkPin - test is the pin is matching :param pin: the pin :param options: additional optional parameters, which could be token specific :return: boolean ''' res = False hsm = context['hsm'] if self.token.isPinEncrypted(): # for comparison we encrypt the pin and do the comparison iv, encrypted_token_pin = self.token.get_encrypted_pin() encrypted_pin = SecretObj.encrypt_pin(pin, iv=iv, hsm=hsm) if encrypted_token_pin == encrypted_pin: res = True else: # for hashed pins we re-do the hash and compare the hashes iv, hashed_token_pin = self.token.get_hashed_pin() iv, hashed_pin = SecretObj.hash_pin(pin or '', iv, hsm=hsm) if hashed_pin == hashed_token_pin: res = True # special case of empty pin, where pin has never been set # especially in case of lost token with the pw token if len(hashed_token_pin) == 0 and len(pin) == 0: res = True return res
def setPin(self, pin, param=None): ''' set the PIN. The optional parameter "param" can hold the information, if the PIN is encrypted or hashed. :param pin: the pin value :param param: the additional request parameters, which could contain the 'encryptpin' value, that triggers, that the token secret are stored in an encrypted form :return: - nothing - ''' if param is None: param = {} hsm = context['hsm'] storeHashed = True enc = param.get("encryptpin", None) if enc is not None and "true" == enc.lower(): storeHashed = False if storeHashed is True: iv, hashed_pin = SecretObj.hash_pin(pin, hsm=hsm) self.token.set_hashed_pin(hashed_pin, iv) else: enc_pin = SecretObj.encrypt_pin(pin, hsm=hsm) iv = enc_pin.split(':')[0] self.token.set_encrypted_pin(enc_pin, binascii.unhexlify(iv))
def _rollout_1(self, params): ''' do the rollout 1 step 1. https://linotpserver/admin/init? type=ocra& genkey=1& sharedsecret=1& user=BENUTZERNAME& session=SESSIONKEY =>> "serial" : SERIENNUMMER, "sharedsecret" : DATAOBJECT, "app_import" : IMPORTURL - genSharedSecret - vom HSM oder urandom ? - app_import : + linotp:// + ocrasuite ->> default aus dem config: (DefaultOcraSuite) + sharedsecret (Länge wie ???) + seriennummer - seriennummer: uuid ?? - token wird angelegt ist aber nicht aktiv!!! (counter == 0) ''' sharedSecret = params.get('sharedsecret', None) if sharedSecret == '1': # preserve the rollout state self.addToTokenInfo('rollout', '1') # preserve the current key as sharedSecret secObj = self._get_secret_object() key = secObj.getKey() encSharedSecret = SecretObj.encrypt_pin(key) self.addToTokenInfo('sharedSecret', encSharedSecret) info = {} uInfo = {} info['sharedsecret'] = key uInfo['sh'] = key info['ocrasuite'] = self.getOcraSuiteSuite() uInfo['os'] = self.getOcraSuiteSuite() info['serial'] = self.getSerial() uInfo['se'] = self.getSerial() info['app_import'] = 'lseqr://init?%s' % ( urllib.parse.urlencode(uInfo)) del info['ocrasuite'] self.info = info self.token.LinOtpIsactive = False return
def _transform_action(action): """ transform the action, especialy the secret parameter of the url """ servers = [] name, _sep, values = action.partition("=") for value in values.split(" "): # decompose the server url to identify, if there is a secret inside parsed_server = urllib.parse.urlparse(value) # the urlparse has a bug,, where in elder versions, the # path is not split from the query if not parsed_server.query: path, _sep, query = parsed_server.path.partition("?") else: path = parsed_server.path query = parsed_server.query # in gereal url parsing allows mutiple entries per key # but we support here only one params = urllib.parse.parse_qs(query) for key, entry in list(params.items()): params[key] = entry[0] # finally we found the query parameters if "secret" in params: secret = params["secret"] params["encsecret"] = SecretObj.encrypt_pin(secret) del params["secret"] # build the server url with the encrypted param: # as the named tuple is not updateable, we have to convert this # into an list to make the update and then back to a tuple to # create an url from this parsed_list = list(parsed_server[:]) parsed_list[ForwardServerPolicy.Path_index] = path.strip() parsed_list[ForwardServerPolicy. Query_index] = urllib.parse.urlencode(params) server_url = urllib.parse.urlunparse(tuple(parsed_list)) servers.append(server_url) ret = "=".join([name, " ".join(servers)]) return ret
def set_token_data(self, token_data): serial = token_data["Serial"] tokens = Session.query(model_token).\ filter(model_token.LinOtpTokenSerialnumber == serial).all() token = tokens[0] if 'TokenPin' in token_data: enc_pin = token_data['TokenPin'] token_pin = self.crypter.decrypt(enc_pin, just_mac=serial + token.LinOtpPinHash) # prove, we can write enc_pin = SecretObj.encrypt_pin(token_pin) iv = enc_pin.split(':')[0] token.set_encrypted_pin(enc_pin, binascii.unhexlify(iv)) if 'TokenUserPin' in token_data: token_enc_user_pin = token_data['TokenUserPin'] user_pin = self.crypter.decrypt(token_enc_user_pin, just_mac=serial + token.LinOtpTokenPinUser) # prove, we can write iv, enc_user_pin = SecretObj.encrypt(user_pin, hsm=self.hsm) token.setUserPin(enc_user_pin, iv) # we put the current crypted seed in the mac to check if # something changed in meantime encKey = token.LinOtpKeyEnc enc_seed = token_data['TokenSeed'] token_seed = self.crypter.decrypt(enc_seed, just_mac=serial + encKey) # the encryption of the token seed is not part of the model anymore iv, enc_token_seed = SecretObj.encrypt(token_seed) token.set_encrypted_seed(enc_token_seed, iv, reset_failcount=False, reset_counter=False)
def set_token_data(self, token_data): serial = token_data["Serial"] tokens = Session.query(model_token).\ filter(model_token.LinOtpTokenSerialnumber == serial).all() token = tokens[0] if 'TokenPin' in token_data: enc_pin = token_data['TokenPin'] token_pin = self.crypter.decrypt( enc_pin, just_mac=serial + token.LinOtpPinHash) # prove, we can write enc_pin = SecretObj.encrypt_pin(token_pin) iv = enc_pin.split(':')[0] token.set_encrypted_pin(enc_pin, binascii.unhexlify(iv)) if 'TokenUserPin' in token_data: token_enc_user_pin = token_data['TokenUserPin'] user_pin = self.crypter.decrypt( token_enc_user_pin, just_mac=serial + token.LinOtpTokenPinUser) # prove, we can write iv, enc_user_pin = SecretObj.encrypt(user_pin, hsm=self.hsm) token.setUserPin(enc_user_pin, iv) # we put the current crypted seed in the mac to check if # something changed in meantime encKey = token.LinOtpKeyEnc enc_seed = token_data['TokenSeed'] token_seed = self.crypter.decrypt(enc_seed, just_mac=serial + encKey) # the encryption of the token seed is not part of the model anymore iv, enc_token_seed = SecretObj.encrypt(token_seed) token.set_encrypted_seed(enc_token_seed, iv, reset_failcount=False, reset_counter=False)