initCryptoIdentity method

Future<String> initCryptoIdentity({
  1. String? passphrase,
  2. bool wipeSecureStorage = true,
  3. bool wipeKeyBackup = true,
  4. bool wipeCrossSigning = true,
  5. bool setupMasterKey = true,
  6. bool setupSelfSigningKey = true,
  7. bool setupUserSigningKey = true,
  8. bool setupOnlineKeyBackup = true,
  9. String? keyName,
})

Bootsraps a new crypto identity for the client. Creates secret storage and cross-signing keys and optionally online key backup. Returns the generated recovery key when secret storage is newly created.

passphrase lets users remember a human-readable phrase from which the recovery key is derived using PBKDF2. When wipeSecureStorage or wipeKeyBackup or wipeCrossSigning are true, existing data is wiped during setup. The setup* flags control which cross-signing keys and key backup are provisioned. keyName can label the generated secret storage key.

Implementation

Future<String> initCryptoIdentity({
  String? passphrase,
  bool wipeSecureStorage = true,
  bool wipeKeyBackup = true,
  bool wipeCrossSigning = true,
  bool setupMasterKey = true,
  bool setupSelfSigningKey = true,
  bool setupUserSigningKey = true,
  bool setupOnlineKeyBackup = true,
  String? keyName,
}) async {
  final encryption = this.encryption;
  if (encryption == null) {
    throw Exception('End to end encryption not available!');
  }

  String? newSsssKey;
  final completer = Completer();
  encryption.bootstrap(
    onUpdate: (bootstrap) async {
      try {
        newSsssKey ??= bootstrap.newSsssKey?.recoveryKey;
        switch (bootstrap.state) {
          case BootstrapState.loading:
            break;
          case BootstrapState.askWipeSsss:
            bootstrap.wipeSsss(wipeSecureStorage);
            break;
          case BootstrapState.askUseExistingSsss:
            bootstrap.useExistingSsss(false);
            break;
          case BootstrapState.askUnlockSsss:
            bootstrap.unlockedSsss();
            break;
          case BootstrapState.askBadSsss:
            bootstrap.ignoreBadSecrets(true);
            break;
          case BootstrapState.askWipeCrossSigning:
            await bootstrap.wipeCrossSigning(wipeCrossSigning);
            break;
          case BootstrapState.askWipeOnlineKeyBackup:
            bootstrap.wipeOnlineKeyBackup(wipeKeyBackup);
            break;
          case BootstrapState.askSetupOnlineKeyBackup:
            await bootstrap.askSetupOnlineKeyBackup(setupOnlineKeyBackup);
            break;
          case BootstrapState.askSetupCrossSigning:
            await bootstrap.askSetupCrossSigning(
              setupMasterKey: setupMasterKey,
              setupSelfSigningKey: setupSelfSigningKey,
              setupUserSigningKey: setupUserSigningKey,
            );
            break;
          case BootstrapState.askNewSsss:
            await bootstrap.newSsss(passphrase, keyName);
            break;
          case BootstrapState.openExistingSsss:
            throw Exception(
              'Bootstrap state ${bootstrap.state} should not happen!',
            );
          case BootstrapState.error:
            throw Exception('Bootstrap error!');
          case BootstrapState.done:
            completer.complete();
            break;
        }
      } catch (e, s) {
        if (completer.isCompleted) {
          return Logs().e('Bootstrap error after completed', e, s);
        }
        return completer.completeError(e, s);
      }
    },
  );

  await completer.future;
  return newSsssKey!;
}