add more tests
This commit is contained in:
parent
34619c065b
commit
7803dc4b93
|
@ -405,8 +405,7 @@ class KeyManager {
|
|||
try {
|
||||
await loadSingleKey(room.id, sessionId);
|
||||
} catch (err, stacktrace) {
|
||||
print('++++++++++++++++++');
|
||||
print(err.toString());
|
||||
print('[KeyManager] Failed to access online key backup: ' + err.toString());
|
||||
print(stacktrace);
|
||||
}
|
||||
if (!hadPreviously &&
|
||||
|
|
|
@ -127,7 +127,7 @@ void main() {
|
|||
}
|
||||
expect(sync.nextBatch == matrix.prevBatch, true);
|
||||
|
||||
expect(matrix.accountData.length, 3);
|
||||
expect(matrix.accountData.length, 9);
|
||||
expect(matrix.getDirectChatFromUserId('@bob:example.com'),
|
||||
'!726s6s6q:example.com');
|
||||
expect(matrix.rooms[1].directChatMatrixID, '@bob:example.com');
|
||||
|
@ -157,7 +157,7 @@ void main() {
|
|||
expect(matrix.presences['@alice:example.com'].presence.presence,
|
||||
PresenceType.online);
|
||||
expect(presenceCounter, 1);
|
||||
expect(accountDataCounter, 3);
|
||||
expect(accountDataCounter, 9);
|
||||
await Future.delayed(Duration(milliseconds: 50));
|
||||
expect(matrix.userDeviceKeys.length, 4);
|
||||
expect(matrix.userDeviceKeys['@alice:example.com'].outdated, false);
|
||||
|
|
207
test/encryption/ssss_test.dart
Normal file
207
test/encryption/ssss_test.dart
Normal file
|
@ -0,0 +1,207 @@
|
|||
/*
|
||||
* Ansible inventory script used at Famedly GmbH for managing many hosts
|
||||
* Copyright (C) 2020 Famedly GmbH
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import 'dart:typed_data';
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:famedlysdk/famedlysdk.dart';
|
||||
import 'package:famedlysdk/matrix_api.dart';
|
||||
import 'package:famedlysdk/encryption.dart';
|
||||
import 'package:test/test.dart';
|
||||
import 'package:encrypt/encrypt.dart';
|
||||
import 'package:olm/olm.dart' as olm;
|
||||
|
||||
import '../fake_client.dart';
|
||||
import '../fake_matrix_api.dart';
|
||||
|
||||
void main() {
|
||||
group('SSSS', () {
|
||||
var olmEnabled = true;
|
||||
try {
|
||||
olm.init();
|
||||
olm.Account();
|
||||
} catch (_) {
|
||||
olmEnabled = false;
|
||||
print('[LibOlm] Failed to load LibOlm: ' + _.toString());
|
||||
}
|
||||
print('[LibOlm] Enabled: $olmEnabled');
|
||||
|
||||
if (!olmEnabled) return;
|
||||
|
||||
Client client;
|
||||
|
||||
test('setupClient', () async {
|
||||
client = await getClient();
|
||||
});
|
||||
|
||||
test('basic things', () async {
|
||||
expect(client.encryption.ssss.defaultKeyId, '0FajDWYaM6wQ4O60OZnLvwZfsBNu4Bu3');
|
||||
});
|
||||
|
||||
test('encrypt / decrypt', () {
|
||||
final signing = olm.PkSigning();
|
||||
final key = Uint8List.fromList(SecureRandom(32).bytes);
|
||||
|
||||
final enc = SSSS.encryptAes('secret foxies', key, 'name');
|
||||
final dec = SSSS.decryptAes(enc, key, 'name');
|
||||
expect(dec, 'secret foxies');
|
||||
});
|
||||
|
||||
test('store', () async {
|
||||
final handle = client.encryption.ssss.open();
|
||||
var failed = false;
|
||||
try {
|
||||
handle.unlock(passphrase: 'invalid');
|
||||
} catch (_) {
|
||||
failed = true;
|
||||
}
|
||||
expect(failed, true);
|
||||
expect(handle.isUnlocked, false);
|
||||
failed = false;
|
||||
try {
|
||||
handle.unlock(recoveryKey: 'invalid');
|
||||
} catch (_) {
|
||||
failed = true;
|
||||
}
|
||||
expect(failed, true);
|
||||
expect(handle.isUnlocked, false);
|
||||
handle.unlock(passphrase: SSSS_PASSPHRASE);
|
||||
handle.unlock(recoveryKey: SSSS_KEY);
|
||||
expect(handle.isUnlocked, true);
|
||||
FakeMatrixApi.calledEndpoints.clear();
|
||||
await handle.store('best animal', 'foxies');
|
||||
// alright, since we don't properly sync we will manually have to update
|
||||
// account_data for this test
|
||||
final content = FakeMatrixApi.calledEndpoints['/client/r0/user/%40test%3AfakeServer.notExisting/account_data/best+animal'].first;
|
||||
client.accountData['best animal'] = BasicEvent.fromJson({
|
||||
'type': 'best animal',
|
||||
'content': json.decode(content),
|
||||
});
|
||||
expect(await handle.getStored('best animal'), 'foxies');
|
||||
});
|
||||
|
||||
test('cache', () async {
|
||||
final handle = client.encryption.ssss.open('m.cross_signing.self_signing');
|
||||
handle.unlock(recoveryKey: SSSS_KEY);
|
||||
expect((await client.encryption.ssss.getCached('m.cross_signing.self_signing')) != null, false);
|
||||
expect((await client.encryption.ssss.getCached('m.cross_signing.user_signing')) != null, false);
|
||||
await handle.getStored('m.cross_signing.self_signing');
|
||||
expect((await client.encryption.ssss.getCached('m.cross_signing.self_signing')) != null, true);
|
||||
await handle.maybeCacheAll();
|
||||
expect((await client.encryption.ssss.getCached('m.cross_signing.user_signing')) != null, true);
|
||||
expect((await client.encryption.ssss.getCached('m.megolm_backup.v1')) != null, true);
|
||||
});
|
||||
|
||||
test('make share requests', () async {
|
||||
final key = client.userDeviceKeys[client.userID].deviceKeys['OTHERDEVICE'];
|
||||
key.setDirectVerified(true);
|
||||
FakeMatrixApi.calledEndpoints.clear();
|
||||
await client.encryption.ssss.request('some.type', [key]);
|
||||
expect(FakeMatrixApi.calledEndpoints.keys.any((k) => k.startsWith('/client/r0/sendToDevice/m.room.encrypted')), true);
|
||||
});
|
||||
|
||||
test('answer to share requests', () async {
|
||||
var event = ToDeviceEvent(
|
||||
sender: client.userID,
|
||||
type: 'm.secret.request',
|
||||
content: {
|
||||
'action': 'request',
|
||||
'requesting_device_id': 'OTHERDEVICE',
|
||||
'name': 'm.cross_signing.self_signing',
|
||||
'request_id': '1',
|
||||
},
|
||||
);
|
||||
FakeMatrixApi.calledEndpoints.clear();
|
||||
await client.encryption.ssss.handleToDeviceEvent(event);
|
||||
expect(FakeMatrixApi.calledEndpoints.keys.any((k) => k.startsWith('/client/r0/sendToDevice/m.room.encrypted')), true);
|
||||
|
||||
// now test some fail scenarios
|
||||
|
||||
// not by us
|
||||
event = ToDeviceEvent(
|
||||
sender: '@someotheruser:example.org',
|
||||
type: 'm.secret.request',
|
||||
content: {
|
||||
'action': 'request',
|
||||
'requesting_device_id': 'OTHERDEVICE',
|
||||
'name': 'm.cross_signing.self_signing',
|
||||
'request_id': '1',
|
||||
},
|
||||
);
|
||||
FakeMatrixApi.calledEndpoints.clear();
|
||||
await client.encryption.ssss.handleToDeviceEvent(event);
|
||||
expect(FakeMatrixApi.calledEndpoints.keys.any((k) => k.startsWith('/client/r0/sendToDevice/m.room.encrypted')), false);
|
||||
|
||||
// secret not cached
|
||||
event = ToDeviceEvent(
|
||||
sender: client.userID,
|
||||
type: 'm.secret.request',
|
||||
content: {
|
||||
'action': 'request',
|
||||
'requesting_device_id': 'OTHERDEVICE',
|
||||
'name': 'm.unknown.secret',
|
||||
'request_id': '1',
|
||||
},
|
||||
);
|
||||
FakeMatrixApi.calledEndpoints.clear();
|
||||
await client.encryption.ssss.handleToDeviceEvent(event);
|
||||
expect(FakeMatrixApi.calledEndpoints.keys.any((k) => k.startsWith('/client/r0/sendToDevice/m.room.encrypted')), false);
|
||||
|
||||
// is a cancelation
|
||||
event = ToDeviceEvent(
|
||||
sender: client.userID,
|
||||
type: 'm.secret.request',
|
||||
content: {
|
||||
'action': 'request_cancellation',
|
||||
'requesting_device_id': 'OTHERDEVICE',
|
||||
'name': 'm.cross_signing.self_signing',
|
||||
'request_id': '1',
|
||||
},
|
||||
);
|
||||
FakeMatrixApi.calledEndpoints.clear();
|
||||
await client.encryption.ssss.handleToDeviceEvent(event);
|
||||
expect(FakeMatrixApi.calledEndpoints.keys.any((k) => k.startsWith('/client/r0/sendToDevice/m.room.encrypted')), false);
|
||||
|
||||
// device not verified
|
||||
final key = client.userDeviceKeys[client.userID].deviceKeys['OTHERDEVICE'];
|
||||
key.setDirectVerified(false);
|
||||
event = ToDeviceEvent(
|
||||
sender: client.userID,
|
||||
type: 'm.secret.request',
|
||||
content: {
|
||||
'action': 'request',
|
||||
'requesting_device_id': 'OTHERDEVICE',
|
||||
'name': 'm.cross_signing.self_signing',
|
||||
'request_id': '1',
|
||||
},
|
||||
);
|
||||
FakeMatrixApi.calledEndpoints.clear();
|
||||
await client.encryption.ssss.handleToDeviceEvent(event);
|
||||
expect(FakeMatrixApi.calledEndpoints.keys.any((k) => k.startsWith('/client/r0/sendToDevice/m.room.encrypted')), false);
|
||||
key.setDirectVerified(true);
|
||||
});
|
||||
|
||||
// test('fail', () {
|
||||
// expect(true, false);
|
||||
// });
|
||||
|
||||
test('dispose client', () async {
|
||||
await client.dispose(closeDatabase: true);
|
||||
});
|
||||
});
|
||||
}
|
|
@ -21,6 +21,9 @@ import 'package:famedlysdk/famedlysdk.dart';
|
|||
import 'fake_matrix_api.dart';
|
||||
import 'fake_database.dart';
|
||||
|
||||
const SSSS_PASSPHRASE = 'nae7ahDiequ7ohniufah3ieS2je1thohX4xeeka7aixohsho9O';
|
||||
const SSSS_KEY = 'EsT9 RzbW VhPW yqNp cC7j ViiW 5TZB LuY4 ryyv 9guN Ysmr WDPH';
|
||||
|
||||
// key @test:fakeServer.notExisting
|
||||
const pickledOlmAccount =
|
||||
'N2v1MkIFGcl0mQpo2OCwSopxPQJ0wnl7oe7PKiT4141AijfdTIhRu+ceXzXKy3Kr00nLqXtRv7kid6hU4a+V0rfJWLL0Y51+3Rp/ORDVnQy+SSeo6Fn4FHcXrxifJEJ0djla5u98fBcJ8BSkhIDmtXRPi5/oJAvpiYn+8zMjFHobOeZUAxYR0VfQ9JzSYBsSovoQ7uFkNks1M4EDUvHtuyg3RxViwdNxs3718fyAqQ/VSwbXsY0Nl+qQbF+nlVGHenGqk5SuNl1P6e1PzZxcR0IfXA94Xij1Ob5gDv5YH4UCn9wRMG0abZsQP0YzpDM0FLaHSCyo9i5JD/vMlhH+nZWrgAzPPCTNGYewNV8/h3c+VyJh8ZTx/fVi6Yq46Fv+27Ga2ETRZ3Qn+Oyx6dLBjnBZ9iUvIhqpe2XqaGA1PopOz8iDnaZitw';
|
||||
|
|
|
@ -516,6 +516,71 @@ class FakeMatrixApi extends MockClient {
|
|||
},
|
||||
'type': 'm.direct'
|
||||
},
|
||||
{
|
||||
'type': 'm.secret_storage.default_key',
|
||||
'content': {'key': '0FajDWYaM6wQ4O60OZnLvwZfsBNu4Bu3'}
|
||||
},
|
||||
{
|
||||
'type': 'm.secret_storage.key.0FajDWYaM6wQ4O60OZnLvwZfsBNu4Bu3',
|
||||
'content': {
|
||||
'algorithm': 'm.secret_storage.v1.aes-hmac-sha2',
|
||||
'passphrase': {
|
||||
'algorithm': 'm.pbkdf2',
|
||||
'iterations': 500000,
|
||||
'salt': 'F4jJ80mr0Fc8mRwU9JgA3lQDyjPuZXQL'
|
||||
},
|
||||
'iv': 'HjbTgIoQH2pI7jQo19NUzA==',
|
||||
'mac': 'QbJjQzDnAggU0cM4RBnDxw2XyarRGjdahcKukP9xVlk='
|
||||
}
|
||||
},
|
||||
{
|
||||
'type': 'm.cross_signing.master',
|
||||
'content': {
|
||||
'encrypted': {
|
||||
'0FajDWYaM6wQ4O60OZnLvwZfsBNu4Bu3': {
|
||||
'iv': 'eIb2IITxtmcq+1TrT8D5eQ==',
|
||||
'ciphertext': 'lWRTPo5qxf4LAVwVPzGHOyMcP181n7bb9/B0lvkLDC2Oy4DvAL0eLx2x3bY=',
|
||||
'mac': 'Ynx89tIxPkx0o6ljMgxszww17JOgB4tg4etmNnMC9XI='
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
'type': 'm.cross_signing.self_signing',
|
||||
'content': {
|
||||
'encrypted': {
|
||||
'0FajDWYaM6wQ4O60OZnLvwZfsBNu4Bu3': {
|
||||
'iv': 'YqU2XIjYulYZl+bkZtGgVw==',
|
||||
'ciphertext': 'kM2TSoy/jR/4d357ZoRPbpPypxQl6XRLo3FsEXz+f7vIOp82GeRp28RYb3k=',
|
||||
'mac': 'F+DZa5tAFmWsYSryw5EuEpzTmmABRab4GETkM85bGGo='
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
'type': 'm.cross_signing.user_signing',
|
||||
'content': {
|
||||
'encrypted': {
|
||||
'0FajDWYaM6wQ4O60OZnLvwZfsBNu4Bu3': {
|
||||
'iv': 'D7AM3LXFu7ZlyGOkR+OeqQ==',
|
||||
'ciphertext': 'bYA2+OMgsO6QB1E31aY+ESAWrT0fUBTXqajy4qmL7bVDSZY4Uj64EXNbHuA=',
|
||||
'mac': 'j2UtyPo/UBSoiaQCWfzCiRZXp3IRt0ZZujuXgUMjnw4='
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
'type': 'm.megolm_backup.v1',
|
||||
'content': {
|
||||
'encrypted': {
|
||||
'0FajDWYaM6wQ4O60OZnLvwZfsBNu4Bu3': {
|
||||
'iv': 'cL/0MJZaiEd3fNU+I9oJrw==',
|
||||
'ciphertext': 'WL73Pzdk5wZdaaSpaeRH0uZYKcxkuV8IS6Qa2FEfA1+vMeRLuHcWlXbMX0w=',
|
||||
'mac': '+xozp909S6oDX8KRV8D8ZFVRyh7eEYQpPP76f+DOsnw='
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
'to_device': {
|
||||
|
@ -1461,6 +1526,13 @@ class FakeMatrixApi extends MockClient {
|
|||
'event_format': 'client',
|
||||
'event_fields': ['type', 'content', 'sender']
|
||||
},
|
||||
'/client/unstable/room_keys/version': (var req) => {
|
||||
'algorithm': 'm.megolm_backup.v1.curve25519-aes-sha2',
|
||||
'auth_data': {'public_key': 'GXYaxqhNhUK28zUdxOmEsFRguz+PzBsDlTLlF0O0RkM'},
|
||||
'count': 0,
|
||||
'etag': '0',
|
||||
'version': '5',
|
||||
},
|
||||
},
|
||||
'POST': {
|
||||
'/client/r0/delete_devices': (var req) => {},
|
||||
|
@ -1673,6 +1745,19 @@ class FakeMatrixApi extends MockClient {
|
|||
},
|
||||
'signatures': {},
|
||||
},
|
||||
'OTHERDEVICE': {
|
||||
'user_id': '@test:fakeServer.notExisting',
|
||||
'device_id': 'OTHERDEVICE',
|
||||
'algorithms': [
|
||||
'm.olm.v1.curve25519-aes-sha2',
|
||||
'm.megolm.v1.aes-sha2'
|
||||
],
|
||||
'keys': {
|
||||
'curve25519:OTHERDEVICE': 'blah',
|
||||
'ed25519:OTHERDEVICE': 'blah'
|
||||
},
|
||||
'signatures': {},
|
||||
},
|
||||
},
|
||||
'@othertest:fakeServer.notExisting': {
|
||||
'FOXDEVICE': {
|
||||
|
@ -1692,6 +1777,36 @@ class FakeMatrixApi extends MockClient {
|
|||
},
|
||||
},
|
||||
},
|
||||
'master_keys': {
|
||||
'@test:fakeServer.notExisting': {
|
||||
'user_id': '@test:fakeServer.notExisting',
|
||||
'usage': ['master'],
|
||||
'keys': {
|
||||
'ed25519:82mAXjsmbTbrE6zyShpR869jnrANO75H8nYY0nDLoJ8': '82mAXjsmbTbrE6zyShpR869jnrANO75H8nYY0nDLoJ8',
|
||||
},
|
||||
'signatures': {},
|
||||
},
|
||||
},
|
||||
'self_signing_keys': {
|
||||
'@test:fakeServer.notExisting': {
|
||||
'user_id': '@test:fakeServer.notExisting',
|
||||
'usage': ['self_signing'],
|
||||
'keys': {
|
||||
'ed25519:F9ypFzgbISXCzxQhhSnXMkc1vq12Luna3Nw5rqViOJY': 'F9ypFzgbISXCzxQhhSnXMkc1vq12Luna3Nw5rqViOJY',
|
||||
},
|
||||
'signatures': {},
|
||||
},
|
||||
},
|
||||
'user_signing_keys': {
|
||||
'@test:fakeServer.notExisting': {
|
||||
'user_id': '@test:fakeServer.notExisting',
|
||||
'usage': ['user_signing'],
|
||||
'keys': {
|
||||
'ed25519:0PiwulzJ/RU86LlzSSZ8St80HUMN3dqjKa/orIJoA0g': '0PiwulzJ/RU86LlzSSZ8St80HUMN3dqjKa/orIJoA0g',
|
||||
},
|
||||
'signatures': {},
|
||||
},
|
||||
},
|
||||
},
|
||||
'/client/r0/register': (var req) => {
|
||||
'user_id': '@testuser:example.com',
|
||||
|
@ -1783,6 +1898,8 @@ class FakeMatrixApi extends MockClient {
|
|||
(var req) => {},
|
||||
'/client/r0/user/%40alice%3Aexample.com/account_data/test.account.data':
|
||||
(var req) => {},
|
||||
'/client/r0/user/%40test%3AfakeServer.notExisting/account_data/best+animal':
|
||||
(var req) => {},
|
||||
'/client/r0/user/%40alice%3Aexample.com/rooms/1234/account_data/test.account.data':
|
||||
(var req) => {},
|
||||
'/client/r0/profile/%40alice%3Aexample.com/displayname': (var reqI) => {},
|
||||
|
|
Loading…
Reference in a new issue