verifyKeysSAS method

Future<void> verifyKeysSAS(
  1. Map<String, String> keys,
  2. Future<bool> verifier(
    1. String,
    2. SignableKey
    )
)

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);
  }
}