feat: Add a way to string-encode a recovery key

This commit is contained in:
Sorunome 2021-02-03 11:34:56 +01:00
parent 650484c306
commit 0c4db25d05
No known key found for this signature in database
GPG Key ID: B19471D07FC9BE9C
2 changed files with 32 additions and 0 deletions

View File

@ -142,6 +142,24 @@ class SSSS {
OLM_RECOVERY_KEY_PREFIX.length + SSSS_KEY_LENGTH));
}
static String encodeRecoveryKey(Uint8List recoveryKey) {
final keyToEncode = <int>[];
for (final b in OLM_RECOVERY_KEY_PREFIX) {
keyToEncode.add(b);
}
keyToEncode.addAll(recoveryKey);
var parity = 0;
for (final b in keyToEncode) {
parity ^= b;
}
keyToEncode.add(parity);
// base58-encode and add a space every four chars
return base58
.encode(keyToEncode)
.replaceAllMapped(RegExp(r'.{4}'), (s) => '${s.group(0)} ')
.trim();
}
static Uint8List keyFromPassphrase(String passphrase, PassphraseInfo info) {
if (info.algorithm != AlgorithmTypes.pbkdf2) {
throw Exception('Unknown algorithm');
@ -596,6 +614,9 @@ class OpenSSSS {
bool get isUnlocked => privateKey != null;
String get recoveryKey =>
isUnlocked ? SSSS.encodeRecoveryKey(privateKey) : null;
Future<void> unlock(
{String passphrase, String recoveryKey, String keyOrPassphrase}) async {
if (keyOrPassphrase != null) {

View File

@ -112,6 +112,17 @@ void main() {
expect(await handle.getStored('best animal'), 'foxies');
});
test('encode / decode recovery key', () async {
final key = Uint8List.fromList(SecureRandom(32).bytes);
final encoded = SSSS.encodeRecoveryKey(key);
final decoded = SSSS.decodeRecoveryKey(encoded);
expect(key, decoded);
final handle = client.encryption.ssss.open();
await handle.unlock(recoveryKey: SSSS_KEY);
expect(handle.recoveryKey, SSSS_KEY);
});
test('cache', () async {
final handle =
client.encryption.ssss.open(EventTypes.CrossSigningSelfSigning);