From e6f77924d651f09c9e5a759ff6849cd92ec25a2f Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Thu, 28 Oct 2021 03:40:52 +0200 Subject: [PATCH] refactor: port encryption tests --- test/encryption/bootstrap_test.dart | 61 ++-- test/encryption/cross_signing_test.dart | 45 +-- .../encrypt_decrypt_room_message_test.dart | 21 +- .../encrypt_decrypt_to_device_test.dart | 17 +- test/encryption/key_manager_test.dart | 285 +++++++++--------- test/encryption/key_request_test.dart | 81 ++--- test/encryption/key_verification_test.dart | 157 +++++----- test/encryption/olm_manager_test.dart | 76 ++--- test/encryption/online_key_backup_test.dart | 37 ++- test/encryption/ssss_test.dart | 213 ++++++------- 10 files changed, 506 insertions(+), 487 deletions(-) diff --git a/test/encryption/bootstrap_test.dart b/test/encryption/bootstrap_test.dart index 7cd9d1aa..69a643fe 100644 --- a/test/encryption/bootstrap_test.dart +++ b/test/encryption/bootstrap_test.dart @@ -1,4 +1,3 @@ -// @dart=2.9 /* * Famedly Matrix SDK * Copyright (C) 2020 Famedly GmbH @@ -33,9 +32,9 @@ void main() { Logs().level = Level.error; var olmEnabled = true; - Client client; - Map oldSecret; - String origKeyId; + late Client client; + late Map oldSecret; + late String origKeyId; test('setupClient', () async { client = await getClient(); @@ -53,8 +52,8 @@ void main() { Logs().i('[LibOlm] Enabled: $olmEnabled'); if (!olmEnabled) return; - Bootstrap bootstrap; - bootstrap = client.encryption.bootstrap( + Bootstrap? bootstrap; + bootstrap = client.encryption!.bootstrap( onUpdate: () async { while (bootstrap == null) { await Future.delayed(Duration(milliseconds: 5)); @@ -82,7 +81,7 @@ void main() { while (bootstrap.state != BootstrapState.done) { await Future.delayed(Duration(milliseconds: 50)); } - final defaultKey = client.encryption.ssss.open(); + final defaultKey = client.encryption!.ssss.open(); await defaultKey.unlock(passphrase: 'foxies'); // test all the x-signing keys match up @@ -95,8 +94,8 @@ void main() { expect( pubKey, client.userDeviceKeys[client.userID] - .getCrossSigningKey(keyType) - .publicKey); + ?.getCrossSigningKey(keyType) + ?.publicKey); } finally { keyObj.free(); } @@ -104,14 +103,15 @@ void main() { await defaultKey.store('foxes', 'floof'); await Future.delayed(Duration(milliseconds: 50)); - oldSecret = json.decode(json.encode(client.accountData['foxes'].content)); + oldSecret = + json.decode(json.encode(client.accountData['foxes']!.content)); origKeyId = defaultKey.keyId; }, timeout: Timeout(Duration(minutes: 2))); test('change recovery passphrase', () async { if (!olmEnabled) return; - Bootstrap bootstrap; - bootstrap = client.encryption.bootstrap( + Bootstrap? bootstrap; + bootstrap = client.encryption!.bootstrap( onUpdate: () async { while (bootstrap == null) { await Future.delayed(Duration(milliseconds: 5)); @@ -121,7 +121,7 @@ void main() { } else if (bootstrap.state == BootstrapState.askUseExistingSsss) { bootstrap.useExistingSsss(false); } else if (bootstrap.state == BootstrapState.askUnlockSsss) { - await bootstrap.oldSsssKeys[client.encryption.ssss.defaultKeyId] + await bootstrap.oldSsssKeys![client.encryption!.ssss.defaultKeyId]! .unlock(passphrase: 'foxies'); bootstrap.unlockedSsss(); } else if (bootstrap.state == BootstrapState.askNewSsss) { @@ -136,7 +136,7 @@ void main() { while (bootstrap.state != BootstrapState.done) { await Future.delayed(Duration(milliseconds: 50)); } - final defaultKey = client.encryption.ssss.open(); + final defaultKey = client.encryption!.ssss.open(); await defaultKey.unlock(passphrase: 'newfoxies'); // test all the x-signing keys match up @@ -149,8 +149,8 @@ void main() { expect( pubKey, client.userDeviceKeys[client.userID] - .getCrossSigningKey(keyType) - .publicKey); + ?.getCrossSigningKey(keyType) + ?.publicKey); } finally { keyObj.free(); } @@ -161,11 +161,11 @@ void main() { test('change passphrase with multiple keys', () async { if (!olmEnabled) return; - await client.setAccountData(client.userID, 'foxes', oldSecret); + await client.setAccountData(client.userID!, 'foxes', oldSecret); await Future.delayed(Duration(milliseconds: 50)); - Bootstrap bootstrap; - bootstrap = client.encryption.bootstrap( + Bootstrap? bootstrap; + bootstrap = client.encryption!.bootstrap( onUpdate: () async { while (bootstrap == null) { await Future.delayed(Duration(milliseconds: 5)); @@ -175,9 +175,10 @@ void main() { } else if (bootstrap.state == BootstrapState.askUseExistingSsss) { bootstrap.useExistingSsss(false); } else if (bootstrap.state == BootstrapState.askUnlockSsss) { - await bootstrap.oldSsssKeys[client.encryption.ssss.defaultKeyId] + await bootstrap.oldSsssKeys![client.encryption!.ssss.defaultKeyId]! .unlock(passphrase: 'newfoxies'); - await bootstrap.oldSsssKeys[origKeyId].unlock(passphrase: 'foxies'); + await bootstrap.oldSsssKeys![origKeyId]! + .unlock(passphrase: 'foxies'); bootstrap.unlockedSsss(); } else if (bootstrap.state == BootstrapState.askNewSsss) { await bootstrap.newSsss('supernewfoxies'); @@ -191,7 +192,7 @@ void main() { while (bootstrap.state != BootstrapState.done) { await Future.delayed(Duration(milliseconds: 50)); } - final defaultKey = client.encryption.ssss.open(); + final defaultKey = client.encryption!.ssss.open(); await defaultKey.unlock(passphrase: 'supernewfoxies'); // test all the x-signing keys match up @@ -204,8 +205,8 @@ void main() { expect( pubKey, client.userDeviceKeys[client.userID] - .getCrossSigningKey(keyType) - .publicKey); + ?.getCrossSigningKey(keyType) + ?.publicKey); } finally { keyObj.free(); } @@ -217,8 +218,8 @@ void main() { test('setup new ssss', () async { if (!olmEnabled) return; client.accountData.clear(); - Bootstrap bootstrap; - bootstrap = client.encryption.bootstrap( + Bootstrap? bootstrap; + bootstrap = client.encryption!.bootstrap( onUpdate: () async { while (bootstrap == null) { await Future.delayed(Duration(milliseconds: 5)); @@ -236,18 +237,18 @@ void main() { while (bootstrap.state != BootstrapState.done) { await Future.delayed(Duration(milliseconds: 50)); } - final defaultKey = client.encryption.ssss.open(); + final defaultKey = client.encryption!.ssss.open(); await defaultKey.unlock(passphrase: 'thenewestfoxies'); }, timeout: Timeout(Duration(minutes: 2))); test('bad ssss', () async { if (!olmEnabled) return; client.accountData.clear(); - await client.setAccountData(client.userID, 'foxes', oldSecret); + await client.setAccountData(client.userID!, 'foxes', oldSecret); await Future.delayed(Duration(milliseconds: 50)); var askedBadSsss = false; - Bootstrap bootstrap; - bootstrap = client.encryption.bootstrap( + Bootstrap? bootstrap; + bootstrap = client.encryption!.bootstrap( onUpdate: () async { while (bootstrap == null) { await Future.delayed(Duration(milliseconds: 5)); diff --git a/test/encryption/cross_signing_test.dart b/test/encryption/cross_signing_test.dart index 56628249..260dff98 100644 --- a/test/encryption/cross_signing_test.dart +++ b/test/encryption/cross_signing_test.dart @@ -1,4 +1,3 @@ -// @dart=2.9 /* * Famedly Matrix SDK * Copyright (C) 2020 Famedly GmbH @@ -32,7 +31,7 @@ void main() { Logs().level = Level.error; var olmEnabled = true; - Client client; + late Client client; test('setupClient', () async { try { @@ -50,41 +49,43 @@ void main() { test('basic things', () async { if (!olmEnabled) return; - expect(client.encryption.crossSigning.enabled, true); + expect(client.encryption?.crossSigning.enabled, true); }); test('selfSign', () async { if (!olmEnabled) return; - final key = client.userDeviceKeys[client.userID].masterKey; + final key = client.userDeviceKeys[client.userID]!.masterKey!; key.setDirectVerified(false); FakeMatrixApi.calledEndpoints.clear(); - await client.encryption.crossSigning.selfSign(recoveryKey: ssssKey); + await client.encryption!.crossSigning.selfSign(recoveryKey: ssssKey); expect(key.directVerified, true); expect( FakeMatrixApi.calledEndpoints .containsKey('/client/r0/keys/signatures/upload'), true); - expect(await client.encryption.crossSigning.isCached(), true); + expect(await client.encryption!.crossSigning.isCached(), true); }); test('signable', () async { if (!olmEnabled) return; expect( - client.encryption.crossSigning - .signable([client.userDeviceKeys[client.userID].masterKey]), + client.encryption!.crossSigning + .signable([client.userDeviceKeys[client.userID!]!.masterKey!]), true); expect( - client.encryption.crossSigning.signable([ - client.userDeviceKeys[client.userID].deviceKeys[client.deviceID] + client.encryption!.crossSigning.signable([ + client.userDeviceKeys[client.userID!]!.deviceKeys[client.deviceID!]! ]), false); expect( - client.encryption.crossSigning.signable( - [client.userDeviceKeys[client.userID].deviceKeys['OTHERDEVICE']]), + client.encryption!.crossSigning.signable([ + client.userDeviceKeys[client.userID!]!.deviceKeys['OTHERDEVICE']! + ]), true); expect( - client.encryption.crossSigning.signable([ - client.userDeviceKeys['@alice:example.com'].deviceKeys['JLAFKJWSCS'] + client.encryption!.crossSigning.signable([ + client + .userDeviceKeys['@alice:example.com']!.deviceKeys['JLAFKJWSCS']! ]), false); }); @@ -92,24 +93,24 @@ void main() { test('sign', () async { if (!olmEnabled) return; FakeMatrixApi.calledEndpoints.clear(); - await client.encryption.crossSigning.sign([ - client.userDeviceKeys[client.userID].masterKey, - client.userDeviceKeys[client.userID].deviceKeys['OTHERDEVICE'], - client.userDeviceKeys['@othertest:fakeServer.notExisting'].masterKey + await client.encryption!.crossSigning.sign([ + client.userDeviceKeys[client.userID!]!.masterKey!, + client.userDeviceKeys[client.userID!]!.deviceKeys['OTHERDEVICE']!, + client.userDeviceKeys['@othertest:fakeServer.notExisting']!.masterKey! ]); final body = json.decode(FakeMatrixApi - .calledEndpoints['/client/r0/keys/signatures/upload'].first); + .calledEndpoints['/client/r0/keys/signatures/upload']!.first); expect(body['@test:fakeServer.notExisting']?.containsKey('OTHERDEVICE'), true); expect( body['@test:fakeServer.notExisting'].containsKey( - client.userDeviceKeys[client.userID].masterKey.publicKey), + client.userDeviceKeys[client.userID]!.masterKey!.publicKey), true); expect( body['@othertest:fakeServer.notExisting'].containsKey(client .userDeviceKeys['@othertest:fakeServer.notExisting'] - .masterKey - .publicKey), + ?.masterKey + ?.publicKey), true); }); diff --git a/test/encryption/encrypt_decrypt_room_message_test.dart b/test/encryption/encrypt_decrypt_room_message_test.dart index cfa61aa7..6c0c4f89 100644 --- a/test/encryption/encrypt_decrypt_room_message_test.dart +++ b/test/encryption/encrypt_decrypt_room_message_test.dart @@ -1,4 +1,3 @@ -// @dart=2.9 /* * Famedly Matrix SDK * Copyright (C) 2020 Famedly GmbH @@ -29,10 +28,10 @@ void main() { Logs().level = Level.error; var olmEnabled = true; - Client client; + late Client client; final roomId = '!726s6s6q:example.com'; - Room room; - Map payload; + late Room room; + late Map payload; final now = DateTime.now(); test('setupClient', () async { @@ -47,12 +46,12 @@ void main() { if (!olmEnabled) return; client = await getClient(); - room = client.getRoomById(roomId); + room = client.getRoomById(roomId)!; }); test('encrypt payload', () async { if (!olmEnabled) return; - payload = await client.encryption.encryptGroupMessagePayload(roomId, { + payload = await client.encryption!.encryptGroupMessagePayload(roomId, { 'msgtype': 'm.text', 'text': 'Hello foxies!', }); @@ -72,10 +71,10 @@ void main() { room: room, originServerTs: now, eventId: '\$event', - senderId: client.userID, + senderId: client.userID!, ); final decryptedEvent = - await client.encryption.decryptRoomEvent(roomId, encryptedEvent); + await client.encryption!.decryptRoomEvent(roomId, encryptedEvent); expect(decryptedEvent.type, 'm.room.message'); expect(decryptedEvent.content['msgtype'], 'm.text'); expect(decryptedEvent.content['text'], 'Hello foxies!'); @@ -83,7 +82,7 @@ void main() { test('decrypt payload nocache', () async { if (!olmEnabled) return; - client.encryption.keyManager.clearInboundGroupSessions(); + client.encryption!.keyManager.clearInboundGroupSessions(); final encryptedEvent = Event( type: EventTypes.Encrypted, content: payload, @@ -94,11 +93,11 @@ void main() { senderId: '@alice:example.com', ); final decryptedEvent = - await client.encryption.decryptRoomEvent(roomId, encryptedEvent); + await client.encryption!.decryptRoomEvent(roomId, encryptedEvent); expect(decryptedEvent.type, 'm.room.message'); expect(decryptedEvent.content['msgtype'], 'm.text'); expect(decryptedEvent.content['text'], 'Hello foxies!'); - await client.encryption + await client.encryption! .decryptRoomEvent(roomId, encryptedEvent, store: true); }); diff --git a/test/encryption/encrypt_decrypt_to_device_test.dart b/test/encryption/encrypt_decrypt_to_device_test.dart index 47fec8df..69828063 100644 --- a/test/encryption/encrypt_decrypt_to_device_test.dart +++ b/test/encryption/encrypt_decrypt_to_device_test.dart @@ -1,4 +1,3 @@ -// @dart=2.9 /* * Famedly Matrix SDK * Copyright (C) 2020 Famedly GmbH @@ -35,11 +34,11 @@ void main() { Logs().level = Level.error; var olmEnabled = true; - Client client; + late Client client; final otherClient = Client('othertestclient', httpClient: FakeMatrixApi(), databaseBuilder: getDatabase); - DeviceKeys device; - Map payload; + late DeviceKeys device; + late Map payload; test('setupClient', () async { try { @@ -83,7 +82,7 @@ void main() { test('encryptToDeviceMessage', () async { if (!olmEnabled) return; - payload = await otherClient.encryption + payload = await otherClient.encryption! .encryptToDeviceMessage([device], 'm.to_device', {'hello': 'foxies'}); }); @@ -95,15 +94,15 @@ void main() { content: payload[client.userID][client.deviceID], ); final decryptedEvent = - await client.encryption.decryptToDeviceEvent(encryptedEvent); + await client.encryption!.decryptToDeviceEvent(encryptedEvent); expect(decryptedEvent.type, 'm.to_device'); expect(decryptedEvent.content['hello'], 'foxies'); }); test('decryptToDeviceEvent nocache', () async { if (!olmEnabled) return; - client.encryption.olmManager.olmSessions.clear(); - payload = await otherClient.encryption.encryptToDeviceMessage( + client.encryption!.olmManager.olmSessions.clear(); + payload = await otherClient.encryption!.encryptToDeviceMessage( [device], 'm.to_device', {'hello': 'superfoxies'}); final encryptedEvent = ToDeviceEvent( sender: '@othertest:fakeServer.notExisting', @@ -111,7 +110,7 @@ void main() { content: payload[client.userID][client.deviceID], ); final decryptedEvent = - await client.encryption.decryptToDeviceEvent(encryptedEvent); + await client.encryption!.decryptToDeviceEvent(encryptedEvent); expect(decryptedEvent.type, 'm.to_device'); expect(decryptedEvent.content['hello'], 'superfoxies'); }); diff --git a/test/encryption/key_manager_test.dart b/test/encryption/key_manager_test.dart index 0b93386c..8606f617 100644 --- a/test/encryption/key_manager_test.dart +++ b/test/encryption/key_manager_test.dart @@ -1,4 +1,3 @@ -// @dart=2.9 /* * Famedly Matrix SDK * Copyright (C) 2020 Famedly GmbH @@ -32,7 +31,7 @@ void main() { Logs().level = Level.error; var olmEnabled = true; - Client client; + late Client client; test('setupClient', () async { try { @@ -55,7 +54,7 @@ void main() { final sessionKey = 'AgAAAAAQcQ6XrFJk6Prm8FikZDqfry/NbDz8Xw7T6e+/9Yf/q3YHIPEQlzv7IZMNcYb51ifkRzFejVvtphS7wwG2FaXIp4XS2obla14iKISR0X74ugB2vyb1AydIHE/zbBQ1ic5s3kgjMFlWpu/S3FQCnCrv+DPFGEt3ERGWxIl3Bl5X53IjPyVkz65oljz2TZESwz0GH/QFvyOOm8ci0q/gceaF3S7Dmafg3dwTKYwcA5xkcc+BLyrLRzB6Hn+oMAqSNSscnm4mTeT5zYibIhrzqyUTMWr32spFtI9dNR/RFSzfCw'; - client.encryption.keyManager.clearInboundGroupSessions(); + client.encryption!.keyManager.clearInboundGroupSessions(); var event = ToDeviceEvent( sender: '@alice:example.com', type: 'm.room_key', @@ -68,9 +67,9 @@ void main() { encryptedContent: { 'sender_key': validSenderKey, }); - await client.encryption.keyManager.handleToDeviceEvent(event); + await client.encryption!.keyManager.handleToDeviceEvent(event); expect( - client.encryption.keyManager.getInboundGroupSession( + client.encryption!.keyManager.getInboundGroupSession( '!726s6s6q:example.com', validSessionId, validSenderKey) != null, true); @@ -78,7 +77,7 @@ void main() { // now test a few invalid scenarios // not encrypted - client.encryption.keyManager.clearInboundGroupSessions(); + client.encryption!.keyManager.clearInboundGroupSessions(); event = ToDeviceEvent( sender: '@alice:example.com', type: 'm.room_key', @@ -88,9 +87,9 @@ void main() { 'session_id': validSessionId, 'session_key': sessionKey, }); - await client.encryption.keyManager.handleToDeviceEvent(event); + await client.encryption!.keyManager.handleToDeviceEvent(event); expect( - client.encryption.keyManager.getInboundGroupSession( + client.encryption!.keyManager.getInboundGroupSession( '!726s6s6q:example.com', validSessionId, validSenderKey) != null, false); @@ -100,99 +99,104 @@ void main() { if (!olmEnabled) return; final roomId = '!726s6s6q:example.com'; expect( - client.encryption.keyManager.getOutboundGroupSession(roomId) != null, + client.encryption!.keyManager.getOutboundGroupSession(roomId) != null, false); - var sess = - await client.encryption.keyManager.createOutboundGroupSession(roomId); + var sess = await client.encryption!.keyManager + .createOutboundGroupSession(roomId); expect( - client.encryption.keyManager.getOutboundGroupSession(roomId) != null, + client.encryption!.keyManager.getOutboundGroupSession(roomId) != null, true); - await client.encryption.keyManager.clearOrUseOutboundGroupSession(roomId); + await client.encryption!.keyManager + .clearOrUseOutboundGroupSession(roomId); expect( - client.encryption.keyManager.getOutboundGroupSession(roomId) != null, + client.encryption!.keyManager.getOutboundGroupSession(roomId) != null, true); - var inbound = client.encryption.keyManager.getInboundGroupSession( - roomId, sess.outboundGroupSession.session_id(), client.identityKey); + var inbound = client.encryption!.keyManager.getInboundGroupSession( + roomId, sess.outboundGroupSession!.session_id(), client.identityKey); expect(inbound != null, true); expect( - inbound.allowedAtIndex['@alice:example.com'] - ['L+4+JCl8MD63dgo8z5Ta+9QAHXiANyOVSfgbHA5d3H8'], + inbound!.allowedAtIndex['@alice:example.com'] + ?['L+4+JCl8MD63dgo8z5Ta+9QAHXiANyOVSfgbHA5d3H8'], 0); expect( inbound.allowedAtIndex['@alice:example.com'] - ['wMIDhiQl5jEXQrTB03ePOSQfR8sA/KMrW0CIfFfXKEE'], + ?['wMIDhiQl5jEXQrTB03ePOSQfR8sA/KMrW0CIfFfXKEE'], 0); // rotate after too many messages Iterable.generate(300).forEach((_) { - sess.outboundGroupSession.encrypt('some string'); + sess.outboundGroupSession!.encrypt('some string'); }); - await client.encryption.keyManager.clearOrUseOutboundGroupSession(roomId); + await client.encryption!.keyManager + .clearOrUseOutboundGroupSession(roomId); expect( - client.encryption.keyManager.getOutboundGroupSession(roomId) != null, + client.encryption!.keyManager.getOutboundGroupSession(roomId) != null, false); // rotate if device is blocked - sess = - await client.encryption.keyManager.createOutboundGroupSession(roomId); - client.userDeviceKeys['@alice:example.com'].deviceKeys['JLAFKJWSCS'] + sess = await client.encryption!.keyManager + .createOutboundGroupSession(roomId); + client.userDeviceKeys['@alice:example.com']!.deviceKeys['JLAFKJWSCS']! .blocked = true; - await client.encryption.keyManager.clearOrUseOutboundGroupSession(roomId); + await client.encryption!.keyManager + .clearOrUseOutboundGroupSession(roomId); expect( - client.encryption.keyManager.getOutboundGroupSession(roomId) != null, + client.encryption!.keyManager.getOutboundGroupSession(roomId) != null, false); - client.userDeviceKeys['@alice:example.com'].deviceKeys['JLAFKJWSCS'] + client.userDeviceKeys['@alice:example.com']!.deviceKeys['JLAFKJWSCS']! .blocked = false; // lazy-create if it would rotate - sess = - await client.encryption.keyManager.createOutboundGroupSession(roomId); - final oldSessKey = sess.outboundGroupSession.session_key(); - client.userDeviceKeys['@alice:example.com'].deviceKeys['JLAFKJWSCS'] + sess = await client.encryption!.keyManager + .createOutboundGroupSession(roomId); + final oldSessKey = sess.outboundGroupSession!.session_key(); + client.userDeviceKeys['@alice:example.com']!.deviceKeys['JLAFKJWSCS']! .blocked = true; - await client.encryption.keyManager.prepareOutboundGroupSession(roomId); + await client.encryption!.keyManager.prepareOutboundGroupSession(roomId); expect( - client.encryption.keyManager.getOutboundGroupSession(roomId) != null, + client.encryption!.keyManager.getOutboundGroupSession(roomId) != null, true); expect( - client.encryption.keyManager - .getOutboundGroupSession(roomId) - .outboundGroupSession + client.encryption!.keyManager + .getOutboundGroupSession(roomId)! + .outboundGroupSession! .session_key() != oldSessKey, true); - client.userDeviceKeys['@alice:example.com'].deviceKeys['JLAFKJWSCS'] + client.userDeviceKeys['@alice:example.com']!.deviceKeys['JLAFKJWSCS']! .blocked = false; // rotate if too far in the past - sess = - await client.encryption.keyManager.createOutboundGroupSession(roomId); + sess = await client.encryption!.keyManager + .createOutboundGroupSession(roomId); sess.creationTime = DateTime.now().subtract(Duration(days: 30)); - await client.encryption.keyManager.clearOrUseOutboundGroupSession(roomId); + await client.encryption!.keyManager + .clearOrUseOutboundGroupSession(roomId); expect( - client.encryption.keyManager.getOutboundGroupSession(roomId) != null, + client.encryption!.keyManager.getOutboundGroupSession(roomId) != null, false); // rotate if user leaves - sess = - await client.encryption.keyManager.createOutboundGroupSession(roomId); - final room = client.getRoomById(roomId); + sess = await client.encryption!.keyManager + .createOutboundGroupSession(roomId); + final room = client.getRoomById(roomId)!; final member = room.getState('m.room.member', '@alice:example.com'); - member.content['membership'] = 'leave'; - room.summary.mJoinedMemberCount--; - await client.encryption.keyManager.clearOrUseOutboundGroupSession(roomId); + member!.content['membership'] = 'leave'; + room.summary.mJoinedMemberCount = room.summary.mJoinedMemberCount! - 1; + await client.encryption!.keyManager + .clearOrUseOutboundGroupSession(roomId); expect( - client.encryption.keyManager.getOutboundGroupSession(roomId) != null, + client.encryption!.keyManager.getOutboundGroupSession(roomId) != null, false); member.content['membership'] = 'join'; - room.summary.mJoinedMemberCount++; + room.summary.mJoinedMemberCount = room.summary.mJoinedMemberCount! + 1; // do not rotate if new device is added - sess = - await client.encryption.keyManager.createOutboundGroupSession(roomId); - sess.outboundGroupSession.encrypt( + sess = await client.encryption!.keyManager + .createOutboundGroupSession(roomId); + sess.outboundGroupSession!.encrypt( 'foxies'); // so that the new device will have a different index - client.userDeviceKeys['@alice:example.com'].deviceKeys['NEWDEVICE'] = + client.userDeviceKeys['@alice:example.com']?.deviceKeys['NEWDEVICE'] = DeviceKeys.fromJson({ 'user_id': '@alice:example.com', 'device_id': 'NEWDEVICE', @@ -211,56 +215,58 @@ void main() { } } }, client); - await client.encryption.keyManager.clearOrUseOutboundGroupSession(roomId); + await client.encryption!.keyManager + .clearOrUseOutboundGroupSession(roomId); expect( - client.encryption.keyManager.getOutboundGroupSession(roomId) != null, + client.encryption!.keyManager.getOutboundGroupSession(roomId) != null, true); - inbound = client.encryption.keyManager.getInboundGroupSession( - roomId, sess.outboundGroupSession.session_id(), client.identityKey); + inbound = client.encryption!.keyManager.getInboundGroupSession( + roomId, sess.outboundGroupSession!.session_id(), client.identityKey); expect( - inbound.allowedAtIndex['@alice:example.com'] - ['L+4+JCl8MD63dgo8z5Ta+9QAHXiANyOVSfgbHA5d3H8'], + inbound!.allowedAtIndex['@alice:example.com'] + ?['L+4+JCl8MD63dgo8z5Ta+9QAHXiANyOVSfgbHA5d3H8'], 0); expect( inbound.allowedAtIndex['@alice:example.com'] - ['wMIDhiQl5jEXQrTB03ePOSQfR8sA/KMrW0CIfFfXKEE'], + ?['wMIDhiQl5jEXQrTB03ePOSQfR8sA/KMrW0CIfFfXKEE'], 0); expect( inbound.allowedAtIndex['@alice:example.com'] - ['bnKQp6pPW0l9cGoIgHpBoK5OUi4h0gylJ7upc4asFV8'], + ?['bnKQp6pPW0l9cGoIgHpBoK5OUi4h0gylJ7upc4asFV8'], 1); // do not rotate if new user is added member.content['membership'] = 'leave'; - room.summary.mJoinedMemberCount--; - sess = - await client.encryption.keyManager.createOutboundGroupSession(roomId); + room.summary.mJoinedMemberCount = room.summary.mJoinedMemberCount! - 1; + sess = await client.encryption!.keyManager + .createOutboundGroupSession(roomId); member.content['membership'] = 'join'; - room.summary.mJoinedMemberCount++; - await client.encryption.keyManager.clearOrUseOutboundGroupSession(roomId); + room.summary.mJoinedMemberCount = room.summary.mJoinedMemberCount! + 1; + await client.encryption!.keyManager + .clearOrUseOutboundGroupSession(roomId); expect( - client.encryption.keyManager.getOutboundGroupSession(roomId) != null, + client.encryption!.keyManager.getOutboundGroupSession(roomId) != null, true); // force wipe - sess = - await client.encryption.keyManager.createOutboundGroupSession(roomId); - await client.encryption.keyManager + sess = await client.encryption!.keyManager + .createOutboundGroupSession(roomId); + await client.encryption!.keyManager .clearOrUseOutboundGroupSession(roomId, wipe: true); expect( - client.encryption.keyManager.getOutboundGroupSession(roomId) != null, + client.encryption!.keyManager.getOutboundGroupSession(roomId) != null, false); // load from database - sess = - await client.encryption.keyManager.createOutboundGroupSession(roomId); - client.encryption.keyManager.clearOutboundGroupSessions(); + sess = await client.encryption!.keyManager + .createOutboundGroupSession(roomId); + client.encryption!.keyManager.clearOutboundGroupSessions(); expect( - client.encryption.keyManager.getOutboundGroupSession(roomId) != null, + client.encryption!.keyManager.getOutboundGroupSession(roomId) != null, false); - await client.encryption.keyManager.loadOutboundGroupSession(roomId); + await client.encryption!.keyManager.loadOutboundGroupSession(roomId); expect( - client.encryption.keyManager.getOutboundGroupSession(roomId) != null, + client.encryption!.keyManager.getOutboundGroupSession(roomId) != null, true); }); @@ -276,71 +282,71 @@ void main() { 'session_key': 'AgAAAAAQcQ6XrFJk6Prm8FikZDqfry/NbDz8Xw7T6e+/9Yf/q3YHIPEQlzv7IZMNcYb51ifkRzFejVvtphS7wwG2FaXIp4XS2obla14iKISR0X74ugB2vyb1AydIHE/zbBQ1ic5s3kgjMFlWpu/S3FQCnCrv+DPFGEt3ERGWxIl3Bl5X53IjPyVkz65oljz2TZESwz0GH/QFvyOOm8ci0q/gceaF3S7Dmafg3dwTKYwcA5xkcc+BLyrLRzB6Hn+oMAqSNSscnm4mTeT5zYibIhrzqyUTMWr32spFtI9dNR/RFSzfCw' }; - client.encryption.keyManager.clearInboundGroupSessions(); + client.encryption!.keyManager.clearInboundGroupSessions(); expect( - client.encryption.keyManager + client.encryption!.keyManager .getInboundGroupSession(roomId, sessionId, senderKey) != null, false); - client.encryption.keyManager + client.encryption!.keyManager .setInboundGroupSession(roomId, sessionId, senderKey, sessionContent); await Future.delayed(Duration(milliseconds: 10)); expect( - client.encryption.keyManager + client.encryption!.keyManager .getInboundGroupSession(roomId, sessionId, senderKey) != null, true); expect( - client.encryption.keyManager + client.encryption!.keyManager .getInboundGroupSession(roomId, sessionId, 'invalid') != null, false); expect( - client.encryption.keyManager + client.encryption!.keyManager .getInboundGroupSession(roomId, sessionId, senderKey) != null, true); expect( - client.encryption.keyManager + client.encryption!.keyManager .getInboundGroupSession('otherroom', sessionId, senderKey) != null, true); expect( - client.encryption.keyManager + client.encryption!.keyManager .getInboundGroupSession('otherroom', sessionId, 'invalid') != null, false); expect( - client.encryption.keyManager + client.encryption!.keyManager .getInboundGroupSession('otherroom', 'invalid', senderKey) != null, false); - client.encryption.keyManager.clearInboundGroupSessions(); + client.encryption!.keyManager.clearInboundGroupSessions(); expect( - client.encryption.keyManager + client.encryption!.keyManager .getInboundGroupSession(roomId, sessionId, senderKey) != null, false); - await client.encryption.keyManager + await client.encryption!.keyManager .loadInboundGroupSession(roomId, sessionId, senderKey); expect( - client.encryption.keyManager + client.encryption!.keyManager .getInboundGroupSession(roomId, sessionId, senderKey) != null, true); - client.encryption.keyManager.clearInboundGroupSessions(); + client.encryption!.keyManager.clearInboundGroupSessions(); expect( - client.encryption.keyManager + client.encryption!.keyManager .getInboundGroupSession(roomId, sessionId, senderKey) != null, false); - await client.encryption.keyManager + await client.encryption!.keyManager .loadInboundGroupSession(roomId, sessionId, 'invalid'); expect( - client.encryption.keyManager + client.encryption!.keyManager .getInboundGroupSession(roomId, sessionId, 'invalid') != null, false); @@ -379,7 +385,7 @@ void main() { stateKey: '', ), ); - expect(room.lastEvent.type, 'm.room.encrypted'); + expect(room.lastEvent?.type, 'm.room.encrypted'); // set a payload... var sessionPayload = { 'algorithm': AlgorithmTypes.megolmV1AesSha2, @@ -390,20 +396,20 @@ void main() { 'sender_key': senderKey, 'sender_claimed_ed25519_key': client.fingerprintKey, }; - client.encryption.keyManager.setInboundGroupSession( + client.encryption!.keyManager.setInboundGroupSession( roomId, sessionId, senderKey, sessionPayload, forwarded: true); expect( - client.encryption.keyManager + client.encryption!.keyManager .getInboundGroupSession(roomId, sessionId, senderKey) - .inboundGroupSession - .first_known_index(), + ?.inboundGroupSession + ?.first_known_index(), 1); expect( - client.encryption.keyManager + client.encryption!.keyManager .getInboundGroupSession(roomId, sessionId, senderKey) - .forwardingCurve25519KeyChain - .length, + ?.forwardingCurve25519KeyChain + ?.length, 1); // not set one with a higher first known index @@ -416,20 +422,20 @@ void main() { 'sender_key': senderKey, 'sender_claimed_ed25519_key': client.fingerprintKey, }; - client.encryption.keyManager.setInboundGroupSession( + client.encryption!.keyManager.setInboundGroupSession( roomId, sessionId, senderKey, sessionPayload, forwarded: true); expect( - client.encryption.keyManager + client.encryption!.keyManager .getInboundGroupSession(roomId, sessionId, senderKey) - .inboundGroupSession - .first_known_index(), + ?.inboundGroupSession + ?.first_known_index(), 1); expect( - client.encryption.keyManager + client.encryption!.keyManager .getInboundGroupSession(roomId, sessionId, senderKey) - .forwardingCurve25519KeyChain - .length, + ?.forwardingCurve25519KeyChain + ?.length, 1); // set one with a lower first known index @@ -442,20 +448,20 @@ void main() { 'sender_key': senderKey, 'sender_claimed_ed25519_key': client.fingerprintKey, }; - client.encryption.keyManager.setInboundGroupSession( + client.encryption!.keyManager.setInboundGroupSession( roomId, sessionId, senderKey, sessionPayload, forwarded: true); expect( - client.encryption.keyManager + client.encryption!.keyManager .getInboundGroupSession(roomId, sessionId, senderKey) - .inboundGroupSession - .first_known_index(), + ?.inboundGroupSession + ?.first_known_index(), 0); expect( - client.encryption.keyManager + client.encryption!.keyManager .getInboundGroupSession(roomId, sessionId, senderKey) - .forwardingCurve25519KeyChain - .length, + ?.forwardingCurve25519KeyChain + ?.length, 1); // not set one with a longer forwarding chain @@ -468,20 +474,20 @@ void main() { 'sender_key': senderKey, 'sender_claimed_ed25519_key': client.fingerprintKey, }; - client.encryption.keyManager.setInboundGroupSession( + client.encryption!.keyManager.setInboundGroupSession( roomId, sessionId, senderKey, sessionPayload, forwarded: true); expect( - client.encryption.keyManager + client.encryption!.keyManager .getInboundGroupSession(roomId, sessionId, senderKey) - .inboundGroupSession - .first_known_index(), + ?.inboundGroupSession + ?.first_known_index(), 0); expect( - client.encryption.keyManager + client.encryption!.keyManager .getInboundGroupSession(roomId, sessionId, senderKey) - .forwardingCurve25519KeyChain - .length, + ?.forwardingCurve25519KeyChain + ?.length, 1); // set one with a shorter forwarding chain @@ -494,25 +500,25 @@ void main() { 'sender_key': senderKey, 'sender_claimed_ed25519_key': client.fingerprintKey, }; - client.encryption.keyManager.setInboundGroupSession( + client.encryption!.keyManager.setInboundGroupSession( roomId, sessionId, senderKey, sessionPayload, forwarded: true); expect( - client.encryption.keyManager + client.encryption!.keyManager .getInboundGroupSession(roomId, sessionId, senderKey) - .inboundGroupSession - .first_known_index(), + ?.inboundGroupSession + ?.first_known_index(), 0); expect( - client.encryption.keyManager + client.encryption!.keyManager .getInboundGroupSession(roomId, sessionId, senderKey) - .forwardingCurve25519KeyChain - .length, + ?.forwardingCurve25519KeyChain + ?.length, 0); // test that it decrypted the last event - expect(room.lastEvent.type, 'm.room.message'); - expect(room.lastEvent.content['body'], 'foxies'); + expect(room.lastEvent?.type, 'm.room.message'); + expect(room.lastEvent?.content['body'], 'foxies'); inbound.free(); session.free(); @@ -521,22 +527,21 @@ void main() { test('Reused deviceID attack', () async { if (!olmEnabled) return; Logs().level = Level.warning; - client ??= await getClient(); // Ensure the device came from sync expect( client.userDeviceKeys['@alice:example.com'] - .deviceKeys['JLAFKJWSCS'] != + ?.deviceKeys['JLAFKJWSCS'] != null, true); // Alice removes her device - client.userDeviceKeys['@alice:example.com'].deviceKeys + client.userDeviceKeys['@alice:example.com']?.deviceKeys .remove('JLAFKJWSCS'); // Alice adds her device with same device ID but different keys - final oldResp = FakeMatrixApi.api['POST']['/client/r0/keys/query'](null); - FakeMatrixApi.api['POST']['/client/r0/keys/query'] = (_) { + final oldResp = FakeMatrixApi.api['POST']?['/client/r0/keys/query'](null); + FakeMatrixApi.api['POST']?['/client/r0/keys/query'] = (_) { oldResp['device_keys']['@alice:example.com']['JLAFKJWSCS'] = { 'user_id': '@alice:example.com', 'device_id': 'JLAFKJWSCS', @@ -558,10 +563,10 @@ void main() { }; return oldResp; }; - client.userDeviceKeys['@alice:example.com'].outdated = true; + client.userDeviceKeys['@alice:example.com']!.outdated = true; await client.updateUserDeviceKeys(); expect( - client.userDeviceKeys['@alice:example.com'].deviceKeys['JLAFKJWSCS'], + client.userDeviceKeys['@alice:example.com']?.deviceKeys['JLAFKJWSCS'], null); }); diff --git a/test/encryption/key_request_test.dart b/test/encryption/key_request_test.dart index 80d7dbd0..01d02657 100644 --- a/test/encryption/key_request_test.dart +++ b/test/encryption/key_request_test.dart @@ -1,4 +1,3 @@ -// @dart=2.9 /* * Famedly Matrix SDK * Copyright (C) 2020 Famedly GmbH @@ -58,8 +57,8 @@ void main() { if (!olmEnabled) return; final matrix = await getClient(); - final requestRoom = matrix.getRoomById('!726s6s6q:example.com'); - await matrix.encryption.keyManager.request( + final requestRoom = matrix.getRoomById('!726s6s6q:example.com')!; + await matrix.encryption!.keyManager.request( requestRoom, 'sessionId', validSenderKey, tryOnlineBackup: false); var foundEvent = false; @@ -89,12 +88,12 @@ void main() { matrix.setUserId('@alice:example.com'); // we need to pretend to be alice FakeMatrixApi.calledEndpoints.clear(); await matrix - .userDeviceKeys['@alice:example.com'].deviceKeys['OTHERDEVICE'] + .userDeviceKeys['@alice:example.com']!.deviceKeys['OTHERDEVICE']! .setBlocked(false); await matrix - .userDeviceKeys['@alice:example.com'].deviceKeys['OTHERDEVICE'] + .userDeviceKeys['@alice:example.com']!.deviceKeys['OTHERDEVICE']! .setVerified(true); - final session = await matrix.encryption.keyManager + final session = await matrix.encryption!.keyManager .loadInboundGroupSession( '!726s6s6q:example.com', validSessionId, validSenderKey); // test a successful share @@ -112,7 +111,7 @@ void main() { 'request_id': 'request_1', 'requesting_device_id': 'OTHERDEVICE', }); - await matrix.encryption.keyManager.handleToDeviceEvent(event); + await matrix.encryption!.keyManager.handleToDeviceEvent(event); Logs().i(FakeMatrixApi.calledEndpoints.keys.toString()); expect( FakeMatrixApi.calledEndpoints.keys.any( @@ -121,9 +120,9 @@ void main() { // test a successful foreign share FakeMatrixApi.calledEndpoints.clear(); - session.allowedAtIndex['@test:fakeServer.notExisting'] = { - matrix.userDeviceKeys['@test:fakeServer.notExisting'] - .deviceKeys['OTHERDEVICE'].curve25519Key: 0, + session!.allowedAtIndex['@test:fakeServer.notExisting'] = { + matrix.userDeviceKeys['@test:fakeServer.notExisting']! + .deviceKeys['OTHERDEVICE']!.curve25519Key!: 0, }; event = ToDeviceEvent( sender: '@test:fakeServer.notExisting', @@ -139,7 +138,7 @@ void main() { 'request_id': 'request_a1', 'requesting_device_id': 'OTHERDEVICE', }); - await matrix.encryption.keyManager.handleToDeviceEvent(event); + await matrix.encryption!.keyManager.handleToDeviceEvent(event); Logs().i(FakeMatrixApi.calledEndpoints.keys.toString()); expect( FakeMatrixApi.calledEndpoints.keys.any( @@ -165,7 +164,7 @@ void main() { 'request_id': 'request_a2', 'requesting_device_id': 'OTHERDEVICE', }); - await matrix.encryption.keyManager.handleToDeviceEvent(event); + await matrix.encryption!.keyManager.handleToDeviceEvent(event); Logs().i(FakeMatrixApi.calledEndpoints.keys.toString()); expect( FakeMatrixApi.calledEndpoints.keys.any( @@ -182,7 +181,7 @@ void main() { 'request_id': 'request_2', 'requesting_device_id': 'OTHERDEVICE', }); - await matrix.encryption.keyManager.handleToDeviceEvent(event); + await matrix.encryption!.keyManager.handleToDeviceEvent(event); expect( FakeMatrixApi.calledEndpoints.keys.any( (k) => k.startsWith('/client/r0/sendToDevice/m.room.encrypted')), @@ -204,7 +203,7 @@ void main() { 'request_id': 'request_3', 'requesting_device_id': 'JLAFKJWSCS', }); - await matrix.encryption.keyManager.handleToDeviceEvent(event); + await matrix.encryption!.keyManager.handleToDeviceEvent(event); expect( FakeMatrixApi.calledEndpoints.keys.any( (k) => k.startsWith('/client/r0/sendToDevice/m.room.encrypted')), @@ -226,7 +225,7 @@ void main() { 'request_id': 'request_4', 'requesting_device_id': 'blubb', }); - await matrix.encryption.keyManager.handleToDeviceEvent(event); + await matrix.encryption!.keyManager.handleToDeviceEvent(event); expect( FakeMatrixApi.calledEndpoints.keys.any( (k) => k.startsWith('/client/r0/sendToDevice/m.room.encrypted')), @@ -248,7 +247,7 @@ void main() { 'request_id': 'request_5', 'requesting_device_id': 'OTHERDEVICE', }); - await matrix.encryption.keyManager.handleToDeviceEvent(event); + await matrix.encryption!.keyManager.handleToDeviceEvent(event); expect( FakeMatrixApi.calledEndpoints.keys.any( (k) => k.startsWith('/client/r0/sendToDevice/m.room.encrypted')), @@ -270,7 +269,7 @@ void main() { 'request_id': 'request_6', 'requesting_device_id': 'OTHERDEVICE', }); - await matrix.encryption.keyManager.handleToDeviceEvent(event); + await matrix.encryption!.keyManager.handleToDeviceEvent(event); expect( FakeMatrixApi.calledEndpoints.keys.any( (k) => k.startsWith('/client/r0/sendToDevice/m.room.encrypted')), @@ -282,17 +281,17 @@ void main() { test('Receive shared keys', () async { if (!olmEnabled) return; final matrix = await getClient(); - final requestRoom = matrix.getRoomById('!726s6s6q:example.com'); - await matrix.encryption.keyManager.request( + final requestRoom = matrix.getRoomById('!726s6s6q:example.com')!; + await matrix.encryption!.keyManager.request( requestRoom, validSessionId, validSenderKey, tryOnlineBackup: false); - final session = await matrix.encryption.keyManager + final session = (await matrix.encryption!.keyManager .loadInboundGroupSession( - requestRoom.id, validSessionId, validSenderKey); - final sessionKey = session.inboundGroupSession - .export_session(session.inboundGroupSession.first_known_index()); - matrix.encryption.keyManager.clearInboundGroupSessions(); + requestRoom.id, validSessionId, validSenderKey))!; + final sessionKey = session.inboundGroupSession! + .export_session(session.inboundGroupSession!.first_known_index()); + matrix.encryption!.keyManager.clearInboundGroupSessions(); var event = ToDeviceEvent( sender: '@alice:example.com', type: 'm.forwarded_room_key', @@ -303,13 +302,15 @@ void main() { 'session_key': sessionKey, 'sender_key': validSenderKey, 'forwarding_curve25519_key_chain': [], + 'sender_claimed_ed25519_key': + 'L+4+JCl8MD63dgo8z5Ta+9QAHXiANyOVSfgbHA5d3H8', }, encryptedContent: { 'sender_key': 'L+4+JCl8MD63dgo8z5Ta+9QAHXiANyOVSfgbHA5d3H8', }); - await matrix.encryption.keyManager.handleToDeviceEvent(event); + await matrix.encryption!.keyManager.handleToDeviceEvent(event); expect( - matrix.encryption.keyManager.getInboundGroupSession( + matrix.encryption!.keyManager.getInboundGroupSession( requestRoom.id, validSessionId, validSenderKey) != null, true); @@ -317,7 +318,7 @@ void main() { // now test a few invalid scenarios // request not found - matrix.encryption.keyManager.clearInboundGroupSessions(); + matrix.encryption!.keyManager.clearInboundGroupSessions(); event = ToDeviceEvent( sender: '@alice:example.com', type: 'm.forwarded_room_key', @@ -328,22 +329,24 @@ void main() { 'session_key': sessionKey, 'sender_key': validSenderKey, 'forwarding_curve25519_key_chain': [], + 'sender_claimed_ed25519_key': + 'L+4+JCl8MD63dgo8z5Ta+9QAHXiANyOVSfgbHA5d3H8', }, encryptedContent: { 'sender_key': 'L+4+JCl8MD63dgo8z5Ta+9QAHXiANyOVSfgbHA5d3H8', }); - await matrix.encryption.keyManager.handleToDeviceEvent(event); + await matrix.encryption!.keyManager.handleToDeviceEvent(event); expect( - matrix.encryption.keyManager.getInboundGroupSession( + matrix.encryption!.keyManager.getInboundGroupSession( requestRoom.id, validSessionId, validSenderKey) != null, false); // unknown device - await matrix.encryption.keyManager.request( + await matrix.encryption!.keyManager.request( requestRoom, validSessionId, validSenderKey, tryOnlineBackup: false); - matrix.encryption.keyManager.clearInboundGroupSessions(); + matrix.encryption!.keyManager.clearInboundGroupSessions(); event = ToDeviceEvent( sender: '@alice:example.com', type: 'm.forwarded_room_key', @@ -354,22 +357,24 @@ void main() { 'session_key': sessionKey, 'sender_key': validSenderKey, 'forwarding_curve25519_key_chain': [], + 'sender_claimed_ed25519_key': + 'L+4+JCl8MD63dgo8z5Ta+9QAHXiANyOVSfgbHA5d3H8', }, encryptedContent: { 'sender_key': 'invalid', }); - await matrix.encryption.keyManager.handleToDeviceEvent(event); + await matrix.encryption!.keyManager.handleToDeviceEvent(event); expect( - matrix.encryption.keyManager.getInboundGroupSession( + matrix.encryption!.keyManager.getInboundGroupSession( requestRoom.id, validSessionId, validSenderKey) != null, false); // no encrypted content - await matrix.encryption.keyManager.request( + await matrix.encryption!.keyManager.request( requestRoom, validSessionId, validSenderKey, tryOnlineBackup: false); - matrix.encryption.keyManager.clearInboundGroupSessions(); + matrix.encryption!.keyManager.clearInboundGroupSessions(); event = ToDeviceEvent( sender: '@alice:example.com', type: 'm.forwarded_room_key', @@ -380,10 +385,12 @@ void main() { 'session_key': sessionKey, 'sender_key': validSenderKey, 'forwarding_curve25519_key_chain': [], + 'sender_claimed_ed25519_key': + 'L+4+JCl8MD63dgo8z5Ta+9QAHXiANyOVSfgbHA5d3H8', }); - await matrix.encryption.keyManager.handleToDeviceEvent(event); + await matrix.encryption!.keyManager.handleToDeviceEvent(event); expect( - matrix.encryption.keyManager.getInboundGroupSession( + matrix.encryption!.keyManager.getInboundGroupSession( requestRoom.id, validSessionId, validSenderKey) != null, false); diff --git a/test/encryption/key_verification_test.dart b/test/encryption/key_verification_test.dart index 1b7aa433..58362e00 100644 --- a/test/encryption/key_verification_test.dart +++ b/test/encryption/key_verification_test.dart @@ -1,4 +1,3 @@ -// @dart=2.9 /* * Famedly Matrix SDK * Copyright (C) 2020 Famedly GmbH @@ -34,7 +33,7 @@ class MockSSSS extends SSSS { bool requestedSecrets = false; @override - Future maybeRequestAll([List devices]) async { + Future maybeRequestAll([List? devices]) async { requestedSecrets = true; final handle = open(); await handle.unlock(recoveryKey: ssssKey); @@ -56,7 +55,7 @@ EventUpdate getLastSentEvent(KeyVerification req) { 'sender': req.client.userID, }, type: EventUpdateType.timeline, - roomID: req.room.id, + roomID: req.room!.id, ); } @@ -70,8 +69,8 @@ void main() { const otherPickledOlmAccount = 'VWhVApbkcilKAEGppsPDf9nNVjaK8/IxT3asSR0sYg0S5KgbfE8vXEPwoiKBX2cEvwX3OessOBOkk+ZE7TTbjlrh/KEd31p8Wo+47qj0AP+Ky+pabnhi+/rTBvZy+gfzTqUfCxZrkzfXI9Op4JnP6gYmy7dVX2lMYIIs9WCO1jcmIXiXum5jnfXu1WLfc7PZtO2hH+k9CDKosOFaXRBmsu8k/BGXPSoWqUpvu6WpEG9t5STk4FeAzA'; - Client client1; - Client client2; + late Client client1; + late Client client2; test('setupClient', () async { try { @@ -117,24 +116,25 @@ void main() { // because then we can easily intercept the payloads and inject in the other client FakeMatrixApi.calledEndpoints.clear(); // make sure our master key is *not* verified to not triger SSSS for now - client1.userDeviceKeys[client1.userID].masterKey.setDirectVerified(false); + client1.userDeviceKeys[client1.userID]!.masterKey! + .setDirectVerified(false); final req1 = - await client1.userDeviceKeys[client2.userID].startVerification(); + await client1.userDeviceKeys[client2.userID]!.startVerification(); var evt = getLastSentEvent(req1); expect(req1.state, KeyVerificationState.waitingAccept); - KeyVerification req2; + late KeyVerification req2; final sub = client2.onKeyVerificationRequest.stream.listen((req) { req2 = req; }); - await client2.encryption.keyVerificationManager.handleEventUpdate(evt); + await client2.encryption!.keyVerificationManager.handleEventUpdate(evt); await Future.delayed(Duration(milliseconds: 10)); await sub.cancel(); expect(req2 != null, true); expect( - client2.encryption.keyVerificationManager - .getRequest(req2.transactionId), + client2.encryption!.keyVerificationManager + .getRequest(req2.transactionId!), req2); // send ready @@ -145,27 +145,27 @@ void main() { // send start FakeMatrixApi.calledEndpoints.clear(); - await client1.encryption.keyVerificationManager.handleEventUpdate(evt); + await client1.encryption!.keyVerificationManager.handleEventUpdate(evt); evt = getLastSentEvent(req1); // send accept FakeMatrixApi.calledEndpoints.clear(); - await client2.encryption.keyVerificationManager.handleEventUpdate(evt); + await client2.encryption!.keyVerificationManager.handleEventUpdate(evt); evt = getLastSentEvent(req2); // send key FakeMatrixApi.calledEndpoints.clear(); - await client1.encryption.keyVerificationManager.handleEventUpdate(evt); + await client1.encryption!.keyVerificationManager.handleEventUpdate(evt); evt = getLastSentEvent(req1); // send key FakeMatrixApi.calledEndpoints.clear(); - await client2.encryption.keyVerificationManager.handleEventUpdate(evt); + await client2.encryption!.keyVerificationManager.handleEventUpdate(evt); evt = getLastSentEvent(req2); // receive last key FakeMatrixApi.calledEndpoints.clear(); - await client1.encryption.keyVerificationManager.handleEventUpdate(evt); + await client1.encryption!.keyVerificationManager.handleEventUpdate(evt); // compare emoji expect(req1.state, KeyVerificationState.askSas); @@ -194,61 +194,64 @@ void main() { FakeMatrixApi.calledEndpoints.clear(); await req1.acceptSas(); evt = getLastSentEvent(req1); - await client2.encryption.keyVerificationManager.handleEventUpdate(evt); + await client2.encryption!.keyVerificationManager.handleEventUpdate(evt); expect(req1.state, KeyVerificationState.waitingSas); // send mac FakeMatrixApi.calledEndpoints.clear(); await req2.acceptSas(); evt = getLastSentEvent(req2); - await client1.encryption.keyVerificationManager.handleEventUpdate(evt); + await client1.encryption!.keyVerificationManager.handleEventUpdate(evt); expect(req1.state, KeyVerificationState.done); expect(req2.state, KeyVerificationState.done); expect( - client1.userDeviceKeys[client2.userID].deviceKeys[client2.deviceID] - .directVerified, + client1.userDeviceKeys[client2.userID]?.deviceKeys[client2.deviceID] + ?.directVerified, true); expect( - client2.userDeviceKeys[client1.userID].deviceKeys[client1.deviceID] - .directVerified, + client2.userDeviceKeys[client1.userID]?.deviceKeys[client1.deviceID] + ?.directVerified, true); - await client1.encryption.keyVerificationManager.cleanup(); - await client2.encryption.keyVerificationManager.cleanup(); + await client1.encryption!.keyVerificationManager.cleanup(); + await client2.encryption!.keyVerificationManager.cleanup(); }); test('ask SSSS start', () async { if (!olmEnabled) return; - client1.userDeviceKeys[client1.userID].masterKey.setDirectVerified(true); - await client1.encryption.ssss.clearCache(); + client1.userDeviceKeys[client1.userID]!.masterKey! + .setDirectVerified(true); + await client1.encryption!.ssss.clearCache(); final req1 = - await client1.userDeviceKeys[client2.userID].startVerification(); + await client1.userDeviceKeys[client2.userID]!.startVerification(); expect(req1.state, KeyVerificationState.askSSSS); await req1.openSSSS(recoveryKey: ssssKey); await Future.delayed(Duration(seconds: 1)); expect(req1.state, KeyVerificationState.waitingAccept); await req1.cancel(); - await client1.encryption.keyVerificationManager.cleanup(); + await client1.encryption!.keyVerificationManager.cleanup(); }); test('ask SSSS end', () async { if (!olmEnabled) return; FakeMatrixApi.calledEndpoints.clear(); // make sure our master key is *not* verified to not triger SSSS for now - client1.userDeviceKeys[client1.userID].masterKey.setDirectVerified(false); + client1.userDeviceKeys[client1.userID]!.masterKey! + .setDirectVerified(false); // the other one has to have their master key verified to trigger asking for ssss - client2.userDeviceKeys[client2.userID].masterKey.setDirectVerified(true); + client2.userDeviceKeys[client2.userID]!.masterKey! + .setDirectVerified(true); final req1 = - await client1.userDeviceKeys[client2.userID].startVerification(); + await client1.userDeviceKeys[client2.userID]!.startVerification(); var evt = getLastSentEvent(req1); expect(req1.state, KeyVerificationState.waitingAccept); - KeyVerification req2; + late KeyVerification req2; final sub = client2.onKeyVerificationRequest.stream.listen((req) { req2 = req; }); - await client2.encryption.keyVerificationManager.handleEventUpdate(evt); + await client2.encryption!.keyVerificationManager.handleEventUpdate(evt); await Future.delayed(Duration(milliseconds: 10)); await sub.cancel(); expect(req2 != null, true); @@ -261,27 +264,27 @@ void main() { // send start FakeMatrixApi.calledEndpoints.clear(); - await client1.encryption.keyVerificationManager.handleEventUpdate(evt); + await client1.encryption!.keyVerificationManager.handleEventUpdate(evt); evt = getLastSentEvent(req1); // send accept FakeMatrixApi.calledEndpoints.clear(); - await client2.encryption.keyVerificationManager.handleEventUpdate(evt); + await client2.encryption!.keyVerificationManager.handleEventUpdate(evt); evt = getLastSentEvent(req2); // send key FakeMatrixApi.calledEndpoints.clear(); - await client1.encryption.keyVerificationManager.handleEventUpdate(evt); + await client1.encryption!.keyVerificationManager.handleEventUpdate(evt); evt = getLastSentEvent(req1); // send key FakeMatrixApi.calledEndpoints.clear(); - await client2.encryption.keyVerificationManager.handleEventUpdate(evt); + await client2.encryption!.keyVerificationManager.handleEventUpdate(evt); evt = getLastSentEvent(req2); // receive last key FakeMatrixApi.calledEndpoints.clear(); - await client1.encryption.keyVerificationManager.handleEventUpdate(evt); + await client1.encryption!.keyVerificationManager.handleEventUpdate(evt); // compare emoji expect(req1.state, KeyVerificationState.askSas); @@ -301,21 +304,22 @@ void main() { } // alright, they match - client1.userDeviceKeys[client1.userID].masterKey.setDirectVerified(true); - await client1.encryption.ssss.clearCache(); + client1.userDeviceKeys[client1.userID]!.masterKey! + .setDirectVerified(true); + await client1.encryption!.ssss.clearCache(); // send mac FakeMatrixApi.calledEndpoints.clear(); await req1.acceptSas(); evt = getLastSentEvent(req1); - await client2.encryption.keyVerificationManager.handleEventUpdate(evt); + await client2.encryption!.keyVerificationManager.handleEventUpdate(evt); expect(req1.state, KeyVerificationState.waitingSas); // send mac FakeMatrixApi.calledEndpoints.clear(); await req2.acceptSas(); evt = getLastSentEvent(req2); - await client1.encryption.keyVerificationManager.handleEventUpdate(evt); + await client1.encryption!.keyVerificationManager.handleEventUpdate(evt); expect(req1.state, KeyVerificationState.askSSSS); expect(req2.state, KeyVerificationState.done); @@ -324,63 +328,65 @@ void main() { await Future.delayed(Duration(milliseconds: 10)); expect(req1.state, KeyVerificationState.done); - client1.encryption.ssss = MockSSSS(client1.encryption); - (client1.encryption.ssss as MockSSSS).requestedSecrets = false; - await client1.encryption.ssss.clearCache(); + client1.encryption!.ssss = MockSSSS(client1.encryption!); + (client1.encryption!.ssss as MockSSSS).requestedSecrets = false; + await client1.encryption!.ssss.clearCache(); await req1.maybeRequestSSSSSecrets(); await Future.delayed(Duration(milliseconds: 10)); - expect((client1.encryption.ssss as MockSSSS).requestedSecrets, true); + expect((client1.encryption!.ssss as MockSSSS).requestedSecrets, true); // delay for 12 seconds to be sure no other tests clear the ssss cache await Future.delayed(Duration(seconds: 12)); - await client1.encryption.keyVerificationManager.cleanup(); - await client2.encryption.keyVerificationManager.cleanup(); + await client1.encryption!.keyVerificationManager.cleanup(); + await client2.encryption!.keyVerificationManager.cleanup(); }); test('reject verification', () async { if (!olmEnabled) return; FakeMatrixApi.calledEndpoints.clear(); // make sure our master key is *not* verified to not triger SSSS for now - client1.userDeviceKeys[client1.userID].masterKey.setDirectVerified(false); + client1.userDeviceKeys[client1.userID]!.masterKey! + .setDirectVerified(false); final req1 = - await client1.userDeviceKeys[client2.userID].startVerification(); + await client1.userDeviceKeys[client2.userID]!.startVerification(); var evt = getLastSentEvent(req1); expect(req1.state, KeyVerificationState.waitingAccept); - KeyVerification req2; + late KeyVerification req2; final sub = client2.onKeyVerificationRequest.stream.listen((req) { req2 = req; }); - await client2.encryption.keyVerificationManager.handleEventUpdate(evt); + await client2.encryption!.keyVerificationManager.handleEventUpdate(evt); await Future.delayed(Duration(milliseconds: 10)); await sub.cancel(); FakeMatrixApi.calledEndpoints.clear(); await req2.rejectVerification(); evt = getLastSentEvent(req2); - await client1.encryption.keyVerificationManager.handleEventUpdate(evt); + await client1.encryption!.keyVerificationManager.handleEventUpdate(evt); expect(req1.state, KeyVerificationState.error); expect(req2.state, KeyVerificationState.error); - await client1.encryption.keyVerificationManager.cleanup(); - await client2.encryption.keyVerificationManager.cleanup(); + await client1.encryption!.keyVerificationManager.cleanup(); + await client2.encryption!.keyVerificationManager.cleanup(); }); test('reject sas', () async { if (!olmEnabled) return; FakeMatrixApi.calledEndpoints.clear(); // make sure our master key is *not* verified to not triger SSSS for now - client1.userDeviceKeys[client1.userID].masterKey.setDirectVerified(false); + client1.userDeviceKeys[client1.userID]!.masterKey! + .setDirectVerified(false); final req1 = - await client1.userDeviceKeys[client2.userID].startVerification(); + await client1.userDeviceKeys[client2.userID]!.startVerification(); var evt = getLastSentEvent(req1); expect(req1.state, KeyVerificationState.waitingAccept); - KeyVerification req2; + late KeyVerification req2; final sub = client2.onKeyVerificationRequest.stream.listen((req) { req2 = req; }); - await client2.encryption.keyVerificationManager.handleEventUpdate(evt); + await client2.encryption!.keyVerificationManager.handleEventUpdate(evt); await Future.delayed(Duration(milliseconds: 10)); await sub.cancel(); expect(req2 != null, true); @@ -393,60 +399,61 @@ void main() { // send start FakeMatrixApi.calledEndpoints.clear(); - await client1.encryption.keyVerificationManager.handleEventUpdate(evt); + await client1.encryption!.keyVerificationManager.handleEventUpdate(evt); evt = getLastSentEvent(req1); // send accept FakeMatrixApi.calledEndpoints.clear(); - await client2.encryption.keyVerificationManager.handleEventUpdate(evt); + await client2.encryption!.keyVerificationManager.handleEventUpdate(evt); evt = getLastSentEvent(req2); // send key FakeMatrixApi.calledEndpoints.clear(); - await client1.encryption.keyVerificationManager.handleEventUpdate(evt); + await client1.encryption!.keyVerificationManager.handleEventUpdate(evt); evt = getLastSentEvent(req1); // send key FakeMatrixApi.calledEndpoints.clear(); - await client2.encryption.keyVerificationManager.handleEventUpdate(evt); + await client2.encryption!.keyVerificationManager.handleEventUpdate(evt); evt = getLastSentEvent(req2); // receive last key FakeMatrixApi.calledEndpoints.clear(); - await client1.encryption.keyVerificationManager.handleEventUpdate(evt); + await client1.encryption!.keyVerificationManager.handleEventUpdate(evt); await req1.acceptSas(); FakeMatrixApi.calledEndpoints.clear(); await req2.rejectSas(); evt = getLastSentEvent(req2); - await client1.encryption.keyVerificationManager.handleEventUpdate(evt); + await client1.encryption!.keyVerificationManager.handleEventUpdate(evt); expect(req1.state, KeyVerificationState.error); expect(req2.state, KeyVerificationState.error); - await client1.encryption.keyVerificationManager.cleanup(); - await client2.encryption.keyVerificationManager.cleanup(); + await client1.encryption!.keyVerificationManager.cleanup(); + await client2.encryption!.keyVerificationManager.cleanup(); }); test('other device accepted', () async { if (!olmEnabled) return; FakeMatrixApi.calledEndpoints.clear(); // make sure our master key is *not* verified to not triger SSSS for now - client1.userDeviceKeys[client1.userID].masterKey.setDirectVerified(false); + client1.userDeviceKeys[client1.userID]!.masterKey! + .setDirectVerified(false); final req1 = - await client1.userDeviceKeys[client2.userID].startVerification(); + await client1.userDeviceKeys[client2.userID]!.startVerification(); final evt = getLastSentEvent(req1); expect(req1.state, KeyVerificationState.waitingAccept); - KeyVerification req2; + late KeyVerification req2; final sub = client2.onKeyVerificationRequest.stream.listen((req) { req2 = req; }); - await client2.encryption.keyVerificationManager.handleEventUpdate(evt); + await client2.encryption!.keyVerificationManager.handleEventUpdate(evt); await Future.delayed(Duration(milliseconds: 10)); await sub.cancel(); expect(req2 != null, true); - await client2.encryption.keyVerificationManager + await client2.encryption!.keyVerificationManager .handleEventUpdate(EventUpdate( content: { 'event_id': req2.transactionId, @@ -463,13 +470,13 @@ void main() { 'sender': client2.userID, }, type: EventUpdateType.timeline, - roomID: req2.room.id, + roomID: req2.room!.id, )); expect(req2.state, KeyVerificationState.error); await req2.cancel(); - await client1.encryption.keyVerificationManager.cleanup(); - await client2.encryption.keyVerificationManager.cleanup(); + await client1.encryption!.keyVerificationManager.cleanup(); + await client2.encryption!.keyVerificationManager.cleanup(); }); test('dispose client', () async { diff --git a/test/encryption/olm_manager_test.dart b/test/encryption/olm_manager_test.dart index e6e7b5f6..40ebc08c 100644 --- a/test/encryption/olm_manager_test.dart +++ b/test/encryption/olm_manager_test.dart @@ -1,4 +1,3 @@ -// @dart=2.9 /* * Famedly Matrix SDK * Copyright (C) 2020, 2021 Famedly GmbH @@ -32,7 +31,7 @@ void main() { Logs().level = Level.error; var olmEnabled = true; - Client client; + late Client client; test('setupClient', () async { try { @@ -53,37 +52,37 @@ void main() { final payload = { 'fox': 'floof', }; - final signedPayload = client.encryption.olmManager.signJson(payload); + final signedPayload = client.encryption!.olmManager.signJson(payload); expect( signedPayload.checkJsonSignature( - client.fingerprintKey, client.userID, client.deviceID), + client.fingerprintKey, client.userID!, client.deviceID!), true); }); test('uploadKeys', () async { if (!olmEnabled) return; FakeMatrixApi.calledEndpoints.clear(); - final res = - await client.encryption.olmManager.uploadKeys(uploadDeviceKeys: true); + final res = await client.encryption!.olmManager + .uploadKeys(uploadDeviceKeys: true); expect(res, true); var sent = json.decode( - FakeMatrixApi.calledEndpoints['/client/r0/keys/upload'].first); + FakeMatrixApi.calledEndpoints['/client/r0/keys/upload']!.first); expect(sent['device_keys'] != null, true); expect(sent['one_time_keys'] != null, true); expect(sent['one_time_keys'].keys.length, 66); expect(sent['fallback_keys'] != null, true); expect(sent['fallback_keys'].keys.length, 1); FakeMatrixApi.calledEndpoints.clear(); - await client.encryption.olmManager.uploadKeys(); + await client.encryption!.olmManager.uploadKeys(); sent = json.decode( - FakeMatrixApi.calledEndpoints['/client/r0/keys/upload'].first); + FakeMatrixApi.calledEndpoints['/client/r0/keys/upload']!.first); expect(sent['device_keys'] != null, false); expect(sent['fallback_keys'].keys.length, 1); FakeMatrixApi.calledEndpoints.clear(); - await client.encryption.olmManager + await client.encryption!.olmManager .uploadKeys(oldKeyCount: 20, unusedFallbackKey: true); sent = json.decode( - FakeMatrixApi.calledEndpoints['/client/r0/keys/upload'].first); + FakeMatrixApi.calledEndpoints['/client/r0/keys/upload']!.first); expect(sent['one_time_keys'].keys.length, 46); expect(sent['fallback_keys'].keys.length, 0); }); @@ -91,7 +90,7 @@ void main() { test('handleDeviceOneTimeKeysCount', () async { if (!olmEnabled) return; FakeMatrixApi.calledEndpoints.clear(); - client.encryption.olmManager + client.encryption!.olmManager .handleDeviceOneTimeKeysCount({'signed_curve25519': 20}, null); await Future.delayed(Duration(milliseconds: 50)); expect( @@ -99,7 +98,7 @@ void main() { true); FakeMatrixApi.calledEndpoints.clear(); - client.encryption.olmManager + client.encryption!.olmManager .handleDeviceOneTimeKeysCount({'signed_curve25519': 70}, null); await Future.delayed(Duration(milliseconds: 50)); expect( @@ -107,7 +106,7 @@ void main() { false); FakeMatrixApi.calledEndpoints.clear(); - client.encryption.olmManager.handleDeviceOneTimeKeysCount(null, []); + client.encryption!.olmManager.handleDeviceOneTimeKeysCount(null, []); await Future.delayed(Duration(milliseconds: 50)); expect( FakeMatrixApi.calledEndpoints.containsKey('/client/r0/keys/upload'), @@ -115,7 +114,7 @@ void main() { // this will upload keys because we assume the key count is 0, if the server doesn't send one FakeMatrixApi.calledEndpoints.clear(); - client.encryption.olmManager + client.encryption!.olmManager .handleDeviceOneTimeKeysCount(null, ['signed_curve25519']); await Future.delayed(Duration(milliseconds: 50)); expect( @@ -125,30 +124,31 @@ void main() { test('restoreOlmSession', () async { if (!olmEnabled) return; - client.encryption.olmManager.olmSessions.clear(); - await client.encryption.olmManager - .restoreOlmSession(client.userID, client.identityKey); - expect(client.encryption.olmManager.olmSessions.length, 1); + client.encryption!.olmManager.olmSessions.clear(); + await client.encryption!.olmManager + .restoreOlmSession(client.userID!, client.identityKey); + expect(client.encryption!.olmManager.olmSessions.length, 1); - client.encryption.olmManager.olmSessions.clear(); - await client.encryption.olmManager - .restoreOlmSession(client.userID, 'invalid'); - expect(client.encryption.olmManager.olmSessions.length, 0); + client.encryption!.olmManager.olmSessions.clear(); + await client.encryption!.olmManager + .restoreOlmSession(client.userID!, 'invalid'); + expect(client.encryption!.olmManager.olmSessions.length, 0); - client.encryption.olmManager.olmSessions.clear(); - await client.encryption.olmManager + client.encryption!.olmManager.olmSessions.clear(); + await client.encryption!.olmManager .restoreOlmSession('invalid', client.identityKey); - expect(client.encryption.olmManager.olmSessions.length, 0); + expect(client.encryption!.olmManager.olmSessions.length, 0); }); test('startOutgoingOlmSessions', () async { if (!olmEnabled) return; // start an olm session.....with ourself! - client.encryption.olmManager.olmSessions.clear(); - await client.encryption.olmManager.startOutgoingOlmSessions( - [client.userDeviceKeys[client.userID].deviceKeys[client.deviceID]]); + client.encryption!.olmManager.olmSessions.clear(); + await client.encryption!.olmManager.startOutgoingOlmSessions([ + client.userDeviceKeys[client.userID!]!.deviceKeys[client.deviceID]! + ]); expect( - client.encryption.olmManager.olmSessions + client.encryption!.olmManager.olmSessions .containsKey(client.identityKey), true); }); @@ -159,7 +159,7 @@ void main() { final deviceId = 'JLAFKJWSCS'; final senderKey = 'L+4+JCl8MD63dgo8z5Ta+9QAHXiANyOVSfgbHA5d3H8'; FakeMatrixApi.calledEndpoints.clear(); - await client.database.setLastSentMessageUserDeviceKey( + await client.database!.setLastSentMessageUserDeviceKey( json.encode({ 'type': 'm.foxies', 'content': { @@ -176,7 +176,7 @@ void main() { 'sender_key': senderKey, }, ); - await client.encryption.olmManager.handleToDeviceEvent(event); + await client.encryption!.olmManager.handleToDeviceEvent(event); expect( FakeMatrixApi.calledEndpoints.keys.any( (k) => k.startsWith('/client/r0/sendToDevice/m.room.encrypted')), @@ -186,7 +186,7 @@ void main() { // not encrypted FakeMatrixApi.calledEndpoints.clear(); - await client.database.setLastSentMessageUserDeviceKey( + await client.database!.setLastSentMessageUserDeviceKey( json.encode({ 'type': 'm.foxies', 'content': { @@ -201,7 +201,7 @@ void main() { content: {}, encryptedContent: null, ); - await client.encryption.olmManager.handleToDeviceEvent(event); + await client.encryption!.olmManager.handleToDeviceEvent(event); expect( FakeMatrixApi.calledEndpoints.keys.any( (k) => k.startsWith('/client/r0/sendToDevice/m.room.encrypted')), @@ -209,7 +209,7 @@ void main() { // device not found FakeMatrixApi.calledEndpoints.clear(); - await client.database.setLastSentMessageUserDeviceKey( + await client.database!.setLastSentMessageUserDeviceKey( json.encode({ 'type': 'm.foxies', 'content': { @@ -226,7 +226,7 @@ void main() { 'sender_key': 'invalid', }, ); - await client.encryption.olmManager.handleToDeviceEvent(event); + await client.encryption!.olmManager.handleToDeviceEvent(event); expect( FakeMatrixApi.calledEndpoints.keys.any( (k) => k.startsWith('/client/r0/sendToDevice/m.room.encrypted')), @@ -234,7 +234,7 @@ void main() { // don't replay if the last event is m.dummy itself FakeMatrixApi.calledEndpoints.clear(); - await client.database.setLastSentMessageUserDeviceKey( + await client.database!.setLastSentMessageUserDeviceKey( json.encode({ 'type': 'm.dummy', 'content': {}, @@ -249,7 +249,7 @@ void main() { 'sender_key': senderKey, }, ); - await client.encryption.olmManager.handleToDeviceEvent(event); + await client.encryption!.olmManager.handleToDeviceEvent(event); expect( FakeMatrixApi.calledEndpoints.keys.any( (k) => k.startsWith('/client/r0/sendToDevice/m.room.encrypted')), diff --git a/test/encryption/online_key_backup_test.dart b/test/encryption/online_key_backup_test.dart index 4cd8feac..48f03efe 100644 --- a/test/encryption/online_key_backup_test.dart +++ b/test/encryption/online_key_backup_test.dart @@ -1,4 +1,3 @@ -// @dart=2.9 /* * Famedly Matrix SDK * Copyright (C) 2020 Famedly GmbH @@ -32,7 +31,7 @@ void main() { Logs().level = Level.error; var olmEnabled = true; - Client client; + late Client client; final roomId = '!726s6s6q:example.com'; final sessionId = 'ciM/JWTPrmiWPPZNkRLDPQYf9AW/I46bxyLSr+Bx5oU'; @@ -54,21 +53,21 @@ void main() { test('basic things', () async { if (!olmEnabled) return; - expect(client.encryption.keyManager.enabled, true); - expect(await client.encryption.keyManager.isCached(), false); - final handle = client.encryption.ssss.open(); + expect(client.encryption!.keyManager.enabled, true); + expect(await client.encryption!.keyManager.isCached(), false); + final handle = client.encryption!.ssss.open(); await handle.unlock(recoveryKey: ssssKey); await handle.maybeCacheAll(); - expect(await client.encryption.keyManager.isCached(), true); + expect(await client.encryption!.keyManager.isCached(), true); }); test('load key', () async { if (!olmEnabled) return; - client.encryption.keyManager.clearInboundGroupSessions(); - await client.encryption.keyManager - .request(client.getRoomById(roomId), sessionId, senderKey); + client.encryption!.keyManager.clearInboundGroupSessions(); + await client.encryption!.keyManager + .request(client.getRoomById(roomId)!, sessionId, senderKey); expect( - client.encryption.keyManager + client.encryption!.keyManager .getInboundGroupSession(roomId, sessionId, senderKey) != null, true); @@ -94,25 +93,25 @@ void main() { 'sender_claimed_ed25519_key': client.fingerprintKey, }; FakeMatrixApi.calledEndpoints.clear(); - client.encryption.keyManager.setInboundGroupSession( + client.encryption!.keyManager.setInboundGroupSession( roomId, sessionId, senderKey, sessionPayload, forwarded: true); await Future.delayed(Duration(milliseconds: 500)); - var dbSessions = await client.database.getInboundGroupSessionsToUpload(); + var dbSessions = await client.database!.getInboundGroupSessionsToUpload(); expect(dbSessions.isNotEmpty, true); - await client.encryption.keyManager.backgroundTasks(); + await client.encryption!.keyManager.backgroundTasks(); final payload = FakeMatrixApi - .calledEndpoints['/client/unstable/room_keys/keys?version=5'].first; - dbSessions = await client.database.getInboundGroupSessionsToUpload(); + .calledEndpoints['/client/unstable/room_keys/keys?version=5']!.first; + dbSessions = await client.database!.getInboundGroupSessionsToUpload(); expect(dbSessions.isEmpty, true); final onlineKeys = RoomKeys.fromJson(json.decode(payload)); - client.encryption.keyManager.clearInboundGroupSessions(); - var ret = client.encryption.keyManager + client.encryption!.keyManager.clearInboundGroupSessions(); + var ret = client.encryption!.keyManager .getInboundGroupSession(roomId, sessionId, senderKey); expect(ret, null); - await client.encryption.keyManager.loadFromResponse(onlineKeys); - ret = client.encryption.keyManager + await client.encryption!.keyManager.loadFromResponse(onlineKeys); + ret = client.encryption!.keyManager .getInboundGroupSession(roomId, sessionId, senderKey); expect(ret != null, true); }); diff --git a/test/encryption/ssss_test.dart b/test/encryption/ssss_test.dart index 4189e1f8..13de3af8 100644 --- a/test/encryption/ssss_test.dart +++ b/test/encryption/ssss_test.dart @@ -1,4 +1,3 @@ -// @dart=2.9 /* * Famedly Matrix SDK * Copyright (C) 2020 Famedly GmbH @@ -42,7 +41,7 @@ class MockSSSS extends SSSS { bool requestedSecrets = false; @override - Future maybeRequestAll([List devices]) async { + Future maybeRequestAll([List? devices]) async { requestedSecrets = true; final handle = open(); await handle.unlock(recoveryKey: ssssKey); @@ -55,7 +54,7 @@ void main() { Logs().level = Level.error; var olmEnabled = true; - Client client; + late Client client; test('setupClient', () async { try { @@ -73,7 +72,7 @@ void main() { test('basic things', () async { if (!olmEnabled) return; - expect(client.encryption.ssss.defaultKeyId, + expect(client.encryption!.ssss.defaultKeyId, '0FajDWYaM6wQ4O60OZnLvwZfsBNu4Bu3'); }); @@ -88,7 +87,7 @@ void main() { test('store', () async { if (!olmEnabled) return; - final handle = client.encryption.ssss.open(); + final handle = client.encryption!.ssss.open(); var failed = false; try { await handle.unlock(passphrase: 'invalid'); @@ -114,7 +113,7 @@ void main() { // account_data for this test final content = FakeMatrixApi .calledEndpoints[ - '/client/r0/user/%40test%3AfakeServer.notExisting/account_data/best%20animal'] + '/client/r0/user/%40test%3AfakeServer.notExisting/account_data/best%20animal']! .first; client.accountData['best animal'] = BasicEvent.fromJson({ 'type': 'best animal', @@ -130,77 +129,78 @@ void main() { final decoded = SSSS.decodeRecoveryKey(encoded); expect(key, decoded); - final handle = client.encryption.ssss.open(); + final handle = client.encryption!.ssss.open(); await handle.unlock(recoveryKey: ssssKey); expect(handle.recoveryKey, ssssKey); }); test('cache', () async { if (!olmEnabled) return; - await client.encryption.ssss.clearCache(); + await client.encryption!.ssss.clearCache(); final handle = - client.encryption.ssss.open(EventTypes.CrossSigningSelfSigning); + client.encryption!.ssss.open(EventTypes.CrossSigningSelfSigning); await handle.unlock(recoveryKey: ssssKey, postUnlock: false); expect( - (await client.encryption.ssss + (await client.encryption!.ssss .getCached(EventTypes.CrossSigningSelfSigning)) != null, false); expect( - (await client.encryption.ssss + (await client.encryption!.ssss .getCached(EventTypes.CrossSigningUserSigning)) != null, false); await handle.getStored(EventTypes.CrossSigningSelfSigning); expect( - (await client.encryption.ssss + (await client.encryption!.ssss .getCached(EventTypes.CrossSigningSelfSigning)) != null, true); await handle.maybeCacheAll(); expect( - (await client.encryption.ssss + (await client.encryption!.ssss .getCached(EventTypes.CrossSigningUserSigning)) != null, true); expect( - (await client.encryption.ssss.getCached(EventTypes.MegolmBackup)) != + (await client.encryption!.ssss.getCached(EventTypes.MegolmBackup)) != null, true); }); test('postUnlock', () async { if (!olmEnabled) return; - await client.encryption.ssss.clearCache(); - client.userDeviceKeys[client.userID].masterKey.setDirectVerified(false); + await client.encryption!.ssss.clearCache(); + client.userDeviceKeys[client.userID!]!.masterKey! + .setDirectVerified(false); final handle = - client.encryption.ssss.open(EventTypes.CrossSigningSelfSigning); + client.encryption!.ssss.open(EventTypes.CrossSigningSelfSigning); await handle.unlock(recoveryKey: ssssKey); expect( - (await client.encryption.ssss + (await client.encryption!.ssss .getCached(EventTypes.CrossSigningSelfSigning)) != null, true); expect( - (await client.encryption.ssss + (await client.encryption!.ssss .getCached(EventTypes.CrossSigningUserSigning)) != null, true); expect( - (await client.encryption.ssss.getCached(EventTypes.MegolmBackup)) != + (await client.encryption!.ssss.getCached(EventTypes.MegolmBackup)) != null, true); - expect( - client.userDeviceKeys[client.userID].masterKey.directVerified, true); + expect(client.userDeviceKeys[client.userID!]!.masterKey!.directVerified, + true); }); test('make share requests', () async { if (!olmEnabled) return; final key = - client.userDeviceKeys[client.userID].deviceKeys['OTHERDEVICE']; + client.userDeviceKeys[client.userID!]!.deviceKeys['OTHERDEVICE']!; key.setDirectVerified(true); FakeMatrixApi.calledEndpoints.clear(); - await client.encryption.ssss.request('some.type', [key]); + await client.encryption!.ssss.request('some.type', [key]); expect( FakeMatrixApi.calledEndpoints.keys.any( (k) => k.startsWith('/client/r0/sendToDevice/m.room.encrypted')), @@ -210,7 +210,7 @@ void main() { test('answer to share requests', () async { if (!olmEnabled) return; var event = ToDeviceEvent( - sender: client.userID, + sender: client.userID!, type: 'm.secret.request', content: { 'action': 'request', @@ -220,7 +220,7 @@ void main() { }, ); FakeMatrixApi.calledEndpoints.clear(); - await client.encryption.ssss.handleToDeviceEvent(event); + await client.encryption!.ssss.handleToDeviceEvent(event); expect( FakeMatrixApi.calledEndpoints.keys.any( (k) => k.startsWith('/client/r0/sendToDevice/m.room.encrypted')), @@ -240,7 +240,7 @@ void main() { }, ); FakeMatrixApi.calledEndpoints.clear(); - await client.encryption.ssss.handleToDeviceEvent(event); + await client.encryption!.ssss.handleToDeviceEvent(event); expect( FakeMatrixApi.calledEndpoints.keys.any( (k) => k.startsWith('/client/r0/sendToDevice/m.room.encrypted')), @@ -248,7 +248,7 @@ void main() { // secret not cached event = ToDeviceEvent( - sender: client.userID, + sender: client.userID!, type: 'm.secret.request', content: { 'action': 'request', @@ -258,7 +258,7 @@ void main() { }, ); FakeMatrixApi.calledEndpoints.clear(); - await client.encryption.ssss.handleToDeviceEvent(event); + await client.encryption!.ssss.handleToDeviceEvent(event); expect( FakeMatrixApi.calledEndpoints.keys.any( (k) => k.startsWith('/client/r0/sendToDevice/m.room.encrypted')), @@ -266,7 +266,7 @@ void main() { // is a cancelation event = ToDeviceEvent( - sender: client.userID, + sender: client.userID!, type: 'm.secret.request', content: { 'action': 'request_cancellation', @@ -276,7 +276,7 @@ void main() { }, ); FakeMatrixApi.calledEndpoints.clear(); - await client.encryption.ssss.handleToDeviceEvent(event); + await client.encryption!.ssss.handleToDeviceEvent(event); expect( FakeMatrixApi.calledEndpoints.keys.any( (k) => k.startsWith('/client/r0/sendToDevice/m.room.encrypted')), @@ -284,11 +284,12 @@ void main() { // device not verified final key = - client.userDeviceKeys[client.userID].deviceKeys['OTHERDEVICE']; + client.userDeviceKeys[client.userID!]!.deviceKeys['OTHERDEVICE']!; key.setDirectVerified(false); - client.userDeviceKeys[client.userID].masterKey.setDirectVerified(false); + client.userDeviceKeys[client.userID!]!.masterKey! + .setDirectVerified(false); event = ToDeviceEvent( - sender: client.userID, + sender: client.userID!, type: 'm.secret.request', content: { 'action': 'request', @@ -298,7 +299,7 @@ void main() { }, ); FakeMatrixApi.calledEndpoints.clear(); - await client.encryption.ssss.handleToDeviceEvent(event); + await client.encryption!.ssss.handleToDeviceEvent(event); expect( FakeMatrixApi.calledEndpoints.keys.any( (k) => k.startsWith('/client/r0/sendToDevice/m.room.encrypted')), @@ -309,28 +310,28 @@ void main() { test('receive share requests', () async { if (!olmEnabled) return; final key = - client.userDeviceKeys[client.userID].deviceKeys['OTHERDEVICE']; + client.userDeviceKeys[client.userID!]!.deviceKeys['OTHERDEVICE']!; key.setDirectVerified(true); final handle = - client.encryption.ssss.open(EventTypes.CrossSigningSelfSigning); + client.encryption!.ssss.open(EventTypes.CrossSigningSelfSigning); await handle.unlock(recoveryKey: ssssKey); - await client.encryption.ssss.clearCache(); - client.encryption.ssss.pendingShareRequests.clear(); - await client.encryption.ssss.request('best animal', [key]); + await client.encryption!.ssss.clearCache(); + client.encryption!.ssss.pendingShareRequests.clear(); + await client.encryption!.ssss.request('best animal', [key]); var event = ToDeviceEvent( - sender: client.userID, + sender: client.userID!, type: 'm.secret.send', content: { - 'request_id': client.encryption.ssss.pendingShareRequests.keys.first, + 'request_id': client.encryption!.ssss.pendingShareRequests.keys.first, 'secret': 'foxies!', }, encryptedContent: { 'sender_key': key.curve25519Key, }, ); - await client.encryption.ssss.handleToDeviceEvent(event); - expect(await client.encryption.ssss.getCached('best animal'), 'foxies!'); + await client.encryption!.ssss.handleToDeviceEvent(event); + expect(await client.encryption!.ssss.getCached('best animal'), 'foxies!'); // test the different validators for (final type in [ @@ -339,48 +340,48 @@ void main() { EventTypes.MegolmBackup ]) { final secret = await handle.getStored(type); - await client.encryption.ssss.clearCache(); - client.encryption.ssss.pendingShareRequests.clear(); - await client.encryption.ssss.request(type, [key]); + await client.encryption!.ssss.clearCache(); + client.encryption!.ssss.pendingShareRequests.clear(); + await client.encryption!.ssss.request(type, [key]); event = ToDeviceEvent( - sender: client.userID, + sender: client.userID!, type: 'm.secret.send', content: { 'request_id': - client.encryption.ssss.pendingShareRequests.keys.first, + client.encryption!.ssss.pendingShareRequests.keys.first, 'secret': secret, }, encryptedContent: { 'sender_key': key.curve25519Key, }, ); - await client.encryption.ssss.handleToDeviceEvent(event); - expect(await client.encryption.ssss.getCached(type), secret); + await client.encryption!.ssss.handleToDeviceEvent(event); + expect(await client.encryption!.ssss.getCached(type), secret); } // test different fail scenarios // not encrypted - await client.encryption.ssss.clearCache(); - client.encryption.ssss.pendingShareRequests.clear(); - await client.encryption.ssss.request('best animal', [key]); + await client.encryption!.ssss.clearCache(); + client.encryption!.ssss.pendingShareRequests.clear(); + await client.encryption!.ssss.request('best animal', [key]); event = ToDeviceEvent( - sender: client.userID, + sender: client.userID!, type: 'm.secret.send', content: { - 'request_id': client.encryption.ssss.pendingShareRequests.keys.first, + 'request_id': client.encryption!.ssss.pendingShareRequests.keys.first, 'secret': 'foxies!', }, ); - await client.encryption.ssss.handleToDeviceEvent(event); - expect(await client.encryption.ssss.getCached('best animal'), null); + await client.encryption!.ssss.handleToDeviceEvent(event); + expect(await client.encryption!.ssss.getCached('best animal'), null); // unknown request id - await client.encryption.ssss.clearCache(); - client.encryption.ssss.pendingShareRequests.clear(); - await client.encryption.ssss.request('best animal', [key]); + await client.encryption!.ssss.clearCache(); + client.encryption!.ssss.pendingShareRequests.clear(); + await client.encryption!.ssss.request('best animal', [key]); event = ToDeviceEvent( - sender: client.userID, + sender: client.userID!, type: 'm.secret.send', content: { 'request_id': 'invalid', @@ -390,103 +391,103 @@ void main() { 'sender_key': key.curve25519Key, }, ); - await client.encryption.ssss.handleToDeviceEvent(event); - expect(await client.encryption.ssss.getCached('best animal'), null); + await client.encryption!.ssss.handleToDeviceEvent(event); + expect(await client.encryption!.ssss.getCached('best animal'), null); // not from a device we sent the request to - await client.encryption.ssss.clearCache(); - client.encryption.ssss.pendingShareRequests.clear(); - await client.encryption.ssss.request('best animal', [key]); + await client.encryption!.ssss.clearCache(); + client.encryption!.ssss.pendingShareRequests.clear(); + await client.encryption!.ssss.request('best animal', [key]); event = ToDeviceEvent( - sender: client.userID, + sender: client.userID!, type: 'm.secret.send', content: { - 'request_id': client.encryption.ssss.pendingShareRequests.keys.first, + 'request_id': client.encryption!.ssss.pendingShareRequests.keys.first, 'secret': 'foxies!', }, encryptedContent: { 'sender_key': 'invalid', }, ); - await client.encryption.ssss.handleToDeviceEvent(event); - expect(await client.encryption.ssss.getCached('best animal'), null); + await client.encryption!.ssss.handleToDeviceEvent(event); + expect(await client.encryption!.ssss.getCached('best animal'), null); // secret not a string - await client.encryption.ssss.clearCache(); - client.encryption.ssss.pendingShareRequests.clear(); - await client.encryption.ssss.request('best animal', [key]); + await client.encryption!.ssss.clearCache(); + client.encryption!.ssss.pendingShareRequests.clear(); + await client.encryption!.ssss.request('best animal', [key]); event = ToDeviceEvent( - sender: client.userID, + sender: client.userID!, type: 'm.secret.send', content: { - 'request_id': client.encryption.ssss.pendingShareRequests.keys.first, + 'request_id': client.encryption!.ssss.pendingShareRequests.keys.first, 'secret': 42, }, encryptedContent: { 'sender_key': key.curve25519Key, }, ); - await client.encryption.ssss.handleToDeviceEvent(event); - expect(await client.encryption.ssss.getCached('best animal'), null); + await client.encryption!.ssss.handleToDeviceEvent(event); + expect(await client.encryption!.ssss.getCached('best animal'), null); // validator doesn't check out - await client.encryption.ssss.clearCache(); - client.encryption.ssss.pendingShareRequests.clear(); - await client.encryption.ssss.request(EventTypes.MegolmBackup, [key]); + await client.encryption!.ssss.clearCache(); + client.encryption!.ssss.pendingShareRequests.clear(); + await client.encryption!.ssss.request(EventTypes.MegolmBackup, [key]); event = ToDeviceEvent( - sender: client.userID, + sender: client.userID!, type: 'm.secret.send', content: { - 'request_id': client.encryption.ssss.pendingShareRequests.keys.first, + 'request_id': client.encryption!.ssss.pendingShareRequests.keys.first, 'secret': 'foxies!', }, encryptedContent: { 'sender_key': key.curve25519Key, }, ); - await client.encryption.ssss.handleToDeviceEvent(event); - expect(await client.encryption.ssss.getCached(EventTypes.MegolmBackup), + await client.encryption!.ssss.handleToDeviceEvent(event); + expect(await client.encryption!.ssss.getCached(EventTypes.MegolmBackup), null); }); test('request all', () async { if (!olmEnabled) return; final key = - client.userDeviceKeys[client.userID].deviceKeys['OTHERDEVICE']; + client.userDeviceKeys[client.userID!]!.deviceKeys['OTHERDEVICE']!; key.setDirectVerified(true); - await client.encryption.ssss.clearCache(); - client.encryption.ssss.pendingShareRequests.clear(); - await client.encryption.ssss.maybeRequestAll([key]); - expect(client.encryption.ssss.pendingShareRequests.length, 3); + await client.encryption!.ssss.clearCache(); + client.encryption!.ssss.pendingShareRequests.clear(); + await client.encryption!.ssss.maybeRequestAll([key]); + expect(client.encryption!.ssss.pendingShareRequests.length, 3); }); test('periodicallyRequestMissingCache', () async { if (!olmEnabled) return; - client.userDeviceKeys[client.userID].masterKey.setDirectVerified(true); - client.encryption.ssss = MockSSSS(client.encryption); - (client.encryption.ssss as MockSSSS).requestedSecrets = false; - await client.encryption.ssss.periodicallyRequestMissingCache(); - expect((client.encryption.ssss as MockSSSS).requestedSecrets, true); + client.userDeviceKeys[client.userID!]!.masterKey!.setDirectVerified(true); + client.encryption!.ssss = MockSSSS(client.encryption!); + (client.encryption!.ssss as MockSSSS).requestedSecrets = false; + await client.encryption!.ssss.periodicallyRequestMissingCache(); + expect((client.encryption!.ssss as MockSSSS).requestedSecrets, true); // it should only retry once every 15 min - (client.encryption.ssss as MockSSSS).requestedSecrets = false; - await client.encryption.ssss.periodicallyRequestMissingCache(); - expect((client.encryption.ssss as MockSSSS).requestedSecrets, false); + (client.encryption!.ssss as MockSSSS).requestedSecrets = false; + await client.encryption!.ssss.periodicallyRequestMissingCache(); + expect((client.encryption!.ssss as MockSSSS).requestedSecrets, false); }); test('createKey', () async { if (!olmEnabled) return; // with passphrase - var newKey = await client.encryption.ssss.createKey('test'); - expect(client.encryption.ssss.isKeyValid(newKey.keyId), true); - var testKey = client.encryption.ssss.open(newKey.keyId); + var newKey = await client.encryption!.ssss.createKey('test'); + expect(client.encryption!.ssss.isKeyValid(newKey.keyId), true); + var testKey = client.encryption!.ssss.open(newKey.keyId); await testKey.unlock(passphrase: 'test'); - await testKey.setPrivateKey(newKey.privateKey); + await testKey.setPrivateKey(newKey.privateKey!); // without passphrase - newKey = await client.encryption.ssss.createKey(); - expect(client.encryption.ssss.isKeyValid(newKey.keyId), true); - testKey = client.encryption.ssss.open(newKey.keyId); - await testKey.setPrivateKey(newKey.privateKey); + newKey = await client.encryption!.ssss.createKey(); + expect(client.encryption!.ssss.isKeyValid(newKey.keyId), true); + testKey = client.encryption!.ssss.open(newKey.keyId); + await testKey.setPrivateKey(newKey.privateKey!); }); test('dispose client', () async {