createKey method

Future<OpenSSSS> createKey([
  1. String? passphrase
])

Creates a new secret storage key, optional encrypts it with passphrase and stores it in the user's accountData.

Implementation

Future<OpenSSSS> createKey([String? passphrase]) async {
  Uint8List privateKey;
  final content = SecretStorageKeyContent();
  if (passphrase != null) {
    // we need to derive the key off of the passphrase
    content.passphrase = PassphraseInfo(
      iterations: pbkdf2DefaultIterations,
      salt: base64.encode(uc.secureRandomBytes(pbkdf2SaltLength)),
      algorithm: AlgorithmTypes.pbkdf2,
      bits: ssssKeyLength * 8,
    );
    privateKey = await Future.value(
      client.nativeImplementations.keyFromPassphrase(
        KeyFromPassphraseArgs(
          passphrase: passphrase,
          info: content.passphrase!,
        ),
      ),
    ).timeout(Duration(seconds: 10));
  } else {
    // we need to just generate a new key from scratch
    privateKey = Uint8List.fromList(uc.secureRandomBytes(ssssKeyLength));
  }
  // now that we have the private key, let's create the iv and mac
  final encrypted = await encryptAes(zeroStr, privateKey, '');
  content.iv = encrypted.iv;
  content.mac = encrypted.mac;
  content.algorithm = AlgorithmTypes.secretStorageV1AesHmcSha2;

  const keyidByteLength = 24;

  // make sure we generate a unique key id
  final keyId = () sync* {
    for (;;) {
      yield base64.encode(uc.secureRandomBytes(keyidByteLength));
    }
  }()
      .firstWhere((keyId) => getKey(keyId) == null);

  final accountDataTypeKeyId = EventTypes.secretStorageKey(keyId);
  // noooow we set the account data

  await client.setAccountData(
    client.userID!,
    accountDataTypeKeyId,
    content.toJson(),
  );

  while (!client.accountData.containsKey(accountDataTypeKeyId)) {
    Logs().v('Waiting accountData to have $accountDataTypeKeyId');
    await client.oneShotSync();
  }

  final key = open(keyId);
  await key.setPrivateKey(privateKey);
  return key;
}