def parse(self, key_package): """Read key information from the provided <KeyPackage> tree.""" from pskc.xml import find, findtext, findtime, getint, getbool if key_package is None: return key = find(key_package, "pskc:Key") if key is not None: self.id = key.get("Id") self.algorithm = key.get("Algorithm") data = find(key_package, "pskc:Key/pskc:Data") if data is not None: self._secret.parse(find(data, "pskc:Secret")) self._counter.parse(find(data, "pskc:Counter")) self._time_offset.parse(find(data, "pskc:Time")) self._time_interval.parse(find(data, "pskc:TimeInterval")) self._time_drift.parse(find(data, "pskc:TimeDrift")) self.issuer = findtext(key_package, "pskc:Key/pskc:Issuer") self.key_profile = findtext(key_package, "pskc:Key/pskc:KeyProfileId") self.key_reference = findtext(key_package, "pskc:Key/pskc:KeyReference") self.friendly_name = findtext(key_package, "pskc:Key/pskc:FriendlyName") # TODO: support multi-language values of <FriendlyName> self.key_userid = findtext(key_package, "pskc:Key/pskc:UserId") self.manufacturer = findtext(key_package, "pskc:DeviceInfo/pskc:Manufacturer") self.serial = findtext(key_package, "pskc:DeviceInfo/pskc:SerialNo") self.model = findtext(key_package, "pskc:DeviceInfo/pskc:Model") self.issue_no = findtext(key_package, "pskc:DeviceInfo/pskc:IssueNo") self.device_binding = findtext(key_package, "pskc:DeviceInfo/pskc:DeviceBinding") self.start_date = findtime(key_package, "pskc:DeviceInfo/pskc:StartDate") self.expiry_date = findtime(key_package, "pskc:DeviceInfo/pskc:ExpiryDate") self.device_userid = findtext(key_package, "pskc:DeviceInfo/pskc:UserId") self.crypto_module = findtext(key_package, "pskc:CryptoModuleInfo/pskc:Id") self.algorithm_suite = findtext(key_package, "pskc:Key/pskc:AlgorithmParameters/pskc:Suite") challenge_format = find(key_package, "pskc:Key/pskc:AlgorithmParameters/pskc:ChallengeFormat") if challenge_format is not None: self.challenge_encoding = challenge_format.get("Encoding") self.challenge_min_length = getint(challenge_format, "Min") self.challenge_max_length = getint(challenge_format, "Max") self.challenge_check = getbool(challenge_format, "CheckDigits") response_format = find(key_package, "pskc:Key/pskc:AlgorithmParameters/pskc:ResponseFormat") if response_format is not None: self.response_encoding = response_format.get("Encoding") self.response_length = getint(response_format, "Length") self.response_check = getbool(response_format, "CheckDigits") self.policy.parse(find(key_package, "pskc:Key/pskc:Policy"))
def parse_key_package(cls, device, key_package): """Read key information from the provided <KeyPackage> tree.""" # find basic device information info = find(key_package, 'DeviceInfo', 'DeviceId') if info is not None: device.manufacturer = findtext(info, 'Manufacturer') device.serial = findtext(info, 'SerialNo') device.model = findtext(info, 'Model') device.issue_no = findtext(info, 'IssueNo') device.device_binding = findtext(info, 'DeviceBinding') device.start_date = findtime(info, 'StartDate') device.expiry_date = findtime(info, 'ExpiryDate', 'Expiry') device.device_userid = findtext(info, 'UserId') # find crypto module info device.crypto_module = findtext(key_package, 'CryptoModuleInfo/Id') # find keys for device for key_elm in findall(key_package, 'Key', 'Secret'): cls.parse_key(device.add_key(), key_elm)
def parse_policy(cls, policy, policy_elm): """Read key policy information from the provided <Policy> tree.""" if policy_elm is None: return policy.start_date = findtime(policy_elm, 'StartDate') policy.expiry_date = findtime(policy_elm, 'ExpiryDate') policy.number_of_transactions = findint( policy_elm, 'NumberOfTransactions') for key_usage in findall(policy_elm, 'KeyUsage'): policy.key_usage.append(findtext(key_usage, '.')) pin_policy_elm = find(policy_elm, 'PINPolicy') if pin_policy_elm is not None: policy.pin_key_id = pin_policy_elm.get('PINKeyId') policy.pin_usage = pin_policy_elm.get('PINUsageMode') policy.pin_max_failed_attempts = getint( pin_policy_elm, 'MaxFailedAttempts') policy.pin_min_length = getint(pin_policy_elm, 'MinLength') policy.pin_max_length = getint(pin_policy_elm, 'MaxLength') policy.pin_encoding = pin_policy_elm.get('PINEncoding') # check for child elements if list(pin_policy_elm): policy.unknown_policy_elements = True # check for unknown attributes known_attributes = set([ 'PINKeyId', 'PINUsageMode', 'MaxFailedAttempts', 'MinLength', 'MaxLength', 'PINEncoding']) if set(pin_policy_elm.keys()) - known_attributes: policy.unknown_policy_elements = True # check for other child elements known_children = set([ 'StartDate', 'ExpiryDate', 'NumberOfTransactions', 'KeyUsage', 'PINPolicy']) for child in policy_elm: if child.tag not in known_children: policy.unknown_policy_elements = True
def parse(self, policy): """Read key policy information from the provided <Policy> tree.""" from pskc.xml import ( find, findall, findtext, findint, findtime, getint) if policy is None: return self.start_date = findtime(policy, 'pskc:StartDate') self.expiry_date = findtime(policy, 'pskc:ExpiryDate') self.number_of_transactions = findint( policy, 'pskc:NumberOfTransactions') for key_usage in findall(policy, 'pskc:KeyUsage'): self.key_usage.append(findtext(key_usage, '.')) pin_policy = find(policy, 'pskc:PINPolicy') if pin_policy is not None: self.pin_key_id = pin_policy.get('PINKeyId') self.pin_usage = pin_policy.get('PINUsageMode') self.pin_max_failed_attemtps = getint( pin_policy, 'MaxFailedAttempts') self.pin_min_length = getint(pin_policy, 'MinLength') self.pin_max_length = getint(pin_policy, 'MaxLength') self.pin_encoding = pin_policy.get('PINEncoding')
def parse_key(cls, key, key_elm): """Read key information from the provided <KeyPackage> tree.""" # get key basic information key.id = ( key_elm.get('Id') or key_elm.get('KeyId') or key_elm.get('SecretId')) key.algorithm = ( key_elm.get('Algorithm') or key_elm.get('KeyAlgorithm') or key_elm.get('SecretAlgorithm')) # parse data section with possibly encrypted data data = find(key_elm, 'Data') if data is not None: cls.parse_data(key, 'secret', find(data, 'Secret')) cls.parse_data(key, 'counter', find(data, 'Counter')) cls.parse_data(key, 'time_offset', find(data, 'Time')) cls.parse_data(key, 'time_interval', find(data, 'TimeInterval')) cls.parse_data(key, 'time_drift', find(data, 'TimeDrift')) # parse legacy data elements with name attribute for data in findall(key_elm, 'Data'): name = data.get('Name') if name: cls.parse_data(key, dict( secret='secret', counter='counter', time='time_offset', time_interval='time_interval', ).get(name.lower()), data) # parse more basic key properties key.issuer = findtext(key_elm, 'Issuer') key.key_profile = findtext(key_elm, 'KeyProfileId') key.key_reference = findtext(key_elm, 'KeyReference') key.friendly_name = findtext(key_elm, 'FriendlyName') # TODO: support multi-language values of <FriendlyName> key.key_userid = findtext(key_elm, 'UserId') key.algorithm_suite = findtext( key_elm, 'AlgorithmParameters/Suite') # parse challenge format challenge_format = find( key_elm, 'AlgorithmParameters/ChallengeFormat', 'Usage/ChallengeFormat') if challenge_format is not None: key.challenge_encoding = ( challenge_format.get('Encoding') or challenge_format.get('Format') or challenge_format.get('format')) key.challenge_min_length = ( getint(challenge_format, 'Min') or getint(challenge_format, 'min')) key.challenge_max_length = ( getint(challenge_format, 'Max') or getint(challenge_format, 'max')) key.challenge_check = getbool( challenge_format, 'CheckDigits', getbool( challenge_format, 'CheckDigit')) # parse response format response_format = find( key_elm, 'AlgorithmParameters/ResponseFormat', 'Usage/ResponseFormat') if response_format is not None: key.response_encoding = ( response_format.get('Encoding') or response_format.get('Format') or response_format.get('format')) key.response_length = ( getint(response_format, 'Length') or getint(response_format, 'length')) key.response_check = getbool( response_format, 'CheckDigits', getbool( response_format, 'CheckDigit')) # parse key policy information cls.parse_policy(key.policy, find(key_elm, 'Policy')) # parse key usage information usage = find(key_elm, 'Usage') if usage is not None: for att in ('OTP', 'CR', 'Integrity', 'Encrypt', 'Unlock'): if getbool(usage, att): key.policy.key_usage.append(att) key.policy.start_date = ( findtime(key_elm, 'StartDate') or key.policy.start_date) key.policy.expiry_date = ( findtime(key_elm, 'ExpiryDate') or key.policy.expiry_date)