From 56817df437342057ba220bee561c9e20b00920c3 Mon Sep 17 00:00:00 2001 From: Sorunome Date: Fri, 27 Aug 2021 16:59:01 +0200 Subject: [PATCH] fix: missing null check It seems `device_keys` in the reply of `/keys/query` is not required. While synapse always sent it, conduit did not, which resulted in an error. --- lib/src/client.dart | 131 ++++++++++++++++++++++---------------------- 1 file changed, 67 insertions(+), 64 deletions(-) diff --git a/lib/src/client.dart b/lib/src/client.dart index c58f7387..6ed81e06 100644 --- a/lib/src/client.dart +++ b/lib/src/client.dart @@ -1663,74 +1663,77 @@ sort order of ${prevState.sortOrder}. This should never happen...'''); final response = await queryKeys(outdatedLists, timeout: 10000); if (!isLogged()) return; - for (final rawDeviceKeyListEntry in response.deviceKeys.entries) { - final userId = rawDeviceKeyListEntry.key; - if (!userDeviceKeys.containsKey(userId)) { - _userDeviceKeys[userId] = DeviceKeysList(userId, this); - } - final oldKeys = - Map.from(_userDeviceKeys[userId].deviceKeys); - _userDeviceKeys[userId].deviceKeys = {}; - for (final rawDeviceKeyEntry in rawDeviceKeyListEntry.value.entries) { - final deviceId = rawDeviceKeyEntry.key; + if (response.deviceKeys != null) { + for (final rawDeviceKeyListEntry in response.deviceKeys.entries) { + final userId = rawDeviceKeyListEntry.key; + if (!userDeviceKeys.containsKey(userId)) { + _userDeviceKeys[userId] = DeviceKeysList(userId, this); + } + final oldKeys = Map.from( + _userDeviceKeys[userId].deviceKeys); + _userDeviceKeys[userId].deviceKeys = {}; + for (final rawDeviceKeyEntry + in rawDeviceKeyListEntry.value.entries) { + final deviceId = rawDeviceKeyEntry.key; - // Set the new device key for this device - final entry = DeviceKeys.fromMatrixDeviceKeys( - rawDeviceKeyEntry.value, this, oldKeys[deviceId]?.lastActive); - if (entry.isValid) { - // is this a new key or the same one as an old one? - // better store an update - the signatures might have changed! - if (!oldKeys.containsKey(deviceId) || - oldKeys[deviceId].ed25519Key == entry.ed25519Key) { - if (oldKeys.containsKey(deviceId)) { - // be sure to save the verified status - entry.setDirectVerified(oldKeys[deviceId].directVerified); - entry.blocked = oldKeys[deviceId].blocked; - entry.validSignatures = oldKeys[deviceId].validSignatures; + // Set the new device key for this device + final entry = DeviceKeys.fromMatrixDeviceKeys( + rawDeviceKeyEntry.value, this, oldKeys[deviceId]?.lastActive); + if (entry.isValid) { + // is this a new key or the same one as an old one? + // better store an update - the signatures might have changed! + if (!oldKeys.containsKey(deviceId) || + oldKeys[deviceId].ed25519Key == entry.ed25519Key) { + if (oldKeys.containsKey(deviceId)) { + // be sure to save the verified status + entry.setDirectVerified(oldKeys[deviceId].directVerified); + entry.blocked = oldKeys[deviceId].blocked; + entry.validSignatures = oldKeys[deviceId].validSignatures; + } + _userDeviceKeys[userId].deviceKeys[deviceId] = entry; + if (deviceId == deviceID && + entry.ed25519Key == fingerprintKey) { + // Always trust the own device + entry.setDirectVerified(true); + } + if (database != null) { + dbActions.add(() => database.storeUserDeviceKey( + id, + userId, + deviceId, + json.encode(entry.toJson()), + entry.directVerified, + entry.blocked, + entry.lastActive.millisecondsSinceEpoch, + )); + } + } else if (oldKeys.containsKey(deviceId)) { + // This shouldn't ever happen. The same device ID has gotten + // a new public key. So we ignore the update. TODO: ask krille + // if we should instead use the new key with unknown verified / blocked status + _userDeviceKeys[userId].deviceKeys[deviceId] = + oldKeys[deviceId]; } - _userDeviceKeys[userId].deviceKeys[deviceId] = entry; - if (deviceId == deviceID && - entry.ed25519Key == fingerprintKey) { - // Always trust the own device - entry.setDirectVerified(true); - } - if (database != null) { - dbActions.add(() => database.storeUserDeviceKey( - id, - userId, - deviceId, - json.encode(entry.toJson()), - entry.directVerified, - entry.blocked, - entry.lastActive.millisecondsSinceEpoch, - )); - } - } else if (oldKeys.containsKey(deviceId)) { - // This shouldn't ever happen. The same device ID has gotten - // a new public key. So we ignore the update. TODO: ask krille - // if we should instead use the new key with unknown verified / blocked status - _userDeviceKeys[userId].deviceKeys[deviceId] = - oldKeys[deviceId]; - } - } else { - Logs().w('Invalid device ${entry.userId}:${entry.deviceId}'); - } - } - // delete old/unused entries - if (database != null) { - for (final oldDeviceKeyEntry in oldKeys.entries) { - final deviceId = oldDeviceKeyEntry.key; - if (!_userDeviceKeys[userId].deviceKeys.containsKey(deviceId)) { - // we need to remove an old key - dbActions.add( - () => database.removeUserDeviceKey(id, userId, deviceId)); + } else { + Logs().w('Invalid device ${entry.userId}:${entry.deviceId}'); } } - } - _userDeviceKeys[userId].outdated = false; - if (database != null) { - dbActions - .add(() => database.storeUserDeviceKeysInfo(id, userId, false)); + // delete old/unused entries + if (database != null) { + for (final oldDeviceKeyEntry in oldKeys.entries) { + final deviceId = oldDeviceKeyEntry.key; + if (!_userDeviceKeys[userId].deviceKeys.containsKey(deviceId)) { + // we need to remove an old key + dbActions.add( + () => database.removeUserDeviceKey(id, userId, deviceId)); + } + } + } + _userDeviceKeys[userId].outdated = false; + if (database != null) { + dbActions.add( + () => database.storeUserDeviceKeysInfo(id, userId, false)); + } } } // next we parse and persist the cross signing keys