verifyQrData method

Future<bool> verifyQrData(
  1. Uint8List qrDataRawBytes
)

Implementation

Future<bool> verifyQrData(Uint8List qrDataRawBytes) async {
  final data = qrDataRawBytes;
  // hardcoded stuff + 2 keys + secret
  if (data.length < 10 + 32 + 32 + 8 + utf8.encode(transactionId!).length) {
    return false;
  }
  if (data[6] != version) return false;
  final remoteQrMode =
      QRMode.values.singleWhere((mode) => mode.code == data[7]);
  if (ascii.decode(data.sublist(0, 6)) != prefix) return false;
  if (data[6] != version) return false;
  final tmpBuf = Uint8List.fromList([data[8], data[9]]);
  final encodedTxnLen = ByteData.view(tmpBuf.buffer).getUint16(0);
  if (utf8.decode(data.sublist(10, 10 + encodedTxnLen)) != transactionId) {
    return false;
  }
  final keys = client.userDeviceKeys;

  final ownKeys = keys[client.userID];
  final otherUserKeys = keys[userId];
  final ownMasterKey = ownKeys?.getCrossSigningKey('master');
  final ownDeviceKey = ownKeys?.getKey(client.deviceID!);
  final ownOtherDeviceKey = ownKeys?.getKey(deviceId!);
  final otherUserMasterKey = otherUserKeys?.masterKey;

  final secondKey = encodeBase64Unpadded(
    data.sublist(10 + encodedTxnLen + 32, 10 + encodedTxnLen + 32 + 32),
  );
  final randomSharedSecret =
      encodeBase64Unpadded(data.sublist(10 + encodedTxnLen + 32 + 32));

  /// `request.randomSharedSecretForQRCode` is overwritten below to send with `sendStart`
  if ({QRMode.verifyOtherUser, QRMode.verifySelfUntrusted}
      .contains(remoteQrMode)) {
    if (!(ownMasterKey?.verified ?? false)) {
      Logs().e(
        '[KeyVerification] verifyQrData because you were in mode 0/2 and had untrusted msk',
      );
      return false;
    }
  }

  if (remoteQrMode == QRMode.verifyOtherUser &&
      otherUserMasterKey != null &&
      ownMasterKey != null) {
    if (secondKey == ownMasterKey.ed25519Key) {
      randomSharedSecretForQRCode = randomSharedSecret;
      await verifyKeysQR(otherUserMasterKey, shower: false);
      return true;
    }
  } else if (remoteQrMode == QRMode.verifySelfTrusted &&
      ownMasterKey != null &&
      ownDeviceKey != null) {
    if (secondKey == ownDeviceKey.ed25519Key) {
      randomSharedSecretForQRCode = randomSharedSecret;
      await verifyKeysQR(ownMasterKey, shower: false);
      return true;
    }
  } else if (remoteQrMode == QRMode.verifySelfUntrusted &&
      ownOtherDeviceKey != null &&
      ownMasterKey != null) {
    if (secondKey == ownMasterKey.ed25519Key) {
      randomSharedSecretForQRCode = randomSharedSecret;
      await verifyKeysQR(ownOtherDeviceKey, shower: false);
      return true;
    }
  }

  return false;
}