diff --git a/src/omemo/omemo.c b/src/omemo/omemo.c index 728fe5c1..e3a652b1 100644 --- a/src/omemo/omemo.c +++ b/src/omemo/omemo.c @@ -1145,6 +1145,12 @@ omemo_on_message_recv(const char* const from_jid, uint32_t sid, return NULL; } + if (payload == NULL) { + signal_buffer_free(plaintext_key); + *error = OMEMO_ERR_KEY_TRANSPORT; + return NULL; + } + size_t plaintext_len = payload_len; plaintext = malloc(plaintext_len + 1); res = aes128gcm_decrypt(plaintext, &plaintext_len, payload, payload_len, iv, diff --git a/src/xmpp/message.c b/src/xmpp/message.c index a154f7d3..76179efc 100644 --- a/src/xmpp/message.c +++ b/src/xmpp/message.c @@ -1089,23 +1089,7 @@ _handle_groupchat(xmpp_stanza_t* const stanza) if (message->omemo_err != OMEMO_ERR_NONE) { message->enc = PROF_MSG_ENC_OMEMO; if (message->plain == NULL) { - switch (message->omemo_err) { - case OMEMO_ERR_NO_KEY: - message->plain = g_strdup("OMEMO message received but no key for this device found."); - break; - case OMEMO_ERR_NOT_TRUSTED: - message->plain = g_strdup("OMEMO message received but sender identity is untrusted."); - break; - case OMEMO_ERR_NO_SESSION: - message->plain = g_strdup("OMEMO message received but no session found. Try '/omemo start'."); - break; - case OMEMO_ERR_DECRYPT_FAILED: - message->plain = g_strdup("OMEMO message received but decryption failed."); - break; - default: - message->plain = g_strdup("OMEMO message received but could not be decrypted."); - break; - } + message->plain = omemo_error_to_string(message->omemo_err); } } else if (message->plain != NULL) { message->enc = PROF_MSG_ENC_OMEMO; @@ -1270,23 +1254,7 @@ _handle_muc_private_message(xmpp_stanza_t* const stanza) if (message->omemo_err != OMEMO_ERR_NONE) { message->enc = PROF_MSG_ENC_OMEMO; if (message->plain == NULL) { - switch (message->omemo_err) { - case OMEMO_ERR_NO_KEY: - message->plain = g_strdup("OMEMO message received but no key for this device found."); - break; - case OMEMO_ERR_NOT_TRUSTED: - message->plain = g_strdup("OMEMO message received but sender identity is untrusted."); - break; - case OMEMO_ERR_NO_SESSION: - message->plain = g_strdup("OMEMO message received but no session found. Try '/omemo start'."); - break; - case OMEMO_ERR_DECRYPT_FAILED: - message->plain = g_strdup("OMEMO message received but decryption failed."); - break; - default: - message->plain = g_strdup("OMEMO message received but could not be decrypted."); - break; - } + message->plain = omemo_error_to_string(message->omemo_err); } } else if (message->plain != NULL) { message->enc = PROF_MSG_ENC_OMEMO; @@ -1458,23 +1426,7 @@ _handle_chat(xmpp_stanza_t* const stanza, gboolean is_mam, gboolean is_carbon, c if (message->omemo_err != OMEMO_ERR_NONE) { message->enc = PROF_MSG_ENC_OMEMO; if (message->plain == NULL) { - switch (message->omemo_err) { - case OMEMO_ERR_NO_KEY: - message->plain = g_strdup("OMEMO message received but no key for this device found."); - break; - case OMEMO_ERR_NOT_TRUSTED: - message->plain = g_strdup("OMEMO message received but sender identity is untrusted."); - break; - case OMEMO_ERR_NO_SESSION: - message->plain = g_strdup("OMEMO message received but no session found. Try '/omemo start'."); - break; - case OMEMO_ERR_DECRYPT_FAILED: - message->plain = g_strdup("OMEMO message received but decryption failed."); - break; - default: - message->plain = g_strdup("OMEMO message received but could not be decrypted."); - break; - } + message->plain = omemo_error_to_string(message->omemo_err); } } else if (message->plain != NULL) { message->enc = PROF_MSG_ENC_OMEMO; diff --git a/src/xmpp/omemo.c b/src/xmpp/omemo.c index ca55d5f4..cef09dde 100644 --- a/src/xmpp/omemo.c +++ b/src/xmpp/omemo.c @@ -333,6 +333,7 @@ omemo_receive_message(xmpp_stanza_t* const stanza, gboolean* trusted, omemo_erro unsigned char* payload_raw = NULL; char* iv_text = NULL; char* payload_text = NULL; + size_t payload_len = 0; *error = OMEMO_ERR_NONE; @@ -372,20 +373,15 @@ omemo_receive_message(xmpp_stanza_t* const stanza, gboolean* trusted, omemo_erro } xmpp_stanza_t* payload = xmpp_stanza_get_child_by_name(encrypted, "payload"); - if (!payload) { - *error = OMEMO_ERR_OTHER; - goto quit; - } - payload_text = xmpp_stanza_get_text(payload); - if (!payload_text) { - *error = OMEMO_ERR_OTHER; - goto quit; - } - size_t payload_len; - payload_raw = g_base64_decode(payload_text, &payload_len); - if (!payload_raw) { - *error = OMEMO_ERR_OTHER; - goto quit; + if (payload) { + payload_text = xmpp_stanza_get_text(payload); + if (payload_text) { + payload_raw = g_base64_decode(payload_text, &payload_len); + if (!payload_raw) { + *error = OMEMO_ERR_OTHER; + goto quit; + } + } } xmpp_stanza_t* key_stanza; @@ -707,3 +703,24 @@ _omemo_bundle_publish_configure_result(xmpp_stanza_t* const stanza, void* const return 0; } + +char* +omemo_error_to_string(omemo_error_t error) +{ + switch (error) { + case OMEMO_ERR_NO_KEY: + return g_strdup("OMEMO message received but no key for this device found."); + case OMEMO_ERR_NOT_TRUSTED: + return g_strdup("OMEMO message received but sender identity is untrusted."); + case OMEMO_ERR_NO_SESSION: + return g_strdup("OMEMO message received but no session found. Try '/omemo start'."); + case OMEMO_ERR_DECRYPT_FAILED: + return g_strdup("OMEMO message received but decryption failed."); + case OMEMO_ERR_KEY_TRANSPORT: + return NULL; + case OMEMO_ERR_NONE: + return NULL; + default: + return g_strdup("OMEMO message received but could not be decrypted."); + } +} diff --git a/src/xmpp/omemo.h b/src/xmpp/omemo.h index ff6d648b..772bd186 100644 --- a/src/xmpp/omemo.h +++ b/src/xmpp/omemo.h @@ -20,3 +20,4 @@ void omemo_bundle_request(const char* const jid, uint32_t device_id, ProfIqCallb int omemo_start_device_session_handle_bundle(xmpp_stanza_t* const stanza, void* const userdata); char* omemo_receive_message(xmpp_stanza_t* const stanza, gboolean* trusted, omemo_error_t* error) __attribute__((nonnull(2, 3))); +char* omemo_error_to_string(omemo_error_t error); diff --git a/src/xmpp/xmpp.h b/src/xmpp/xmpp.h index c329d221..83d87fb6 100644 --- a/src/xmpp/xmpp.h +++ b/src/xmpp/xmpp.h @@ -132,6 +132,7 @@ typedef enum { OMEMO_ERR_DECRYPT_FAILED, OMEMO_ERR_INVALID_JID, OMEMO_ERR_MUC_SENDER_NOT_FOUND, + OMEMO_ERR_KEY_TRANSPORT, OMEMO_ERR_OTHER } omemo_error_t;