verifyKeysSAS method
Implementation
Future<void> verifyKeysSAS(Map<String, String> keys,
Future<bool> Function(String, SignableKey) verifier) async {
_verifiedDevices = <SignableKey>[];
final userDeviceKey = client.userDeviceKeys[userId];
if (userDeviceKey == null) {
await cancel('m.key_mismatch');
return;
}
for (final entry in keys.entries) {
final keyId = entry.key;
final verifyDeviceId = keyId.substring('ed25519:'.length);
final keyInfo = entry.value;
final key = userDeviceKey.getKey(verifyDeviceId);
if (key != null) {
if (!(await verifier(keyInfo, key))) {
await cancel('m.key_mismatch');
return;
}
_verifiedDevices.add(key);
}
}
// okay, we reached this far, so all the devices are verified!
var verifiedMasterKey = false;
final wasUnknownSession = client.isUnknownSession;
for (final key in _verifiedDevices) {
await key.setVerified(
true, false); // we don't want to sign the keys juuuust yet
if (key is CrossSigningKey && key.usage.contains('master')) {
verifiedMasterKey = true;
}
}
if (verifiedMasterKey && userId == client.userID) {
// it was our own master key, let's request the cross signing keys
// we do it in the background, thus no await needed here
// ignore: unawaited_futures
maybeRequestSSSSSecrets();
}
await send(EventTypes.KeyVerificationDone, {});
var askingSSSS = false;
if (encryption.crossSigning.enabled &&
encryption.crossSigning.signable(_verifiedDevices)) {
// these keys can be signed! Let's do so
if (await encryption.crossSigning.isCached()) {
// we want to make sure the verification state is correct for the other party after this event is handled.
// Otherwise the verification dialog might be stuck in an unverified but done state for a bit.
await encryption.crossSigning.sign(_verifiedDevices);
} else if (!wasUnknownSession) {
askingSSSS = true;
}
}
if (askingSSSS) {
setState(KeyVerificationState.askSSSS);
_nextAction = 'done';
} else {
setState(KeyVerificationState.done);
}
}