fix: Message index replay attack check

This commit is contained in:
Sorunome 2020-09-21 10:24:15 +02:00
parent 0ff971faa9
commit 70939a7c9c
No known key found for this signature in database
GPG key ID: B19471D07FC9BE9C
2 changed files with 15 additions and 16 deletions

View file

@ -160,24 +160,18 @@ class Encryption {
final decryptResult = inboundGroupSession.inboundGroupSession
.decrypt(event.content['ciphertext']);
canRequestSession = false;
final messageIndexKey = event.eventId +
// we can't have the key be an int, else json-serializing will fail, thus we need it to be a string
final messageIndexKey = 'key-' + decryptResult.message_index.toString();
final messageIndexValue = event.eventId +
'|' +
event.originServerTs.millisecondsSinceEpoch.toString();
var haveIndex = inboundGroupSession.indexes.containsKey(messageIndexKey);
if (haveIndex &&
inboundGroupSession.indexes[messageIndexKey] !=
decryptResult.message_index) {
inboundGroupSession.indexes[messageIndexKey] != messageIndexValue) {
// TODO: maybe clear outbound session, if it is ours
throw (DecryptError.CHANNEL_CORRUPTED);
}
final existingIndex = inboundGroupSession.indexes.entries.firstWhere(
(e) => e.value == decryptResult.message_index,
orElse: () => null);
if (existingIndex != null && existingIndex.key != messageIndexKey) {
// TODO: maybe clear outbound session, if it is ours
throw (DecryptError.CHANNEL_CORRUPTED);
}
inboundGroupSession.indexes[messageIndexKey] =
decryptResult.message_index;
inboundGroupSession.indexes[messageIndexKey] = messageIndexValue;
if (!haveIndex) {
// now we persist the udpated indexes into the database.
// the entry should always exist. In the case it doesn't, the following

View file

@ -26,7 +26,7 @@ import '../../src/utils/logs.dart';
class SessionKey {
Map<String, dynamic> content;
Map<String, int> indexes;
Map<String, String> indexes;
olm.InboundGroupSession inboundGroupSession;
final String key;
List<String> get forwardingCurve25519KeyChain =>
@ -60,9 +60,14 @@ class SessionKey {
Event.getMapFromPayload(dbEntry.senderClaimedKeys);
content =
parsedContent != null ? Map<String, dynamic>.from(parsedContent) : null;
// we need to try...catch as the map used to be <String, int> and that will throw an error.
try {
indexes = parsedIndexes != null
? Map<String, int>.from(parsedIndexes)
: <String, int>{};
? Map<String, String>.from(parsedIndexes)
: <String, String>{};
} catch (e) {
indexes = <String, String>{};
}
roomId = dbEntry.roomId;
sessionId = dbEntry.sessionId;
_setSenderKey(dbEntry.senderKey);