From c33d8e5f0bd38dff8b0b034d16699d6c382b207f Mon Sep 17 00:00:00 2001 From: Paul Fariello Date: Fri, 12 Apr 2019 08:24:50 +0320 Subject: [PATCH 1/3] Don't unload OMEMO cryto on disconnect if OMEMO wasn't loaded If OMEMO wasn't loaded, removing key would create empty identity.txt file. Then at load time it would segfault profanity. Another commit should fix load of malformed identity.txt. --- src/omemo/omemo.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/omemo/omemo.c b/src/omemo/omemo.c index 7b3855dd..6545c279 100644 --- a/src/omemo/omemo.c +++ b/src/omemo/omemo.c @@ -241,6 +241,10 @@ omemo_on_connect(ProfAccount *account) void omemo_on_disconnect(void) { + if (!loaded) { + return; + } + signal_protocol_signed_pre_key_remove_key(omemo_ctx.store, omemo_ctx.signed_pre_key_id); _g_hash_table_free(omemo_ctx.signed_pre_key_store); From 94a39b2e9b3fc445604ba3d15db340131316eab1 Mon Sep 17 00:00:00 2001 From: Paul Fariello Date: Fri, 12 Apr 2019 18:57:28 +0320 Subject: [PATCH 2/3] Handle malformed OMEMO identity.txt If OMEMO identity.txt is malformed just abort loading. User should be able to call `/omemo gen` again. --- src/omemo/omemo.c | 41 ++++++++++++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/src/omemo/omemo.c b/src/omemo/omemo.c index 6545c279..c15517a2 100644 --- a/src/omemo/omemo.c +++ b/src/omemo/omemo.c @@ -30,7 +30,7 @@ static gboolean loaded; static void _generate_pre_keys(int count); static void _generate_signed_pre_key(void); -static void _load_identity(void); +static gboolean _load_identity(void); static void _load_trust(void); static void _load_sessions(void); static void _lock(void *user_data); @@ -217,7 +217,9 @@ omemo_on_connect(ProfAccount *account) omemo_ctx.sessions_keyfile = g_key_file_new(); if (g_key_file_load_from_file(omemo_ctx.identity_keyfile, omemo_ctx.identity_filename->str, G_KEY_FILE_KEEP_COMMENTS, &error)) { - _load_identity(); + if (!_load_identity()) { + return; + } } else if (error->code != G_FILE_ERROR_NOENT) { log_warning("OMEMO: error loading identity from: %s, %s", omemo_ctx.identity_filename->str, error->message); return; @@ -1205,26 +1207,49 @@ omemo_fingerprint_autocomplete_reset(void) autocomplete_reset(omemo_ctx.fingerprint_ac); } -static void +static gboolean _load_identity(void) { + GError *error = NULL; log_info("Loading OMEMO identity"); /* Device ID */ - omemo_ctx.device_id = g_key_file_get_uint64(omemo_ctx.identity_keyfile, OMEMO_STORE_GROUP_IDENTITY, OMEMO_STORE_KEY_DEVICE_ID, NULL); + error = NULL; + omemo_ctx.device_id = g_key_file_get_uint64(omemo_ctx.identity_keyfile, OMEMO_STORE_GROUP_IDENTITY, OMEMO_STORE_KEY_DEVICE_ID, &error); + if (error != NULL) { + log_error("OMEMO: cannot load device id: %s", error->message); + return FALSE; + } log_info("OMEMO: device id: %d", omemo_ctx.device_id); /* Registration ID */ - omemo_ctx.registration_id = g_key_file_get_uint64(omemo_ctx.identity_keyfile, OMEMO_STORE_GROUP_IDENTITY, OMEMO_STORE_KEY_REGISTRATION_ID, NULL); + error = NULL; + omemo_ctx.registration_id = g_key_file_get_uint64(omemo_ctx.identity_keyfile, OMEMO_STORE_GROUP_IDENTITY, OMEMO_STORE_KEY_REGISTRATION_ID, &error); + if (error != NULL) { + log_error("OMEMO: cannot load registration id: %s", error->message); + return FALSE; + } /* Identity key */ - char *identity_key_public_b64 = g_key_file_get_string(omemo_ctx.identity_keyfile, OMEMO_STORE_GROUP_IDENTITY, OMEMO_STORE_KEY_IDENTITY_KEY_PUBLIC, NULL); + error = NULL; + char *identity_key_public_b64 = g_key_file_get_string(omemo_ctx.identity_keyfile, OMEMO_STORE_GROUP_IDENTITY, OMEMO_STORE_KEY_IDENTITY_KEY_PUBLIC, &error); + if (!identity_key_public_b64) { + log_error("OMEMO: cannot load identity public key: %s", error->message); + return FALSE; + } + size_t identity_key_public_len; unsigned char *identity_key_public = g_base64_decode(identity_key_public_b64, &identity_key_public_len); g_free(identity_key_public_b64); omemo_ctx.identity_key_store.public = signal_buffer_create(identity_key_public, identity_key_public_len); - char *identity_key_private_b64 = g_key_file_get_string(omemo_ctx.identity_keyfile, OMEMO_STORE_GROUP_IDENTITY, OMEMO_STORE_KEY_IDENTITY_KEY_PRIVATE, NULL); + error = NULL; + char *identity_key_private_b64 = g_key_file_get_string(omemo_ctx.identity_keyfile, OMEMO_STORE_GROUP_IDENTITY, OMEMO_STORE_KEY_IDENTITY_KEY_PRIVATE, &error); + if (!identity_key_private_b64) { + log_error("OMEMO: cannot load identity private key: %s", error->message); + return FALSE; + } + size_t identity_key_private_len; unsigned char *identity_key_private = g_base64_decode(identity_key_private_b64, &identity_key_private_len); g_free(identity_key_private_b64); @@ -1288,6 +1313,8 @@ _load_identity(void) omemo_identity_keyfile_save(); omemo_start_sessions(); + + return TRUE; } static void From 9c0a3954086491dbc70a0cf54c9ff90f7bc3094f Mon Sep 17 00:00:00 2001 From: Paul Fariello Date: Fri, 12 Apr 2019 19:10:48 +0320 Subject: [PATCH 3/3] Don't persist OMEMO {signed,}prekey cleaning on disconnect We should not remove signed prekey and prekey from persistent storage when cleaning OMEMO store on disconnect. --- src/omemo/omemo.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/omemo/omemo.c b/src/omemo/omemo.c index c15517a2..b85029ee 100644 --- a/src/omemo/omemo.c +++ b/src/omemo/omemo.c @@ -247,17 +247,7 @@ omemo_on_disconnect(void) return; } - signal_protocol_signed_pre_key_remove_key(omemo_ctx.store, omemo_ctx.signed_pre_key_id); _g_hash_table_free(omemo_ctx.signed_pre_key_store); - - GHashTableIter iter; - gpointer id; - - g_hash_table_iter_init(&iter, omemo_ctx.pre_key_store); - while (g_hash_table_iter_next(&iter, &id, NULL)) { - signal_protocol_pre_key_remove_key(omemo_ctx.store, GPOINTER_TO_INT(id)); - } - _g_hash_table_free(omemo_ctx.pre_key_store); g_string_free(omemo_ctx.identity_filename, TRUE);