diff options
author | Paul Fariello <paul@fariello.eu> | 2019-03-05 20:01:15 +0140 |
---|---|---|
committer | Paul Fariello <paul@fariello.eu> | 2019-04-10 16:31:45 +0200 |
commit | 9b8c1d7d2c3c5ecc8abd431b9d407a59c95446f9 (patch) | |
tree | d5b7e9483364052333b4198ca39eca143c403ab4 /src | |
parent | 20ed86c58c3ae9ad23b27010ec4e429661b8c311 (diff) | |
download | profani-tty-9b8c1d7d2c3c5ecc8abd431b9d407a59c95446f9.tar.gz |
Add support for encrypted carbon
Fix {signed,}_pre_key store
Diffstat (limited to 'src')
-rw-r--r-- | src/event/server_events.c | 2 | ||||
-rw-r--r-- | src/event/server_events.h | 2 | ||||
-rw-r--r-- | src/omemo/omemo.c | 103 | ||||
-rw-r--r-- | src/omemo/store.c | 44 | ||||
-rw-r--r-- | src/omemo/store.h | 198 | ||||
-rw-r--r-- | src/xmpp/message.c | 18 | ||||
-rw-r--r-- | src/xmpp/stanza.c | 2 |
7 files changed, 326 insertions, 43 deletions
diff --git a/src/event/server_events.c b/src/event/server_events.c index b8ee36cf..33712328 100644 --- a/src/event/server_events.c +++ b/src/event/server_events.c @@ -510,7 +510,7 @@ sv_ev_incoming_message(char *barejid, char *resource, char *message, char *pgp_m } void -sv_ev_incoming_carbon(char *barejid, char *resource, char *message, char *pgp_message) +sv_ev_incoming_carbon(char *barejid, char *resource, char *message, char *pgp_message, gboolean omemo) { gboolean new_win = FALSE; ProfChatWin *chatwin = wins_get_chat(barejid); diff --git a/src/event/server_events.h b/src/event/server_events.h index b12ac94c..96fdb58c 100644 --- a/src/event/server_events.h +++ b/src/event/server_events.h @@ -74,7 +74,7 @@ void sv_ev_room_banned(const char *const room, const char *const actor, const ch void sv_ev_room_occupent_banned(const char *const room, const char *const nick, const char *const actor, const char *const reason); void sv_ev_outgoing_carbon(char *barejid, char *message, char *pgp_message); -void sv_ev_incoming_carbon(char *barejid, char *resource, char *message, char *pgp_message); +void sv_ev_incoming_carbon(char *barejid, char *resource, char *message, char *pgp_message, gboolean omemo); void sv_ev_xmpp_stanza(const char *const msg); void sv_ev_muc_self_online(const char *const room, const char *const nick, gboolean config_required, const char *const role, const char *const affiliation, const char *const actor, const char *const reason, diff --git a/src/omemo/omemo.c b/src/omemo/omemo.c index 4ca8bd47..6e964e81 100644 --- a/src/omemo/omemo.c +++ b/src/omemo/omemo.c @@ -42,8 +42,7 @@ struct omemo_context_t { GHashTable *device_list_handler; ratchet_identity_key_pair *identity_key_pair; uint32_t registration_id; - signal_protocol_key_helper_pre_key_list_node *pre_keys_head; - session_signed_pre_key *signed_pre_key; + uint32_t signed_pre_key_id; signal_protocol_store_context *store; GHashTable *session_store; GHashTable *pre_key_store; @@ -132,7 +131,7 @@ omemo_init(void) .contains_signed_pre_key = contains_signed_pre_key, .remove_signed_pre_key = remove_signed_pre_key, .destroy_func = NULL, - .user_data = omemo_ctx.pre_key_store + .user_data = omemo_ctx.signed_pre_key_store }; signal_protocol_store_context_set_signed_pre_key_store(omemo_ctx.store, &signed_pre_key_store); @@ -246,12 +245,23 @@ omemo_generate_crypto_materials(ProfAccount *account) static void omemo_generate_short_term_crypto_materials(ProfAccount *account) { - signal_protocol_key_helper_generate_pre_keys(&omemo_ctx.pre_keys_head, randombytes_random(), 100, omemo_ctx.signal); + signal_protocol_key_helper_pre_key_list_node *pre_keys_head; + signal_protocol_key_helper_generate_pre_keys(&pre_keys_head, randombytes_random(), 100, omemo_ctx.signal); + session_signed_pre_key *signed_pre_key; struct timeval tv; gettimeofday(&tv, NULL); unsigned long long timestamp = (unsigned long long)(tv.tv_sec) * 1000 + (unsigned long long)(tv.tv_usec) / 1000; - signal_protocol_key_helper_generate_signed_pre_key(&omemo_ctx.signed_pre_key, omemo_ctx.identity_key_pair, 5, timestamp, omemo_ctx.signal); + + omemo_ctx.signed_pre_key_id = 1; + signal_protocol_key_helper_generate_signed_pre_key(&signed_pre_key, omemo_ctx.identity_key_pair, omemo_ctx.signed_pre_key_id, timestamp, omemo_ctx.signal); + + signal_protocol_key_helper_pre_key_list_node *p; + for (p = pre_keys_head; p != NULL; p = signal_protocol_key_helper_key_list_next(p)) { + session_pre_key *prekey = signal_protocol_key_helper_key_list_element(p); + signal_protocol_pre_key_store_key(omemo_ctx.store, prekey); + } + signal_protocol_signed_pre_key_store_key(omemo_ctx.store, signed_pre_key); loaded = TRUE; @@ -308,8 +318,11 @@ omemo_identity_key(unsigned char **output, size_t *length) void omemo_signed_prekey(unsigned char **output, size_t *length) { + session_signed_pre_key *signed_pre_key; signal_buffer *buffer = NULL; - ec_public_key_serialize(&buffer, ec_key_pair_get_public(session_signed_pre_key_get_key_pair(omemo_ctx.signed_pre_key))); + + signal_protocol_signed_pre_key_load_key(omemo_ctx.store, &signed_pre_key, omemo_ctx.signed_pre_key_id); + ec_public_key_serialize(&buffer, ec_key_pair_get_public(session_signed_pre_key_get_key_pair(signed_pre_key))); *length = signal_buffer_len(buffer); *output = malloc(*length); memcpy(*output, signal_buffer_data(buffer), *length); @@ -319,25 +332,36 @@ omemo_signed_prekey(unsigned char **output, size_t *length) void omemo_signed_prekey_signature(unsigned char **output, size_t *length) { - *length = session_signed_pre_key_get_signature_len(omemo_ctx.signed_pre_key); + session_signed_pre_key *signed_pre_key; + + signal_protocol_signed_pre_key_load_key(omemo_ctx.store, &signed_pre_key, omemo_ctx.signed_pre_key_id); + *length = session_signed_pre_key_get_signature_len(signed_pre_key); *output = malloc(*length); - memcpy(*output, session_signed_pre_key_get_signature(omemo_ctx.signed_pre_key), *length); + memcpy(*output, session_signed_pre_key_get_signature(signed_pre_key), *length); } void omemo_prekeys(GList **prekeys, GList **ids, GList **lengths) { - signal_protocol_key_helper_pre_key_list_node *p; - for (p = omemo_ctx.pre_keys_head; p != NULL; p = signal_protocol_key_helper_key_list_next(p)) { - session_pre_key *prekey = signal_protocol_key_helper_key_list_element(p); - signal_buffer *buffer = NULL; - ec_public_key_serialize(&buffer, ec_key_pair_get_public(session_pre_key_get_key_pair(prekey))); - size_t length = signal_buffer_len(buffer); + GHashTableIter iter; + gpointer id; + + g_hash_table_iter_init(&iter, omemo_ctx.pre_key_store); + while (g_hash_table_iter_next(&iter, &id, NULL)) { + session_pre_key *pre_key; + int ret; + ret = signal_protocol_pre_key_load_key(omemo_ctx.store, &pre_key, GPOINTER_TO_INT(id)); + if (ret != SG_SUCCESS) { + continue; + } + + signal_buffer *public_key; + ec_public_key_serialize(&public_key, ec_key_pair_get_public(session_pre_key_get_key_pair(pre_key))); + size_t length = signal_buffer_len(public_key); unsigned char *prekey_value = malloc(length); - memcpy(prekey_value, signal_buffer_data(buffer), length); - signal_buffer_free(buffer); + memcpy(prekey_value, signal_buffer_data(public_key), length); *prekeys = g_list_append(*prekeys, prekey_value); - *ids = g_list_append(*ids, GINT_TO_POINTER(session_pre_key_get_id(prekey))); + *ids = g_list_append(*ids, GINT_TO_POINTER(id)); *lengths = g_list_append(*lengths, GINT_TO_POINTER(length)); } } @@ -349,6 +373,10 @@ omemo_set_device_list(const char *const jid, GList * device_list) char *barejid = xmpp_jid_bare(ctx, jid); g_hash_table_insert(omemo_ctx.device_list, strdup(barejid), device_list); + if (strchr(barejid, '@') == NULL) { + // barejid is server so we should handle it as our own device list + g_hash_table_insert(omemo_ctx.device_list_handler, strdup(barejid), handle_own_device_list); + } OmemoDeviceListHandler handler = g_hash_table_lookup(omemo_ctx.device_list_handler, barejid); if (handler) { @@ -397,16 +425,13 @@ omemo_on_message_send(ProfChatWin *chatwin, const char *const message, gboolean int res; xmpp_ctx_t * const ctx = connection_get_ctx(); char *barejid = xmpp_jid_bare(ctx, session_get_account_name()); - GList *device_ids = NULL; GList *recipient_device_id = g_hash_table_lookup(omemo_ctx.device_list, chatwin->barejid); if (!recipient_device_id) { return FALSE; } - device_ids = g_list_copy(recipient_device_id); GList *sender_device_id = g_hash_table_lookup(omemo_ctx.device_list, barejid); - device_ids = g_list_concat(device_ids, g_list_copy(sender_device_id)); /* TODO generate fresh AES-GCM materials */ /* TODO encrypt message */ @@ -430,7 +455,7 @@ omemo_on_message_send(ProfChatWin *chatwin, const char *const message, gboolean GList *keys = NULL; GList *device_ids_iter; - for (device_ids_iter = device_ids; device_ids_iter != NULL; device_ids_iter = device_ids_iter->next) { + for (device_ids_iter = recipient_device_id; device_ids_iter != NULL; device_ids_iter = device_ids_iter->next) { int res; ciphertext_message *ciphertext; session_cipher *cipher; @@ -452,7 +477,33 @@ omemo_on_message_send(ProfChatWin *chatwin, const char *const message, gboolean key->data = signal_buffer_data(buffer); key->length = signal_buffer_len(buffer); key->device_id = GPOINTER_TO_INT(device_ids_iter->data); - key->prekey = TRUE; + key->prekey = ciphertext_message_get_type(ciphertext) == CIPHERTEXT_PREKEY_TYPE; + keys = g_list_append(keys, key); + } + + for (device_ids_iter = sender_device_id; device_ids_iter != NULL; device_ids_iter = device_ids_iter->next) { + int res; + ciphertext_message *ciphertext; + session_cipher *cipher; + signal_protocol_address address = { + barejid, strlen(barejid), GPOINTER_TO_INT(device_ids_iter->data) + }; + + res = session_cipher_create(&cipher, omemo_ctx.store, &address, omemo_ctx.signal); + if (res != 0) { + continue; + } + + res = session_cipher_encrypt(cipher, key, AES128_GCM_KEY_LENGTH, &ciphertext); + if (res != 0) { + continue; + } + signal_buffer *buffer = ciphertext_message_get_serialized(ciphertext); + omemo_key_t *key = malloc(sizeof(omemo_key_t)); + key->data = signal_buffer_data(buffer); + key->length = signal_buffer_len(buffer); + key->device_id = GPOINTER_TO_INT(device_ids_iter->data); + key->prekey = ciphertext_message_get_type(ciphertext) == CIPHERTEXT_PREKEY_TYPE; keys = g_list_append(keys, key); } @@ -465,7 +516,6 @@ omemo_on_message_send(ProfChatWin *chatwin, const char *const message, gboolean free(ciphertext); sodium_free(key); sodium_free(iv); - g_list_free(device_ids); return TRUE; } @@ -544,7 +594,7 @@ unlock(void *user_data) static void omemo_log(int level, const char *message, size_t len, void *user_data) { - cons_show(message); + cons_show("OMEMO: %s", message); } static gboolean @@ -559,6 +609,11 @@ handle_own_device_list(const char *const jid, GList *device_list) omemo_devicelist_publish(device_list); } + GList *device_id; + for (device_id = device_list; device_id != NULL; device_id = device_id->next) { + omemo_bundle_request(jid, GPOINTER_TO_INT(device_id->data), omemo_start_device_session_handle_bundle, free, strdup(jid)); + } + return TRUE; } diff --git a/src/omemo/store.c b/src/omemo/store.c index ab8cd81b..9fec33e5 100644 --- a/src/omemo/store.c +++ b/src/omemo/store.c @@ -96,9 +96,19 @@ store_session(const signal_protocol_address *address, uint8_t *record, int contains_session(const signal_protocol_address *address, void *user_data) { - signal_buffer *record; - load_session(&record, address, user_data); - return record != NULL; + GHashTable *session_store = (GHashTable *)user_data; + GHashTable *device_store = NULL; + + device_store = g_hash_table_lookup(session_store, address->name); + if (!device_store) { + return 0; + } + + if (!g_hash_table_lookup(device_store, GINT_TO_POINTER(address->device_id))) { + return 0; + } + + return 1; } int @@ -134,9 +144,15 @@ delete_all_sessions(const char *name, size_t name_len, void *user_data) int load_pre_key(signal_buffer **record, uint32_t pre_key_id, void *user_data) { + signal_buffer *original; GHashTable *pre_key_store = (GHashTable *)user_data; - *record = g_hash_table_lookup(pre_key_store, GINT_TO_POINTER(pre_key_id)); + original = g_hash_table_lookup(pre_key_store, GINT_TO_POINTER(pre_key_id)); + if (original == NULL) { + return SG_ERR_INVALID_KEY_ID; + } + + *record = signal_buffer_copy(original); return SG_SUCCESS; } @@ -154,10 +170,9 @@ store_pre_key(uint32_t pre_key_id, uint8_t *record, size_t record_len, int contains_pre_key(uint32_t pre_key_id, void *user_data) { - signal_buffer *record; - load_pre_key(&record, pre_key_id, user_data); + GHashTable *pre_key_store = (GHashTable *)user_data; - return record != NULL; + return g_hash_table_lookup(pre_key_store, GINT_TO_POINTER(pre_key_id)) != NULL; } int @@ -172,9 +187,15 @@ int load_signed_pre_key(signal_buffer **record, uint32_t signed_pre_key_id, void *user_data) { + signal_buffer *original; GHashTable *signed_pre_key_store = (GHashTable *)user_data; - *record = g_hash_table_lookup(signed_pre_key_store, GINT_TO_POINTER(signed_pre_key_id)); + original = g_hash_table_lookup(signed_pre_key_store, GINT_TO_POINTER(signed_pre_key_id)); + if (!original) { + return SG_ERR_INVALID_KEY_ID; + } + + *record = signal_buffer_copy(original); return SG_SUCCESS; } @@ -192,10 +213,9 @@ store_signed_pre_key(uint32_t signed_pre_key_id, uint8_t *record, int contains_signed_pre_key(uint32_t signed_pre_key_id, void *user_data) { - signal_buffer *record; - load_signed_pre_key(&record, signed_pre_key_id, user_data); + GHashTable *signed_pre_key_store = (GHashTable *)user_data; - return record != NULL; + return g_hash_table_lookup(signed_pre_key_store, GINT_TO_POINTER(signed_pre_key_id)) != NULL; } int @@ -251,7 +271,7 @@ is_trusted_identity(const signal_protocol_address *address, uint8_t *key_data, signal_buffer *buffer = signal_buffer_create(key_data, key_len); signal_buffer *original = g_hash_table_lookup(identity_key_store->identity_key_store, node); - return original == NULL || signal_buffer_compare(buffer, original); + return original == NULL || signal_buffer_compare(buffer, original) == 0; } int diff --git a/src/omemo/store.h b/src/omemo/store.h index 491e1495..ad33d5a5 100644 --- a/src/omemo/store.h +++ b/src/omemo/store.h @@ -18,23 +18,221 @@ GHashTable * pre_key_store_new(void); GHashTable * signed_pre_key_store_new(void); void identity_key_store_new(identity_key_store_t *identity_key_store); +/** + * Returns a copy of the serialized session record corresponding to the + * provided recipient ID + device ID tuple. + * + * @param record pointer to a freshly allocated buffer containing the + * serialized session record. Unset if no record was found. + * The Signal Protocol library is responsible for freeing this buffer. + * @param address the address of the remote client + * @return 1 if the session was loaded, 0 if the session was not found, negative on failure + */ int load_session(signal_buffer **record, const signal_protocol_address *address, void *user_data); + +/** + * Returns all known devices with active sessions for a recipient + * + * @param pointer to an array that will be allocated and populated with the result + * @param name the name of the remote client + * @param name_len the length of the name + * @return size of the sessions array, or negative on failure + */ int get_sub_device_sessions(signal_int_list **sessions, const char *name, size_t name_len, void *user_data); + +/** + * Commit to storage the session record for a given + * recipient ID + device ID tuple. + * + * @param address the address of the remote client + * @param record pointer to a buffer containing the serialized session + * record for the remote client + * @param record_len length of the serialized session record + * @return 0 on success, negative on failure + */ int store_session(const signal_protocol_address *address, uint8_t *record, size_t record_len, void *user_data); + +/** + * Determine whether there is a committed session record for a + * recipient ID + device ID tuple. + * + * @param address the address of the remote client + * @return 1 if a session record exists, 0 otherwise. + */ int contains_session(const signal_protocol_address *address, void *user_data); + +/** + * Remove a session record for a recipient ID + device ID tuple. + * + * @param address the address of the remote client + * @return 1 if a session was deleted, 0 if a session was not deleted, negative on error + */ int delete_session(const signal_protocol_address *address, void *user_data); + +/** + * Remove the session records corresponding to all devices of a recipient ID. + * + * @param name the name of the remote client + * @param name_len the length of the name + * @return the number of deleted sessions on success, negative on failure + */ int delete_all_sessions(const char *name, size_t name_len, void *user_data); + +/** + * Load a local serialized PreKey record. + * + * @param record pointer to a newly allocated buffer containing the record, + * if found. Unset if no record was found. + * The Signal Protocol library is responsible for freeing this buffer. + * @param pre_key_id the ID of the local serialized PreKey record + * @retval SG_SUCCESS if the key was found + * @retval SG_ERR_INVALID_KEY_ID if the key could not be found + */ int load_pre_key(signal_buffer **record, uint32_t pre_key_id, void *user_data); + +/** + * Store a local serialized PreKey record. + * + * @param pre_key_id the ID of the PreKey record to store. + * @param record pointer to a buffer containing the serialized record + * @param record_len length of the serialized record + * @return 0 on success, negative on failure + */ int store_pre_key(uint32_t pre_key_id, uint8_t *record, size_t record_len, void *user_data); + +/** + * Determine whether there is a committed PreKey record matching the + * provided ID. + * + * @param pre_key_id A PreKey record ID. + * @return 1 if the store has a record for the PreKey ID, 0 otherwise + */ int contains_pre_key(uint32_t pre_key_id, void *user_data); + +/** + * Delete a PreKey record from local storage. + * + * @param pre_key_id The ID of the PreKey record to remove. + * @return 0 on success, negative on failure + */ int remove_pre_key(uint32_t pre_key_id, void *user_data); + +/** + * Load a local serialized signed PreKey record. + * + * @param record pointer to a newly allocated buffer containing the record, + * if found. Unset if no record was found. + * The Signal Protocol library is responsible for freeing this buffer. + * @param signed_pre_key_id the ID of the local signed PreKey record + * @retval SG_SUCCESS if the key was found + * @retval SG_ERR_INVALID_KEY_ID if the key could not be found + */ int load_signed_pre_key(signal_buffer **record, uint32_t signed_pre_key_id, void *user_data); + +/** + * Store a local serialized signed PreKey record. + * + * @param signed_pre_key_id the ID of the signed PreKey record to store + * @param record pointer to a buffer containing the serialized record + * @param record_len length of the serialized record + * @return 0 on success, negative on failure + */ int store_signed_pre_key(uint32_t signed_pre_key_id, uint8_t *record, size_t record_len, void *user_data); + +/** + * Determine whether there is a committed signed PreKey record matching + * the provided ID. + * + * @param signed_pre_key_id A signed PreKey record ID. + * @return 1 if the store has a record for the signed PreKey ID, 0 otherwise + */ int contains_signed_pre_key(uint32_t signed_pre_key_id, void *user_data); + +/** + * Delete a SignedPreKeyRecord from local storage. + * + * @param signed_pre_key_id The ID of the signed PreKey record to remove. + * @return 0 on success, negative on failure + */ int remove_signed_pre_key(uint32_t signed_pre_key_id, void *user_data); + +/** + * Get the local client's identity key pair. + * + * @param public_data pointer to a newly allocated buffer containing the + * public key, if found. Unset if no record was found. + * The Signal Protocol library is responsible for freeing this buffer. + * @param private_data pointer to a newly allocated buffer containing the + * private key, if found. Unset if no record was found. + * The Signal Protocol library is responsible for freeing this buffer. + * @return 0 on success, negative on failure + */ int get_identity_key_pair(signal_buffer **public_data, signal_buffer **private_data, void *user_data); + +/** + * Return the local client's registration ID. + * + * Clients should maintain a registration ID, a random number + * between 1 and 16380 that's generated once at install time. + * + * @param registration_id pointer to be set to the local client's + * registration ID, if it was successfully retrieved. + * @return 0 on success, negative on failure + */ int get_local_registration_id(void *user_data, uint32_t *registration_id); + +/** + * Save a remote client's identity key + * <p> + * Store a remote client's identity key as trusted. + * The value of key_data may be null. In this case remove the key data + * from the identity store, but retain any metadata that may be kept + * alongside it. + * + * @param address the address of the remote client + * @param key_data Pointer to the remote client's identity key, may be null + * @param key_len Length of the remote client's identity key + * @return 0 on success, negative on failure + */ int save_identity(const signal_protocol_address *address, uint8_t *key_data, size_t key_len, void *user_data); + +/** + * Verify a remote client's identity key. + * + * Determine whether a remote client's identity is trusted. Convention is + * that the TextSecure protocol is 'trust on first use.' This means that + * an identity key is considered 'trusted' if there is no entry for the recipient + * in the local store, or if it matches the saved key for a recipient in the local + * store. Only if it mismatches an entry in the local store is it considered + * 'untrusted.' + * + * @param address the address of the remote client + * @param identityKey The identity key to verify. + * @param key_data Pointer to the identity key to verify + * @param key_len Length of the identity key to verify + * @return 1 if trusted, 0 if untrusted, negative on failure + */ int is_trusted_identity(const signal_protocol_address *address, uint8_t *key_data, size_t key_len, void *user_data); + +/** + * Store a serialized sender key record for a given + * (groupId + senderId + deviceId) tuple. + * + * @param sender_key_name the (groupId + senderId + deviceId) tuple + * @param record pointer to a buffer containing the serialized record + * @param record_len length of the serialized record + * @return 0 on success, negative on failure + */ int store_sender_key(const signal_protocol_sender_key_name *sender_key_name, uint8_t *record, size_t record_len, uint8_t *user_record, size_t user_record_len, void *user_data); + +/** + * Returns a copy of the sender key record corresponding to the + * (groupId + senderId + deviceId) tuple. + * + * @param record pointer to a newly allocated buffer containing the record, + * if found. Unset if no record was found. + * The Signal Protocol library is responsible for freeing this buffer. + * @param sender_key_name the (groupId + senderId + deviceId) tuple + * @return 1 if the record was loaded, 0 if the record was not found, negative on failure + */ int load_sender_key(signal_buffer **record, signal_buffer **user_record, const signal_protocol_sender_key_name *sender_key_name, void *user_data); diff --git a/src/xmpp/message.c b/src/xmpp/message.c index 08ff4530..28fe96d8 100644 --- a/src/xmpp/message.c +++ b/src/xmpp/message.c @@ -840,6 +840,7 @@ _private_chat_handler(xmpp_stanza_t *const stanza, const char *const fulljid) static gboolean _handle_carbons(xmpp_stanza_t *const stanza) { + char *message_txt; xmpp_stanza_t *carbons = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_CARBONS); if (!carbons) { return FALSE; @@ -873,10 +874,19 @@ _handle_carbons(xmpp_stanza_t *const stanza) return TRUE; } - char *message_txt = xmpp_message_get_body(message); + // check omemo encryption + gboolean omemo = FALSE; +#ifdef HAVE_OMEMO + message_txt = omemo_receive_message(message); + omemo = message_txt != NULL; +#endif + if (!message_txt) { - log_warning("Carbon received with no message."); - return TRUE; + message_txt = xmpp_message_get_body(message); + if (!message_txt) { + log_warning("Carbon received with no message."); + return TRUE; + } } Jid *my_jid = jid_create(connection_get_fulljid()); @@ -904,7 +914,7 @@ _handle_carbons(xmpp_stanza_t *const stanza) // if we are the recipient, treat as standard incoming message if (g_strcmp0(my_jid->barejid, jid_to->barejid) == 0) { - sv_ev_incoming_carbon(jid_from->barejid, jid_from->resourcepart, message_txt, enc_message); + sv_ev_incoming_carbon(jid_from->barejid, jid_from->resourcepart, message_txt, enc_message, omemo); // else treat as a sent message } else { diff --git a/src/xmpp/stanza.c b/src/xmpp/stanza.c index 302258ec..61086f77 100644 --- a/src/xmpp/stanza.c +++ b/src/xmpp/stanza.c @@ -2251,7 +2251,7 @@ stanza_create_omemo_bundle_publish(xmpp_ctx_t *ctx, uint32_t device_id, xmpp_stanza_t *prekey = xmpp_stanza_new(ctx); xmpp_stanza_set_name(prekey, "preKeyPublic"); char *id = g_strdup_printf("%d", GPOINTER_TO_INT(i->data)); - xmpp_stanza_set_attribute(prekey, "id", id); + xmpp_stanza_set_attribute(prekey, "preKeyId", id); g_free(id); xmpp_stanza_t *prekey_text = xmpp_stanza_new(ctx); |