ios/mac secure storage pin migration (potential fix) (#1205)
* ios/mac secure storage pin migration * function call was incorrect * Update default_settings_migration.dart --------- Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>
Matthew Fosse committed
Nov 30, 2023 at 16:39 UTC
3760285a64405935fafe7aeeb051fd25d850585b
2 files changed
+64
-36
lib/entities/default_settings_migration.dart
+63
-35
@@ -1,5 +1,6 @@
1
import 'dart:io' show Directory, File, Platform;
2
import 'package:cake_wallet/bitcoin/bitcoin.dart';
3
+import 'package:cake_wallet/entities/encrypt.dart';
4
import 'package:cake_wallet/entities/exchange_api_mode.dart';
5
import 'package:cw_core/pathForWallet.dart';
6
import 'package:cake_wallet/entities/secret_store_key.dart';
@@ -82,8 +83,7 @@ Future<void> defaultSettingsMigration(
83
sharedPreferences: sharedPreferences, nodes: nodes);
84
await changeLitecoinCurrentElectrumServerToDefault(
85
sharedPreferences: sharedPreferences, nodes: nodes);
85
- await changeHavenCurrentNodeToDefault(
86
- sharedPreferences: sharedPreferences, nodes: nodes);
86
+ await changeHavenCurrentNodeToDefault(sharedPreferences: sharedPreferences, nodes: nodes);
87
await changeBitcoinCashCurrentNodeToDefault(
88
sharedPreferences: sharedPreferences, nodes: nodes);
89
@@ -175,6 +175,9 @@ Future<void> defaultSettingsMigration(
175
await changeBitcoinCurrentElectrumServerToDefault(
176
sharedPreferences: sharedPreferences, nodes: nodes);
177
break;
178
+ case 25:
179
+ await rewriteSecureStoragePin(secureStorage: secureStorage);
180
+ break;
181
182
default:
183
break;
@@ -340,9 +343,9 @@ Node? getNanoDefaultPowNode({required Box<Node> nodes}) {
343
}
344
345
Node? getBitcoinCashDefaultElectrumServer({required Box<Node> nodes}) {
343
- return nodes.values.firstWhereOrNull(
344
- (Node node) => node.uriRaw == cakeWalletBitcoinCashDefaultNodeUri)
345
- ?? nodes.values.firstWhereOrNull((node) => node.type == WalletType.bitcoinCash);
346
+ return nodes.values
347
+ .firstWhereOrNull((Node node) => node.uriRaw == cakeWalletBitcoinCashDefaultNodeUri) ??
348
+ nodes.values.firstWhereOrNull((node) => node.type == WalletType.bitcoinCash);
349
}
350
351
Node getMoneroDefaultNode({required Box<Node> nodes}) {
@@ -364,6 +367,37 @@ Node getMoneroDefaultNode({required Box<Node> nodes}) {
367
}
368
}
369
370
+Future<void> rewriteSecureStoragePin({required FlutterSecureStorage secureStorage}) async {
371
+ // the bug only affects ios/mac:
372
+ if (!Platform.isIOS && !Platform.isMacOS) {
373
+ return;
374
+ }
375
+
376
+ // first, get the encoded pin:
377
+ final keyForPinCode = generateStoreKeyFor(key: SecretStoreKey.pinCodePassword);
378
+ String? encodedPin;
379
+ try {
380
+ encodedPin = await secureStorage.read(key: keyForPinCode);
381
+ } catch (e) {
382
+ // either we don't have a pin, or we can't read it (maybe even because of the bug!)
383
+ // the only option here is to abort the migration or we risk losing the pin and locking the user out
384
+ return;
385
+ }
386
+
387
+ if (encodedPin == null) {
388
+ return;
389
+ }
390
+
391
+ // ensure we overwrite by deleting the old key first:
392
+ await secureStorage.delete(key: keyForPinCode);
393
+ await secureStorage.write(
394
+ key: keyForPinCode,
395
+ value: encodedPin,
396
+ iOptions: IOSOptions(accessibility: KeychainAccessibility.first_unlock),
397
+ mOptions: MacOsOptions(accessibility: KeychainAccessibility.first_unlock),
398
+ );
399
+}
400
+
401
Future<void> changeBitcoinCurrentElectrumServerToDefault(
402
{required SharedPreferences sharedPreferences, required Box<Node> nodes}) async {
403
final server = getBitcoinDefaultElectrumServer(nodes: nodes);
@@ -381,8 +415,7 @@ Future<void> changeLitecoinCurrentElectrumServerToDefault(
415
}
416
417
Future<void> changeBitcoinCashCurrentNodeToDefault(
384
- {required SharedPreferences sharedPreferences,
385
- required Box<Node> nodes}) async {
418
+ {required SharedPreferences sharedPreferences, required Box<Node> nodes}) async {
419
final server = getBitcoinCashDefaultElectrumServer(nodes: nodes);
420
final serverId = server?.key as int ?? 0;
421
@@ -538,34 +571,30 @@ Future<void> checkCurrentNodes(
571
final currentMoneroNodeId = sharedPreferences.getInt(PreferencesKey.currentNodeIdKey);
572
final currentBitcoinElectrumSeverId =
573
sharedPreferences.getInt(PreferencesKey.currentBitcoinElectrumSererIdKey);
541
- final currentLitecoinElectrumSeverId = sharedPreferences
542
- .getInt(PreferencesKey.currentLitecoinElectrumSererIdKey);
543
- final currentHavenNodeId = sharedPreferences
544
- .getInt(PreferencesKey.currentHavenNodeIdKey);
545
- final currentEthereumNodeId = sharedPreferences
546
- .getInt(PreferencesKey.currentEthereumNodeIdKey);
547
- final currentNanoNodeId = sharedPreferences
548
- .getInt(PreferencesKey.currentNanoNodeIdKey);
549
- final currentNanoPowNodeId = sharedPreferences
550
- .getInt(PreferencesKey.currentNanoPowNodeIdKey);
551
- final currentBitcoinCashNodeId = sharedPreferences
552
- .getInt(PreferencesKey.currentBitcoinCashNodeIdKey);
553
- final currentMoneroNode = nodeSource.values.firstWhereOrNull(
554
- (node) => node.key == currentMoneroNodeId);
555
- final currentBitcoinElectrumServer = nodeSource.values.firstWhereOrNull(
556
- (node) => node.key == currentBitcoinElectrumSeverId);
557
- final currentLitecoinElectrumServer = nodeSource.values.firstWhereOrNull(
558
- (node) => node.key == currentLitecoinElectrumSeverId);
559
- final currentHavenNodeServer = nodeSource.values.firstWhereOrNull(
560
- (node) => node.key == currentHavenNodeId);
561
- final currentEthereumNodeServer = nodeSource.values.firstWhereOrNull(
562
- (node) => node.key == currentEthereumNodeId);
574
+ final currentLitecoinElectrumSeverId =
575
+ sharedPreferences.getInt(PreferencesKey.currentLitecoinElectrumSererIdKey);
576
+ final currentHavenNodeId = sharedPreferences.getInt(PreferencesKey.currentHavenNodeIdKey);
577
+ final currentEthereumNodeId = sharedPreferences.getInt(PreferencesKey.currentEthereumNodeIdKey);
578
+ final currentNanoNodeId = sharedPreferences.getInt(PreferencesKey.currentNanoNodeIdKey);
579
+ final currentNanoPowNodeId = sharedPreferences.getInt(PreferencesKey.currentNanoPowNodeIdKey);
580
+ final currentBitcoinCashNodeId =
581
+ sharedPreferences.getInt(PreferencesKey.currentBitcoinCashNodeIdKey);
582
+ final currentMoneroNode =
583
+ nodeSource.values.firstWhereOrNull((node) => node.key == currentMoneroNodeId);
584
+ final currentBitcoinElectrumServer =
585
+ nodeSource.values.firstWhereOrNull((node) => node.key == currentBitcoinElectrumSeverId);
586
+ final currentLitecoinElectrumServer =
587
+ nodeSource.values.firstWhereOrNull((node) => node.key == currentLitecoinElectrumSeverId);
588
+ final currentHavenNodeServer =
589
+ nodeSource.values.firstWhereOrNull((node) => node.key == currentHavenNodeId);
590
+ final currentEthereumNodeServer =
591
+ nodeSource.values.firstWhereOrNull((node) => node.key == currentEthereumNodeId);
592
final currentNanoNodeServer =
564
- nodeSource.values.firstWhereOrNull((node) => node.key == currentNanoNodeId);
593
+ nodeSource.values.firstWhereOrNull((node) => node.key == currentNanoNodeId);
594
final currentNanoPowNodeServer =
566
- powNodeSource.values.firstWhereOrNull((node) => node.key == currentNanoPowNodeId);
567
- final currentBitcoinCashNodeServer = nodeSource.values.firstWhereOrNull(
568
- (node) => node.key == currentBitcoinCashNodeId);
595
+ powNodeSource.values.firstWhereOrNull((node) => node.key == currentNanoPowNodeId);
596
+ final currentBitcoinCashNodeServer =
597
+ nodeSource.values.firstWhereOrNull((node) => node.key == currentBitcoinCashNodeId);
598
if (currentMoneroNode == null) {
599
final newCakeWalletNode = Node(uri: newCakeWalletMoneroUri, type: WalletType.monero);
600
await nodeSource.add(newCakeWalletNode);
@@ -617,8 +646,7 @@ Future<void> checkCurrentNodes(
646
if (currentBitcoinCashNodeServer == null) {
647
final node = Node(uri: cakeWalletBitcoinCashDefaultNodeUri, type: WalletType.bitcoinCash);
648
await nodeSource.add(node);
620
- await sharedPreferences.setInt(
621
- PreferencesKey.currentBitcoinCashNodeIdKey, node.key as int);
649
+ await sharedPreferences.setInt(PreferencesKey.currentBitcoinCashNodeIdKey, node.key as int);
650
}
651
}
652
lib/main.dart
+1
-1
@@ -163,7 +163,7 @@ Future<void> initializeAppConfigs() async {
163
transactionDescriptions: transactionDescriptions,
164
secureStorage: secureStorage,
165
anonpayInvoiceInfo: anonpayInvoiceInfo,
166
- initialMigrationVersion: 23);
166
+ initialMigrationVersion: 25);
167
}
168
169
Future<void> initialSetup(