mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2024-12-23 03:59:23 +00:00
Vulnerable btc seeds (#1238)
* Add flow to notify users with vulnerable seeds * - Show vulnerable wallets warning on every app launch - Change text * increment build number * add seeds sha text [skip ci]
This commit is contained in:
parent
ec140b813c
commit
01e2a84809
8 changed files with 8903 additions and 10 deletions
8717
assets/text/cakewallet_weak_bitcoin_seeds_hashed_sorted_version1.txt
Normal file
8717
assets/text/cakewallet_weak_bitcoin_seeds_hashed_sorted_version1.txt
Normal file
File diff suppressed because it is too large
Load diff
|
@ -374,7 +374,8 @@ Future<void> setup({
|
||||||
settingsStore: settingsStore,
|
settingsStore: settingsStore,
|
||||||
yatStore: getIt.get<YatStore>(),
|
yatStore: getIt.get<YatStore>(),
|
||||||
ordersStore: getIt.get<OrdersStore>(),
|
ordersStore: getIt.get<OrdersStore>(),
|
||||||
anonpayTransactionsStore: getIt.get<AnonpayTransactionsStore>()));
|
anonpayTransactionsStore: getIt.get<AnonpayTransactionsStore>(),
|
||||||
|
keyService: getIt.get<KeyService>()));
|
||||||
|
|
||||||
getIt.registerFactory<AuthService>(
|
getIt.registerFactory<AuthService>(
|
||||||
() => AuthService(
|
() => AuthService(
|
||||||
|
@ -792,8 +793,8 @@ Future<void> setup({
|
||||||
getIt.registerFactory<RobinhoodBuyProvider>(
|
getIt.registerFactory<RobinhoodBuyProvider>(
|
||||||
() => RobinhoodBuyProvider(wallet: getIt.get<AppStore>().wallet!));
|
() => RobinhoodBuyProvider(wallet: getIt.get<AppStore>().wallet!));
|
||||||
|
|
||||||
getIt.registerFactory<DFXBuyProvider>(
|
getIt
|
||||||
() => DFXBuyProvider(wallet: getIt.get<AppStore>().wallet!));
|
.registerFactory<DFXBuyProvider>(() => DFXBuyProvider(wallet: getIt.get<AppStore>().wallet!));
|
||||||
|
|
||||||
getIt.registerFactory<OnRamperBuyProvider>(() => OnRamperBuyProvider(
|
getIt.registerFactory<OnRamperBuyProvider>(() => OnRamperBuyProvider(
|
||||||
settingsStore: getIt.get<AppStore>().settingsStore,
|
settingsStore: getIt.get<AppStore>().settingsStore,
|
||||||
|
|
|
@ -7,6 +7,7 @@ import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_sideba
|
||||||
import 'package:cake_wallet/src/screens/dashboard/pages/market_place_page.dart';
|
import 'package:cake_wallet/src/screens/dashboard/pages/market_place_page.dart';
|
||||||
import 'package:cake_wallet/src/screens/wallet_connect/widgets/modals/bottom_sheet_listener.dart';
|
import 'package:cake_wallet/src/screens/wallet_connect/widgets/modals/bottom_sheet_listener.dart';
|
||||||
import 'package:cake_wallet/src/widgets/gradient_background.dart';
|
import 'package:cake_wallet/src/widgets/gradient_background.dart';
|
||||||
|
import 'package:cake_wallet/src/widgets/vulnerable_seeds_popup.dart';
|
||||||
import 'package:cake_wallet/themes/extensions/sync_indicator_theme.dart';
|
import 'package:cake_wallet/themes/extensions/sync_indicator_theme.dart';
|
||||||
import 'package:cake_wallet/utils/device_info.dart';
|
import 'package:cake_wallet/utils/device_info.dart';
|
||||||
import 'package:cake_wallet/utils/version_comparator.dart';
|
import 'package:cake_wallet/utils/version_comparator.dart';
|
||||||
|
@ -60,7 +61,8 @@ class DashboardPage extends StatelessWidget {
|
||||||
);
|
);
|
||||||
|
|
||||||
if (DeviceInfo.instance.isDesktop) {
|
if (DeviceInfo.instance.isDesktop) {
|
||||||
if (responsiveLayoutUtil.screenWidth > ResponsiveLayoutUtilBase.kDesktopMaxDashBoardWidthConstraint) {
|
if (responsiveLayoutUtil.screenWidth >
|
||||||
|
ResponsiveLayoutUtilBase.kDesktopMaxDashBoardWidthConstraint) {
|
||||||
return getIt.get<DesktopSidebarWrapper>();
|
return getIt.get<DesktopSidebarWrapper>();
|
||||||
} else {
|
} else {
|
||||||
return dashboardPageView;
|
return dashboardPageView;
|
||||||
|
@ -295,6 +297,8 @@ class _DashboardPageView extends BasePage {
|
||||||
|
|
||||||
_showReleaseNotesPopup(context);
|
_showReleaseNotesPopup(context);
|
||||||
|
|
||||||
|
_showVulnerableSeedsPopup(context);
|
||||||
|
|
||||||
var needToPresentYat = false;
|
var needToPresentYat = false;
|
||||||
var isInactive = false;
|
var isInactive = false;
|
||||||
|
|
||||||
|
@ -354,4 +358,22 @@ class _DashboardPageView extends BasePage {
|
||||||
sharedPrefs.setInt(PreferencesKey.lastSeenAppVersion, currentAppVersion);
|
sharedPrefs.setInt(PreferencesKey.lastSeenAppVersion, currentAppVersion);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _showVulnerableSeedsPopup(BuildContext context) async {
|
||||||
|
final List<String> affectedWalletNames = await dashboardViewModel.checkAffectedWallets();
|
||||||
|
|
||||||
|
if (affectedWalletNames.isNotEmpty) {
|
||||||
|
Future<void>.delayed(
|
||||||
|
Duration(seconds: 1),
|
||||||
|
() {
|
||||||
|
showPopUp<void>(
|
||||||
|
context: context,
|
||||||
|
builder: (BuildContext context) {
|
||||||
|
return VulnerableSeedsPopup(affectedWalletNames);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ import 'package:cake_wallet/entities/preferences_key.dart';
|
||||||
import 'package:cake_wallet/routes.dart';
|
import 'package:cake_wallet/routes.dart';
|
||||||
import 'package:cake_wallet/src/screens/release_notes/release_notes_screen.dart';
|
import 'package:cake_wallet/src/screens/release_notes/release_notes_screen.dart';
|
||||||
import 'package:cake_wallet/src/screens/yat_emoji_id.dart';
|
import 'package:cake_wallet/src/screens/yat_emoji_id.dart';
|
||||||
|
import 'package:cake_wallet/src/widgets/vulnerable_seeds_popup.dart';
|
||||||
import 'package:cake_wallet/utils/show_pop_up.dart';
|
import 'package:cake_wallet/utils/show_pop_up.dart';
|
||||||
import 'package:cake_wallet/utils/version_comparator.dart';
|
import 'package:cake_wallet/utils/version_comparator.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
@ -110,5 +111,25 @@ class DesktopDashboardPage extends StatelessWidget {
|
||||||
} else if (isNewInstall!) {
|
} else if (isNewInstall!) {
|
||||||
sharedPrefs.setInt(PreferencesKey.lastSeenAppVersion, currentAppVersion);
|
sharedPrefs.setInt(PreferencesKey.lastSeenAppVersion, currentAppVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_showVulnerableSeedsPopup(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _showVulnerableSeedsPopup(BuildContext context) async {
|
||||||
|
final List<String> affectedWalletNames = await dashboardViewModel.checkAffectedWallets();
|
||||||
|
|
||||||
|
if (affectedWalletNames.isNotEmpty) {
|
||||||
|
Future<void>.delayed(
|
||||||
|
Duration(seconds: 1),
|
||||||
|
() {
|
||||||
|
showPopUp<void>(
|
||||||
|
context: context,
|
||||||
|
builder: (BuildContext context) {
|
||||||
|
return VulnerableSeedsPopup(affectedWalletNames);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
91
lib/src/widgets/vulnerable_seeds_popup.dart
Normal file
91
lib/src/widgets/vulnerable_seeds_popup.dart
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
import 'package:cake_wallet/src/widgets/alert_background.dart';
|
||||||
|
import 'package:cake_wallet/src/widgets/alert_close_button.dart';
|
||||||
|
import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class VulnerableSeedsPopup extends StatelessWidget {
|
||||||
|
final List<String> affectedWalletNames;
|
||||||
|
|
||||||
|
const VulnerableSeedsPopup(this.affectedWalletNames, {Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Stack(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
children: [
|
||||||
|
AlertBackground(
|
||||||
|
child: AlertDialog(
|
||||||
|
insetPadding: EdgeInsets.only(left: 16, right: 16, bottom: 48),
|
||||||
|
elevation: 0.0,
|
||||||
|
contentPadding: EdgeInsets.zero,
|
||||||
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(30))),
|
||||||
|
content: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(30.0),
|
||||||
|
gradient: LinearGradient(colors: [
|
||||||
|
Theme.of(context).extension<DashboardPageTheme>()!.firstGradientBackgroundColor,
|
||||||
|
Theme.of(context)
|
||||||
|
.extension<DashboardPageTheme>()!
|
||||||
|
.secondGradientBackgroundColor,
|
||||||
|
], begin: Alignment.centerLeft, end: Alignment.centerRight)),
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 24.0),
|
||||||
|
child: Stack(
|
||||||
|
children: [
|
||||||
|
SingleChildScrollView(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.only(top: 16.0),
|
||||||
|
child: Container(
|
||||||
|
alignment: Alignment.bottomCenter,
|
||||||
|
child: DefaultTextStyle(
|
||||||
|
style: TextStyle(
|
||||||
|
decoration: TextDecoration.none,
|
||||||
|
fontSize: 24.0,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
fontFamily: 'Lato',
|
||||||
|
color: Theme.of(context).extension<DashboardPageTheme>()!.textColor,
|
||||||
|
),
|
||||||
|
child: Text("Emergency Notice"),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SingleChildScrollView(
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.only(top: 48, bottom: 16),
|
||||||
|
child: Container(
|
||||||
|
width: double.maxFinite,
|
||||||
|
child: Column(
|
||||||
|
children: <Widget>[
|
||||||
|
ConstrainedBox(
|
||||||
|
constraints: BoxConstraints(
|
||||||
|
maxHeight: MediaQuery.of(context).size.height * 0.7,
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
"Your Bitcoin wallet(s) below use a legacy seed format that is vulnerable, which MAY result in you losing money from these wallet(s) if no action is taken.\nWe recommend that you IMMEDIATELY create wallet(s) in Cake Wallet and immediately transfer the funds to these wallet(s).\nVulnerable wallet name(s):\n\n[${affectedWalletNames.join(", ")}]\n\nFor assistance, please use the in-app support or email support@cakewallet.com",
|
||||||
|
style: TextStyle(
|
||||||
|
decoration: TextDecoration.none,
|
||||||
|
fontSize: 16.0,
|
||||||
|
fontFamily: 'Lato',
|
||||||
|
color: Theme.of(context)
|
||||||
|
.extension<DashboardPageTheme>()!
|
||||||
|
.textColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
AlertCloseButton(bottom: 30)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,3 +1,6 @@
|
||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:cake_wallet/core/key_service.dart';
|
||||||
import 'package:cake_wallet/entities/auto_generate_subaddress_status.dart';
|
import 'package:cake_wallet/entities/auto_generate_subaddress_status.dart';
|
||||||
import 'package:cake_wallet/entities/balance_display_mode.dart';
|
import 'package:cake_wallet/entities/balance_display_mode.dart';
|
||||||
import 'package:cake_wallet/entities/buy_provider_types.dart';
|
import 'package:cake_wallet/entities/buy_provider_types.dart';
|
||||||
|
@ -24,12 +27,19 @@ import 'package:cake_wallet/view_model/dashboard/trade_list_item.dart';
|
||||||
import 'package:cake_wallet/view_model/dashboard/transaction_list_item.dart';
|
import 'package:cake_wallet/view_model/dashboard/transaction_list_item.dart';
|
||||||
import 'package:cake_wallet/view_model/settings/sync_mode.dart';
|
import 'package:cake_wallet/view_model/settings/sync_mode.dart';
|
||||||
import 'package:cake_wallet/wallet_type_utils.dart';
|
import 'package:cake_wallet/wallet_type_utils.dart';
|
||||||
|
import 'package:cryptography/cryptography.dart';
|
||||||
import 'package:cw_core/balance.dart';
|
import 'package:cw_core/balance.dart';
|
||||||
|
import 'package:cw_core/cake_hive.dart';
|
||||||
|
import 'package:cw_core/pathForWallet.dart';
|
||||||
import 'package:cw_core/sync_status.dart';
|
import 'package:cw_core/sync_status.dart';
|
||||||
import 'package:cw_core/transaction_history.dart';
|
import 'package:cw_core/transaction_history.dart';
|
||||||
import 'package:cw_core/transaction_info.dart';
|
import 'package:cw_core/transaction_info.dart';
|
||||||
|
import 'package:cw_core/utils/file.dart';
|
||||||
import 'package:cw_core/wallet_base.dart';
|
import 'package:cw_core/wallet_base.dart';
|
||||||
|
import 'package:cw_core/wallet_info.dart';
|
||||||
import 'package:cw_core/wallet_type.dart';
|
import 'package:cw_core/wallet_type.dart';
|
||||||
|
import 'package:eth_sig_util/util/utils.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
import 'package:mobx/mobx.dart';
|
import 'package:mobx/mobx.dart';
|
||||||
|
|
||||||
part 'dashboard_view_model.g.dart';
|
part 'dashboard_view_model.g.dart';
|
||||||
|
@ -46,7 +56,8 @@ abstract class DashboardViewModelBase with Store {
|
||||||
required this.settingsStore,
|
required this.settingsStore,
|
||||||
required this.yatStore,
|
required this.yatStore,
|
||||||
required this.ordersStore,
|
required this.ordersStore,
|
||||||
required this.anonpayTransactionsStore})
|
required this.anonpayTransactionsStore,
|
||||||
|
required this.keyService})
|
||||||
: hasSellAction = false,
|
: hasSellAction = false,
|
||||||
hasBuyAction = false,
|
hasBuyAction = false,
|
||||||
hasExchangeAction = false,
|
hasExchangeAction = false,
|
||||||
|
@ -262,6 +273,8 @@ abstract class DashboardViewModelBase with Store {
|
||||||
|
|
||||||
bool get hasRescan => wallet.type == WalletType.monero || wallet.type == WalletType.haven;
|
bool get hasRescan => wallet.type == WalletType.monero || wallet.type == WalletType.haven;
|
||||||
|
|
||||||
|
final KeyService keyService;
|
||||||
|
|
||||||
BalanceViewModel balanceViewModel;
|
BalanceViewModel balanceViewModel;
|
||||||
|
|
||||||
AppStore appStore;
|
AppStore appStore;
|
||||||
|
@ -283,12 +296,12 @@ abstract class DashboardViewModelBase with Store {
|
||||||
Map<String, List<FilterItem>> filterItems;
|
Map<String, List<FilterItem>> filterItems;
|
||||||
|
|
||||||
BuyProviderType get defaultBuyProvider =>
|
BuyProviderType get defaultBuyProvider =>
|
||||||
settingsStore.defaultBuyProviders[wallet.type] ??
|
settingsStore.defaultBuyProviders[wallet.type] ?? BuyProviderType.AskEachTime;
|
||||||
BuyProviderType.AskEachTime;
|
|
||||||
|
|
||||||
bool get isBuyEnabled => settingsStore.isBitcoinBuyEnabled;
|
bool get isBuyEnabled => settingsStore.isBitcoinBuyEnabled;
|
||||||
|
|
||||||
List<BuyProviderType> get availableProviders => BuyProviderType.getAvailableProviders(wallet.type);
|
List<BuyProviderType> get availableProviders =>
|
||||||
|
BuyProviderType.getAvailableProviders(wallet.type);
|
||||||
|
|
||||||
bool get shouldShowYatPopup => settingsStore.shouldShowYatPopup;
|
bool get shouldShowYatPopup => settingsStore.shouldShowYatPopup;
|
||||||
|
|
||||||
|
@ -433,4 +446,32 @@ abstract class DashboardViewModelBase with Store {
|
||||||
|
|
||||||
@action
|
@action
|
||||||
void setSyncAll(bool value) => settingsStore.currentSyncAll = value;
|
void setSyncAll(bool value) => settingsStore.currentSyncAll = value;
|
||||||
|
|
||||||
|
Future<List<String>> checkAffectedWallets() async {
|
||||||
|
// await load file
|
||||||
|
final vulnerableSeedsString = await rootBundle.loadString('assets/text/cakewallet_weak_bitcoin_seeds_hashed_sorted_version1.txt');
|
||||||
|
final vulnerableSeeds = vulnerableSeedsString.split("\n");
|
||||||
|
|
||||||
|
final walletInfoSource = await CakeHive.openBox<WalletInfo>(WalletInfo.boxName);
|
||||||
|
|
||||||
|
List<String> affectedWallets = [];
|
||||||
|
for (var walletInfo in walletInfoSource.values) {
|
||||||
|
if (walletInfo.type == WalletType.bitcoin) {
|
||||||
|
final password = await keyService.getWalletPassword(walletName: walletInfo.name);
|
||||||
|
final path = await pathForWallet(name: walletInfo.name, type: walletInfo.type);
|
||||||
|
final jsonSource = await read(path: path, password: password);
|
||||||
|
final data = json.decode(jsonSource) as Map;
|
||||||
|
final mnemonic = data['mnemonic'] as String;
|
||||||
|
|
||||||
|
final hash = await Cryptography.instance.sha256().hash(utf8.encode(mnemonic));
|
||||||
|
final seedSha = bytesToHex(hash.bytes);
|
||||||
|
|
||||||
|
if (vulnerableSeeds.contains(seedSha)) {
|
||||||
|
affectedWallets.add(walletInfo.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return affectedWallets;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ MONERO_COM_SCHEME="monero.com"
|
||||||
|
|
||||||
CAKEWALLET_NAME="Cake Wallet"
|
CAKEWALLET_NAME="Cake Wallet"
|
||||||
CAKEWALLET_VERSION="4.12.0"
|
CAKEWALLET_VERSION="4.12.0"
|
||||||
CAKEWALLET_BUILD_NUMBER=186
|
CAKEWALLET_BUILD_NUMBER=187
|
||||||
CAKEWALLET_BUNDLE_ID="com.cakewallet.cake_wallet"
|
CAKEWALLET_BUNDLE_ID="com.cakewallet.cake_wallet"
|
||||||
CAKEWALLET_PACKAGE="com.cakewallet.cake_wallet"
|
CAKEWALLET_PACKAGE="com.cakewallet.cake_wallet"
|
||||||
CAKEWALLET_SCHEME="cakewallet"
|
CAKEWALLET_SCHEME="cakewallet"
|
||||||
|
|
|
@ -19,7 +19,7 @@ MONERO_COM_BUNDLE_ID="com.cakewallet.monero"
|
||||||
|
|
||||||
CAKEWALLET_NAME="Cake Wallet"
|
CAKEWALLET_NAME="Cake Wallet"
|
||||||
CAKEWALLET_VERSION="4.12.0"
|
CAKEWALLET_VERSION="4.12.0"
|
||||||
CAKEWALLET_BUILD_NUMBER=204
|
CAKEWALLET_BUILD_NUMBER=205
|
||||||
CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet"
|
CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet"
|
||||||
|
|
||||||
HAVEN_NAME="Haven"
|
HAVEN_NAME="Haven"
|
||||||
|
|
Loading…
Reference in a new issue