PSBT Addition (BIP 174) for authenticating source/output PSBT files

PSBT Addition (BIP 174) for authenticating source/output PSBT files
2020-01-11 20:17 ` Dmitry Petukhov
  
From: Peter D. Gray @ 2020-01-11 17:29 UTC (permalink / raw)
  To: bitcoin-dev

[-- Attachment #1: Type: text/plain, Size: 4019 bytes --]

## Background

PSBT files in transit are at risk of MiTM changes. This isn't
supposed to matter, but as another layer of defence, I would like
to add two signatures to PSBT files when they are processed by the
PSBT Signer. These additional fields would be optional, and should
pass through existing PSBT processors transparently, assuming they
pass unknown key/values as BIP-174 specifies.

## Additional Key/Values

1) In the PSBT globals section, a signature over the "source" PSBT
file. It would cover all the bytes of the original PSBT file, as
it was received by the Signer. The key used for the signature may
be any one the keys that the Signer applied during its transaction
signing process. (This is flexible so that the Signer can make the
signature at any point in the signing process. On the Coldcard, we
would probably use the first key that we used for signing, so the
first key involved in the first input.)

The "key" of the global value will be pubkey value of the key which
was selected by the Signer.  If its BIP32 derivation is needed for
some reason, that is documented in the input section already.

The "value" will be 65(?) bytes of a standard Bitcoin signature.
The digest (hash) of the source PSBT is not provided, so any tool
that wants to verify this signature will need to have a copy of the
original PSBT. (I see that as a critical feature, not a limitation).

2) In the output section, specifically, the last key/value pair of
the last output of the transaction, I want to add a similar signature,
again signed by one of the keys used in the signing process. This
signature will cover all the bytes of the resulting (signed) PSBT
up to that point. Because it is the last output of the output
section, that signature will be the last few bytes of the PSBT file.
By "appending" the signature in this way, it's easier to validate
and create the signature, without blanking the signature area during
digest step.

## Role-Based View

The above additions can only be made by a PSBT processor in the Signer
role. No-one else has the keys needed. As for the other PSBT roles:

- Any tool that reads in a PSBT and finds a signature in the final output
  section can and should verify it:
    - check signature over a digest of the PSBT file up to the last X bytes
    - file must end at that point, with only the signature following it
    - also check the key used for signature is one of the input's keys

- PSBT processors in the "combining" role, should preserve the
signatures in the global section, accumulating them into the next
PSBT. (Of course they should validate them, if they have the original
PSBT on hand as well, but that's optional and could be done later
in the flow.) The Combiner should always check a signed PSBT was
not modified in transit via the signature in the final output
section, and then strip it out of the combined PSBT.

- At the end of the signing process, the Finalizer should check all
the Signers have worked from the same PSBT file (assuming that's
the flow expected), or the appropriate PSBT if it's a more complex
case. If the Finalizer is working on a file directly from a Signer,
then it can verify the signature in the output section as well.

## Open Questions

For the message digest, I propose simple SHA256(SHA256(bytes of PSBT)).
I'm not sure of the best way to serialize the signature, but to be
consistent with the rest of the file, it should probably be DER-encoded
and variable length.

## Next Steps

I'd like to get two officially-assigned BIP-174 key numbers assigned
for these two signatures, and then I will see that it gets added
into Coldcard's firmware immediately. In time, other tools are
welcome to take advantage of these checks. I will also write a BIP
for this, and/or make an addition to BIP-174.

I think with these changes, and assuming all the tools are verifying
properly, we can shutdown undetectable MiTM changes to PSBT contents.

---
Peter D. Gray  ||  Founder, Coinkite  ||  Twitter: @dochex  ||  GPG: A3A31BAD 5A2A5B10


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 529 bytes --]

 permalink raw reply	[|nested]
2020-01-11 17:29 [bitcoin-dev] PSBT Addition (BIP 174) for authenticating source/output PSBT files Peter D. Gray

  2020-01-13  6:39   ` Andrew Chow
  
From: Dmitry Petukhov @ 2020-01-11 20:17 UTC (permalink / raw)
  To: Peter D. Gray via bitcoin-dev;  Peter Gray

[-- Attachment #1: Type: text/plain, Size: 4613 bytes --]

I am not sure that this particular task should be done with data
embedded in PSBT itself, and not with some sort of container that
includes PSBT and the authentication information.

The benefit seems to be in reusing PSBT structure for compatibilty, and
this might be a valid way, although I do not agree with some of your
points. I elaborate below:

> 1) In the PSBT globals section, a signature over the "source" PSBT
> file. It would cover all the bytes of the original PSBT file, as
> it was received by the Signer.

The problem of authenticating the contents of PSBT is independent of
the signing action. PSBT might be altered on the path from Creator to
Signer. Therefore you cannot always say that Signer will be an
authority over 'correctness' of PSBT.

> - At the end of the signing process, the Finalizer should check all
> the Signers have worked from the same PSBT file (assuming that's
> the flow expected)

If there is MitM, checking something at Finalizer is likely too
late - the party that can intercept PSBTs can finalize before the
legitimate Finalizer and broadcast the transaction.

Participants can work from the same PSBT file if they all receive the
same PSBT, and not working in chain where next particpant receives
updated PSBT from the previous participant. Otherwise they will need to
either pass two files (original and updated), or work out which fields
(key-value blobs) to remove to get the 'source' PSBT (which might not be
trivial with presense of proprietary and unknown fields). Even if you
know which key-value pairs to remove, there is no requirement for
ordering of the fields, and some signer can serialize them in different
order after dserialize/sign/add-signatures/re-serialize operation.

Introducing additional ordering or other structure requirements over
simple key-value structure will add complexity to PSBT processing, and
adding complexity on such a basic level should have really serious
reasons, because that increases effort required for even basic
implementations and increases chance of bugs.

If there is some authority on the 'correctness' of 'original' PSBT
(all particpants receive same PSBT at the start), particpants should
check the signature by that authority. That authority might use
the key used only for authentication, and not in the tx signing.

If particpants send PSBT in chain after adding their signatures, then
each participant can add their signature to say 'the contents
of PSBT after my updates should match this hash'.

The signatures of previous participants in the chain most likely do not
matter because of difficulty of restoring the contents of PSBT as it
was before the previous particpant, if you do not pass _all_ the PSBTs
(which is excessive). 
 
> 2) In the output section, specifically, the last key/value pair of
> the last output of the transaction, I want to add a similar signature,
> again signed by one of the keys used in the signing process. This
> signature will cover all the bytes of the resulting (signed) PSBT
> up to that point. Because it is the last output of the output
> section, that signature will be the last few bytes of the PSBT file.
> By "appending" the signature in this way, it's easier to validate
> and create the signature, without blanking the signature area during
> digest step.

This will introduce unnecessary higher-level structure to PSBT for the
reasons that I do not find strong enough for the amount of complexity
added.

Also, as I said above, you likely do not need more than one
signature - if this is 'fan-out' scheme, then participants need do
check the sig of authority that created PSBT; if this is piggy-back
chain, then only previous particpant's signature is easily verifiable.

> ## Next Steps
> 
> I'd like to get two officially-assigned BIP-174 key numbers assigned
> for these two signatures, and then I will see that it gets added
> into Coldcard's firmware immediately. In time, other tools are
> welcome to take advantage of these checks. I will also write a BIP
> for this, and/or make an addition to BIP-174.

I think you do not need to wait for officially-assigned key numbers,
and can just implement the scheme you envision with proprietary keys,
document and promote it. Then if it shows its usefulness, it will
either become de-facto standard with your proprietary keys (and
everyone will want to support 'Coldard PSBT auth' or whatever the name),
or the scheme will have serious grounds to be converted to standard and
have non-proprietary keys assigned.

// Dmitry.

