Skip to content
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

Additional safety checks in PSBT signer #13917

Merged
merged 4 commits into from Aug 14, 2018
Merged

Conversation

sipa
Copy link
Member

@sipa sipa commented Aug 8, 2018

The current PSBT signing code can end up producing a non-segwit signature, while only the UTXO being spent is provided in the PSBT (as opposed to the entire transaction being spent). This may be used to trick a user to incorrectly decide a transaction has the semantics he intends to sign.

Fix this by refusing to sign if there is any mismatch between the provided data and what is being signed.

@maflcko maflcko added Tests and removed Tests labels Aug 8, 2018
@maflcko maflcko added this to the 0.17.0 milestone Aug 8, 2018
@maflcko maflcko added the Wallet label Aug 8, 2018
@sipa sipa added the Bug label Aug 8, 2018
@practicalswift
Copy link
Contributor

Excellent! Thanks for tightening PSBT!

Concept ACK

@DrahtBot
Copy link
Contributor

DrahtBot commented Aug 8, 2018

Note to reviewers: 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.

input.non_witness_utxo = nullptr;
} else {
input.witness_utxo.SetNull();
if (from_wallet) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Commit "Only wipe wrong UTXO type data if overwritten by wallet"

Suggestion, either reuse above condition if (it != pwallet->mapWallet.end())or above do:

const bool from_wallet = it != pwallet->mapWallet.end();
if (from_wallet) {
    ...
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

CTxOut utxo;
if (input.non_witness_utxo) {
// If we're taking our information from a non-witness UTXO, verify that it matches the prevout.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Commit "Additional sanity checks in SignPSBTInput"

nit, could reflow comments.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think they're fine.

@achow101
Copy link
Member

achow101 commented Aug 8, 2018

utACK

Here is a commit with some more test cases: achow101@9f110e1. It tests for non-matching redeem scripts with both witness and non-witness utxos and non-matching witness scripts (for witness utxo only)

@sipa
Copy link
Member Author

sipa commented Aug 8, 2018

Addressed @promag's nit, and included more tests by @achow101.

Copy link
Member

@kallewoof kallewoof left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utACK 2bc1296db7ba4e99f52a4002e67b11c0351819d6

if (input.non_witness_utxo->GetHash() != tx.vin[index].prevout.hash) return false;
// If both witness and non-witness UTXO are provided, verify that they match. This check shouldn't
// matter, as the PSBT deserializer enforces only one of both is provided, and the only way both
// can be present is when they're added simultaneously by FillPSBT (in which case they always match).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this comment based on the BIP/spec or implementation? What about other implementations that may not do what FillPSBT does in Bitcoin Core? I understand that the check is done anyway, but the comment sounds like it could be skipped due to an implementation detail, which sounds error-prone.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@achow101 just opened a PR that adds the actual requirements to test for to BIP 174, including a simple implementation in pseudocode that implements it.

@achow101
Copy link
Member

achow101 commented Aug 9, 2018

utACK 2bc1296db7ba4e99f52a4002e67b11c0351819d6

@kallewoof
Copy link
Member

Perhaps unrelated, but either createpsbt is too lenient, or decodepsbt is broken.

$ ./bitcoin-cli createpsbt "[]" "[{\"$(./bitcoin-cli getnewaddress)\":0.01}]"
cHNidP8BACoCAAAAAAFAQg8AAAAAABepFG6Rty1Vk+fUOR4v9E6R6YXDFkHwhwAAAAAAAA==
$ ./bitcoin-cli decodepsbt cHNidP8BACoCAAAAAAFAQg8AAAAAABepFG6Rty1Vk+fUOR4v9E6R6YXDFkHwhwAAAAAAAA==
error code: -22
error message:
TX decode failed CDataStream::read(): end of data: unspecified iostream_category error

@fanquake
Copy link
Member

@sipa Can you rebase this now that #13666 is merged.

@sipa
Copy link
Member Author

sipa commented Aug 13, 2018

Rebased after #13666.

@achow101
Copy link
Member

re-utACK

@kallewoof
Copy link
Member

re-utACK 5df6f08

@laanwj
Copy link
Member

laanwj commented Aug 14, 2018

utACK 5df6f08

@laanwj laanwj merged commit 5df6f08 into bitcoin:master Aug 14, 2018
fanquake pushed a commit to fanquake/bitcoin that referenced this pull request Aug 15, 2018
fanquake pushed a commit to fanquake/bitcoin that referenced this pull request Aug 15, 2018
fanquake pushed a commit to fanquake/bitcoin that referenced this pull request Aug 15, 2018
fanquake pushed a commit to fanquake/bitcoin that referenced this pull request Aug 15, 2018
@fanquake
Copy link
Member

Will be backported in #13976

laanwj added a commit that referenced this pull request Aug 15, 2018
0333914 More tests of signer checks (Andrew Chow)
8935869 Test that a non-witness script as witness utxo is not signed (Andrew Chow)
dbaadc9 Only wipe wrong UTXO type data if overwritten by wallet (Pieter Wuille)
ad6d845 Additional sanity checks in SignPSBTInput (Pieter Wuille)
517010e Serialize non-witness utxo as a non-witness tx but always deserialize as witness (Andrew Chow)
8c4cd2b Fix PSBT deserialization of 0-input transactions (Andrew Chow)

Pull request description:

  Backports #13917 and #13960 to the 0.17 branch.

Tree-SHA512: b3853aff2a13a53aa0a390b6b4b0c539f0ef0d42f2c517e956efd0b135c74c4ddce6a1d00700849a58c696824fa95951d8cac6ca58b426e8dfcb8bb62f680b7c
HashUnlimited pushed a commit to HashUnlimited/chaincoin that referenced this pull request Sep 14, 2018
HashUnlimited pushed a commit to HashUnlimited/chaincoin that referenced this pull request Sep 14, 2018
HashUnlimited pushed a commit to HashUnlimited/chaincoin that referenced this pull request Sep 14, 2018
HashUnlimited pushed a commit to HashUnlimited/chaincoin that referenced this pull request Sep 14, 2018
@bitcoin bitcoin locked as resolved and limited conversation to collaborators Sep 8, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

9 participants