mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2025-01-03 17:29:23 +00:00
self contained desktop password service refactor that does not keep its db open when not in use
This commit is contained in:
parent
9513b203a9
commit
6fb526efe5
1 changed files with 63 additions and 77 deletions
|
@ -10,9 +10,9 @@
|
||||||
|
|
||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
import 'package:stack_wallet_backup/secure_storage.dart';
|
import 'package:stack_wallet_backup/secure_storage.dart';
|
||||||
import 'package:stackwallet/db/hive/db.dart';
|
|
||||||
import 'package:stackwallet/utilities/logger.dart';
|
import 'package:stackwallet/utilities/logger.dart';
|
||||||
|
|
||||||
|
const String kBoxNameDesktopData = "desktopData";
|
||||||
const String _kKeyBlobKey = "swbKeyBlobKeyStringID";
|
const String _kKeyBlobKey = "swbKeyBlobKeyStringID";
|
||||||
const String _kKeyBlobVersionKey = "swbKeyBlobVersionKeyStringID";
|
const String _kKeyBlobVersionKey = "swbKeyBlobVersionKeyStringID";
|
||||||
|
|
||||||
|
@ -62,14 +62,8 @@ class DPS {
|
||||||
kLatestBlobVersion,
|
kLatestBlobVersion,
|
||||||
);
|
);
|
||||||
|
|
||||||
final box = await Hive.openBox<String>(DB.boxNameDesktopData);
|
await _put(key: _kKeyBlobKey, value: await _handler!.getKeyBlob());
|
||||||
await DB.instance.put<String>(
|
|
||||||
boxName: DB.boxNameDesktopData,
|
|
||||||
key: _kKeyBlobKey,
|
|
||||||
value: await _handler!.getKeyBlob(),
|
|
||||||
);
|
|
||||||
await _updateStoredKeyBlobVersion(kLatestBlobVersion);
|
await _updateStoredKeyBlobVersion(kLatestBlobVersion);
|
||||||
await box.close();
|
|
||||||
} catch (e, s) {
|
} catch (e, s) {
|
||||||
Logging.instance.log(
|
Logging.instance.log(
|
||||||
"${_getMessageFromException(e)}\n$s",
|
"${_getMessageFromException(e)}\n$s",
|
||||||
|
@ -85,19 +79,13 @@ class DPS {
|
||||||
"DPS: attempted to re initialize with existing passphrase");
|
"DPS: attempted to re initialize with existing passphrase");
|
||||||
}
|
}
|
||||||
|
|
||||||
final box = await Hive.openBox<String>(DB.boxNameDesktopData);
|
|
||||||
final keyBlob = DB.instance.get<String>(
|
|
||||||
boxName: DB.boxNameDesktopData,
|
|
||||||
key: _kKeyBlobKey,
|
|
||||||
);
|
|
||||||
await box.close();
|
|
||||||
|
|
||||||
if (keyBlob == null) {
|
|
||||||
throw Exception(
|
|
||||||
"DPS: failed to find keyBlob while attempting to initialize with existing passphrase");
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
final keyBlob = await _get(key: _kKeyBlobKey);
|
||||||
|
|
||||||
|
if (keyBlob == null) {
|
||||||
|
throw Exception(
|
||||||
|
"DPS: failed to find keyBlob while attempting to initialize with existing passphrase");
|
||||||
|
}
|
||||||
final blobVersion = await _getStoredKeyBlobVersion();
|
final blobVersion = await _getStoredKeyBlobVersion();
|
||||||
_handler = await StorageCryptoHandler.fromExisting(
|
_handler = await StorageCryptoHandler.fromExisting(
|
||||||
passphrase,
|
passphrase,
|
||||||
|
@ -107,14 +95,8 @@ class DPS {
|
||||||
if (blobVersion < kLatestBlobVersion) {
|
if (blobVersion < kLatestBlobVersion) {
|
||||||
// update blob
|
// update blob
|
||||||
await _handler!.resetPassphrase(passphrase, kLatestBlobVersion);
|
await _handler!.resetPassphrase(passphrase, kLatestBlobVersion);
|
||||||
final box = await Hive.openBox<String>(DB.boxNameDesktopData);
|
await _put(key: _kKeyBlobKey, value: await _handler!.getKeyBlob());
|
||||||
await DB.instance.put<String>(
|
|
||||||
boxName: DB.boxNameDesktopData,
|
|
||||||
key: _kKeyBlobKey,
|
|
||||||
value: await _handler!.getKeyBlob(),
|
|
||||||
);
|
|
||||||
await _updateStoredKeyBlobVersion(kLatestBlobVersion);
|
await _updateStoredKeyBlobVersion(kLatestBlobVersion);
|
||||||
await box.close();
|
|
||||||
}
|
}
|
||||||
} catch (e, s) {
|
} catch (e, s) {
|
||||||
Logging.instance.log(
|
Logging.instance.log(
|
||||||
|
@ -126,19 +108,13 @@ class DPS {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> verifyPassphrase(String passphrase) async {
|
Future<bool> verifyPassphrase(String passphrase) async {
|
||||||
final box = await Hive.openBox<String>(DB.boxNameDesktopData);
|
|
||||||
final keyBlob = DB.instance.get<String>(
|
|
||||||
boxName: DB.boxNameDesktopData,
|
|
||||||
key: _kKeyBlobKey,
|
|
||||||
);
|
|
||||||
await box.close();
|
|
||||||
|
|
||||||
if (keyBlob == null) {
|
|
||||||
// no passphrase key blob found so any passphrase is technically bad
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
final keyBlob = await _get(key: _kKeyBlobKey);
|
||||||
|
|
||||||
|
if (keyBlob == null) {
|
||||||
|
// no passphrase key blob found so any passphrase is technically bad
|
||||||
|
return false;
|
||||||
|
}
|
||||||
final blobVersion = await _getStoredKeyBlobVersion();
|
final blobVersion = await _getStoredKeyBlobVersion();
|
||||||
await StorageCryptoHandler.fromExisting(passphrase, keyBlob, blobVersion);
|
await StorageCryptoHandler.fromExisting(passphrase, keyBlob, blobVersion);
|
||||||
// existing passphrase matches key blob
|
// existing passphrase matches key blob
|
||||||
|
@ -157,35 +133,25 @@ class DPS {
|
||||||
String passphraseOld,
|
String passphraseOld,
|
||||||
String passphraseNew,
|
String passphraseNew,
|
||||||
) async {
|
) async {
|
||||||
final box = await Hive.openBox<String>(DB.boxNameDesktopData);
|
|
||||||
final keyBlob = DB.instance.get<String>(
|
|
||||||
boxName: DB.boxNameDesktopData,
|
|
||||||
key: _kKeyBlobKey,
|
|
||||||
);
|
|
||||||
await box.close();
|
|
||||||
|
|
||||||
if (keyBlob == null) {
|
|
||||||
// no passphrase key blob found so any passphrase is technically bad
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(await verifyPassphrase(passphraseOld))) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
final blobVersion = await _getStoredKeyBlobVersion();
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await _handler!.resetPassphrase(passphraseNew, blobVersion);
|
final keyBlob = await _get(key: _kKeyBlobKey);
|
||||||
|
|
||||||
final box = await Hive.openBox<String>(DB.boxNameDesktopData);
|
if (keyBlob == null) {
|
||||||
await DB.instance.put<String>(
|
// no passphrase key blob found so any passphrase is technically bad
|
||||||
boxName: DB.boxNameDesktopData,
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(await verifyPassphrase(passphraseOld))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
final blobVersion = await _getStoredKeyBlobVersion();
|
||||||
|
await _handler!.resetPassphrase(passphraseNew, blobVersion);
|
||||||
|
await _put(
|
||||||
key: _kKeyBlobKey,
|
key: _kKeyBlobKey,
|
||||||
value: await _handler!.getKeyBlob(),
|
value: await _handler!.getKeyBlob(),
|
||||||
);
|
);
|
||||||
await _updateStoredKeyBlobVersion(blobVersion);
|
await _updateStoredKeyBlobVersion(blobVersion);
|
||||||
await box.close();
|
|
||||||
|
|
||||||
// successfully updated passphrase
|
// successfully updated passphrase
|
||||||
return true;
|
return true;
|
||||||
|
@ -199,28 +165,48 @@ class DPS {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> hasPassword() async {
|
Future<bool> hasPassword() async {
|
||||||
final keyBlob = DB.instance.get<String>(
|
final keyBlob = await _get(key: _kKeyBlobKey);
|
||||||
boxName: DB.boxNameDesktopData,
|
|
||||||
key: _kKeyBlobKey,
|
|
||||||
);
|
|
||||||
return keyBlob != null;
|
return keyBlob != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<int> _getStoredKeyBlobVersion() async {
|
Future<int> _getStoredKeyBlobVersion() async {
|
||||||
final box = await Hive.openBox<String>(DB.boxNameDesktopData);
|
final keyBlobVersionString = await _get(key: _kKeyBlobVersionKey);
|
||||||
final keyBlobVersionString = DB.instance.get<String>(
|
|
||||||
boxName: DB.boxNameDesktopData,
|
|
||||||
key: _kKeyBlobVersionKey,
|
|
||||||
);
|
|
||||||
await box.close();
|
|
||||||
return int.tryParse(keyBlobVersionString ?? "1") ?? 1;
|
return int.tryParse(keyBlobVersionString ?? "1") ?? 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _updateStoredKeyBlobVersion(int version) async {
|
Future<void> _updateStoredKeyBlobVersion(int version) async {
|
||||||
await DB.instance.put<String>(
|
await _put(key: _kKeyBlobVersionKey, value: version.toString());
|
||||||
boxName: DB.boxNameDesktopData,
|
}
|
||||||
key: _kKeyBlobVersionKey,
|
|
||||||
value: version.toString(),
|
Future<void> _put({required String key, required String value}) async {
|
||||||
);
|
Box<String>? box;
|
||||||
|
try {
|
||||||
|
box = await Hive.openBox<String>(kBoxNameDesktopData);
|
||||||
|
await box.put(key, value);
|
||||||
|
} catch (e, s) {
|
||||||
|
Logging.instance.log(
|
||||||
|
"DPS failed put($key): $e\n$s",
|
||||||
|
level: LogLevel.Fatal,
|
||||||
|
);
|
||||||
|
} finally {
|
||||||
|
await box?.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<String?> _get({required String key}) async {
|
||||||
|
String? value;
|
||||||
|
Box<String>? box;
|
||||||
|
try {
|
||||||
|
box = await Hive.openBox<String>(kBoxNameDesktopData);
|
||||||
|
value = box.get(key);
|
||||||
|
} catch (e, s) {
|
||||||
|
Logging.instance.log(
|
||||||
|
"DPS failed get($key): $e\n$s",
|
||||||
|
level: LogLevel.Fatal,
|
||||||
|
);
|
||||||
|
} finally {
|
||||||
|
await box?.close();
|
||||||
|
}
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue