add signature verification tests
This commit is contained in:
parent
9b2952435f
commit
e874a5e00b
|
@ -1135,7 +1135,7 @@ class Client {
|
||||||
var outdatedLists = <String, dynamic>{};
|
var outdatedLists = <String, dynamic>{};
|
||||||
for (var userId in trackedUserIds) {
|
for (var userId in trackedUserIds) {
|
||||||
if (!userDeviceKeys.containsKey(userId)) {
|
if (!userDeviceKeys.containsKey(userId)) {
|
||||||
_userDeviceKeys[userId] = DeviceKeysList(userId);
|
_userDeviceKeys[userId] = DeviceKeysList(userId, this);
|
||||||
}
|
}
|
||||||
var deviceKeysList = userDeviceKeys[userId];
|
var deviceKeysList = userDeviceKeys[userId];
|
||||||
if (deviceKeysList.outdated) {
|
if (deviceKeysList.outdated) {
|
||||||
|
@ -1151,7 +1151,7 @@ class Client {
|
||||||
for (final rawDeviceKeyListEntry in response.deviceKeys.entries) {
|
for (final rawDeviceKeyListEntry in response.deviceKeys.entries) {
|
||||||
final userId = rawDeviceKeyListEntry.key;
|
final userId = rawDeviceKeyListEntry.key;
|
||||||
if (!userDeviceKeys.containsKey(userId)) {
|
if (!userDeviceKeys.containsKey(userId)) {
|
||||||
_userDeviceKeys[userId] = DeviceKeysList(userId);
|
_userDeviceKeys[userId] = DeviceKeysList(userId, this);
|
||||||
}
|
}
|
||||||
final oldKeys =
|
final oldKeys =
|
||||||
Map<String, DeviceKeys>.from(_userDeviceKeys[userId].deviceKeys);
|
Map<String, DeviceKeys>.from(_userDeviceKeys[userId].deviceKeys);
|
||||||
|
@ -1230,7 +1230,7 @@ class Client {
|
||||||
for (final crossSigningKeyListEntry in keys.entries) {
|
for (final crossSigningKeyListEntry in keys.entries) {
|
||||||
final userId = crossSigningKeyListEntry.key;
|
final userId = crossSigningKeyListEntry.key;
|
||||||
if (!userDeviceKeys.containsKey(userId)) {
|
if (!userDeviceKeys.containsKey(userId)) {
|
||||||
_userDeviceKeys[userId] = DeviceKeysList(userId);
|
_userDeviceKeys[userId] = DeviceKeysList(userId, this);
|
||||||
}
|
}
|
||||||
final oldKeys = Map<String, CrossSigningKey>.from(
|
final oldKeys = Map<String, CrossSigningKey>.from(
|
||||||
_userDeviceKeys[userId].crossSigningKeys);
|
_userDeviceKeys[userId].crossSigningKeys);
|
||||||
|
|
|
@ -54,6 +54,8 @@ class DeviceKeysList {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<KeyVerification> startVerification() async {
|
Future<KeyVerification> startVerification() async {
|
||||||
|
print('++++++++++++');
|
||||||
|
print(client.toString());
|
||||||
final roomId =
|
final roomId =
|
||||||
await User(userId, room: Room(client: client)).startDirectChat();
|
await User(userId, room: Room(client: client)).startDirectChat();
|
||||||
if (roomId == null) {
|
if (roomId == null) {
|
||||||
|
@ -95,7 +97,7 @@ class DeviceKeysList {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DeviceKeysList(this.userId);
|
DeviceKeysList(this.userId, this.client);
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class SignableKey extends MatrixSignableKey {
|
abstract class SignableKey extends MatrixSignableKey {
|
||||||
|
@ -239,7 +241,8 @@ abstract class SignableKey extends MatrixSignableKey {
|
||||||
|
|
||||||
Future<void> setVerified(bool newVerified, [bool sign = true]) {
|
Future<void> setVerified(bool newVerified, [bool sign = true]) {
|
||||||
_verified = newVerified;
|
_verified = newVerified;
|
||||||
if (sign &&
|
if (newVerified &&
|
||||||
|
sign &&
|
||||||
client.encryptionEnabled &&
|
client.encryptionEnabled &&
|
||||||
client.encryption.crossSigning.signable([this])) {
|
client.encryption.crossSigning.signable([this])) {
|
||||||
// sign the key!
|
// sign the key!
|
||||||
|
|
|
@ -20,6 +20,10 @@ import 'dart:convert';
|
||||||
|
|
||||||
import 'package:famedlysdk/famedlysdk.dart';
|
import 'package:famedlysdk/famedlysdk.dart';
|
||||||
import 'package:test/test.dart';
|
import 'package:test/test.dart';
|
||||||
|
import 'package:olm/olm.dart' as olm;
|
||||||
|
|
||||||
|
import './fake_client.dart';
|
||||||
|
import './fake_matrix_api.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
/// All Tests related to device keys
|
/// All Tests related to device keys
|
||||||
|
@ -49,6 +53,125 @@ void main() {
|
||||||
expect(json.encode(key.toJson()), json.encode(rawJson));
|
expect(json.encode(key.toJson()), json.encode(rawJson));
|
||||||
expect(key.directVerified, false);
|
expect(key.directVerified, false);
|
||||||
expect(key.blocked, true);
|
expect(key.blocked, true);
|
||||||
|
|
||||||
|
rawJson = <String, dynamic>{
|
||||||
|
'user_id': '@test:fakeServer.notExisting',
|
||||||
|
'usage': ['master'],
|
||||||
|
'keys': {
|
||||||
|
'ed25519:82mAXjsmbTbrE6zyShpR869jnrANO75H8nYY0nDLoJ8':
|
||||||
|
'82mAXjsmbTbrE6zyShpR869jnrANO75H8nYY0nDLoJ8',
|
||||||
|
},
|
||||||
|
'signatures': {},
|
||||||
|
};
|
||||||
|
final crossKey = CrossSigningKey.fromJson(rawJson, null);
|
||||||
|
expect(json.encode(crossKey.toJson()), json.encode(rawJson));
|
||||||
|
expect(crossKey.usage.first, 'master');
|
||||||
|
});
|
||||||
|
|
||||||
|
var olmEnabled = true;
|
||||||
|
try {
|
||||||
|
olm.init();
|
||||||
|
olm.Account();
|
||||||
|
} catch (_) {
|
||||||
|
olmEnabled = false;
|
||||||
|
print('[LibOlm] Failed to load LibOlm: ' + _.toString());
|
||||||
|
}
|
||||||
|
print('[LibOlm] Enabled: $olmEnabled');
|
||||||
|
|
||||||
|
if (!olmEnabled) return;
|
||||||
|
|
||||||
|
Client client;
|
||||||
|
|
||||||
|
test('setupClient', () async {
|
||||||
|
client = await getClient();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('set blocked / verified', () async {
|
||||||
|
final key =
|
||||||
|
client.userDeviceKeys[client.userID].deviceKeys['OTHERDEVICE'];
|
||||||
|
final masterKey = client.userDeviceKeys[client.userID].masterKey;
|
||||||
|
masterKey.setDirectVerified(true);
|
||||||
|
// we need to populate the ssss cache to be able to test signing easily
|
||||||
|
final handle = client.encryption.ssss.open();
|
||||||
|
handle.unlock(recoveryKey: SSSS_KEY);
|
||||||
|
await handle.maybeCacheAll();
|
||||||
|
|
||||||
|
expect(key.verified, true);
|
||||||
|
await key.setBlocked(true);
|
||||||
|
expect(key.verified, false);
|
||||||
|
await key.setBlocked(false);
|
||||||
|
expect(key.directVerified, false);
|
||||||
|
expect(key.verified, true); // still verified via cross-sgining
|
||||||
|
|
||||||
|
expect(masterKey.verified, true);
|
||||||
|
await masterKey.setBlocked(true);
|
||||||
|
expect(masterKey.verified, false);
|
||||||
|
await masterKey.setBlocked(false);
|
||||||
|
expect(masterKey.verified, true);
|
||||||
|
|
||||||
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
|
await key.setVerified(true);
|
||||||
|
await Future.delayed(Duration(milliseconds: 10));
|
||||||
|
expect(
|
||||||
|
FakeMatrixApi.calledEndpoints.keys
|
||||||
|
.any((k) => k == '/client/r0/keys/signatures/upload'),
|
||||||
|
true);
|
||||||
|
expect(key.directVerified, true);
|
||||||
|
|
||||||
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
|
await key.setVerified(false);
|
||||||
|
await Future.delayed(Duration(milliseconds: 10));
|
||||||
|
expect(
|
||||||
|
FakeMatrixApi.calledEndpoints.keys
|
||||||
|
.any((k) => k == '/client/r0/keys/signatures/upload'),
|
||||||
|
false);
|
||||||
|
expect(key.directVerified, false);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('verification based on signatures', () async {
|
||||||
|
final user = client.userDeviceKeys[client.userID];
|
||||||
|
user.masterKey.setDirectVerified(true);
|
||||||
|
expect(user.deviceKeys['GHTYAJCE'].crossVerified, true);
|
||||||
|
expect(user.deviceKeys['GHTYAJCE'].signed, true);
|
||||||
|
expect(user.getKey('GHTYAJCE').crossVerified, true);
|
||||||
|
expect(user.deviceKeys['OTHERDEVICE'].crossVerified, true);
|
||||||
|
expect(user.selfSigningKey.crossVerified, true);
|
||||||
|
expect(
|
||||||
|
user
|
||||||
|
.getKey('F9ypFzgbISXCzxQhhSnXMkc1vq12Luna3Nw5rqViOJY')
|
||||||
|
.crossVerified,
|
||||||
|
true);
|
||||||
|
expect(user.userSigningKey.crossVerified, true);
|
||||||
|
expect(user.verified, UserVerifiedStatus.verified);
|
||||||
|
user.masterKey.setDirectVerified(false);
|
||||||
|
expect(user.deviceKeys['GHTYAJCE'].crossVerified, false);
|
||||||
|
expect(user.deviceKeys['OTHERDEVICE'].crossVerified, false);
|
||||||
|
expect(user.verified, UserVerifiedStatus.unknown);
|
||||||
|
user.masterKey.setDirectVerified(true);
|
||||||
|
user.deviceKeys['GHTYAJCE'].signatures.clear();
|
||||||
|
expect(user.deviceKeys['GHTYAJCE'].verified,
|
||||||
|
true); // it's our own device, should be direct verified
|
||||||
|
expect(
|
||||||
|
user.deviceKeys['GHTYAJCE'].signed, false); // not verified for others
|
||||||
|
user.deviceKeys['OTHERDEVICE'].signatures.clear();
|
||||||
|
expect(user.verified, UserVerifiedStatus.unknownDevice);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('start verification', () async {
|
||||||
|
var req = client
|
||||||
|
.userDeviceKeys['@alice:example.com'].deviceKeys['JLAFKJWSCS']
|
||||||
|
.startVerification();
|
||||||
|
expect(req != null, true);
|
||||||
|
expect(req.room != null, false);
|
||||||
|
|
||||||
|
req =
|
||||||
|
await client.userDeviceKeys['@alice:example.com'].startVerification();
|
||||||
|
expect(req != null, true);
|
||||||
|
expect(req.room != null, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('dispose client', () async {
|
||||||
|
await client.dispose(closeDatabase: true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1799,7 +1799,12 @@ class FakeMatrixApi extends MockClient {
|
||||||
'ed25519:GHTYAJCE':
|
'ed25519:GHTYAJCE':
|
||||||
'gjL//fyaFHADt9KBADGag8g7F8Up78B/K1zXeiEPLJo'
|
'gjL//fyaFHADt9KBADGag8g7F8Up78B/K1zXeiEPLJo'
|
||||||
},
|
},
|
||||||
'signatures': {},
|
'signatures': {
|
||||||
|
'@test:fakeServer.notExisting': {
|
||||||
|
'ed25519:F9ypFzgbISXCzxQhhSnXMkc1vq12Luna3Nw5rqViOJY':
|
||||||
|
'Q4/55vZjEJD7M2EC40bgZqd9Zuy/4C75UPVopJdXeioQVaKtFf6EF0nUUuql0yD+r3hinsZcock0wO6Q2xcoAQ',
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
'OTHERDEVICE': {
|
'OTHERDEVICE': {
|
||||||
'user_id': '@test:fakeServer.notExisting',
|
'user_id': '@test:fakeServer.notExisting',
|
||||||
|
@ -1812,7 +1817,12 @@ class FakeMatrixApi extends MockClient {
|
||||||
'curve25519:OTHERDEVICE': 'blah',
|
'curve25519:OTHERDEVICE': 'blah',
|
||||||
'ed25519:OTHERDEVICE': 'blah'
|
'ed25519:OTHERDEVICE': 'blah'
|
||||||
},
|
},
|
||||||
'signatures': {},
|
'signatures': {
|
||||||
|
'@test:fakeServer.notExisting': {
|
||||||
|
'ed25519:F9ypFzgbISXCzxQhhSnXMkc1vq12Luna3Nw5rqViOJY':
|
||||||
|
'o7ucKPWrF2VKx7wYqP1f+aw4QohLMz7kX+SIw6aWCYsLC3XyIlg8rX/7QQ9B8figCVnRK7IjtjWvQodBCfWCAA',
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'@othertest:fakeServer.notExisting': {
|
'@othertest:fakeServer.notExisting': {
|
||||||
|
@ -1860,7 +1870,12 @@ class FakeMatrixApi extends MockClient {
|
||||||
'ed25519:F9ypFzgbISXCzxQhhSnXMkc1vq12Luna3Nw5rqViOJY':
|
'ed25519:F9ypFzgbISXCzxQhhSnXMkc1vq12Luna3Nw5rqViOJY':
|
||||||
'F9ypFzgbISXCzxQhhSnXMkc1vq12Luna3Nw5rqViOJY',
|
'F9ypFzgbISXCzxQhhSnXMkc1vq12Luna3Nw5rqViOJY',
|
||||||
},
|
},
|
||||||
'signatures': {},
|
'signatures': {
|
||||||
|
'@test:fakeServer.notExisting': {
|
||||||
|
'ed25519:82mAXjsmbTbrE6zyShpR869jnrANO75H8nYY0nDLoJ8':
|
||||||
|
'afkrbGvPn5Zb5zc7Lk9cz2skI3QrzI/L0st1GS+/GATxNjMzc6vKmGu7r9cMb1GJxy4RdeUpfH3L7Fs/fNL1Dw',
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
'@othertest:fakeServer.notExisting': {
|
'@othertest:fakeServer.notExisting': {
|
||||||
'user_id': '@othertest:fakeServer.notExisting',
|
'user_id': '@othertest:fakeServer.notExisting',
|
||||||
|
@ -1879,7 +1894,12 @@ class FakeMatrixApi extends MockClient {
|
||||||
'ed25519:0PiwulzJ/RU86LlzSSZ8St80HUMN3dqjKa/orIJoA0g':
|
'ed25519:0PiwulzJ/RU86LlzSSZ8St80HUMN3dqjKa/orIJoA0g':
|
||||||
'0PiwulzJ/RU86LlzSSZ8St80HUMN3dqjKa/orIJoA0g',
|
'0PiwulzJ/RU86LlzSSZ8St80HUMN3dqjKa/orIJoA0g',
|
||||||
},
|
},
|
||||||
'signatures': {},
|
'signatures': {
|
||||||
|
'@test:fakeServer.notExisting': {
|
||||||
|
'ed25519:82mAXjsmbTbrE6zyShpR869jnrANO75H8nYY0nDLoJ8':
|
||||||
|
'pvgbZxEbllaElhpiRnb7/uOIUhrglvHCFnpoxr3/5ZrWa0EK/uaefhex9eEV4uBLrHjHg2ymwdNaM7ap9+sBBg',
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
'@othertest:fakeServer.notExisting': {
|
'@othertest:fakeServer.notExisting': {
|
||||||
'user_id': '@othertest:fakeServer.notExisting',
|
'user_id': '@othertest:fakeServer.notExisting',
|
||||||
|
|
Loading…
Reference in a new issue