diff --git a/lib/encryption/key_manager.dart b/lib/encryption/key_manager.dart index b7f451d5..dbd75e27 100644 --- a/lib/encryption/key_manager.dart +++ b/lib/encryption/key_manager.dart @@ -256,7 +256,7 @@ class KeyManager { if (!deviceKeyIds.containsKey(device.userId)) { deviceKeyIds[device.userId] = {}; } - 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>(device.userId) ?.tryGet(device.deviceId) != diff --git a/lib/src/utils/device_keys_list.dart b/lib/src/utils/device_keys_list.dart index 83b3d0ed..98591ab3 100644 --- a/lib/src/utils/device_keys_list.dart +++ b/lib/src/utils/device_keys_list.dart @@ -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 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; diff --git a/test/device_keys_list_test.dart b/test/device_keys_list_test.dart index ae69029c..4f4aec8c 100644 --- a/test/device_keys_list_test.dart +++ b/test/device_keys_list_test.dart @@ -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': {}, + }, 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,