[-- Attachment #2: Ð¦Ð¸Ñ„Ñ€Ð¾Ð²Ð°Ñ Ð¿Ð¾Ð´Ð¿Ð¸ÑÑŒ OpenPGP --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

 permalink raw reply	[|nested]
2020-01-11 20:17 ` Dmitry Petukhov

  2020-01-13 14:28     ` Peter D. Gray
  
From: Andrew Chow @ 2020-01-13  6:39 UTC (permalink / raw)
  To: Dmitry Petukhov, Bitcoin Protocol Discussion;  Peter Gray

I agree with Dimitry. I don't see the point of having the MiTM
protection within the PSBT structure itself, in addition to the fact
that adding new fields is largely unnecessary. In fact, I'm not quite
sure what kind of attack you are trying to defend against with this
proposal.

If there is a MiTM who can modify your PSBT, then they can just modify
the result the signed PSBT to drop the auth signatures. Furthermore, any
modifications to scripts or UTXOs would just result in an invalid
signature, so only time is wasted. But you'll just waste time anyways
when you see a failed auth sig.

Additionally, when a signer processes a PSBT, it will either accept the
PSBT and add a signature for its inputs, or reject it and do nothing.
Given this behavior (and I assume you aren't going to add auth sigs for
rejected PSBTs because that doesn't make any sense), then you already
have a signature there that covers everything your auth signature would
cover. So just verify those signatures instead; for any inputs with
signatures, everything you need to verify them are already there.

Lastly, IMO, if you want MiTM protection, then you should do your
protection with out of band communication. Just PGP sign the PSBT (or
something similar) and send the signature along separately.

Andrew

On 1/11/20 3:17 PM, Dmitry Petukhov via bitcoin-dev wrote:
> 
> I am not sure that this particular task should be done with data
> embedded in PSBT itself, and not with some sort of container that
> includes PSBT and the authentication information.
> 
> The benefit seems to be in reusing PSBT structure for compatibilty, and
> this might be a valid way, although I do not agree with some of your
> points. I elaborate below:
> 
>> 1) In the PSBT globals section, a signature over the "source" PSBT
>> file. It would cover all the bytes of the original PSBT file, as
>> it was received by the Signer.
> 
> The problem of authenticating the contents of PSBT is independent of
> the signing action. PSBT might be altered on the path from Creator to
> Signer. Therefore you cannot always say that Signer will be an
> authority over 'correctness' of PSBT.
> 
>> - At the end of the signing process, the Finalizer should check all
>> the Signers have worked from the same PSBT file (assuming that's
>> the flow expected)
> 
> If there is MitM, checking something at Finalizer is likely too
> late - the party that can intercept PSBTs can finalize before the
> legitimate Finalizer and broadcast the transaction.
> 
> Participants can work from the same PSBT file if they all receive the
> same PSBT, and not working in chain where next particpant receives
> updated PSBT from the previous participant. Otherwise they will need to
> either pass two files (original and updated), or work out which fields
> (key-value blobs) to remove to get the 'source' PSBT (which might not be
> trivial with presense of proprietary and unknown fields). Even if you
> know which key-value pairs to remove, there is no requirement for
> ordering of the fields, and some signer can serialize them in different
> order after dserialize/sign/add-signatures/re-serialize operation.
> 
> Introducing additional ordering or other structure requirements over
> simple key-value structure will add complexity to PSBT processing, and
> adding complexity on such a basic level should have really serious
> reasons, because that increases effort required for even basic
> implementations and increases chance of bugs.
> 
> If there is some authority on the 'correctness' of 'original' PSBT
> (all particpants receive same PSBT at the start), particpants should
> check the signature by that authority. That authority might use
> the key used only for authentication, and not in the tx signing.
> 
> If particpants send PSBT in chain after adding their signatures, then
> each participant can add their signature to say 'the contents
> of PSBT after my updates should match this hash'.
> 
> The signatures of previous participants in the chain most likely do not
> matter because of difficulty of restoring the contents of PSBT as it
> was before the previous particpant, if you do not pass _all_ the PSBTs
> (which is excessive).
> 
>> 2) In the output section, specifically, the last key/value pair of
>> the last output of the transaction, I want to add a similar signature,
>> again signed by one of the keys used in the signing process. This
>> signature will cover all the bytes of the resulting (signed) PSBT
>> up to that point. Because it is the last output of the output
>> section, that signature will be the last few bytes of the PSBT file.
>> By "appending" the signature in this way, it's easier to validate
>> and create the signature, without blanking the signature area during
>> digest step.
> 
> This will introduce unnecessary higher-level structure to PSBT for the
> reasons that I do not find strong enough for the amount of complexity
> added.
> 
> Also, as I said above, you likely do not need more than one
> signature - if this is 'fan-out' scheme, then participants need do
> check the sig of authority that created PSBT; if this is piggy-back
> chain, then only previous particpant's signature is easily verifiable.
> 
>> ## Next Steps
>>
>> I'd like to get two officially-assigned BIP-174 key numbers assigned
>> for these two signatures, and then I will see that it gets added
>> into Coldcard's firmware immediately. In time, other tools are
>> welcome to take advantage of these checks. I will also write a BIP
>> for this, and/or make an addition to BIP-174.
> 
> I think you do not need to wait for officially-assigned key numbers,
> and can just implement the scheme you envision with proprietary keys,
> document and promote it. Then if it shows its usefulness, it will
> either become de-facto standard with your proprietary keys (and
> everyone will want to support 'Coldard PSBT auth' or whatever the name),
> or the scheme will have serious grounds to be converted to standard and
> have non-proprietary keys assigned.
> 
> // Dmitry.
> _______________________________________________
> bitcoin-dev mailing list
> bitcoin-dev@lists•linuxfoundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
> 



 permalink raw reply	[|nested]
2020-01-13  6:39   ` Andrew Chow

  2020-01-13 17:05       ` Andrew Chow
  
From: Peter D. Gray @ 2020-01-13 14:28 UTC (permalink / raw)
  To: Andrew Chow, Dmitry Petukhov;  Bitcoin Protocol Discussion

[-- Attachment #1: Type: text/plain, Size: 13163 bytes --]

Thanks for the useful comments guys. I understand where you are
coming from, but my PoV is from the deep embedded side.

On Mon, Jan 13, 2020 at 06:39:28AM +0000, Andrew Chow wrote:
> ... In fact, I'm not quite
> sure what kind of attack you are trying to defend against with this
> proposal.

I don't have a specific attack in mind, but these signatures, if
adopted by the community at large, will allow detection of-, and
could mitigate damage from-, some broad "bug-classes".

Consider if the PSBT Signer (hardware wallet) has bugs. Perhaps if
you tweak the PSBT in some unnatural way it produces output that
reveals the private key (duplicate k-value perhaps), or corrupts
the display of the transaction in helpful (to the attacker) ways
(typically case: output hidden as change).

Seeing a corrupted file signature would alert you of the attempt
to do this. So maybe you don't transmit the transaction, maybe you
warn the user and so on. What happens next is up to you, but at
least we know something is happening.

There could also be bugs in the Combiner/Finalizer which the MiTM
wants to trigger. Legimate files, signed by the PSBT Signer, will not
contain those attacks, so are "safer" to process, even if your
Combiner's PSBT parser has bugs or is tragically dumb.

It's just another layer of security and confidence, on top of the
existing system-level security (which is already excellent).

> If there is a MiTM who can modify your PSBT, then they can just modify
> the result the signed PSBT to drop the auth signatures.

Yes, the MiTM can remove the signatures. However, if your tools expect
and require the signatures in place, then the feature is working
as intended, because the user will be alerted to the funny-business.

More importantly: nothing has been lost by implementing the feature,
and Coldcard (and other PSBT Signers) have to be first to implement it.

> ... then you already
> have a signature there that covers everything your auth signature would
> cover. So just verify those signatures instead; for any inputs with

That's just it, when we receive a signed PSBT, at present we don't
know *what* was signed without a complete understanding of the
transaction, the input UTXO (at least syntactially), and PSBT file
contents.  If there are bugs in that understanding (ie. checks we
all know are needed, but no-one actually implemented) then we might
transmit an harmful transaction, or continue to process a file
that has been corrupted-with-intent by a MiTM.

> Lastly, IMO, if you want MiTM protection, then you should do your
> protection with out of band communication. Just PGP sign the PSBT (or
> something similar) and send the signature along separately.

It's fine to say that, but in an embedded environment, with very
limited memory like the Coldcard, PGP isn't an option (signing vs.
signature verification). I want to leverage the existing crypto and
PKI that we already have in play.

> On 1/11/20 3:17 PM, Dmitry Petukhov via bitcoin-dev wrote:
... [many valid points, repeated by Andrew] ...
> > If there is MitM, checking something at Finalizer is likely too
> > late - the party that can intercept PSBTs can finalize before the
> > legitimate Finalizer and broadcast the transaction.

Yes, that is a problem which is proposal does not address. If the
MitM has control over both directions, in and out, then whatever
he or she was trying to do will still happen. Personally, I'm okay
with that as a limition, but using the same signatures features,
and a pre-shared public key between the PSBT Creator and the Signer,
we could block the Signer from looking at MitM'ed files. (The Signer
would require and verify incoming unsigned PSBT to contain the
last-output-section-signature thing.) I'm not planning on supporting
that on the Coldcard (at least not yet), but with the proposed
additions, it is possible to do without further changes to the PSBT
spec.

> > Participants can work from the same PSBT ...
> > either pass two files (original and updated), or work out which fields
> > (key-value blobs) to remove to get the 'source' PSBT (which might not be
> > trivial with presense of proprietary and unknown fields). Even if you
> > know which key-value pairs to remove, there is no requirement for
> > ordering of the fields, and some signer can serialize them in different
> > order after dserialize/sign/add-signatures/re-serialize operation.
...
> > Introducing additional ordering or other structure requirements over
> > simple key-value structure will add complexity to PSBT processing, and
> > adding complexity on such a basic level should have really serious
> > reasons, because that increases effort required for even basic
> > implementations and increases chance of bugs.

