#ifndef SESSION_CIPHER_H #define SESSION_CIPHER_H #include #include #include "signal_protocol_types.h" #ifdef __cplusplus extern "C" { #endif /** * The main entry point for Signal Protocol encrypt/decrypt operations. * * Once a session has been established with session_builder, * this class can be used for all encrypt/decrypt operations within * that session. */ /** * Construct a session cipher for encrypt/decrypt operations on a session. * In order to use session_cipher, a session must have already been created * and stored using session_builder. * * The store and global contexts must remain valid for the lifetime of the * session cipher. * * When finished, free the returned instance by calling session_cipher_free(). * * @param cipher set to a freshly allocated session cipher instance * @param store the signal_protocol_store_context to store all state information in * @param remote_address the remote address that messages will be encrypted to or decrypted from. * @param global_context the global library context * @return 0 on success, or negative on failure */ int session_cipher_create(session_cipher **cipher, signal_protocol_store_context *store, const signal_protocol_address *remote_address, signal_context *global_context); /** * Set the optional user data pointer for the session cipher. * * This is to give callback functions a way of accessing app specific * context information for this cipher. */ void session_cipher_set_user_data(session_cipher *cipher, void *user_data); /** * Get the optional user data pointer for the session cipher. * * This is to give callback functions a way of accessing app specific * context information for this cipher. */ void *session_cipher_get_user_data(session_cipher *cipher); /** * Set the callback function that is called during the decrypt process. * * The callback function is called from within * session_cipher_decrypt_pre_key_signal_message() and * session_cipher_decrypt_signal_message() after decryption is complete * but before the updated session state has been committed to the session * store. If the callback function returns a negative value, then the * decrypt function will immediately fail with an error. * * This a callback allows some implementations to store the committed plaintext * to their local message store first, in case they are concerned with a crash * or write error happening between the time the session state is updated but * before they're able to successfully store the plaintext to disk. * * @param callback the callback function to set */ void session_cipher_set_decryption_callback(session_cipher *cipher, int (*callback)(session_cipher *cipher, signal_buffer *plaintext, void *decrypt_context)); /** * Encrypt a message. * * @param padded_message The plaintext message bytes, optionally padded to a constant multiple. * @param padded_message_len The length of the data pointed to by padded_message * @param encrypted_message Set to a ciphertext message encrypted to the recipient+device tuple. * * @return SG_SUCCESS on success, negative on error */ int session_cipher_encrypt(session_cipher *cipher, const uint8_t *padded_message, size_t padded_message_len, ciphertext_message **encrypted_message); /** * Decrypt a message. * * @param ciphertext The pre_key_signal_message to decrypt. * @param decrypt_context Optional context pointer associated with the * ciphertext, which is passed to the decryption callback function * @param plaintext Set to a newly allocated buffer containing the plaintext. * * @retval SG_SUCCESS Success * @retval SG_ERR_INVALID_MESSAGE if the input is not valid ciphertext. * @retval SG_ERR_DUPLICATE_MESSAGE if the input is a message that has already been received. * @retval SG_ERR_LEGACY_MESSAGE if the input is a message formatted by a protocol version that * is no longer supported. * @retval SG_ERR_INVALID_KEY_ID when there is no local pre_key_record * that corresponds to the pre key ID in the message. * @retval SG_ERR_INVALID_KEY when the message is formatted incorrectly. * @retval SG_ERR_UNTRUSTED_IDENTITY when the identity key of the sender is untrusted. */ int session_cipher_decrypt_pre_key_signal_message(session_cipher *cipher, pre_key_signal_message *ciphertext, void *decrypt_context, signal_buffer **plaintext); /** * Decrypt a message. * * @param ciphertext The signal_message to decrypt. * @param decrypt_context Optional context pointer associated with the * ciphertext, which is passed to the decryption callback function * @param plaintext Set to a newly allocated buffer containing the plaintext. * * @retval SG_SUCCESS Success * @retval SG_ERR_INVALID_MESSAGE if the input is not valid ciphertext. * @retval SG_ERR_DUPLICATE_MESSAGE if the input is a message that has already been received. * @retval SG_ERR_LEGACY_MESSAGE if the input is a message formatted by a protocol version that * is no longer supported. * @retval SG_ERR_NO_SESSION if there is no established session for this contact. */ int session_cipher_decrypt_signal_message(session_cipher *cipher, signal_message *ciphertext, void *decrypt_context, signal_buffer **plaintext); /** * Gets the remote registration ID for this session cipher. * * @param remote_id Set to the value of the remote registration ID * * @return SG_SUCCESS on success, negative on error */ int session_cipher_get_remote_registration_id(session_cipher *cipher, uint32_t *remote_id); /** * Gets the version of the session associated with this session cipher. * * @param version Set to the value of the session version * * @retval SG_SUCCESS Success * @retval SG_ERR_NO_SESSION if no session could be found */ int session_cipher_get_session_version(session_cipher *cipher, uint32_t *version); void session_cipher_free(session_cipher *cipher); #ifdef __cplusplus } #endif #endif /* SESSION_CIPHER_H */