CW-599-Extract-Secure-Storage (#1353)

* feat: Modify app to depend on secure storage abstraction instead of the direct package

* chore: Revert command

* Update configure.dart [skip ci]

* Update configure.dart

* Fix conflicts

* clean up and fixes

* minor fix

---------

Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>
This commit is contained in:
Adegoke David
2024-05-08 23:23:27 +03:00
committed by GitHub
co-authored by Omar Hatem
parent c35929f28e
commit bfb78eded9
23 changed files with 259 additions and 199 deletions
+4 -10
View File
@@ -1,5 +1,4 @@
import 'dart:async';
import 'dart:io';
import 'package:cake_wallet/core/secure_storage.dart';
import 'package:cake_wallet/core/totp_request_details.dart';
@@ -7,7 +6,6 @@ import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/auth/auth_page.dart';
import 'package:flutter/material.dart';
import 'package:mobx/mobx.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:cake_wallet/entities/preferences_key.dart';
import 'package:cake_wallet/entities/secret_store_key.dart';
@@ -35,14 +33,14 @@ class AuthService with Store {
Routes.restoreOptions,
];
final FlutterSecureStorage secureStorage;
final SecureStorage secureStorage;
final SharedPreferences sharedPreferences;
final SettingsStore settingsStore;
Future<void> setPassword(String password) async {
final key = generateStoreKeyFor(key: SecretStoreKey.pinCodePassword);
final encodedPassword = encodedPinCode(pin: password);
await writeSecureStorage(secureStorage, key: key, value: encodedPassword);
await secureStorage.write(key: key, value: encodedPassword);
}
Future<bool> canAuthenticate() async {
@@ -61,7 +59,7 @@ class AuthService with Store {
Future<bool> authenticate(String pin) async {
final key = generateStoreKeyFor(key: SecretStoreKey.pinCodePassword);
final encodedPin = await readSecureStorage(secureStorage, key);
final encodedPin = await secureStorage.read(key: key);
final decodedPin = decodedPinCode(pin: encodedPin!);
return decodedPin == pin;
@@ -69,11 +67,7 @@ class AuthService with Store {
void saveLastAuthTime() {
int timestamp = DateTime.now().millisecondsSinceEpoch;
writeSecureStorage(
secureStorage,
key: SecureKey.lastAuthTimeMilliseconds,
value: timestamp.toString(),
);
secureStorage.write(key: SecureKey.lastAuthTimeMilliseconds, value: timestamp.toString());
}
Future<bool> requireAuth() async {
+8 -11
View File
@@ -7,7 +7,6 @@ import 'package:cake_wallet/utils/device_info.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:flutter/foundation.dart';
import 'package:hive/hive.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:path_provider/path_provider.dart';
import 'package:cryptography/cryptography.dart';
import 'package:shared_preferences/shared_preferences.dart';
@@ -25,7 +24,7 @@ import 'package:cake_backup/backup.dart' as cake_backup;
class BackupService {
BackupService(
this._flutterSecureStorage, this._walletInfoSource, this._keyService, this._sharedPreferences)
this._secureStorage, this._walletInfoSource, this._keyService, this._sharedPreferences)
: _cipher = Cryptography.instance.chacha20Poly1305Aead(),
_correctWallets = <WalletInfo>[];
@@ -35,7 +34,7 @@ class BackupService {
static const _v2 = 2;
final Cipher _cipher;
final FlutterSecureStorage _flutterSecureStorage;
final SecureStorage _secureStorage;
final SharedPreferences _sharedPreferences;
final Box<WalletInfo> _walletInfoSource;
final KeyService _keyService;
@@ -374,15 +373,14 @@ class BackupService {
final backupPasswordKey = generateStoreKeyFor(key: SecretStoreKey.backupPassword);
final backupPassword = keychainJSON[backupPasswordKey] as String;
await writeSecureStorage(_flutterSecureStorage, key: backupPasswordKey, value: backupPassword);
await _secureStorage.write(key: backupPasswordKey, value: backupPassword);
keychainWalletsInfo.forEach((dynamic rawInfo) async {
final info = rawInfo as Map<String, dynamic>;
await importWalletKeychainInfo(info);
});
await writeSecureStorage(_flutterSecureStorage,
key: pinCodeKey, value: encodedPinCode(pin: decodedPin));
await _secureStorage.write(key: pinCodeKey, value: encodedPinCode(pin: decodedPin));
keychainDumpFile.deleteSync();
}
@@ -401,15 +399,14 @@ class BackupService {
final backupPasswordKey = generateStoreKeyFor(key: SecretStoreKey.backupPassword);
final backupPassword = keychainJSON[backupPasswordKey] as String;
await writeSecureStorage(_flutterSecureStorage, key: backupPasswordKey, value: backupPassword);
await _secureStorage.write(key: backupPasswordKey, value: backupPassword);
keychainWalletsInfo.forEach((dynamic rawInfo) async {
final info = rawInfo as Map<String, dynamic>;
await importWalletKeychainInfo(info);
});
await writeSecureStorage(_flutterSecureStorage,
key: pinCodeKey, value: encodedPinCode(pin: decodedPin));
await _secureStorage.write(key: pinCodeKey, value: encodedPinCode(pin: decodedPin));
keychainDumpFile.deleteSync();
}
@@ -429,7 +426,7 @@ class BackupService {
Future<Uint8List> _exportKeychainDumpV2(String password,
{String keychainSalt = secrets.backupKeychainSalt}) async {
final key = generateStoreKeyFor(key: SecretStoreKey.pinCodePassword);
final encodedPin = await _flutterSecureStorage.read(key: key);
final encodedPin = await _secureStorage.read(key: key);
final decodedPin = decodedPinCode(pin: encodedPin!);
final wallets = await Future.wait(_walletInfoSource.values.map((walletInfo) async {
return {
@@ -439,7 +436,7 @@ class BackupService {
};
}));
final backupPasswordKey = generateStoreKeyFor(key: SecretStoreKey.backupPassword);
final backupPassword = await _flutterSecureStorage.read(key: backupPasswordKey);
final backupPassword = await _secureStorage.read(key: backupPasswordKey);
final data = utf8.encode(
json.encode({'pin': decodedPin, 'wallets': wallets, backupPasswordKey: backupPassword}));
final encrypted = await _encryptV2(Uint8List.fromList(data), '$keychainSalt$password');
+9 -10
View File
@@ -1,31 +1,30 @@
import 'package:cake_wallet/core/secure_storage.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:cake_wallet/entities/secret_store_key.dart';
import 'package:cake_wallet/entities/encrypt.dart';
class KeyService {
KeyService(this._secureStorage);
final FlutterSecureStorage _secureStorage;
final SecureStorage _secureStorage;
Future<String> getWalletPassword({required String walletName}) async {
final key = generateStoreKeyFor(
key: SecretStoreKey.moneroWalletPassword, walletName: walletName);
final encodedPassword = await readSecureStorage(_secureStorage, key);
final key =
generateStoreKeyFor(key: SecretStoreKey.moneroWalletPassword, walletName: walletName);
final encodedPassword = await _secureStorage.read(key: key);
return decodeWalletPassword(password: encodedPassword!);
}
Future<void> saveWalletPassword({required String walletName, required String password}) async {
final key = generateStoreKeyFor(
key: SecretStoreKey.moneroWalletPassword, walletName: walletName);
final key =
generateStoreKeyFor(key: SecretStoreKey.moneroWalletPassword, walletName: walletName);
final encodedPassword = encodeWalletPassword(password: password);
await writeSecureStorage(_secureStorage, key: key, value: encodedPassword);
await _secureStorage.write(key: key, value: encodedPassword);
}
Future<void> deleteWalletPassword({required String walletName}) async {
final key = generateStoreKeyFor(
key: SecretStoreKey.moneroWalletPassword, walletName: walletName);
final key =
generateStoreKeyFor(key: SecretStoreKey.moneroWalletPassword, walletName: walletName);
await _secureStorage.delete(key: key);
}
-38
View File
@@ -1,38 +0,0 @@
import 'dart:async';
import 'dart:io';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
// For now, we can create a utility function to handle this.
//
// However, we could look into abstracting the entire FlutterSecureStorage package
// so the app doesn't depend on the package directly but an absraction.
// It'll make these kind of modifications to read/write come from a single point.
Future<String?> readSecureStorage(FlutterSecureStorage secureStorage, String key) async {
String? result;
const maxWait = Duration(seconds: 3);
const checkInterval = Duration(milliseconds: 200);
DateTime start = DateTime.now();
while (result == null && DateTime.now().difference(start) < maxWait) {
result = await secureStorage.read(key: key);
if (result != null) {
break;
}
await Future.delayed(checkInterval);
}
return result;
}
Future<void> writeSecureStorage(FlutterSecureStorage secureStorage,
{required String key, required String value}) async {
// delete the value before writing on macOS because of a weird bug
// https://github.com/mogol/flutter_secure_storage/issues/581
if (Platform.isMacOS) {
await secureStorage.delete(key: key);
}
await secureStorage.write(key: key, value: value);
}
+2 -2
View File
@@ -1,8 +1,8 @@
import 'package:cake_wallet/core/secure_storage.dart';
import 'package:cake_wallet/di.dart';
import 'package:cake_wallet/store/settings_store.dart';
import 'package:cw_core/wallet_info.dart';
import 'package:cake_wallet/entities/preferences_key.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:hive/hive.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:cake_wallet/core/key_service.dart';
@@ -25,7 +25,7 @@ class WalletCreationService {
}
WalletType type;
final FlutterSecureStorage secureStorage;
final SecureStorage secureStorage;
final SharedPreferences sharedPreferences;
final SettingsStore settingsStore;
final KeyService keyService;