I want these signatures to protect against PSBT parsing bugs. That's
why they are byte-level on the whole file contents, and not based
on sub-sections of the file or various fields inside the file. Yes,
there are non-linear PSBT paths that will be difficult or impossible
to support with this approach. I would not expect implementations to
do anything fancy to reconstruct PSBT contents, I think they would
just track the complete file. In most setups today the Creator,
Combiner and Finalizer are the same device, and they are desktop
systems with gigs of memory.

> > If there is some authority on the 'correctness' of 'original' PSBT
> > (all particpants receive same PSBT at the start), particpants should
> > check the signature by that authority. That authority might use
> > the key used only for authentication, and not in the tx signing.

Yes, this can be acheived by pre-sharing a public key with the
Signer (described above). Only signed incoming PSBT's would be
accepted. That key doesn't have anything to do with the blockchain
or value transfer.

> > I think you do not need to wait for officially-assigned key numbers,
> > and can just implement the scheme you envision with proprietary keys,
> > document and promote it. Then if it shows its usefulness, it will
> > either become de-facto standard with your proprietary keys...

Yes, 100% ... but I value the list's feedback, and I would prefer to
start with a legitimate key number which I don't need to change later. It's
a non-breaking change and I wouldn't propose it otherwise.

---
Peter D. Gray  ||  Founder, Coinkite  ||  Twitter: @dochex  ||  GPG: A3A31BAD 5A2A5B10

On Mon, Jan 13, 2020 at 06:39:28AM +0000, Andrew Chow wrote:
> I agree with Dimitry. I don't see the point of having the MiTM
> protection within the PSBT structure itself, in addition to the fact
> that adding new fields is largely unnecessary. In fact, I'm not quite
> sure what kind of attack you are trying to defend against with this
> proposal.
> 
> If there is a MiTM who can modify your PSBT, then they can just modify
> the result the signed PSBT to drop the auth signatures. Furthermore, any
> modifications to scripts or UTXOs would just result in an invalid
> signature, so only time is wasted. But you'll just waste time anyways
> when you see a failed auth sig.
> 
> Additionally, when a signer processes a PSBT, it will either accept the
> PSBT and add a signature for its inputs, or reject it and do nothing.
> Given this behavior (and I assume you aren't going to add auth sigs for
> rejected PSBTs because that doesn't make any sense), then you already
> have a signature there that covers everything your auth signature would
> cover. So just verify those signatures instead; for any inputs with
> signatures, everything you need to verify them are already there.
> 
> Lastly, IMO, if you want MiTM protection, then you should do your
> protection with out of band communication. Just PGP sign the PSBT (or
> something similar) and send the signature along separately.
> 
> Andrew
> 
> On 1/11/20 3:17 PM, Dmitry Petukhov via bitcoin-dev wrote:
> > 
> > I am not sure that this particular task should be done with data
> > embedded in PSBT itself, and not with some sort of container that
> > includes PSBT and the authentication information.
> > 
> > The benefit seems to be in reusing PSBT structure for compatibilty, and
> > this might be a valid way, although I do not agree with some of your
> > points. I elaborate below:
> > 
> >> 1) In the PSBT globals section, a signature over the "source" PSBT
> >> file. It would cover all the bytes of the original PSBT file, as
> >> it was received by the Signer.
> > 
> > The problem of authenticating the contents of PSBT is independent of
> > the signing action. PSBT might be altered on the path from Creator to
> > Signer. Therefore you cannot always say that Signer will be an
> > authority over 'correctness' of PSBT.
> > 
> >> - At the end of the signing process, the Finalizer should check all
> >> the Signers have worked from the same PSBT file (assuming that's
> >> the flow expected)
> > 
> > If there is MitM, checking something at Finalizer is likely too
> > late - the party that can intercept PSBTs can finalize before the
> > legitimate Finalizer and broadcast the transaction.
> > 
> > Participants can work from the same PSBT file if they all receive the
> > same PSBT, and not working in chain where next particpant receives
> > updated PSBT from the previous participant. Otherwise they will need to
> > either pass two files (original and updated), or work out which fields
> > (key-value blobs) to remove to get the 'source' PSBT (which might not be
> > trivial with presense of proprietary and unknown fields). Even if you
> > know which key-value pairs to remove, there is no requirement for
> > ordering of the fields, and some signer can serialize them in different
> > order after dserialize/sign/add-signatures/re-serialize operation.
> > 
> > Introducing additional ordering or other structure requirements over
> > simple key-value structure will add complexity to PSBT processing, and
> > adding complexity on such a basic level should have really serious
> > reasons, because that increases effort required for even basic
> > implementations and increases chance of bugs.
> > 
> > If there is some authority on the 'correctness' of 'original' PSBT
> > (all particpants receive same PSBT at the start), particpants should
> > check the signature by that authority. That authority might use
> > the key used only for authentication, and not in the tx signing.
> > 
> > If particpants send PSBT in chain after adding their signatures, then
> > each participant can add their signature to say 'the contents
> > of PSBT after my updates should match this hash'.
> > 
> > The signatures of previous participants in the chain most likely do not
> > matter because of difficulty of restoring the contents of PSBT as it
> > was before the previous particpant, if you do not pass _all_ the PSBTs
> > (which is excessive).
> > 
> >> 2) In the output section, specifically, the last key/value pair of
> >> the last output of the transaction, I want to add a similar signature,
> >> again signed by one of the keys used in the signing process. This
> >> signature will cover all the bytes of the resulting (signed) PSBT
> >> up to that point. Because it is the last output of the output
> >> section, that signature will be the last few bytes of the PSBT file.
> >> By "appending" the signature in this way, it's easier to validate
> >> and create the signature, without blanking the signature area during
> >> digest step.
> > 
> > This will introduce unnecessary higher-level structure to PSBT for the
> > reasons that I do not find strong enough for the amount of complexity
> > added.
> > 
> > Also, as I said above, you likely do not need more than one
> > signature - if this is 'fan-out' scheme, then participants need do
> > check the sig of authority that created PSBT; if this is piggy-back
> > chain, then only previous particpant's signature is easily verifiable.
> > 
> >> ## Next Steps
> >>
> >> I'd like to get two officially-assigned BIP-174 key numbers assigned
> >> for these two signatures, and then I will see that it gets added
> >> into Coldcard's firmware immediately. In time, other tools are
> >> welcome to take advantage of these checks. I will also write a BIP
> >> for this, and/or make an addition to BIP-174.
> > 
> > I think you do not need to wait for officially-assigned key numbers,
> > and can just implement the scheme you envision with proprietary keys,
> > document and promote it. Then if it shows its usefulness, it will
> > either become de-facto standard with your proprietary keys (and
> > everyone will want to support 'Coldard PSBT auth' or whatever the name),
> > or the scheme will have serious grounds to be converted to standard and
> > have non-proprietary keys assigned.
> > 
> > // Dmitry.
> > _______________________________________________
> > bitcoin-dev mailing list
> > bitcoin-dev@lists•linuxfoundation.org
> > https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
> > 
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 529 bytes --]

 permalink raw reply	[|nested]
2020-01-13 14:28     ` Peter D. Gray

  2020-01-13 20:29         ` Peter D. Gray
  
From: Andrew Chow @ 2020-01-13 17:05 UTC (permalink / raw)
  To: Peter D. Gray, Dmitry Petukhov;  Bitcoin Protocol Discussion


On 1/13/20 9:28 AM, Peter D. Gray wrote:
> I don't have a specific attack in mind, but these signatures, if
> adopted by the community at large, will allow detection of-, and
> could mitigate damage from-, some broad "bug-classes".
> 
> Consider if the PSBT Signer (hardware wallet) has bugs. Perhaps if
> you tweak the PSBT in some unnatural way it produces output that
> reveals the private key (duplicate k-value perhaps), or corrupts
> the display of the transaction in helpful (to the attacker) ways
> (typically case: output hidden as change).

Since the PSBT is to be signed by one of the Signers for the PSBT, I
don't see how this is useful. If it is mutated and the signer has bugs,
especially parsing bugs, the Signer also adding its signature won't
help. In your proposal, it is the Signer who adds the signature, so it
will receive a PSBT without auth sigs and thus that could be mutated to
trigger those bugs anyways.

> There could also be bugs in the Combiner/Finalizer which the MiTM
> wants to trigger. Legimate files, signed by the PSBT Signer, will not
> contain those attacks, so are "safer" to process, even if your
> Combiner's PSBT parser has bugs or is tragically dumb.

The job of Combiners is fairly limited and is really just related to
parsing the PSBT into some internal object then shuffling those fields
around. In that case, any bugs an attacker would want to exploit have to
be deserialization bugs, in which case, your auth sigs don't help. The
Combiner still has to deserialize the PSBT to get the signature, then it
needs to re-serialize the PSBT to check that signature. An attacker
could insert bad bytes into the PSBT which causes problems during
deserialization, before the Combiner is able to check the signature.

For Finalizers, since its job is to construct the final
scriptSig/scriptWitness, at worst, all it can do is produce an invalid
transaction. Finalizers don't have access to the private keys so there's
no bug possible that can result in a Finalizer producing a transaction
that reveals the private key.

> 
> That's just it, when we receive a signed PSBT, at present we don't
> know *what* was signed without a complete understanding of the
> transaction, the input UTXO (at least syntactially), and PSBT file
> contents.  If there are bugs in that understanding (ie. checks we
> all know are needed, but no-one actually implemented) then we might
> transmit an harmful transaction, or continue to process a file
> that has been corrupted-with-intent by a MiTM.

ISTM the same is true of your proposal. You need to deserialize the PSBT
and then figure out which fields were "original" and in what order. If
there is a bug in your deserialization, an attacker can still exploit
that. And if there is a bug in your reconstruction of "original", you'll
have false positives.

> It's fine to say that, but in an embedded environment, with very
> limited memory like the Coldcard, PGP isn't an option (signing vs.
> signature verification). I want to leverage the existing crypto and
> PKI that we already have in play.

My point was that you can achieve your MiTM protection by having the
signature separate from the PSBT. You can still make your ECDSA
signature and send it along with the PSBT, and you can do it with fixed
or exchanged keys, no need for parsing the PSBT itself. It can be part
of the transport protocol, not part of the data that is being transferred.

Andrew

> 
>> On 1/11/20 3:17 PM, Dmitry Petukhov via bitcoin-dev wrote:
> ... [many valid points, repeated by Andrew] ...
>>> If there is MitM, checking something at Finalizer is likely too
>>> late - the party that can intercept PSBTs can finalize before the
>>> legitimate Finalizer and broadcast the transaction.
> 
> Yes, that is a problem which is proposal does not address. If the
> MitM has control over both directions, in and out, then whatever
> he or she was trying to do will still happen. Personally, I'm okay
> with that as a limition, but using the same signatures features,
> and a pre-shared public key between the PSBT Creator and the Signer,
> we could block the Signer from looking at MitM'ed files. (The Signer
> would require and verify incoming unsigned PSBT to contain the
> last-output-section-signature thing.) I'm not planning on supporting
> that on the Coldcard (at least not yet), but with the proposed
> additions, it is possible to do without further changes to the PSBT
> spec.
> 
>>> Participants can work from the same PSBT ...
>>> either pass two files (original and updated), or work out which fields
>>> (key-value blobs) to remove to get the 'source' PSBT (which might not be
>>> trivial with presense of proprietary and unknown fields). Even if you
>>> know which key-value pairs to remove, there is no requirement for
>>> ordering of the fields, and some signer can serialize them in different
>>> order after dserialize/sign/add-signatures/re-serialize operation.
> ...
>>> Introducing additional ordering or other structure requirements over
>>> simple key-value structure will add complexity to PSBT processing, and
>>> adding complexity on such a basic level should have really serious
>>> reasons, because that increases effort required for even basic
>>> implementations and increases chance of bugs.
> 
> I want these signatures to protect against PSBT parsing bugs. That's
> why they are byte-level on the whole file contents, and not based
> on sub-sections of the file or various fields inside the file. Yes,
> there are non-linear PSBT paths that will be difficult or impossible
> to support with this approach. I would not expect implementations to
> do anything fancy to reconstruct PSBT contents, I think they would
> just track the complete file. In most setups today the Creator,
> Combiner and Finalizer are the same device, and they are desktop
> systems with gigs of memory.
> 
>>> If there is some authority on the 'correctness' of 'original' PSBT
>>> (all particpants receive same PSBT at the start), particpants should
>>> check the signature by that authority. That authority might use
>>> the key used only for authentication, and not in the tx signing.
> 
> Yes, this can be acheived by pre-sharing a public key with the
> Signer (described above). Only signed incoming PSBT's would be
> accepted. That key doesn't have anything to do with the blockchain
> or value transfer.
> 
>>> I think you do not need to wait for officially-assigned key numbers,
>>> and can just implement the scheme you envision with proprietary keys,
>>> document and promote it. Then if it shows its usefulness, it will
>>> either become de-facto standard with your proprietary keys...
> 
> Yes, 100% ... but I value the list's feedback, and I would prefer to
> start with a legitimate key number which I don't need to change later. It's
> a non-breaking change and I wouldn't propose it otherwise.
> 
> ---
> Peter D. Gray  ||  Founder, Coinkite  ||  Twitter: @dochex  ||  GPG: A3A31BAD 5A2A5B10
> 
> On Mon, Jan 13, 2020 at 06:39:28AM +0000, Andrew Chow wrote:
>> I agree with Dimitry. I don't see the point of having the MiTM
>> protection within the PSBT structure itself, in addition to the fact
>> that adding new fields is largely unnecessary. In fact, I'm not quite
>> sure what kind of attack you are trying to defend against with this
>> proposal.
>>
>> If there is a MiTM who can modify your PSBT, then they can just modify
>> the result the signed PSBT to drop the auth signatures. Furthermore, any
>> modifications to scripts or UTXOs would just result in an invalid
>> signature, so only time is wasted. But you'll just waste time anyways
>> when you see a failed auth sig.
>>
>> Additionally, when a signer processes a PSBT, it will either accept the
>> PSBT and add a signature for its inputs, or reject it and do nothing.
>> Given this behavior (and I assume you aren't going to add auth sigs for
>> rejected PSBTs because that doesn't make any sense), then you already
>> have a signature there that covers everything your auth signature would
>> cover. So just verify those signatures instead; for any inputs with
>> signatures, everything you need to verify them are already there.
>>
>> Lastly, IMO, if you want MiTM protection, then you should do your
>> protection with out of band communication. Just PGP sign the PSBT (or
>> something similar) and send the signature along separately.
>>
>> Andrew
>>
>> On 1/11/20 3:17 PM, Dmitry Petukhov via bitcoin-dev wrote:
>>>
>>> I am not sure that this particular task should be done with data
>>> embedded in PSBT itself, and not with some sort of container that
>>> includes PSBT and the authentication information.
>>>
>>> The benefit seems to be in reusing PSBT structure for compatibilty, and
>>> this might be a valid way, although I do not agree with some of your
>>> points. I elaborate below:
>>>
>>>> 1) In the PSBT globals section, a signature over the "source" PSBT
>>>> file. It would cover all the bytes of the original PSBT file, as
>>>> it was received by the Signer.
>>>
>>> The problem of authenticating the contents of PSBT is independent of
>>> the signing action. PSBT might be altered on the path from Creator to
>>> Signer. Therefore you cannot always say that Signer will be an
>>> authority over 'correctness' of PSBT.
>>>
>>>> - At the end of the signing process, the Finalizer should check all
>>>> the Signers have worked from the same PSBT file (assuming that's
>>>> the flow expected)
>>>
>>> If there is MitM, checking something at Finalizer is likely too
>>> late - the party that can intercept PSBTs can finalize before the
>>> legitimate Finalizer and broadcast the transaction.
>>>
>>> Participants can work from the same PSBT file if they all receive the
>>> same PSBT, and not working in chain where next particpant receives
>>> updated PSBT from the previous participant. Otherwise they will need to
>>> either pass two files (original and updated), or work out which fields
>>> (key-value blobs) to remove to get the 'source' PSBT (which might not be
>>> trivial with presense of proprietary and unknown fields). Even if you
>>> know which key-value pairs to remove, there is no requirement for
>>> ordering of the fields, and some signer can serialize them in different
>>> order after dserialize/sign/add-signatures/re-serialize operation.
>>>
>>> Introducing additional ordering or other structure requirements over
>>> simple key-value structure will add complexity to PSBT processing, and
>>> adding complexity on such a basic level should have really serious
>>> reasons, because that increases effort required for even basic
>>> implementations and increases chance of bugs.
>>>
>>> If there is some authority on the 'correctness' of 'original' PSBT
>>> (all particpants receive same PSBT at the start), particpants should
>>> check the signature by that authority. That authority might use
>>> the key used only for authentication, and not in the tx signing.
>>>
>>> If particpants send PSBT in chain after adding their signatures, then
>>> each participant can add their signature to say 'the contents
>>> of PSBT after my updates should match this hash'.
>>>
>>> The signatures of previous participants in the chain most likely do not
>>> matter because of difficulty of restoring the contents of PSBT as it
>>> was before the previous particpant, if you do not pass _all_ the PSBTs
>>> (which is excessive).
>>>
>>>> 2) In the output section, specifically, the last key/value pair of
>>>> the last output of the transaction, I want to add a similar signature,
>>>> again signed by one of the keys used in the signing process. This
>>>> signature will cover all the bytes of the resulting (signed) PSBT
>>>> up to that point. Because it is the last output of the output
>>>> section, that signature will be the last few bytes of the PSBT file.
>>>> By "appending" the signature in this way, it's easier to validate
>>>> and create the signature, without blanking the signature area during
>>>> digest step.
>>>
>>> This will introduce unnecessary higher-level structure to PSBT for the
>>> reasons that I do not find strong enough for the amount of complexity
>>> added.
>>>
>>> Also, as I said above, you likely do not need more than one
>>> signature - if this is 'fan-out' scheme, then participants need do
>>> check the sig of authority that created PSBT; if this is piggy-back
>>> chain, then only previous particpant's signature is easily verifiable.
>>>
>>>> ## Next Steps
>>>>
>>>> I'd like to get two officially-assigned BIP-174 key numbers assigned
>>>> for these two signatures, and then I will see that it gets added
>>>> into Coldcard's firmware immediately. In time, other tools are
>>>> welcome to take advantage of these checks. I will also write a BIP
>>>> for this, and/or make an addition to BIP-174.
>>>
>>> I think you do not need to wait for officially-assigned key numbers,
>>> and can just implement the scheme you envision with proprietary keys,
>>> document and promote it. Then if it shows its usefulness, it will
>>> either become de-facto standard with your proprietary keys (and
>>> everyone will want to support 'Coldard PSBT auth' or whatever the name),
>>> or the scheme will have serious grounds to be converted to standard and
>>> have non-proprietary keys assigned.
>>>
>>> // Dmitry.
>>> _______________________________________________
>>> bitcoin-dev mailing list
>>> bitcoin-dev@lists•linuxfoundation.org
>>> https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
>>>



 permalink raw reply	[|nested]
