refactor: port encryption tests
This commit is contained in:
parent
32c6e0ec6e
commit
e6f77924d6
|
|
@ -1,4 +1,3 @@
|
||||||
// @dart=2.9
|
|
||||||
/*
|
/*
|
||||||
* Famedly Matrix SDK
|
* Famedly Matrix SDK
|
||||||
* Copyright (C) 2020 Famedly GmbH
|
* Copyright (C) 2020 Famedly GmbH
|
||||||
|
|
@ -33,9 +32,9 @@ void main() {
|
||||||
Logs().level = Level.error;
|
Logs().level = Level.error;
|
||||||
var olmEnabled = true;
|
var olmEnabled = true;
|
||||||
|
|
||||||
Client client;
|
late Client client;
|
||||||
Map<String, dynamic> oldSecret;
|
late Map<String, dynamic> oldSecret;
|
||||||
String origKeyId;
|
late String origKeyId;
|
||||||
|
|
||||||
test('setupClient', () async {
|
test('setupClient', () async {
|
||||||
client = await getClient();
|
client = await getClient();
|
||||||
|
|
@ -53,8 +52,8 @@ void main() {
|
||||||
Logs().i('[LibOlm] Enabled: $olmEnabled');
|
Logs().i('[LibOlm] Enabled: $olmEnabled');
|
||||||
if (!olmEnabled) return;
|
if (!olmEnabled) return;
|
||||||
|
|
||||||
Bootstrap bootstrap;
|
Bootstrap? bootstrap;
|
||||||
bootstrap = client.encryption.bootstrap(
|
bootstrap = client.encryption!.bootstrap(
|
||||||
onUpdate: () async {
|
onUpdate: () async {
|
||||||
while (bootstrap == null) {
|
while (bootstrap == null) {
|
||||||
await Future.delayed(Duration(milliseconds: 5));
|
await Future.delayed(Duration(milliseconds: 5));
|
||||||
|
|
@ -82,7 +81,7 @@ void main() {
|
||||||
while (bootstrap.state != BootstrapState.done) {
|
while (bootstrap.state != BootstrapState.done) {
|
||||||
await Future.delayed(Duration(milliseconds: 50));
|
await Future.delayed(Duration(milliseconds: 50));
|
||||||
}
|
}
|
||||||
final defaultKey = client.encryption.ssss.open();
|
final defaultKey = client.encryption!.ssss.open();
|
||||||
await defaultKey.unlock(passphrase: 'foxies');
|
await defaultKey.unlock(passphrase: 'foxies');
|
||||||
|
|
||||||
// test all the x-signing keys match up
|
// test all the x-signing keys match up
|
||||||
|
|
@ -95,8 +94,8 @@ void main() {
|
||||||
expect(
|
expect(
|
||||||
pubKey,
|
pubKey,
|
||||||
client.userDeviceKeys[client.userID]
|
client.userDeviceKeys[client.userID]
|
||||||
.getCrossSigningKey(keyType)
|
?.getCrossSigningKey(keyType)
|
||||||
.publicKey);
|
?.publicKey);
|
||||||
} finally {
|
} finally {
|
||||||
keyObj.free();
|
keyObj.free();
|
||||||
}
|
}
|
||||||
|
|
@ -104,14 +103,15 @@ void main() {
|
||||||
|
|
||||||
await defaultKey.store('foxes', 'floof');
|
await defaultKey.store('foxes', 'floof');
|
||||||
await Future.delayed(Duration(milliseconds: 50));
|
await Future.delayed(Duration(milliseconds: 50));
|
||||||
oldSecret = json.decode(json.encode(client.accountData['foxes'].content));
|
oldSecret =
|
||||||
|
json.decode(json.encode(client.accountData['foxes']!.content));
|
||||||
origKeyId = defaultKey.keyId;
|
origKeyId = defaultKey.keyId;
|
||||||
}, timeout: Timeout(Duration(minutes: 2)));
|
}, timeout: Timeout(Duration(minutes: 2)));
|
||||||
|
|
||||||
test('change recovery passphrase', () async {
|
test('change recovery passphrase', () async {
|
||||||
if (!olmEnabled) return;
|
if (!olmEnabled) return;
|
||||||
Bootstrap bootstrap;
|
Bootstrap? bootstrap;
|
||||||
bootstrap = client.encryption.bootstrap(
|
bootstrap = client.encryption!.bootstrap(
|
||||||
onUpdate: () async {
|
onUpdate: () async {
|
||||||
while (bootstrap == null) {
|
while (bootstrap == null) {
|
||||||
await Future.delayed(Duration(milliseconds: 5));
|
await Future.delayed(Duration(milliseconds: 5));
|
||||||
|
|
@ -121,7 +121,7 @@ void main() {
|
||||||
} else if (bootstrap.state == BootstrapState.askUseExistingSsss) {
|
} else if (bootstrap.state == BootstrapState.askUseExistingSsss) {
|
||||||
bootstrap.useExistingSsss(false);
|
bootstrap.useExistingSsss(false);
|
||||||
} else if (bootstrap.state == BootstrapState.askUnlockSsss) {
|
} else if (bootstrap.state == BootstrapState.askUnlockSsss) {
|
||||||
await bootstrap.oldSsssKeys[client.encryption.ssss.defaultKeyId]
|
await bootstrap.oldSsssKeys![client.encryption!.ssss.defaultKeyId]!
|
||||||
.unlock(passphrase: 'foxies');
|
.unlock(passphrase: 'foxies');
|
||||||
bootstrap.unlockedSsss();
|
bootstrap.unlockedSsss();
|
||||||
} else if (bootstrap.state == BootstrapState.askNewSsss) {
|
} else if (bootstrap.state == BootstrapState.askNewSsss) {
|
||||||
|
|
@ -136,7 +136,7 @@ void main() {
|
||||||
while (bootstrap.state != BootstrapState.done) {
|
while (bootstrap.state != BootstrapState.done) {
|
||||||
await Future.delayed(Duration(milliseconds: 50));
|
await Future.delayed(Duration(milliseconds: 50));
|
||||||
}
|
}
|
||||||
final defaultKey = client.encryption.ssss.open();
|
final defaultKey = client.encryption!.ssss.open();
|
||||||
await defaultKey.unlock(passphrase: 'newfoxies');
|
await defaultKey.unlock(passphrase: 'newfoxies');
|
||||||
|
|
||||||
// test all the x-signing keys match up
|
// test all the x-signing keys match up
|
||||||
|
|
@ -149,8 +149,8 @@ void main() {
|
||||||
expect(
|
expect(
|
||||||
pubKey,
|
pubKey,
|
||||||
client.userDeviceKeys[client.userID]
|
client.userDeviceKeys[client.userID]
|
||||||
.getCrossSigningKey(keyType)
|
?.getCrossSigningKey(keyType)
|
||||||
.publicKey);
|
?.publicKey);
|
||||||
} finally {
|
} finally {
|
||||||
keyObj.free();
|
keyObj.free();
|
||||||
}
|
}
|
||||||
|
|
@ -161,11 +161,11 @@ void main() {
|
||||||
|
|
||||||
test('change passphrase with multiple keys', () async {
|
test('change passphrase with multiple keys', () async {
|
||||||
if (!olmEnabled) return;
|
if (!olmEnabled) return;
|
||||||
await client.setAccountData(client.userID, 'foxes', oldSecret);
|
await client.setAccountData(client.userID!, 'foxes', oldSecret);
|
||||||
await Future.delayed(Duration(milliseconds: 50));
|
await Future.delayed(Duration(milliseconds: 50));
|
||||||
|
|
||||||
Bootstrap bootstrap;
|
Bootstrap? bootstrap;
|
||||||
bootstrap = client.encryption.bootstrap(
|
bootstrap = client.encryption!.bootstrap(
|
||||||
onUpdate: () async {
|
onUpdate: () async {
|
||||||
while (bootstrap == null) {
|
while (bootstrap == null) {
|
||||||
await Future.delayed(Duration(milliseconds: 5));
|
await Future.delayed(Duration(milliseconds: 5));
|
||||||
|
|
@ -175,9 +175,10 @@ void main() {
|
||||||
} else if (bootstrap.state == BootstrapState.askUseExistingSsss) {
|
} else if (bootstrap.state == BootstrapState.askUseExistingSsss) {
|
||||||
bootstrap.useExistingSsss(false);
|
bootstrap.useExistingSsss(false);
|
||||||
} else if (bootstrap.state == BootstrapState.askUnlockSsss) {
|
} else if (bootstrap.state == BootstrapState.askUnlockSsss) {
|
||||||
await bootstrap.oldSsssKeys[client.encryption.ssss.defaultKeyId]
|
await bootstrap.oldSsssKeys![client.encryption!.ssss.defaultKeyId]!
|
||||||
.unlock(passphrase: 'newfoxies');
|
.unlock(passphrase: 'newfoxies');
|
||||||
await bootstrap.oldSsssKeys[origKeyId].unlock(passphrase: 'foxies');
|
await bootstrap.oldSsssKeys![origKeyId]!
|
||||||
|
.unlock(passphrase: 'foxies');
|
||||||
bootstrap.unlockedSsss();
|
bootstrap.unlockedSsss();
|
||||||
} else if (bootstrap.state == BootstrapState.askNewSsss) {
|
} else if (bootstrap.state == BootstrapState.askNewSsss) {
|
||||||
await bootstrap.newSsss('supernewfoxies');
|
await bootstrap.newSsss('supernewfoxies');
|
||||||
|
|
@ -191,7 +192,7 @@ void main() {
|
||||||
while (bootstrap.state != BootstrapState.done) {
|
while (bootstrap.state != BootstrapState.done) {
|
||||||
await Future.delayed(Duration(milliseconds: 50));
|
await Future.delayed(Duration(milliseconds: 50));
|
||||||
}
|
}
|
||||||
final defaultKey = client.encryption.ssss.open();
|
final defaultKey = client.encryption!.ssss.open();
|
||||||
await defaultKey.unlock(passphrase: 'supernewfoxies');
|
await defaultKey.unlock(passphrase: 'supernewfoxies');
|
||||||
|
|
||||||
// test all the x-signing keys match up
|
// test all the x-signing keys match up
|
||||||
|
|
@ -204,8 +205,8 @@ void main() {
|
||||||
expect(
|
expect(
|
||||||
pubKey,
|
pubKey,
|
||||||
client.userDeviceKeys[client.userID]
|
client.userDeviceKeys[client.userID]
|
||||||
.getCrossSigningKey(keyType)
|
?.getCrossSigningKey(keyType)
|
||||||
.publicKey);
|
?.publicKey);
|
||||||
} finally {
|
} finally {
|
||||||
keyObj.free();
|
keyObj.free();
|
||||||
}
|
}
|
||||||
|
|
@ -217,8 +218,8 @@ void main() {
|
||||||
test('setup new ssss', () async {
|
test('setup new ssss', () async {
|
||||||
if (!olmEnabled) return;
|
if (!olmEnabled) return;
|
||||||
client.accountData.clear();
|
client.accountData.clear();
|
||||||
Bootstrap bootstrap;
|
Bootstrap? bootstrap;
|
||||||
bootstrap = client.encryption.bootstrap(
|
bootstrap = client.encryption!.bootstrap(
|
||||||
onUpdate: () async {
|
onUpdate: () async {
|
||||||
while (bootstrap == null) {
|
while (bootstrap == null) {
|
||||||
await Future.delayed(Duration(milliseconds: 5));
|
await Future.delayed(Duration(milliseconds: 5));
|
||||||
|
|
@ -236,18 +237,18 @@ void main() {
|
||||||
while (bootstrap.state != BootstrapState.done) {
|
while (bootstrap.state != BootstrapState.done) {
|
||||||
await Future.delayed(Duration(milliseconds: 50));
|
await Future.delayed(Duration(milliseconds: 50));
|
||||||
}
|
}
|
||||||
final defaultKey = client.encryption.ssss.open();
|
final defaultKey = client.encryption!.ssss.open();
|
||||||
await defaultKey.unlock(passphrase: 'thenewestfoxies');
|
await defaultKey.unlock(passphrase: 'thenewestfoxies');
|
||||||
}, timeout: Timeout(Duration(minutes: 2)));
|
}, timeout: Timeout(Duration(minutes: 2)));
|
||||||
|
|
||||||
test('bad ssss', () async {
|
test('bad ssss', () async {
|
||||||
if (!olmEnabled) return;
|
if (!olmEnabled) return;
|
||||||
client.accountData.clear();
|
client.accountData.clear();
|
||||||
await client.setAccountData(client.userID, 'foxes', oldSecret);
|
await client.setAccountData(client.userID!, 'foxes', oldSecret);
|
||||||
await Future.delayed(Duration(milliseconds: 50));
|
await Future.delayed(Duration(milliseconds: 50));
|
||||||
var askedBadSsss = false;
|
var askedBadSsss = false;
|
||||||
Bootstrap bootstrap;
|
Bootstrap? bootstrap;
|
||||||
bootstrap = client.encryption.bootstrap(
|
bootstrap = client.encryption!.bootstrap(
|
||||||
onUpdate: () async {
|
onUpdate: () async {
|
||||||
while (bootstrap == null) {
|
while (bootstrap == null) {
|
||||||
await Future.delayed(Duration(milliseconds: 5));
|
await Future.delayed(Duration(milliseconds: 5));
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
// @dart=2.9
|
|
||||||
/*
|
/*
|
||||||
* Famedly Matrix SDK
|
* Famedly Matrix SDK
|
||||||
* Copyright (C) 2020 Famedly GmbH
|
* Copyright (C) 2020 Famedly GmbH
|
||||||
|
|
@ -32,7 +31,7 @@ void main() {
|
||||||
Logs().level = Level.error;
|
Logs().level = Level.error;
|
||||||
var olmEnabled = true;
|
var olmEnabled = true;
|
||||||
|
|
||||||
Client client;
|
late Client client;
|
||||||
|
|
||||||
test('setupClient', () async {
|
test('setupClient', () async {
|
||||||
try {
|
try {
|
||||||
|
|
@ -50,41 +49,43 @@ void main() {
|
||||||
|
|
||||||
test('basic things', () async {
|
test('basic things', () async {
|
||||||
if (!olmEnabled) return;
|
if (!olmEnabled) return;
|
||||||
expect(client.encryption.crossSigning.enabled, true);
|
expect(client.encryption?.crossSigning.enabled, true);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('selfSign', () async {
|
test('selfSign', () async {
|
||||||
if (!olmEnabled) return;
|
if (!olmEnabled) return;
|
||||||
final key = client.userDeviceKeys[client.userID].masterKey;
|
final key = client.userDeviceKeys[client.userID]!.masterKey!;
|
||||||
key.setDirectVerified(false);
|
key.setDirectVerified(false);
|
||||||
FakeMatrixApi.calledEndpoints.clear();
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
await client.encryption.crossSigning.selfSign(recoveryKey: ssssKey);
|
await client.encryption!.crossSigning.selfSign(recoveryKey: ssssKey);
|
||||||
expect(key.directVerified, true);
|
expect(key.directVerified, true);
|
||||||
expect(
|
expect(
|
||||||
FakeMatrixApi.calledEndpoints
|
FakeMatrixApi.calledEndpoints
|
||||||
.containsKey('/client/r0/keys/signatures/upload'),
|
.containsKey('/client/r0/keys/signatures/upload'),
|
||||||
true);
|
true);
|
||||||
expect(await client.encryption.crossSigning.isCached(), true);
|
expect(await client.encryption!.crossSigning.isCached(), true);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('signable', () async {
|
test('signable', () async {
|
||||||
if (!olmEnabled) return;
|
if (!olmEnabled) return;
|
||||||
expect(
|
expect(
|
||||||
client.encryption.crossSigning
|
client.encryption!.crossSigning
|
||||||
.signable([client.userDeviceKeys[client.userID].masterKey]),
|
.signable([client.userDeviceKeys[client.userID!]!.masterKey!]),
|
||||||
true);
|
true);
|
||||||
expect(
|
expect(
|
||||||
client.encryption.crossSigning.signable([
|
client.encryption!.crossSigning.signable([
|
||||||
client.userDeviceKeys[client.userID].deviceKeys[client.deviceID]
|
client.userDeviceKeys[client.userID!]!.deviceKeys[client.deviceID!]!
|
||||||
]),
|
]),
|
||||||
false);
|
false);
|
||||||
expect(
|
expect(
|
||||||
client.encryption.crossSigning.signable(
|
client.encryption!.crossSigning.signable([
|
||||||
[client.userDeviceKeys[client.userID].deviceKeys['OTHERDEVICE']]),
|
client.userDeviceKeys[client.userID!]!.deviceKeys['OTHERDEVICE']!
|
||||||
|
]),
|
||||||
true);
|
true);
|
||||||
expect(
|
expect(
|
||||||
client.encryption.crossSigning.signable([
|
client.encryption!.crossSigning.signable([
|
||||||
client.userDeviceKeys['@alice:example.com'].deviceKeys['JLAFKJWSCS']
|
client
|
||||||
|
.userDeviceKeys['@alice:example.com']!.deviceKeys['JLAFKJWSCS']!
|
||||||
]),
|
]),
|
||||||
false);
|
false);
|
||||||
});
|
});
|
||||||
|
|
@ -92,24 +93,24 @@ void main() {
|
||||||
test('sign', () async {
|
test('sign', () async {
|
||||||
if (!olmEnabled) return;
|
if (!olmEnabled) return;
|
||||||
FakeMatrixApi.calledEndpoints.clear();
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
await client.encryption.crossSigning.sign([
|
await client.encryption!.crossSigning.sign([
|
||||||
client.userDeviceKeys[client.userID].masterKey,
|
client.userDeviceKeys[client.userID!]!.masterKey!,
|
||||||
client.userDeviceKeys[client.userID].deviceKeys['OTHERDEVICE'],
|
client.userDeviceKeys[client.userID!]!.deviceKeys['OTHERDEVICE']!,
|
||||||
client.userDeviceKeys['@othertest:fakeServer.notExisting'].masterKey
|
client.userDeviceKeys['@othertest:fakeServer.notExisting']!.masterKey!
|
||||||
]);
|
]);
|
||||||
final body = json.decode(FakeMatrixApi
|
final body = json.decode(FakeMatrixApi
|
||||||
.calledEndpoints['/client/r0/keys/signatures/upload'].first);
|
.calledEndpoints['/client/r0/keys/signatures/upload']!.first);
|
||||||
expect(body['@test:fakeServer.notExisting']?.containsKey('OTHERDEVICE'),
|
expect(body['@test:fakeServer.notExisting']?.containsKey('OTHERDEVICE'),
|
||||||
true);
|
true);
|
||||||
expect(
|
expect(
|
||||||
body['@test:fakeServer.notExisting'].containsKey(
|
body['@test:fakeServer.notExisting'].containsKey(
|
||||||
client.userDeviceKeys[client.userID].masterKey.publicKey),
|
client.userDeviceKeys[client.userID]!.masterKey!.publicKey),
|
||||||
true);
|
true);
|
||||||
expect(
|
expect(
|
||||||
body['@othertest:fakeServer.notExisting'].containsKey(client
|
body['@othertest:fakeServer.notExisting'].containsKey(client
|
||||||
.userDeviceKeys['@othertest:fakeServer.notExisting']
|
.userDeviceKeys['@othertest:fakeServer.notExisting']
|
||||||
.masterKey
|
?.masterKey
|
||||||
.publicKey),
|
?.publicKey),
|
||||||
true);
|
true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
// @dart=2.9
|
|
||||||
/*
|
/*
|
||||||
* Famedly Matrix SDK
|
* Famedly Matrix SDK
|
||||||
* Copyright (C) 2020 Famedly GmbH
|
* Copyright (C) 2020 Famedly GmbH
|
||||||
|
|
@ -29,10 +28,10 @@ void main() {
|
||||||
Logs().level = Level.error;
|
Logs().level = Level.error;
|
||||||
var olmEnabled = true;
|
var olmEnabled = true;
|
||||||
|
|
||||||
Client client;
|
late Client client;
|
||||||
final roomId = '!726s6s6q:example.com';
|
final roomId = '!726s6s6q:example.com';
|
||||||
Room room;
|
late Room room;
|
||||||
Map<String, dynamic> payload;
|
late Map<String, dynamic> payload;
|
||||||
final now = DateTime.now();
|
final now = DateTime.now();
|
||||||
|
|
||||||
test('setupClient', () async {
|
test('setupClient', () async {
|
||||||
|
|
@ -47,12 +46,12 @@ void main() {
|
||||||
if (!olmEnabled) return;
|
if (!olmEnabled) return;
|
||||||
|
|
||||||
client = await getClient();
|
client = await getClient();
|
||||||
room = client.getRoomById(roomId);
|
room = client.getRoomById(roomId)!;
|
||||||
});
|
});
|
||||||
|
|
||||||
test('encrypt payload', () async {
|
test('encrypt payload', () async {
|
||||||
if (!olmEnabled) return;
|
if (!olmEnabled) return;
|
||||||
payload = await client.encryption.encryptGroupMessagePayload(roomId, {
|
payload = await client.encryption!.encryptGroupMessagePayload(roomId, {
|
||||||
'msgtype': 'm.text',
|
'msgtype': 'm.text',
|
||||||
'text': 'Hello foxies!',
|
'text': 'Hello foxies!',
|
||||||
});
|
});
|
||||||
|
|
@ -72,10 +71,10 @@ void main() {
|
||||||
room: room,
|
room: room,
|
||||||
originServerTs: now,
|
originServerTs: now,
|
||||||
eventId: '\$event',
|
eventId: '\$event',
|
||||||
senderId: client.userID,
|
senderId: client.userID!,
|
||||||
);
|
);
|
||||||
final decryptedEvent =
|
final decryptedEvent =
|
||||||
await client.encryption.decryptRoomEvent(roomId, encryptedEvent);
|
await client.encryption!.decryptRoomEvent(roomId, encryptedEvent);
|
||||||
expect(decryptedEvent.type, 'm.room.message');
|
expect(decryptedEvent.type, 'm.room.message');
|
||||||
expect(decryptedEvent.content['msgtype'], 'm.text');
|
expect(decryptedEvent.content['msgtype'], 'm.text');
|
||||||
expect(decryptedEvent.content['text'], 'Hello foxies!');
|
expect(decryptedEvent.content['text'], 'Hello foxies!');
|
||||||
|
|
@ -83,7 +82,7 @@ void main() {
|
||||||
|
|
||||||
test('decrypt payload nocache', () async {
|
test('decrypt payload nocache', () async {
|
||||||
if (!olmEnabled) return;
|
if (!olmEnabled) return;
|
||||||
client.encryption.keyManager.clearInboundGroupSessions();
|
client.encryption!.keyManager.clearInboundGroupSessions();
|
||||||
final encryptedEvent = Event(
|
final encryptedEvent = Event(
|
||||||
type: EventTypes.Encrypted,
|
type: EventTypes.Encrypted,
|
||||||
content: payload,
|
content: payload,
|
||||||
|
|
@ -94,11 +93,11 @@ void main() {
|
||||||
senderId: '@alice:example.com',
|
senderId: '@alice:example.com',
|
||||||
);
|
);
|
||||||
final decryptedEvent =
|
final decryptedEvent =
|
||||||
await client.encryption.decryptRoomEvent(roomId, encryptedEvent);
|
await client.encryption!.decryptRoomEvent(roomId, encryptedEvent);
|
||||||
expect(decryptedEvent.type, 'm.room.message');
|
expect(decryptedEvent.type, 'm.room.message');
|
||||||
expect(decryptedEvent.content['msgtype'], 'm.text');
|
expect(decryptedEvent.content['msgtype'], 'm.text');
|
||||||
expect(decryptedEvent.content['text'], 'Hello foxies!');
|
expect(decryptedEvent.content['text'], 'Hello foxies!');
|
||||||
await client.encryption
|
await client.encryption!
|
||||||
.decryptRoomEvent(roomId, encryptedEvent, store: true);
|
.decryptRoomEvent(roomId, encryptedEvent, store: true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
// @dart=2.9
|
|
||||||
/*
|
/*
|
||||||
* Famedly Matrix SDK
|
* Famedly Matrix SDK
|
||||||
* Copyright (C) 2020 Famedly GmbH
|
* Copyright (C) 2020 Famedly GmbH
|
||||||
|
|
@ -35,11 +34,11 @@ void main() {
|
||||||
Logs().level = Level.error;
|
Logs().level = Level.error;
|
||||||
var olmEnabled = true;
|
var olmEnabled = true;
|
||||||
|
|
||||||
Client client;
|
late Client client;
|
||||||
final otherClient = Client('othertestclient',
|
final otherClient = Client('othertestclient',
|
||||||
httpClient: FakeMatrixApi(), databaseBuilder: getDatabase);
|
httpClient: FakeMatrixApi(), databaseBuilder: getDatabase);
|
||||||
DeviceKeys device;
|
late DeviceKeys device;
|
||||||
Map<String, dynamic> payload;
|
late Map<String, dynamic> payload;
|
||||||
|
|
||||||
test('setupClient', () async {
|
test('setupClient', () async {
|
||||||
try {
|
try {
|
||||||
|
|
@ -83,7 +82,7 @@ void main() {
|
||||||
|
|
||||||
test('encryptToDeviceMessage', () async {
|
test('encryptToDeviceMessage', () async {
|
||||||
if (!olmEnabled) return;
|
if (!olmEnabled) return;
|
||||||
payload = await otherClient.encryption
|
payload = await otherClient.encryption!
|
||||||
.encryptToDeviceMessage([device], 'm.to_device', {'hello': 'foxies'});
|
.encryptToDeviceMessage([device], 'm.to_device', {'hello': 'foxies'});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -95,15 +94,15 @@ void main() {
|
||||||
content: payload[client.userID][client.deviceID],
|
content: payload[client.userID][client.deviceID],
|
||||||
);
|
);
|
||||||
final decryptedEvent =
|
final decryptedEvent =
|
||||||
await client.encryption.decryptToDeviceEvent(encryptedEvent);
|
await client.encryption!.decryptToDeviceEvent(encryptedEvent);
|
||||||
expect(decryptedEvent.type, 'm.to_device');
|
expect(decryptedEvent.type, 'm.to_device');
|
||||||
expect(decryptedEvent.content['hello'], 'foxies');
|
expect(decryptedEvent.content['hello'], 'foxies');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('decryptToDeviceEvent nocache', () async {
|
test('decryptToDeviceEvent nocache', () async {
|
||||||
if (!olmEnabled) return;
|
if (!olmEnabled) return;
|
||||||
client.encryption.olmManager.olmSessions.clear();
|
client.encryption!.olmManager.olmSessions.clear();
|
||||||
payload = await otherClient.encryption.encryptToDeviceMessage(
|
payload = await otherClient.encryption!.encryptToDeviceMessage(
|
||||||
[device], 'm.to_device', {'hello': 'superfoxies'});
|
[device], 'm.to_device', {'hello': 'superfoxies'});
|
||||||
final encryptedEvent = ToDeviceEvent(
|
final encryptedEvent = ToDeviceEvent(
|
||||||
sender: '@othertest:fakeServer.notExisting',
|
sender: '@othertest:fakeServer.notExisting',
|
||||||
|
|
@ -111,7 +110,7 @@ void main() {
|
||||||
content: payload[client.userID][client.deviceID],
|
content: payload[client.userID][client.deviceID],
|
||||||
);
|
);
|
||||||
final decryptedEvent =
|
final decryptedEvent =
|
||||||
await client.encryption.decryptToDeviceEvent(encryptedEvent);
|
await client.encryption!.decryptToDeviceEvent(encryptedEvent);
|
||||||
expect(decryptedEvent.type, 'm.to_device');
|
expect(decryptedEvent.type, 'm.to_device');
|
||||||
expect(decryptedEvent.content['hello'], 'superfoxies');
|
expect(decryptedEvent.content['hello'], 'superfoxies');
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
// @dart=2.9
|
|
||||||
/*
|
/*
|
||||||
* Famedly Matrix SDK
|
* Famedly Matrix SDK
|
||||||
* Copyright (C) 2020 Famedly GmbH
|
* Copyright (C) 2020 Famedly GmbH
|
||||||
|
|
@ -32,7 +31,7 @@ void main() {
|
||||||
Logs().level = Level.error;
|
Logs().level = Level.error;
|
||||||
var olmEnabled = true;
|
var olmEnabled = true;
|
||||||
|
|
||||||
Client client;
|
late Client client;
|
||||||
|
|
||||||
test('setupClient', () async {
|
test('setupClient', () async {
|
||||||
try {
|
try {
|
||||||
|
|
@ -55,7 +54,7 @@ void main() {
|
||||||
final sessionKey =
|
final sessionKey =
|
||||||
'AgAAAAAQcQ6XrFJk6Prm8FikZDqfry/NbDz8Xw7T6e+/9Yf/q3YHIPEQlzv7IZMNcYb51ifkRzFejVvtphS7wwG2FaXIp4XS2obla14iKISR0X74ugB2vyb1AydIHE/zbBQ1ic5s3kgjMFlWpu/S3FQCnCrv+DPFGEt3ERGWxIl3Bl5X53IjPyVkz65oljz2TZESwz0GH/QFvyOOm8ci0q/gceaF3S7Dmafg3dwTKYwcA5xkcc+BLyrLRzB6Hn+oMAqSNSscnm4mTeT5zYibIhrzqyUTMWr32spFtI9dNR/RFSzfCw';
|
'AgAAAAAQcQ6XrFJk6Prm8FikZDqfry/NbDz8Xw7T6e+/9Yf/q3YHIPEQlzv7IZMNcYb51ifkRzFejVvtphS7wwG2FaXIp4XS2obla14iKISR0X74ugB2vyb1AydIHE/zbBQ1ic5s3kgjMFlWpu/S3FQCnCrv+DPFGEt3ERGWxIl3Bl5X53IjPyVkz65oljz2TZESwz0GH/QFvyOOm8ci0q/gceaF3S7Dmafg3dwTKYwcA5xkcc+BLyrLRzB6Hn+oMAqSNSscnm4mTeT5zYibIhrzqyUTMWr32spFtI9dNR/RFSzfCw';
|
||||||
|
|
||||||
client.encryption.keyManager.clearInboundGroupSessions();
|
client.encryption!.keyManager.clearInboundGroupSessions();
|
||||||
var event = ToDeviceEvent(
|
var event = ToDeviceEvent(
|
||||||
sender: '@alice:example.com',
|
sender: '@alice:example.com',
|
||||||
type: 'm.room_key',
|
type: 'm.room_key',
|
||||||
|
|
@ -68,9 +67,9 @@ void main() {
|
||||||
encryptedContent: {
|
encryptedContent: {
|
||||||
'sender_key': validSenderKey,
|
'sender_key': validSenderKey,
|
||||||
});
|
});
|
||||||
await client.encryption.keyManager.handleToDeviceEvent(event);
|
await client.encryption!.keyManager.handleToDeviceEvent(event);
|
||||||
expect(
|
expect(
|
||||||
client.encryption.keyManager.getInboundGroupSession(
|
client.encryption!.keyManager.getInboundGroupSession(
|
||||||
'!726s6s6q:example.com', validSessionId, validSenderKey) !=
|
'!726s6s6q:example.com', validSessionId, validSenderKey) !=
|
||||||
null,
|
null,
|
||||||
true);
|
true);
|
||||||
|
|
@ -78,7 +77,7 @@ void main() {
|
||||||
// now test a few invalid scenarios
|
// now test a few invalid scenarios
|
||||||
|
|
||||||
// not encrypted
|
// not encrypted
|
||||||
client.encryption.keyManager.clearInboundGroupSessions();
|
client.encryption!.keyManager.clearInboundGroupSessions();
|
||||||
event = ToDeviceEvent(
|
event = ToDeviceEvent(
|
||||||
sender: '@alice:example.com',
|
sender: '@alice:example.com',
|
||||||
type: 'm.room_key',
|
type: 'm.room_key',
|
||||||
|
|
@ -88,9 +87,9 @@ void main() {
|
||||||
'session_id': validSessionId,
|
'session_id': validSessionId,
|
||||||
'session_key': sessionKey,
|
'session_key': sessionKey,
|
||||||
});
|
});
|
||||||
await client.encryption.keyManager.handleToDeviceEvent(event);
|
await client.encryption!.keyManager.handleToDeviceEvent(event);
|
||||||
expect(
|
expect(
|
||||||
client.encryption.keyManager.getInboundGroupSession(
|
client.encryption!.keyManager.getInboundGroupSession(
|
||||||
'!726s6s6q:example.com', validSessionId, validSenderKey) !=
|
'!726s6s6q:example.com', validSessionId, validSenderKey) !=
|
||||||
null,
|
null,
|
||||||
false);
|
false);
|
||||||
|
|
@ -100,99 +99,104 @@ void main() {
|
||||||
if (!olmEnabled) return;
|
if (!olmEnabled) return;
|
||||||
final roomId = '!726s6s6q:example.com';
|
final roomId = '!726s6s6q:example.com';
|
||||||
expect(
|
expect(
|
||||||
client.encryption.keyManager.getOutboundGroupSession(roomId) != null,
|
client.encryption!.keyManager.getOutboundGroupSession(roomId) != null,
|
||||||
false);
|
false);
|
||||||
var sess =
|
var sess = await client.encryption!.keyManager
|
||||||
await client.encryption.keyManager.createOutboundGroupSession(roomId);
|
.createOutboundGroupSession(roomId);
|
||||||
expect(
|
expect(
|
||||||
client.encryption.keyManager.getOutboundGroupSession(roomId) != null,
|
client.encryption!.keyManager.getOutboundGroupSession(roomId) != null,
|
||||||
true);
|
true);
|
||||||
await client.encryption.keyManager.clearOrUseOutboundGroupSession(roomId);
|
await client.encryption!.keyManager
|
||||||
|
.clearOrUseOutboundGroupSession(roomId);
|
||||||
expect(
|
expect(
|
||||||
client.encryption.keyManager.getOutboundGroupSession(roomId) != null,
|
client.encryption!.keyManager.getOutboundGroupSession(roomId) != null,
|
||||||
true);
|
true);
|
||||||
var inbound = client.encryption.keyManager.getInboundGroupSession(
|
var inbound = client.encryption!.keyManager.getInboundGroupSession(
|
||||||
roomId, sess.outboundGroupSession.session_id(), client.identityKey);
|
roomId, sess.outboundGroupSession!.session_id(), client.identityKey);
|
||||||
expect(inbound != null, true);
|
expect(inbound != null, true);
|
||||||
expect(
|
expect(
|
||||||
inbound.allowedAtIndex['@alice:example.com']
|
inbound!.allowedAtIndex['@alice:example.com']
|
||||||
['L+4+JCl8MD63dgo8z5Ta+9QAHXiANyOVSfgbHA5d3H8'],
|
?['L+4+JCl8MD63dgo8z5Ta+9QAHXiANyOVSfgbHA5d3H8'],
|
||||||
0);
|
0);
|
||||||
expect(
|
expect(
|
||||||
inbound.allowedAtIndex['@alice:example.com']
|
inbound.allowedAtIndex['@alice:example.com']
|
||||||
['wMIDhiQl5jEXQrTB03ePOSQfR8sA/KMrW0CIfFfXKEE'],
|
?['wMIDhiQl5jEXQrTB03ePOSQfR8sA/KMrW0CIfFfXKEE'],
|
||||||
0);
|
0);
|
||||||
|
|
||||||
// rotate after too many messages
|
// rotate after too many messages
|
||||||
Iterable.generate(300).forEach((_) {
|
Iterable.generate(300).forEach((_) {
|
||||||
sess.outboundGroupSession.encrypt('some string');
|
sess.outboundGroupSession!.encrypt('some string');
|
||||||
});
|
});
|
||||||
await client.encryption.keyManager.clearOrUseOutboundGroupSession(roomId);
|
await client.encryption!.keyManager
|
||||||
|
.clearOrUseOutboundGroupSession(roomId);
|
||||||
expect(
|
expect(
|
||||||
client.encryption.keyManager.getOutboundGroupSession(roomId) != null,
|
client.encryption!.keyManager.getOutboundGroupSession(roomId) != null,
|
||||||
false);
|
false);
|
||||||
|
|
||||||
// rotate if device is blocked
|
// rotate if device is blocked
|
||||||
sess =
|
sess = await client.encryption!.keyManager
|
||||||
await client.encryption.keyManager.createOutboundGroupSession(roomId);
|
.createOutboundGroupSession(roomId);
|
||||||
client.userDeviceKeys['@alice:example.com'].deviceKeys['JLAFKJWSCS']
|
client.userDeviceKeys['@alice:example.com']!.deviceKeys['JLAFKJWSCS']!
|
||||||
.blocked = true;
|
.blocked = true;
|
||||||
await client.encryption.keyManager.clearOrUseOutboundGroupSession(roomId);
|
await client.encryption!.keyManager
|
||||||
|
.clearOrUseOutboundGroupSession(roomId);
|
||||||
expect(
|
expect(
|
||||||
client.encryption.keyManager.getOutboundGroupSession(roomId) != null,
|
client.encryption!.keyManager.getOutboundGroupSession(roomId) != null,
|
||||||
false);
|
false);
|
||||||
client.userDeviceKeys['@alice:example.com'].deviceKeys['JLAFKJWSCS']
|
client.userDeviceKeys['@alice:example.com']!.deviceKeys['JLAFKJWSCS']!
|
||||||
.blocked = false;
|
.blocked = false;
|
||||||
|
|
||||||
// lazy-create if it would rotate
|
// lazy-create if it would rotate
|
||||||
sess =
|
sess = await client.encryption!.keyManager
|
||||||
await client.encryption.keyManager.createOutboundGroupSession(roomId);
|
.createOutboundGroupSession(roomId);
|
||||||
final oldSessKey = sess.outboundGroupSession.session_key();
|
final oldSessKey = sess.outboundGroupSession!.session_key();
|
||||||
client.userDeviceKeys['@alice:example.com'].deviceKeys['JLAFKJWSCS']
|
client.userDeviceKeys['@alice:example.com']!.deviceKeys['JLAFKJWSCS']!
|
||||||
.blocked = true;
|
.blocked = true;
|
||||||
await client.encryption.keyManager.prepareOutboundGroupSession(roomId);
|
await client.encryption!.keyManager.prepareOutboundGroupSession(roomId);
|
||||||
expect(
|
expect(
|
||||||
client.encryption.keyManager.getOutboundGroupSession(roomId) != null,
|
client.encryption!.keyManager.getOutboundGroupSession(roomId) != null,
|
||||||
true);
|
true);
|
||||||
expect(
|
expect(
|
||||||
client.encryption.keyManager
|
client.encryption!.keyManager
|
||||||
.getOutboundGroupSession(roomId)
|
.getOutboundGroupSession(roomId)!
|
||||||
.outboundGroupSession
|
.outboundGroupSession!
|
||||||
.session_key() !=
|
.session_key() !=
|
||||||
oldSessKey,
|
oldSessKey,
|
||||||
true);
|
true);
|
||||||
client.userDeviceKeys['@alice:example.com'].deviceKeys['JLAFKJWSCS']
|
client.userDeviceKeys['@alice:example.com']!.deviceKeys['JLAFKJWSCS']!
|
||||||
.blocked = false;
|
.blocked = false;
|
||||||
|
|
||||||
// rotate if too far in the past
|
// rotate if too far in the past
|
||||||
sess =
|
sess = await client.encryption!.keyManager
|
||||||
await client.encryption.keyManager.createOutboundGroupSession(roomId);
|
.createOutboundGroupSession(roomId);
|
||||||
sess.creationTime = DateTime.now().subtract(Duration(days: 30));
|
sess.creationTime = DateTime.now().subtract(Duration(days: 30));
|
||||||
await client.encryption.keyManager.clearOrUseOutboundGroupSession(roomId);
|
await client.encryption!.keyManager
|
||||||
|
.clearOrUseOutboundGroupSession(roomId);
|
||||||
expect(
|
expect(
|
||||||
client.encryption.keyManager.getOutboundGroupSession(roomId) != null,
|
client.encryption!.keyManager.getOutboundGroupSession(roomId) != null,
|
||||||
false);
|
false);
|
||||||
|
|
||||||
// rotate if user leaves
|
// rotate if user leaves
|
||||||
sess =
|
sess = await client.encryption!.keyManager
|
||||||
await client.encryption.keyManager.createOutboundGroupSession(roomId);
|
.createOutboundGroupSession(roomId);
|
||||||
final room = client.getRoomById(roomId);
|
final room = client.getRoomById(roomId)!;
|
||||||
final member = room.getState('m.room.member', '@alice:example.com');
|
final member = room.getState('m.room.member', '@alice:example.com');
|
||||||
member.content['membership'] = 'leave';
|
member!.content['membership'] = 'leave';
|
||||||
room.summary.mJoinedMemberCount--;
|
room.summary.mJoinedMemberCount = room.summary.mJoinedMemberCount! - 1;
|
||||||
await client.encryption.keyManager.clearOrUseOutboundGroupSession(roomId);
|
await client.encryption!.keyManager
|
||||||
|
.clearOrUseOutboundGroupSession(roomId);
|
||||||
expect(
|
expect(
|
||||||
client.encryption.keyManager.getOutboundGroupSession(roomId) != null,
|
client.encryption!.keyManager.getOutboundGroupSession(roomId) != null,
|
||||||
false);
|
false);
|
||||||
member.content['membership'] = 'join';
|
member.content['membership'] = 'join';
|
||||||
room.summary.mJoinedMemberCount++;
|
room.summary.mJoinedMemberCount = room.summary.mJoinedMemberCount! + 1;
|
||||||
|
|
||||||
// do not rotate if new device is added
|
// do not rotate if new device is added
|
||||||
sess =
|
sess = await client.encryption!.keyManager
|
||||||
await client.encryption.keyManager.createOutboundGroupSession(roomId);
|
.createOutboundGroupSession(roomId);
|
||||||
sess.outboundGroupSession.encrypt(
|
sess.outboundGroupSession!.encrypt(
|
||||||
'foxies'); // so that the new device will have a different index
|
'foxies'); // so that the new device will have a different index
|
||||||
client.userDeviceKeys['@alice:example.com'].deviceKeys['NEWDEVICE'] =
|
client.userDeviceKeys['@alice:example.com']?.deviceKeys['NEWDEVICE'] =
|
||||||
DeviceKeys.fromJson({
|
DeviceKeys.fromJson({
|
||||||
'user_id': '@alice:example.com',
|
'user_id': '@alice:example.com',
|
||||||
'device_id': 'NEWDEVICE',
|
'device_id': 'NEWDEVICE',
|
||||||
|
|
@ -211,56 +215,58 @@ void main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, client);
|
}, client);
|
||||||
await client.encryption.keyManager.clearOrUseOutboundGroupSession(roomId);
|
await client.encryption!.keyManager
|
||||||
|
.clearOrUseOutboundGroupSession(roomId);
|
||||||
expect(
|
expect(
|
||||||
client.encryption.keyManager.getOutboundGroupSession(roomId) != null,
|
client.encryption!.keyManager.getOutboundGroupSession(roomId) != null,
|
||||||
true);
|
true);
|
||||||
inbound = client.encryption.keyManager.getInboundGroupSession(
|
inbound = client.encryption!.keyManager.getInboundGroupSession(
|
||||||
roomId, sess.outboundGroupSession.session_id(), client.identityKey);
|
roomId, sess.outboundGroupSession!.session_id(), client.identityKey);
|
||||||
expect(
|
expect(
|
||||||
inbound.allowedAtIndex['@alice:example.com']
|
inbound!.allowedAtIndex['@alice:example.com']
|
||||||
['L+4+JCl8MD63dgo8z5Ta+9QAHXiANyOVSfgbHA5d3H8'],
|
?['L+4+JCl8MD63dgo8z5Ta+9QAHXiANyOVSfgbHA5d3H8'],
|
||||||
0);
|
0);
|
||||||
expect(
|
expect(
|
||||||
inbound.allowedAtIndex['@alice:example.com']
|
inbound.allowedAtIndex['@alice:example.com']
|
||||||
['wMIDhiQl5jEXQrTB03ePOSQfR8sA/KMrW0CIfFfXKEE'],
|
?['wMIDhiQl5jEXQrTB03ePOSQfR8sA/KMrW0CIfFfXKEE'],
|
||||||
0);
|
0);
|
||||||
expect(
|
expect(
|
||||||
inbound.allowedAtIndex['@alice:example.com']
|
inbound.allowedAtIndex['@alice:example.com']
|
||||||
['bnKQp6pPW0l9cGoIgHpBoK5OUi4h0gylJ7upc4asFV8'],
|
?['bnKQp6pPW0l9cGoIgHpBoK5OUi4h0gylJ7upc4asFV8'],
|
||||||
1);
|
1);
|
||||||
|
|
||||||
// do not rotate if new user is added
|
// do not rotate if new user is added
|
||||||
member.content['membership'] = 'leave';
|
member.content['membership'] = 'leave';
|
||||||
room.summary.mJoinedMemberCount--;
|
room.summary.mJoinedMemberCount = room.summary.mJoinedMemberCount! - 1;
|
||||||
sess =
|
sess = await client.encryption!.keyManager
|
||||||
await client.encryption.keyManager.createOutboundGroupSession(roomId);
|
.createOutboundGroupSession(roomId);
|
||||||
member.content['membership'] = 'join';
|
member.content['membership'] = 'join';
|
||||||
room.summary.mJoinedMemberCount++;
|
room.summary.mJoinedMemberCount = room.summary.mJoinedMemberCount! + 1;
|
||||||
await client.encryption.keyManager.clearOrUseOutboundGroupSession(roomId);
|
await client.encryption!.keyManager
|
||||||
|
.clearOrUseOutboundGroupSession(roomId);
|
||||||
expect(
|
expect(
|
||||||
client.encryption.keyManager.getOutboundGroupSession(roomId) != null,
|
client.encryption!.keyManager.getOutboundGroupSession(roomId) != null,
|
||||||
true);
|
true);
|
||||||
|
|
||||||
// force wipe
|
// force wipe
|
||||||
sess =
|
sess = await client.encryption!.keyManager
|
||||||
await client.encryption.keyManager.createOutboundGroupSession(roomId);
|
.createOutboundGroupSession(roomId);
|
||||||
await client.encryption.keyManager
|
await client.encryption!.keyManager
|
||||||
.clearOrUseOutboundGroupSession(roomId, wipe: true);
|
.clearOrUseOutboundGroupSession(roomId, wipe: true);
|
||||||
expect(
|
expect(
|
||||||
client.encryption.keyManager.getOutboundGroupSession(roomId) != null,
|
client.encryption!.keyManager.getOutboundGroupSession(roomId) != null,
|
||||||
false);
|
false);
|
||||||
|
|
||||||
// load from database
|
// load from database
|
||||||
sess =
|
sess = await client.encryption!.keyManager
|
||||||
await client.encryption.keyManager.createOutboundGroupSession(roomId);
|
.createOutboundGroupSession(roomId);
|
||||||
client.encryption.keyManager.clearOutboundGroupSessions();
|
client.encryption!.keyManager.clearOutboundGroupSessions();
|
||||||
expect(
|
expect(
|
||||||
client.encryption.keyManager.getOutboundGroupSession(roomId) != null,
|
client.encryption!.keyManager.getOutboundGroupSession(roomId) != null,
|
||||||
false);
|
false);
|
||||||
await client.encryption.keyManager.loadOutboundGroupSession(roomId);
|
await client.encryption!.keyManager.loadOutboundGroupSession(roomId);
|
||||||
expect(
|
expect(
|
||||||
client.encryption.keyManager.getOutboundGroupSession(roomId) != null,
|
client.encryption!.keyManager.getOutboundGroupSession(roomId) != null,
|
||||||
true);
|
true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -276,71 +282,71 @@ void main() {
|
||||||
'session_key':
|
'session_key':
|
||||||
'AgAAAAAQcQ6XrFJk6Prm8FikZDqfry/NbDz8Xw7T6e+/9Yf/q3YHIPEQlzv7IZMNcYb51ifkRzFejVvtphS7wwG2FaXIp4XS2obla14iKISR0X74ugB2vyb1AydIHE/zbBQ1ic5s3kgjMFlWpu/S3FQCnCrv+DPFGEt3ERGWxIl3Bl5X53IjPyVkz65oljz2TZESwz0GH/QFvyOOm8ci0q/gceaF3S7Dmafg3dwTKYwcA5xkcc+BLyrLRzB6Hn+oMAqSNSscnm4mTeT5zYibIhrzqyUTMWr32spFtI9dNR/RFSzfCw'
|
'AgAAAAAQcQ6XrFJk6Prm8FikZDqfry/NbDz8Xw7T6e+/9Yf/q3YHIPEQlzv7IZMNcYb51ifkRzFejVvtphS7wwG2FaXIp4XS2obla14iKISR0X74ugB2vyb1AydIHE/zbBQ1ic5s3kgjMFlWpu/S3FQCnCrv+DPFGEt3ERGWxIl3Bl5X53IjPyVkz65oljz2TZESwz0GH/QFvyOOm8ci0q/gceaF3S7Dmafg3dwTKYwcA5xkcc+BLyrLRzB6Hn+oMAqSNSscnm4mTeT5zYibIhrzqyUTMWr32spFtI9dNR/RFSzfCw'
|
||||||
};
|
};
|
||||||
client.encryption.keyManager.clearInboundGroupSessions();
|
client.encryption!.keyManager.clearInboundGroupSessions();
|
||||||
expect(
|
expect(
|
||||||
client.encryption.keyManager
|
client.encryption!.keyManager
|
||||||
.getInboundGroupSession(roomId, sessionId, senderKey) !=
|
.getInboundGroupSession(roomId, sessionId, senderKey) !=
|
||||||
null,
|
null,
|
||||||
false);
|
false);
|
||||||
client.encryption.keyManager
|
client.encryption!.keyManager
|
||||||
.setInboundGroupSession(roomId, sessionId, senderKey, sessionContent);
|
.setInboundGroupSession(roomId, sessionId, senderKey, sessionContent);
|
||||||
await Future.delayed(Duration(milliseconds: 10));
|
await Future.delayed(Duration(milliseconds: 10));
|
||||||
expect(
|
expect(
|
||||||
client.encryption.keyManager
|
client.encryption!.keyManager
|
||||||
.getInboundGroupSession(roomId, sessionId, senderKey) !=
|
.getInboundGroupSession(roomId, sessionId, senderKey) !=
|
||||||
null,
|
null,
|
||||||
true);
|
true);
|
||||||
expect(
|
expect(
|
||||||
client.encryption.keyManager
|
client.encryption!.keyManager
|
||||||
.getInboundGroupSession(roomId, sessionId, 'invalid') !=
|
.getInboundGroupSession(roomId, sessionId, 'invalid') !=
|
||||||
null,
|
null,
|
||||||
false);
|
false);
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
client.encryption.keyManager
|
client.encryption!.keyManager
|
||||||
.getInboundGroupSession(roomId, sessionId, senderKey) !=
|
.getInboundGroupSession(roomId, sessionId, senderKey) !=
|
||||||
null,
|
null,
|
||||||
true);
|
true);
|
||||||
expect(
|
expect(
|
||||||
client.encryption.keyManager
|
client.encryption!.keyManager
|
||||||
.getInboundGroupSession('otherroom', sessionId, senderKey) !=
|
.getInboundGroupSession('otherroom', sessionId, senderKey) !=
|
||||||
null,
|
null,
|
||||||
true);
|
true);
|
||||||
expect(
|
expect(
|
||||||
client.encryption.keyManager
|
client.encryption!.keyManager
|
||||||
.getInboundGroupSession('otherroom', sessionId, 'invalid') !=
|
.getInboundGroupSession('otherroom', sessionId, 'invalid') !=
|
||||||
null,
|
null,
|
||||||
false);
|
false);
|
||||||
expect(
|
expect(
|
||||||
client.encryption.keyManager
|
client.encryption!.keyManager
|
||||||
.getInboundGroupSession('otherroom', 'invalid', senderKey) !=
|
.getInboundGroupSession('otherroom', 'invalid', senderKey) !=
|
||||||
null,
|
null,
|
||||||
false);
|
false);
|
||||||
|
|
||||||
client.encryption.keyManager.clearInboundGroupSessions();
|
client.encryption!.keyManager.clearInboundGroupSessions();
|
||||||
expect(
|
expect(
|
||||||
client.encryption.keyManager
|
client.encryption!.keyManager
|
||||||
.getInboundGroupSession(roomId, sessionId, senderKey) !=
|
.getInboundGroupSession(roomId, sessionId, senderKey) !=
|
||||||
null,
|
null,
|
||||||
false);
|
false);
|
||||||
await client.encryption.keyManager
|
await client.encryption!.keyManager
|
||||||
.loadInboundGroupSession(roomId, sessionId, senderKey);
|
.loadInboundGroupSession(roomId, sessionId, senderKey);
|
||||||
expect(
|
expect(
|
||||||
client.encryption.keyManager
|
client.encryption!.keyManager
|
||||||
.getInboundGroupSession(roomId, sessionId, senderKey) !=
|
.getInboundGroupSession(roomId, sessionId, senderKey) !=
|
||||||
null,
|
null,
|
||||||
true);
|
true);
|
||||||
|
|
||||||
client.encryption.keyManager.clearInboundGroupSessions();
|
client.encryption!.keyManager.clearInboundGroupSessions();
|
||||||
expect(
|
expect(
|
||||||
client.encryption.keyManager
|
client.encryption!.keyManager
|
||||||
.getInboundGroupSession(roomId, sessionId, senderKey) !=
|
.getInboundGroupSession(roomId, sessionId, senderKey) !=
|
||||||
null,
|
null,
|
||||||
false);
|
false);
|
||||||
await client.encryption.keyManager
|
await client.encryption!.keyManager
|
||||||
.loadInboundGroupSession(roomId, sessionId, 'invalid');
|
.loadInboundGroupSession(roomId, sessionId, 'invalid');
|
||||||
expect(
|
expect(
|
||||||
client.encryption.keyManager
|
client.encryption!.keyManager
|
||||||
.getInboundGroupSession(roomId, sessionId, 'invalid') !=
|
.getInboundGroupSession(roomId, sessionId, 'invalid') !=
|
||||||
null,
|
null,
|
||||||
false);
|
false);
|
||||||
|
|
@ -379,7 +385,7 @@ void main() {
|
||||||
stateKey: '',
|
stateKey: '',
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
expect(room.lastEvent.type, 'm.room.encrypted');
|
expect(room.lastEvent?.type, 'm.room.encrypted');
|
||||||
// set a payload...
|
// set a payload...
|
||||||
var sessionPayload = <String, dynamic>{
|
var sessionPayload = <String, dynamic>{
|
||||||
'algorithm': AlgorithmTypes.megolmV1AesSha2,
|
'algorithm': AlgorithmTypes.megolmV1AesSha2,
|
||||||
|
|
@ -390,20 +396,20 @@ void main() {
|
||||||
'sender_key': senderKey,
|
'sender_key': senderKey,
|
||||||
'sender_claimed_ed25519_key': client.fingerprintKey,
|
'sender_claimed_ed25519_key': client.fingerprintKey,
|
||||||
};
|
};
|
||||||
client.encryption.keyManager.setInboundGroupSession(
|
client.encryption!.keyManager.setInboundGroupSession(
|
||||||
roomId, sessionId, senderKey, sessionPayload,
|
roomId, sessionId, senderKey, sessionPayload,
|
||||||
forwarded: true);
|
forwarded: true);
|
||||||
expect(
|
expect(
|
||||||
client.encryption.keyManager
|
client.encryption!.keyManager
|
||||||
.getInboundGroupSession(roomId, sessionId, senderKey)
|
.getInboundGroupSession(roomId, sessionId, senderKey)
|
||||||
.inboundGroupSession
|
?.inboundGroupSession
|
||||||
.first_known_index(),
|
?.first_known_index(),
|
||||||
1);
|
1);
|
||||||
expect(
|
expect(
|
||||||
client.encryption.keyManager
|
client.encryption!.keyManager
|
||||||
.getInboundGroupSession(roomId, sessionId, senderKey)
|
.getInboundGroupSession(roomId, sessionId, senderKey)
|
||||||
.forwardingCurve25519KeyChain
|
?.forwardingCurve25519KeyChain
|
||||||
.length,
|
?.length,
|
||||||
1);
|
1);
|
||||||
|
|
||||||
// not set one with a higher first known index
|
// not set one with a higher first known index
|
||||||
|
|
@ -416,20 +422,20 @@ void main() {
|
||||||
'sender_key': senderKey,
|
'sender_key': senderKey,
|
||||||
'sender_claimed_ed25519_key': client.fingerprintKey,
|
'sender_claimed_ed25519_key': client.fingerprintKey,
|
||||||
};
|
};
|
||||||
client.encryption.keyManager.setInboundGroupSession(
|
client.encryption!.keyManager.setInboundGroupSession(
|
||||||
roomId, sessionId, senderKey, sessionPayload,
|
roomId, sessionId, senderKey, sessionPayload,
|
||||||
forwarded: true);
|
forwarded: true);
|
||||||
expect(
|
expect(
|
||||||
client.encryption.keyManager
|
client.encryption!.keyManager
|
||||||
.getInboundGroupSession(roomId, sessionId, senderKey)
|
.getInboundGroupSession(roomId, sessionId, senderKey)
|
||||||
.inboundGroupSession
|
?.inboundGroupSession
|
||||||
.first_known_index(),
|
?.first_known_index(),
|
||||||
1);
|
1);
|
||||||
expect(
|
expect(
|
||||||
client.encryption.keyManager
|
client.encryption!.keyManager
|
||||||
.getInboundGroupSession(roomId, sessionId, senderKey)
|
.getInboundGroupSession(roomId, sessionId, senderKey)
|
||||||
.forwardingCurve25519KeyChain
|
?.forwardingCurve25519KeyChain
|
||||||
.length,
|
?.length,
|
||||||
1);
|
1);
|
||||||
|
|
||||||
// set one with a lower first known index
|
// set one with a lower first known index
|
||||||
|
|
@ -442,20 +448,20 @@ void main() {
|
||||||
'sender_key': senderKey,
|
'sender_key': senderKey,
|
||||||
'sender_claimed_ed25519_key': client.fingerprintKey,
|
'sender_claimed_ed25519_key': client.fingerprintKey,
|
||||||
};
|
};
|
||||||
client.encryption.keyManager.setInboundGroupSession(
|
client.encryption!.keyManager.setInboundGroupSession(
|
||||||
roomId, sessionId, senderKey, sessionPayload,
|
roomId, sessionId, senderKey, sessionPayload,
|
||||||
forwarded: true);
|
forwarded: true);
|
||||||
expect(
|
expect(
|
||||||
client.encryption.keyManager
|
client.encryption!.keyManager
|
||||||
.getInboundGroupSession(roomId, sessionId, senderKey)
|
.getInboundGroupSession(roomId, sessionId, senderKey)
|
||||||
.inboundGroupSession
|
?.inboundGroupSession
|
||||||
.first_known_index(),
|
?.first_known_index(),
|
||||||
0);
|
0);
|
||||||
expect(
|
expect(
|
||||||
client.encryption.keyManager
|
client.encryption!.keyManager
|
||||||
.getInboundGroupSession(roomId, sessionId, senderKey)
|
.getInboundGroupSession(roomId, sessionId, senderKey)
|
||||||
.forwardingCurve25519KeyChain
|
?.forwardingCurve25519KeyChain
|
||||||
.length,
|
?.length,
|
||||||
1);
|
1);
|
||||||
|
|
||||||
// not set one with a longer forwarding chain
|
// not set one with a longer forwarding chain
|
||||||
|
|
@ -468,20 +474,20 @@ void main() {
|
||||||
'sender_key': senderKey,
|
'sender_key': senderKey,
|
||||||
'sender_claimed_ed25519_key': client.fingerprintKey,
|
'sender_claimed_ed25519_key': client.fingerprintKey,
|
||||||
};
|
};
|
||||||
client.encryption.keyManager.setInboundGroupSession(
|
client.encryption!.keyManager.setInboundGroupSession(
|
||||||
roomId, sessionId, senderKey, sessionPayload,
|
roomId, sessionId, senderKey, sessionPayload,
|
||||||
forwarded: true);
|
forwarded: true);
|
||||||
expect(
|
expect(
|
||||||
client.encryption.keyManager
|
client.encryption!.keyManager
|
||||||
.getInboundGroupSession(roomId, sessionId, senderKey)
|
.getInboundGroupSession(roomId, sessionId, senderKey)
|
||||||
.inboundGroupSession
|
?.inboundGroupSession
|
||||||
.first_known_index(),
|
?.first_known_index(),
|
||||||
0);
|
0);
|
||||||
expect(
|
expect(
|
||||||
client.encryption.keyManager
|
client.encryption!.keyManager
|
||||||
.getInboundGroupSession(roomId, sessionId, senderKey)
|
.getInboundGroupSession(roomId, sessionId, senderKey)
|
||||||
.forwardingCurve25519KeyChain
|
?.forwardingCurve25519KeyChain
|
||||||
.length,
|
?.length,
|
||||||
1);
|
1);
|
||||||
|
|
||||||
// set one with a shorter forwarding chain
|
// set one with a shorter forwarding chain
|
||||||
|
|
@ -494,25 +500,25 @@ void main() {
|
||||||
'sender_key': senderKey,
|
'sender_key': senderKey,
|
||||||
'sender_claimed_ed25519_key': client.fingerprintKey,
|
'sender_claimed_ed25519_key': client.fingerprintKey,
|
||||||
};
|
};
|
||||||
client.encryption.keyManager.setInboundGroupSession(
|
client.encryption!.keyManager.setInboundGroupSession(
|
||||||
roomId, sessionId, senderKey, sessionPayload,
|
roomId, sessionId, senderKey, sessionPayload,
|
||||||
forwarded: true);
|
forwarded: true);
|
||||||
expect(
|
expect(
|
||||||
client.encryption.keyManager
|
client.encryption!.keyManager
|
||||||
.getInboundGroupSession(roomId, sessionId, senderKey)
|
.getInboundGroupSession(roomId, sessionId, senderKey)
|
||||||
.inboundGroupSession
|
?.inboundGroupSession
|
||||||
.first_known_index(),
|
?.first_known_index(),
|
||||||
0);
|
0);
|
||||||
expect(
|
expect(
|
||||||
client.encryption.keyManager
|
client.encryption!.keyManager
|
||||||
.getInboundGroupSession(roomId, sessionId, senderKey)
|
.getInboundGroupSession(roomId, sessionId, senderKey)
|
||||||
.forwardingCurve25519KeyChain
|
?.forwardingCurve25519KeyChain
|
||||||
.length,
|
?.length,
|
||||||
0);
|
0);
|
||||||
|
|
||||||
// test that it decrypted the last event
|
// test that it decrypted the last event
|
||||||
expect(room.lastEvent.type, 'm.room.message');
|
expect(room.lastEvent?.type, 'm.room.message');
|
||||||
expect(room.lastEvent.content['body'], 'foxies');
|
expect(room.lastEvent?.content['body'], 'foxies');
|
||||||
|
|
||||||
inbound.free();
|
inbound.free();
|
||||||
session.free();
|
session.free();
|
||||||
|
|
@ -521,22 +527,21 @@ void main() {
|
||||||
test('Reused deviceID attack', () async {
|
test('Reused deviceID attack', () async {
|
||||||
if (!olmEnabled) return;
|
if (!olmEnabled) return;
|
||||||
Logs().level = Level.warning;
|
Logs().level = Level.warning;
|
||||||
client ??= await getClient();
|
|
||||||
|
|
||||||
// Ensure the device came from sync
|
// Ensure the device came from sync
|
||||||
expect(
|
expect(
|
||||||
client.userDeviceKeys['@alice:example.com']
|
client.userDeviceKeys['@alice:example.com']
|
||||||
.deviceKeys['JLAFKJWSCS'] !=
|
?.deviceKeys['JLAFKJWSCS'] !=
|
||||||
null,
|
null,
|
||||||
true);
|
true);
|
||||||
|
|
||||||
// Alice removes her device
|
// Alice removes her device
|
||||||
client.userDeviceKeys['@alice:example.com'].deviceKeys
|
client.userDeviceKeys['@alice:example.com']?.deviceKeys
|
||||||
.remove('JLAFKJWSCS');
|
.remove('JLAFKJWSCS');
|
||||||
|
|
||||||
// Alice adds her device with same device ID but different keys
|
// Alice adds her device with same device ID but different keys
|
||||||
final oldResp = FakeMatrixApi.api['POST']['/client/r0/keys/query'](null);
|
final oldResp = FakeMatrixApi.api['POST']?['/client/r0/keys/query'](null);
|
||||||
FakeMatrixApi.api['POST']['/client/r0/keys/query'] = (_) {
|
FakeMatrixApi.api['POST']?['/client/r0/keys/query'] = (_) {
|
||||||
oldResp['device_keys']['@alice:example.com']['JLAFKJWSCS'] = {
|
oldResp['device_keys']['@alice:example.com']['JLAFKJWSCS'] = {
|
||||||
'user_id': '@alice:example.com',
|
'user_id': '@alice:example.com',
|
||||||
'device_id': 'JLAFKJWSCS',
|
'device_id': 'JLAFKJWSCS',
|
||||||
|
|
@ -558,10 +563,10 @@ void main() {
|
||||||
};
|
};
|
||||||
return oldResp;
|
return oldResp;
|
||||||
};
|
};
|
||||||
client.userDeviceKeys['@alice:example.com'].outdated = true;
|
client.userDeviceKeys['@alice:example.com']!.outdated = true;
|
||||||
await client.updateUserDeviceKeys();
|
await client.updateUserDeviceKeys();
|
||||||
expect(
|
expect(
|
||||||
client.userDeviceKeys['@alice:example.com'].deviceKeys['JLAFKJWSCS'],
|
client.userDeviceKeys['@alice:example.com']?.deviceKeys['JLAFKJWSCS'],
|
||||||
null);
|
null);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
// @dart=2.9
|
|
||||||
/*
|
/*
|
||||||
* Famedly Matrix SDK
|
* Famedly Matrix SDK
|
||||||
* Copyright (C) 2020 Famedly GmbH
|
* Copyright (C) 2020 Famedly GmbH
|
||||||
|
|
@ -58,8 +57,8 @@ void main() {
|
||||||
if (!olmEnabled) return;
|
if (!olmEnabled) return;
|
||||||
|
|
||||||
final matrix = await getClient();
|
final matrix = await getClient();
|
||||||
final requestRoom = matrix.getRoomById('!726s6s6q:example.com');
|
final requestRoom = matrix.getRoomById('!726s6s6q:example.com')!;
|
||||||
await matrix.encryption.keyManager.request(
|
await matrix.encryption!.keyManager.request(
|
||||||
requestRoom, 'sessionId', validSenderKey,
|
requestRoom, 'sessionId', validSenderKey,
|
||||||
tryOnlineBackup: false);
|
tryOnlineBackup: false);
|
||||||
var foundEvent = false;
|
var foundEvent = false;
|
||||||
|
|
@ -89,12 +88,12 @@ void main() {
|
||||||
matrix.setUserId('@alice:example.com'); // we need to pretend to be alice
|
matrix.setUserId('@alice:example.com'); // we need to pretend to be alice
|
||||||
FakeMatrixApi.calledEndpoints.clear();
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
await matrix
|
await matrix
|
||||||
.userDeviceKeys['@alice:example.com'].deviceKeys['OTHERDEVICE']
|
.userDeviceKeys['@alice:example.com']!.deviceKeys['OTHERDEVICE']!
|
||||||
.setBlocked(false);
|
.setBlocked(false);
|
||||||
await matrix
|
await matrix
|
||||||
.userDeviceKeys['@alice:example.com'].deviceKeys['OTHERDEVICE']
|
.userDeviceKeys['@alice:example.com']!.deviceKeys['OTHERDEVICE']!
|
||||||
.setVerified(true);
|
.setVerified(true);
|
||||||
final session = await matrix.encryption.keyManager
|
final session = await matrix.encryption!.keyManager
|
||||||
.loadInboundGroupSession(
|
.loadInboundGroupSession(
|
||||||
'!726s6s6q:example.com', validSessionId, validSenderKey);
|
'!726s6s6q:example.com', validSessionId, validSenderKey);
|
||||||
// test a successful share
|
// test a successful share
|
||||||
|
|
@ -112,7 +111,7 @@ void main() {
|
||||||
'request_id': 'request_1',
|
'request_id': 'request_1',
|
||||||
'requesting_device_id': 'OTHERDEVICE',
|
'requesting_device_id': 'OTHERDEVICE',
|
||||||
});
|
});
|
||||||
await matrix.encryption.keyManager.handleToDeviceEvent(event);
|
await matrix.encryption!.keyManager.handleToDeviceEvent(event);
|
||||||
Logs().i(FakeMatrixApi.calledEndpoints.keys.toString());
|
Logs().i(FakeMatrixApi.calledEndpoints.keys.toString());
|
||||||
expect(
|
expect(
|
||||||
FakeMatrixApi.calledEndpoints.keys.any(
|
FakeMatrixApi.calledEndpoints.keys.any(
|
||||||
|
|
@ -121,9 +120,9 @@ void main() {
|
||||||
|
|
||||||
// test a successful foreign share
|
// test a successful foreign share
|
||||||
FakeMatrixApi.calledEndpoints.clear();
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
session.allowedAtIndex['@test:fakeServer.notExisting'] = <String, int>{
|
session!.allowedAtIndex['@test:fakeServer.notExisting'] = <String, int>{
|
||||||
matrix.userDeviceKeys['@test:fakeServer.notExisting']
|
matrix.userDeviceKeys['@test:fakeServer.notExisting']!
|
||||||
.deviceKeys['OTHERDEVICE'].curve25519Key: 0,
|
.deviceKeys['OTHERDEVICE']!.curve25519Key!: 0,
|
||||||
};
|
};
|
||||||
event = ToDeviceEvent(
|
event = ToDeviceEvent(
|
||||||
sender: '@test:fakeServer.notExisting',
|
sender: '@test:fakeServer.notExisting',
|
||||||
|
|
@ -139,7 +138,7 @@ void main() {
|
||||||
'request_id': 'request_a1',
|
'request_id': 'request_a1',
|
||||||
'requesting_device_id': 'OTHERDEVICE',
|
'requesting_device_id': 'OTHERDEVICE',
|
||||||
});
|
});
|
||||||
await matrix.encryption.keyManager.handleToDeviceEvent(event);
|
await matrix.encryption!.keyManager.handleToDeviceEvent(event);
|
||||||
Logs().i(FakeMatrixApi.calledEndpoints.keys.toString());
|
Logs().i(FakeMatrixApi.calledEndpoints.keys.toString());
|
||||||
expect(
|
expect(
|
||||||
FakeMatrixApi.calledEndpoints.keys.any(
|
FakeMatrixApi.calledEndpoints.keys.any(
|
||||||
|
|
@ -165,7 +164,7 @@ void main() {
|
||||||
'request_id': 'request_a2',
|
'request_id': 'request_a2',
|
||||||
'requesting_device_id': 'OTHERDEVICE',
|
'requesting_device_id': 'OTHERDEVICE',
|
||||||
});
|
});
|
||||||
await matrix.encryption.keyManager.handleToDeviceEvent(event);
|
await matrix.encryption!.keyManager.handleToDeviceEvent(event);
|
||||||
Logs().i(FakeMatrixApi.calledEndpoints.keys.toString());
|
Logs().i(FakeMatrixApi.calledEndpoints.keys.toString());
|
||||||
expect(
|
expect(
|
||||||
FakeMatrixApi.calledEndpoints.keys.any(
|
FakeMatrixApi.calledEndpoints.keys.any(
|
||||||
|
|
@ -182,7 +181,7 @@ void main() {
|
||||||
'request_id': 'request_2',
|
'request_id': 'request_2',
|
||||||
'requesting_device_id': 'OTHERDEVICE',
|
'requesting_device_id': 'OTHERDEVICE',
|
||||||
});
|
});
|
||||||
await matrix.encryption.keyManager.handleToDeviceEvent(event);
|
await matrix.encryption!.keyManager.handleToDeviceEvent(event);
|
||||||
expect(
|
expect(
|
||||||
FakeMatrixApi.calledEndpoints.keys.any(
|
FakeMatrixApi.calledEndpoints.keys.any(
|
||||||
(k) => k.startsWith('/client/r0/sendToDevice/m.room.encrypted')),
|
(k) => k.startsWith('/client/r0/sendToDevice/m.room.encrypted')),
|
||||||
|
|
@ -204,7 +203,7 @@ void main() {
|
||||||
'request_id': 'request_3',
|
'request_id': 'request_3',
|
||||||
'requesting_device_id': 'JLAFKJWSCS',
|
'requesting_device_id': 'JLAFKJWSCS',
|
||||||
});
|
});
|
||||||
await matrix.encryption.keyManager.handleToDeviceEvent(event);
|
await matrix.encryption!.keyManager.handleToDeviceEvent(event);
|
||||||
expect(
|
expect(
|
||||||
FakeMatrixApi.calledEndpoints.keys.any(
|
FakeMatrixApi.calledEndpoints.keys.any(
|
||||||
(k) => k.startsWith('/client/r0/sendToDevice/m.room.encrypted')),
|
(k) => k.startsWith('/client/r0/sendToDevice/m.room.encrypted')),
|
||||||
|
|
@ -226,7 +225,7 @@ void main() {
|
||||||
'request_id': 'request_4',
|
'request_id': 'request_4',
|
||||||
'requesting_device_id': 'blubb',
|
'requesting_device_id': 'blubb',
|
||||||
});
|
});
|
||||||
await matrix.encryption.keyManager.handleToDeviceEvent(event);
|
await matrix.encryption!.keyManager.handleToDeviceEvent(event);
|
||||||
expect(
|
expect(
|
||||||
FakeMatrixApi.calledEndpoints.keys.any(
|
FakeMatrixApi.calledEndpoints.keys.any(
|
||||||
(k) => k.startsWith('/client/r0/sendToDevice/m.room.encrypted')),
|
(k) => k.startsWith('/client/r0/sendToDevice/m.room.encrypted')),
|
||||||
|
|
@ -248,7 +247,7 @@ void main() {
|
||||||
'request_id': 'request_5',
|
'request_id': 'request_5',
|
||||||
'requesting_device_id': 'OTHERDEVICE',
|
'requesting_device_id': 'OTHERDEVICE',
|
||||||
});
|
});
|
||||||
await matrix.encryption.keyManager.handleToDeviceEvent(event);
|
await matrix.encryption!.keyManager.handleToDeviceEvent(event);
|
||||||
expect(
|
expect(
|
||||||
FakeMatrixApi.calledEndpoints.keys.any(
|
FakeMatrixApi.calledEndpoints.keys.any(
|
||||||
(k) => k.startsWith('/client/r0/sendToDevice/m.room.encrypted')),
|
(k) => k.startsWith('/client/r0/sendToDevice/m.room.encrypted')),
|
||||||
|
|
@ -270,7 +269,7 @@ void main() {
|
||||||
'request_id': 'request_6',
|
'request_id': 'request_6',
|
||||||
'requesting_device_id': 'OTHERDEVICE',
|
'requesting_device_id': 'OTHERDEVICE',
|
||||||
});
|
});
|
||||||
await matrix.encryption.keyManager.handleToDeviceEvent(event);
|
await matrix.encryption!.keyManager.handleToDeviceEvent(event);
|
||||||
expect(
|
expect(
|
||||||
FakeMatrixApi.calledEndpoints.keys.any(
|
FakeMatrixApi.calledEndpoints.keys.any(
|
||||||
(k) => k.startsWith('/client/r0/sendToDevice/m.room.encrypted')),
|
(k) => k.startsWith('/client/r0/sendToDevice/m.room.encrypted')),
|
||||||
|
|
@ -282,17 +281,17 @@ void main() {
|
||||||
test('Receive shared keys', () async {
|
test('Receive shared keys', () async {
|
||||||
if (!olmEnabled) return;
|
if (!olmEnabled) return;
|
||||||
final matrix = await getClient();
|
final matrix = await getClient();
|
||||||
final requestRoom = matrix.getRoomById('!726s6s6q:example.com');
|
final requestRoom = matrix.getRoomById('!726s6s6q:example.com')!;
|
||||||
await matrix.encryption.keyManager.request(
|
await matrix.encryption!.keyManager.request(
|
||||||
requestRoom, validSessionId, validSenderKey,
|
requestRoom, validSessionId, validSenderKey,
|
||||||
tryOnlineBackup: false);
|
tryOnlineBackup: false);
|
||||||
|
|
||||||
final session = await matrix.encryption.keyManager
|
final session = (await matrix.encryption!.keyManager
|
||||||
.loadInboundGroupSession(
|
.loadInboundGroupSession(
|
||||||
requestRoom.id, validSessionId, validSenderKey);
|
requestRoom.id, validSessionId, validSenderKey))!;
|
||||||
final sessionKey = session.inboundGroupSession
|
final sessionKey = session.inboundGroupSession!
|
||||||
.export_session(session.inboundGroupSession.first_known_index());
|
.export_session(session.inboundGroupSession!.first_known_index());
|
||||||
matrix.encryption.keyManager.clearInboundGroupSessions();
|
matrix.encryption!.keyManager.clearInboundGroupSessions();
|
||||||
var event = ToDeviceEvent(
|
var event = ToDeviceEvent(
|
||||||
sender: '@alice:example.com',
|
sender: '@alice:example.com',
|
||||||
type: 'm.forwarded_room_key',
|
type: 'm.forwarded_room_key',
|
||||||
|
|
@ -303,13 +302,15 @@ void main() {
|
||||||
'session_key': sessionKey,
|
'session_key': sessionKey,
|
||||||
'sender_key': validSenderKey,
|
'sender_key': validSenderKey,
|
||||||
'forwarding_curve25519_key_chain': [],
|
'forwarding_curve25519_key_chain': [],
|
||||||
|
'sender_claimed_ed25519_key':
|
||||||
|
'L+4+JCl8MD63dgo8z5Ta+9QAHXiANyOVSfgbHA5d3H8',
|
||||||
},
|
},
|
||||||
encryptedContent: {
|
encryptedContent: {
|
||||||
'sender_key': 'L+4+JCl8MD63dgo8z5Ta+9QAHXiANyOVSfgbHA5d3H8',
|
'sender_key': 'L+4+JCl8MD63dgo8z5Ta+9QAHXiANyOVSfgbHA5d3H8',
|
||||||
});
|
});
|
||||||
await matrix.encryption.keyManager.handleToDeviceEvent(event);
|
await matrix.encryption!.keyManager.handleToDeviceEvent(event);
|
||||||
expect(
|
expect(
|
||||||
matrix.encryption.keyManager.getInboundGroupSession(
|
matrix.encryption!.keyManager.getInboundGroupSession(
|
||||||
requestRoom.id, validSessionId, validSenderKey) !=
|
requestRoom.id, validSessionId, validSenderKey) !=
|
||||||
null,
|
null,
|
||||||
true);
|
true);
|
||||||
|
|
@ -317,7 +318,7 @@ void main() {
|
||||||
// now test a few invalid scenarios
|
// now test a few invalid scenarios
|
||||||
|
|
||||||
// request not found
|
// request not found
|
||||||
matrix.encryption.keyManager.clearInboundGroupSessions();
|
matrix.encryption!.keyManager.clearInboundGroupSessions();
|
||||||
event = ToDeviceEvent(
|
event = ToDeviceEvent(
|
||||||
sender: '@alice:example.com',
|
sender: '@alice:example.com',
|
||||||
type: 'm.forwarded_room_key',
|
type: 'm.forwarded_room_key',
|
||||||
|
|
@ -328,22 +329,24 @@ void main() {
|
||||||
'session_key': sessionKey,
|
'session_key': sessionKey,
|
||||||
'sender_key': validSenderKey,
|
'sender_key': validSenderKey,
|
||||||
'forwarding_curve25519_key_chain': [],
|
'forwarding_curve25519_key_chain': [],
|
||||||
|
'sender_claimed_ed25519_key':
|
||||||
|
'L+4+JCl8MD63dgo8z5Ta+9QAHXiANyOVSfgbHA5d3H8',
|
||||||
},
|
},
|
||||||
encryptedContent: {
|
encryptedContent: {
|
||||||
'sender_key': 'L+4+JCl8MD63dgo8z5Ta+9QAHXiANyOVSfgbHA5d3H8',
|
'sender_key': 'L+4+JCl8MD63dgo8z5Ta+9QAHXiANyOVSfgbHA5d3H8',
|
||||||
});
|
});
|
||||||
await matrix.encryption.keyManager.handleToDeviceEvent(event);
|
await matrix.encryption!.keyManager.handleToDeviceEvent(event);
|
||||||
expect(
|
expect(
|
||||||
matrix.encryption.keyManager.getInboundGroupSession(
|
matrix.encryption!.keyManager.getInboundGroupSession(
|
||||||
requestRoom.id, validSessionId, validSenderKey) !=
|
requestRoom.id, validSessionId, validSenderKey) !=
|
||||||
null,
|
null,
|
||||||
false);
|
false);
|
||||||
|
|
||||||
// unknown device
|
// unknown device
|
||||||
await matrix.encryption.keyManager.request(
|
await matrix.encryption!.keyManager.request(
|
||||||
requestRoom, validSessionId, validSenderKey,
|
requestRoom, validSessionId, validSenderKey,
|
||||||
tryOnlineBackup: false);
|
tryOnlineBackup: false);
|
||||||
matrix.encryption.keyManager.clearInboundGroupSessions();
|
matrix.encryption!.keyManager.clearInboundGroupSessions();
|
||||||
event = ToDeviceEvent(
|
event = ToDeviceEvent(
|
||||||
sender: '@alice:example.com',
|
sender: '@alice:example.com',
|
||||||
type: 'm.forwarded_room_key',
|
type: 'm.forwarded_room_key',
|
||||||
|
|
@ -354,22 +357,24 @@ void main() {
|
||||||
'session_key': sessionKey,
|
'session_key': sessionKey,
|
||||||
'sender_key': validSenderKey,
|
'sender_key': validSenderKey,
|
||||||
'forwarding_curve25519_key_chain': [],
|
'forwarding_curve25519_key_chain': [],
|
||||||
|
'sender_claimed_ed25519_key':
|
||||||
|
'L+4+JCl8MD63dgo8z5Ta+9QAHXiANyOVSfgbHA5d3H8',
|
||||||
},
|
},
|
||||||
encryptedContent: {
|
encryptedContent: {
|
||||||
'sender_key': 'invalid',
|
'sender_key': 'invalid',
|
||||||
});
|
});
|
||||||
await matrix.encryption.keyManager.handleToDeviceEvent(event);
|
await matrix.encryption!.keyManager.handleToDeviceEvent(event);
|
||||||
expect(
|
expect(
|
||||||
matrix.encryption.keyManager.getInboundGroupSession(
|
matrix.encryption!.keyManager.getInboundGroupSession(
|
||||||
requestRoom.id, validSessionId, validSenderKey) !=
|
requestRoom.id, validSessionId, validSenderKey) !=
|
||||||
null,
|
null,
|
||||||
false);
|
false);
|
||||||
|
|
||||||
// no encrypted content
|
// no encrypted content
|
||||||
await matrix.encryption.keyManager.request(
|
await matrix.encryption!.keyManager.request(
|
||||||
requestRoom, validSessionId, validSenderKey,
|
requestRoom, validSessionId, validSenderKey,
|
||||||
tryOnlineBackup: false);
|
tryOnlineBackup: false);
|
||||||
matrix.encryption.keyManager.clearInboundGroupSessions();
|
matrix.encryption!.keyManager.clearInboundGroupSessions();
|
||||||
event = ToDeviceEvent(
|
event = ToDeviceEvent(
|
||||||
sender: '@alice:example.com',
|
sender: '@alice:example.com',
|
||||||
type: 'm.forwarded_room_key',
|
type: 'm.forwarded_room_key',
|
||||||
|
|
@ -380,10 +385,12 @@ void main() {
|
||||||
'session_key': sessionKey,
|
'session_key': sessionKey,
|
||||||
'sender_key': validSenderKey,
|
'sender_key': validSenderKey,
|
||||||
'forwarding_curve25519_key_chain': [],
|
'forwarding_curve25519_key_chain': [],
|
||||||
|
'sender_claimed_ed25519_key':
|
||||||
|
'L+4+JCl8MD63dgo8z5Ta+9QAHXiANyOVSfgbHA5d3H8',
|
||||||
});
|
});
|
||||||
await matrix.encryption.keyManager.handleToDeviceEvent(event);
|
await matrix.encryption!.keyManager.handleToDeviceEvent(event);
|
||||||
expect(
|
expect(
|
||||||
matrix.encryption.keyManager.getInboundGroupSession(
|
matrix.encryption!.keyManager.getInboundGroupSession(
|
||||||
requestRoom.id, validSessionId, validSenderKey) !=
|
requestRoom.id, validSessionId, validSenderKey) !=
|
||||||
null,
|
null,
|
||||||
false);
|
false);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
// @dart=2.9
|
|
||||||
/*
|
/*
|
||||||
* Famedly Matrix SDK
|
* Famedly Matrix SDK
|
||||||
* Copyright (C) 2020 Famedly GmbH
|
* Copyright (C) 2020 Famedly GmbH
|
||||||
|
|
@ -34,7 +33,7 @@ class MockSSSS extends SSSS {
|
||||||
|
|
||||||
bool requestedSecrets = false;
|
bool requestedSecrets = false;
|
||||||
@override
|
@override
|
||||||
Future<void> maybeRequestAll([List<DeviceKeys> devices]) async {
|
Future<void> maybeRequestAll([List<DeviceKeys>? devices]) async {
|
||||||
requestedSecrets = true;
|
requestedSecrets = true;
|
||||||
final handle = open();
|
final handle = open();
|
||||||
await handle.unlock(recoveryKey: ssssKey);
|
await handle.unlock(recoveryKey: ssssKey);
|
||||||
|
|
@ -56,7 +55,7 @@ EventUpdate getLastSentEvent(KeyVerification req) {
|
||||||
'sender': req.client.userID,
|
'sender': req.client.userID,
|
||||||
},
|
},
|
||||||
type: EventUpdateType.timeline,
|
type: EventUpdateType.timeline,
|
||||||
roomID: req.room.id,
|
roomID: req.room!.id,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -70,8 +69,8 @@ void main() {
|
||||||
const otherPickledOlmAccount =
|
const otherPickledOlmAccount =
|
||||||
'VWhVApbkcilKAEGppsPDf9nNVjaK8/IxT3asSR0sYg0S5KgbfE8vXEPwoiKBX2cEvwX3OessOBOkk+ZE7TTbjlrh/KEd31p8Wo+47qj0AP+Ky+pabnhi+/rTBvZy+gfzTqUfCxZrkzfXI9Op4JnP6gYmy7dVX2lMYIIs9WCO1jcmIXiXum5jnfXu1WLfc7PZtO2hH+k9CDKosOFaXRBmsu8k/BGXPSoWqUpvu6WpEG9t5STk4FeAzA';
|
'VWhVApbkcilKAEGppsPDf9nNVjaK8/IxT3asSR0sYg0S5KgbfE8vXEPwoiKBX2cEvwX3OessOBOkk+ZE7TTbjlrh/KEd31p8Wo+47qj0AP+Ky+pabnhi+/rTBvZy+gfzTqUfCxZrkzfXI9Op4JnP6gYmy7dVX2lMYIIs9WCO1jcmIXiXum5jnfXu1WLfc7PZtO2hH+k9CDKosOFaXRBmsu8k/BGXPSoWqUpvu6WpEG9t5STk4FeAzA';
|
||||||
|
|
||||||
Client client1;
|
late Client client1;
|
||||||
Client client2;
|
late Client client2;
|
||||||
|
|
||||||
test('setupClient', () async {
|
test('setupClient', () async {
|
||||||
try {
|
try {
|
||||||
|
|
@ -117,24 +116,25 @@ void main() {
|
||||||
// because then we can easily intercept the payloads and inject in the other client
|
// because then we can easily intercept the payloads and inject in the other client
|
||||||
FakeMatrixApi.calledEndpoints.clear();
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
// make sure our master key is *not* verified to not triger SSSS for now
|
// make sure our master key is *not* verified to not triger SSSS for now
|
||||||
client1.userDeviceKeys[client1.userID].masterKey.setDirectVerified(false);
|
client1.userDeviceKeys[client1.userID]!.masterKey!
|
||||||
|
.setDirectVerified(false);
|
||||||
final req1 =
|
final req1 =
|
||||||
await client1.userDeviceKeys[client2.userID].startVerification();
|
await client1.userDeviceKeys[client2.userID]!.startVerification();
|
||||||
var evt = getLastSentEvent(req1);
|
var evt = getLastSentEvent(req1);
|
||||||
expect(req1.state, KeyVerificationState.waitingAccept);
|
expect(req1.state, KeyVerificationState.waitingAccept);
|
||||||
|
|
||||||
KeyVerification req2;
|
late KeyVerification req2;
|
||||||
final sub = client2.onKeyVerificationRequest.stream.listen((req) {
|
final sub = client2.onKeyVerificationRequest.stream.listen((req) {
|
||||||
req2 = req;
|
req2 = req;
|
||||||
});
|
});
|
||||||
await client2.encryption.keyVerificationManager.handleEventUpdate(evt);
|
await client2.encryption!.keyVerificationManager.handleEventUpdate(evt);
|
||||||
await Future.delayed(Duration(milliseconds: 10));
|
await Future.delayed(Duration(milliseconds: 10));
|
||||||
await sub.cancel();
|
await sub.cancel();
|
||||||
expect(req2 != null, true);
|
expect(req2 != null, true);
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
client2.encryption.keyVerificationManager
|
client2.encryption!.keyVerificationManager
|
||||||
.getRequest(req2.transactionId),
|
.getRequest(req2.transactionId!),
|
||||||
req2);
|
req2);
|
||||||
|
|
||||||
// send ready
|
// send ready
|
||||||
|
|
@ -145,27 +145,27 @@ void main() {
|
||||||
|
|
||||||
// send start
|
// send start
|
||||||
FakeMatrixApi.calledEndpoints.clear();
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
await client1.encryption.keyVerificationManager.handleEventUpdate(evt);
|
await client1.encryption!.keyVerificationManager.handleEventUpdate(evt);
|
||||||
evt = getLastSentEvent(req1);
|
evt = getLastSentEvent(req1);
|
||||||
|
|
||||||
// send accept
|
// send accept
|
||||||
FakeMatrixApi.calledEndpoints.clear();
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
await client2.encryption.keyVerificationManager.handleEventUpdate(evt);
|
await client2.encryption!.keyVerificationManager.handleEventUpdate(evt);
|
||||||
evt = getLastSentEvent(req2);
|
evt = getLastSentEvent(req2);
|
||||||
|
|
||||||
// send key
|
// send key
|
||||||
FakeMatrixApi.calledEndpoints.clear();
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
await client1.encryption.keyVerificationManager.handleEventUpdate(evt);
|
await client1.encryption!.keyVerificationManager.handleEventUpdate(evt);
|
||||||
evt = getLastSentEvent(req1);
|
evt = getLastSentEvent(req1);
|
||||||
|
|
||||||
// send key
|
// send key
|
||||||
FakeMatrixApi.calledEndpoints.clear();
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
await client2.encryption.keyVerificationManager.handleEventUpdate(evt);
|
await client2.encryption!.keyVerificationManager.handleEventUpdate(evt);
|
||||||
evt = getLastSentEvent(req2);
|
evt = getLastSentEvent(req2);
|
||||||
|
|
||||||
// receive last key
|
// receive last key
|
||||||
FakeMatrixApi.calledEndpoints.clear();
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
await client1.encryption.keyVerificationManager.handleEventUpdate(evt);
|
await client1.encryption!.keyVerificationManager.handleEventUpdate(evt);
|
||||||
|
|
||||||
// compare emoji
|
// compare emoji
|
||||||
expect(req1.state, KeyVerificationState.askSas);
|
expect(req1.state, KeyVerificationState.askSas);
|
||||||
|
|
@ -194,61 +194,64 @@ void main() {
|
||||||
FakeMatrixApi.calledEndpoints.clear();
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
await req1.acceptSas();
|
await req1.acceptSas();
|
||||||
evt = getLastSentEvent(req1);
|
evt = getLastSentEvent(req1);
|
||||||
await client2.encryption.keyVerificationManager.handleEventUpdate(evt);
|
await client2.encryption!.keyVerificationManager.handleEventUpdate(evt);
|
||||||
expect(req1.state, KeyVerificationState.waitingSas);
|
expect(req1.state, KeyVerificationState.waitingSas);
|
||||||
|
|
||||||
// send mac
|
// send mac
|
||||||
FakeMatrixApi.calledEndpoints.clear();
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
await req2.acceptSas();
|
await req2.acceptSas();
|
||||||
evt = getLastSentEvent(req2);
|
evt = getLastSentEvent(req2);
|
||||||
await client1.encryption.keyVerificationManager.handleEventUpdate(evt);
|
await client1.encryption!.keyVerificationManager.handleEventUpdate(evt);
|
||||||
|
|
||||||
expect(req1.state, KeyVerificationState.done);
|
expect(req1.state, KeyVerificationState.done);
|
||||||
expect(req2.state, KeyVerificationState.done);
|
expect(req2.state, KeyVerificationState.done);
|
||||||
expect(
|
expect(
|
||||||
client1.userDeviceKeys[client2.userID].deviceKeys[client2.deviceID]
|
client1.userDeviceKeys[client2.userID]?.deviceKeys[client2.deviceID]
|
||||||
.directVerified,
|
?.directVerified,
|
||||||
true);
|
true);
|
||||||
expect(
|
expect(
|
||||||
client2.userDeviceKeys[client1.userID].deviceKeys[client1.deviceID]
|
client2.userDeviceKeys[client1.userID]?.deviceKeys[client1.deviceID]
|
||||||
.directVerified,
|
?.directVerified,
|
||||||
true);
|
true);
|
||||||
await client1.encryption.keyVerificationManager.cleanup();
|
await client1.encryption!.keyVerificationManager.cleanup();
|
||||||
await client2.encryption.keyVerificationManager.cleanup();
|
await client2.encryption!.keyVerificationManager.cleanup();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('ask SSSS start', () async {
|
test('ask SSSS start', () async {
|
||||||
if (!olmEnabled) return;
|
if (!olmEnabled) return;
|
||||||
client1.userDeviceKeys[client1.userID].masterKey.setDirectVerified(true);
|
client1.userDeviceKeys[client1.userID]!.masterKey!
|
||||||
await client1.encryption.ssss.clearCache();
|
.setDirectVerified(true);
|
||||||
|
await client1.encryption!.ssss.clearCache();
|
||||||
final req1 =
|
final req1 =
|
||||||
await client1.userDeviceKeys[client2.userID].startVerification();
|
await client1.userDeviceKeys[client2.userID]!.startVerification();
|
||||||
expect(req1.state, KeyVerificationState.askSSSS);
|
expect(req1.state, KeyVerificationState.askSSSS);
|
||||||
await req1.openSSSS(recoveryKey: ssssKey);
|
await req1.openSSSS(recoveryKey: ssssKey);
|
||||||
await Future.delayed(Duration(seconds: 1));
|
await Future.delayed(Duration(seconds: 1));
|
||||||
expect(req1.state, KeyVerificationState.waitingAccept);
|
expect(req1.state, KeyVerificationState.waitingAccept);
|
||||||
|
|
||||||
await req1.cancel();
|
await req1.cancel();
|
||||||
await client1.encryption.keyVerificationManager.cleanup();
|
await client1.encryption!.keyVerificationManager.cleanup();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('ask SSSS end', () async {
|
test('ask SSSS end', () async {
|
||||||
if (!olmEnabled) return;
|
if (!olmEnabled) return;
|
||||||
FakeMatrixApi.calledEndpoints.clear();
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
// make sure our master key is *not* verified to not triger SSSS for now
|
// make sure our master key is *not* verified to not triger SSSS for now
|
||||||
client1.userDeviceKeys[client1.userID].masterKey.setDirectVerified(false);
|
client1.userDeviceKeys[client1.userID]!.masterKey!
|
||||||
|
.setDirectVerified(false);
|
||||||
// the other one has to have their master key verified to trigger asking for ssss
|
// the other one has to have their master key verified to trigger asking for ssss
|
||||||
client2.userDeviceKeys[client2.userID].masterKey.setDirectVerified(true);
|
client2.userDeviceKeys[client2.userID]!.masterKey!
|
||||||
|
.setDirectVerified(true);
|
||||||
final req1 =
|
final req1 =
|
||||||
await client1.userDeviceKeys[client2.userID].startVerification();
|
await client1.userDeviceKeys[client2.userID]!.startVerification();
|
||||||
var evt = getLastSentEvent(req1);
|
var evt = getLastSentEvent(req1);
|
||||||
expect(req1.state, KeyVerificationState.waitingAccept);
|
expect(req1.state, KeyVerificationState.waitingAccept);
|
||||||
|
|
||||||
KeyVerification req2;
|
late KeyVerification req2;
|
||||||
final sub = client2.onKeyVerificationRequest.stream.listen((req) {
|
final sub = client2.onKeyVerificationRequest.stream.listen((req) {
|
||||||
req2 = req;
|
req2 = req;
|
||||||
});
|
});
|
||||||
await client2.encryption.keyVerificationManager.handleEventUpdate(evt);
|
await client2.encryption!.keyVerificationManager.handleEventUpdate(evt);
|
||||||
await Future.delayed(Duration(milliseconds: 10));
|
await Future.delayed(Duration(milliseconds: 10));
|
||||||
await sub.cancel();
|
await sub.cancel();
|
||||||
expect(req2 != null, true);
|
expect(req2 != null, true);
|
||||||
|
|
@ -261,27 +264,27 @@ void main() {
|
||||||
|
|
||||||
// send start
|
// send start
|
||||||
FakeMatrixApi.calledEndpoints.clear();
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
await client1.encryption.keyVerificationManager.handleEventUpdate(evt);
|
await client1.encryption!.keyVerificationManager.handleEventUpdate(evt);
|
||||||
evt = getLastSentEvent(req1);
|
evt = getLastSentEvent(req1);
|
||||||
|
|
||||||
// send accept
|
// send accept
|
||||||
FakeMatrixApi.calledEndpoints.clear();
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
await client2.encryption.keyVerificationManager.handleEventUpdate(evt);
|
await client2.encryption!.keyVerificationManager.handleEventUpdate(evt);
|
||||||
evt = getLastSentEvent(req2);
|
evt = getLastSentEvent(req2);
|
||||||
|
|
||||||
// send key
|
// send key
|
||||||
FakeMatrixApi.calledEndpoints.clear();
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
await client1.encryption.keyVerificationManager.handleEventUpdate(evt);
|
await client1.encryption!.keyVerificationManager.handleEventUpdate(evt);
|
||||||
evt = getLastSentEvent(req1);
|
evt = getLastSentEvent(req1);
|
||||||
|
|
||||||
// send key
|
// send key
|
||||||
FakeMatrixApi.calledEndpoints.clear();
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
await client2.encryption.keyVerificationManager.handleEventUpdate(evt);
|
await client2.encryption!.keyVerificationManager.handleEventUpdate(evt);
|
||||||
evt = getLastSentEvent(req2);
|
evt = getLastSentEvent(req2);
|
||||||
|
|
||||||
// receive last key
|
// receive last key
|
||||||
FakeMatrixApi.calledEndpoints.clear();
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
await client1.encryption.keyVerificationManager.handleEventUpdate(evt);
|
await client1.encryption!.keyVerificationManager.handleEventUpdate(evt);
|
||||||
|
|
||||||
// compare emoji
|
// compare emoji
|
||||||
expect(req1.state, KeyVerificationState.askSas);
|
expect(req1.state, KeyVerificationState.askSas);
|
||||||
|
|
@ -301,21 +304,22 @@ void main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// alright, they match
|
// alright, they match
|
||||||
client1.userDeviceKeys[client1.userID].masterKey.setDirectVerified(true);
|
client1.userDeviceKeys[client1.userID]!.masterKey!
|
||||||
await client1.encryption.ssss.clearCache();
|
.setDirectVerified(true);
|
||||||
|
await client1.encryption!.ssss.clearCache();
|
||||||
|
|
||||||
// send mac
|
// send mac
|
||||||
FakeMatrixApi.calledEndpoints.clear();
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
await req1.acceptSas();
|
await req1.acceptSas();
|
||||||
evt = getLastSentEvent(req1);
|
evt = getLastSentEvent(req1);
|
||||||
await client2.encryption.keyVerificationManager.handleEventUpdate(evt);
|
await client2.encryption!.keyVerificationManager.handleEventUpdate(evt);
|
||||||
expect(req1.state, KeyVerificationState.waitingSas);
|
expect(req1.state, KeyVerificationState.waitingSas);
|
||||||
|
|
||||||
// send mac
|
// send mac
|
||||||
FakeMatrixApi.calledEndpoints.clear();
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
await req2.acceptSas();
|
await req2.acceptSas();
|
||||||
evt = getLastSentEvent(req2);
|
evt = getLastSentEvent(req2);
|
||||||
await client1.encryption.keyVerificationManager.handleEventUpdate(evt);
|
await client1.encryption!.keyVerificationManager.handleEventUpdate(evt);
|
||||||
|
|
||||||
expect(req1.state, KeyVerificationState.askSSSS);
|
expect(req1.state, KeyVerificationState.askSSSS);
|
||||||
expect(req2.state, KeyVerificationState.done);
|
expect(req2.state, KeyVerificationState.done);
|
||||||
|
|
@ -324,63 +328,65 @@ void main() {
|
||||||
await Future.delayed(Duration(milliseconds: 10));
|
await Future.delayed(Duration(milliseconds: 10));
|
||||||
expect(req1.state, KeyVerificationState.done);
|
expect(req1.state, KeyVerificationState.done);
|
||||||
|
|
||||||
client1.encryption.ssss = MockSSSS(client1.encryption);
|
client1.encryption!.ssss = MockSSSS(client1.encryption!);
|
||||||
(client1.encryption.ssss as MockSSSS).requestedSecrets = false;
|
(client1.encryption!.ssss as MockSSSS).requestedSecrets = false;
|
||||||
await client1.encryption.ssss.clearCache();
|
await client1.encryption!.ssss.clearCache();
|
||||||
await req1.maybeRequestSSSSSecrets();
|
await req1.maybeRequestSSSSSecrets();
|
||||||
await Future.delayed(Duration(milliseconds: 10));
|
await Future.delayed(Duration(milliseconds: 10));
|
||||||
expect((client1.encryption.ssss as MockSSSS).requestedSecrets, true);
|
expect((client1.encryption!.ssss as MockSSSS).requestedSecrets, true);
|
||||||
// delay for 12 seconds to be sure no other tests clear the ssss cache
|
// delay for 12 seconds to be sure no other tests clear the ssss cache
|
||||||
await Future.delayed(Duration(seconds: 12));
|
await Future.delayed(Duration(seconds: 12));
|
||||||
|
|
||||||
await client1.encryption.keyVerificationManager.cleanup();
|
await client1.encryption!.keyVerificationManager.cleanup();
|
||||||
await client2.encryption.keyVerificationManager.cleanup();
|
await client2.encryption!.keyVerificationManager.cleanup();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('reject verification', () async {
|
test('reject verification', () async {
|
||||||
if (!olmEnabled) return;
|
if (!olmEnabled) return;
|
||||||
FakeMatrixApi.calledEndpoints.clear();
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
// make sure our master key is *not* verified to not triger SSSS for now
|
// make sure our master key is *not* verified to not triger SSSS for now
|
||||||
client1.userDeviceKeys[client1.userID].masterKey.setDirectVerified(false);
|
client1.userDeviceKeys[client1.userID]!.masterKey!
|
||||||
|
.setDirectVerified(false);
|
||||||
final req1 =
|
final req1 =
|
||||||
await client1.userDeviceKeys[client2.userID].startVerification();
|
await client1.userDeviceKeys[client2.userID]!.startVerification();
|
||||||
var evt = getLastSentEvent(req1);
|
var evt = getLastSentEvent(req1);
|
||||||
expect(req1.state, KeyVerificationState.waitingAccept);
|
expect(req1.state, KeyVerificationState.waitingAccept);
|
||||||
|
|
||||||
KeyVerification req2;
|
late KeyVerification req2;
|
||||||
final sub = client2.onKeyVerificationRequest.stream.listen((req) {
|
final sub = client2.onKeyVerificationRequest.stream.listen((req) {
|
||||||
req2 = req;
|
req2 = req;
|
||||||
});
|
});
|
||||||
await client2.encryption.keyVerificationManager.handleEventUpdate(evt);
|
await client2.encryption!.keyVerificationManager.handleEventUpdate(evt);
|
||||||
await Future.delayed(Duration(milliseconds: 10));
|
await Future.delayed(Duration(milliseconds: 10));
|
||||||
await sub.cancel();
|
await sub.cancel();
|
||||||
|
|
||||||
FakeMatrixApi.calledEndpoints.clear();
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
await req2.rejectVerification();
|
await req2.rejectVerification();
|
||||||
evt = getLastSentEvent(req2);
|
evt = getLastSentEvent(req2);
|
||||||
await client1.encryption.keyVerificationManager.handleEventUpdate(evt);
|
await client1.encryption!.keyVerificationManager.handleEventUpdate(evt);
|
||||||
expect(req1.state, KeyVerificationState.error);
|
expect(req1.state, KeyVerificationState.error);
|
||||||
expect(req2.state, KeyVerificationState.error);
|
expect(req2.state, KeyVerificationState.error);
|
||||||
|
|
||||||
await client1.encryption.keyVerificationManager.cleanup();
|
await client1.encryption!.keyVerificationManager.cleanup();
|
||||||
await client2.encryption.keyVerificationManager.cleanup();
|
await client2.encryption!.keyVerificationManager.cleanup();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('reject sas', () async {
|
test('reject sas', () async {
|
||||||
if (!olmEnabled) return;
|
if (!olmEnabled) return;
|
||||||
FakeMatrixApi.calledEndpoints.clear();
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
// make sure our master key is *not* verified to not triger SSSS for now
|
// make sure our master key is *not* verified to not triger SSSS for now
|
||||||
client1.userDeviceKeys[client1.userID].masterKey.setDirectVerified(false);
|
client1.userDeviceKeys[client1.userID]!.masterKey!
|
||||||
|
.setDirectVerified(false);
|
||||||
final req1 =
|
final req1 =
|
||||||
await client1.userDeviceKeys[client2.userID].startVerification();
|
await client1.userDeviceKeys[client2.userID]!.startVerification();
|
||||||
var evt = getLastSentEvent(req1);
|
var evt = getLastSentEvent(req1);
|
||||||
expect(req1.state, KeyVerificationState.waitingAccept);
|
expect(req1.state, KeyVerificationState.waitingAccept);
|
||||||
|
|
||||||
KeyVerification req2;
|
late KeyVerification req2;
|
||||||
final sub = client2.onKeyVerificationRequest.stream.listen((req) {
|
final sub = client2.onKeyVerificationRequest.stream.listen((req) {
|
||||||
req2 = req;
|
req2 = req;
|
||||||
});
|
});
|
||||||
await client2.encryption.keyVerificationManager.handleEventUpdate(evt);
|
await client2.encryption!.keyVerificationManager.handleEventUpdate(evt);
|
||||||
await Future.delayed(Duration(milliseconds: 10));
|
await Future.delayed(Duration(milliseconds: 10));
|
||||||
await sub.cancel();
|
await sub.cancel();
|
||||||
expect(req2 != null, true);
|
expect(req2 != null, true);
|
||||||
|
|
@ -393,60 +399,61 @@ void main() {
|
||||||
|
|
||||||
// send start
|
// send start
|
||||||
FakeMatrixApi.calledEndpoints.clear();
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
await client1.encryption.keyVerificationManager.handleEventUpdate(evt);
|
await client1.encryption!.keyVerificationManager.handleEventUpdate(evt);
|
||||||
evt = getLastSentEvent(req1);
|
evt = getLastSentEvent(req1);
|
||||||
|
|
||||||
// send accept
|
// send accept
|
||||||
FakeMatrixApi.calledEndpoints.clear();
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
await client2.encryption.keyVerificationManager.handleEventUpdate(evt);
|
await client2.encryption!.keyVerificationManager.handleEventUpdate(evt);
|
||||||
evt = getLastSentEvent(req2);
|
evt = getLastSentEvent(req2);
|
||||||
|
|
||||||
// send key
|
// send key
|
||||||
FakeMatrixApi.calledEndpoints.clear();
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
await client1.encryption.keyVerificationManager.handleEventUpdate(evt);
|
await client1.encryption!.keyVerificationManager.handleEventUpdate(evt);
|
||||||
evt = getLastSentEvent(req1);
|
evt = getLastSentEvent(req1);
|
||||||
|
|
||||||
// send key
|
// send key
|
||||||
FakeMatrixApi.calledEndpoints.clear();
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
await client2.encryption.keyVerificationManager.handleEventUpdate(evt);
|
await client2.encryption!.keyVerificationManager.handleEventUpdate(evt);
|
||||||
evt = getLastSentEvent(req2);
|
evt = getLastSentEvent(req2);
|
||||||
|
|
||||||
// receive last key
|
// receive last key
|
||||||
FakeMatrixApi.calledEndpoints.clear();
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
await client1.encryption.keyVerificationManager.handleEventUpdate(evt);
|
await client1.encryption!.keyVerificationManager.handleEventUpdate(evt);
|
||||||
|
|
||||||
await req1.acceptSas();
|
await req1.acceptSas();
|
||||||
FakeMatrixApi.calledEndpoints.clear();
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
await req2.rejectSas();
|
await req2.rejectSas();
|
||||||
evt = getLastSentEvent(req2);
|
evt = getLastSentEvent(req2);
|
||||||
await client1.encryption.keyVerificationManager.handleEventUpdate(evt);
|
await client1.encryption!.keyVerificationManager.handleEventUpdate(evt);
|
||||||
expect(req1.state, KeyVerificationState.error);
|
expect(req1.state, KeyVerificationState.error);
|
||||||
expect(req2.state, KeyVerificationState.error);
|
expect(req2.state, KeyVerificationState.error);
|
||||||
|
|
||||||
await client1.encryption.keyVerificationManager.cleanup();
|
await client1.encryption!.keyVerificationManager.cleanup();
|
||||||
await client2.encryption.keyVerificationManager.cleanup();
|
await client2.encryption!.keyVerificationManager.cleanup();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('other device accepted', () async {
|
test('other device accepted', () async {
|
||||||
if (!olmEnabled) return;
|
if (!olmEnabled) return;
|
||||||
FakeMatrixApi.calledEndpoints.clear();
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
// make sure our master key is *not* verified to not triger SSSS for now
|
// make sure our master key is *not* verified to not triger SSSS for now
|
||||||
client1.userDeviceKeys[client1.userID].masterKey.setDirectVerified(false);
|
client1.userDeviceKeys[client1.userID]!.masterKey!
|
||||||
|
.setDirectVerified(false);
|
||||||
final req1 =
|
final req1 =
|
||||||
await client1.userDeviceKeys[client2.userID].startVerification();
|
await client1.userDeviceKeys[client2.userID]!.startVerification();
|
||||||
final evt = getLastSentEvent(req1);
|
final evt = getLastSentEvent(req1);
|
||||||
expect(req1.state, KeyVerificationState.waitingAccept);
|
expect(req1.state, KeyVerificationState.waitingAccept);
|
||||||
|
|
||||||
KeyVerification req2;
|
late KeyVerification req2;
|
||||||
final sub = client2.onKeyVerificationRequest.stream.listen((req) {
|
final sub = client2.onKeyVerificationRequest.stream.listen((req) {
|
||||||
req2 = req;
|
req2 = req;
|
||||||
});
|
});
|
||||||
await client2.encryption.keyVerificationManager.handleEventUpdate(evt);
|
await client2.encryption!.keyVerificationManager.handleEventUpdate(evt);
|
||||||
await Future.delayed(Duration(milliseconds: 10));
|
await Future.delayed(Duration(milliseconds: 10));
|
||||||
await sub.cancel();
|
await sub.cancel();
|
||||||
expect(req2 != null, true);
|
expect(req2 != null, true);
|
||||||
|
|
||||||
await client2.encryption.keyVerificationManager
|
await client2.encryption!.keyVerificationManager
|
||||||
.handleEventUpdate(EventUpdate(
|
.handleEventUpdate(EventUpdate(
|
||||||
content: {
|
content: {
|
||||||
'event_id': req2.transactionId,
|
'event_id': req2.transactionId,
|
||||||
|
|
@ -463,13 +470,13 @@ void main() {
|
||||||
'sender': client2.userID,
|
'sender': client2.userID,
|
||||||
},
|
},
|
||||||
type: EventUpdateType.timeline,
|
type: EventUpdateType.timeline,
|
||||||
roomID: req2.room.id,
|
roomID: req2.room!.id,
|
||||||
));
|
));
|
||||||
expect(req2.state, KeyVerificationState.error);
|
expect(req2.state, KeyVerificationState.error);
|
||||||
|
|
||||||
await req2.cancel();
|
await req2.cancel();
|
||||||
await client1.encryption.keyVerificationManager.cleanup();
|
await client1.encryption!.keyVerificationManager.cleanup();
|
||||||
await client2.encryption.keyVerificationManager.cleanup();
|
await client2.encryption!.keyVerificationManager.cleanup();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('dispose client', () async {
|
test('dispose client', () async {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
// @dart=2.9
|
|
||||||
/*
|
/*
|
||||||
* Famedly Matrix SDK
|
* Famedly Matrix SDK
|
||||||
* Copyright (C) 2020, 2021 Famedly GmbH
|
* Copyright (C) 2020, 2021 Famedly GmbH
|
||||||
|
|
@ -32,7 +31,7 @@ void main() {
|
||||||
Logs().level = Level.error;
|
Logs().level = Level.error;
|
||||||
var olmEnabled = true;
|
var olmEnabled = true;
|
||||||
|
|
||||||
Client client;
|
late Client client;
|
||||||
|
|
||||||
test('setupClient', () async {
|
test('setupClient', () async {
|
||||||
try {
|
try {
|
||||||
|
|
@ -53,37 +52,37 @@ void main() {
|
||||||
final payload = <String, dynamic>{
|
final payload = <String, dynamic>{
|
||||||
'fox': 'floof',
|
'fox': 'floof',
|
||||||
};
|
};
|
||||||
final signedPayload = client.encryption.olmManager.signJson(payload);
|
final signedPayload = client.encryption!.olmManager.signJson(payload);
|
||||||
expect(
|
expect(
|
||||||
signedPayload.checkJsonSignature(
|
signedPayload.checkJsonSignature(
|
||||||
client.fingerprintKey, client.userID, client.deviceID),
|
client.fingerprintKey, client.userID!, client.deviceID!),
|
||||||
true);
|
true);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('uploadKeys', () async {
|
test('uploadKeys', () async {
|
||||||
if (!olmEnabled) return;
|
if (!olmEnabled) return;
|
||||||
FakeMatrixApi.calledEndpoints.clear();
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
final res =
|
final res = await client.encryption!.olmManager
|
||||||
await client.encryption.olmManager.uploadKeys(uploadDeviceKeys: true);
|
.uploadKeys(uploadDeviceKeys: true);
|
||||||
expect(res, true);
|
expect(res, true);
|
||||||
var sent = json.decode(
|
var sent = json.decode(
|
||||||
FakeMatrixApi.calledEndpoints['/client/r0/keys/upload'].first);
|
FakeMatrixApi.calledEndpoints['/client/r0/keys/upload']!.first);
|
||||||
expect(sent['device_keys'] != null, true);
|
expect(sent['device_keys'] != null, true);
|
||||||
expect(sent['one_time_keys'] != null, true);
|
expect(sent['one_time_keys'] != null, true);
|
||||||
expect(sent['one_time_keys'].keys.length, 66);
|
expect(sent['one_time_keys'].keys.length, 66);
|
||||||
expect(sent['fallback_keys'] != null, true);
|
expect(sent['fallback_keys'] != null, true);
|
||||||
expect(sent['fallback_keys'].keys.length, 1);
|
expect(sent['fallback_keys'].keys.length, 1);
|
||||||
FakeMatrixApi.calledEndpoints.clear();
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
await client.encryption.olmManager.uploadKeys();
|
await client.encryption!.olmManager.uploadKeys();
|
||||||
sent = json.decode(
|
sent = json.decode(
|
||||||
FakeMatrixApi.calledEndpoints['/client/r0/keys/upload'].first);
|
FakeMatrixApi.calledEndpoints['/client/r0/keys/upload']!.first);
|
||||||
expect(sent['device_keys'] != null, false);
|
expect(sent['device_keys'] != null, false);
|
||||||
expect(sent['fallback_keys'].keys.length, 1);
|
expect(sent['fallback_keys'].keys.length, 1);
|
||||||
FakeMatrixApi.calledEndpoints.clear();
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
await client.encryption.olmManager
|
await client.encryption!.olmManager
|
||||||
.uploadKeys(oldKeyCount: 20, unusedFallbackKey: true);
|
.uploadKeys(oldKeyCount: 20, unusedFallbackKey: true);
|
||||||
sent = json.decode(
|
sent = json.decode(
|
||||||
FakeMatrixApi.calledEndpoints['/client/r0/keys/upload'].first);
|
FakeMatrixApi.calledEndpoints['/client/r0/keys/upload']!.first);
|
||||||
expect(sent['one_time_keys'].keys.length, 46);
|
expect(sent['one_time_keys'].keys.length, 46);
|
||||||
expect(sent['fallback_keys'].keys.length, 0);
|
expect(sent['fallback_keys'].keys.length, 0);
|
||||||
});
|
});
|
||||||
|
|
@ -91,7 +90,7 @@ void main() {
|
||||||
test('handleDeviceOneTimeKeysCount', () async {
|
test('handleDeviceOneTimeKeysCount', () async {
|
||||||
if (!olmEnabled) return;
|
if (!olmEnabled) return;
|
||||||
FakeMatrixApi.calledEndpoints.clear();
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
client.encryption.olmManager
|
client.encryption!.olmManager
|
||||||
.handleDeviceOneTimeKeysCount({'signed_curve25519': 20}, null);
|
.handleDeviceOneTimeKeysCount({'signed_curve25519': 20}, null);
|
||||||
await Future.delayed(Duration(milliseconds: 50));
|
await Future.delayed(Duration(milliseconds: 50));
|
||||||
expect(
|
expect(
|
||||||
|
|
@ -99,7 +98,7 @@ void main() {
|
||||||
true);
|
true);
|
||||||
|
|
||||||
FakeMatrixApi.calledEndpoints.clear();
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
client.encryption.olmManager
|
client.encryption!.olmManager
|
||||||
.handleDeviceOneTimeKeysCount({'signed_curve25519': 70}, null);
|
.handleDeviceOneTimeKeysCount({'signed_curve25519': 70}, null);
|
||||||
await Future.delayed(Duration(milliseconds: 50));
|
await Future.delayed(Duration(milliseconds: 50));
|
||||||
expect(
|
expect(
|
||||||
|
|
@ -107,7 +106,7 @@ void main() {
|
||||||
false);
|
false);
|
||||||
|
|
||||||
FakeMatrixApi.calledEndpoints.clear();
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
client.encryption.olmManager.handleDeviceOneTimeKeysCount(null, []);
|
client.encryption!.olmManager.handleDeviceOneTimeKeysCount(null, []);
|
||||||
await Future.delayed(Duration(milliseconds: 50));
|
await Future.delayed(Duration(milliseconds: 50));
|
||||||
expect(
|
expect(
|
||||||
FakeMatrixApi.calledEndpoints.containsKey('/client/r0/keys/upload'),
|
FakeMatrixApi.calledEndpoints.containsKey('/client/r0/keys/upload'),
|
||||||
|
|
@ -115,7 +114,7 @@ void main() {
|
||||||
|
|
||||||
// this will upload keys because we assume the key count is 0, if the server doesn't send one
|
// this will upload keys because we assume the key count is 0, if the server doesn't send one
|
||||||
FakeMatrixApi.calledEndpoints.clear();
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
client.encryption.olmManager
|
client.encryption!.olmManager
|
||||||
.handleDeviceOneTimeKeysCount(null, ['signed_curve25519']);
|
.handleDeviceOneTimeKeysCount(null, ['signed_curve25519']);
|
||||||
await Future.delayed(Duration(milliseconds: 50));
|
await Future.delayed(Duration(milliseconds: 50));
|
||||||
expect(
|
expect(
|
||||||
|
|
@ -125,30 +124,31 @@ void main() {
|
||||||
|
|
||||||
test('restoreOlmSession', () async {
|
test('restoreOlmSession', () async {
|
||||||
if (!olmEnabled) return;
|
if (!olmEnabled) return;
|
||||||
client.encryption.olmManager.olmSessions.clear();
|
client.encryption!.olmManager.olmSessions.clear();
|
||||||
await client.encryption.olmManager
|
await client.encryption!.olmManager
|
||||||
.restoreOlmSession(client.userID, client.identityKey);
|
.restoreOlmSession(client.userID!, client.identityKey);
|
||||||
expect(client.encryption.olmManager.olmSessions.length, 1);
|
expect(client.encryption!.olmManager.olmSessions.length, 1);
|
||||||
|
|
||||||
client.encryption.olmManager.olmSessions.clear();
|
client.encryption!.olmManager.olmSessions.clear();
|
||||||
await client.encryption.olmManager
|
await client.encryption!.olmManager
|
||||||
.restoreOlmSession(client.userID, 'invalid');
|
.restoreOlmSession(client.userID!, 'invalid');
|
||||||
expect(client.encryption.olmManager.olmSessions.length, 0);
|
expect(client.encryption!.olmManager.olmSessions.length, 0);
|
||||||
|
|
||||||
client.encryption.olmManager.olmSessions.clear();
|
client.encryption!.olmManager.olmSessions.clear();
|
||||||
await client.encryption.olmManager
|
await client.encryption!.olmManager
|
||||||
.restoreOlmSession('invalid', client.identityKey);
|
.restoreOlmSession('invalid', client.identityKey);
|
||||||
expect(client.encryption.olmManager.olmSessions.length, 0);
|
expect(client.encryption!.olmManager.olmSessions.length, 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('startOutgoingOlmSessions', () async {
|
test('startOutgoingOlmSessions', () async {
|
||||||
if (!olmEnabled) return;
|
if (!olmEnabled) return;
|
||||||
// start an olm session.....with ourself!
|
// start an olm session.....with ourself!
|
||||||
client.encryption.olmManager.olmSessions.clear();
|
client.encryption!.olmManager.olmSessions.clear();
|
||||||
await client.encryption.olmManager.startOutgoingOlmSessions(
|
await client.encryption!.olmManager.startOutgoingOlmSessions([
|
||||||
[client.userDeviceKeys[client.userID].deviceKeys[client.deviceID]]);
|
client.userDeviceKeys[client.userID!]!.deviceKeys[client.deviceID]!
|
||||||
|
]);
|
||||||
expect(
|
expect(
|
||||||
client.encryption.olmManager.olmSessions
|
client.encryption!.olmManager.olmSessions
|
||||||
.containsKey(client.identityKey),
|
.containsKey(client.identityKey),
|
||||||
true);
|
true);
|
||||||
});
|
});
|
||||||
|
|
@ -159,7 +159,7 @@ void main() {
|
||||||
final deviceId = 'JLAFKJWSCS';
|
final deviceId = 'JLAFKJWSCS';
|
||||||
final senderKey = 'L+4+JCl8MD63dgo8z5Ta+9QAHXiANyOVSfgbHA5d3H8';
|
final senderKey = 'L+4+JCl8MD63dgo8z5Ta+9QAHXiANyOVSfgbHA5d3H8';
|
||||||
FakeMatrixApi.calledEndpoints.clear();
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
await client.database.setLastSentMessageUserDeviceKey(
|
await client.database!.setLastSentMessageUserDeviceKey(
|
||||||
json.encode({
|
json.encode({
|
||||||
'type': 'm.foxies',
|
'type': 'm.foxies',
|
||||||
'content': {
|
'content': {
|
||||||
|
|
@ -176,7 +176,7 @@ void main() {
|
||||||
'sender_key': senderKey,
|
'sender_key': senderKey,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
await client.encryption.olmManager.handleToDeviceEvent(event);
|
await client.encryption!.olmManager.handleToDeviceEvent(event);
|
||||||
expect(
|
expect(
|
||||||
FakeMatrixApi.calledEndpoints.keys.any(
|
FakeMatrixApi.calledEndpoints.keys.any(
|
||||||
(k) => k.startsWith('/client/r0/sendToDevice/m.room.encrypted')),
|
(k) => k.startsWith('/client/r0/sendToDevice/m.room.encrypted')),
|
||||||
|
|
@ -186,7 +186,7 @@ void main() {
|
||||||
|
|
||||||
// not encrypted
|
// not encrypted
|
||||||
FakeMatrixApi.calledEndpoints.clear();
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
await client.database.setLastSentMessageUserDeviceKey(
|
await client.database!.setLastSentMessageUserDeviceKey(
|
||||||
json.encode({
|
json.encode({
|
||||||
'type': 'm.foxies',
|
'type': 'm.foxies',
|
||||||
'content': {
|
'content': {
|
||||||
|
|
@ -201,7 +201,7 @@ void main() {
|
||||||
content: {},
|
content: {},
|
||||||
encryptedContent: null,
|
encryptedContent: null,
|
||||||
);
|
);
|
||||||
await client.encryption.olmManager.handleToDeviceEvent(event);
|
await client.encryption!.olmManager.handleToDeviceEvent(event);
|
||||||
expect(
|
expect(
|
||||||
FakeMatrixApi.calledEndpoints.keys.any(
|
FakeMatrixApi.calledEndpoints.keys.any(
|
||||||
(k) => k.startsWith('/client/r0/sendToDevice/m.room.encrypted')),
|
(k) => k.startsWith('/client/r0/sendToDevice/m.room.encrypted')),
|
||||||
|
|
@ -209,7 +209,7 @@ void main() {
|
||||||
|
|
||||||
// device not found
|
// device not found
|
||||||
FakeMatrixApi.calledEndpoints.clear();
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
await client.database.setLastSentMessageUserDeviceKey(
|
await client.database!.setLastSentMessageUserDeviceKey(
|
||||||
json.encode({
|
json.encode({
|
||||||
'type': 'm.foxies',
|
'type': 'm.foxies',
|
||||||
'content': {
|
'content': {
|
||||||
|
|
@ -226,7 +226,7 @@ void main() {
|
||||||
'sender_key': 'invalid',
|
'sender_key': 'invalid',
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
await client.encryption.olmManager.handleToDeviceEvent(event);
|
await client.encryption!.olmManager.handleToDeviceEvent(event);
|
||||||
expect(
|
expect(
|
||||||
FakeMatrixApi.calledEndpoints.keys.any(
|
FakeMatrixApi.calledEndpoints.keys.any(
|
||||||
(k) => k.startsWith('/client/r0/sendToDevice/m.room.encrypted')),
|
(k) => k.startsWith('/client/r0/sendToDevice/m.room.encrypted')),
|
||||||
|
|
@ -234,7 +234,7 @@ void main() {
|
||||||
|
|
||||||
// don't replay if the last event is m.dummy itself
|
// don't replay if the last event is m.dummy itself
|
||||||
FakeMatrixApi.calledEndpoints.clear();
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
await client.database.setLastSentMessageUserDeviceKey(
|
await client.database!.setLastSentMessageUserDeviceKey(
|
||||||
json.encode({
|
json.encode({
|
||||||
'type': 'm.dummy',
|
'type': 'm.dummy',
|
||||||
'content': {},
|
'content': {},
|
||||||
|
|
@ -249,7 +249,7 @@ void main() {
|
||||||
'sender_key': senderKey,
|
'sender_key': senderKey,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
await client.encryption.olmManager.handleToDeviceEvent(event);
|
await client.encryption!.olmManager.handleToDeviceEvent(event);
|
||||||
expect(
|
expect(
|
||||||
FakeMatrixApi.calledEndpoints.keys.any(
|
FakeMatrixApi.calledEndpoints.keys.any(
|
||||||
(k) => k.startsWith('/client/r0/sendToDevice/m.room.encrypted')),
|
(k) => k.startsWith('/client/r0/sendToDevice/m.room.encrypted')),
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
// @dart=2.9
|
|
||||||
/*
|
/*
|
||||||
* Famedly Matrix SDK
|
* Famedly Matrix SDK
|
||||||
* Copyright (C) 2020 Famedly GmbH
|
* Copyright (C) 2020 Famedly GmbH
|
||||||
|
|
@ -32,7 +31,7 @@ void main() {
|
||||||
Logs().level = Level.error;
|
Logs().level = Level.error;
|
||||||
var olmEnabled = true;
|
var olmEnabled = true;
|
||||||
|
|
||||||
Client client;
|
late Client client;
|
||||||
|
|
||||||
final roomId = '!726s6s6q:example.com';
|
final roomId = '!726s6s6q:example.com';
|
||||||
final sessionId = 'ciM/JWTPrmiWPPZNkRLDPQYf9AW/I46bxyLSr+Bx5oU';
|
final sessionId = 'ciM/JWTPrmiWPPZNkRLDPQYf9AW/I46bxyLSr+Bx5oU';
|
||||||
|
|
@ -54,21 +53,21 @@ void main() {
|
||||||
|
|
||||||
test('basic things', () async {
|
test('basic things', () async {
|
||||||
if (!olmEnabled) return;
|
if (!olmEnabled) return;
|
||||||
expect(client.encryption.keyManager.enabled, true);
|
expect(client.encryption!.keyManager.enabled, true);
|
||||||
expect(await client.encryption.keyManager.isCached(), false);
|
expect(await client.encryption!.keyManager.isCached(), false);
|
||||||
final handle = client.encryption.ssss.open();
|
final handle = client.encryption!.ssss.open();
|
||||||
await handle.unlock(recoveryKey: ssssKey);
|
await handle.unlock(recoveryKey: ssssKey);
|
||||||
await handle.maybeCacheAll();
|
await handle.maybeCacheAll();
|
||||||
expect(await client.encryption.keyManager.isCached(), true);
|
expect(await client.encryption!.keyManager.isCached(), true);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('load key', () async {
|
test('load key', () async {
|
||||||
if (!olmEnabled) return;
|
if (!olmEnabled) return;
|
||||||
client.encryption.keyManager.clearInboundGroupSessions();
|
client.encryption!.keyManager.clearInboundGroupSessions();
|
||||||
await client.encryption.keyManager
|
await client.encryption!.keyManager
|
||||||
.request(client.getRoomById(roomId), sessionId, senderKey);
|
.request(client.getRoomById(roomId)!, sessionId, senderKey);
|
||||||
expect(
|
expect(
|
||||||
client.encryption.keyManager
|
client.encryption!.keyManager
|
||||||
.getInboundGroupSession(roomId, sessionId, senderKey) !=
|
.getInboundGroupSession(roomId, sessionId, senderKey) !=
|
||||||
null,
|
null,
|
||||||
true);
|
true);
|
||||||
|
|
@ -94,25 +93,25 @@ void main() {
|
||||||
'sender_claimed_ed25519_key': client.fingerprintKey,
|
'sender_claimed_ed25519_key': client.fingerprintKey,
|
||||||
};
|
};
|
||||||
FakeMatrixApi.calledEndpoints.clear();
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
client.encryption.keyManager.setInboundGroupSession(
|
client.encryption!.keyManager.setInboundGroupSession(
|
||||||
roomId, sessionId, senderKey, sessionPayload,
|
roomId, sessionId, senderKey, sessionPayload,
|
||||||
forwarded: true);
|
forwarded: true);
|
||||||
await Future.delayed(Duration(milliseconds: 500));
|
await Future.delayed(Duration(milliseconds: 500));
|
||||||
var dbSessions = await client.database.getInboundGroupSessionsToUpload();
|
var dbSessions = await client.database!.getInboundGroupSessionsToUpload();
|
||||||
expect(dbSessions.isNotEmpty, true);
|
expect(dbSessions.isNotEmpty, true);
|
||||||
await client.encryption.keyManager.backgroundTasks();
|
await client.encryption!.keyManager.backgroundTasks();
|
||||||
final payload = FakeMatrixApi
|
final payload = FakeMatrixApi
|
||||||
.calledEndpoints['/client/unstable/room_keys/keys?version=5'].first;
|
.calledEndpoints['/client/unstable/room_keys/keys?version=5']!.first;
|
||||||
dbSessions = await client.database.getInboundGroupSessionsToUpload();
|
dbSessions = await client.database!.getInboundGroupSessionsToUpload();
|
||||||
expect(dbSessions.isEmpty, true);
|
expect(dbSessions.isEmpty, true);
|
||||||
|
|
||||||
final onlineKeys = RoomKeys.fromJson(json.decode(payload));
|
final onlineKeys = RoomKeys.fromJson(json.decode(payload));
|
||||||
client.encryption.keyManager.clearInboundGroupSessions();
|
client.encryption!.keyManager.clearInboundGroupSessions();
|
||||||
var ret = client.encryption.keyManager
|
var ret = client.encryption!.keyManager
|
||||||
.getInboundGroupSession(roomId, sessionId, senderKey);
|
.getInboundGroupSession(roomId, sessionId, senderKey);
|
||||||
expect(ret, null);
|
expect(ret, null);
|
||||||
await client.encryption.keyManager.loadFromResponse(onlineKeys);
|
await client.encryption!.keyManager.loadFromResponse(onlineKeys);
|
||||||
ret = client.encryption.keyManager
|
ret = client.encryption!.keyManager
|
||||||
.getInboundGroupSession(roomId, sessionId, senderKey);
|
.getInboundGroupSession(roomId, sessionId, senderKey);
|
||||||
expect(ret != null, true);
|
expect(ret != null, true);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
// @dart=2.9
|
|
||||||
/*
|
/*
|
||||||
* Famedly Matrix SDK
|
* Famedly Matrix SDK
|
||||||
* Copyright (C) 2020 Famedly GmbH
|
* Copyright (C) 2020 Famedly GmbH
|
||||||
|
|
@ -42,7 +41,7 @@ class MockSSSS extends SSSS {
|
||||||
|
|
||||||
bool requestedSecrets = false;
|
bool requestedSecrets = false;
|
||||||
@override
|
@override
|
||||||
Future<void> maybeRequestAll([List<DeviceKeys> devices]) async {
|
Future<void> maybeRequestAll([List<DeviceKeys>? devices]) async {
|
||||||
requestedSecrets = true;
|
requestedSecrets = true;
|
||||||
final handle = open();
|
final handle = open();
|
||||||
await handle.unlock(recoveryKey: ssssKey);
|
await handle.unlock(recoveryKey: ssssKey);
|
||||||
|
|
@ -55,7 +54,7 @@ void main() {
|
||||||
Logs().level = Level.error;
|
Logs().level = Level.error;
|
||||||
var olmEnabled = true;
|
var olmEnabled = true;
|
||||||
|
|
||||||
Client client;
|
late Client client;
|
||||||
|
|
||||||
test('setupClient', () async {
|
test('setupClient', () async {
|
||||||
try {
|
try {
|
||||||
|
|
@ -73,7 +72,7 @@ void main() {
|
||||||
|
|
||||||
test('basic things', () async {
|
test('basic things', () async {
|
||||||
if (!olmEnabled) return;
|
if (!olmEnabled) return;
|
||||||
expect(client.encryption.ssss.defaultKeyId,
|
expect(client.encryption!.ssss.defaultKeyId,
|
||||||
'0FajDWYaM6wQ4O60OZnLvwZfsBNu4Bu3');
|
'0FajDWYaM6wQ4O60OZnLvwZfsBNu4Bu3');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -88,7 +87,7 @@ void main() {
|
||||||
|
|
||||||
test('store', () async {
|
test('store', () async {
|
||||||
if (!olmEnabled) return;
|
if (!olmEnabled) return;
|
||||||
final handle = client.encryption.ssss.open();
|
final handle = client.encryption!.ssss.open();
|
||||||
var failed = false;
|
var failed = false;
|
||||||
try {
|
try {
|
||||||
await handle.unlock(passphrase: 'invalid');
|
await handle.unlock(passphrase: 'invalid');
|
||||||
|
|
@ -114,7 +113,7 @@ void main() {
|
||||||
// account_data for this test
|
// account_data for this test
|
||||||
final content = FakeMatrixApi
|
final content = FakeMatrixApi
|
||||||
.calledEndpoints[
|
.calledEndpoints[
|
||||||
'/client/r0/user/%40test%3AfakeServer.notExisting/account_data/best%20animal']
|
'/client/r0/user/%40test%3AfakeServer.notExisting/account_data/best%20animal']!
|
||||||
.first;
|
.first;
|
||||||
client.accountData['best animal'] = BasicEvent.fromJson({
|
client.accountData['best animal'] = BasicEvent.fromJson({
|
||||||
'type': 'best animal',
|
'type': 'best animal',
|
||||||
|
|
@ -130,77 +129,78 @@ void main() {
|
||||||
final decoded = SSSS.decodeRecoveryKey(encoded);
|
final decoded = SSSS.decodeRecoveryKey(encoded);
|
||||||
expect(key, decoded);
|
expect(key, decoded);
|
||||||
|
|
||||||
final handle = client.encryption.ssss.open();
|
final handle = client.encryption!.ssss.open();
|
||||||
await handle.unlock(recoveryKey: ssssKey);
|
await handle.unlock(recoveryKey: ssssKey);
|
||||||
expect(handle.recoveryKey, ssssKey);
|
expect(handle.recoveryKey, ssssKey);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('cache', () async {
|
test('cache', () async {
|
||||||
if (!olmEnabled) return;
|
if (!olmEnabled) return;
|
||||||
await client.encryption.ssss.clearCache();
|
await client.encryption!.ssss.clearCache();
|
||||||
final handle =
|
final handle =
|
||||||
client.encryption.ssss.open(EventTypes.CrossSigningSelfSigning);
|
client.encryption!.ssss.open(EventTypes.CrossSigningSelfSigning);
|
||||||
await handle.unlock(recoveryKey: ssssKey, postUnlock: false);
|
await handle.unlock(recoveryKey: ssssKey, postUnlock: false);
|
||||||
expect(
|
expect(
|
||||||
(await client.encryption.ssss
|
(await client.encryption!.ssss
|
||||||
.getCached(EventTypes.CrossSigningSelfSigning)) !=
|
.getCached(EventTypes.CrossSigningSelfSigning)) !=
|
||||||
null,
|
null,
|
||||||
false);
|
false);
|
||||||
expect(
|
expect(
|
||||||
(await client.encryption.ssss
|
(await client.encryption!.ssss
|
||||||
.getCached(EventTypes.CrossSigningUserSigning)) !=
|
.getCached(EventTypes.CrossSigningUserSigning)) !=
|
||||||
null,
|
null,
|
||||||
false);
|
false);
|
||||||
await handle.getStored(EventTypes.CrossSigningSelfSigning);
|
await handle.getStored(EventTypes.CrossSigningSelfSigning);
|
||||||
expect(
|
expect(
|
||||||
(await client.encryption.ssss
|
(await client.encryption!.ssss
|
||||||
.getCached(EventTypes.CrossSigningSelfSigning)) !=
|
.getCached(EventTypes.CrossSigningSelfSigning)) !=
|
||||||
null,
|
null,
|
||||||
true);
|
true);
|
||||||
await handle.maybeCacheAll();
|
await handle.maybeCacheAll();
|
||||||
expect(
|
expect(
|
||||||
(await client.encryption.ssss
|
(await client.encryption!.ssss
|
||||||
.getCached(EventTypes.CrossSigningUserSigning)) !=
|
.getCached(EventTypes.CrossSigningUserSigning)) !=
|
||||||
null,
|
null,
|
||||||
true);
|
true);
|
||||||
expect(
|
expect(
|
||||||
(await client.encryption.ssss.getCached(EventTypes.MegolmBackup)) !=
|
(await client.encryption!.ssss.getCached(EventTypes.MegolmBackup)) !=
|
||||||
null,
|
null,
|
||||||
true);
|
true);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('postUnlock', () async {
|
test('postUnlock', () async {
|
||||||
if (!olmEnabled) return;
|
if (!olmEnabled) return;
|
||||||
await client.encryption.ssss.clearCache();
|
await client.encryption!.ssss.clearCache();
|
||||||
client.userDeviceKeys[client.userID].masterKey.setDirectVerified(false);
|
client.userDeviceKeys[client.userID!]!.masterKey!
|
||||||
|
.setDirectVerified(false);
|
||||||
final handle =
|
final handle =
|
||||||
client.encryption.ssss.open(EventTypes.CrossSigningSelfSigning);
|
client.encryption!.ssss.open(EventTypes.CrossSigningSelfSigning);
|
||||||
await handle.unlock(recoveryKey: ssssKey);
|
await handle.unlock(recoveryKey: ssssKey);
|
||||||
expect(
|
expect(
|
||||||
(await client.encryption.ssss
|
(await client.encryption!.ssss
|
||||||
.getCached(EventTypes.CrossSigningSelfSigning)) !=
|
.getCached(EventTypes.CrossSigningSelfSigning)) !=
|
||||||
null,
|
null,
|
||||||
true);
|
true);
|
||||||
expect(
|
expect(
|
||||||
(await client.encryption.ssss
|
(await client.encryption!.ssss
|
||||||
.getCached(EventTypes.CrossSigningUserSigning)) !=
|
.getCached(EventTypes.CrossSigningUserSigning)) !=
|
||||||
null,
|
null,
|
||||||
true);
|
true);
|
||||||
expect(
|
expect(
|
||||||
(await client.encryption.ssss.getCached(EventTypes.MegolmBackup)) !=
|
(await client.encryption!.ssss.getCached(EventTypes.MegolmBackup)) !=
|
||||||
null,
|
null,
|
||||||
true);
|
true);
|
||||||
expect(
|
expect(client.userDeviceKeys[client.userID!]!.masterKey!.directVerified,
|
||||||
client.userDeviceKeys[client.userID].masterKey.directVerified, true);
|
true);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('make share requests', () async {
|
test('make share requests', () async {
|
||||||
if (!olmEnabled) return;
|
if (!olmEnabled) return;
|
||||||
final key =
|
final key =
|
||||||
client.userDeviceKeys[client.userID].deviceKeys['OTHERDEVICE'];
|
client.userDeviceKeys[client.userID!]!.deviceKeys['OTHERDEVICE']!;
|
||||||
key.setDirectVerified(true);
|
key.setDirectVerified(true);
|
||||||
FakeMatrixApi.calledEndpoints.clear();
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
await client.encryption.ssss.request('some.type', [key]);
|
await client.encryption!.ssss.request('some.type', [key]);
|
||||||
expect(
|
expect(
|
||||||
FakeMatrixApi.calledEndpoints.keys.any(
|
FakeMatrixApi.calledEndpoints.keys.any(
|
||||||
(k) => k.startsWith('/client/r0/sendToDevice/m.room.encrypted')),
|
(k) => k.startsWith('/client/r0/sendToDevice/m.room.encrypted')),
|
||||||
|
|
@ -210,7 +210,7 @@ void main() {
|
||||||
test('answer to share requests', () async {
|
test('answer to share requests', () async {
|
||||||
if (!olmEnabled) return;
|
if (!olmEnabled) return;
|
||||||
var event = ToDeviceEvent(
|
var event = ToDeviceEvent(
|
||||||
sender: client.userID,
|
sender: client.userID!,
|
||||||
type: 'm.secret.request',
|
type: 'm.secret.request',
|
||||||
content: {
|
content: {
|
||||||
'action': 'request',
|
'action': 'request',
|
||||||
|
|
@ -220,7 +220,7 @@ void main() {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
FakeMatrixApi.calledEndpoints.clear();
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
await client.encryption.ssss.handleToDeviceEvent(event);
|
await client.encryption!.ssss.handleToDeviceEvent(event);
|
||||||
expect(
|
expect(
|
||||||
FakeMatrixApi.calledEndpoints.keys.any(
|
FakeMatrixApi.calledEndpoints.keys.any(
|
||||||
(k) => k.startsWith('/client/r0/sendToDevice/m.room.encrypted')),
|
(k) => k.startsWith('/client/r0/sendToDevice/m.room.encrypted')),
|
||||||
|
|
@ -240,7 +240,7 @@ void main() {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
FakeMatrixApi.calledEndpoints.clear();
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
await client.encryption.ssss.handleToDeviceEvent(event);
|
await client.encryption!.ssss.handleToDeviceEvent(event);
|
||||||
expect(
|
expect(
|
||||||
FakeMatrixApi.calledEndpoints.keys.any(
|
FakeMatrixApi.calledEndpoints.keys.any(
|
||||||
(k) => k.startsWith('/client/r0/sendToDevice/m.room.encrypted')),
|
(k) => k.startsWith('/client/r0/sendToDevice/m.room.encrypted')),
|
||||||
|
|
@ -248,7 +248,7 @@ void main() {
|
||||||
|
|
||||||
// secret not cached
|
// secret not cached
|
||||||
event = ToDeviceEvent(
|
event = ToDeviceEvent(
|
||||||
sender: client.userID,
|
sender: client.userID!,
|
||||||
type: 'm.secret.request',
|
type: 'm.secret.request',
|
||||||
content: {
|
content: {
|
||||||
'action': 'request',
|
'action': 'request',
|
||||||
|
|
@ -258,7 +258,7 @@ void main() {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
FakeMatrixApi.calledEndpoints.clear();
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
await client.encryption.ssss.handleToDeviceEvent(event);
|
await client.encryption!.ssss.handleToDeviceEvent(event);
|
||||||
expect(
|
expect(
|
||||||
FakeMatrixApi.calledEndpoints.keys.any(
|
FakeMatrixApi.calledEndpoints.keys.any(
|
||||||
(k) => k.startsWith('/client/r0/sendToDevice/m.room.encrypted')),
|
(k) => k.startsWith('/client/r0/sendToDevice/m.room.encrypted')),
|
||||||
|
|
@ -266,7 +266,7 @@ void main() {
|
||||||
|
|
||||||
// is a cancelation
|
// is a cancelation
|
||||||
event = ToDeviceEvent(
|
event = ToDeviceEvent(
|
||||||
sender: client.userID,
|
sender: client.userID!,
|
||||||
type: 'm.secret.request',
|
type: 'm.secret.request',
|
||||||
content: {
|
content: {
|
||||||
'action': 'request_cancellation',
|
'action': 'request_cancellation',
|
||||||
|
|
@ -276,7 +276,7 @@ void main() {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
FakeMatrixApi.calledEndpoints.clear();
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
await client.encryption.ssss.handleToDeviceEvent(event);
|
await client.encryption!.ssss.handleToDeviceEvent(event);
|
||||||
expect(
|
expect(
|
||||||
FakeMatrixApi.calledEndpoints.keys.any(
|
FakeMatrixApi.calledEndpoints.keys.any(
|
||||||
(k) => k.startsWith('/client/r0/sendToDevice/m.room.encrypted')),
|
(k) => k.startsWith('/client/r0/sendToDevice/m.room.encrypted')),
|
||||||
|
|
@ -284,11 +284,12 @@ void main() {
|
||||||
|
|
||||||
// device not verified
|
// device not verified
|
||||||
final key =
|
final key =
|
||||||
client.userDeviceKeys[client.userID].deviceKeys['OTHERDEVICE'];
|
client.userDeviceKeys[client.userID!]!.deviceKeys['OTHERDEVICE']!;
|
||||||
key.setDirectVerified(false);
|
key.setDirectVerified(false);
|
||||||
client.userDeviceKeys[client.userID].masterKey.setDirectVerified(false);
|
client.userDeviceKeys[client.userID!]!.masterKey!
|
||||||
|
.setDirectVerified(false);
|
||||||
event = ToDeviceEvent(
|
event = ToDeviceEvent(
|
||||||
sender: client.userID,
|
sender: client.userID!,
|
||||||
type: 'm.secret.request',
|
type: 'm.secret.request',
|
||||||
content: {
|
content: {
|
||||||
'action': 'request',
|
'action': 'request',
|
||||||
|
|
@ -298,7 +299,7 @@ void main() {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
FakeMatrixApi.calledEndpoints.clear();
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
await client.encryption.ssss.handleToDeviceEvent(event);
|
await client.encryption!.ssss.handleToDeviceEvent(event);
|
||||||
expect(
|
expect(
|
||||||
FakeMatrixApi.calledEndpoints.keys.any(
|
FakeMatrixApi.calledEndpoints.keys.any(
|
||||||
(k) => k.startsWith('/client/r0/sendToDevice/m.room.encrypted')),
|
(k) => k.startsWith('/client/r0/sendToDevice/m.room.encrypted')),
|
||||||
|
|
@ -309,28 +310,28 @@ void main() {
|
||||||
test('receive share requests', () async {
|
test('receive share requests', () async {
|
||||||
if (!olmEnabled) return;
|
if (!olmEnabled) return;
|
||||||
final key =
|
final key =
|
||||||
client.userDeviceKeys[client.userID].deviceKeys['OTHERDEVICE'];
|
client.userDeviceKeys[client.userID!]!.deviceKeys['OTHERDEVICE']!;
|
||||||
key.setDirectVerified(true);
|
key.setDirectVerified(true);
|
||||||
final handle =
|
final handle =
|
||||||
client.encryption.ssss.open(EventTypes.CrossSigningSelfSigning);
|
client.encryption!.ssss.open(EventTypes.CrossSigningSelfSigning);
|
||||||
await handle.unlock(recoveryKey: ssssKey);
|
await handle.unlock(recoveryKey: ssssKey);
|
||||||
|
|
||||||
await client.encryption.ssss.clearCache();
|
await client.encryption!.ssss.clearCache();
|
||||||
client.encryption.ssss.pendingShareRequests.clear();
|
client.encryption!.ssss.pendingShareRequests.clear();
|
||||||
await client.encryption.ssss.request('best animal', [key]);
|
await client.encryption!.ssss.request('best animal', [key]);
|
||||||
var event = ToDeviceEvent(
|
var event = ToDeviceEvent(
|
||||||
sender: client.userID,
|
sender: client.userID!,
|
||||||
type: 'm.secret.send',
|
type: 'm.secret.send',
|
||||||
content: {
|
content: {
|
||||||
'request_id': client.encryption.ssss.pendingShareRequests.keys.first,
|
'request_id': client.encryption!.ssss.pendingShareRequests.keys.first,
|
||||||
'secret': 'foxies!',
|
'secret': 'foxies!',
|
||||||
},
|
},
|
||||||
encryptedContent: {
|
encryptedContent: {
|
||||||
'sender_key': key.curve25519Key,
|
'sender_key': key.curve25519Key,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
await client.encryption.ssss.handleToDeviceEvent(event);
|
await client.encryption!.ssss.handleToDeviceEvent(event);
|
||||||
expect(await client.encryption.ssss.getCached('best animal'), 'foxies!');
|
expect(await client.encryption!.ssss.getCached('best animal'), 'foxies!');
|
||||||
|
|
||||||
// test the different validators
|
// test the different validators
|
||||||
for (final type in [
|
for (final type in [
|
||||||
|
|
@ -339,48 +340,48 @@ void main() {
|
||||||
EventTypes.MegolmBackup
|
EventTypes.MegolmBackup
|
||||||
]) {
|
]) {
|
||||||
final secret = await handle.getStored(type);
|
final secret = await handle.getStored(type);
|
||||||
await client.encryption.ssss.clearCache();
|
await client.encryption!.ssss.clearCache();
|
||||||
client.encryption.ssss.pendingShareRequests.clear();
|
client.encryption!.ssss.pendingShareRequests.clear();
|
||||||
await client.encryption.ssss.request(type, [key]);
|
await client.encryption!.ssss.request(type, [key]);
|
||||||
event = ToDeviceEvent(
|
event = ToDeviceEvent(
|
||||||
sender: client.userID,
|
sender: client.userID!,
|
||||||
type: 'm.secret.send',
|
type: 'm.secret.send',
|
||||||
content: {
|
content: {
|
||||||
'request_id':
|
'request_id':
|
||||||
client.encryption.ssss.pendingShareRequests.keys.first,
|
client.encryption!.ssss.pendingShareRequests.keys.first,
|
||||||
'secret': secret,
|
'secret': secret,
|
||||||
},
|
},
|
||||||
encryptedContent: {
|
encryptedContent: {
|
||||||
'sender_key': key.curve25519Key,
|
'sender_key': key.curve25519Key,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
await client.encryption.ssss.handleToDeviceEvent(event);
|
await client.encryption!.ssss.handleToDeviceEvent(event);
|
||||||
expect(await client.encryption.ssss.getCached(type), secret);
|
expect(await client.encryption!.ssss.getCached(type), secret);
|
||||||
}
|
}
|
||||||
|
|
||||||
// test different fail scenarios
|
// test different fail scenarios
|
||||||
|
|
||||||
// not encrypted
|
// not encrypted
|
||||||
await client.encryption.ssss.clearCache();
|
await client.encryption!.ssss.clearCache();
|
||||||
client.encryption.ssss.pendingShareRequests.clear();
|
client.encryption!.ssss.pendingShareRequests.clear();
|
||||||
await client.encryption.ssss.request('best animal', [key]);
|
await client.encryption!.ssss.request('best animal', [key]);
|
||||||
event = ToDeviceEvent(
|
event = ToDeviceEvent(
|
||||||
sender: client.userID,
|
sender: client.userID!,
|
||||||
type: 'm.secret.send',
|
type: 'm.secret.send',
|
||||||
content: {
|
content: {
|
||||||
'request_id': client.encryption.ssss.pendingShareRequests.keys.first,
|
'request_id': client.encryption!.ssss.pendingShareRequests.keys.first,
|
||||||
'secret': 'foxies!',
|
'secret': 'foxies!',
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
await client.encryption.ssss.handleToDeviceEvent(event);
|
await client.encryption!.ssss.handleToDeviceEvent(event);
|
||||||
expect(await client.encryption.ssss.getCached('best animal'), null);
|
expect(await client.encryption!.ssss.getCached('best animal'), null);
|
||||||
|
|
||||||
// unknown request id
|
// unknown request id
|
||||||
await client.encryption.ssss.clearCache();
|
await client.encryption!.ssss.clearCache();
|
||||||
client.encryption.ssss.pendingShareRequests.clear();
|
client.encryption!.ssss.pendingShareRequests.clear();
|
||||||
await client.encryption.ssss.request('best animal', [key]);
|
await client.encryption!.ssss.request('best animal', [key]);
|
||||||
event = ToDeviceEvent(
|
event = ToDeviceEvent(
|
||||||
sender: client.userID,
|
sender: client.userID!,
|
||||||
type: 'm.secret.send',
|
type: 'm.secret.send',
|
||||||
content: {
|
content: {
|
||||||
'request_id': 'invalid',
|
'request_id': 'invalid',
|
||||||
|
|
@ -390,103 +391,103 @@ void main() {
|
||||||
'sender_key': key.curve25519Key,
|
'sender_key': key.curve25519Key,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
await client.encryption.ssss.handleToDeviceEvent(event);
|
await client.encryption!.ssss.handleToDeviceEvent(event);
|
||||||
expect(await client.encryption.ssss.getCached('best animal'), null);
|
expect(await client.encryption!.ssss.getCached('best animal'), null);
|
||||||
|
|
||||||
// not from a device we sent the request to
|
// not from a device we sent the request to
|
||||||
await client.encryption.ssss.clearCache();
|
await client.encryption!.ssss.clearCache();
|
||||||
client.encryption.ssss.pendingShareRequests.clear();
|
client.encryption!.ssss.pendingShareRequests.clear();
|
||||||
await client.encryption.ssss.request('best animal', [key]);
|
await client.encryption!.ssss.request('best animal', [key]);
|
||||||
event = ToDeviceEvent(
|
event = ToDeviceEvent(
|
||||||
sender: client.userID,
|
sender: client.userID!,
|
||||||
type: 'm.secret.send',
|
type: 'm.secret.send',
|
||||||
content: {
|
content: {
|
||||||
'request_id': client.encryption.ssss.pendingShareRequests.keys.first,
|
'request_id': client.encryption!.ssss.pendingShareRequests.keys.first,
|
||||||
'secret': 'foxies!',
|
'secret': 'foxies!',
|
||||||
},
|
},
|
||||||
encryptedContent: {
|
encryptedContent: {
|
||||||
'sender_key': 'invalid',
|
'sender_key': 'invalid',
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
await client.encryption.ssss.handleToDeviceEvent(event);
|
await client.encryption!.ssss.handleToDeviceEvent(event);
|
||||||
expect(await client.encryption.ssss.getCached('best animal'), null);
|
expect(await client.encryption!.ssss.getCached('best animal'), null);
|
||||||
|
|
||||||
// secret not a string
|
// secret not a string
|
||||||
await client.encryption.ssss.clearCache();
|
await client.encryption!.ssss.clearCache();
|
||||||
client.encryption.ssss.pendingShareRequests.clear();
|
client.encryption!.ssss.pendingShareRequests.clear();
|
||||||
await client.encryption.ssss.request('best animal', [key]);
|
await client.encryption!.ssss.request('best animal', [key]);
|
||||||
event = ToDeviceEvent(
|
event = ToDeviceEvent(
|
||||||
sender: client.userID,
|
sender: client.userID!,
|
||||||
type: 'm.secret.send',
|
type: 'm.secret.send',
|
||||||
content: {
|
content: {
|
||||||
'request_id': client.encryption.ssss.pendingShareRequests.keys.first,
|
'request_id': client.encryption!.ssss.pendingShareRequests.keys.first,
|
||||||
'secret': 42,
|
'secret': 42,
|
||||||
},
|
},
|
||||||
encryptedContent: {
|
encryptedContent: {
|
||||||
'sender_key': key.curve25519Key,
|
'sender_key': key.curve25519Key,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
await client.encryption.ssss.handleToDeviceEvent(event);
|
await client.encryption!.ssss.handleToDeviceEvent(event);
|
||||||
expect(await client.encryption.ssss.getCached('best animal'), null);
|
expect(await client.encryption!.ssss.getCached('best animal'), null);
|
||||||
|
|
||||||
// validator doesn't check out
|
// validator doesn't check out
|
||||||
await client.encryption.ssss.clearCache();
|
await client.encryption!.ssss.clearCache();
|
||||||
client.encryption.ssss.pendingShareRequests.clear();
|
client.encryption!.ssss.pendingShareRequests.clear();
|
||||||
await client.encryption.ssss.request(EventTypes.MegolmBackup, [key]);
|
await client.encryption!.ssss.request(EventTypes.MegolmBackup, [key]);
|
||||||
event = ToDeviceEvent(
|
event = ToDeviceEvent(
|
||||||
sender: client.userID,
|
sender: client.userID!,
|
||||||
type: 'm.secret.send',
|
type: 'm.secret.send',
|
||||||
content: {
|
content: {
|
||||||
'request_id': client.encryption.ssss.pendingShareRequests.keys.first,
|
'request_id': client.encryption!.ssss.pendingShareRequests.keys.first,
|
||||||
'secret': 'foxies!',
|
'secret': 'foxies!',
|
||||||
},
|
},
|
||||||
encryptedContent: {
|
encryptedContent: {
|
||||||
'sender_key': key.curve25519Key,
|
'sender_key': key.curve25519Key,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
await client.encryption.ssss.handleToDeviceEvent(event);
|
await client.encryption!.ssss.handleToDeviceEvent(event);
|
||||||
expect(await client.encryption.ssss.getCached(EventTypes.MegolmBackup),
|
expect(await client.encryption!.ssss.getCached(EventTypes.MegolmBackup),
|
||||||
null);
|
null);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('request all', () async {
|
test('request all', () async {
|
||||||
if (!olmEnabled) return;
|
if (!olmEnabled) return;
|
||||||
final key =
|
final key =
|
||||||
client.userDeviceKeys[client.userID].deviceKeys['OTHERDEVICE'];
|
client.userDeviceKeys[client.userID!]!.deviceKeys['OTHERDEVICE']!;
|
||||||
key.setDirectVerified(true);
|
key.setDirectVerified(true);
|
||||||
await client.encryption.ssss.clearCache();
|
await client.encryption!.ssss.clearCache();
|
||||||
client.encryption.ssss.pendingShareRequests.clear();
|
client.encryption!.ssss.pendingShareRequests.clear();
|
||||||
await client.encryption.ssss.maybeRequestAll([key]);
|
await client.encryption!.ssss.maybeRequestAll([key]);
|
||||||
expect(client.encryption.ssss.pendingShareRequests.length, 3);
|
expect(client.encryption!.ssss.pendingShareRequests.length, 3);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('periodicallyRequestMissingCache', () async {
|
test('periodicallyRequestMissingCache', () async {
|
||||||
if (!olmEnabled) return;
|
if (!olmEnabled) return;
|
||||||
client.userDeviceKeys[client.userID].masterKey.setDirectVerified(true);
|
client.userDeviceKeys[client.userID!]!.masterKey!.setDirectVerified(true);
|
||||||
client.encryption.ssss = MockSSSS(client.encryption);
|
client.encryption!.ssss = MockSSSS(client.encryption!);
|
||||||
(client.encryption.ssss as MockSSSS).requestedSecrets = false;
|
(client.encryption!.ssss as MockSSSS).requestedSecrets = false;
|
||||||
await client.encryption.ssss.periodicallyRequestMissingCache();
|
await client.encryption!.ssss.periodicallyRequestMissingCache();
|
||||||
expect((client.encryption.ssss as MockSSSS).requestedSecrets, true);
|
expect((client.encryption!.ssss as MockSSSS).requestedSecrets, true);
|
||||||
// it should only retry once every 15 min
|
// it should only retry once every 15 min
|
||||||
(client.encryption.ssss as MockSSSS).requestedSecrets = false;
|
(client.encryption!.ssss as MockSSSS).requestedSecrets = false;
|
||||||
await client.encryption.ssss.periodicallyRequestMissingCache();
|
await client.encryption!.ssss.periodicallyRequestMissingCache();
|
||||||
expect((client.encryption.ssss as MockSSSS).requestedSecrets, false);
|
expect((client.encryption!.ssss as MockSSSS).requestedSecrets, false);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('createKey', () async {
|
test('createKey', () async {
|
||||||
if (!olmEnabled) return;
|
if (!olmEnabled) return;
|
||||||
// with passphrase
|
// with passphrase
|
||||||
var newKey = await client.encryption.ssss.createKey('test');
|
var newKey = await client.encryption!.ssss.createKey('test');
|
||||||
expect(client.encryption.ssss.isKeyValid(newKey.keyId), true);
|
expect(client.encryption!.ssss.isKeyValid(newKey.keyId), true);
|
||||||
var testKey = client.encryption.ssss.open(newKey.keyId);
|
var testKey = client.encryption!.ssss.open(newKey.keyId);
|
||||||
await testKey.unlock(passphrase: 'test');
|
await testKey.unlock(passphrase: 'test');
|
||||||
await testKey.setPrivateKey(newKey.privateKey);
|
await testKey.setPrivateKey(newKey.privateKey!);
|
||||||
|
|
||||||
// without passphrase
|
// without passphrase
|
||||||
newKey = await client.encryption.ssss.createKey();
|
newKey = await client.encryption!.ssss.createKey();
|
||||||
expect(client.encryption.ssss.isKeyValid(newKey.keyId), true);
|
expect(client.encryption!.ssss.isKeyValid(newKey.keyId), true);
|
||||||
testKey = client.encryption.ssss.open(newKey.keyId);
|
testKey = client.encryption!.ssss.open(newKey.keyId);
|
||||||
await testKey.setPrivateKey(newKey.privateKey);
|
await testKey.setPrivateKey(newKey.privateKey!);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('dispose client', () async {
|
test('dispose client', () async {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue