def signature_subpacket_from_data(data, offset=0): offset, length, partial = utils.new_packet_length(data, offset) # TODO: smarter error assert not partial tag = data[offset] subpacket_type = tag & 0x7F critical = bool(tag & 0x80) length -= 1 # Since we've parsed the tag from the data offset += 1 sub_data = data[offset : offset + length] offset += length cls = SIGNATURE_SUBPACKET_TYPES.get(subpacket_type, SignatureSubpacket) return (cls.from_subpacket_content(subpacket_type, critical, sub_data), offset)
def signature_subpacket_from_data(data, offset=0): offset, length, partial = utils.new_packet_length(data, offset) # TODO: smarter error assert not partial tag = data[offset] subpacket_type = tag & 0x7f critical = bool(tag & 0x80) length -= 1 # Since we've parsed the tag from the data offset += 1 sub_data = data[offset:offset + length] offset += length cls = SIGNATURE_SUBPACKET_TYPES.get(subpacket_type, SignatureSubpacket) return (cls.from_subpacket_content(subpacket_type, critical, sub_data), offset)
def user_attribute_subpacket_from_data(data, offset=0): sub_data = bytearray() offset, sub_len, sub_partial = utils.new_packet_length(data, offset) if sub_partial: # "An implementation MAY use Partial Body Lengths for data # packets, be they literal, compressed, or encrypted. [...] # Partial Body Lengths MUST NOT be used for any other packet # types." raise ValueError sub_type = int(data[offset]) # + 1 for sub type sub_data_start = offset + 1 sub_data_end = sub_data_start + sub_len - 1 sub_data.extend(data[sub_data_start:sub_data_end]) offset = sub_data_end cls = USER_ATTRIBUTE_SUBPACKET_TYPES.get(sub_type, UserAttributeSubpacket) return cls.from_subpacket_content(sub_type, sub_data), offset
def user_attribute_subpacket_from_data(data, offset=0): sub_data = bytearray() offset, sub_len, sub_partial = utils.new_packet_length(data, offset) if sub_partial: # "An implementation MAY use Partial Body Lengths for data # packets, be they literal, compressed, or encrypted. [...] # Partial Body Lengths MUST NOT be used for any other packet # types." raise ValueError sub_type = int(data[offset]) # + 1 for sub type sub_data_start = offset + 1 sub_data_end = sub_data_start + sub_len - 1 sub_data.extend(data[sub_data_start:sub_data_end]) offset = sub_data_end cls = USER_ATTRIBUTE_SUBPACKET_TYPES.get(sub_type, UserAttributeSubpacket) return cls.from_subpacket_content(sub_type, sub_data), offset
def parse_user_attribute_subpackets(p, parse_unknown=False): offset = 0 while offset < len(p.data): sub_data = bytearray() sub_type = None sub_offset, sub_len, sub_partial = \ utils.new_packet_length(p.data, offset) if sub_partial: # "An implementation MAY use Partial Body Lengths for data # packets, be they literal, compressed, or encrypted. [...] # Partial Body Lengths MUST NOT be used for any other packet # types." return sub_type = p.data[sub_offset] # + 1 for sub type sub_data_start = offset + sub_offset + 1 sub_data_end = sub_data_start + sub_len sub_data.extend(p.data[sub_data_start:sub_data_end]) offset = sub_data_end if sub_type == 0x01: # "The only currently defined subpacket type is 1, signifying # an image." # "The first two octets of the image header contain the length of # the image header. Note that unlike other multi-octet numerical # values in this document, due to a historical accident this # value is encoded as a little-endian number." header_length = sub_data[0] + (sub_data[1] << 8) header_version = sub_data[2] if header_version == 1: if not header_length == 16: continue image_format = sub_data[3] if any(sub_data[4:16]): # Incorrect continue if (image_format == 1 or (image_format > 99 and image_format < 111)): # "The only currently defined encoding format is the value # 1 to indicate JPEG. Image format types 100 through 110 # are reserved for private or experimental use." # # "An implementation MAY try to determine the type of an # image by examination of the image data if it is unable # to handle a particular version of the image header or # if a specified encoding format value is not # recognized." mime_type = magic.from_buffer(bytes(sub_data[16:1040]), mime=True).decode('ascii') yield { 'sub_type': sub_type, 'content_data': sub_data[16:], 'mimetype': mime_type, } elif parse_unknown: # If we want to parse unknown, non-image data content_data = sub_data[header_length:] mime_type = magic.from_buffer(bytes(content_data[:1024]), mime=True).decode('ascii') yield { 'sub_type': sub_type, 'content_data': content_data, 'mimetype': mime_type, }
def parse_user_attribute_subpackets(p, parse_unknown=False): offset = 0 while offset < len(p.data): sub_data = bytearray() sub_type = None sub_offset, sub_len, sub_partial = \ utils.new_packet_length(p.data, offset) if sub_partial: # "An implementation MAY use Partial Body Lengths for data # packets, be they literal, compressed, or encrypted. [...] # Partial Body Lengths MUST NOT be used for any other packet # types." return sub_type = p.data[sub_offset] # + 1 for sub type sub_data_start = offset + sub_offset + 1 sub_data_end = sub_data_start + sub_len sub_data.extend(p.data[sub_data_start:sub_data_end]) offset = sub_data_end if sub_type == 0x01: # "The only currently defined subpacket type is 1, signifying # an image." # "The first two octets of the image header contain the length of # the image header. Note that unlike other multi-octet numerical # values in this document, due to a historical accident this # value is encoded as a little-endian number." header_length = sub_data[0] + (sub_data[1] << 8) header_version = sub_data[2] if header_version == 1: if not header_length == 16: continue image_format = sub_data[3] if any(sub_data[4:16]): # Incorrect continue if (image_format == 1 or (image_format > 99 and image_format < 111) ): # "The only currently defined encoding format is the value # 1 to indicate JPEG. Image format types 100 through 110 # are reserved for private or experimental use." # # "An implementation MAY try to determine the type of an # image by examination of the image data if it is unable # to handle a particular version of the image header or # if a specified encoding format value is not # recognized." mime_type = magic.from_buffer(bytes(sub_data[16:1040]), mime=True).decode('ascii') yield { 'sub_type': sub_type, 'content_data': sub_data[16:], 'mimetype': mime_type, } elif parse_unknown: # If we want to parse unknown, non-image data content_data = sub_data[header_length:] mime_type = magic.from_buffer(bytes(content_data[:1024]), mime=True).decode('ascii') yield { 'sub_type': sub_type, 'content_data': content_data, 'mimetype': mime_type, }