2020-01-13 17:05       ` Andrew Chow

  2020-01-13 23:18           ` Andrew Chow
  
From: Peter D. Gray @ 2020-01-13 20:29 UTC (permalink / raw)
  To: Andrew Chow;  Bitcoin Protocol Discussion

> In your proposal, it is the Signer who adds the signature, so it
> will receive a PSBT without auth sigs and thus that could be mutated to
> trigger those bugs anyways.

The Signer may be signing a PSBT that was corrupted by the MitM,
but at least later users of the signed PSBT can detect that occured.
At present, they do not know what the input PSBT content was when
it got to the Signer.

> ... The Combiner still has to deserialize the PSBT to get the signature, then it
> needs to re-serialize the PSBT to check that signature. 

If we use a fixed-width signature, such as just R+S bytes (64 bytes),
and not DER-encoding, then the signature is a fixed distance from
the last byte of the file. A conservative PSBT parser could start
by verifying the signature exists and is valid, before parsing the
rest of the file. (It would need to use the pubkeys from the original
PSBT, which it would ideally have on-hand already to verify the source
PSBT to the Coldcard.)

> For Finalizers, since its job is to construct the final
> scriptSig/scriptWitness, at worst, all it can do is produce an invalid
> transaction. Finalizers don't have access to the private keys so there's
> no bug possible that can result in a Finalizer producing a transaction
> that reveals the private key.

I agree that Finalizers cannot access the Bitcoin private keys, but
they still have stacks that can overflow, buffers that can be overrun
and so on. Perhaps if sighash is not SIGHASH_ALL, there are dangerous
things they can be tricked into... I don't know, but at least we
should make it possible to detect these cases. My goal is detection.

> ISTM the same is true of your proposal. You need to deserialize the PSBT
> and then figure out which fields were "original" and in what order. If
> there is a bug in your deserialization, an attacker can still exploit
> that. And if there is a bug in your reconstruction of "original", you'll
> have false positives.

No, I am not proposing anyone re-construct PSBT's... My proposal
is really only helpful if you have the full original PSBT on hand
(or its digest). For ultimate safety I would recommend checking the
incoming PSBT's signature is valid before parsing it.(If the
signature is fixed-length, see above.)

> My point was that you can achieve your MiTM protection by having the
> signature separate from the PSBT. You can still make your ECDSA
> signature and send it along with the PSBT, and you can do it with fixed
> or exchanged keys, no need for parsing the PSBT itself. It can be part
> of the transport protocol, not part of the data that is being transferred.

In the USB protocol between Coldcard and desktop, we do end-to-end
encryption with a session key picked via diff-hel so we're doing
our best there against MitM. However, our customers love the air-gap
feature which involves lots of sneakernet handling of MicroSD cards.
I don't want to force them into handling paired files, like detacted
signatures, and I was hoping this would be a good way to move the
signatures inside the PSBT files already being moved about.

---
Peter D. Gray  ||  Founder, Coinkite  ||  Twitter: @dochex  ||  GPG: A3A31BAD 5A2A5B10

