chore: port the remaining encryption files to nullsafety
This commit is contained in:
parent
3ae42d1a88
commit
60956bde00
|
|
@ -3,6 +3,7 @@
|
|||
*.log
|
||||
*.pyc
|
||||
*.swp
|
||||
*.swo
|
||||
.DS_Store
|
||||
.atom/
|
||||
.buildlog/
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
// @dart=2.9
|
||||
/*
|
||||
* Famedly Matrix SDK
|
||||
* Copyright (C) 2020, 2021 Famedly GmbH
|
||||
|
|
@ -35,7 +34,7 @@ class CrossSigning {
|
|||
final keyObj = olm.PkSigning();
|
||||
try {
|
||||
return keyObj.init_with_seed(base64.decode(secret)) ==
|
||||
client.userDeviceKeys[client.userID].selfSigningKey.ed25519Key;
|
||||
client.userDeviceKeys[client.userID]!.selfSigningKey!.ed25519Key;
|
||||
} catch (_) {
|
||||
return false;
|
||||
} finally {
|
||||
|
|
@ -47,7 +46,7 @@ class CrossSigning {
|
|||
final keyObj = olm.PkSigning();
|
||||
try {
|
||||
return keyObj.init_with_seed(base64.decode(secret)) ==
|
||||
client.userDeviceKeys[client.userID].userSigningKey.ed25519Key;
|
||||
client.userDeviceKeys[client.userID]!.userSigningKey!.ed25519Key;
|
||||
} catch (_) {
|
||||
return false;
|
||||
} finally {
|
||||
|
|
@ -73,10 +72,10 @@ class CrossSigning {
|
|||
}
|
||||
|
||||
Future<void> selfSign(
|
||||
{String passphrase,
|
||||
String recoveryKey,
|
||||
String keyOrPassphrase,
|
||||
OpenSSSS openSsss}) async {
|
||||
{String? passphrase,
|
||||
String? recoveryKey,
|
||||
String? keyOrPassphrase,
|
||||
OpenSSSS? openSsss}) async {
|
||||
var handle = openSsss;
|
||||
if (handle == null) {
|
||||
handle = encryption.ssss.open(EventTypes.CrossSigningMasterKey);
|
||||
|
|
@ -97,13 +96,12 @@ class CrossSigning {
|
|||
} finally {
|
||||
keyObj.free();
|
||||
}
|
||||
if (masterPubkey == null ||
|
||||
!client.userDeviceKeys.containsKey(client.userID) ||
|
||||
!client.userDeviceKeys[client.userID].deviceKeys
|
||||
.containsKey(client.deviceID)) {
|
||||
final userDeviceKeys =
|
||||
client.userDeviceKeys[client.userID]?.deviceKeys[client.deviceID];
|
||||
if (masterPubkey == null || userDeviceKeys == null) {
|
||||
throw Exception('Master or user keys not found');
|
||||
}
|
||||
final masterKey = client.userDeviceKeys[client.userID].masterKey;
|
||||
final masterKey = client.userDeviceKeys[client.userID]?.masterKey;
|
||||
if (masterKey == null || masterKey.ed25519Key != masterPubkey) {
|
||||
throw Exception('Master pubkey key doesn\'t match');
|
||||
}
|
||||
|
|
@ -112,7 +110,7 @@ class CrossSigning {
|
|||
// and now sign both our own key and our master key
|
||||
await sign([
|
||||
masterKey,
|
||||
client.userDeviceKeys[client.userID].deviceKeys[client.deviceID]
|
||||
userDeviceKeys,
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
@ -123,20 +121,26 @@ class CrossSigning {
|
|||
key.identifier != client.deviceID);
|
||||
|
||||
Future<void> sign(List<SignableKey> keys) async {
|
||||
Uint8List selfSigningKey;
|
||||
Uint8List userSigningKey;
|
||||
final signedKeys = <MatrixSignableKey>[];
|
||||
Uint8List? selfSigningKey;
|
||||
Uint8List? userSigningKey;
|
||||
final userKeys = client.userDeviceKeys[client.userID];
|
||||
if (userKeys == null) {
|
||||
throw Exception('[sign] keys are not in cache but sign was called');
|
||||
}
|
||||
|
||||
final addSignature =
|
||||
(SignableKey key, SignableKey signedWith, String signature) {
|
||||
if (key == null || signedWith == null || signature == null) {
|
||||
return;
|
||||
}
|
||||
final signedKey = key.cloneForSigning();
|
||||
signedKey.signatures[signedWith.userId] = <String, String>{};
|
||||
signedKey.signatures[signedWith.userId]
|
||||
['ed25519:${signedWith.identifier}'] = signature;
|
||||
((signedKey.signatures ??=
|
||||
<String, Map<String, String>>{})[signedWith.userId] ??=
|
||||
<String, String>{})['ed25519:${signedWith.identifier}'] = signature;
|
||||
signedKeys.add(signedKey);
|
||||
};
|
||||
|
||||
for (final key in keys) {
|
||||
if (key.userId == client.userID) {
|
||||
// we are singing a key of ourself
|
||||
|
|
@ -145,11 +149,7 @@ class CrossSigning {
|
|||
// okay, we'll sign our own master key
|
||||
final signature =
|
||||
encryption.olmManager.signString(key.signingContent);
|
||||
addSignature(
|
||||
key,
|
||||
client
|
||||
.userDeviceKeys[client.userID].deviceKeys[client.deviceID],
|
||||
signature);
|
||||
addSignature(key, userKeys.deviceKeys[client.deviceID]!, signature);
|
||||
}
|
||||
// we don't care about signing other cross-signing keys
|
||||
} else {
|
||||
|
|
@ -159,8 +159,7 @@ class CrossSigning {
|
|||
'');
|
||||
if (selfSigningKey.isNotEmpty) {
|
||||
final signature = _sign(key.signingContent, selfSigningKey);
|
||||
addSignature(key,
|
||||
client.userDeviceKeys[client.userID].selfSigningKey, signature);
|
||||
addSignature(key, userKeys.selfSigningKey!, signature);
|
||||
}
|
||||
}
|
||||
} else if (key is CrossSigningKey && key.usage.contains('master')) {
|
||||
|
|
@ -170,8 +169,7 @@ class CrossSigning {
|
|||
'');
|
||||
if (userSigningKey.isNotEmpty) {
|
||||
final signature = _sign(key.signingContent, userSigningKey);
|
||||
addSignature(key, client.userDeviceKeys[client.userID].userSigningKey,
|
||||
signature);
|
||||
addSignature(key, userKeys.userSigningKey!, signature);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -181,19 +179,19 @@ class CrossSigning {
|
|||
for (final key in signedKeys) {
|
||||
if (key.identifier == null ||
|
||||
key.signatures == null ||
|
||||
key.signatures.isEmpty) {
|
||||
key.signatures?.isEmpty != false) {
|
||||
continue;
|
||||
}
|
||||
if (!payload.containsKey(key.userId)) {
|
||||
payload[key.userId] = <String, Map<String, dynamic>>{};
|
||||
}
|
||||
if (payload[key.userId].containsKey(key.identifier)) {
|
||||
if (payload[key.userId]?[key.identifier]?['signatures'] != null) {
|
||||
// we need to merge signature objects
|
||||
payload[key.userId][key.identifier]['signatures']
|
||||
payload[key.userId]![key.identifier]!['signatures']
|
||||
.addAll(key.signatures);
|
||||
} else {
|
||||
// we can just add signatures
|
||||
payload[key.userId][key.identifier] = key.toJson();
|
||||
payload[key.userId]![key.identifier!] = key.toJson();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -355,10 +355,10 @@ class Encryption {
|
|||
final encryptedPayload = <String, dynamic>{
|
||||
'algorithm': AlgorithmTypes.megolmV1AesSha2,
|
||||
'ciphertext':
|
||||
sess!.outboundGroupSession.encrypt(json.encode(payloadContent)),
|
||||
sess!.outboundGroupSession!.encrypt(json.encode(payloadContent)),
|
||||
'device_id': client.deviceID,
|
||||
'sender_key': identityKey,
|
||||
'session_id': sess.outboundGroupSession.session_id(),
|
||||
'session_id': sess.outboundGroupSession!.session_id(),
|
||||
if (mRelatesTo != null) 'm.relates_to': mRelatesTo,
|
||||
};
|
||||
await keyManager.storeOutboundGroupSession(roomId, sess);
|
||||
|
|
|
|||
|
|
@ -281,7 +281,7 @@ class KeyManager {
|
|||
{bool wipe = false, bool use = true}) async {
|
||||
final room = client.getRoomById(roomId);
|
||||
final sess = getOutboundGroupSession(roomId);
|
||||
if (room == null || sess == null) {
|
||||
if (room == null || sess == null || sess.outboundGroupSession == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -292,7 +292,7 @@ class KeyManager {
|
|||
final maxMessages = encryptionContent?.rotationPeriodMsgs ?? 100;
|
||||
final maxAge = encryptionContent?.rotationPeriodMs ??
|
||||
604800000; // default of one week
|
||||
if (sess.sentMessages >= maxMessages ||
|
||||
if ((sess.sentMessages ?? maxMessages) >= maxMessages ||
|
||||
sess.creationTime
|
||||
.add(Duration(milliseconds: maxAge))
|
||||
.isBefore(DateTime.now())) {
|
||||
|
|
@ -301,7 +301,7 @@ class KeyManager {
|
|||
}
|
||||
|
||||
final inboundSess = await loadInboundGroupSession(room.id,
|
||||
sess.outboundGroupSession.session_id(), encryption.identityKey!);
|
||||
sess.outboundGroupSession!.session_id(), encryption.identityKey!);
|
||||
if (inboundSess == null) {
|
||||
wipe = true;
|
||||
}
|
||||
|
|
@ -371,13 +371,12 @@ class KeyManager {
|
|||
return false;
|
||||
}
|
||||
// okay, we use the outbound group session!
|
||||
sess.sentMessages++;
|
||||
sess.devices = newDeviceKeyIds;
|
||||
final rawSession = <String, dynamic>{
|
||||
'algorithm': AlgorithmTypes.megolmV1AesSha2,
|
||||
'room_id': room.id,
|
||||
'session_id': sess.outboundGroupSession.session_id(),
|
||||
'session_key': sess.outboundGroupSession.session_key(),
|
||||
'session_id': sess.outboundGroupSession!.session_id(),
|
||||
'session_key': sess.outboundGroupSession!.session_key(),
|
||||
};
|
||||
try {
|
||||
devicesToReceive.removeWhere((k) => !k.encryptToDevice);
|
||||
|
|
@ -389,17 +388,17 @@ class KeyManager {
|
|||
.containsKey(device.curve25519Key) ||
|
||||
inboundSess.allowedAtIndex[device.userId]![
|
||||
device.curve25519Key]! >
|
||||
sess.outboundGroupSession.message_index()) {
|
||||
sess.outboundGroupSession!.message_index()) {
|
||||
inboundSess
|
||||
.allowedAtIndex[device.userId]![device.curve25519Key!] =
|
||||
sess.outboundGroupSession.message_index();
|
||||
sess.outboundGroupSession!.message_index();
|
||||
}
|
||||
}
|
||||
if (client.database != null) {
|
||||
await client.database.updateInboundGroupSessionAllowedAtIndex(
|
||||
json.encode(inboundSess!.allowedAtIndex),
|
||||
room.id,
|
||||
sess.outboundGroupSession.session_id());
|
||||
sess.outboundGroupSession!.session_id());
|
||||
}
|
||||
// send out the key
|
||||
await client.sendToDeviceEncryptedChunked(
|
||||
|
|
@ -425,10 +424,9 @@ class KeyManager {
|
|||
String roomId, OutboundGroupSession sess) async {
|
||||
await client.database?.storeOutboundGroupSession(
|
||||
roomId,
|
||||
sess.outboundGroupSession.pickle(client.userID),
|
||||
sess.outboundGroupSession!.pickle(client.userID),
|
||||
json.encode(sess.devices),
|
||||
sess.creationTime.millisecondsSinceEpoch,
|
||||
sess.sentMessages);
|
||||
sess.creationTime.millisecondsSinceEpoch);
|
||||
}
|
||||
|
||||
final Map<String, Future<OutboundGroupSession>>
|
||||
|
|
@ -500,7 +498,6 @@ class KeyManager {
|
|||
devices: deviceKeyIds,
|
||||
creationTime: DateTime.now(),
|
||||
outboundGroupSession: outboundGroupSession,
|
||||
sentMessages: 0,
|
||||
key: client.userID,
|
||||
);
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
// @dart=2.9
|
||||
/*
|
||||
* Famedly Matrix SDK
|
||||
* Copyright (C) 2020, 2021 Famedly GmbH
|
||||
|
|
@ -50,10 +49,10 @@ class KeyVerificationManager {
|
|||
if (request.transactionId == null) {
|
||||
return;
|
||||
}
|
||||
_requests[request.transactionId] = request;
|
||||
_requests[request.transactionId!] = request;
|
||||
}
|
||||
|
||||
KeyVerification getRequest(String requestId) => _requests[requestId];
|
||||
KeyVerification? getRequest(String requestId) => _requests[requestId];
|
||||
|
||||
Future<void> handleToDeviceEvent(ToDeviceEvent event) async {
|
||||
if (!event.type.startsWith('m.key.verification.') ||
|
||||
|
|
@ -65,10 +64,11 @@ class KeyVerificationManager {
|
|||
if (transactionId == null) {
|
||||
return; // TODO: send cancel with unknown transaction id
|
||||
}
|
||||
if (_requests.containsKey(transactionId)) {
|
||||
final request = _requests[transactionId];
|
||||
if (request != null) {
|
||||
// make sure that new requests can't come from ourself
|
||||
if (!{EventTypes.KeyVerificationRequest}.contains(event.type)) {
|
||||
await _requests[transactionId].handlePayload(event.type, event.content);
|
||||
await request.handlePayload(event.type, event.content);
|
||||
}
|
||||
} else {
|
||||
if (!{EventTypes.KeyVerificationRequest, EventTypes.KeyVerificationStart}
|
||||
|
|
@ -105,8 +105,8 @@ class KeyVerificationManager {
|
|||
final transactionId =
|
||||
KeyVerification.getTransactionId(event['content']) ?? event['event_id'];
|
||||
|
||||
if (_requests.containsKey(transactionId)) {
|
||||
final req = _requests[transactionId];
|
||||
if (req != null) {
|
||||
final otherDeviceId = event['content']['from_device'];
|
||||
if (event['sender'] != client.userID) {
|
||||
await req.handlePayload(type, event['content'], event['event_id']);
|
||||
|
|
|
|||
|
|
@ -145,7 +145,8 @@ class OlmManager {
|
|||
bool updateDatabase = true,
|
||||
bool? unusedFallbackKey = false,
|
||||
}) async {
|
||||
if (!enabled) {
|
||||
final _olmAccount = this._olmAccount;
|
||||
if (_olmAccount == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -161,22 +162,22 @@ class OlmManager {
|
|||
// check if we have OTKs that still need uploading. If we do, we don't try to generate new ones,
|
||||
// instead we try to upload the old ones first
|
||||
final oldOTKsNeedingUpload = json
|
||||
.decode(_olmAccount!.one_time_keys())['curve25519']
|
||||
.decode(_olmAccount.one_time_keys())['curve25519']
|
||||
.entries
|
||||
.length as int;
|
||||
// generate one-time keys
|
||||
// we generate 2/3rds of max, so that other keys people may still have can
|
||||
// still be used
|
||||
final oneTimeKeysCount =
|
||||
(_olmAccount!.max_number_of_one_time_keys() * 2 / 3).floor() -
|
||||
(_olmAccount.max_number_of_one_time_keys() * 2 / 3).floor() -
|
||||
oldKeyCount -
|
||||
oldOTKsNeedingUpload;
|
||||
if (oneTimeKeysCount > 0) {
|
||||
_olmAccount!.generate_one_time_keys(oneTimeKeysCount);
|
||||
_olmAccount.generate_one_time_keys(oneTimeKeysCount);
|
||||
}
|
||||
uploadedOneTimeKeysCount = oneTimeKeysCount + oldOTKsNeedingUpload;
|
||||
final Map<String, dynamic> oneTimeKeys =
|
||||
json.decode(_olmAccount!.one_time_keys());
|
||||
json.decode(_olmAccount.one_time_keys());
|
||||
|
||||
// now sign all the one-time keys
|
||||
for (final entry in oneTimeKeys['curve25519'].entries) {
|
||||
|
|
@ -191,8 +192,8 @@ class OlmManager {
|
|||
final signedFallbackKeys = <String, dynamic>{};
|
||||
if (encryption.isMinOlmVersion(3, 2, 0) && unusedFallbackKey == false) {
|
||||
// we don't have an unused fallback key uploaded....so let's change that!
|
||||
_olmAccount!.generate_fallback_key();
|
||||
final fallbackKey = json.decode(_olmAccount!.fallback_key());
|
||||
_olmAccount.generate_fallback_key();
|
||||
final fallbackKey = json.decode(_olmAccount.fallback_key());
|
||||
// now sign all the fallback keys
|
||||
for (final entry in fallbackKey['curve25519'].entries) {
|
||||
final key = entry.key;
|
||||
|
|
@ -219,7 +220,7 @@ class OlmManager {
|
|||
};
|
||||
if (uploadDeviceKeys) {
|
||||
final Map<String, dynamic> keys =
|
||||
json.decode(_olmAccount!.identity_keys());
|
||||
json.decode(_olmAccount.identity_keys());
|
||||
for (final entry in keys.entries) {
|
||||
final algorithm = entry.key;
|
||||
final value = entry.value;
|
||||
|
|
@ -244,7 +245,7 @@ class OlmManager {
|
|||
fallbackKeys: signedFallbackKeys,
|
||||
);
|
||||
// mark the OTKs as published and save that to datbase
|
||||
_olmAccount!.mark_keys_as_published();
|
||||
_olmAccount.mark_keys_as_published();
|
||||
if (updateDatabase) {
|
||||
await client.database?.updateClientKeys(pickledOlmAccount!);
|
||||
}
|
||||
|
|
@ -553,14 +554,16 @@ class OlmManager {
|
|||
client.userDeviceKeys[userId]!.deviceKeys[deviceId]!.curve25519Key;
|
||||
for (final Map<String, dynamic> deviceKey
|
||||
in deviceKeysEntry.value.values) {
|
||||
if (!deviceKey.checkJsonSignature(fingerprintKey, userId, deviceId)) {
|
||||
if (fingerprintKey == null ||
|
||||
identityKey == null ||
|
||||
!deviceKey.checkJsonSignature(fingerprintKey, userId, deviceId)) {
|
||||
continue;
|
||||
}
|
||||
Logs().v('[OlmManager] Starting session with $userId:$deviceId');
|
||||
final session = olm.Session();
|
||||
try {
|
||||
session.create_outbound(
|
||||
_olmAccount!, identityKey!, deviceKey['key']);
|
||||
_olmAccount!, identityKey, deviceKey['key']);
|
||||
await storeOlmSession(OlmSession(
|
||||
key: client.userID,
|
||||
identityKey: identityKey,
|
||||
|
|
@ -666,8 +669,7 @@ class OlmManager {
|
|||
'[OlmManager] Device ${device.userId}:${device.deviceId} generated a new olm session, replaying last sent message...');
|
||||
final lastSentMessageRes = await client.database
|
||||
.getLastSentMessageUserDeviceKey(device.userId, device.deviceId!);
|
||||
if (lastSentMessageRes.isEmpty ||
|
||||
(lastSentMessageRes.first?.isEmpty ?? true)) {
|
||||
if (lastSentMessageRes.isEmpty || (lastSentMessageRes.first.isEmpty)) {
|
||||
return;
|
||||
}
|
||||
final lastSentMessage = json.decode(lastSentMessageRes.first);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
// @dart=2.9
|
||||
/*
|
||||
* Famedly Matrix SDK
|
||||
* Copyright (C) 2020, 2021 Famedly GmbH
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ class KeyVerification {
|
|||
method?.dispose();
|
||||
}
|
||||
|
||||
static String getTransactionId(Map<String, dynamic> payload) {
|
||||
static String? getTransactionId(Map<String, dynamic> payload) {
|
||||
return payload['transaction_id'] ??
|
||||
(payload['m.relates_to'] is Map
|
||||
? payload['m.relates_to']['event_id']
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
// @dart=2.9
|
||||
/*
|
||||
* Famedly Matrix SDK
|
||||
* Copyright (C) 2019, 2020, 2021 Famedly GmbH
|
||||
|
|
@ -28,24 +27,23 @@ class OutboundGroupSession {
|
|||
/// This way we can easily know if a new user is added, leaves, a new devices is added, and,
|
||||
/// very importantly, if we block a device. These are all important for determining if/when
|
||||
/// an outbound session needs to be rotated.
|
||||
Map<String, Map<String, bool>> devices;
|
||||
DateTime creationTime;
|
||||
olm.OutboundGroupSession outboundGroupSession;
|
||||
int sentMessages;
|
||||
Map<String, Map<String, bool>> devices = {};
|
||||
// Default to a date, that would get this session rotated in any case to make handling easier
|
||||
DateTime creationTime = DateTime.fromMillisecondsSinceEpoch(0);
|
||||
olm.OutboundGroupSession? outboundGroupSession;
|
||||
int? get sentMessages => outboundGroupSession?.message_index();
|
||||
bool get isValid => outboundGroupSession != null;
|
||||
final String key;
|
||||
|
||||
OutboundGroupSession(
|
||||
{this.devices,
|
||||
this.creationTime,
|
||||
this.outboundGroupSession,
|
||||
this.sentMessages,
|
||||
this.key});
|
||||
{required this.devices,
|
||||
required this.creationTime,
|
||||
required this.outboundGroupSession,
|
||||
required this.key});
|
||||
|
||||
OutboundGroupSession.fromJson(Map<String, dynamic> dbEntry, String key)
|
||||
: key = key {
|
||||
try {
|
||||
devices = {};
|
||||
for (final entry in json.decode(dbEntry['device_ids']).entries) {
|
||||
devices[entry.key] = Map<String, bool>.from(entry.value);
|
||||
}
|
||||
|
|
@ -58,10 +56,9 @@ class OutboundGroupSession {
|
|||
}
|
||||
outboundGroupSession = olm.OutboundGroupSession();
|
||||
try {
|
||||
outboundGroupSession.unpickle(key, dbEntry['pickle']);
|
||||
outboundGroupSession!.unpickle(key, dbEntry['pickle']);
|
||||
creationTime =
|
||||
DateTime.fromMillisecondsSinceEpoch(dbEntry['creation_time']);
|
||||
sentMessages = dbEntry['sent_messages'];
|
||||
} catch (e, s) {
|
||||
dispose();
|
||||
Logs().e('[LibOlm] Unable to unpickle outboundGroupSession', e, s);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
// @dart=2.9
|
||||
/*
|
||||
* Famedly Matrix SDK
|
||||
* Copyright (C) 2021 Famedly GmbH
|
||||
|
|
@ -29,15 +28,15 @@ class StoredInboundGroupSession {
|
|||
final String senderClaimedKeys;
|
||||
|
||||
StoredInboundGroupSession({
|
||||
this.roomId,
|
||||
this.sessionId,
|
||||
this.pickle,
|
||||
this.content,
|
||||
this.indexes,
|
||||
this.allowedAtIndex,
|
||||
this.uploaded,
|
||||
this.senderKey,
|
||||
this.senderClaimedKeys,
|
||||
required this.roomId,
|
||||
required this.sessionId,
|
||||
required this.pickle,
|
||||
required this.content,
|
||||
required this.indexes,
|
||||
required this.allowedAtIndex,
|
||||
required this.uploaded,
|
||||
required this.senderKey,
|
||||
required this.senderClaimedKeys,
|
||||
});
|
||||
|
||||
factory StoredInboundGroupSession.fromJson(Map<String, dynamic> json) =>
|
||||
|
|
|
|||
|
|
@ -146,7 +146,6 @@ abstract class DatabaseApi {
|
|||
String pickle,
|
||||
String deviceIds,
|
||||
int creationTime,
|
||||
int sentMessages,
|
||||
);
|
||||
|
||||
Future updateClientKeys(
|
||||
|
|
|
|||
|
|
@ -1028,14 +1028,13 @@ class FamedlySdkHiveDatabase extends DatabaseApi {
|
|||
}
|
||||
|
||||
@override
|
||||
Future<void> storeOutboundGroupSession(String roomId, String pickle,
|
||||
String deviceIds, int creationTime, int sentMessages) async {
|
||||
Future<void> storeOutboundGroupSession(
|
||||
String roomId, String pickle, String deviceIds, int creationTime) async {
|
||||
await _outboundGroupSessionsBox.put(roomId.toHiveKey, <String, dynamic>{
|
||||
'room_id': roomId,
|
||||
'pickle': pickle,
|
||||
'device_ids': deviceIds,
|
||||
'creation_time': creationTime,
|
||||
'sent_messages': sentMessages,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -299,7 +299,7 @@ abstract class SignableKey extends MatrixSignableKey {
|
|||
// or else we just recurse into that key and chack if it works out
|
||||
final haveChain = key.hasValidSignatureChain(
|
||||
verifiedOnly: verifiedOnly,
|
||||
visited: visited,
|
||||
visited: visited_,
|
||||
onlyValidateUserIds: onlyValidateUserIds);
|
||||
if (haveChain) {
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -342,7 +342,6 @@ void testDatabase(
|
|||
'pickle',
|
||||
'{}',
|
||||
0,
|
||||
0,
|
||||
);
|
||||
final session = await database.getOutboundGroupSession(
|
||||
'!testroom:example.com',
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ void main() {
|
|||
]);
|
||||
final body = json.decode(FakeMatrixApi
|
||||
.calledEndpoints['/client/r0/keys/signatures/upload'].first);
|
||||
expect(body['@test:fakeServer.notExisting'].containsKey('OTHERDEVICE'),
|
||||
expect(body['@test:fakeServer.notExisting']?.containsKey('OTHERDEVICE'),
|
||||
true);
|
||||
expect(
|
||||
body['@test:fakeServer.notExisting'].containsKey(
|
||||
|
|
|
|||
|
|
@ -124,7 +124,9 @@ void main() {
|
|||
0);
|
||||
|
||||
// rotate after too many messages
|
||||
sess.sentMessages = 300;
|
||||
Iterable.generate(300).forEach((_) {
|
||||
sess.outboundGroupSession.encrypt('some string');
|
||||
});
|
||||
await client.encryption.keyManager.clearOrUseOutboundGroupSession(roomId);
|
||||
expect(
|
||||
client.encryption.keyManager.getOutboundGroupSession(roomId) != null,
|
||||
|
|
|
|||
Loading…
Reference in New Issue