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) {
// 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) {
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] = <String, Map<String, dynamic>>{};
payload[key.userId] = <String, Map<String, Object?>>{};
}
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<String, Map<String, String>>('signatures')!
.addAll(signatures);
} else {
// 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
/// json.
Map<String, dynamic> signJson(Map<String, dynamic> payload) {
Map<String, Object?> signJson(Map<String, Object?> payload) {
if (!enabled) throw ('Encryption is disabled');
final Map<String, dynamic>? unsigned = payload['unsigned'];
final Map<String, dynamic>? 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'] = <String, dynamic>{};
}
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;
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<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,
});
OlmSession.fromJson(Map<String, dynamic> dbEntry, this.key)
: identityKey = dbEntry['identity_key'] ?? '' {
OlmSession.fromJson(Map<String, Object?> dbEntry, this.key)
: identityKey = dbEntry.tryGet<String>('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<int>('last_received') ?? 0,
);
assert(sessionId == session!.sessionId);
} catch (e, s) {
Logs().e('[Vodozemac] Could not unpickle olm session', e, s);