From 5a3083f273954ec395224d6670d87a865b1c7438 Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Fri, 6 Mar 2026 23:57:44 +0100 Subject: [PATCH] feat: Show active and trust status in /omemo fingerprint The /omemo fingerprint command provided a list of all keys ever seen for a contact but did not indicate which keys were currently "active" (present in the latest server device list). This made it difficult for users to identify which fingerprints actually required verification to fix encryption issues. Users can now easily distinguish between devices currently in use and historical keys that no longer matter. When encryption fails users can immediately see which "active" key is "untrusted," allowing them to verify the correct fingerprint fast. Function `omemo_is_device_active` will check if a fingerprint belongs to a device currently announced by the contacts server. --- src/command/cmd_funcs.c | 3 ++- src/omemo/omemo.c | 33 ++++++++++++++++++++++++++++++ src/omemo/omemo.h | 1 + tests/unittests/omemo/stub_omemo.c | 18 ++++++++++++++++ 4 files changed, 54 insertions(+), 1 deletion(-) diff --git a/src/command/cmd_funcs.c b/src/command/cmd_funcs.c index 7f574aff..4d847778 100644 --- a/src/command/cmd_funcs.c +++ b/src/command/cmd_funcs.c @@ -8686,8 +8686,9 @@ cmd_omemo_fingerprint(ProfWin* window, const char* const command, gchar** args) for (GList* fingerprint = fingerprints; fingerprint != NULL; fingerprint = fingerprint->next) { auto_char char* formatted_fingerprint = omemo_format_fingerprint(fingerprint->data); gboolean trusted = omemo_is_trusted_identity(jid->barejid, fingerprint->data); + gboolean active = omemo_is_device_active(jid->barejid, fingerprint->data); - win_println(window, THEME_DEFAULT, "-", "%s's OMEMO fingerprint: %s%s", jid->barejid, formatted_fingerprint, trusted ? " (trusted)" : ""); + win_println(window, THEME_DEFAULT, "-", "%s's OMEMO fingerprint: %s%s%s", jid->barejid, formatted_fingerprint, trusted ? " (trusted)" : " (untrusted)", active ? " (active)" : " (inactive)"); } g_list_free(fingerprints); diff --git a/src/omemo/omemo.c b/src/omemo/omemo.c index 568932c1..e6d3a6ce 100644 --- a/src/omemo/omemo.c +++ b/src/omemo/omemo.c @@ -1313,6 +1313,39 @@ omemo_get_jid_untrusted_fingerprints(const char* const jid) return untrusted_fps; } +gboolean +omemo_is_device_active(const char* const jid, const char* const fingerprint) +{ + if (!omemo_loaded()) { + return FALSE; + } + + GList* device_list = g_hash_table_lookup(omemo_ctx.device_list, jid); + if (!device_list) { + return FALSE; + } + + GHashTable* known_identities = g_hash_table_lookup(omemo_ctx.known_devices, jid); + if (!known_identities) { + return FALSE; + } + + void* device_id = g_hash_table_lookup(known_identities, fingerprint); + if (!device_id) { + return FALSE; + } + + uint32_t dev_id = GPOINTER_TO_INT(device_id); + GList* iter; + for (iter = device_list; iter != NULL; iter = iter->next) { + if (GPOINTER_TO_INT(iter->data) == dev_id) { + return TRUE; + } + } + + return FALSE; +} + static char* _omemo_fingerprint(ec_public_key* identity, gboolean formatted) { diff --git a/src/omemo/omemo.h b/src/omemo/omemo.h index 8618b6e7..47ebaaf7 100644 --- a/src/omemo/omemo.h +++ b/src/omemo/omemo.h @@ -87,6 +87,7 @@ GList* omemo_known_device_identities(const char* const jid); gboolean omemo_is_trusted_identity(const char* const jid, const char* const fingerprint); gboolean omemo_is_jid_trusted(const char* const jid); GList* omemo_get_jid_untrusted_fingerprints(const char* const jid); +gboolean omemo_is_device_active(const char* const jid, const char* const fingerprint); char* omemo_fingerprint_autocomplete(const char* const search_str, gboolean previous, void* context); void omemo_fingerprint_autocomplete_reset(void); gboolean omemo_automatic_start(const char* const recipient); diff --git a/tests/unittests/omemo/stub_omemo.c b/tests/unittests/omemo/stub_omemo.c index a19c6b71..c445eb23 100644 --- a/tests/unittests/omemo/stub_omemo.c +++ b/tests/unittests/omemo/stub_omemo.c @@ -42,12 +42,30 @@ omemo_is_trusted_identity(const char* const jid, const char* const fingerprint) return TRUE; } +gboolean +omemo_is_jid_trusted(const char* const jid) +{ + return TRUE; +} + +GList* +omemo_get_jid_untrusted_fingerprints(const char* const jid) +{ + return NULL; +} + GList* omemo_known_device_identities(const char* const jid) { return NULL; } +gboolean +omemo_is_device_active(const char* const jid, const char* const fingerprint) +{ + return TRUE; +} + gboolean omemo_loaded(void) {