Merge pull request #2126 from famedly/krille/remove-dynamic-in-maps

refactor: Remove dynamic in cross signing code
This commit is contained in:
Krille-chan 2025-08-27 09:18:14 +02:00 committed by GitHub
commit 138eddac3f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 47 additions and 35 deletions

View File

@ -181,23 +181,24 @@ class CrossSigning {
} }
if (signedKeys.isNotEmpty) { if (signedKeys.isNotEmpty) {
// post our new keys! // post our new keys!
final payload = <String, Map<String, Map<String, dynamic>>>{}; final payload = <String, Map<String, Map<String, Object?>>>{};
for (final key in signedKeys) { for (final key in signedKeys) {
if (key.identifier == null || final signatures = key.signatures;
key.signatures == null || final identifier = key.identifier;
key.signatures?.isEmpty != false) { if (identifier == null || signatures == null || signatures.isEmpty) {
continue; continue;
} }
if (!payload.containsKey(key.userId)) { if (!payload.containsKey(key.userId)) {
payload[key.userId] = <String, Map<String, dynamic>>{}; payload[key.userId] = <String, Map<String, Object?>>{};
} }
if (payload[key.userId]?[key.identifier]?['signatures'] != null) { if (payload[key.userId]?[key.identifier]?['signatures'] != null) {
// we need to merge signature objects // we need to merge signature objects
payload[key.userId]![key.identifier]!['signatures'] payload[key.userId]![key.identifier]!
.addAll(key.signatures); .tryGetMap<String, Map<String, String>>('signatures')!
.addAll(signatures);
} else { } else {
// we can just add signatures // we can just add signatures
payload[key.userId]![key.identifier!] = key.toJson(); payload[key.userId]![identifier] = key.toJson();
} }
} }

View File

@ -102,28 +102,17 @@ class OlmManager {
/// Adds a signature to this json from this olm account and returns the signed /// Adds a signature to this json from this olm account and returns the signed
/// json. /// json.
Map<String, dynamic> signJson(Map<String, dynamic> payload) { Map<String, Object?> signJson(Map<String, Object?> payload) {
if (!enabled) throw ('Encryption is disabled'); if (!enabled) throw ('Encryption is disabled');
final Map<String, dynamic>? unsigned = payload['unsigned']; final signableJson = SignableJsonMap(payload);
final Map<String, dynamic>? signatures = payload['signatures'];
payload.remove('unsigned'); final canonical = canonicalJson.encode(signableJson.jsonMap);
payload.remove('signatures');
final canonical = canonicalJson.encode(payload);
final signature = _olmAccount!.sign(String.fromCharCodes(canonical)); final signature = _olmAccount!.sign(String.fromCharCodes(canonical));
if (signatures != null) {
payload['signatures'] = signatures; final userSignatures = signableJson.signatures[client.userID!] ??= {};
} else { userSignatures['ed25519:$ourDeviceId'] = signature.toBase64();
payload['signatures'] = <String, dynamic>{};
} return signableJson.toJson();
if (!payload['signatures'].containsKey(client.userID)) {
payload['signatures'][client.userID] = <String, dynamic>{};
}
payload['signatures'][client.userID]['ed25519:$ourDeviceId'] =
signature.toBase64();
if (unsigned != null) {
payload['unsigned'] = unsigned;
}
return payload;
} }
String signString(String s) { String signString(String s) {
@ -811,3 +800,24 @@ class NoOlmSessionFoundException implements Exception {
String toString() => String toString() =>
'No olm session found for ${device.userId}:${device.deviceId}'; 'No olm session found for ${device.userId}:${device.deviceId}';
} }
class SignableJsonMap {
final Map<String, Object?> jsonMap;
final Map<String, Map<String, String>> signatures;
final Map<String, Object?>? unsigned;
SignableJsonMap(Map<String, Object?> json)
: jsonMap = json,
signatures =
json.tryGetMap<String, Map<String, String>>('signatures') ?? {},
unsigned = json.tryGetMap<String, Object?>('unsigned') {
jsonMap.remove('signatures');
jsonMap.remove('unsigned');
}
Map<String, Object?> toJson() => {
...jsonMap,
'signatures': signatures,
if (unsigned != null) 'unsigned': unsigned,
};
}

View File

@ -41,24 +41,25 @@ class OlmSession {
required this.lastReceived, required this.lastReceived,
}); });
OlmSession.fromJson(Map<String, dynamic> dbEntry, this.key) OlmSession.fromJson(Map<String, Object?> dbEntry, this.key)
: identityKey = dbEntry['identity_key'] ?? '' { : identityKey = dbEntry.tryGet<String>('identity_key') ?? '' {
try { try {
try { try {
session = vod.Session.fromPickleEncrypted( session = vod.Session.fromPickleEncrypted(
pickleKey: key.toPickleKey(), pickleKey: key.toPickleKey(),
pickle: dbEntry['pickle'], pickle: dbEntry['pickle'] as String,
); );
} catch (_) { } catch (_) {
Logs().d('Unable to unpickle Olm session. Try LibOlm format.'); Logs().d('Unable to unpickle Olm session. Try LibOlm format.');
session = vod.Session.fromOlmPickleEncrypted( session = vod.Session.fromOlmPickleEncrypted(
pickleKey: utf8.encode(key), pickleKey: utf8.encode(key),
pickle: dbEntry['pickle'], pickle: dbEntry['pickle'] as String,
); );
} }
sessionId = dbEntry['session_id']; sessionId = dbEntry['session_id'] as String;
lastReceived = lastReceived = DateTime.fromMillisecondsSinceEpoch(
DateTime.fromMillisecondsSinceEpoch(dbEntry['last_received'] ?? 0); dbEntry.tryGet<int>('last_received') ?? 0,
);
assert(sessionId == session!.sessionId); assert(sessionId == session!.sessionId);
} catch (e, s) { } catch (e, s) {
Logs().e('[Vodozemac] Could not unpickle olm session', e, s); Logs().e('[Vodozemac] Could not unpickle olm session', e, s);