about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--src/command/cmd_funcs.c15
-rw-r--r--src/omemo/omemo.c20
2 files changed, 27 insertions, 8 deletions
diff --git a/src/command/cmd_funcs.c b/src/command/cmd_funcs.c
index b140de53..90c41dfd 100644
--- a/src/command/cmd_funcs.c
+++ b/src/command/cmd_funcs.c
@@ -2151,22 +2151,21 @@ cmd_msg(ProfWin* window, const char* const command, gchar** args)
 
         ProfChatWin* chatwin = wins_get_chat(barejid);
         if (!chatwin) {
-            // NOTE: This will also start the new OMEMO session
-            // and send a MAM request.
+            // NOTE: This will also start the new OMEMO session and send a MAM request.
             chatwin = chatwin_new(barejid);
         }
         ui_focus_win((ProfWin*)chatwin);
 
         if (msg) {
-            // FIXME [OMEMO] We can't be sure whether the
-            // bundles have already been receieved. Thus, it is
-            // possible (and probable) that the recipent can't
-            // encrypt the message.
+            // NOTE: In case the message is OMEMO encrypted, we can't be sure
+            // whether the key bundles of the recipient have already been
+            // received. In the case that *no* bundles have been received yet,
+            // the message won't be sent, and an error is shown to the user.
+            // Other cases are not handled here.
             cl_ev_send_msg(chatwin, msg, NULL);
         } else {
 #ifdef HAVE_LIBOTR
-            // Start the OTR session after this (i.e. the
-            // first) message was sent
+            // Start the OTR session after this (i.e. the first) message was sent
             if (otr_is_secure(barejid)) {
                 chatwin_otr_secured(chatwin, otr_is_trusted(barejid));
             }
diff --git a/src/omemo/omemo.c b/src/omemo/omemo.c
index a552cd57..495842bf 100644
--- a/src/omemo/omemo.c
+++ b/src/omemo/omemo.c
@@ -705,6 +705,7 @@ omemo_on_message_send(ProfWin* win, const char* const message, gboolean request_
     memcpy(key_tag, key, AES128_GCM_KEY_LENGTH);
     memcpy(key_tag + AES128_GCM_KEY_LENGTH, tag, AES128_GCM_TAG_LENGTH);
 
+    // List of barejids of the recipients of this message
     GList* recipients = NULL;
     if (muc) {
         ProfMucWin* mucwin = (ProfMucWin*)win;
@@ -727,6 +728,7 @@ omemo_on_message_send(ProfWin* win, const char* const message, gboolean request_
 
     omemo_ctx.identity_key_store.recv = false;
 
+    // Encrypt keys for the recipients
     GList* recipients_iter;
     for (recipients_iter = recipients; recipients_iter != NULL; recipients_iter = recipients_iter->next) {
         GList* recipient_device_id = NULL;
@@ -772,6 +774,17 @@ omemo_on_message_send(ProfWin* win, const char* const message, gboolean request_
 
     g_list_free_full(recipients, free);
 
+    // Don't send the message if no key could be encrypted.
+    // (Since none of the recipients would be able to read the message.)
+    if (keys == NULL) {
+        win_println(win, THEME_ERROR, "!", "This message cannot be decrypted for any recipient.\n"
+                "You should trust your recipients' device fingerprint(s) using \"/omemo fingerprint trust FINGERPRINT\".\n"
+                "It could also be that the key bundle of the recipient(s) have not been received. "
+                "In this case, you could try \"omemo end\", \"omemo start\", and send the message again.");
+        goto out;
+    }
+
+    // Encrypt keys for the sender
     if (!muc) {
         GList* sender_device_id = g_hash_table_lookup(omemo_ctx.device_list, jid->barejid);
         for (device_ids_iter = sender_device_id; device_ids_iter != NULL; device_ids_iter = device_ids_iter->next) {
@@ -784,6 +797,12 @@ omemo_on_message_send(ProfWin* win, const char* const message, gboolean request_
                 .device_id = GPOINTER_TO_INT(device_ids_iter->data)
             };
 
+            // Don't encrypt for this device (according to
+            // <https://xmpp.org/extensions/xep-0384.html#encrypt>).
+            if (address.device_id == omemo_ctx.device_id) {
+                continue;
+            }
+
             res = session_cipher_create(&cipher, omemo_ctx.store, &address, omemo_ctx.signal);
             if (res != 0) {
                 log_error("[OMEMO] cannot create cipher for %s device id %d", address.name, address.device_id);
@@ -808,6 +827,7 @@ omemo_on_message_send(ProfWin* win, const char* const message, gboolean request_
         }
     }
 
+    // Send the message
     if (muc) {
         ProfMucWin* mucwin = (ProfMucWin*)win;
         assert(mucwin->memcheck == PROFMUCWIN_MEMCHECK);