feat: Better determine which devices to encrypt to

This commit is contained in:
Sorunome 2020-12-21 15:08:21 +01:00
parent dfd88277b9
commit b00a9e8834
No known key found for this signature in database
GPG Key ID: B19471D07FC9BE9C
3 changed files with 46 additions and 4 deletions

View File

@ -256,7 +256,7 @@ class KeyManager {
if (!deviceKeyIds.containsKey(device.userId)) {
deviceKeyIds[device.userId] = <String, bool>{};
}
deviceKeyIds[device.userId][device.deviceId] = device.blocked;
deviceKeyIds[device.userId][device.deviceId] = !device.encryptToDevice;
}
return deviceKeyIds;
}
@ -429,7 +429,7 @@ class KeyManager {
}
final deviceKeys = await room.getUserDeviceKeys();
final deviceKeyIds = _getDeviceKeyIdMap(deviceKeys);
deviceKeys.removeWhere((k) => k.blocked);
deviceKeys.removeWhere((k) => !k.encryptToDevice);
final outboundGroupSession = olm.OutboundGroupSession();
try {
outboundGroupSession.create();
@ -794,7 +794,7 @@ class KeyManager {
Logs().i('[KeyManager] All checks out, forwarding key...');
// alright, we can forward the key
await roomKeyRequest.forwardKey();
} else if (!device.blocked &&
} else if (device.encryptToDevice &&
session.allowedAtIndex
.tryGet<Map<String, dynamic>>(device.userId)
?.tryGet(device.deviceId) !=

View File

@ -49,8 +49,14 @@ class DeviceKeysList {
}
}
return UserVerifiedStatus.verified;
} else {
for (final key in deviceKeys.values) {
if (!key.verified) {
return UserVerifiedStatus.unknown;
}
}
return UserVerifiedStatus.verified;
}
return UserVerifiedStatus.unknown;
}
Future<KeyVerification> startVerification() async {
@ -117,6 +123,11 @@ abstract class SignableKey extends MatrixSignableKey {
String get ed25519Key => keys['ed25519:$identifier'];
bool get verified => (directVerified || crossVerified) && !blocked;
bool get encryptToDevice =>
!blocked &&
(client.userDeviceKeys[userId]?.masterKey?.verified ?? false
? verified
: true);
void setDirectVerified(bool v) {
_verified = v;

View File

@ -95,6 +95,20 @@ void main() {
test('set blocked / verified', () async {
final key =
client.userDeviceKeys[client.userID].deviceKeys['OTHERDEVICE'];
client.userDeviceKeys[client.userID].deviceKeys['UNSIGNEDDEVICE'] =
DeviceKeys.fromJson({
'user_id': '@test:fakeServer.notExisting',
'device_id': 'UNSIGNEDDEVICE',
'algorithms': [
AlgorithmTypes.olmV1Curve25519AesSha2,
AlgorithmTypes.megolmV1AesSha2
],
'keys': {
'curve25519:UNSIGNEDDEVICE': 'blah',
'ed25519:UNSIGNEDDEVICE': 'blah'
},
'signatures': <String, dynamic>{},
}, client);
final masterKey = client.userDeviceKeys[client.userID].masterKey;
masterKey.setDirectVerified(true);
// we need to populate the ssss cache to be able to test signing easily
@ -103,15 +117,26 @@ void main() {
await handle.maybeCacheAll();
expect(key.verified, true);
expect(key.encryptToDevice, true);
await key.setBlocked(true);
expect(key.verified, false);
expect(key.encryptToDevice, false);
await key.setBlocked(false);
expect(key.directVerified, false);
expect(key.verified, true); // still verified via cross-sgining
expect(key.encryptToDevice, true);
expect(
client.userDeviceKeys[client.userID].deviceKeys['UNSIGNEDDEVICE']
.encryptToDevice,
false);
expect(masterKey.verified, true);
await masterKey.setBlocked(true);
expect(masterKey.verified, false);
expect(
client.userDeviceKeys[client.userID].deviceKeys['UNSIGNEDDEVICE']
.encryptToDevice,
true);
await masterKey.setBlocked(false);
expect(masterKey.verified, true);
@ -132,6 +157,7 @@ void main() {
.any((k) => k == '/client/r0/keys/signatures/upload'),
false);
expect(key.directVerified, false);
client.userDeviceKeys[client.userID].deviceKeys.remove('UNSIGNEDDEVICE');
});
test('verification based on signatures', () async {
@ -153,6 +179,11 @@ void main() {
expect(user.deviceKeys['GHTYAJCE'].crossVerified, false);
expect(user.deviceKeys['OTHERDEVICE'].crossVerified, false);
expect(user.verified, UserVerifiedStatus.unknown);
user.deviceKeys['OTHERDEVICE'].setDirectVerified(true);
expect(user.verified, UserVerifiedStatus.verified);
user.deviceKeys['OTHERDEVICE'].setDirectVerified(false);
user.masterKey.setDirectVerified(true);
user.deviceKeys['GHTYAJCE'].signatures.clear();
expect(user.deviceKeys['GHTYAJCE'].verified,