Exemple #1
0
 def __hash__(self):
     return crc24(bytes(self.to_subpacket()))
 def __hash__(self):
     return crc24.crc24(bytes(self))
Exemple #3
0
 def __hash__(self):
     return crc24(bytes(self.to_subpacket()))
 def __hash__(self):
     return crc24.crc24(bytes(self))
Exemple #5
0
    def from_ascii(cls, text):
        lines = text.splitlines()
        line_no = 0

        # Skip blank lines before header line
        while not len(lines[line_no].strip()):
            line_no += 1

        # Parse header line
        header_line = lines[line_no]
        header_matches = header_line_expr.match(header_line)
        if header_matches is None:
            raise ValueError('{0} is not a valid header.'.format(
                repr(header_line)))

        line_no += 1
        part = None
        total_parts = None
        if header_matches.group('message'):
            data_type = PGP_MESSAGE
            part = header_matches.group('part')
            if part is not None:
                part = int(part)
            total_parts = header_matches.group('total_parts')
            if total_parts is not None:
                total_parts = int(total_parts)
        elif header_matches.group('public_key'):
            data_type = PGP_PUBLIC_KEY_BLOCK
        elif header_matches.group('private_key'):
            data_type = PGP_PRIVATE_KEY_BLOCK
        elif header_matches.group('signature'):
            data_type = PGP_SIGNATURE
        else:
            raise ValueError

        # Parse headers
        version = None
        comment = None
        message_id = None
        hash_algorithms = None
        charset = None
        extra_headers = {}

        while len(lines[line_no].strip()):
            header_key, header_value = lines[line_no].split(': ', 1)
            if header_key == 'Version':
                version = header_value
            elif header_key == 'Comment':
                comment = header_value
            elif header_key == 'MessageID':
                message_id = header_value
            elif header_key == 'Hash':
                hash_algorithms = header_value
            elif header_key == 'Charset':
                charset = header_value
            else:
                # "Unknown keys should be reported to the user, but OpenPGP
                #  should continue to process the message."
                warnings.warn(
                    'Unsupported armor header, "{0}"'.format(header_key))
                extra_headers[header_key] = header_value
            line_no += 1

        # blank line
        line_no += 1

        data_lines = []

        while lines[line_no][:1] != '=':
            data_lines.append(lines[line_no])
            line_no += 1

        data = b64decode(''.join(data_lines))
        checksum_data = b64decode(lines[line_no][1:])
        expected_checksum = (((checksum_data[0] << 16)) +
                             ((checksum_data[1] << 8)) + checksum_data[2])
        line_no += 1

        actual_checksum = crc24(data)
        if actual_checksum != expected_checksum:
            raise ValueError(
                ('Checksum does not match. {0} (actual) != {1} (expected).'
                 ).format(repr(actual_checksum), repr(expected_checksum)))

        tail_line = lines[line_no]
        if tail_line != header_line.replace('BEGIN', 'END'):
            raise ValueError(
                'Tail line does not match header line. {0} {1}'.format(
                    repr(header_line), repr(tail_line)))

        return cls(data_type, data, part, total_parts, version, comment,
                   message_id, hash_algorithms, charset)
Exemple #6
0
    def __str__(self):
        result_lines = []
        if self.data_type != PGP_MESSAGE:
            result_lines.append('{dashes}BEGIN {data_type}{dashes}'.format(
                dashes=DASHES, data_type=data_types[self.data_type]))
        elif self.data_type == PGP_MESSAGE:
            if self.part is not None and self.total_parts is not None:
                result_lines.append(
                    ('{dashes}BEGIN {data_type}, PART {part}/{total_parts}'
                     '{dashes}').format(dashes=DASHES,
                                        data_type=data_types[self.data_type],
                                        part=self.part,
                                        total_parts=self.total_parts))
            elif self.part is not None:
                result_lines.append(
                    ('{dashes}BEGIN {data_type}, PART {part}{dashes}').format(
                        dashes=DASHES,
                        data_type=data_types[self.data_type],
                        part=self.part,
                    ))
            else:
                result_lines.append(
                    ('{dashes}BEGIN {data_type}{dashes}').format(
                        dashes=DASHES,
                        data_type=data_types[self.data_type],
                    ))
        if self.version is not None:
            result_lines.append(
                'Version: {version}'.format(version=self.version))
        if self.comment is not None:
            result_lines.append(
                'Comment: {comment}'.format(comment=self.comment))
        if self.message_id is not None:
            result_lines.append(
                'MessageID: {message_id}'.format(message_id=self.message_id))
        if self.hash_algorithms is not None:
            result_lines.append(
                'Hash: {hash}'.format(hash=self.hash_algorithms))
        if self.charset is not None:
            result_lines.append(
                'Charset: {charset}'.format(charset=self.charset))
        if self.extra_headers is not None:
            for k, v in self.extra_headers:
                result_lines.append('{0}: {1}'.format(k, v))

        result_lines.append('')

        encoded_data = b64encode(self.data).decode('us-ascii')
        data_lines = []
        for l in range(int(math.ceil(len(encoded_data) / 72.0))):
            data_lines.append(encoded_data[l * 72:(l * 72) + 72])

        result_lines.extend(data_lines)
        checksum_value = crc24(self.data)
        checksum_bytes = bytearray([(checksum_value >> (i * 8)) & 0xff
                                    for i in (2, 1, 0)])
        checksum = b64encode(checksum_bytes).decode('us-ascii')
        result_lines.append('={0}'.format(checksum))
        result_lines.append(result_lines[0].replace('BEGIN', 'END'))

        return '\n'.join(result_lines) + '\n'