-
Notifications
You must be signed in to change notification settings - Fork 94
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(hd-wallet): enable/withdraw using any account'/change/address_index #1933
Conversation
… instead of hd_account_id in adex-cli,
…Policy for reusable code
drop_mutability!(priv_key); | ||
|
||
let secret = *priv_key.private_key().as_ref(); | ||
Ok(Secp256k1Secret::from(secret)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we shouldn't store sensitive data longer in memory than needed. could use e.g. https://crates.io/crates/zeroize or similar approach. We ult. need the key only in case of signing requirement. Will open separate issue ticket since this affects multiple layers - but figured, maybe we want to start here / with HD withdrawl layer, since critical layer?
EDIT: given workload, lets keep on radar / handle in one of the next iterations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could use e.g. https://crates.io/crates/zeroize or similar approach
Thanks for the suggestion. Using zeroize
looks like a good approach to zeroing the memory region after the variable is dropped, we should also consider disabling swapping for this memory region to avoid the OS saving secrets to disk unintentionally. Please note that the master seed is kept in memory throughout the application runtime, we should probably add the option to keep it encrypted only in memory and decrypt it using the RPC password (the rpc password is also kept in memory, so maybe we should keep the hash of the password+salt instead to verify the password on each call) as part of this separate issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
drop
itself is enough for this purpose
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For certain values, we have to keep them in memory constantly to operate mm2 without always asking users. Which might not be good for GUI clients and bots. To protect against memory attacks, we can change the memory addresses dynamically while the program is running so we don't have the important values on the same address all the time while the program is running. However, we should also make sure passphrases(and other informations) are safe, as they're stored in a plain text file right know (MM_CONF_PATH). If someone gets into the mm2 device, they can quickly get the passphrases from the text file without needing doing complicated hardware attack / reverse engineering stuff.
We talked about this topic in a public Mattermost channel with @gcharang. We sort of figured out a quite good solution for the issue, but I can't recall all the details since our discussion was very detailed and it was months ago.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I know that komodod use MemoryPageLocker object for locking privkeys in memory, I guess, to prevent sending virtual pages with sensitive data to swap file. I wonder if we have the same feature in rust
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I know that komodod use MemoryPageLocker object for locking privkeys in memory, I guess, to prevent sending virtual pages with sensitive data to swap file. I wonder if we have the same feature in rust
We can use mlock
from libc, I don't know if there is any better way for that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
seems this would be platform-dependant as in komodod it is implemented like
bool MemoryPageLocker::Lock(const void* addr, size_t len)
{
#ifdef _WIN32
return VirtualLock(const_cast<void*>(addr), len) != 0;
#else
return mlock(addr, len) == 0;
#endif
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for your input @dimxy @ozkanonur, I will look into it once the issue is opened and planned. We can discuss the details more then :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, we need to use winapi
for doing this on Windows as libc doesn't support windows. Both winapi
and libc
are already present in our dependency tree, so we can do it easily.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
secure code reviewed
feedback given on key handling / secure mem zeroing
- should additionally ensure we don't accidentally create multiple mem copies of "sensitive" data due to (de)serialization and other relevant data ops.
|
Yes, it's better this way since we will not be tied to an address path (the
This is the most important #1933 (comment) as others can change. Everything else can change to make HD wallet feature better, but I will provide examples for everything else below: Coins Activation:
UTXO electrum:{
"userpass": "{{userpass}}",
"method": "electrum",
"coin": "RICK",
"servers": [
{
"url": "electrum1.cipig.net:10017"
},
{
"url": "electrum2.cipig.net:10017"
},
{
"url": "electrum3.cipig.net:10017"
}
],
"path_to_address": {
"account": 7,
"is_change": false,
"address_index": 77
}
} UTXO v2 (
|
Tendermint Activation (
|
|
NFT activate / withdraw:If mm2 is started with Trezor activate / withdrawThis PR doesn't affect Trezor implementation at all and it should work as it has been before. BIP39 HD without trezor activate / withdraw@smk762 what do you mean with this? to use |
Withdraw methods (
|
Zcoin withdraw:We can't withdraw from any account for now, it will be added in next PRs too. Only enabled account with coin activation is used using
All are working for wasm except zcoin since it's not supported in wasm yet. |
Thanks for the examples and clarifications
Basically meaning to test the activation / withdraw without using a hardware wallet |
Yeah, this whole PR is for this. Not related to hardware wallet at all. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks.
The only issues errors encountered are TODO in subsequent PRs, so approving this one.
For reference, these were the issues I encountered:
- unsure of derivation paths for zhtlc, and the ones attempted returned an address which would not receive funds sent from a legacy desktop address.
- SLP activates, but there was an infra issue with withdrawals unrelated to this PR
"Internal error: Error PayloadTooShort on request to the url https://bchd.dragonhound.info/pb.bchrpc/GetSlpTrustedValidation"
I will check the node. - Tendermint activates, but withdraw not tested as docs for [r2r] cosmos ibc transfer implementation #1636 have not yet been drafted. I will revisit these tests when drafting the docs and/or future related PRs.
Thank you for the testing @smk762, I added this comment to the issue checklist #1838 (comment) to not forget about them :) |
Intermediate PR part of #1838
Global enabling of an
account'/change/address_index
path for all coins usinghd_account_id
config parameter is replaced byenable_hd
which is abool
that defaults to false. I couldn't remove this parameter all together and make enabling ofIguana
or HD mode at the coin level since the Iguana seed phrases which is passed to config at initiation will not always beBIP39
compliant which will result in HD context to fail in initializing. I madeenable_hd
default to false to not break backward compatibility. c.c. @KomodoPlatform/qaHD withdrawal from any
account'/change/address_index
path is implemented for UTXO, EVM and Tendermint coins for now, other coins will be added in next PRs.path_to_address
parameter is added to coins activation requests to set the defaultaccount'/change/address_index
path that will be used for swaps. If not provided, the default will be0'/0/0
.from
parameter inwithdraw
can be used to withdraw from anyaccount'/change/address_index
usingno need to document any of these changes for now since these parameters can be changed as this is is only an
Intermediate PR. For instance
from.address_id
that is used in HW wallets can be used instead since I found they arethe same, c.c. @KomodoPlatform/qa
Review process notes:
adex-cli
changes related to replacinghd_account_id
withenable_hd
, activation scheme data doesn't support HD wallet, I should update how HD wallet enabling work withadex-cli
when all the HD fixes are done in next PRs, as activation scheme data doesn't support HD wallet and will not be able to support it with the current changes.Todo in next PRs:
account'/change/address_index
forARRR
,NFTs
,SLP
andQRC20
.account'/change/address_index
and also Solana support can be postponed until these features are planned.account_balance
RPC.