sign method
Implementation
Future<void> sign(List<SignableKey> keys) async {
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');
}
void addSignature(
SignableKey key,
SignableKey signedWith,
String signature,
) {
final signedKey = key.cloneForSigning();
((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
if (key is CrossSigningKey) {
if (key.usage.contains('master')) {
// okay, we'll sign our own master key
final signature =
encryption.olmManager.signString(key.signingContent);
addSignature(key, userKeys.deviceKeys[client.deviceID]!, signature);
}
// we don't care about signing other cross-signing keys
} else {
// okay, we'll sign a device key with our self signing key
selfSigningKey ??= base64decodeUnpadded(
await encryption.ssss
.getCached(EventTypes.CrossSigningSelfSigning) ??
'',
);
if (selfSigningKey.isNotEmpty) {
final signature = _sign(key.signingContent, selfSigningKey);
addSignature(key, userKeys.selfSigningKey!, signature);
}
}
} else if (key is CrossSigningKey && key.usage.contains('master')) {
// we are signing someone elses master key
userSigningKey ??= base64decodeUnpadded(
await encryption.ssss.getCached(EventTypes.CrossSigningUserSigning) ??
'',
);
if (userSigningKey.isNotEmpty) {
final signature = _sign(key.signingContent, userSigningKey);
addSignature(key, userKeys.userSigningKey!, signature);
}
}
}
if (signedKeys.isNotEmpty) {
// post our new keys!
final payload = <String, Map<String, Map<String, Object?>>>{};
for (final key in signedKeys) {
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, Object?>>{};
}
if (payload[key.userId]?[key.identifier]?['signatures'] != null) {
// we need to merge signature objects
payload[key.userId]![key.identifier]!
.tryGetMap<String, Map<String, String>>('signatures')!
.addAll(signatures);
} else {
// we can just add signatures
payload[key.userId]![identifier] = key.toJson();
}
}
await client.uploadCrossSigningSignatures(payload);
}
}