-
Notifications
You must be signed in to change notification settings - Fork 38.6k
[WIP] External signer support (e.g. hardware wallet) #14912
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
Conversation
e021812 to
a2b018d
Compare
|
Now that #14491 has been rebased, the See also the wallet meeting notes. |
a2b018d to
9ec4aac
Compare
|
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. ConflictsReviewers, this pull request conflicts with the following ones:
If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first. |
src/wallet/externalsigner.cpp
Outdated
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.
ExternalSigner signer shadows UniValue signer :-)
src/wallet/rpcdump.cpp
Outdated
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.
Make signedness changing implicit conversion explicit? Also, remove redundant initialization to zero on the line above? Merge the two lines.
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.
The compiler didn't like it when I initialized using gArgs.GetArg.
src/util/system.cpp
Outdated
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.
Initialize to zero?
src/wallet/rpcwallet.cpp
Outdated
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.
Should be "fingerprint" :-)
src/util/system.cpp
Outdated
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.
I haven't reviewed this use of popen(…) closer, but please note the recommendations/risks with regards to popen(…) used described in the CERT secure coding guidelines (more specifically rule ENV33-C).
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.
This is straight from stack overflow, so certainly needs more review... I'm surprised how complicated it is to just read some JSON from stdout.
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.
popen and pclose are unix-like only. You can't use them on Windows. IMO you could use boost process instead.
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.
I think we don't depend on boost process.
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.
I know. But this is the simplest way if this is really necessary to call another process. I don't think that any one here know how to use Windows CreateProcess API.
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.
It would be reasonable to call _popen function here on windows or #define popen _popen: https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/system-wsystem.
You do need to be very careful about special characters passed in the command string, but it should be ok if you stick to hex/base64.
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.
_popen would only work in console program. See https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/popen-wpopen. So it doesn't work in Qt.
src/util/strencodings.cpp
Outdated
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.
keypath should be const reference?
src/wallet/rpcwallet.cpp
Outdated
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.
Nit: Could use command.empty()? :-)
src/wallet/externalsigner.cpp
Outdated
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.
Should be const reference? :-)
src/wallet/externalsigner.cpp
Outdated
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.
Should be const reference? :-)
src/wallet/externalsigner.cpp
Outdated
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.
Use string equality operator instead of compare :-)
src/wallet/rpcwallet.cpp
Outdated
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.
signer can be nullptr here if the check on L4016 is correct?
src/wallet/rpcwallet.cpp
Outdated
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.
Same here: signer can be nullptr here if the check on L4016 is correct?
src/util/strencodings.h
Outdated
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.
keypath should be const reference?
src/wallet/rpcdump.cpp
Outdated
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.
Nit: Could use std::copy instead?
src/wallet/rpcdump.cpp
Outdated
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.
Same here: Could you std::copy?
src/wallet/rpcdump.cpp
Outdated
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.
Missing space before (. Consider running new code through clang-format :-)
src/wallet/rpcdump.cpp
Outdated
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.
Same here: Missing whitespace before (.
Create basic ExternalSigner class with contructor. A Signer(<cmd>) is added to CWallet on load if -signer=<cmd> is set.
c739648 to
157b8f2
Compare
|
Rebased now that #15911 is merged. Dropped a few commits that should have been in #15876 and aren't needed anyway after #15713. Removed the need for the unit test to add private keys to the keypool (closing #15414). I'll keep this and the convenience methods in #15876 up to date and work on a "boxed" version in a separate PR. |
157b8f2 to
3ba77e9
Compare
|
Here's a simple rebase on top of a native descriptor wallet #16528 (benefit: gives access to full BIP44/49/84 address tree): https://github.com/Sjors/bitcoin/tree/2019/08/hww-box |
Includes a mock to mimick the HWI interace.
3ba77e9 to
264425b
Compare
|
Closing in favor of the native descriptor edition in #16546. |
This PR lets
bitcoindto call an arbitrary command-signer=<cmd>, e.g. a hardware wallet driver, where it can fetch public keys, ask to display an address, and sign a PSBT.It's design to work with https://github.com/bitcoin-core/HWI, which supports multiple hardware wallets. Any command with the same arguments and return values will work. It simplifies the manual procedure described here.
Usage is documented in doc/external-signer.md, which also describes what protocol a different signer binary should conform to.
It adds the following RPC methods:
enumeratesigners: asks for a list of signers (e.g. devices) and their master key fingerprintsignerfetchkeys(needs Add getdescriptors command bitcoin-core/HWI#137): asks for descriptors and then fills the keypool (no private keys)signerdisplayaddress <address>: asks to display an addresssignerprocesspsbt <psbt>to send the<psbt>to<cmd>to sign and wait for the resultUsage TL&DR:
bitcoind -signer=../HWI/hwi.pybitcoin-cli createwallet hww truebitcoin-cli enumeratesignersbitcoin-cli -rpcwallet=hww signerfetchkeysFor easier review, this builds on the following PRs:
Potentially useful followups: