about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--src/command/cmd_ac.c1
-rw-r--r--src/command/cmd_defs.c9
-rw-r--r--src/command/cmd_funcs.c28
-rw-r--r--src/command/cmd_funcs.h1
-rw-r--r--src/omemo/omemo.c51
-rw-r--r--src/omemo/omemo.h3
6 files changed, 90 insertions, 3 deletions
diff --git a/src/command/cmd_ac.c b/src/command/cmd_ac.c
index daf4f3a9..55f05c7c 100644
--- a/src/command/cmd_ac.c
+++ b/src/command/cmd_ac.c
@@ -579,6 +579,7 @@ cmd_ac_init(void)
     omemo_ac = autocomplete_new();
     autocomplete_add(omemo_ac, "gen");
     autocomplete_add(omemo_ac, "start");
+    autocomplete_add(omemo_ac, "fingerprint");
 
     connect_property_ac = autocomplete_new();
     autocomplete_add(connect_property_ac, "server");
diff --git a/src/command/cmd_defs.c b/src/command/cmd_defs.c
index 3cd8330e..7b2df39b 100644
--- a/src/command/cmd_defs.c
+++ b/src/command/cmd_defs.c
@@ -2334,19 +2334,22 @@ static struct cmd_t command_defs[] =
         parse_args, 1, 2, NULL,
         CMD_SUBFUNCS(
             { "gen", cmd_omemo_gen },
-            { "start", cmd_omemo_start })
+            { "start", cmd_omemo_start },
+            { "fingerprint", cmd_omemo_fingerprint })
         CMD_NOMAINFUNC
         CMD_TAGS(
             CMD_TAG_CHAT,
             CMD_TAG_UI)
         CMD_SYN(
             "/omemo gen",
-            "/omemo start [<contact>]")
+            "/omemo start [<contact>]",
+            "/omemo fingerprint")
         CMD_DESC(
             "Omemo commands to manage keys, and perform encryption during chat sessions.")
         CMD_ARGS(
             { "gen",               "Generate OMEMO crytographic materials for current account." },
-            { "start [<contact>]", "Start an OMEMO session with contact, or current recipient if omitted." })
+            { "start [<contact>]", "Start an OMEMO session with contact, or current recipient if omitted." },
+            { "fingerprint",       "Show current device fingerprint." })
         CMD_EXAMPLES(
             "/omemo gen",
             "/omemo start buddy@buddychat.org")
diff --git a/src/command/cmd_funcs.c b/src/command/cmd_funcs.c
index 5ce9b7f4..70940f17 100644
--- a/src/command/cmd_funcs.c
+++ b/src/command/cmd_funcs.c
@@ -7988,3 +7988,31 @@ cmd_omemo_start(ProfWin *window, const char *const command, gchar **args)
     return TRUE;
 #endif
 }
+
+gboolean
+cmd_omemo_fingerprint(ProfWin *window, const char *const command, gchar **args)
+{
+#ifdef HAVE_OMEMO
+    if (connection_get_status() != JABBER_CONNECTED) {
+        cons_show("You must be connected with an account to load OMEMO information.");
+        return TRUE;
+    }
+
+    if (!omemo_loaded()) {
+        win_println(window, THEME_DEFAULT, '!', "You have not generated or loaded a cryptographic materials, use '/omemo gen'");
+        return TRUE;
+    }
+
+    char *fingerprint = omemo_own_fingerprint();
+    char *formated_fingerprint = omemo_format_fingerprint(fingerprint);
+    cons_show("%s", formated_fingerprint);
+
+    free(fingerprint);
+    free(formated_fingerprint);
+
+    return TRUE;
+#else
+    cons_show("This version of Profanity has not been built with OMEMO support enabled");
+    return TRUE;
+#endif
+}
diff --git a/src/command/cmd_funcs.h b/src/command/cmd_funcs.h
index f39e8c17..4809f703 100644
--- a/src/command/cmd_funcs.h
+++ b/src/command/cmd_funcs.h
@@ -216,5 +216,6 @@ gboolean cmd_form_field(ProfWin *window, char *tag, gchar **args);
 
 gboolean cmd_omemo_gen(ProfWin *window, const char *const command, gchar **args);
 gboolean cmd_omemo_start(ProfWin *window, const char *const command, gchar **args);
+gboolean cmd_omemo_fingerprint(ProfWin *window, const char *const command, gchar **args);
 
 #endif
diff --git a/src/omemo/omemo.c b/src/omemo/omemo.c
index 3a771b6b..b293022f 100644
--- a/src/omemo/omemo.c
+++ b/src/omemo/omemo.c
@@ -679,6 +679,57 @@ omemo_on_message_recv(const char *const from, uint32_t sid,
 
 }
 
+char *
+omemo_format_fingerprint(const char *const fingerprint)
+{
+    char *output = malloc(strlen(fingerprint) + strlen(fingerprint) / 8 + 1);
+
+    int i, j;
+    for (i = 0, j = 0; i < strlen(fingerprint); i++) {
+        if (i > 0 && i % 8 == 0) {
+            output[j++] = '-';
+        }
+        output[j++] = fingerprint[i];
+    }
+
+    output[strlen(fingerprint) + strlen(fingerprint) / 8] = '\0';
+
+    return output;
+}
+
+char *
+omemo_own_fingerprint()
+{
+    signal_buffer *public = omemo_ctx.identity_key_store.public;
+    /* Skip first byte corresponding to signal base type */
+    return omemo_fingerprint(signal_buffer_data(public) + 1, signal_buffer_len(public) - 1);
+}
+
+char *
+omemo_fingerprint(const unsigned char *const identity_key_public, size_t len)
+{
+    int i;
+    char *fingerprint = malloc(len * 2 + 1);
+
+    for (i = 0; i < len; i++) {
+        fingerprint[i * 2] = (identity_key_public[i] & 0xf0) >> 4;
+        fingerprint[i * 2] += 0x30;
+        if (fingerprint[i * 2] > 0x39) {
+            fingerprint[i * 2] += 0x27;
+        }
+
+        fingerprint[(i * 2) + 1] = identity_key_public[i] & 0x0f;
+        fingerprint[(i * 2) + 1] += 0x30;
+        if (fingerprint[(i * 2) + 1] > 0x39) {
+            fingerprint[(i * 2) + 1] += 0x27;
+        }
+    }
+
+    fingerprint[len * 2] = '\0';
+
+    return fingerprint;
+}
+
 static void
 lock(void *user_data)
 {
diff --git a/src/omemo/omemo.h b/src/omemo/omemo.h
index ef43617d..88c6d27c 100644
--- a/src/omemo/omemo.h
+++ b/src/omemo/omemo.h
@@ -28,6 +28,9 @@ void omemo_prekeys(GList **prekeys, GList **ids, GList **lengths);
 void omemo_set_device_list(const char *const jid, GList * device_list);
 GKeyFile *omemo_sessions_keyfile(void);
 void omemo_sessions_keyfile_save(void);
+char *omemo_fingerprint(const unsigned char *const identity_key_public, size_t len);
+char *omemo_format_fingerprint(const char *const fingerprint);
+char *omemo_own_fingerprint();
 
 void omemo_start_session(const char *const barejid);
 void omemo_start_device_session(const char *const jid, uint32_t device_id, GList *prekeys, uint32_t signed_prekey_id, const unsigned char *const signed_prekey, size_t signed_prekey_len, const unsigned char *const signature, size_t signature_len, const unsigned char *const identity_key, size_t identity_key_len);