From ff65db0b10015e8c25e18af13bcfe9575a3a8b08 Mon Sep 17 00:00:00 2001 From: Steffen Jaeckel Date: Thu, 12 Mar 2026 10:38:15 +0100 Subject: [PATCH 1/3] Fix potential segfault. It's not guaranteed that `log_database_get_limits_info()` returns a non-NULL value or that `timestamp` is non-NULL. Signed-off-by: Steffen Jaeckel --- src/xmpp/iq.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/xmpp/iq.c b/src/xmpp/iq.c index 42505b37..1bb2bb64 100644 --- a/src/xmpp/iq.c +++ b/src/xmpp/iq.c @@ -2668,8 +2668,10 @@ _iq_mam_request(ProfChatWin* win, GDateTime* startdate, GDateTime* enddate) if (connection_supports(XMPP_FEATURE_MAM2) == FALSE) { log_warning("Server doesn't advertise %s feature.", XMPP_FEATURE_MAM2); cons_show_error("Server doesn't support MAM (%s).", XMPP_FEATURE_MAM2); - g_date_time_unref(startdate); - g_date_time_unref(enddate); + if (startdate) + g_date_time_unref(startdate); + if (enddate) + g_date_time_unref(enddate); return; } @@ -2718,8 +2720,12 @@ void iq_mam_request(ProfChatWin* win, GDateTime* enddate) { ProfMessage* last_msg = log_database_get_limits_info(win->barejid, TRUE); - GDateTime* startdate = g_date_time_ref(last_msg->timestamp); - message_free(last_msg); + GDateTime* startdate = NULL; + if (last_msg) { + if (last_msg->timestamp) + startdate = g_date_time_ref(last_msg->timestamp); + message_free(last_msg); + } // Save request for later if disco items haven't been received yet if (!received_disco_items) { From cbe6dac44812e86b59a0f51d3b62ecabff4d4e13 Mon Sep 17 00:00:00 2001 From: Steffen Jaeckel Date: Thu, 12 Mar 2026 12:00:22 +0100 Subject: [PATCH 2/3] Flush OMEMO store only after encrypting for all recipients. Instead of flushing the OMEMO store to disk after each operation, do it only once after all recipients are processed. A user reported a long delay between hitting enter on the keyboard and the message being sent on the wire in an OMEMO-enabled group chat. This patch hopefully improves this situation. Signed-off-by: Steffen Jaeckel --- src/omemo/omemo.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/omemo/omemo.c b/src/omemo/omemo.c index b4c89c32..2c678fc1 100644 --- a/src/omemo/omemo.c +++ b/src/omemo/omemo.c @@ -612,9 +612,13 @@ omemo_sessions_keyfile(void) return omemo_ctx.sessions.keyfile; } +static gboolean omemo_sessions_keyfile_save_disable = FALSE; + void omemo_sessions_keyfile_save(void) { + if (omemo_sessions_keyfile_save_disable) + return; save_keyfile(&omemo_ctx.sessions); } @@ -766,6 +770,8 @@ omemo_on_message_send(ProfWin* win, const char* const message, gboolean request_ unsigned char* key_tag = NULL; size_t ciphertext_len, tag_len; + omemo_sessions_keyfile_save_disable = TRUE; + ciphertext_len = strlen(message); ciphertext = malloc(ciphertext_len); if (!ciphertext) { @@ -983,6 +989,8 @@ omemo_on_message_send(ProfWin* win, const char* const message, gboolean request_ } out: + omemo_sessions_keyfile_save_disable = FALSE; + omemo_sessions_keyfile_save(); g_list_free_full(keys, (GDestroyNotify)omemo_key_free); free(ciphertext); gcry_free(key); From d9a8c579b60938372d1b4076ef7d272ecd6ba296 Mon Sep 17 00:00:00 2001 From: Steffen Jaeckel Date: Thu, 12 Mar 2026 12:06:18 +0100 Subject: [PATCH 3/3] Optimize random data generation. In the process of trying to bring down the time of sending an OMEMO encrypted message I noticed that a lot of time was spent in generating the random key and IV (~0.54s on my machine). By changing this to a single call to `gcry_random_bytes_secure()` I have been able to slash the time by 50% to ~0.27s. Signed-off-by: Steffen Jaeckel --- src/omemo/omemo.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/omemo/omemo.c b/src/omemo/omemo.c index 2c678fc1..bfd984a3 100644 --- a/src/omemo/omemo.c +++ b/src/omemo/omemo.c @@ -781,8 +781,8 @@ omemo_on_message_send(ProfWin* win, const char* const message, gboolean request_ tag = gcry_malloc_secure(tag_len); key_tag = gcry_malloc_secure(AES128_GCM_KEY_LENGTH + AES128_GCM_TAG_LENGTH); - key = gcry_random_bytes_secure(AES128_GCM_KEY_LENGTH, GCRY_VERY_STRONG_RANDOM); - iv = gcry_random_bytes_secure(AES128_GCM_IV_LENGTH, GCRY_VERY_STRONG_RANDOM); + key = gcry_random_bytes_secure(AES128_GCM_KEY_LENGTH + AES128_GCM_IV_LENGTH, GCRY_VERY_STRONG_RANDOM); + iv = key + AES128_GCM_KEY_LENGTH; res = aes128gcm_encrypt(ciphertext, &ciphertext_len, tag, &tag_len, (const unsigned char* const)message, strlen(message), iv, key); if (res != 0) { @@ -994,7 +994,6 @@ out: g_list_free_full(keys, (GDestroyNotify)omemo_key_free); free(ciphertext); gcry_free(key); - gcry_free(iv); gcry_free(tag); gcry_free(key_tag);