def encrypt(self, plaintext): # type: (AnyStr) -> _OlmMessage """Encrypts a message using the session. Returns the ciphertext as a base64 encoded string on success. Raises OlmSessionError on failure. Args: plaintext(str): The plaintext message that will be encrypted. """ byte_plaintext = to_bytearray(plaintext) r_length = lib.olm_encrypt_random_length(self._session) random = URANDOM(r_length) try: message_type = lib.olm_encrypt_message_type(self._session) self._check_error(message_type) ciphertext_length = lib.olm_encrypt_message_length( self._session, len(byte_plaintext)) ciphertext_buffer = ffi.new("char[]", ciphertext_length) self._check_error( lib.olm_encrypt( self._session, ffi.from_buffer(byte_plaintext), len(byte_plaintext), ffi.from_buffer(random), r_length, ciphertext_buffer, ciphertext_length, )) finally: # clear out copies of plaintext if byte_plaintext is not plaintext: for i in range(0, len(byte_plaintext)): byte_plaintext[i] = 0 if message_type == lib.OLM_MESSAGE_TYPE_PRE_KEY: return OlmPreKeyMessage( bytes_to_native_str( ffi.unpack(ciphertext_buffer, ciphertext_length))) elif message_type == lib.OLM_MESSAGE_TYPE_MESSAGE: return OlmMessage( bytes_to_native_str( ffi.unpack(ciphertext_buffer, ciphertext_length))) else: # pragma: no cover raise ValueError("Unknown message type")
def encrypt(self, plaintext): # type: (AnyStr) -> _OlmMessage """Encrypts a message using the session. Returns the ciphertext as an base64 encoded strin on success. Raises OlmSessionError on failure. If there weren't enough random bytes to encrypt the message the error message for the exception will be NOT_ENOUGH_RANDOM. Args: plaintext(str): The plaintext message that will be encrypted. """ byte_plaintext = to_bytes(plaintext) r_length = lib.olm_encrypt_random_length(self._session) random = URANDOM(r_length) random_buffer = ffi.new("char[]", random) message_type = lib.olm_encrypt_message_type(self._session) self._check_error(message_type) ciphertext_length = lib.olm_encrypt_message_length( self._session, len(plaintext) ) ciphertext_buffer = ffi.new("char[]", ciphertext_length) plaintext_buffer = ffi.new("char[]", byte_plaintext) self._check_error(lib.olm_encrypt( self._session, plaintext_buffer, len(byte_plaintext), random_buffer, r_length, ciphertext_buffer, ciphertext_length, )) if message_type == lib.OLM_MESSAGE_TYPE_PRE_KEY: return OlmPreKeyMessage( bytes_to_native_str(ffi.unpack( ciphertext_buffer, ciphertext_length ))) elif message_type == lib.OLM_MESSAGE_TYPE_MESSAGE: return OlmMessage( bytes_to_native_str(ffi.unpack( ciphertext_buffer, ciphertext_length ))) else: # pragma: no cover raise ValueError("Unknown message type")
def __init__(self, seed): # type: (bytes) -> None """Create a new signing object. Args: seed(bytes): the seed to use as the private key for signing. The seed must have the same length as the seeds generated by PkSigning.generate_seed(). """ if not seed: raise ValueError("seed can't be empty") self._buf = ffi.new("char[]", lib.olm_pk_signing_size()) self._pk_signing = lib.olm_pk_signing(self._buf) track_for_finalization(self, self._pk_signing, _clear_pk_signing) seed_buffer = ffi.new("char[]", seed) pubkey_length = lib.olm_pk_signing_public_key_length() pubkey_buffer = ffi.new("char[]", pubkey_length) ret = lib.olm_pk_signing_key_from_seed(self._pk_signing, pubkey_buffer, pubkey_length, seed_buffer, len(seed)) # zero out copies of the seed lib.memset(seed_buffer, 0, len(seed)) self._check_error(ret) self.public_key = bytes_to_native_str( ffi.unpack(pubkey_buffer, pubkey_length))
def pickle(self, passphrase=""): # type: (str) -> bytes """Store a PkDecryption object. Stores a PkDecryption object as a base64 string. Encrypts the object using the supplied passphrase. Returns a byte object containing the base64 encoded string of the pickled session. Args: passphrase(str, optional): The passphrase to be used to encrypt the object. """ byte_key = to_bytearray(passphrase) pickle_length = lib.olm_pickle_pk_decryption_length( self._pk_decryption) pickle_buffer = ffi.new("char[]", pickle_length) ret = lib.olm_pickle_pk_decryption(self._pk_decryption, ffi.from_buffer(byte_key), len(byte_key), pickle_buffer, pickle_length) try: self._check_error(ret) finally: # zero out copies of the passphrase for i in range(0, len(byte_key)): byte_key[i] = 0 return ffi.unpack(pickle_buffer, pickle_length)
def decrypt(self, message): # type: (_OlmMessage) -> str """Decrypts a message using the session. Returns the plaintext string on success. Raises OlmSessionError on failure. If the base64 couldn't be decoded then the error message will be "INVALID_BASE64". If the message is for an unsupported version of the protocol the error message will be "BAD_MESSAGE_VERSION". If the message couldn't be decoded then the error message will be "BAD_MESSAGE_FORMAT". If the MAC on the message was invalid then the error message will be "BAD_MESSAGE_MAC". Args: message(OlmMessage): The Olm message that will be decrypted. It can be either an OlmPreKeyMessage or an OlmMessage. """ if not message.ciphertext: raise ValueError("Ciphertext can't be empty") byte_ciphertext = to_bytes(message.ciphertext) ciphertext_buffer = ffi.new("char[]", byte_ciphertext) max_plaintext_length = lib.olm_decrypt_max_plaintext_length( self._session, message.message_type, ciphertext_buffer, len(byte_ciphertext)) plaintext_buffer = ffi.new("char[]", max_plaintext_length) ciphertext_buffer = ffi.new("char[]", byte_ciphertext) plaintext_length = lib.olm_decrypt(self._session, message.message_type, ciphertext_buffer, len(byte_ciphertext), plaintext_buffer, max_plaintext_length) self._check_error(plaintext_length) return bytes_to_native_str( ffi.unpack(plaintext_buffer, plaintext_length))
def pickle(self, passphrase=""): # type: (Optional[str]) -> bytes """Store an inbound group session. Stores a group session as a base64 string. Encrypts the session using the supplied passphrase. Returns a byte object containing the base64 encoded string of the pickled session. Args: passphrase(str, optional): The passphrase to be used to encrypt the session. """ byte_passphrase = bytes(passphrase, "utf-8") if passphrase else b"" passphrase_buffer = ffi.new("char[]", byte_passphrase) pickle_length = lib.olm_pickle_inbound_group_session_length( self._session) pickle_buffer = ffi.new("char[]", pickle_length) ret = lib.olm_pickle_inbound_group_session(self._session, passphrase_buffer, len(byte_passphrase), pickle_buffer, pickle_length) self._check_error(ret) return ffi.unpack(pickle_buffer, pickle_length)
def pickle(self, passphrase=""): # type: (Optional[str]) -> bytes """Store an Olm account. Stores an account as a base64 string. Encrypts the account using the supplied passphrase. Returns a byte object containing the base64 encoded string of the pickled account. Raises OlmAccountError on failure. Args: passphrase(str, optional): The passphrase to be used to encrypt the account. """ byte_key = bytearray(passphrase, "utf-8") if passphrase else b"" pickle_length = lib.olm_pickle_account_length(self._account) pickle_buffer = ffi.new("char[]", pickle_length) try: self._check_error( lib.olm_pickle_account(self._account, ffi.from_buffer(byte_key), len(byte_key), pickle_buffer, pickle_length)) finally: # zero out copies of the passphrase for i in range(0, len(byte_key)): byte_key[i] = 0 return ffi.unpack(pickle_buffer, pickle_length)
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 generate_bytes(self, extra_info, length): # type: (str, int) -> bytes """Generate bytes to use for the short authentication string. Args: extra_info (str): Extra information to mix in when generating the bytes. length (int): The number of bytes to generate. Raises OlmSasError if the other users persons public key isn't set or an internal Olm error happens. """ if length < 1: raise ValueError("The length needs to be a positive integer value") byte_info = to_bytearray(extra_info) out_buffer = ffi.new("char[]", length) self._check_error( lib.olm_sas_generate_bytes( self._sas, ffi.from_buffer(byte_info), len(byte_info), out_buffer, length ) ) return ffi.unpack(out_buffer, length)
def export_session(self, message_index): # type: (int) -> str """Export an inbound group session Export the base64-encoded ratchet key for this session, at the given index, in a format which can be used by import_session(). Raises OlmGroupSessionError on failure. The error message for the exception will be: * OLM_UNKNOWN_MESSAGE_INDEX if we do not have a session key corresponding to the given index (ie, it was sent before the session key was shared with us) Args: message_index(int): The message index at which the session should be exported. """ export_length = lib.olm_export_inbound_group_session_length( self._session) export_buffer = ffi.new("char[]", export_length) ret = lib.olm_export_inbound_group_session(self._session, export_buffer, export_length, message_index) self._check_error(ret) return bytes_to_native_str(ffi.unpack(export_buffer, export_length))
def encrypt(self, plaintext): # type: (AnyStr) -> str """Encrypt a message. Returns the encrypted ciphertext. Args: plaintext(str): A string that will be encrypted using the group session. """ byte_plaintext = to_bytes(plaintext) message_length = lib.olm_group_encrypt_message_length( self._session, len(byte_plaintext)) message_buffer = ffi.new("char[]", message_length) plaintext_buffer = ffi.new("char[]", byte_plaintext) ret = lib.olm_group_encrypt( self._session, plaintext_buffer, len(byte_plaintext), message_buffer, message_length, ) self._check_error(ret) return bytes_to_native_str(ffi.unpack(message_buffer, message_length))
def calculate_mac(self, message, extra_info): # type: (str, str) -> str """Generate a message authentication code based on the shared secret. Args: message (str): The message to produce the authentication code for. extra_info (str): Extra information to mix in when generating the MAC Raises OlmSasError on failure. """ byte_message = to_bytes(message) byte_info = to_bytes(extra_info) mac_length = lib.olm_sas_mac_length(self._sas) mac_buffer = ffi.new("char[]", mac_length) self._check_error( lib.olm_sas_calculate_mac( self._sas, ffi.from_buffer(byte_message), len(byte_message), ffi.from_buffer(byte_info), len(byte_info), mac_buffer, mac_length ) ) return bytes_to_native_str(ffi.unpack(mac_buffer, mac_length))
def calculate_mac_long_kdf(self, message, extra_info): # type: (str, str) -> str """Generate a message authentication code based on the shared secret. This function should not be used unless compatibility with an older non-tagged Olm version is required. Args: message (str): The message to produce the authentication code for. extra_info (str): Extra information to mix in when generating the MAC Raises OlmSasError on failure. """ byte_message = to_bytes(message) byte_info = to_bytes(extra_info) mac_length = lib.olm_sas_mac_length(self._sas) mac_buffer = ffi.new("char[]", mac_length) self._check_error( lib.olm_sas_calculate_mac_long_kdf( self._sas, ffi.from_buffer(byte_message), len(byte_message), ffi.from_buffer(byte_info), len(byte_info), mac_buffer, mac_length ) ) return bytes_to_native_str(ffi.unpack(mac_buffer, mac_length))
def sign(self, message): # type: (AnyStr) -> str """Signs a message with this account. Signs a message with the private ed25519 identity key of this account. Returns the signature. Raises OlmAccountError on failure. Args: message(str): The message to sign. """ bytes_message = to_bytearray(message) out_length = lib.olm_account_signature_length(self._account) out_buffer = ffi.new("char[]", out_length) try: self._check_error( lib.olm_account_sign(self._account, ffi.from_buffer(bytes_message), len(bytes_message), out_buffer, out_length)) finally: # clear out copies of the message, which may be plaintext if bytes_message is not message: for i in range(0, len(bytes_message)): bytes_message[i] = 0 return bytes_to_native_str(ffi.unpack(out_buffer, out_length))
def pickle(self, passphrase=""): # type: (Optional[str]) -> bytes """Store an outbound group session. Stores a group session as a base64 string. Encrypts the session using the supplied passphrase. Returns a byte object containing the base64 encoded string of the pickled session. Args: passphrase(str, optional): The passphrase to be used to encrypt the session. """ byte_passphrase = bytearray(passphrase, "utf-8") if passphrase else b"" pickle_length = lib.olm_pickle_outbound_group_session_length( self._session) pickle_buffer = ffi.new("char[]", pickle_length) try: ret = lib.olm_pickle_outbound_group_session( self._session, ffi.from_buffer(byte_passphrase), len(byte_passphrase), pickle_buffer, pickle_length) self._check_error(ret) finally: # clear out copies of the passphrase for i in range(0, len(byte_passphrase)): byte_passphrase[i] = 0 return ffi.unpack(pickle_buffer, pickle_length)
def decrypt(self, message): # type (PkMessage) -> str ephermal_key = to_bytes(message.ephermal_key) ephermal_key_size = len(ephermal_key) mac = to_bytes(message.mac) mac_length = len(mac) ciphertext = to_bytes(message.ciphertext) ciphertext_length = len(ciphertext) max_plaintext_length = lib.olm_pk_max_plaintext_length( self._pk_decryption, ciphertext_length ) plaintext = ffi.new("char[]", max_plaintext_length) ret = lib.olm_pk_decrypt( self._pk_decryption, ephermal_key, ephermal_key_size, mac, mac_length, ciphertext, ciphertext_length, plaintext, max_plaintext_length) self._check_error(ret) unpacked_plaintext = (ffi.unpack( plaintext, ret )) return bytes_to_native_str(unpacked_plaintext)
def encrypt(self, plaintext): # type: (AnyStr) -> str """Encrypt a message. Returns the encrypted ciphertext. Args: plaintext(str): A string that will be encrypted using the group session. """ byte_plaintext = to_bytearray(plaintext) message_length = lib.olm_group_encrypt_message_length( self._session, len(byte_plaintext)) message_buffer = ffi.new("char[]", message_length) try: ret = lib.olm_group_encrypt( self._session, ffi.from_buffer(byte_plaintext), len(byte_plaintext), message_buffer, message_length, ) self._check_error(ret) finally: # clear out copies of plaintext if byte_plaintext is not plaintext: for i in range(0, len(byte_plaintext)): byte_plaintext[i] = 0 return bytes_to_native_str(ffi.unpack(message_buffer, message_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 id(self): # type: () -> str """str: A base64 encoded identifier for this session.""" id_length = lib.olm_inbound_group_session_id_length(self._session) id_buffer = ffi.new("char[]", id_length) ret = lib.olm_inbound_group_session_id(self._session, id_buffer, id_length) self._check_error(ret) return bytes_to_native_str(ffi.unpack(id_buffer, id_length))
def identity_keys(self): # type: () -> Dict[str, str] """dict: Public part of the identity keys of the account.""" out_length = lib.olm_account_identity_keys_length(self._account) out_buffer = ffi.new("char[]", out_length) self._check_error( lib.olm_account_identity_keys(self._account, out_buffer, out_length)) return json.loads(ffi.unpack(out_buffer, out_length).decode("utf-8"))
def decrypt(self, ciphertext): # type: (AnyStr) -> Tuple[str, int] """Decrypt a message Returns a tuple of the decrypted plain-text and the message index of the decrypted message or raises OlmGroupSessionError on failure. On failure the error message of the exception will be: * OLM_INVALID_BASE64 if the message is not valid base64 * OLM_BAD_MESSAGE_VERSION if the message was encrypted with an unsupported version of the protocol * OLM_BAD_MESSAGE_FORMAT if the message headers could not be decoded * OLM_BAD_MESSAGE_MAC if the message could not be verified * OLM_UNKNOWN_MESSAGE_INDEX if we do not have a session key corresponding to the message's index (i.e., it was sent before the session key was shared with us) Args: ciphertext(str): Base64 encoded ciphertext containing the encrypted message """ if not ciphertext: raise ValueError("Ciphertext can't be empty.") byte_ciphertext = to_bytes(ciphertext) # copy because max_plaintext_length will destroy the buffer ciphertext_buffer = ffi.new("char[]", byte_ciphertext) max_plaintext_length = lib.olm_group_decrypt_max_plaintext_length( self._session, ciphertext_buffer, len(byte_ciphertext)) self._check_error(max_plaintext_length) plaintext_buffer = ffi.new("char[]", max_plaintext_length) # copy because max_plaintext_length will destroy the buffer ciphertext_buffer = ffi.new("char[]", byte_ciphertext) message_index = ffi.new("uint32_t*") plaintext_length = lib.olm_group_decrypt(self._session, ciphertext_buffer, len(byte_ciphertext), plaintext_buffer, max_plaintext_length, message_index) self._check_error(plaintext_length) plaintext = bytes_to_native_str( ffi.unpack(plaintext_buffer, plaintext_length)) # clear out copies of the plaintext lib.memset(plaintext_buffer, 0, max_plaintext_length) return plaintext, message_index[0]
def one_time_keys(self): # type: () -> Dict[str, Dict[str, str]] """dict: The public part of the one-time keys for this account.""" out_length = lib.olm_account_one_time_keys_length(self._account) out_buffer = ffi.new("char[]", out_length) self._check_error( lib.olm_account_one_time_keys(self._account, out_buffer, out_length)) return json.loads(ffi.unpack(out_buffer, out_length).decode("utf-8"))
def id(self): # type: () -> str """str: An identifier for this session. Will be the same for both ends of the conversation. """ id_length = lib.olm_session_id_length(self._session) id_buffer = ffi.new("char[]", id_length) self._check_error( lib.olm_session_id(self._session, id_buffer, id_length)) return bytes_to_native_str(ffi.unpack(id_buffer, id_length))
def decrypt(self, message, unicode_errors="replace"): # type: (_OlmMessage, str) -> str """Decrypts a message using the session. Returns the plaintext string on success. Raises OlmSessionError on failure. If the base64 couldn't be decoded then the error message will be "INVALID_BASE64". If the message is for an unsupported version of the protocol the error message will be "BAD_MESSAGE_VERSION". If the message couldn't be decoded then the error message will be "BAD_MESSAGE_FORMAT". If the MAC on the message was invalid then the error message will be "BAD_MESSAGE_MAC". Args: message(OlmMessage): The Olm message that will be decrypted. It can be either an OlmPreKeyMessage or an OlmMessage. unicode_errors(str, optional): The error handling scheme to use for unicode decoding errors. The default is "replace" meaning that the character that was unable to decode will be replaced with the unicode replacement character (U+FFFD). Other possible values are "strict", "ignore" and "xmlcharrefreplace" as well as any other name registered with codecs.register_error that can handle UnicodeEncodeErrors. """ if not message.ciphertext: raise ValueError("Ciphertext can't be empty") byte_ciphertext = to_bytes(message.ciphertext) # make a copy the ciphertext buffer, because # olm_decrypt_max_plaintext_length wants to destroy something ciphertext_buffer = ffi.new("char[]", byte_ciphertext) max_plaintext_length = lib.olm_decrypt_max_plaintext_length( self._session, message.message_type, ciphertext_buffer, len(byte_ciphertext)) self._check_error(max_plaintext_length) plaintext_buffer = ffi.new("char[]", max_plaintext_length) # make a copy the ciphertext buffer, because # olm_decrypt_max_plaintext_length wants to destroy something ciphertext_buffer = ffi.new("char[]", byte_ciphertext) plaintext_length = lib.olm_decrypt(self._session, message.message_type, ciphertext_buffer, len(byte_ciphertext), plaintext_buffer, max_plaintext_length) self._check_error(plaintext_length) plaintext = to_unicode_str(ffi.unpack(plaintext_buffer, plaintext_length), errors=unicode_errors) # clear out copies of the plaintext lib.memset(plaintext_buffer, 0, max_plaintext_length) return plaintext
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
def _sha256(cls, input): # type: (Type[_Utility], AnyStr) -> str if not cls._utility: cls._allocate() byte_input = to_bytes(input) hash_length = lib.olm_sha256_length(cls._utility) hash = ffi.new("char[]", hash_length) ret = lib.olm_sha256(cls._utility, byte_input, len(byte_input), hash, hash_length) cls._check_error(ret, OlmHashError) return bytes_to_native_str(ffi.unpack(hash, hash_length))
def session_key(self): # type: () -> str """The base64-encoded current ratchet key for this session. Each message is encrypted with a different ratchet key. This function returns the ratchet key that will be used for the next message. """ key_length = lib.olm_outbound_group_session_key_length(self._session) key_buffer = ffi.new("char[]", key_length) ret = lib.olm_outbound_group_session_key(self._session, key_buffer, key_length) self._check_error(ret) return bytes_to_native_str(ffi.unpack(key_buffer, key_length))
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 pubkey(self): # type: () -> str """Get the public key for the SAS object. This returns the public key of the SAS object that can then be shared with another user to perform the authentication process. Raises OlmSasError on failure. """ pubkey_length = lib.olm_sas_pubkey_length(self._sas) pubkey_buffer = ffi.new("char[]", pubkey_length) self._check_error( lib.olm_sas_get_pubkey(self._sas, pubkey_buffer, pubkey_length)) return bytes_to_native_str(ffi.unpack(pubkey_buffer, pubkey_length))
def pickle(self, passphrase=""): # type: (str) -> bytes byte_key = to_bytes(passphrase) key_buffer = ffi.new("char[]", byte_key) pickle_length = lib.olm_pickle_pk_decryption_length( self._pk_decryption ) pickle_buffer = ffi.new("char[]", pickle_length) ret = lib.olm_pickle_pk_decryption( self._pk_decryption, key_buffer, len(byte_key), pickle_buffer, pickle_length ) self._check_error(ret) return ffi.unpack(pickle_buffer, pickle_length)