diff --git a/lib/encryption/cross_signing.dart b/lib/encryption/cross_signing.dart index f725fff2..5f8b04c5 100644 --- a/lib/encryption/cross_signing.dart +++ b/lib/encryption/cross_signing.dart @@ -181,23 +181,24 @@ class CrossSigning { } if (signedKeys.isNotEmpty) { // post our new keys! - final payload = >>{}; + final payload = >>{}; for (final key in signedKeys) { - if (key.identifier == null || - key.signatures == null || - key.signatures?.isEmpty != false) { + final signatures = key.signatures; + final identifier = key.identifier; + if (identifier == null || signatures == null || signatures.isEmpty) { continue; } if (!payload.containsKey(key.userId)) { - payload[key.userId] = >{}; + payload[key.userId] = >{}; } if (payload[key.userId]?[key.identifier]?['signatures'] != null) { // we need to merge signature objects - payload[key.userId]![key.identifier]!['signatures'] - .addAll(key.signatures); + payload[key.userId]![key.identifier]! + .tryGetMap>('signatures')! + .addAll(signatures); } else { // we can just add signatures - payload[key.userId]![key.identifier!] = key.toJson(); + payload[key.userId]![identifier] = key.toJson(); } } diff --git a/lib/encryption/olm_manager.dart b/lib/encryption/olm_manager.dart index 9b41d3c7..2176aee2 100644 --- a/lib/encryption/olm_manager.dart +++ b/lib/encryption/olm_manager.dart @@ -102,28 +102,17 @@ class OlmManager { /// Adds a signature to this json from this olm account and returns the signed /// json. - Map signJson(Map payload) { + Map signJson(Map payload) { if (!enabled) throw ('Encryption is disabled'); - final Map? unsigned = payload['unsigned']; - final Map? signatures = payload['signatures']; - payload.remove('unsigned'); - payload.remove('signatures'); - final canonical = canonicalJson.encode(payload); + final signableJson = SignableJsonMap(payload); + + final canonical = canonicalJson.encode(signableJson.jsonMap); final signature = _olmAccount!.sign(String.fromCharCodes(canonical)); - if (signatures != null) { - payload['signatures'] = signatures; - } else { - payload['signatures'] = {}; - } - if (!payload['signatures'].containsKey(client.userID)) { - payload['signatures'][client.userID] = {}; - } - payload['signatures'][client.userID]['ed25519:$ourDeviceId'] = - signature.toBase64(); - if (unsigned != null) { - payload['unsigned'] = unsigned; - } - return payload; + + final userSignatures = signableJson.signatures[client.userID!] ??= {}; + userSignatures['ed25519:$ourDeviceId'] = signature.toBase64(); + + return signableJson.toJson(); } String signString(String s) { @@ -811,3 +800,24 @@ class NoOlmSessionFoundException implements Exception { String toString() => 'No olm session found for ${device.userId}:${device.deviceId}'; } + +class SignableJsonMap { + final Map jsonMap; + final Map> signatures; + final Map? unsigned; + + SignableJsonMap(Map json) + : jsonMap = json, + signatures = + json.tryGetMap>('signatures') ?? {}, + unsigned = json.tryGetMap('unsigned') { + jsonMap.remove('signatures'); + jsonMap.remove('unsigned'); + } + + Map toJson() => { + ...jsonMap, + 'signatures': signatures, + if (unsigned != null) 'unsigned': unsigned, + }; +} diff --git a/lib/encryption/utils/olm_session.dart b/lib/encryption/utils/olm_session.dart index 6c5a385c..7be42ea2 100644 --- a/lib/encryption/utils/olm_session.dart +++ b/lib/encryption/utils/olm_session.dart @@ -41,24 +41,25 @@ class OlmSession { required this.lastReceived, }); - OlmSession.fromJson(Map dbEntry, this.key) - : identityKey = dbEntry['identity_key'] ?? '' { + OlmSession.fromJson(Map dbEntry, this.key) + : identityKey = dbEntry.tryGet('identity_key') ?? '' { try { try { session = vod.Session.fromPickleEncrypted( pickleKey: key.toPickleKey(), - pickle: dbEntry['pickle'], + pickle: dbEntry['pickle'] as String, ); } catch (_) { Logs().d('Unable to unpickle Olm session. Try LibOlm format.'); session = vod.Session.fromOlmPickleEncrypted( pickleKey: utf8.encode(key), - pickle: dbEntry['pickle'], + pickle: dbEntry['pickle'] as String, ); } - sessionId = dbEntry['session_id']; - lastReceived = - DateTime.fromMillisecondsSinceEpoch(dbEntry['last_received'] ?? 0); + sessionId = dbEntry['session_id'] as String; + lastReceived = DateTime.fromMillisecondsSinceEpoch( + dbEntry.tryGet('last_received') ?? 0, + ); assert(sessionId == session!.sessionId); } catch (e, s) { Logs().e('[Vodozemac] Could not unpickle olm session', e, s);