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
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))
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
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
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