Пример #1
0
 def parse(self, key_info):
     """Read encryption information from the <EncryptionKey> XML tree."""
     from pskc.xml import find, findall, findtext
     if key_info is None:
         return
     self.id = key_info.get('Id')
     for name in findall(key_info, 'ds:KeyName'):
         self.key_names.append(findtext(name, '.'))
     for name in findall(
             key_info, 'xenc11:DerivedKey/xenc11:MasterKeyName'):
         self.key_names.append(findtext(name, '.'))
     self.derivation.parse(find(
         key_info, 'xenc11:DerivedKey/xenc11:KeyDerivationMethod'))
Пример #2
0
 def parse_encryption(cls, encryption, key_info):
     """Read encryption information from the <EncryptionKey> XML tree."""
     if key_info is None:
         return
     encryption.id = key_info.get('Id')
     encryption.algorithm = (
         key_info.get('Algorithm') or
         key_info.get('algorithm') or
         encryption.algorithm)
     for name in findall(key_info,
                         'KeyName', 'DerivedKey/MasterKeyName',
                         'DerivedKey/CarriedKeyName'):
         encryption.key_names.append(findtext(name, '.'))
     encryption.iv = findbin(key_info, 'IV') or encryption.iv
     cls.parse_key_derivation(encryption.derivation, find(
         key_info, 'DerivedKey/KeyDerivationMethod'))
     encryption.derivation.pbkdf2_salt = (
         findbin(key_info, 'PBESalt') or encryption.derivation.pbkdf2_salt)
     encryption.derivation.pbkdf2_iterations = (
         findint(key_info, 'PBEIterationCount') or
         encryption.derivation.pbkdf2_iterations)
     algorithm = (
         key_info.get('Algorithm') or key_info.get('algorithm') or '')
     if (algorithm.lower().startswith('pbe') and
             not encryption.derivation.algorithm):
         encryption.derivation.algorithm = 'pbkdf2'
         encryption.derivation.pbkdf2_key_length = (
             encryption.derivation.pbkdf2_key_length or
             encryption.algorithm_key_lengths[0])
Пример #3
0
 def parse_document(cls, pskc, container):
     """Read information from the provided <KeyContainer> tree."""
     remove_namespaces(container)
     if container.tag not in ('KeyContainer', 'SecretContainer'):
         raise ParseError('Missing KeyContainer')
     # the version of the PSKC schema
     pskc.version = container.get('Version') or container.get('version')
     if (container.tag == 'KeyContainer' and
             pskc.version and
             pskc.version not in ('1', '1.0')):
         raise ParseError('Unsupported version %r' % pskc.version)
     # unique identifier for the container
     pskc.id = (
         container.get('Id') or container.get('ID') or container.get('id'))
     # handle EncryptionKey entries
     cls.parse_encryption(pskc.encryption, find(
         container, 'EncryptionKey', 'EncryptionMethod'))
     # handle MACMethod entries
     cls.parse_mac_method(pskc.mac, find(
         container, 'MACMethod', 'DigestMethod'))
     # fall back to MACAlgorithm
     mac_algorithm = findtext(container, 'MACAlgorithm')
     if mac_algorithm:
         pskc.mac.algorithm = mac_algorithm
     # handle KeyPackage entries
     for key_package in findall(container, 'KeyPackage', 'Device'):
         cls.parse_key_package(pskc.add_device(), key_package)
     # handle Signature entries
     cls.parse_signature(pskc.signature, find(container, 'Signature'))
Пример #4
0
 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)
Пример #5
0
 def parse(self, container):
     """Read information from the provided <KeyContainer> tree."""
     from pskc.exceptions import ParseError
     from pskc.key import Key
     from pskc.xml import find, findall
     if not container.tag.endswith('KeyContainer'):
         raise ParseError('Missing KeyContainer')
     # the version of the PSKC schema
     self.version = container.get('Version')
     if self.version != '1.0':
         raise ParseError('Unsupported version %r' % self.version)
     # unique identifier for the container
     self.id = container.get('Id')
     # handle EncryptionKey entries
     self.encryption.parse(find(container, 'pskc:EncryptionKey'))
     # handle MACMethod entries
     self.mac.parse(find(container, 'pskc:MACMethod'))
     # handle KeyPackage entries
     for key_package in findall(container, 'pskc:KeyPackage'):
         self.keys.append(Key(self, key_package))
Пример #6
0
    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
Пример #7
0
    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')
Пример #8
0
 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)