feat: Remove serialization code
This commit is contained in:
parent
6c301ab88f
commit
6e734ec0c3
@ -56,28 +56,6 @@ OmemoPublicKey? decodeKeyIfNotNull(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<int>? base64DecodeIfNotNull(Map<String, dynamic> map, String key) {
|
|
||||||
if (map[key] == null) return null;
|
|
||||||
|
|
||||||
return base64.decode(map[key]! as String);
|
|
||||||
}
|
|
||||||
|
|
||||||
String? base64EncodeIfNotNull(List<int>? bytes) {
|
|
||||||
if (bytes == null) return null;
|
|
||||||
|
|
||||||
return base64.encode(bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
OmemoKeyPair? decodeKeyPairIfNotNull(String? pk, String? sk, KeyPairType type) {
|
|
||||||
if (pk == null || sk == null) return null;
|
|
||||||
|
|
||||||
return OmemoKeyPair.fromBytes(
|
|
||||||
base64.decode(pk),
|
|
||||||
base64.decode(sk),
|
|
||||||
type,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
int getTimestamp() {
|
int getTimestamp() {
|
||||||
return DateTime.now().millisecondsSinceEpoch;
|
return DateTime.now().millisecondsSinceEpoch;
|
||||||
}
|
}
|
||||||
|
@ -22,76 +22,6 @@ class OmemoDevice {
|
|||||||
this.opks,
|
this.opks,
|
||||||
);
|
);
|
||||||
|
|
||||||
/// Deserialize the Device
|
|
||||||
factory OmemoDevice.fromJson(Map<String, dynamic> data) {
|
|
||||||
// NOTE: We use the way OpenSSH names their keys, meaning that ik is the Identity
|
|
||||||
// Keypair's private key, while ik_pub refers to the Identity Keypair's public
|
|
||||||
// key.
|
|
||||||
/*
|
|
||||||
{
|
|
||||||
'jid': 'alice@...',
|
|
||||||
'id': 123,
|
|
||||||
'ik': 'base/64/encoded',
|
|
||||||
'ik_pub': 'base/64/encoded',
|
|
||||||
'spk': 'base/64/encoded',
|
|
||||||
'spk_pub': 'base/64/encoded',
|
|
||||||
'spk_id': 123,
|
|
||||||
'spk_sig': 'base/64/encoded',
|
|
||||||
'old_spk': 'base/64/encoded',
|
|
||||||
'old_spk_pub': 'base/64/encoded',
|
|
||||||
'old_spk_id': 122,
|
|
||||||
'opks': [
|
|
||||||
{
|
|
||||||
'id': 0,
|
|
||||||
'public': 'base/64/encoded',
|
|
||||||
'private': 'base/64/encoded'
|
|
||||||
}, ...
|
|
||||||
]
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
// NOTE: Dart has some issues with just casting a List<dynamic> to List<Map<...>>, as
|
|
||||||
// such we need to convert the items by hand.
|
|
||||||
final opks = Map<int, OmemoKeyPair>.fromEntries(
|
|
||||||
(data['opks']! as List<dynamic>).map<MapEntry<int, OmemoKeyPair>>(
|
|
||||||
(opk) {
|
|
||||||
final map = opk as Map<String, dynamic>;
|
|
||||||
return MapEntry(
|
|
||||||
map['id']! as int,
|
|
||||||
OmemoKeyPair.fromBytes(
|
|
||||||
base64.decode(map['public']! as String),
|
|
||||||
base64.decode(map['private']! as String),
|
|
||||||
KeyPairType.x25519,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
return OmemoDevice(
|
|
||||||
data['jid']! as String,
|
|
||||||
data['id']! as int,
|
|
||||||
OmemoKeyPair.fromBytes(
|
|
||||||
base64.decode(data['ik_pub']! as String),
|
|
||||||
base64.decode(data['ik']! as String),
|
|
||||||
KeyPairType.ed25519,
|
|
||||||
),
|
|
||||||
OmemoKeyPair.fromBytes(
|
|
||||||
base64.decode(data['spk_pub']! as String),
|
|
||||||
base64.decode(data['spk']! as String),
|
|
||||||
KeyPairType.x25519,
|
|
||||||
),
|
|
||||||
data['spk_id']! as int,
|
|
||||||
base64.decode(data['spk_sig']! as String),
|
|
||||||
decodeKeyPairIfNotNull(
|
|
||||||
data['old_spk_pub'] as String?,
|
|
||||||
data['old_spk'] as String?,
|
|
||||||
KeyPairType.x25519,
|
|
||||||
),
|
|
||||||
data['old_spk_id'] as int?,
|
|
||||||
opks,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Generate a completely new device, i.e. cryptographic identity.
|
/// Generate a completely new device, i.e. cryptographic identity.
|
||||||
static Future<OmemoDevice> generateNewDevice(
|
static Future<OmemoDevice> generateNewDevice(
|
||||||
String jid, {
|
String jid, {
|
||||||
@ -221,34 +151,6 @@ class OmemoDevice {
|
|||||||
return HEX.encode(await curveKey.getBytes());
|
return HEX.encode(await curveKey.getBytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Serialise the device information.
|
|
||||||
Future<Map<String, dynamic>> toJson() async {
|
|
||||||
/// Serialise the OPKs
|
|
||||||
final serialisedOpks = List<Map<String, dynamic>>.empty(growable: true);
|
|
||||||
for (final entry in opks.entries) {
|
|
||||||
serialisedOpks.add({
|
|
||||||
'id': entry.key,
|
|
||||||
'public': base64.encode(await entry.value.pk.getBytes()),
|
|
||||||
'private': base64.encode(await entry.value.sk.getBytes()),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
'jid': jid,
|
|
||||||
'id': id,
|
|
||||||
'ik': base64.encode(await ik.sk.getBytes()),
|
|
||||||
'ik_pub': base64.encode(await ik.pk.getBytes()),
|
|
||||||
'spk': base64.encode(await spk.sk.getBytes()),
|
|
||||||
'spk_pub': base64.encode(await spk.pk.getBytes()),
|
|
||||||
'spk_id': spkId,
|
|
||||||
'spk_sig': base64.encode(spkSignature),
|
|
||||||
'old_spk': base64EncodeIfNotNull(await oldSpk?.sk.getBytes()),
|
|
||||||
'old_spk_pub': base64EncodeIfNotNull(await oldSpk?.pk.getBytes()),
|
|
||||||
'old_spk_id': oldSpkId,
|
|
||||||
'opks': serialisedOpks,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@visibleForTesting
|
@visibleForTesting
|
||||||
Future<bool> equals(OmemoDevice other) async {
|
Future<bool> equals(OmemoDevice other) async {
|
||||||
var opksMatch = true;
|
var opksMatch = true;
|
||||||
|
@ -414,7 +414,12 @@ class OmemoManager {
|
|||||||
} else {
|
} else {
|
||||||
// Check if we even have a ratchet
|
// Check if we even have a ratchet
|
||||||
if (!_ratchetMap.containsKey(ratchetKey)) {
|
if (!_ratchetMap.containsKey(ratchetKey)) {
|
||||||
// TODO: Build a session with the device
|
// TODO: Check if we recently failed to build a session with the device
|
||||||
|
// This causes omemo_dart to build a session with the device.
|
||||||
|
if (!_deviceList[stanza.bareSenderJid]!.contains(stanza.senderDeviceId)) {
|
||||||
|
_deviceList[stanza.bareSenderJid]!.add(stanza.senderDeviceId);
|
||||||
|
}
|
||||||
|
await sendOmemoHeartbeat(stanza.bareSenderJid);
|
||||||
|
|
||||||
return DecryptionResult(
|
return DecryptionResult(
|
||||||
null,
|
null,
|
||||||
|
@ -1,155 +0,0 @@
|
|||||||
import 'dart:convert';
|
|
||||||
import 'package:omemo_dart/omemo_dart.dart';
|
|
||||||
import 'package:omemo_dart/src/protobuf/schema.pb.dart';
|
|
||||||
import 'package:omemo_dart/src/trust/always.dart';
|
|
||||||
import 'package:test/test.dart';
|
|
||||||
|
|
||||||
Map<String, dynamic> jsonify(Map<String, dynamic> map) {
|
|
||||||
return jsonDecode(jsonEncode(map)) as Map<String, dynamic>;
|
|
||||||
}
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
test('Test serialising and deserialising the Device', () async {
|
|
||||||
// Generate a random session
|
|
||||||
final oldDevice =
|
|
||||||
await OmemoDevice.generateNewDevice('user@test.server', opkAmount: 5);
|
|
||||||
final serialised = jsonify(await oldDevice.toJson());
|
|
||||||
|
|
||||||
final newDevice = OmemoDevice.fromJson(serialised);
|
|
||||||
expect(await oldDevice.equals(newDevice), true);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('Test serialising and deserialising the Device after rotating the SPK',
|
|
||||||
() async {
|
|
||||||
// Generate a random session
|
|
||||||
final device =
|
|
||||||
await OmemoDevice.generateNewDevice('user@test.server', opkAmount: 1);
|
|
||||||
final oldDevice = await device.replaceSignedPrekey();
|
|
||||||
final serialised = jsonify(await oldDevice.toJson());
|
|
||||||
|
|
||||||
final newDevice = OmemoDevice.fromJson(serialised);
|
|
||||||
expect(await oldDevice.equals(newDevice), true);
|
|
||||||
});
|
|
||||||
|
|
||||||
/*test('Test serialising and deserialising the OmemoDoubleRatchet', () async {
|
|
||||||
// Generate a random ratchet
|
|
||||||
const aliceJid = 'alice@server.example';
|
|
||||||
const bobJid = 'bob@other.server.example';
|
|
||||||
final aliceManager = OmemoSessionManager.generateNewIdentity(
|
|
||||||
aliceJid,
|
|
||||||
AlwaysTrustingTrustManager(),
|
|
||||||
opkAmount: 1,
|
|
||||||
);
|
|
||||||
final bobSession = await OmemoSessionManager.generateNewIdentity(
|
|
||||||
bobJid,
|
|
||||||
AlwaysTrustingTrustManager(),
|
|
||||||
opkAmount: 1,
|
|
||||||
);
|
|
||||||
final aliceMessage = await aliceSession.encryptToJid(
|
|
||||||
bobJid,
|
|
||||||
'Hello Bob!',
|
|
||||||
newSessions: [
|
|
||||||
await bobSession.getDeviceBundle(),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
await bobSession.decryptMessage(
|
|
||||||
aliceMessage.ciphertext,
|
|
||||||
aliceJid,
|
|
||||||
await aliceSession.getDeviceId(),
|
|
||||||
aliceMessage.encryptedKeys,
|
|
||||||
getTimestamp(),
|
|
||||||
);
|
|
||||||
final aliceOld =
|
|
||||||
aliceSession.getRatchet(bobJid, await bobSession.getDeviceId());
|
|
||||||
final aliceSerialised = jsonify(await aliceOld.toJson());
|
|
||||||
final aliceNew = OmemoDoubleRatchet.fromJson(aliceSerialised);
|
|
||||||
|
|
||||||
expect(await aliceOld.equals(aliceNew), true);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('Test serialising and deserialising the OmemoSessionManager', () async {
|
|
||||||
// Generate a random session
|
|
||||||
final oldSession = await OmemoSessionManager.generateNewIdentity(
|
|
||||||
'a@server',
|
|
||||||
AlwaysTrustingTrustManager(),
|
|
||||||
opkAmount: 4,
|
|
||||||
);
|
|
||||||
final bobSession = await OmemoSessionManager.generateNewIdentity(
|
|
||||||
'b@other.server',
|
|
||||||
AlwaysTrustingTrustManager(),
|
|
||||||
opkAmount: 4,
|
|
||||||
);
|
|
||||||
await oldSession.addSessionFromBundle(
|
|
||||||
'bob@localhost',
|
|
||||||
await bobSession.getDeviceId(),
|
|
||||||
await bobSession.getDeviceBundle(),
|
|
||||||
);
|
|
||||||
|
|
||||||
// Serialise and deserialise
|
|
||||||
final serialised = jsonify(await oldSession.toJsonWithoutSessions());
|
|
||||||
final newSession = OmemoSessionManager.fromJsonWithoutSessions(
|
|
||||||
serialised,
|
|
||||||
// NOTE: At this point, we don't care about this attribute
|
|
||||||
{},
|
|
||||||
AlwaysTrustingTrustManager(),
|
|
||||||
);
|
|
||||||
|
|
||||||
final oldDevice = await oldSession.getDevice();
|
|
||||||
final newDevice = await newSession.getDevice();
|
|
||||||
expect(await oldDevice.equals(newDevice), true);
|
|
||||||
expect(await oldSession.getDeviceMap(), await newSession.getDeviceMap());
|
|
||||||
});
|
|
||||||
|
|
||||||
test('Test serializing and deserializing RatchetMapKey', () {
|
|
||||||
const test1 = RatchetMapKey('user@example.org', 1234);
|
|
||||||
final result1 = RatchetMapKey.fromJsonKey(test1.toJsonKey());
|
|
||||||
expect(result1.jid, test1.jid);
|
|
||||||
expect(result1.deviceId, test1.deviceId);
|
|
||||||
|
|
||||||
const test2 = RatchetMapKey('user@example.org/hallo:welt', 3333);
|
|
||||||
final result2 = RatchetMapKey.fromJsonKey(test2.toJsonKey());
|
|
||||||
expect(result2.jid, test2.jid);
|
|
||||||
expect(result2.deviceId, test2.deviceId);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('Test serializing and deserializing the components of the BTBV manager',
|
|
||||||
() async {
|
|
||||||
// Caroline's BTBV manager
|
|
||||||
final btbv = MemoryBTBVTrustManager();
|
|
||||||
// Example data
|
|
||||||
const aliceJid = 'alice@some.server';
|
|
||||||
const bobJid = 'bob@other.server';
|
|
||||||
|
|
||||||
await btbv.onNewSession(aliceJid, 1);
|
|
||||||
await btbv.setDeviceTrust(aliceJid, 1, BTBVTrustState.verified);
|
|
||||||
await btbv.onNewSession(aliceJid, 2);
|
|
||||||
await btbv.onNewSession(bobJid, 3);
|
|
||||||
await btbv.onNewSession(bobJid, 4);
|
|
||||||
|
|
||||||
final serialized = jsonify(await btbv.toJson());
|
|
||||||
final deviceList =
|
|
||||||
BlindTrustBeforeVerificationTrustManager.deviceListFromJson(
|
|
||||||
serialized,
|
|
||||||
);
|
|
||||||
expect(btbv.devices, deviceList);
|
|
||||||
|
|
||||||
final trustCache =
|
|
||||||
BlindTrustBeforeVerificationTrustManager.trustCacheFromJson(
|
|
||||||
serialized,
|
|
||||||
);
|
|
||||||
expect(btbv.trustCache, trustCache);
|
|
||||||
|
|
||||||
final enableCache =
|
|
||||||
BlindTrustBeforeVerificationTrustManager.enableCacheFromJson(
|
|
||||||
serialized,
|
|
||||||
);
|
|
||||||
expect(btbv.enablementCache, enableCache);
|
|
||||||
});*/
|
|
||||||
|
|
||||||
test('Test reading and writing protobuf', () {
|
|
||||||
final kex = OMEMOKeyExchange.fromBuffer(base64Decode('CFIQqvSv8AEaIHuVKKqf00vYpBIB7PKWheboVKcoKCWkRIUFeokzMYqxIiDOYPRA2vAlHwDLwPn/XIMSmenj3fgUIZHMgUXxVJtedyp8ChA+GfjScvWAllcTavRoyvfIEmgIDhAAGiANff1ES1HdSgtjy9JsoXcAywXJfBmZsFYTKUHRQsCMNiJAAOhS/CMrIdDm+ZZ/fmaOfwD0O7MNUaUMkVahvk4XDAy6mYk65r2TE4REW7h7akcKyoL94YSnTWp8p6fO91VSLA=='));
|
|
||||||
final newKex = OMEMOKeyExchange.fromBuffer(kex.writeToBuffer());
|
|
||||||
|
|
||||||
expect(kex.writeToBuffer(), newKex.writeToBuffer());
|
|
||||||
});
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user