示例#1
0
def parse_binary_packet_data(data):
    offset = 0
    length = len(data)
    while offset < length:
        offset, packet = packet_from_packet_data(data, offset)
        yield packet
示例#2
0
    def decrypt(self, symmetric_algo, key):
        encrypted_data = bytes(self.data)
        decrypted_data = bytearray()
        offset = 0
        padding = 0
        block_len = utils.symmetric_cipher_block_lengths[symmetric_algo]
        encrypted_iv = encrypted_data[:block_len + 2]
        cipher = utils.get_symmetric_cipher(
            symmetric_algo,
            key,
            utils.CFB,
            b'\x00' * block_len)
        decrypted_iv = cipher.decrypt(encrypted_data[:block_len])
        if self.integrity_protected:
            # "Unlike the Symmetrically Encrypted Data Packet, no special CFB
            #  resynchronization is done after encrypting this prefix data."
            offset += block_len
            first_block = cipher.decrypt(
                encrypted_data[offset:offset + block_len])
            offset += block_len
            iv_check = first_block[:2]
            if iv_check != decrypted_iv[-2:]:
                raise ValueError()

            decrypted_data.extend(first_block[2:])

            # Pad the remaining data manually
            padding = block_len - (len(encrypted_data) - offset) % block_len
            encrypted_data += b'\x00' * padding
        else:
            cipher = utils.get_symmetric_cipher(
                symmetric_algo,
                key,
                utils.OPENPGP,
                encrypted_iv)

        decrypted_data.extend(cipher.decrypt(encrypted_data[offset:]))
        decrypted_data = decrypted_data[:-padding]
        # We run into trouble here with partial body lengths and the MDC.
        # Let's make pretend.
        mdc_data = bytearray()
        main_data = decrypted_data
        if decrypted_data[-22:-20] == b'\xd3\x14':
            # It's there. Hold it back.
            mdc_data = decrypted_data[-22:]
            main_data = decrypted_data[:-22]
        data_len = len(main_data)
        offset = 0
        decrypted_packets = []
        while offset < data_len:
            offset, packet = packets.packet_from_packet_data(main_data, offset)
            decrypted_packets.append(packet)

        if mdc_data:
            # One more for the MDC
            offset, packet = packets.packet_from_packet_data(mdc_data, 0)
            decrypted_packets.append(packet)

        if self.integrity_protected:
            if (decrypted_packets[-1].type !=
                    C.MODIFICATION_DETECTION_CODE_PACKET_TYPE):
                raise ValueError(
                    'Integrity protected message is missing modification '
                    'detection code.')
            mdc = decrypted_packets.pop()
            hash_ = SHA.new(decrypted_iv)
            hash_.update(decrypted_iv[-2:])
            hash_.update(decrypted_data[:-20])
            if mdc.data != hash_.digest():
                raise ValueError(
                    'Integrity protected message does not match modification '
                    'detection code.')

        return open_pgp_message_from_packets(decrypted_packets)
示例#3
0
    def decrypt(self, symmetric_algo, key):
        encrypted_data = bytes(self.data)
        decrypted_data = bytearray()
        offset = 0
        padding = 0
        block_len = utils.symmetric_cipher_block_lengths[symmetric_algo]
        encrypted_iv = encrypted_data[:block_len + 2]
        cipher = utils.get_symmetric_cipher(symmetric_algo, key, utils.CFB,
                                            b'\x00' * block_len)
        decrypted_iv = cipher.decrypt(encrypted_data[:block_len])
        if self.integrity_protected:
            # "Unlike the Symmetrically Encrypted Data Packet, no special CFB
            #  resynchronization is done after encrypting this prefix data."
            offset += block_len
            first_block = cipher.decrypt(encrypted_data[offset:offset +
                                                        block_len])
            offset += block_len
            iv_check = first_block[:2]
            if iv_check != decrypted_iv[-2:]:
                raise ValueError()

            decrypted_data.extend(first_block[2:])

            # Pad the remaining data manually
            padding = block_len - (len(encrypted_data) - offset) % block_len
            encrypted_data += b'\x00' * padding
        else:
            cipher = utils.get_symmetric_cipher(symmetric_algo, key,
                                                utils.OPENPGP, encrypted_iv)

        decrypted_data.extend(cipher.decrypt(encrypted_data[offset:]))
        decrypted_data = decrypted_data[:-padding]
        # We run into trouble here with partial body lengths and the MDC.
        # Let's make pretend.
        mdc_data = bytearray()
        main_data = decrypted_data
        if decrypted_data[-22:-20] == b'\xd3\x14':
            # It's there. Hold it back.
            mdc_data = decrypted_data[-22:]
            main_data = decrypted_data[:-22]
        data_len = len(main_data)
        offset = 0
        decrypted_packets = []
        while offset < data_len:
            offset, packet = packets.packet_from_packet_data(main_data, offset)
            decrypted_packets.append(packet)

        if mdc_data:
            # One more for the MDC
            offset, packet = packets.packet_from_packet_data(mdc_data, 0)
            decrypted_packets.append(packet)

        if self.integrity_protected:
            if (decrypted_packets[-1].type !=
                    C.MODIFICATION_DETECTION_CODE_PACKET_TYPE):
                raise ValueError(
                    'Integrity protected message is missing modification '
                    'detection code.')
            mdc = decrypted_packets.pop()
            hash_ = SHA.new(decrypted_iv)
            hash_.update(decrypted_iv[-2:])
            hash_.update(decrypted_data[:-20])
            if mdc.data != hash_.digest():
                raise ValueError(
                    'Integrity protected message does not match modification '
                    'detection code.')

        return open_pgp_message_from_packets(decrypted_packets)
示例#4
0
def parse_binary_packet_data(data):
    offset = 0
    length = len(data)
    while offset < length:
        offset, packet = packet_from_packet_data(data, offset)
        yield packet