migration for wallet passwords

This commit is contained in:
fosse 2023-12-15 14:01:37 -05:00
parent 2cf4d51ccb
commit 6e01814226
5 changed files with 59 additions and 17 deletions

View file

@ -511,7 +511,7 @@ class BackupService {
return {
'name': walletInfo.name,
'type': walletInfo.type.toString(),
'password': await _keyService.getWalletPassword(walletName: walletInfo.name)
'password': await _keyService.getWalletPasswordV2(walletName: walletInfo.name)
};
}));
final backupPasswordKey = generateStoreKeyFor(key: SecretStoreKey.backupPassword);

View file

@ -7,25 +7,41 @@ class KeyService {
final FlutterSecureStorage _secureStorage;
Future<String> getWalletPassword({required String walletName}) async {
final key = generateStoreKeyFor(
key: SecretStoreKey.moneroWalletPassword, walletName: walletName);
Future<String> getWalletPasswordV2({required String walletName}) async {
final key =
generateStoreKeyFor(key: SecretStoreKey.moneroWalletPassword, walletName: walletName);
final encodedPassword = await _secureStorage.read(key: key);
return decodeWalletPassword(password: encodedPassword!);
return decodeWalletPasswordV2(password: encodedPassword!);
}
Future<void> saveWalletPassword({required String walletName, required String password}) async {
final key = generateStoreKeyFor(
key: SecretStoreKey.moneroWalletPassword, walletName: walletName);
final encodedPassword = encodeWalletPassword(password: password);
Future<void> saveWalletPasswordV2({required String walletName, required String password}) async {
final key =
generateStoreKeyFor(key: SecretStoreKey.moneroWalletPassword, walletName: walletName);
final encodedPassword = await encodeWalletPasswordV2(password: password);
await _secureStorage.delete(key: key);
await _secureStorage.write(key: key, value: encodedPassword);
}
Future<String> getWalletPasswordV1({required String walletName}) async {
final key =
generateStoreKeyFor(key: SecretStoreKey.moneroWalletPassword, walletName: walletName);
final encodedPassword = await _secureStorage.read(key: key);
return decodeWalletPasswordV1(password: encodedPassword!);
}
Future<void> saveWalletPasswordV1({required String walletName, required String password}) async {
final key =
generateStoreKeyFor(key: SecretStoreKey.moneroWalletPassword, walletName: walletName);
final encodedPassword = encodeWalletPasswordV1(password: password);
await _secureStorage.delete(key: key);
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);
}

View file

@ -17,10 +17,10 @@ class WalletLoadingService {
Future<void> renameWallet(
WalletType type, String name, String newName) async {
final walletService = walletServiceFactory.call(type);
final password = await keyService.getWalletPassword(walletName: name);
final password = await keyService.getWalletPasswordV2(walletName: name);
// Save the current wallet's password to the new wallet name's key
await keyService.saveWalletPassword(
await keyService.saveWalletPasswordV2(
walletName: newName, password: password);
// Delete previous wallet name from keyService to keep only new wallet's name
// otherwise keeps duplicate (old and new names)

View file

@ -1,5 +1,6 @@
import 'dart:io' show Directory, File, Platform;
import 'package:cake_wallet/bitcoin/bitcoin.dart';
import 'package:cake_wallet/core/key_service.dart';
import 'package:cake_wallet/entities/encrypt.dart';
import 'package:cake_wallet/entities/exchange_api_mode.dart';
import 'package:cw_core/pathForWallet.dart';
@ -187,7 +188,8 @@ Future<void> defaultSettingsMigration(
await rewriteSecureStoragePin(secureStorage: secureStorage);
break;
case 26:
await pinEncryptionMigration(secureStorage: secureStorage);
await pinEncryptionMigration(
secureStorage: secureStorage, walletInfoSource: walletInfoSource);
break;
default:
break;
@ -382,7 +384,9 @@ Node getMoneroDefaultNode({required Box<Node> nodes}) {
}
}
Future<void> pinEncryptionMigration({required FlutterSecureStorage secureStorage}) async {
Future<void> pinEncryptionMigration(
{required FlutterSecureStorage secureStorage,
required Box<WalletInfo> walletInfoSource}) async {
try {
// first, get the encoded pin:
final keyForPinCode = generateStoreKeyFor(key: SecretStoreKey.pinCodePassword);
@ -407,6 +411,14 @@ Future<void> pinEncryptionMigration({required FlutterSecureStorage secureStorage
iOptions: IOSOptions(accessibility: KeychainAccessibility.first_unlock),
mOptions: MacOsOptions(accessibility: KeychainAccessibility.first_unlock),
);
KeyService keyService = KeyService(secureStorage);
// now do the same for all wallet passwords:
await Future.forEach(walletInfoSource.values, (WalletInfo walletInfo) async {
String walletPassword = await keyService.getWalletPasswordV1(walletName: walletInfo.name);
await keyService.saveWalletPasswordV2(walletName: walletInfo.name, password: walletPassword);
});
} catch (e) {
// failure isn't really an option since we'll be updating how pins are stored and used
print("pinEncryptionMigration: $e");

View file

@ -1,7 +1,11 @@
import 'dart:convert';
import 'dart:typed_data';
import 'package:encrypt/encrypt.dart';
// import 'package:password/password.dart';
import 'package:cake_wallet/.secrets.g.dart' as secrets;
import 'package:dargon2_flutter/dargon2_flutter.dart';
import 'package:cake_backup/backup.dart' as cake_backup;
Future<String> argon2Hash({required String password}) async {
final result = await argon2.hashPasswordString(password, salt: Salt.newSalt());
@ -13,6 +17,16 @@ Future<bool> verifyArgon2Hash({required String password, required String hash})
return argon2.verifyHashString(password, hash);
}
Future<String> encodeWalletPasswordV2({required String password}) async {
final _key = secrets.shortKey + secrets.walletSalt;
return utf8.decode(await cake_backup.encrypt(password, Uint8List.fromList(utf8.encode(_key))));
}
Future<String> decodeWalletPasswordV2({required String password}) async {
final _key = secrets.shortKey + secrets.walletSalt;
return utf8.decode(await cake_backup.decrypt(password, Uint8List.fromList(utf8.encode(_key))));
}
// @@@@@@@@@@@@@@@ OLD (kept for reference purposes, do not use!) @@@@@@@@@@@@@
String encrypt({required String source, required String key}) {
@ -50,13 +64,13 @@ String decodedPinCode({required String pin}) {
return decrypted.substring(secrets.key.length, decrypted.length);
}
String encodeWalletPassword({required String password}) {
String encodeWalletPasswordV1({required String password}) {
final source = password;
final _key = secrets.shortKey + secrets.walletSalt;
return encrypt(source: source, key: _key);
}
String decodeWalletPassword({required String password}) {
String decodeWalletPasswordV1({required String password}) {
final source = password;
final _key = secrets.shortKey + secrets.walletSalt;
return decrypt(source: source, key: _key);