about summary refs log tree commit diff stats
path: root/src/xmpp/omemo.c
diff options
context:
space:
mode:
authorPaul Fariello <paul@fariello.eu>2019-03-01 05:10:23 +0220
committerPaul Fariello <paul@fariello.eu>2019-04-10 16:03:50 +0200
commit810ea3222319e349bfc149fd85be470247b66c96 (patch)
treee701635c55f90f7be45758083d06e32df48d27ac /src/xmpp/omemo.c
parentd871efdcf91cce85e0dcc543d5be51b32871903f (diff)
downloadprofani-tty-810ea3222319e349bfc149fd85be470247b66c96.tar.gz
Follow normal workflow for OMEMO message reception
We try to decrypt all messages, if it's successful we use
sv_ev_incoming_message even for OMEMO messages. We pass an OMEMO
boolean to let UI be aware that message were encrypted.
Diffstat (limited to 'src/xmpp/omemo.c')
-rw-r--r--src/xmpp/omemo.c79
1 files changed, 79 insertions, 0 deletions
diff --git a/src/xmpp/omemo.c b/src/xmpp/omemo.c
index 048126fa..25057d55 100644
--- a/src/xmpp/omemo.c
+++ b/src/xmpp/omemo.c
@@ -191,6 +191,85 @@ omemo_start_device_session_handle_bundle(xmpp_stanza_t *const stanza, void *cons
     return 1;
 }
 
+char *
+omemo_receive_message(xmpp_stanza_t *const stanza)
+{
+    xmpp_stanza_t *encrypted = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_OMEMO);
+    if (!encrypted) {
+        return NULL;
+    }
+
+    xmpp_stanza_t *header = xmpp_stanza_get_child_by_name(encrypted, "header");
+    if (!header) {
+        return NULL;
+    }
+
+    const char *sid_text = xmpp_stanza_get_attribute(header, "sid");
+    if (!sid_text) {
+        return NULL;
+    }
+    uint32_t sid = strtoul(sid_text, NULL, 10);
+
+    xmpp_stanza_t *iv = xmpp_stanza_get_child_by_name(header, "iv");
+    if (!iv) {
+        return NULL;
+    }
+    const char *iv_text = xmpp_stanza_get_text(iv);
+    if (!iv_text) {
+        return NULL;
+    }
+    size_t iv_len;
+    const unsigned char *iv_raw = g_base64_decode(iv_text, &iv_len);
+
+    xmpp_stanza_t *payload = xmpp_stanza_get_child_by_name(encrypted, "payload");
+    if (!payload) {
+        return NULL;
+    }
+    const char *payload_text = xmpp_stanza_get_text(payload);
+    if (!payload_text) {
+        return NULL;
+    }
+    size_t payload_len;
+    const unsigned char *payload_raw = g_base64_decode(payload_text, &payload_len);
+
+    GList *keys = NULL;
+    xmpp_stanza_t *key_stanza;
+    for (key_stanza = xmpp_stanza_get_children(header); key_stanza != NULL; key_stanza = xmpp_stanza_get_next(key_stanza)) {
+        if (g_strcmp0(xmpp_stanza_get_name(key_stanza), "key") != 0) {
+            continue;
+        }
+
+        omemo_key_t *key = malloc(sizeof(omemo_key_t));
+        const char *key_text = xmpp_stanza_get_text(key_stanza);
+        if (!key_text) {
+            goto skip;
+        }
+
+
+        const char *rid_text = xmpp_stanza_get_attribute(key_stanza, "rid");
+        key->device_id = strtoul(rid_text, NULL, 10);
+        if (!key->device_id) {
+            goto skip;
+        }
+        key->data = g_base64_decode(key_text, &key->length);
+        key->prekey = g_strcmp0(xmpp_stanza_get_attribute(key_stanza, "prekey"), "true") == 0;
+        keys = g_list_append(keys, key);
+        continue;
+
+skip:
+        free(key);
+    }
+
+    const char *from = xmpp_stanza_get_from(stanza);
+    Jid *jid = jid_create(from);
+
+    char *plaintext = omemo_on_message_recv(jid->barejid, sid, iv_raw, iv_len, keys, payload_raw, payload_len);
+
+    jid_destroy(jid);
+
+    return plaintext;
+}
+
 static int
 _omemo_receive_devicelist(xmpp_stanza_t *const stanza, void *const userdata)
 {