Exemplo n.º 1
0
    def encrypt(self, symmetric_algo, key, message):
        block_len = utils.symmetric_cipher_block_lengths[symmetric_algo]
        iv = Random.new().read(block_len)
        data = bytearray()
        cipher = utils.get_symmetric_cipher(symmetric_algo, key, utils.CFB,
                                            b'\x00' * block_len)
        padding = 0
        offset = 0
        if not self.integrity_protected:
            padding = block_len - len(message) % block_len
            message = message + b'\x00' * padding
            data.extend(cipher.encrypt(iv + iv[-2:]))
            cipher = utils.get_symmetric_cipher(symmetric_algo, key, utils.CFB,
                                                iv)
            data.extend(cipher.encrypt(message))
        else:
            padding = block_len - (len(message) + 2 + 22) % block_len
            data.extend(cipher.encrypt(iv))
            hash_ = SHA.new(iv)
            hash_.update(iv[-2:])
            message = message + b'\xd3\x14'
            hash_.update(message)
            mdc = hash_.digest()
            message = message + mdc + (b'\x00' * padding)
            data.extend(cipher.encrypt(iv[-2:] + message)[:-padding])

        self.data = data
Exemplo n.º 2
0
    def encrypt(self, symmetric_algo, key, message):
        block_len = utils.symmetric_cipher_block_lengths[symmetric_algo]
        iv = Random.new().read(block_len)
        data = bytearray()
        cipher = utils.get_symmetric_cipher(
            symmetric_algo,
            key,
            utils.CFB,
            b'\x00' * block_len
            )
        padding = 0
        if not self.integrity_protected:
            padding = block_len - len(message) % block_len
            message = message + b'\x00' * padding
            data.extend(cipher.encrypt(iv + iv[-2:]))
            cipher = utils.get_symmetric_cipher(
                symmetric_algo,
                key,
                utils.CFB,
                iv
                )
            data.extend(cipher.encrypt(message))
        else:
            padding = block_len - (len(message) + 2 + 22) % block_len
            data.extend(cipher.encrypt(iv))
            hash_ = SHA.new(iv)
            hash_.update(iv[-2:])
            message = message + b'\xd3\x14'
            hash_.update(message)
            mdc = hash_.digest()
            message = message + mdc + (b'\x00' * padding)
            data.extend(cipher.encrypt(iv[-2:] + message)[:-padding])

        self.data = data
Exemplo n.º 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)
Exemplo n.º 4
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)