diff --git a/lib/encryption/utils/key_verification.dart b/lib/encryption/utils/key_verification.dart index c0cdcfc1..489638e3 100644 --- a/lib/encryption/utils/key_verification.dart +++ b/lib/encryption/utils/key_verification.dart @@ -160,10 +160,13 @@ class KeyVerification { } Future sendStart() async { - await send(EventTypes.KeyVerificationRequest, { - 'methods': knownVerificationMethods, - if (room == null) 'timestamp': DateTime.now().millisecondsSinceEpoch, - }); + await send( + EventTypes.KeyVerificationRequest, + { + 'methods': knownVerificationMethods, + if (room == null) 'timestamp': DateTime.now().millisecondsSinceEpoch, + }, + ); startedVerification = true; setState(KeyVerificationState.waitingAccept); lastActivity = DateTime.now(); @@ -604,7 +607,10 @@ class KeyVerification { } } - Future send(String type, Map payload) async { + Future send( + String type, + Map payload, + ) async { makePayload(payload); Logs().i('[Key Verification] Sending type $type: $payload'); if (room != null) { @@ -628,7 +634,17 @@ class KeyVerification { EventTypes.KeyVerificationRequest, EventTypes.KeyVerificationCancel, }.contains(type)) { - await client.sendToDevicesOfUserIds({userId}, type, payload); + final deviceKeys = client.userDeviceKeys[userId]?.deviceKeys.values + .where((deviceKey) => deviceKey.hasValidSignatureChain( + verifiedByTheirMasterKey: true)); + + if (deviceKeys != null) { + await client.sendToDeviceEncrypted( + deviceKeys.toList(), + type, + payload, + ); + } } else { Logs().e( '[Key Verification] Tried to broadcast and un-broadcastable type: $type'); diff --git a/lib/src/utils/device_keys_list.dart b/lib/src/utils/device_keys_list.dart index a18c90be..fb66e91e 100644 --- a/lib/src/utils/device_keys_list.dart +++ b/lib/src/utils/device_keys_list.dart @@ -93,7 +93,7 @@ class DeviceKeysList { // verification request that'll happen automatically once we know the transaction id return request; } else { - // broadcast self-verification + // start verification with verified devices final request = KeyVerification( encryption: encryption, userId: userId, deviceId: '*'); await request.start(); @@ -216,10 +216,14 @@ abstract class SignableKey extends MatrixSignableKey { return valid; } - bool hasValidSignatureChain( - {bool verifiedOnly = true, - Set? visited, - Set? onlyValidateUserIds}) { + bool hasValidSignatureChain({ + bool verifiedOnly = true, + Set? visited, + Set? onlyValidateUserIds, + + /// Only check if this key is verified by their Master key. + bool verifiedByTheirMasterKey = false, + }) { if (!client.encryptionEnabled) { return false; } @@ -300,15 +304,16 @@ abstract class SignableKey extends MatrixSignableKey { if ((verifiedOnly && key.directVerified) || (key is CrossSigningKey && key.usage.contains('master') && - key.directVerified && - key.userId == client.userID)) { + (verifiedByTheirMasterKey || + (key.directVerified && key.userId == client.userID)))) { return true; // we verified this key and it is valid...all checks out! } - // or else we just recurse into that key and chack if it works out + // or else we just recurse into that key and check if it works out final haveChain = key.hasValidSignatureChain( verifiedOnly: verifiedOnly, visited: visited_, - onlyValidateUserIds: onlyValidateUserIds); + onlyValidateUserIds: onlyValidateUserIds, + verifiedByTheirMasterKey: verifiedByTheirMasterKey); if (haveChain) { return true; }