From 9b67992a3ace4e6182a2f57abfdb71effd4d9871 Mon Sep 17 00:00:00 2001 From: Sorunome Date: Tue, 19 May 2020 09:34:11 +0000 Subject: [PATCH] Automatically request for keys from other devices, if not found --- lib/src/client.dart | 2 +- lib/src/event.dart | 28 +-------------------------- lib/src/room.dart | 46 ++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 45 insertions(+), 31 deletions(-) diff --git a/lib/src/client.dart b/lib/src/client.dart index 708c4f9..4cadf28 100644 --- a/lib/src/client.dart +++ b/lib/src/client.dart @@ -1360,7 +1360,7 @@ class Client { } if (update.eventType == 'm.room.encrypted' && database != null) { // the event is still encrytped....let's try fetching the keys from the database! - await room.loadInboundGroupSessionKey(event['content']['session_id']); + await room.loadInboundGroupSessionKey(event['content']['session_id'], event['content']['sender_key']); update = update.decrypt(room); } if (type != 'ephemeral' && database != null) { diff --git a/lib/src/event.dart b/lib/src/event.dart index 0449c44..6021fd1 100644 --- a/lib/src/event.dart +++ b/lib/src/event.dart @@ -435,33 +435,7 @@ class Event { content['body'] != DecryptError.UNKNOWN_SESSION) { throw ('Session key not unknown'); } - final users = await room.requestParticipants(); - await room.client.sendToDevice( - [], - 'm.room_key_request', - { - 'action': 'request_cancellation', - 'request_id': base64.encode(utf8.encode(content['session_id'])), - 'requesting_device_id': room.client.deviceID, - }, - encrypted: false, - toUsers: users); - await room.client.sendToDevice( - [], - 'm.room_key_request', - { - 'action': 'request', - 'body': { - 'algorithm': 'm.megolm.v1.aes-sha2', - 'room_id': roomId, - 'sender_key': content['sender_key'], - 'session_id': content['session_id'], - }, - 'request_id': base64.encode(utf8.encode(content['session_id'])), - 'requesting_device_id': room.client.deviceID, - }, - encrypted: false, - toUsers: users); + await room.requestSessionKey(content['session_id'], content['sender_key']); return; } diff --git a/lib/src/room.dart b/lib/src/room.dart index d1b8154..18a9b7d 100644 --- a/lib/src/room.dart +++ b/lib/src/room.dart @@ -24,6 +24,7 @@ import 'dart:async'; import 'dart:convert'; +import 'package:pedantic/pedantic.dart'; import 'package:famedlysdk/famedlysdk.dart'; import 'package:famedlysdk/src/client.dart'; import 'package:famedlysdk/src/event.dart'; @@ -1776,10 +1777,49 @@ class Room { return encryptedPayload; } - Future loadInboundGroupSessionKey(String sessionId) async { + final Set _requestedSessionIds = {}; + + Future requestSessionKey(String sessionId, String senderKey) async { + final users = await requestParticipants(); + await client.sendToDevice( + [], + 'm.room_key_request', + { + 'action': 'request_cancellation', + 'request_id': base64.encode(utf8.encode(sessionId)), + 'requesting_device_id': client.deviceID, + }, + encrypted: false, + toUsers: users); + await client.sendToDevice( + [], + 'm.room_key_request', + { + 'action': 'request', + 'body': { + 'algorithm': 'm.megolm.v1.aes-sha2', + 'room_id': id, + 'sender_key': senderKey, + 'session_id': sessionId, + }, + 'request_id': base64.encode(utf8.encode(sessionId)), + 'requesting_device_id': client.deviceID, + }, + encrypted: false, + toUsers: users); + } + + Future loadInboundGroupSessionKey(String sessionId, [String senderKey]) async { if (sessionId == null || inboundGroupSessions.containsKey(sessionId)) return; // nothing to do final session = await client.database.getDbInboundGroupSession(client.id, id, sessionId); - if (session == null) return; // no session found + if (session == null) { + // no session found, let's request it! + if (!_requestedSessionIds.contains(sessionId) && senderKey != null) { + unawaited(requestSessionKey(sessionId, senderKey)); + _requestedSessionIds.add(sessionId); + } + return; + } try { _inboundGroupSessions[sessionId] = SessionKey.fromDb(session, client.userID); } catch (e) { @@ -1797,7 +1837,7 @@ class Room { throw (DecryptError.UNKNOWN_ALGORITHM); } final String sessionId = event.content['session_id']; - return loadInboundGroupSessionKey(sessionId); + return loadInboundGroupSessionKey(sessionId, event.content['sender_key']); } /// Decrypts the given [event] with one of the available ingoingGroupSessions.