getAll method
Returns every xpub and hdpubkey secret, decrypted.
All or nothing: if any row cannot be decrypted (no key for its version, wrong key, tampered data) this throws a SecureStorageException naming every such row, rather than returning a partial map that looks complete.
Implementation
@override
Future<Map<String, String>> getAll() async {
final Result result;
try {
result = await _pool.execute(
Sql.named('''
SELECT key_name, encrypted_value, nonce, key_version
FROM secure_secrets
WHERE key_name LIKE @xpub_pattern
OR key_name LIKE @hdpubkey_pattern
'''),
parameters: {
'xpub_pattern': '$_xpubKeyPrefix%',
'hdpubkey_pattern': '$_hdPubKeyPrefix%',
},
);
} catch (e) {
throw SecureStorageException('Failed to retrieve all secrets: $e', e);
}
final secrets = <String, String>{};
final failures = <SecureStorageException>[];
for (final row in result) {
try {
final keyName = row[0] as String;
secrets[keyName] = await _decryptRow(
keyName,
row[1] as Uint8List,
row[2] as Uint8List,
row[3] as int,
);
} on SecureStorageException catch (e) {
failures.add(e);
}
}
if (failures.isNotEmpty) {
throw SecureStorageException(
'Failed to decrypt ${failures.length} of ${result.length} secrets: '
'${failures.map((e) => e.message).join('; ')}',
failures,
);
}
return secrets;
}