Esempio n. 1
0
    def from_pickle(cls, pickle, passphrase=""):
        # types: (bytes, str) -> PkDecryption
        if not pickle:
            raise ValueError("Pickle can't be empty")

        byte_key = to_bytes(passphrase)
        key_buffer = ffi.new("char[]", byte_key)
        pickle_buffer = ffi.new("char[]", pickle)

        pubkey_length = lib.olm_pk_key_length()
        pubkey_buffer = ffi.new("char[]", pubkey_length)

        obj = cls.__new__(cls)

        ret = lib.olm_unpickle_pk_decryption(
            obj._pk_decryption,
            key_buffer, len(byte_key),
            pickle_buffer, len(pickle),
            pubkey_buffer, pubkey_length)

        obj._check_error(ret)

        obj.public_key = bytes_to_native_str(ffi.unpack(
            pubkey_buffer,
            pubkey_length
        ))

        return obj
Esempio n. 2
0
    def __init__(self):
        if False:  # pragma: no cover
            self._pk_decryption = self._pk_decryption  # type: ffi.cdata

        random_length = lib.olm_pk_private_key_length()
        random = URANDOM(random_length)
        random_buffer = ffi.new("char[]", random)

        key_length = lib.olm_pk_key_length()
        key_buffer = ffi.new("char[]", key_length)

        ret = lib.olm_pk_key_from_private(self._pk_decryption, key_buffer,
                                          key_length, random_buffer,
                                          random_length)
        self._check_error(ret)
        self.public_key = bytes_to_native_str(
            ffi.unpack(key_buffer, key_length))
Esempio n. 3
0
    def encrypt(self, plaintext):
        # type: (AnyStr) -> PkMessage
        """Encrypt a message.

        Returns the encrypted PkMessage.

        Args:
            plaintext(str): A string that will be encrypted using the
            PkEncryption object.
        """
        byte_plaintext = to_bytearray(plaintext)

        r_length = lib.olm_pk_encrypt_random_length(self._pk_encryption)
        random = URANDOM(r_length)
        random_buffer = ffi.new("char[]", random)

        ciphertext_length = lib.olm_pk_ciphertext_length(
            self._pk_encryption, len(byte_plaintext))
        ciphertext = ffi.new("char[]", ciphertext_length)

        mac_length = lib.olm_pk_mac_length(self._pk_encryption)
        mac = ffi.new("char[]", mac_length)

        ephemeral_key_size = lib.olm_pk_key_length()
        ephemeral_key = ffi.new("char[]", ephemeral_key_size)

        ret = lib.olm_pk_encrypt(self._pk_encryption,
                                 ffi.from_buffer(byte_plaintext),
                                 len(byte_plaintext), ciphertext,
                                 ciphertext_length, mac, mac_length,
                                 ephemeral_key, ephemeral_key_size,
                                 random_buffer, r_length)

        try:
            self._check_error(ret)
        finally:  # pragma: no cover
            # clear out copies of plaintext
            if byte_plaintext is not plaintext:
                for i in range(0, len(byte_plaintext)):
                    byte_plaintext[i] = 0

        message = PkMessage(
            bytes_to_native_str(ffi.unpack(ephemeral_key, ephemeral_key_size)),
            bytes_to_native_str(ffi.unpack(mac, mac_length)),
            bytes_to_native_str(ffi.unpack(ciphertext, ciphertext_length)))
        return message
Esempio n. 4
0
    def from_pickle(cls, pickle, passphrase=""):
        # types: (bytes, str) -> PkDecryption
        """Restore a previously stored PkDecryption object.

        Creates a PkDecryption object from a pickled base64 string. Decrypts
        the pickled object using the supplied passphrase.
        Raises PkDecryptionError on failure. If the passphrase
        doesn't match the one used to encrypt the session then the error
        message for the exception will be "BAD_ACCOUNT_KEY". If the base64
        couldn't be decoded then the error message will be "INVALID_BASE64".

        Args:
            pickle(bytes): Base64 encoded byte string containing the pickled
                PkDecryption object
            passphrase(str, optional): The passphrase used to encrypt the
                object
        """
        if not pickle:
            raise ValueError("Pickle can't be empty")

        byte_key = to_bytearray(passphrase)
        pickle_buffer = ffi.new("char[]", pickle)

        pubkey_length = lib.olm_pk_key_length()
        pubkey_buffer = ffi.new("char[]", pubkey_length)

        obj = cls.__new__(cls)

        ret = lib.olm_unpickle_pk_decryption(obj._pk_decryption,
                                             ffi.from_buffer(byte_key),
                                             len(byte_key), pickle_buffer,
                                             len(pickle), pubkey_buffer,
                                             pubkey_length)

        try:
            obj._check_error(ret)
        finally:
            for i in range(0, len(byte_key)):
                byte_key[i] = 0

        obj.public_key = bytes_to_native_str(
            ffi.unpack(pubkey_buffer, pubkey_length))

        return obj
Esempio n. 5
0
    def encrypt(self, plaintext):
        # type: (AnyStr) -> PkMessage
        byte_plaintext = to_bytes(plaintext)

        r_length = lib.olm_pk_encrypt_random_length(self._pk_encryption)
        random = URANDOM(r_length)
        random_buffer = ffi.new("char[]", random)

        ciphertext_length = lib.olm_pk_ciphertext_length(
            self._pk_encryption, len(byte_plaintext)
        )
        ciphertext = ffi.new("char[]", ciphertext_length)

        mac_length = lib.olm_pk_mac_length(self._pk_encryption)
        mac = ffi.new("char[]", mac_length)

        ephermal_key_size = lib.olm_pk_key_length()
        ephermal_key = ffi.new("char[]", ephermal_key_size)

        ret = lib.olm_pk_encrypt(
            self._pk_encryption,
            byte_plaintext, len(byte_plaintext),
            ciphertext, ciphertext_length,
            mac, mac_length,
            ephermal_key, ephermal_key_size,
            random_buffer, r_length
        )
        self._check_error(ret)

        message = PkMessage(
            bytes_to_native_str(
                ffi.unpack(ephermal_key, ephermal_key_size)),
            bytes_to_native_str(
                ffi.unpack(mac, mac_length)),
            bytes_to_native_str(
                ffi.unpack(ciphertext, ciphertext_length))
        )
        return message