feat: Add a untest decrypt function

This commit is contained in:
2022-08-04 14:01:50 +02:00
parent e34e0cc7fb
commit 4d6dbef549
4 changed files with 89 additions and 1 deletions

View File

@@ -1,6 +1,9 @@
import 'dart:convert';
import 'package:collection/collection.dart';
import 'package:omemo_dart/protobuf/schema.pb.dart';
import 'package:omemo_dart/src/crypto.dart';
import 'package:omemo_dart/src/double_ratchet/double_ratchet.dart';
import 'package:omemo_dart/src/errors.dart';
import 'package:omemo_dart/src/helpers.dart';
import 'package:omemo_dart/src/omemo/device.dart';
import 'package:synchronized/synchronized.dart';
@@ -20,6 +23,13 @@ class EncryptionResult {
final Map<String, List<int>> encryptedKeys;
}
class EncryptedKey {
const EncryptedKey(this.rid, this.value);
final String rid;
final String value;
}
class OmemoSessionManager {
OmemoSessionManager(this.device) : _ratchetMap = {}, _deviceMap = {}, _lock = Lock();
@@ -92,4 +102,42 @@ class OmemoSessionManager {
encryptedKeys,
);
}
/// Attempt to decrypt [ciphertext]. [keys] refers to the <key /> elements inside the
/// <keys /> element with a "jid" attribute matching our own. [senderJid] refers to the
/// bare Jid of the sender. [senderDeviceId] refers to the "sid" attribute of the
/// <encrypted /> element.
Future<String> decryptMessage(List<int> ciphertext, String senderJid, String senderDeviceId, List<EncryptedKey> keys) async {
// Try to find a session we can decrypt with.
final rawKey = keys.firstWhereOrNull((key) => key.rid == device.id);
if (rawKey == null) {
throw NotEncryptedForDeviceException();
}
final devices = _deviceMap[senderJid];
if (devices == null) {
throw NoDecryptionKeyException();
}
if (!devices.contains(senderDeviceId)) {
throw NoDecryptionKeyException();
}
final decodedRawKey = base64.decode(rawKey.value);
final authMessage = OMEMOAuthenticatedMessage.fromBuffer(decodedRawKey);
final message = OMEMOMessage.fromBuffer(authMessage.message);
final ratchet = _ratchetMap[senderDeviceId]!;
final keyAndHmac = await ratchet.ratchetDecrypt(message, message.ciphertext);
final key = keyAndHmac.sublist(0, 32);
final hmac = keyAndHmac.sublist(32, 48);
final derivedKeys = await deriveEncryptionKeys(key, omemoPayloadInfoString);
final computedHmac = await truncatedHmac(ciphertext, derivedKeys.authenticationKey);
if (!listsEqual(hmac, computedHmac)) {
throw InvalidMessageHMACException();
}
final plaintext = await aes256CbcDecrypt(ciphertext, derivedKeys.encryptionKey, derivedKeys.iv);
return utf8.decode(plaintext);
}
}