On Mon, Jan 13, 2020 at 05:05:10PM +0000, Andrew Chow wrote:
> 
> On 1/13/20 9:28 AM, Peter D. Gray wrote:
> > I don't have a specific attack in mind, but these signatures, if
> > adopted by the community at large, will allow detection of-, and
> > could mitigate damage from-, some broad "bug-classes".
> > 
> > Consider if the PSBT Signer (hardware wallet) has bugs. Perhaps if
> > you tweak the PSBT in some unnatural way it produces output that
> > reveals the private key (duplicate k-value perhaps), or corrupts
> > the display of the transaction in helpful (to the attacker) ways
> > (typically case: output hidden as change).
> 
> Since the PSBT is to be signed by one of the Signers for the PSBT, I
> don't see how this is useful. If it is mutated and the signer has bugs,
> especially parsing bugs, the Signer also adding its signature won't
> help. In your proposal, it is the Signer who adds the signature, so it
> will receive a PSBT without auth sigs and thus that could be mutated to
> trigger those bugs anyways.
> 
> > There could also be bugs in the Combiner/Finalizer which the MiTM
> > wants to trigger. Legimate files, signed by the PSBT Signer, will not
> > contain those attacks, so are "safer" to process, even if your
> > Combiner's PSBT parser has bugs or is tragically dumb.
> 
> The job of Combiners is fairly limited and is really just related to
> parsing the PSBT into some internal object then shuffling those fields
> around. In that case, any bugs an attacker would want to exploit have to
> be deserialization bugs, in which case, your auth sigs don't help. The
> Combiner still has to deserialize the PSBT to get the signature, then it
> needs to re-serialize the PSBT to check that signature. An attacker
> could insert bad bytes into the PSBT which causes problems during
> deserialization, before the Combiner is able to check the signature.
> 
> For Finalizers, since its job is to construct the final
> scriptSig/scriptWitness, at worst, all it can do is produce an invalid
> transaction. Finalizers don't have access to the private keys so there's
> no bug possible that can result in a Finalizer producing a transaction
> that reveals the private key.
> 
> > 
> > That's just it, when we receive a signed PSBT, at present we don't
> > know *what* was signed without a complete understanding of the
> > transaction, the input UTXO (at least syntactially), and PSBT file
> > contents.  If there are bugs in that understanding (ie. checks we
> > all know are needed, but no-one actually implemented) then we might
> > transmit an harmful transaction, or continue to process a file
> > that has been corrupted-with-intent by a MiTM.
> 
> ISTM the same is true of your proposal. You need to deserialize the PSBT
> and then figure out which fields were "original" and in what order. If
> there is a bug in your deserialization, an attacker can still exploit
> that. And if there is a bug in your reconstruction of "original", you'll
> have false positives.
> 
> > It's fine to say that, but in an embedded environment, with very
> > limited memory like the Coldcard, PGP isn't an option (signing vs.
> > signature verification). I want to leverage the existing crypto and
> > PKI that we already have in play.
> 
> My point was that you can achieve your MiTM protection by having the
> signature separate from the PSBT. You can still make your ECDSA
> signature and send it along with the PSBT, and you can do it with fixed
> or exchanged keys, no need for parsing the PSBT itself. It can be part
> of the transport protocol, not part of the data that is being transferred.
> 
> Andrew
> 
> > 
> >> On 1/11/20 3:17 PM, Dmitry Petukhov via bitcoin-dev wrote:
> > ... [many valid points, repeated by Andrew] ...
> >>> If there is MitM, checking something at Finalizer is likely too
> >>> late - the party that can intercept PSBTs can finalize before the
> >>> legitimate Finalizer and broadcast the transaction.
> > 
> > Yes, that is a problem which is proposal does not address. If the
> > MitM has control over both directions, in and out, then whatever
> > he or she was trying to do will still happen. Personally, I'm okay
> > with that as a limition, but using the same signatures features,
> > and a pre-shared public key between the PSBT Creator and the Signer,
> > we could block the Signer from looking at MitM'ed files. (The Signer
> > would require and verify incoming unsigned PSBT to contain the
> > last-output-section-signature thing.) I'm not planning on supporting
> > that on the Coldcard (at least not yet), but with the proposed
> > additions, it is possible to do without further changes to the PSBT
> > spec.
> > 
> >>> Participants can work from the same PSBT ...
> >>> either pass two files (original and updated), or work out which fields
> >>> (key-value blobs) to remove to get the 'source' PSBT (which might not be
> >>> trivial with presense of proprietary and unknown fields). Even if you
> >>> know which key-value pairs to remove, there is no requirement for
> >>> ordering of the fields, and some signer can serialize them in different
> >>> order after dserialize/sign/add-signatures/re-serialize operation.
> > ...
> >>> Introducing additional ordering or other structure requirements over
> >>> simple key-value structure will add complexity to PSBT processing, and
> >>> adding complexity on such a basic level should have really serious
> >>> reasons, because that increases effort required for even basic
> >>> implementations and increases chance of bugs.
> > 
> > I want these signatures to protect against PSBT parsing bugs. That's
> > why they are byte-level on the whole file contents, and not based
> > on sub-sections of the file or various fields inside the file. Yes,
> > there are non-linear PSBT paths that will be difficult or impossible
> > to support with this approach. I would not expect implementations to
> > do anything fancy to reconstruct PSBT contents, I think they would
> > just track the complete file. In most setups today the Creator,
> > Combiner and Finalizer are the same device, and they are desktop
> > systems with gigs of memory.
> > 
> >>> If there is some authority on the 'correctness' of 'original' PSBT
> >>> (all particpants receive same PSBT at the start), particpants should
> >>> check the signature by that authority. That authority might use
> >>> the key used only for authentication, and not in the tx signing.
> > 
> > Yes, this can be acheived by pre-sharing a public key with the
> > Signer (described above). Only signed incoming PSBT's would be
> > accepted. That key doesn't have anything to do with the blockchain
> > or value transfer.
> > 
> >>> I think you do not need to wait for officially-assigned key numbers,
> >>> and can just implement the scheme you envision with proprietary keys,
> >>> document and promote it. Then if it shows its usefulness, it will
> >>> either become de-facto standard with your proprietary keys...
> > 
> > Yes, 100% ... but I value the list's feedback, and I would prefer to
> > start with a legitimate key number which I don't need to change later. It's
> > a non-breaking change and I wouldn't propose it otherwise.
> > 
> > ---
> > Peter D. Gray  ||  Founder, Coinkite  ||  Twitter: @dochex  ||  GPG: A3A31BAD 5A2A5B10
> > 
> > On Mon, Jan 13, 2020 at 06:39:28AM +0000, Andrew Chow wrote:
> >> I agree with Dimitry. I don't see the point of having the MiTM
> >> protection within the PSBT structure itself, in addition to the fact
> >> that adding new fields is largely unnecessary. In fact, I'm not quite
> >> sure what kind of attack you are trying to defend against with this
> >> proposal.
> >>
> >> If there is a MiTM who can modify your PSBT, then they can just modify
> >> the result the signed PSBT to drop the auth signatures. Furthermore, any
> >> modifications to scripts or UTXOs would just result in an invalid
> >> signature, so only time is wasted. But you'll just waste time anyways
> >> when you see a failed auth sig.
> >>
> >> Additionally, when a signer processes a PSBT, it will either accept the
> >> PSBT and add a signature for its inputs, or reject it and do nothing.
> >> Given this behavior (and I assume you aren't going to add auth sigs for
> >> rejected PSBTs because that doesn't make any sense), then you already
> >> have a signature there that covers everything your auth signature would
> >> cover. So just verify those signatures instead; for any inputs with
> >> signatures, everything you need to verify them are already there.
> >>
> >> Lastly, IMO, if you want MiTM protection, then you should do your
> >> protection with out of band communication. Just PGP sign the PSBT (or
> >> something similar) and send the signature along separately.
> >>
> >> Andrew
> >>
> >> On 1/11/20 3:17 PM, Dmitry Petukhov via bitcoin-dev wrote:
> >>>
> >>> I am not sure that this particular task should be done with data
> >>> embedded in PSBT itself, and not with some sort of container that
> >>> includes PSBT and the authentication information.
> >>>
> >>> The benefit seems to be in reusing PSBT structure for compatibilty, and
> >>> this might be a valid way, although I do not agree with some of your
> >>> points. I elaborate below:
> >>>
> >>>> 1) In the PSBT globals section, a signature over the "source" PSBT
> >>>> file. It would cover all the bytes of the original PSBT file, as
> >>>> it was received by the Signer.
> >>>
> >>> The problem of authenticating the contents of PSBT is independent of
> >>> the signing action. PSBT might be altered on the path from Creator to
> >>> Signer. Therefore you cannot always say that Signer will be an
> >>> authority over 'correctness' of PSBT.
> >>>
> >>>> - At the end of the signing process, the Finalizer should check all
> >>>> the Signers have worked from the same PSBT file (assuming that's
> >>>> the flow expected)
> >>>
> >>> If there is MitM, checking something at Finalizer is likely too
> >>> late - the party that can intercept PSBTs can finalize before the
> >>> legitimate Finalizer and broadcast the transaction.
> >>>
> >>> Participants can work from the same PSBT file if they all receive the
> >>> same PSBT, and not working in chain where next particpant receives
> >>> updated PSBT from the previous participant. Otherwise they will need to
> >>> either pass two files (original and updated), or work out which fields
> >>> (key-value blobs) to remove to get the 'source' PSBT (which might not be
> >>> trivial with presense of proprietary and unknown fields). Even if you
> >>> know which key-value pairs to remove, there is no requirement for
> >>> ordering of the fields, and some signer can serialize them in different
> >>> order after dserialize/sign/add-signatures/re-serialize operation.
> >>>
> >>> Introducing additional ordering or other structure requirements over
> >>> simple key-value structure will add complexity to PSBT processing, and
> >>> adding complexity on such a basic level should have really serious
> >>> reasons, because that increases effort required for even basic
> >>> implementations and increases chance of bugs.
> >>>
> >>> If there is some authority on the 'correctness' of 'original' PSBT
> >>> (all particpants receive same PSBT at the start), particpants should
> >>> check the signature by that authority. That authority might use
> >>> the key used only for authentication, and not in the tx signing.
> >>>
> >>> If particpants send PSBT in chain after adding their signatures, then
> >>> each participant can add their signature to say 'the contents
> >>> of PSBT after my updates should match this hash'.
> >>>
> >>> The signatures of previous participants in the chain most likely do not
> >>> matter because of difficulty of restoring the contents of PSBT as it
> >>> was before the previous particpant, if you do not pass _all_ the PSBTs
> >>> (which is excessive).
> >>>
> >>>> 2) In the output section, specifically, the last key/value pair of
> >>>> the last output of the transaction, I want to add a similar signature,
> >>>> again signed by one of the keys used in the signing process. This
> >>>> signature will cover all the bytes of the resulting (signed) PSBT
> >>>> up to that point. Because it is the last output of the output
> >>>> section, that signature will be the last few bytes of the PSBT file.
> >>>> By "appending" the signature in this way, it's easier to validate
> >>>> and create the signature, without blanking the signature area during
> >>>> digest step.
> >>>
> >>> This will introduce unnecessary higher-level structure to PSBT for the
> >>> reasons that I do not find strong enough for the amount of complexity
> >>> added.
> >>>
> >>> Also, as I said above, you likely do not need more than one
> >>> signature - if this is 'fan-out' scheme, then participants need do
> >>> check the sig of authority that created PSBT; if this is piggy-back
> >>> chain, then only previous particpant's signature is easily verifiable.
> >>>
> >>>> ## Next Steps
> >>>>
> >>>> I'd like to get two officially-assigned BIP-174 key numbers assigned
> >>>> for these two signatures, and then I will see that it gets added
> >>>> into Coldcard's firmware immediately. In time, other tools are
> >>>> welcome to take advantage of these checks. I will also write a BIP
> >>>> for this, and/or make an addition to BIP-174.
> >>>
> >>> I think you do not need to wait for officially-assigned key numbers,
> >>> and can just implement the scheme you envision with proprietary keys,
> >>> document and promote it. Then if it shows its usefulness, it will
> >>> either become de-facto standard with your proprietary keys (and
> >>> everyone will want to support 'Coldard PSBT auth' or whatever the name),
> >>> or the scheme will have serious grounds to be converted to standard and
> >>> have non-proprietary keys assigned.
> >>>
> >>> // Dmitry.
> >>> _______________________________________________
> >>> bitcoin-dev mailing list
> >>> bitcoin-dev@lists•linuxfoundation.org
> >>> https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
> >>>
> 


 permalink raw reply	[|nested]
