def decode_integer_mask(tag, name_list): """ Decode a string representation of an integer mask. Args: tag (enums.Tag): the tag of the mask being decoded. name_list (list of str): the list of the items in the mask, e.g. ['Encrypt', '0x00000001'] Returns: int: the final mask value. """ enum_cls = getattr(enums, tag.name, None) if enum_cls is None: raise RuntimeError( 'Error decoding integer mask: ' 'could not find enumeration class for {}'.format(tag)) val = 0 for name in name_list: if name.startswith('0x'): val |= int(name, 16) else: e = getattr(enum_cls, name, None) if e is None: raise RuntimeError( 'Error decoding integer mask: ' 'could not find enumeration value for {}'.format(name)) val |= e.value return val
def decode_enumeration(tag, val): """ Decode a Enumeration from a XML-suitable string. Args: tag (enums.Tag): the tag of the value; used to find the corresponding enumeration. val (str): the input as hex string (e.g. "0x00000001") or enum string (e.g. "CBC"). Returns: Enum or UnknownEnumeration: the result; an UnknownEnumeration if the corresponding enumeration is not found. """ try: if val.startswith('0x'): val = int(val, 16) enum_cls = getattr(enums, tag.name) if isinstance(val, _integer_types): return enum_cls(val) else: return enum_cls[val] except (AttributeError, ValueError): if isinstance(val, _integer_types): return types.UnknownEnumeration(val) return types.UnknownEnumerationString(val)
def decode_interval(val): """ Decode a Integer from a XML-suitable string. Args: val (str): the input as a string Returns: datetime.timedelta: the result. """ return datetime.timedelta(seconds=int(val))
def encode_interval(val): """ Encode a Interval into a XML-suitable string. Args: val (datetime.timedelta): the input. Returns: str: the result. """ return str(int(val.total_seconds()))
def encode_interval(val): """ Encode a Interval into a TTLV byte string. Args: val (datetime.timedelta): the input. Returns: bytes: the result. """ return struct.pack('>I', int(val.total_seconds()))
def decode_datetime(val): """ Decode a DateTime from a XML-suitable string. Args: val (str or int): the input as an int or ISO8601 string. Returns: datetime.datetime: the result. """ if val.startswith('0x'): return datetime.datetime.fromtimestamp(int(val, 16), iso8601.UTC) return iso8601.parse_date(val)
def decode_interval(val): """ Decode a Integer from a JSON-encodable value. Args: val (str or int): the input as an int or hex string (e.g. "0x00000001") Returns: datetime.timedelta: the result. """ if not isinstance(val, _integer_types): val = int(val, 16) return datetime.timedelta(seconds=val)
def decode_boolean(val): """ Decode a Boolean from a JSON-encodable value. Args: val (bool or str): the input as a bool or hex string (e.g. "0x00000001") Returns: bool: the result. """ if not isinstance(val, bool): return bool(int(val, 16)) return val
def decode(root): """ Decode an Element tree into a TTV tree. Args: root (ElementTree.Element): the root of the Element tree. Returns: TTV: the root of the decoded TTV tree. """ if root.tag == 'TTLV': tag = root.get('tag', None) if tag is None: raise RuntimeError('Missing tag key') tag = int(tag, 16) else: tag = root.tag tag = enums.Tag[tag] typ = root.get('type', 'Structure') typ = enums.ItemType[typ] if typ == enums.ItemType.Structure: value = list(root) else: value = root.get('value', None) if value is None: raise RuntimeError('Missing value key') root = { enums.ItemType.Structure: decode_structure, enums.ItemType.Integer: decode_integer, enums.ItemType.LongInteger: decode_longinteger, enums.ItemType.BigInteger: decode_biginteger, enums.ItemType.Enumeration: decode_enumeration, enums.ItemType.Boolean: decode_boolean, enums.ItemType.TextString: decode_textstring, enums.ItemType.ByteString: decode_bytestring, enums.ItemType.DateTime: decode_datetime, enums.ItemType.Interval: decode_interval, } if typ in (enums.ItemType.Enumeration, enums.ItemType.Integer): decoded_value = root[typ](tag, value) else: decoded_value = root[typ](value) from kkmip import ttv return ttv.TTV(tag, decoded_value, typ)
def decode_int_str(val, size): """ Decode a string representing an hexadecimal integer, possibly negative. Args: val: the string, e.g. "0xab01" size: the expected size of the integer, in bits. This is required to parse negative integers. Returns: int: the value represented by the string. """ if val.startswith('0x'): val = val[2:] # Multiply by 4 because each char is 4 bits bit_len = len(val) * 4 val = int(val, 16) # Special case: negative number. In this case, the number is sign-extended to a 64-bit # multiple, so we must check the upper bit if bit_len % size == 0 and (val >> (bit_len - 1)) & 1: val -= 1 << val.bit_length() return val