fix: Track ratchet sessions using the (jid, device) tuple
This commit is contained in:
parent
f8830b974b
commit
189d823c87
@ -20,6 +20,7 @@ import 'package:synchronized/synchronized.dart';
|
|||||||
/// The info used for when encrypting the AES key for the actual payload.
|
/// The info used for when encrypting the AES key for the actual payload.
|
||||||
const omemoPayloadInfoString = 'OMEMO Payload';
|
const omemoPayloadInfoString = 'OMEMO Payload';
|
||||||
|
|
||||||
|
@immutable
|
||||||
class EncryptionResult {
|
class EncryptionResult {
|
||||||
|
|
||||||
const EncryptionResult(this.ciphertext, this.encryptedKeys);
|
const EncryptionResult(this.ciphertext, this.encryptedKeys);
|
||||||
@ -32,6 +33,7 @@ class EncryptionResult {
|
|||||||
final List<EncryptedKey> encryptedKeys;
|
final List<EncryptedKey> encryptedKeys;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@immutable
|
||||||
class EncryptedKey {
|
class EncryptedKey {
|
||||||
|
|
||||||
const EncryptedKey(this.rid, this.value, this.kex);
|
const EncryptedKey(this.rid, this.value, this.kex);
|
||||||
@ -40,6 +42,22 @@ class EncryptedKey {
|
|||||||
final bool kex;
|
final bool kex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@immutable
|
||||||
|
class RatchetMapKey {
|
||||||
|
|
||||||
|
const RatchetMapKey(this.jid, this.deviceId);
|
||||||
|
final String jid;
|
||||||
|
final int deviceId;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return other is RatchetMapKey && jid == other.jid && deviceId == other.deviceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => jid.hashCode ^ deviceId.hashCode;
|
||||||
|
}
|
||||||
|
|
||||||
class OmemoSessionManager {
|
class OmemoSessionManager {
|
||||||
|
|
||||||
OmemoSessionManager(this._device)
|
OmemoSessionManager(this._device)
|
||||||
@ -61,8 +79,7 @@ class OmemoSessionManager {
|
|||||||
final Lock _lock;
|
final Lock _lock;
|
||||||
|
|
||||||
/// Mapping of the Device Id to its OMEMO session
|
/// Mapping of the Device Id to its OMEMO session
|
||||||
// TODO(PapaTutuWawa): Make this map use a tuple (Jid, Id) as a key
|
final Map<RatchetMapKey, OmemoDoubleRatchet> _ratchetMap;
|
||||||
final Map<int, OmemoDoubleRatchet> _ratchetMap;
|
|
||||||
|
|
||||||
/// Mapping of a bare Jid to its Device Ids
|
/// Mapping of a bare Jid to its Device Ids
|
||||||
final Map<String, List<int>> _deviceMap;
|
final Map<String, List<int>> _deviceMap;
|
||||||
@ -99,8 +116,9 @@ class OmemoSessionManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add the ratchet session
|
// Add the ratchet session
|
||||||
if (!_ratchetMap.containsKey(deviceId)) {
|
final key = RatchetMapKey(jid, deviceId);
|
||||||
_ratchetMap[deviceId] = ratchet;
|
if (!_ratchetMap.containsKey(key)) {
|
||||||
|
_ratchetMap[key] = ratchet;
|
||||||
} else {
|
} else {
|
||||||
// TODO(PapaTutuWawa): What do we do now?
|
// TODO(PapaTutuWawa): What do we do now?
|
||||||
throw Exception();
|
throw Exception();
|
||||||
@ -180,7 +198,8 @@ class OmemoSessionManager {
|
|||||||
await _lock.synchronized(() async {
|
await _lock.synchronized(() async {
|
||||||
// We assume that the user already checked if the session exists
|
// We assume that the user already checked if the session exists
|
||||||
for (final deviceId in _deviceMap[jid]!) {
|
for (final deviceId in _deviceMap[jid]!) {
|
||||||
final ratchet = _ratchetMap[deviceId]!;
|
final ratchetKey = RatchetMapKey(jid, deviceId);
|
||||||
|
final ratchet = _ratchetMap[ratchetKey]!;
|
||||||
final ciphertext = (await ratchet.ratchetEncrypt(concatKey)).ciphertext;
|
final ciphertext = (await ratchet.ratchetEncrypt(concatKey)).ciphertext;
|
||||||
|
|
||||||
if (kex.isNotEmpty && kex.containsKey(deviceId)) {
|
if (kex.isNotEmpty && kex.containsKey(deviceId)) {
|
||||||
@ -257,7 +276,8 @@ class OmemoSessionManager {
|
|||||||
|
|
||||||
final message = OmemoMessage.fromBuffer(authMessage.message!);
|
final message = OmemoMessage.fromBuffer(authMessage.message!);
|
||||||
|
|
||||||
final ratchet = _ratchetMap[senderDeviceId]!;
|
final ratchetKey = RatchetMapKey(senderJid, senderDeviceId);
|
||||||
|
final ratchet = _ratchetMap[ratchetKey]!;
|
||||||
List<int> keyAndHmac;
|
List<int> keyAndHmac;
|
||||||
if (rawKey.kex) {
|
if (rawKey.kex) {
|
||||||
keyAndHmac = await ratchet.ratchetDecrypt(message, authMessage.writeToBuffer());
|
keyAndHmac = await ratchet.ratchetDecrypt(message, authMessage.writeToBuffer());
|
||||||
@ -278,5 +298,5 @@ class OmemoSessionManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@visibleForTesting
|
@visibleForTesting
|
||||||
OmemoDoubleRatchet getRatchet(int deviceId) => _ratchetMap[deviceId]!;
|
OmemoDoubleRatchet getRatchet(String jid, int deviceId) => _ratchetMap[RatchetMapKey(jid, deviceId)]!;
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ void main() {
|
|||||||
(await aliceSession.getDevice()).id,
|
(await aliceSession.getDevice()).id,
|
||||||
aliceMessage.encryptedKeys,
|
aliceMessage.encryptedKeys,
|
||||||
);
|
);
|
||||||
final aliceOld = aliceSession.getRatchet((await bobSession.getDevice()).id);
|
final aliceOld = aliceSession.getRatchet(bobJid, (await bobSession.getDevice()).id);
|
||||||
final aliceSerialised = await aliceOld.toJson();
|
final aliceSerialised = await aliceOld.toJson();
|
||||||
final aliceNew = OmemoDoubleRatchet.fromJson(aliceSerialised);
|
final aliceNew = OmemoDoubleRatchet.fromJson(aliceSerialised);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user