diff options
author | Dr. David Alan Gilbert <dave@treblig.org> | 2017-04-11 00:58:01 +0100 |
---|---|---|
committer | Dr. David Alan Gilbert <dave@treblig.org> | 2018-02-25 02:08:49 +0000 |
commit | 754d187786fb41ddcf1f4626a4426d57597447b3 (patch) | |
tree | e09744df2c23506cf34b7a4d00e0ebdd1cc6c77e /matrix-e2e.c | |
parent | 4cdeaabd4863d388e7bc595fff8b680ee9625367 (diff) | |
download | purple-matrix-754d187786fb41ddcf1f4626a4426d57597447b3.tar.gz |
e2e: handle m.room_key
Decrypted olm messages of type m.room_key create inbound megolm
sessions.
Signed-off-by: Dr. David Alan Gilbert <dave@treblig.org>
Diffstat (limited to 'matrix-e2e.c')
-rw-r--r-- | matrix-e2e.c | 79 |
1 files changed, 77 insertions, 2 deletions
diff --git a/matrix-e2e.c b/matrix-e2e.c index af82964..f35af1a 100644 --- a/matrix-e2e.c +++ b/matrix-e2e.c @@ -810,6 +810,81 @@ void matrix_e2e_cleanup_connection(MatrixConnectionData *conn) } } +/* See: https://matrix.org/docs/guides/e2e_implementation.html#handling-an-m-room-key-event + */ +static int handle_m_room_key(PurpleConnection *pc, MatrixConnectionData *conn, + const gchar *sender, const gchar *sender_key, const gchar *sender_device, + JsonObject *mrk) +{ + int ret = 0; + purple_debug_info("matrixprpl", "%s\n", __func__); + JsonObject *mrk_content; + const gchar *mrk_algo; + PurpleConversation *conv; + mrk_content = matrix_json_object_get_object_member(mrk, "content"); + mrk_algo = matrix_json_object_get_string_member(mrk_content, "algorithm"); + OlmInboundGroupSession *in_mo_session = NULL; + + if (!mrk_algo || strcmp(mrk_algo, "m.megolm.v1.aes-sha2")) { + purple_debug_info("matrixprpl", "%s: Not megolm (%s)\n", + __func__, mrk_algo); + ret = -1; + goto out; + } + + const gchar *mrk_room_id, *mrk_session_id, *mrk_session_key; + mrk_room_id = matrix_json_object_get_string_member(mrk_content, "room_id"); + mrk_session_id = matrix_json_object_get_string_member(mrk_content, + "session_id"); + mrk_session_key = matrix_json_object_get_string_member(mrk_content, + "session_key"); + + conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, + mrk_room_id, pc->account); + if (!conv) { + purple_debug_info("matrixprpl", "%s: Unknown room %s\n", + __func__, mrk_room_id); + ret = -1; + goto out; + } + + /* Search for an existing session with the matching room_id, + * sender_key, session_id */ + in_mo_session = get_inbound_megolm_session(conv, sender_key, + sender, mrk_session_id, + sender_device); + + if (!in_mo_session) { + /* Bah, no match, lets make one */ + in_mo_session = olm_inbound_group_session(g_malloc( + olm_inbound_group_session_size())); + if (olm_init_inbound_group_session(in_mo_session, + (const uint8_t *)mrk_session_key, + strlen(mrk_session_key)) == + olm_error()) { + purple_debug_info("matrixprpl", + "%s: megolm inbound session creation failed: %s\n", + __func__, + olm_inbound_group_session_last_error(in_mo_session)); + ret = -1; + goto out; + } + + store_inbound_megolm_session(conv, sender_key, sender, + mrk_session_id, sender_device, + in_mo_session); + } + +out: + if (ret) { + if (in_mo_session) { + olm_clear_inbound_group_session(in_mo_session); + } + g_free(in_mo_session); + } + return ret; +} + /* Called from decypt_olm after we've decrypted an olm message. */ static int handle_decrypted_olm(PurpleConnection *pc, @@ -883,8 +958,8 @@ static int handle_decrypted_olm(PurpleConnection *pc, /* TODO: check the device against the keys in use, stash somewhere? */ if (!strcmp(pt_type, "m.room_key")) { - //ret = handle_m_room_key(pc, conn, pt_sender, sender_key, - // pt_sender_device, pt_body); + ret = handle_m_room_key(pc, conn, pt_sender, sender_key, + pt_sender_device, pt_body); } else { purple_debug_info("matrixprpl", "%s: Got '%s' from '%s'/'%s'\n", |