fix: Message index replay attack check
This commit is contained in:
parent
0ff971faa9
commit
70939a7c9c
|
@ -160,24 +160,18 @@ class Encryption {
|
||||||
final decryptResult = inboundGroupSession.inboundGroupSession
|
final decryptResult = inboundGroupSession.inboundGroupSession
|
||||||
.decrypt(event.content['ciphertext']);
|
.decrypt(event.content['ciphertext']);
|
||||||
canRequestSession = false;
|
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();
|
event.originServerTs.millisecondsSinceEpoch.toString();
|
||||||
var haveIndex = inboundGroupSession.indexes.containsKey(messageIndexKey);
|
var haveIndex = inboundGroupSession.indexes.containsKey(messageIndexKey);
|
||||||
if (haveIndex &&
|
if (haveIndex &&
|
||||||
inboundGroupSession.indexes[messageIndexKey] !=
|
inboundGroupSession.indexes[messageIndexKey] != messageIndexValue) {
|
||||||
decryptResult.message_index) {
|
|
||||||
// TODO: maybe clear outbound session, if it is ours
|
// TODO: maybe clear outbound session, if it is ours
|
||||||
throw (DecryptError.CHANNEL_CORRUPTED);
|
throw (DecryptError.CHANNEL_CORRUPTED);
|
||||||
}
|
}
|
||||||
final existingIndex = inboundGroupSession.indexes.entries.firstWhere(
|
inboundGroupSession.indexes[messageIndexKey] = messageIndexValue;
|
||||||
(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;
|
|
||||||
if (!haveIndex) {
|
if (!haveIndex) {
|
||||||
// now we persist the udpated indexes into the database.
|
// now we persist the udpated indexes into the database.
|
||||||
// the entry should always exist. In the case it doesn't, the following
|
// the entry should always exist. In the case it doesn't, the following
|
||||||
|
|
|
@ -26,7 +26,7 @@ import '../../src/utils/logs.dart';
|
||||||
|
|
||||||
class SessionKey {
|
class SessionKey {
|
||||||
Map<String, dynamic> content;
|
Map<String, dynamic> content;
|
||||||
Map<String, int> indexes;
|
Map<String, String> indexes;
|
||||||
olm.InboundGroupSession inboundGroupSession;
|
olm.InboundGroupSession inboundGroupSession;
|
||||||
final String key;
|
final String key;
|
||||||
List<String> get forwardingCurve25519KeyChain =>
|
List<String> get forwardingCurve25519KeyChain =>
|
||||||
|
@ -60,9 +60,14 @@ class SessionKey {
|
||||||
Event.getMapFromPayload(dbEntry.senderClaimedKeys);
|
Event.getMapFromPayload(dbEntry.senderClaimedKeys);
|
||||||
content =
|
content =
|
||||||
parsedContent != null ? Map<String, dynamic>.from(parsedContent) : null;
|
parsedContent != null ? Map<String, dynamic>.from(parsedContent) : null;
|
||||||
indexes = parsedIndexes != null
|
// we need to try...catch as the map used to be <String, int> and that will throw an error.
|
||||||
? Map<String, int>.from(parsedIndexes)
|
try {
|
||||||
: <String, int>{};
|
indexes = parsedIndexes != null
|
||||||
|
? Map<String, String>.from(parsedIndexes)
|
||||||
|
: <String, String>{};
|
||||||
|
} catch (e) {
|
||||||
|
indexes = <String, String>{};
|
||||||
|
}
|
||||||
roomId = dbEntry.roomId;
|
roomId = dbEntry.roomId;
|
||||||
sessionId = dbEntry.sessionId;
|
sessionId = dbEntry.sessionId;
|
||||||
_setSenderKey(dbEntry.senderKey);
|
_setSenderKey(dbEntry.senderKey);
|
||||||
|
|
Loading…
Reference in a new issue