2020-01-13 20:29         ` Peter D. Gray

  
From: Andrew Chow @ 2020-01-13 23:18 UTC ( / )
  To: Peter Gray;  Bitcoin Protocol Discussion

On 1/13/20 3:29 PM, Peter D. Gray wrote:
> The Signer may be signing a PSBT that was corrupted by the MitM,
> but at least later users of the signed PSBT can detect that occured.
> At present, they do not know what the input PSBT content was when
> it got to the Signer.

But the MiTM on the way to the other roles will still see that signed
PSBT, and if the Signer has produced a signature such that someone can
get the private key, that MiTM will have the private key before the
transaction is broadcast. If this isn't part of your threat model, I
think it should be; I don't think it is reasonable to say that you are
only protecting against MiTM for one specific leg of the entire protocol.

> If we use a fixed-width signature, such as just R+S bytes (64 bytes),
> and not DER-encoding, then the signature is a fixed distance from
> the last byte of the file. A conservative PSBT parser could start
> by verifying the signature exists and is valid, before parsing the
> rest of the file. (It would need to use the pubkeys from the original
> PSBT, which it would ideally have on-hand already to verify the source
> PSBT to the Coldcard.)

Why the end? This brings up a particular implementation detail I didn't
want to get into since I was opposing the idea conceptually, but I don't
think that 2 new types are necessary. We absolutely do not need nor
should we have any global data (and the auth sig is absolutely global
data) in input or output specific fields. The outputs really should be
independent of the other inputs and outputs. So having the last output
have the signature is a layer violation.

Why put it at the end? If you want a byte offset, just put the signature
in the globals as the first kv pair.

> I agree that Finalizers cannot access the Bitcoin private keys, but
> they still have stacks that can overflow, buffers that can be overrun
> and so on. Perhaps if sighash is not SIGHASH_ALL, there are dangerous
> things they can be tricked into... I don't know, but at least we
> should make it possible to detect these cases. My goal is detection.

But that shouldn't matter to the Finalizer. It isn't the Finalizer's job
to enforce that the Signers followed a specific signing policy. If the
Signer chose to sign with a "dangerous policy", that's up to the signer
and the Finalizers shouldn't have anything to do with that.

> No, I am not proposing anyone re-construct PSBT's... My proposal
> is really only helpful if you have the full original PSBT on hand
> (or its digest). For ultimate safety I would recommend checking the
> incoming PSBT's signature is valid before parsing it.(If the
> signature is fixed-length, see above.)

That's another thing I don't understand about your proposal. Your
signature covers the "Original PSBT" which is really nebulous and could
anything. This doesn't make sense to me. Everyone has to somehow get the
same "Original PSBT" so you are assuming there's no MiTM in that initial
distribution (seems like an oversight in your threat model).

But then your "Original PSBT" can also be in a number of different
states, and your signature wouldn't cover some things. For example, the
"Original" could have just some of the UTXOs and some of the scripts,
not everything. So in later steps of the process, the MiTM protection
doesn't cover those things, so an attacker could modify them with no
effect on the signature.

> In the USB protocol between Coldcard and desktop, we do end-to-end
> encryption with a session key picked via diff-hel so we're doing
> our best there against MitM. However, our customers love the air-gap
> feature which involves lots of sneakernet handling of MicroSD cards.
> I don't want to force them into handling paired files, like detacted
> signatures, and I was hoping this would be a good way to move the
> signatures inside the PSBT files already being moved about.

You could put them in an archive (tarfile) so it's still just one file
being copied from the SD card. You already have archive creation on the
coldcard for backup creation anyways.

***

I guess what I don't get about this proposal is your threat model and
what specifically you are protecting against. It seems like this is only
protecting against the specific leg from a specific combined
Updater/Finalizer to and from its respective Signer. But this is not
always the use case and this isn't very generic. Other places that there
could be MiTM aren't covered.

I also don't get what a MiTM could even do. If your parser is vulnerable
to the standard programming vulns (buffer overflows, stack overflows,
etc.), ISTM you will still run into those with just a normal PSBT. If
you don't, then a MiTM can't trigger one there. And likewise for
signature issues; if your signer might produce a private key leaking
signature, then it will probably do that with a non-MiTM'd PSBT, and if
not, MiTM isn't going to change that.

Andrew

> 
> ---
> Peter D. Gray  ||  Founder, Coinkite  ||  Twitter: @dochex  ||  GPG: A3A31BAD 5A2A5B10
> 
> On Mon, Jan 13, 2020 at 05:05:10PM +0000, Andrew Chow wrote:
>>
>> On 1/13/20 9:28 AM, Peter D. Gray wrote:
>>> I don't have a specific attack in mind, but these signatures, if
>>> adopted by the community at large, will allow detection of-, and
>>> could mitigate damage from-, some broad "bug-classes".
>>>
>>> Consider if the PSBT Signer (hardware wallet) has bugs. Perhaps if
>>> you tweak the PSBT in some unnatural way it produces output that
>>> reveals the private key (duplicate k-value perhaps), or corrupts
>>> the display of the transaction in helpful (to the attacker) ways
>>> (typically case: output hidden as change).
>>
>> Since the PSBT is to be signed by one of the Signers for the PSBT, I
>> don't see how this is useful. If it is mutated and the signer has bugs,
>> especially parsing bugs, the Signer also adding its signature won't
>> help. In your proposal, it is the Signer who adds the signature, so it
>> will receive a PSBT without auth sigs and thus that could be mutated to
>> trigger those bugs anyways.
>>
>>> There could also be bugs in the Combiner/Finalizer which the MiTM
>>> wants to trigger. Legimate files, signed by the PSBT Signer, will not
>>> contain those attacks, so are "safer" to process, even if your
>>> Combiner's PSBT parser has bugs or is tragically dumb.
>>
>> The job of Combiners is fairly limited and is really just related to
>> parsing the PSBT into some internal object then shuffling those fields
>> around. In that case, any bugs an attacker would want to exploit have to
>> be deserialization bugs, in which case, your auth sigs don't help. The
>> Combiner still has to deserialize the PSBT to get the signature, then it
>> needs to re-serialize the PSBT to check that signature. An attacker
>> could insert bad bytes into the PSBT which causes problems during
>> deserialization, before the Combiner is able to check the signature.
>>
>> For Finalizers, since its job is to construct the final
>> scriptSig/scriptWitness, at worst, all it can do is produce an invalid
>> transaction. Finalizers don't have access to the private keys so there's
>> no bug possible that can result in a Finalizer producing a transaction
>> that reveals the private key.
>>
>>>
>>> That's just it, when we receive a signed PSBT, at present we don't
>>> know *what* was signed without a complete understanding of the
>>> transaction, the input UTXO (at least syntactially), and PSBT file
>>> contents.  If there are bugs in that understanding (ie. checks we
>>> all know are needed, but no-one actually implemented) then we might
>>> transmit an harmful transaction, or continue to process a file
>>> that has been corrupted-with-intent by a MiTM.
>>
>> ISTM the same is true of your proposal. You need to deserialize the PSBT
>> and then figure out which fields were "original" and in what order. If
>> there is a bug in your deserialization, an attacker can still exploit
>> that. And if there is a bug in your reconstruction of "original", you'll
>> have false positives.
>>
>>> It's fine to say that, but in an embedded environment, with very
>>> limited memory like the Coldcard, PGP isn't an option (signing vs.
>>> signature verification). I want to leverage the existing crypto and
>>> PKI that we already have in play.
>>
>> My point was that you can achieve your MiTM protection by having the
>> signature separate from the PSBT. You can still make your ECDSA
>> signature and send it along with the PSBT, and you can do it with fixed
>> or exchanged keys, no need for parsing the PSBT itself. It can be part
>> of the transport protocol, not part of the data that is being transferred.
>>
>> Andrew
>>
>>>
>>>> On 1/11/20 3:17 PM, Dmitry Petukhov via bitcoin-dev wrote:
>>> ... [many valid points, repeated by Andrew] ...
>>>>> If there is MitM, checking something at Finalizer is likely too
>>>>> late - the party that can intercept PSBTs can finalize before the
>>>>> legitimate Finalizer and broadcast the transaction.
>>>
>>> Yes, that is a problem which is proposal does not address. If the
>>> MitM has control over both directions, in and out, then whatever
>>> he or she was trying to do will still happen. Personally, I'm okay
>>> with that as a limition, but using the same signatures features,
>>> and a pre-shared public key between the PSBT Creator and the Signer,
>>> we could block the Signer from looking at MitM'ed files. (The Signer
>>> would require and verify incoming unsigned PSBT to contain the
>>> last-output-section-signature thing.) I'm not planning on supporting
>>> that on the Coldcard (at least not yet), but with the proposed
>>> additions, it is possible to do without further changes to the PSBT
>>> spec.
>>>
>>>>> Participants can work from the same PSBT ...
>>>>> either pass two files (original and updated), or work out which fields
>>>>> (key-value blobs) to remove to get the 'source' PSBT (which might not be
>>>>> trivial with presense of proprietary and unknown fields). Even if you
>>>>> know which key-value pairs to remove, there is no requirement for
>>>>> ordering of the fields, and some signer can serialize them in different
>>>>> order after dserialize/sign/add-signatures/re-serialize operation.
>>> ...
>>>>> Introducing additional ordering or other structure requirements over
>>>>> simple key-value structure will add complexity to PSBT processing, and
>>>>> adding complexity on such a basic level should have really serious
>>>>> reasons, because that increases effort required for even basic
>>>>> implementations and increases chance of bugs.
>>>
>>> I want these signatures to protect against PSBT parsing bugs. That's
>>> why they are byte-level on the whole file contents, and not based
>>> on sub-sections of the file or various fields inside the file. Yes,
>>> there are non-linear PSBT paths that will be difficult or impossible
>>> to support with this approach. I would not expect implementations to
>>> do anything fancy to reconstruct PSBT contents, I think they would
>>> just track the complete file. In most setups today the Creator,
>>> Combiner and Finalizer are the same device, and they are desktop
>>> systems with gigs of memory.
>>>
>>>>> If there is some authority on the 'correctness' of 'original' PSBT
>>>>> (all particpants receive same PSBT at the start), particpants should
>>>>> check the signature by that authority. That authority might use
>>>>> the key used only for authentication, and not in the tx signing.
>>>
>>> Yes, this can be acheived by pre-sharing a public key with the
>>> Signer (described above). Only signed incoming PSBT's would be
>>> accepted. That key doesn't have anything to do with the blockchain
>>> or value transfer.
>>>
>>>>> I think you do not need to wait for officially-assigned key numbers,
>>>>> and can just implement the scheme you envision with proprietary keys,
>>>>> document and promote it. Then if it shows its usefulness, it will
>>>>> either become de-facto standard with your proprietary keys...
>>>
>>> Yes, 100% ... but I value the list's feedback, and I would prefer to
>>> start with a legitimate key number which I don't need to change later. It's
>>> a non-breaking change and I wouldn't propose it otherwise.
>>>
>>> ---
>>> Peter D. Gray  ||  Founder, Coinkite  ||  Twitter: @dochex  ||  GPG: A3A31BAD 5A2A5B10
>>>
>>> On Mon, Jan 13, 2020 at 06:39:28AM +0000, Andrew Chow wrote:
>>>> I agree with Dimitry. I don't see the point of having the MiTM
>>>> protection within the PSBT structure itself, in addition to the fact
>>>> that adding new fields is largely unnecessary. In fact, I'm not quite
>>>> sure what kind of attack you are trying to defend against with this
>>>> proposal.
>>>>
>>>> If there is a MiTM who can modify your PSBT, then they can just modify
>>>> the result the signed PSBT to drop the auth signatures. Furthermore, any
>>>> modifications to scripts or UTXOs would just result in an invalid
>>>> signature, so only time is wasted. But you'll just waste time anyways
>>>> when you see a failed auth sig.
>>>>
>>>> Additionally, when a signer processes a PSBT, it will either accept the
>>>> PSBT and add a signature for its inputs, or reject it and do nothing.
>>>> Given this behavior (and I assume you aren't going to add auth sigs for
>>>> rejected PSBTs because that doesn't make any sense), then you already
>>>> have a signature there that covers everything your auth signature would
>>>> cover. So just verify those signatures instead; for any inputs with
>>>> signatures, everything you need to verify them are already there.
>>>>
>>>> Lastly, IMO, if you want MiTM protection, then you should do your
>>>> protection with out of band communication. Just PGP sign the PSBT (or
>>>> something similar) and send the signature along separately.
>>>>
>>>> Andrew
>>>>
>>>> On 1/11/20 3:17 PM, Dmitry Petukhov via bitcoin-dev wrote:
>>>>>
>>>>> I am not sure that this particular task should be done with data
>>>>> embedded in PSBT itself, and not with some sort of container that
>>>>> includes PSBT and the authentication information.
>>>>>
>>>>> The benefit seems to be in reusing PSBT structure for compatibilty, and
>>>>> this might be a valid way, although I do not agree with some of your
>>>>> points. I elaborate below:
>>>>>
>>>>>> 1) In the PSBT globals section, a signature over the "source" PSBT
>>>>>> file. It would cover all the bytes of the original PSBT file, as
>>>>>> it was received by the Signer.
>>>>>
>>>>> The problem of authenticating the contents of PSBT is independent of
>>>>> the signing action. PSBT might be altered on the path from Creator to
>>>>> Signer. Therefore you cannot always say that Signer will be an
>>>>> authority over 'correctness' of PSBT.
>>>>>
>>>>>> - At the end of the signing process, the Finalizer should check all
>>>>>> the Signers have worked from the same PSBT file (assuming that's
>>>>>> the flow expected)
>>>>>
>>>>> If there is MitM, checking something at Finalizer is likely too
>>>>> late - the party that can intercept PSBTs can finalize before the
>>>>> legitimate Finalizer and broadcast the transaction.
>>>>>
>>>>> Participants can work from the same PSBT file if they all receive the
>>>>> same PSBT, and not working in chain where next particpant receives
>>>>> updated PSBT from the previous participant. Otherwise they will need to
>>>>> either pass two files (original and updated), or work out which fields
>>>>> (key-value blobs) to remove to get the 'source' PSBT (which might not be
>>>>> trivial with presense of proprietary and unknown fields). Even if you
>>>>> know which key-value pairs to remove, there is no requirement for
>>>>> ordering of the fields, and some signer can serialize them in different
>>>>> order after dserialize/sign/add-signatures/re-serialize operation.
>>>>>
>>>>> Introducing additional ordering or other structure requirements over
>>>>> simple key-value structure will add complexity to PSBT processing, and
>>>>> adding complexity on such a basic level should have really serious
>>>>> reasons, because that increases effort required for even basic
>>>>> implementations and increases chance of bugs.
>>>>>
>>>>> If there is some authority on the 'correctness' of 'original' PSBT
>>>>> (all particpants receive same PSBT at the start), particpants should
>>>>> check the signature by that authority. That authority might use
>>>>> the key used only for authentication, and not in the tx signing.
>>>>>
>>>>> If particpants send PSBT in chain after adding their signatures, then
>>>>> each participant can add their signature to say 'the contents
>>>>> of PSBT after my updates should match this hash'.
>>>>>
>>>>> The signatures of previous participants in the chain most likely do not
>>>>> matter because of difficulty of restoring the contents of PSBT as it
>>>>> was before the previous particpant, if you do not pass _all_ the PSBTs
>>>>> (which is excessive).
>>>>>
>>>>>> 2) In the output section, specifically, the last key/value pair of
>>>>>> the last output of the transaction, I want to add a similar signature,
>>>>>> again signed by one of the keys used in the signing process. This
>>>>>> signature will cover all the bytes of the resulting (signed) PSBT
>>>>>> up to that point. Because it is the last output of the output
>>>>>> section, that signature will be the last few bytes of the PSBT file.
>>>>>> By "appending" the signature in this way, it's easier to validate
>>>>>> and create the signature, without blanking the signature area during
>>>>>> digest step.
>>>>>
>>>>> This will introduce unnecessary higher-level structure to PSBT for the
>>>>> reasons that I do not find strong enough for the amount of complexity
>>>>> added.
>>>>>
>>>>> Also, as I said above, you likely do not need more than one
>>>>> signature - if this is 'fan-out' scheme, then participants need do
>>>>> check the sig of authority that created PSBT; if this is piggy-back
>>>>> chain, then only previous particpant's signature is easily verifiable.
>>>>>
>>>>>> ## Next Steps
>>>>>>
>>>>>> I'd like to get two officially-assigned BIP-174 key numbers assigned
>>>>>> for these two signatures, and then I will see that it gets added
>>>>>> into Coldcard's firmware immediately. In time, other tools are
>>>>>> welcome to take advantage of these checks. I will also write a BIP
>>>>>> for this, and/or make an addition to BIP-174.
>>>>>
>>>>> I think you do not need to wait for officially-assigned key numbers,
>>>>> and can just implement the scheme you envision with proprietary keys,
>>>>> document and promote it. Then if it shows its usefulness, it will
>>>>> either become de-facto standard with your proprietary keys (and
>>>>> everyone will want to support 'Coldard PSBT auth' or whatever the name),
>>>>> or the scheme will have serious grounds to be converted to standard and
>>>>> have non-proprietary keys assigned.
>>>>>
>>>>> // Dmitry.
>>>>> _______________________________________________
>>>>> bitcoin-dev mailing list
>>>>> bitcoin-dev@lists•linuxfoundation.org
>>>>> https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
>>>>>
>>